134597Sbostic /*
234597Sbostic * fight.c Phantasia monster fighting routines
334597Sbostic */
434597Sbostic
534597Sbostic #include "include.h"
634597Sbostic
734597Sbostic /************************************************************************
834597Sbostic /
934597Sbostic / FUNCTION NAME: encounter()
1034597Sbostic /
1134597Sbostic / FUNCTION: monster battle routine
1234597Sbostic /
1334597Sbostic / AUTHOR: E. A. Estes, 2/20/86
1434597Sbostic /
1534597Sbostic / ARGUMENTS:
1634597Sbostic / int particular - particular monster to fight if >= 0
1734597Sbostic /
1834597Sbostic / RETURN VALUE: none
1934597Sbostic /
2034597Sbostic / MODULES CALLED: monsthits(), playerhits(), readmessage(), callmonster(),
2134597Sbostic / writerecord(), pickmonster(), displaystats(), pow(), cancelmonster(),
2234597Sbostic / awardtreasure(), more(), death(), wmove(), setjmp(), drandom(), printw(),
2334597Sbostic / longjmp(), wrefresh(), mvprintw(), wclrtobot()
2434597Sbostic /
2534597Sbostic / GLOBAL INPUTS: Curmonster, Whichmonster, LINES, Lines, Circle, Shield,
2634597Sbostic / Player, *stdscr, Fileloc, Fightenv[], *Enemyname
2734597Sbostic /
2834597Sbostic / GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, Luckout
2934597Sbostic /
3034597Sbostic / DESCRIPTION:
3134597Sbostic / Choose a monster and check against some special types.
3234597Sbostic / Arbitrate between monster and player. Watch for either
3334597Sbostic / dying.
3434597Sbostic /
3534597Sbostic /************************************************************************/
3634597Sbostic
encounter(particular)3734597Sbostic encounter(particular)
3834597Sbostic int particular;
3934597Sbostic {
4034597Sbostic bool firsthit = Player.p_blessing; /* set if player gets the first hit */
41*41446Sbostic int flockcnt = 1; /* how many time flocked */
4234597Sbostic
4334597Sbostic /* let others know what we are doing */
4434597Sbostic Player.p_status = S_MONSTER;
4534597Sbostic writerecord(&Player, Fileloc);
4634597Sbostic
4734597Sbostic #ifdef SYS5
4834597Sbostic flushinp();
4934597Sbostic #endif
5034597Sbostic
5134597Sbostic Shield = 0.0; /* no shield up yet */
5234597Sbostic
5334597Sbostic if (particular >= 0)
5434597Sbostic /* monster is specified */
5534597Sbostic Whichmonster = particular;
5634597Sbostic else
5734597Sbostic /* pick random monster */
5834597Sbostic Whichmonster = pickmonster();
5934597Sbostic
6034597Sbostic setjmp(Fightenv); /* this is to enable changing fight state */
6134597Sbostic
6234597Sbostic move(6, 0);
6334597Sbostic clrtobot(); /* clear bottom area of screen */
6434597Sbostic
6534597Sbostic Lines = 9;
6634597Sbostic callmonster(Whichmonster); /* set up monster to fight */
6734597Sbostic
6834597Sbostic Luckout = FALSE; /* haven't tried to luckout yet */
6934597Sbostic
7034597Sbostic if (Curmonster.m_type == SM_MORGOTH)
7134597Sbostic mvprintw(4, 0, "You've encountered %s, Bane of the Council and Valar.\n",
7234597Sbostic Enemyname);
7334597Sbostic
7434597Sbostic if (Curmonster.m_type == SM_UNICORN)
7534597Sbostic {
7634597Sbostic if (Player.p_virgin)
7734597Sbostic {
7834597Sbostic printw("You just subdued %s, thanks to the virgin.\n", Enemyname);
7934597Sbostic Player.p_virgin = FALSE;
8034597Sbostic }
8134597Sbostic else
8234597Sbostic {
8334597Sbostic printw("You just saw %s running away!\n", Enemyname);
8434597Sbostic Curmonster.m_experience = 0.0;
8534597Sbostic Curmonster.m_treasuretype = 0;
8634597Sbostic }
8734597Sbostic }
8834597Sbostic else
8934597Sbostic /* not a special monster */
9034597Sbostic for (;;)
9134597Sbostic /* print header, and arbitrate between player and monster */
9234597Sbostic {
9334597Sbostic mvprintw(6, 0, "You are being attacked by %s, EXP: %.0f (Size: %.0f)\n",
9434597Sbostic Enemyname, Curmonster.m_experience, Circle);
9534597Sbostic
9634597Sbostic displaystats();
9734597Sbostic mvprintw(1, 26, "%20.0f", Player.p_energy + Shield); /* overprint energy */
9834597Sbostic readmessage();
9934597Sbostic
10034597Sbostic if (Curmonster.m_type == SM_DARKLORD
10134597Sbostic && Player.p_blessing
10234597Sbostic && Player.p_charms > 0)
10334597Sbostic /* overpower Dark Lord with blessing and charm */
10434597Sbostic {
10534597Sbostic mvprintw(7, 0, "You just overpowered %s!", Enemyname);
10634597Sbostic Lines = 8;
10734597Sbostic Player.p_blessing = FALSE;
10834597Sbostic --Player.p_charms;
10934597Sbostic break;
11034597Sbostic }
11134597Sbostic
11234597Sbostic /* allow paralyzed monster to wake up */
11334597Sbostic Curmonster.m_speed = MIN(Curmonster.m_speed + 1.0, Curmonster.m_maxspeed);
11434597Sbostic
11534597Sbostic if (drandom() * Curmonster.m_speed > drandom() * Player.p_speed
11634597Sbostic /* monster is faster */
11734597Sbostic && Curmonster.m_type != SM_DARKLORD
11834597Sbostic /* not D. L. */
11934597Sbostic && Curmonster.m_type != SM_SHRIEKER
12034597Sbostic /* not mimic */
12134597Sbostic && !firsthit)
12234597Sbostic /* monster gets a hit */
12334597Sbostic monsthits();
12434597Sbostic else
12534597Sbostic /* player gets a hit */
12634597Sbostic {
12734597Sbostic firsthit = FALSE;
12834597Sbostic playerhits();
12934597Sbostic }
13034597Sbostic
13134597Sbostic refresh();
13234597Sbostic
13334597Sbostic if (Lines > LINES - 2)
13434597Sbostic /* near bottom of screen - pause */
13534597Sbostic {
13634597Sbostic more(Lines);
13734597Sbostic move(Lines = 8, 0);
13834597Sbostic clrtobot();
13934597Sbostic }
14034597Sbostic
14134597Sbostic if (Player.p_energy <= 0.0)
14234597Sbostic /* player died */
14334597Sbostic {
14434597Sbostic more(Lines);
14534597Sbostic death(Enemyname);
14634597Sbostic cancelmonster();
14734597Sbostic break; /* fight ends if the player is saved from death */
14834597Sbostic }
14934597Sbostic
15034597Sbostic if (Curmonster.m_energy <= 0.0)
15134597Sbostic /* monster died */
15234597Sbostic break;
15334597Sbostic }
15434597Sbostic
15534597Sbostic /* give player credit for killing monster */
15634597Sbostic Player.p_experience += Curmonster.m_experience;
15734597Sbostic
15834597Sbostic if (drandom() < Curmonster.m_flock / 100.0)
15934597Sbostic /* monster flocks */
16034597Sbostic {
16134597Sbostic more(Lines);
162*41446Sbostic ++flockcnt;
16334597Sbostic longjmp(Fightenv, 0);
16434597Sbostic /*NOTREACHED*/
16534597Sbostic }
16634597Sbostic else if (Circle > 1.0
16734597Sbostic && Curmonster.m_treasuretype > 0
168*41446Sbostic && drandom() > 0.2 + pow(0.4, (double) (flockcnt / 3 + Circle / 3.0)))
16934597Sbostic /* monster has treasure; this takes # of flocks and size into account */
17034597Sbostic {
17134597Sbostic more(Lines);
17234597Sbostic awardtreasure();
17334597Sbostic }
17434597Sbostic
17534597Sbostic /* pause before returning */
176*41446Sbostic getyx(stdscr, Lines, flockcnt);
17734597Sbostic more(Lines + 1);
17834597Sbostic
17934597Sbostic Player.p_ring.ring_inuse = FALSE; /* not using ring */
18034597Sbostic
18134597Sbostic /* clean up the screen */
18234597Sbostic move(4, 0);
18334597Sbostic clrtobot();
18434597Sbostic }
18534597Sbostic /**/
18634597Sbostic /************************************************************************
18734597Sbostic /
18834597Sbostic / FUNCTION NAME: pickmonster()
18934597Sbostic /
19034597Sbostic / FUNCTION: choose a monster based upon where we are
19134597Sbostic /
19234597Sbostic / AUTHOR: E. A. Estes, 2/20/86
19334597Sbostic /
19434597Sbostic / ARGUMENTS: none
19534597Sbostic /
19634597Sbostic / RETURN VALUE: monster number to call
19734597Sbostic /
19834597Sbostic / MODULES CALLED: floor(), drandom()
19934597Sbostic /
20034597Sbostic / GLOBAL INPUTS: Marsh, Circle, Player
20134597Sbostic /
20234597Sbostic / GLOBAL OUTPUTS: none
20334597Sbostic /
20434597Sbostic / DESCRIPTION:
20534597Sbostic / Certain monsters can be found in certain areas of the grid.
20634597Sbostic / We take care of rolling them here.
20734597Sbostic / Unfortunately, this routine assumes that the monster data
20834597Sbostic / base is arranged in a particular order. If the data base
20934597Sbostic / is altered (to add monsters, or make them tougher), this
21034597Sbostic / routine may also need to be changed.
21134597Sbostic /
21234597Sbostic /************************************************************************/
21334597Sbostic
pickmonster()21434597Sbostic pickmonster()
21534597Sbostic {
21634597Sbostic if (Player.p_specialtype == SC_VALAR)
21734597Sbostic /* even chance of any monster */
21834597Sbostic return((int) ROLL(0.0, 100.0));
21934597Sbostic
22034597Sbostic if (Marsh)
22134597Sbostic /* water monsters */
22234597Sbostic return((int) ROLL(0.0, 15.0));
22334597Sbostic
22434597Sbostic else if (Circle > 24)
22534597Sbostic /* even chance of all non-water monsters */
22634597Sbostic return((int) ROLL(14.0, 86.0));
22734597Sbostic
22834597Sbostic else if (Circle > 15)
22934597Sbostic /* chance of all non-water monsters, weighted toward middle */
23034597Sbostic return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 37.0)));
23134597Sbostic
23234597Sbostic else if (Circle > 8)
23334597Sbostic /* not all non-water monsters, weighted toward middle */
23434597Sbostic return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 26.0)));
23534597Sbostic
23634597Sbostic else if (Circle > 3)
23734597Sbostic /* even chance of some tamer non-water monsters */
23834597Sbostic return((int) ROLL(14.0, 50.0));
23934597Sbostic
24034597Sbostic else
24134597Sbostic /* even chance of some of the tamest non-water monsters */
24234597Sbostic return((int) ROLL(14.0, 25.0));
24334597Sbostic }
24434597Sbostic /**/
24534597Sbostic /************************************************************************
24634597Sbostic /
24734597Sbostic / FUNCTION NAME: playerhits()
24834597Sbostic /
24934597Sbostic / FUNCTION: prompt player for action in monster battle, and process
25034597Sbostic /
25134597Sbostic / AUTHOR: E. A. Estes, 12/4/85
25234597Sbostic /
25334597Sbostic / ARGUMENTS: none
25434597Sbostic /
25534597Sbostic / RETURN VALUE: none
25634597Sbostic /
25734597Sbostic / MODULES CALLED: hitmonster(), throwspell(), inputoption(), cancelmonster(),
25834597Sbostic / floor(), wmove(), drandom(), altercoordinates(), waddstr(), mvprintw(),
25934597Sbostic / wclrtoeol(), wclrtobot()
26034597Sbostic /
26134597Sbostic / GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, Luckout, *Enemyname
26234597Sbostic /
26334597Sbostic / GLOBAL OUTPUTS: Curmonster, Lines, Player, Luckout
26434597Sbostic /
26534597Sbostic / DESCRIPTION:
26634597Sbostic / Process all monster battle options.
26734597Sbostic /
26834597Sbostic /************************************************************************/
26934597Sbostic
playerhits()27034597Sbostic playerhits()
27134597Sbostic {
27234597Sbostic double inflict; /* damage inflicted */
27334597Sbostic int ch; /* input */
27434597Sbostic
27534597Sbostic mvaddstr(7, 0, "1:Melee 2:Skirmish 3:Evade 4:Spell 5:Nick ");
27634597Sbostic
27734597Sbostic if (!Luckout)
27834597Sbostic /* haven't tried to luckout yet */
27934597Sbostic if (Curmonster.m_type == SM_MORGOTH)
28034597Sbostic /* cannot luckout against Morgoth */
28134597Sbostic addstr("6:Ally ");
28234597Sbostic else
28334597Sbostic addstr("6:Luckout ");
28434597Sbostic
28534597Sbostic if (Player.p_ring.ring_type != R_NONE)
28634597Sbostic /* player has a ring */
28734597Sbostic addstr("7:Use Ring ");
28834597Sbostic else
28934597Sbostic clrtoeol();
29034597Sbostic
29134597Sbostic ch = inputoption();
29234597Sbostic
29334597Sbostic move(8, 0);
29434597Sbostic clrtobot(); /* clear any messages from before */
29534597Sbostic Lines = 9;
29634597Sbostic mvaddstr(4, 0, "\n\n"); /* clear status area */
29734597Sbostic
29834597Sbostic switch (ch)
29934597Sbostic {
30034597Sbostic case 'T': /* timeout; lose turn */
30134597Sbostic break;
30234597Sbostic
30334597Sbostic case ' ':
30434597Sbostic case '1': /* melee */
30534597Sbostic /* melee affects monster's energy and strength */
30634597Sbostic inflict = ROLL(Player.p_might / 2.0 + 5.0, 1.3 * Player.p_might)
30734597Sbostic + (Player.p_ring.ring_inuse ? Player.p_might : 0.0);
30834597Sbostic
30934597Sbostic Curmonster.m_melee += inflict;
31034597Sbostic Curmonster.m_strength = Curmonster.m_o_strength
31134597Sbostic - Curmonster.m_melee / Curmonster.m_o_energy
31234597Sbostic * Curmonster.m_o_strength / 4.0;
31334597Sbostic hitmonster(inflict);
31434597Sbostic break;
31534597Sbostic
31634597Sbostic case '2': /* skirmish */
31734597Sbostic /* skirmish affects monter's energy and speed */
31834597Sbostic inflict = ROLL(Player.p_might / 3.0 + 3.0, 1.1 * Player.p_might)
31934597Sbostic + (Player.p_ring.ring_inuse ? Player.p_might : 0.0);
32034597Sbostic
32134597Sbostic Curmonster.m_skirmish += inflict;
32234597Sbostic Curmonster.m_maxspeed = Curmonster.m_o_speed
32334597Sbostic - Curmonster.m_skirmish / Curmonster.m_o_energy
32434597Sbostic * Curmonster.m_o_speed / 4.0;
32534597Sbostic hitmonster(inflict);
32634597Sbostic break;
32734597Sbostic
32834597Sbostic case '3': /* evade */
32934597Sbostic /* use brains and speed to try to evade */
33034597Sbostic if ((Curmonster.m_type == SM_DARKLORD
33134597Sbostic || Curmonster.m_type == SM_SHRIEKER
33234597Sbostic /* can always run from D. L. and shrieker */
33334597Sbostic || drandom() * Player.p_speed * Player.p_brains
33434597Sbostic > drandom() * Curmonster.m_speed * Curmonster.m_brains)
33534597Sbostic && (Curmonster.m_type != SM_MIMIC))
33634597Sbostic /* cannot run from mimic */
33734597Sbostic {
33834597Sbostic mvaddstr(Lines++, 0, "You got away!");
33934597Sbostic cancelmonster();
34034597Sbostic altercoordinates(0.0, 0.0, A_NEAR);
34134597Sbostic }
34234597Sbostic else
34334597Sbostic mvprintw(Lines++, 0, "%s is still after you!", Enemyname);
34434597Sbostic
34534597Sbostic break;
34634597Sbostic
34734597Sbostic case 'M':
34834597Sbostic case '4': /* magic spell */
34934597Sbostic throwspell();
35034597Sbostic break;
35134597Sbostic
35234597Sbostic case '5': /* nick */
35334597Sbostic /* hit 1 plus sword; give some experience */
35434597Sbostic inflict = 1.0 + Player.p_sword;
35534597Sbostic Player.p_experience += floor(Curmonster.m_experience / 10.0);
35634597Sbostic Curmonster.m_experience *= 0.92;
35734597Sbostic /* monster gets meaner */
35834597Sbostic Curmonster.m_maxspeed += 2.0;
35934597Sbostic Curmonster.m_speed = (Curmonster.m_speed < 0.0) ? 0.0 : Curmonster.m_speed + 2.0;
36034597Sbostic if (Curmonster.m_type == SM_DARKLORD)
36134597Sbostic /* Dark Lord; doesn't like to be nicked */
36234597Sbostic {
36334597Sbostic mvprintw(Lines++, 0,
36434597Sbostic "You hit %s %.0f times, and made him mad!", Enemyname, inflict);
36534597Sbostic Player.p_quickness /= 2.0;
36634597Sbostic altercoordinates(0.0, 0.0, A_FAR);
36734597Sbostic cancelmonster();
36834597Sbostic }
36934597Sbostic else
37034597Sbostic hitmonster(inflict);
37134597Sbostic break;
37234597Sbostic
37334597Sbostic case 'B':
37434597Sbostic case '6': /* luckout */
37534597Sbostic if (Luckout)
37634597Sbostic mvaddstr(Lines++, 0, "You already tried that.");
37734597Sbostic else
37834597Sbostic {
37934597Sbostic Luckout = TRUE;
38034597Sbostic if (Curmonster.m_type == SM_MORGOTH)
38134597Sbostic /* Morgoth; ally */
38234597Sbostic {
38334597Sbostic if (drandom() < Player.p_sin / 100.0)
38434597Sbostic {
38534597Sbostic mvprintw(Lines++, 0, "%s accepted!", Enemyname);
38634597Sbostic cancelmonster();
38734597Sbostic }
38834597Sbostic else
38934597Sbostic mvaddstr(Lines++, 0, "Nope, he's not interested.");
39034597Sbostic }
39134597Sbostic else
39234597Sbostic /* normal monster; use brains for success */
39334597Sbostic {
39434597Sbostic if ((drandom() + 0.333) * Player.p_brains
39534597Sbostic < (drandom() + 0.333) * Curmonster.m_brains)
39634597Sbostic mvprintw(Lines++, 0, "You blew it, %s.", Player.p_name);
39734597Sbostic else
39834597Sbostic {
39934597Sbostic mvaddstr(Lines++, 0, "You made it!");
40034597Sbostic Curmonster.m_energy = 0.0;
40134597Sbostic }
40234597Sbostic }
40334597Sbostic }
40434597Sbostic break;
40534597Sbostic
40634597Sbostic case '7': /* use ring */
40734597Sbostic if (Player.p_ring.ring_type != R_NONE)
40834597Sbostic {
40934597Sbostic mvaddstr(Lines++, 0, "Now using ring.");
41034597Sbostic Player.p_ring.ring_inuse = TRUE;
41134597Sbostic if (Player.p_ring.ring_type != R_DLREG)
41234597Sbostic /* age ring */
41334597Sbostic --Player.p_ring.ring_duration;
41434597Sbostic }
41534597Sbostic break;
41634597Sbostic }
41734597Sbostic
41834597Sbostic }
41934597Sbostic /**/
42034597Sbostic /************************************************************************
42134597Sbostic /
42234597Sbostic / FUNCTION NAME: monsthits()
42334597Sbostic /
42434597Sbostic / FUNCTION: process a monster hitting the player
42534597Sbostic /
42634597Sbostic / AUTHOR: E. A. Estes, 12/4/85
42734597Sbostic /
42834597Sbostic / ARGUMENTS: none
42934597Sbostic /
43034597Sbostic / RETURN VALUE: none
43134597Sbostic /
43234597Sbostic / MODULES CALLED: cancelmonster(), scramblestats(), more(), floor(), wmove(),
43334597Sbostic / drandom(), altercoordinates(), longjmp(), waddstr(), mvprintw(),
43434597Sbostic / getanswer()
43534597Sbostic /
43634597Sbostic / GLOBAL INPUTS: Curmonster, Lines, Circle, Shield, Player, *stdscr,
43734597Sbostic / Fightenv[], *Enemyname
43834597Sbostic /
43934597Sbostic / GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player,
44034597Sbostic / *Enemyname
44134597Sbostic /
44234597Sbostic / DESCRIPTION:
44334597Sbostic / Handle all special monsters here. If the monster is not a special
44434597Sbostic / one, simply roll a hit against the player.
44534597Sbostic /
44634597Sbostic /************************************************************************/
44734597Sbostic
monsthits()44834597Sbostic monsthits()
44934597Sbostic {
45034597Sbostic double inflict; /* damage inflicted */
45134597Sbostic int ch; /* input */
45234597Sbostic
45334597Sbostic switch (Curmonster.m_type)
45434597Sbostic /* may be a special monster */
45534597Sbostic {
45634597Sbostic case SM_DARKLORD:
45734597Sbostic /* hits just enough to kill player */
45834597Sbostic inflict = (Player.p_energy + Shield) * 1.02;
45934597Sbostic goto SPECIALHIT;
46034597Sbostic
46134597Sbostic case SM_SHRIEKER:
46234597Sbostic /* call a big monster */
46334597Sbostic mvaddstr(Lines++, 0,
46434597Sbostic "Shrieeeek!! You scared it, and it called one of its friends.");
46534597Sbostic more(Lines);
46634597Sbostic Whichmonster = (int) ROLL(70.0, 30.0);
46734597Sbostic longjmp(Fightenv, 0);
46834597Sbostic /*NOTREACHED*/
46934597Sbostic
47034597Sbostic case SM_BALROG:
47134597Sbostic /* take experience away */
47234597Sbostic inflict = ROLL(10.0, Curmonster.m_strength);
47334597Sbostic inflict = MIN(Player.p_experience, inflict);
47434597Sbostic mvprintw(Lines++, 0,
47534597Sbostic "%s took away %.0f experience points.", Enemyname, inflict);
47634597Sbostic Player.p_experience -= inflict;
47734597Sbostic return;
47834597Sbostic
47934597Sbostic case SM_FAERIES:
48034597Sbostic if (Player.p_holywater > 0)
48134597Sbostic /* holy water kills when monster tries to hit */
48234597Sbostic {
48334597Sbostic mvprintw(Lines++, 0, "Your holy water killed it!");
48434597Sbostic --Player.p_holywater;
48534597Sbostic Curmonster.m_energy = 0.0;
48634597Sbostic return;
48734597Sbostic }
48834597Sbostic break;
48934597Sbostic
49034597Sbostic case SM_NONE:
49134597Sbostic /* normal hit */
49234597Sbostic break;
49334597Sbostic
49434597Sbostic default:
49534597Sbostic if (drandom() > 0.2)
49634597Sbostic /* normal hit */
49734597Sbostic break;
49834597Sbostic
49934597Sbostic /* else special things */
50034597Sbostic switch (Curmonster.m_type)
50134597Sbostic {
50234597Sbostic case SM_LEANAN:
50334597Sbostic /* takes some of the player's strength */
50434597Sbostic inflict = ROLL(1.0, (Circle - 1.0) / 2.0);
50534597Sbostic inflict = MIN(Player.p_strength, inflict);
50634597Sbostic mvprintw(Lines++, 0, "%s sapped %0.f of your strength!",
50734597Sbostic Enemyname, inflict);
50834597Sbostic Player.p_strength -= inflict;
50934597Sbostic Player.p_might -= inflict;
51034597Sbostic break;
51134597Sbostic
51234597Sbostic case SM_SARUMAN:
51334597Sbostic if (Player.p_palantir)
51434597Sbostic /* take away palantir */
51534597Sbostic {
51634597Sbostic mvprintw(Lines++, 0, "Wormtongue stole your palantir!");
51734597Sbostic Player.p_palantir = FALSE;
51834597Sbostic }
51934597Sbostic else if (drandom() > 0.5)
52034597Sbostic /* gems turn to gold */
52134597Sbostic {
52234597Sbostic mvprintw(Lines++, 0,
52334597Sbostic "%s transformed your gems into gold!", Enemyname);
52434597Sbostic Player.p_gold += Player.p_gems;
52534597Sbostic Player.p_gems = 0.0;
52634597Sbostic }
52734597Sbostic else
52834597Sbostic /* scramble some stats */
52934597Sbostic {
53034597Sbostic mvprintw(Lines++, 0, "%s scrambled your stats!", Enemyname);
53134597Sbostic scramblestats();
53234597Sbostic }
53334597Sbostic break;
53434597Sbostic
53534597Sbostic case SM_THAUMATURG:
53634597Sbostic /* transport player */
53734597Sbostic mvprintw(Lines++, 0, "%s transported you!", Enemyname);
53834597Sbostic altercoordinates(0.0, 0.0, A_FAR);
53934597Sbostic cancelmonster();
54034597Sbostic break;
54134597Sbostic
54234597Sbostic case SM_VORTEX:
54334597Sbostic /* suck up some mana */
54434597Sbostic inflict = ROLL(0, 7.5 * Circle);
54534597Sbostic inflict = MIN(Player.p_mana, floor(inflict));
54634597Sbostic mvprintw(Lines++, 0,
54734597Sbostic "%s sucked up %.0f of your mana!", Enemyname, inflict);
54834597Sbostic Player.p_mana -= inflict;
54934597Sbostic break;
55034597Sbostic
55134597Sbostic case SM_NAZGUL:
55234597Sbostic /* try to take ring if player has one */
55334597Sbostic if (Player.p_ring.ring_type != R_NONE)
55434597Sbostic /* player has a ring */
55534597Sbostic {
55634597Sbostic mvaddstr(Lines++, 0, "Will you relinguish your ring ? ");
55734597Sbostic ch = getanswer("YN", FALSE);
55834597Sbostic if (ch == 'Y')
55934597Sbostic /* take ring away */
56034597Sbostic {
56134597Sbostic Player.p_ring.ring_type = R_NONE;
56234597Sbostic Player.p_ring.ring_inuse = FALSE;
56334597Sbostic cancelmonster();
56434597Sbostic break;
56534597Sbostic }
56634597Sbostic }
56734597Sbostic
56834597Sbostic /* otherwise, take some brains */
56934597Sbostic mvprintw(Lines++, 0,
57034597Sbostic "%s neutralized 1/5 of your brain!", Enemyname);
57134597Sbostic Player.p_brains *= 0.8;
57234597Sbostic break;
57334597Sbostic
57434597Sbostic case SM_TIAMAT:
57534597Sbostic /* take some gold and gems */
57634597Sbostic mvprintw(Lines++, 0,
57734597Sbostic "%s took half your gold and gems and flew off.", Enemyname);
57834597Sbostic Player.p_gold /= 2.0;
57934597Sbostic Player.p_gems /= 2.0;
58034597Sbostic cancelmonster();
58134597Sbostic break;
58234597Sbostic
58334597Sbostic case SM_KOBOLD:
58434597Sbostic /* steal a gold piece and run */
58534597Sbostic mvprintw(Lines++, 0,
58634597Sbostic "%s stole one gold piece and ran away.", Enemyname);
58734597Sbostic Player.p_gold = MAX(0.0, Player.p_gold - 1.0);
58834597Sbostic cancelmonster();
58934597Sbostic break;
59034597Sbostic
59134597Sbostic case SM_SHELOB:
59234597Sbostic /* bite and (medium) poison */
59334597Sbostic mvprintw(Lines++, 0,
59434597Sbostic "%s has bitten and poisoned you!", Enemyname);
59534597Sbostic Player.p_poison -= 1.0;
59634597Sbostic break;
59734597Sbostic
59834597Sbostic case SM_LAMPREY:
59934597Sbostic /* bite and (small) poison */
60034597Sbostic mvprintw(Lines++, 0, "%s bit and poisoned you!", Enemyname);
60134597Sbostic Player.p_poison += 0.25;
60234597Sbostic break;
60334597Sbostic
60434597Sbostic case SM_BONNACON:
60534597Sbostic /* fart and run */
60634597Sbostic mvprintw(Lines++, 0, "%s farted and scampered off.", Enemyname);
60734597Sbostic Player.p_energy /= 2.0; /* damage from fumes */
60834597Sbostic cancelmonster();
60934597Sbostic break;
61034597Sbostic
61134597Sbostic case SM_SMEAGOL:
61234597Sbostic if (Player.p_ring.ring_type != R_NONE)
61334597Sbostic /* try to steal ring */
61434597Sbostic {
61534597Sbostic mvprintw(Lines++, 0,
61634597Sbostic "%s tried to steal your ring, ", Enemyname);
61734597Sbostic if (drandom() > 0.1)
61834597Sbostic addstr("but was unsuccessful.");
61934597Sbostic else
62034597Sbostic {
62134597Sbostic addstr("and ran away with it!");
62234597Sbostic Player.p_ring.ring_type = R_NONE;
62334597Sbostic cancelmonster();
62434597Sbostic }
62534597Sbostic }
62634597Sbostic break;
62734597Sbostic
62834597Sbostic case SM_SUCCUBUS:
62934597Sbostic /* inflict damage through shield */
63034597Sbostic inflict = ROLL(15.0, Circle * 10.0);
63134597Sbostic inflict = MIN(inflict, Player.p_energy);
63234597Sbostic mvprintw(Lines++, 0, "%s sapped %.0f of your energy.",
63334597Sbostic Enemyname, inflict);
63434597Sbostic Player.p_energy -= inflict;
63534597Sbostic break;
63634597Sbostic
63734597Sbostic case SM_CERBERUS:
63834597Sbostic /* take all metal treasures */
63934597Sbostic mvprintw(Lines++, 0,
64034597Sbostic "%s took all your metal treasures!", Enemyname);
64134597Sbostic Player.p_crowns = 0;
64234597Sbostic Player.p_sword =
64334597Sbostic Player.p_shield =
64434597Sbostic Player.p_gold = 0.0;
64534597Sbostic cancelmonster();
64634597Sbostic break;
64734597Sbostic
64834597Sbostic case SM_UNGOLIANT:
64934597Sbostic /* (large) poison and take a quickness */
65034597Sbostic mvprintw(Lines++, 0,
65134597Sbostic "%s poisoned you, and took one quik.", Enemyname);
65234597Sbostic Player.p_poison += 5.0;
65334597Sbostic Player.p_quickness -= 1.0;
65434597Sbostic break;
65534597Sbostic
65634597Sbostic case SM_JABBERWOCK:
65734597Sbostic /* fly away, and leave either a Jubjub bird or Bonnacon */
65834597Sbostic mvprintw(Lines++, 0,
65934597Sbostic "%s flew away, and left you to contend with one of its friends.",
66034597Sbostic Enemyname);
66134597Sbostic Whichmonster = 55 + (drandom() > 0.5) ? 22 : 0;
66234597Sbostic longjmp(Fightenv, 0);
66334597Sbostic /*NOTREACHED*/
66434597Sbostic
66534597Sbostic case SM_TROLL:
66634597Sbostic /* partially regenerate monster */
66734597Sbostic mvprintw(Lines++, 0,
66834597Sbostic "%s partially regenerated his energy.!", Enemyname);
66934597Sbostic Curmonster.m_energy +=
67034597Sbostic floor((Curmonster.m_o_energy - Curmonster.m_energy) / 2.0);
67134597Sbostic Curmonster.m_strength = Curmonster.m_o_strength;
67234597Sbostic Curmonster.m_melee = Curmonster.m_skirmish = 0.0;
67334597Sbostic Curmonster.m_maxspeed = Curmonster.m_o_speed;
67434597Sbostic break;
67534597Sbostic
67634597Sbostic case SM_WRAITH:
67734597Sbostic if (!Player.p_blindness)
67834597Sbostic /* make blind */
67934597Sbostic {
68034597Sbostic mvprintw(Lines++, 0, "%s blinded you!", Enemyname);
68134597Sbostic Player.p_blindness = TRUE;
68234597Sbostic Enemyname = "A monster";
68334597Sbostic }
68434597Sbostic break;
68534597Sbostic }
68634597Sbostic return;
68734597Sbostic }
68834597Sbostic
68934597Sbostic /* fall through to here if monster inflicts a normal hit */
69034597Sbostic inflict = drandom() * Curmonster.m_strength + 0.5;
69134597Sbostic SPECIALHIT:
69234597Sbostic mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, inflict);
69334597Sbostic
69434597Sbostic if ((Shield -= inflict) < 0)
69534597Sbostic {
69634597Sbostic Player.p_energy += Shield;
69734597Sbostic Shield = 0.0;
69834597Sbostic }
69934597Sbostic }
70034597Sbostic /**/
70134597Sbostic /************************************************************************
70234597Sbostic /
70334597Sbostic / FUNCTION NAME: cancelmonster()
70434597Sbostic /
70534597Sbostic / FUNCTION: mark current monster as no longer active
70634597Sbostic /
70734597Sbostic / AUTHOR: E. A. Estes, 12/4/85
70834597Sbostic /
70934597Sbostic / ARGUMENTS: none
71034597Sbostic /
71134597Sbostic / RETURN VALUE: none
71234597Sbostic /
71334597Sbostic / MODULES CALLED: none
71434597Sbostic /
71534597Sbostic / GLOBAL INPUTS: none
71634597Sbostic /
71734597Sbostic / GLOBAL OUTPUTS: Curmonster
71834597Sbostic /
71934597Sbostic / DESCRIPTION:
72034597Sbostic / Clear current monster's energy, experience, treasure type, and
72134597Sbostic / flock. This is the same as having the monster run away.
72234597Sbostic /
72334597Sbostic /************************************************************************/
72434597Sbostic
cancelmonster()72534597Sbostic cancelmonster()
72634597Sbostic {
72734597Sbostic Curmonster.m_energy = 0.0;
72834597Sbostic Curmonster.m_experience = 0.0;
72934597Sbostic Curmonster.m_treasuretype = 0;
73034597Sbostic Curmonster.m_flock = 0.0;
73134597Sbostic }
73234597Sbostic /**/
73334597Sbostic /************************************************************************
73434597Sbostic /
73534597Sbostic / FUNCTION NAME: hitmonster()
73634597Sbostic /
73734597Sbostic / FUNCTION: inflict damage upon current monster
73834597Sbostic /
73934597Sbostic / AUTHOR: E. A. Estes, 12/4/85
74034597Sbostic /
74134597Sbostic / ARGUMENTS:
74234597Sbostic / double inflict - damage to inflict upon monster
74334597Sbostic /
74434597Sbostic / RETURN VALUE: none
74534597Sbostic /
74634597Sbostic / MODULES CALLED: monsthits(), wmove(), strcmp(), waddstr(), mvprintw()
74734597Sbostic /
74834597Sbostic / GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, *Enemyname
74934597Sbostic /
75034597Sbostic / GLOBAL OUTPUTS: Curmonster, Lines
75134597Sbostic /
75234597Sbostic / DESCRIPTION:
75334597Sbostic / Hit monster specified number of times. Handle when monster dies,
75434597Sbostic / and a few special monsters.
75534597Sbostic /
75634597Sbostic /************************************************************************/
75734597Sbostic
hitmonster(inflict)75834597Sbostic hitmonster(inflict)
75934597Sbostic double inflict;
76034597Sbostic {
76134597Sbostic mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, inflict);
76234597Sbostic Curmonster.m_energy -= inflict;
76334597Sbostic if (Curmonster.m_energy > 0.0)
76434597Sbostic {
76534597Sbostic if (Curmonster.m_type == SM_DARKLORD || Curmonster.m_type == SM_SHRIEKER)
76634597Sbostic /* special monster didn't die */
76734597Sbostic monsthits();
76834597Sbostic }
76934597Sbostic else
77034597Sbostic /* monster died. print message. */
77134597Sbostic {
77234597Sbostic if (Curmonster.m_type == SM_MORGOTH)
77334597Sbostic mvaddstr(Lines++, 0, "You have defeated Morgoth, but he may return. . .");
77434597Sbostic else
77534597Sbostic /* all other types of monsters */
77634597Sbostic {
77734597Sbostic mvprintw(Lines++, 0, "You killed it. Good work, %s.", Player.p_name);
77834597Sbostic
77934597Sbostic if (Curmonster.m_type == SM_MIMIC
78034597Sbostic && strcmp(Curmonster.m_name, "A Mimic") != 0
78134597Sbostic && !Player.p_blindness)
78234597Sbostic mvaddstr(Lines++, 0, "The body slowly changes into the form of a mimic.");
78334597Sbostic }
78434597Sbostic }
78534597Sbostic }
78634597Sbostic /**/
78734597Sbostic /************************************************************************
78834597Sbostic /
78934597Sbostic / FUNCTION NAME: throwspell()
79034597Sbostic /
79134597Sbostic / FUNCTION: throw a magic spell
79234597Sbostic /
79334597Sbostic / AUTHOR: E. A. Estes, 12/4/85
79434597Sbostic /
79534597Sbostic / ARGUMENTS: none
79634597Sbostic /
79734597Sbostic / RETURN VALUE: none
79834597Sbostic /
79934597Sbostic / MODULES CALLED: hitmonster(), cancelmonster(), sqrt(), floor(), wmove(),
80034597Sbostic / drandom(), altercoordinates(), longjmp(), infloat(), waddstr(), mvprintw(),
80134597Sbostic / getanswer()
80234597Sbostic /
80334597Sbostic / GLOBAL INPUTS: Curmonster, Whichmonster, Nomana[], Player, *stdscr,
80434597Sbostic / Fightenv[], Illspell[], *Enemyname
80534597Sbostic /
80634597Sbostic / GLOBAL OUTPUTS: Curmonster, Whichmonster, Shield, Player
80734597Sbostic /
80834597Sbostic / DESCRIPTION:
80934597Sbostic / Prompt player and process magic spells.
81034597Sbostic /
81134597Sbostic /************************************************************************/
81234597Sbostic
throwspell()81334597Sbostic throwspell()
81434597Sbostic {
81534597Sbostic double inflict; /* damage inflicted */
81634597Sbostic double dtemp; /* for dtemporary calculations */
81734597Sbostic int ch; /* input */
81834597Sbostic
81934597Sbostic mvaddstr(7, 0, "\n\n"); /* clear menu area */
82034597Sbostic
82134597Sbostic if (Player.p_magiclvl >= ML_ALLORNOTHING)
82234597Sbostic mvaddstr(7, 0, "1:All or Nothing ");
82334597Sbostic if (Player.p_magiclvl >= ML_MAGICBOLT)
82434597Sbostic addstr("2:Magic Bolt ");
82534597Sbostic if (Player.p_magiclvl >= ML_FORCEFIELD)
82634597Sbostic addstr("3:Force Field ");
82734597Sbostic if (Player.p_magiclvl >= ML_XFORM)
82834597Sbostic addstr("4:Transform ");
82934597Sbostic if (Player.p_magiclvl >= ML_INCRMIGHT)
83034597Sbostic addstr("5:Increase Might\n");
83134597Sbostic if (Player.p_magiclvl >= ML_INVISIBLE)
83234597Sbostic mvaddstr(8, 0, "6:Invisibility ");
83334597Sbostic if (Player.p_magiclvl >= ML_XPORT)
83434597Sbostic addstr("7:Transport ");
83534597Sbostic if (Player.p_magiclvl >= ML_PARALYZE)
83634597Sbostic addstr("8:Paralyze ");
83734597Sbostic if (Player.p_specialtype >= SC_COUNCIL)
83834597Sbostic addstr("9:Specify");
83934597Sbostic mvaddstr(4, 0, "Spell ? ");
84034597Sbostic
84134597Sbostic ch = getanswer(" ", TRUE);
84234597Sbostic
84334597Sbostic mvaddstr(7, 0, "\n\n"); /* clear menu area */
84434597Sbostic
84534597Sbostic if (Curmonster.m_type == SM_MORGOTH && ch != '3')
84634597Sbostic /* can only throw force field against Morgoth */
84734597Sbostic ILLSPELL();
84834597Sbostic else
84934597Sbostic switch (ch)
85034597Sbostic {
85134597Sbostic case '1': /* all or nothing */
85234597Sbostic if (drandom() < 0.25)
85334597Sbostic /* success */
85434597Sbostic {
85534597Sbostic inflict = Curmonster.m_energy * 1.01 + 1.0;
85634597Sbostic
85734597Sbostic if (Curmonster.m_type == SM_DARKLORD)
85834597Sbostic /* all or nothing doesn't quite work against D. L. */
85934597Sbostic inflict *= 0.9;
86034597Sbostic }
86134597Sbostic else
86234597Sbostic /* failure -- monster gets stronger and quicker */
86334597Sbostic {
86434597Sbostic Curmonster.m_o_strength = Curmonster.m_strength *= 2.0;
86534597Sbostic Curmonster.m_maxspeed *= 2.0;
86634597Sbostic Curmonster.m_o_speed *= 2.0;
86734597Sbostic
86834597Sbostic /* paralyzed monsters wake up a bit */
86934597Sbostic Curmonster.m_speed = MAX(1.0, Curmonster.m_speed * 2.0);
87034597Sbostic }
87134597Sbostic
87234597Sbostic if (Player.p_mana >= MM_ALLORNOTHING)
87334597Sbostic /* take a mana if player has one */
87434597Sbostic Player.p_mana -= MM_ALLORNOTHING;
87534597Sbostic
87634597Sbostic hitmonster(inflict);
87734597Sbostic break;
87834597Sbostic
87934597Sbostic case '2': /* magic bolt */
88034597Sbostic if (Player.p_magiclvl < ML_MAGICBOLT)
88134597Sbostic ILLSPELL();
88234597Sbostic else
88334597Sbostic {
88434597Sbostic do
88534597Sbostic /* prompt for amount to expend */
88634597Sbostic {
88734597Sbostic mvaddstr(4, 0, "How much mana for bolt? ");
88834597Sbostic dtemp = floor(infloat());
88934597Sbostic }
89034597Sbostic while (dtemp < 0.0 || dtemp > Player.p_mana);
89134597Sbostic
89234597Sbostic Player.p_mana -= dtemp;
89334597Sbostic
89434597Sbostic if (Curmonster.m_type == SM_DARKLORD)
89534597Sbostic /* magic bolts don't work against D. L. */
89634597Sbostic inflict = 0.0;
89734597Sbostic else
89834597Sbostic inflict = dtemp * ROLL(15.0, sqrt(Player.p_magiclvl / 3.0 + 1.0));
89934597Sbostic mvaddstr(5, 0, "Magic Bolt fired!\n");
90034597Sbostic hitmonster(inflict);
90134597Sbostic }
90234597Sbostic break;
90334597Sbostic
90434597Sbostic case '3': /* force field */
90534597Sbostic if (Player.p_magiclvl < ML_FORCEFIELD)
90634597Sbostic ILLSPELL();
90734597Sbostic else if (Player.p_mana < MM_FORCEFIELD)
90834597Sbostic NOMANA();
90934597Sbostic else
91034597Sbostic {
91134597Sbostic Player.p_mana -= MM_FORCEFIELD;
91234597Sbostic Shield = (Player.p_maxenergy + Player.p_shield) * 4.2 + 45.0;
91334597Sbostic mvaddstr(5, 0, "Force Field up.\n");
91434597Sbostic }
91534597Sbostic break;
91634597Sbostic
91734597Sbostic case '4': /* transform */
91834597Sbostic if (Player.p_magiclvl < ML_XFORM)
91934597Sbostic ILLSPELL();
92034597Sbostic else if (Player.p_mana < MM_XFORM)
92134597Sbostic NOMANA();
92234597Sbostic else
92334597Sbostic {
92434597Sbostic Player.p_mana -= MM_XFORM;
92534597Sbostic Whichmonster = (int) ROLL(0.0, 100.0);
92634597Sbostic longjmp(Fightenv, 0);
92734597Sbostic /*NOTREACHED*/
92834597Sbostic }
92934597Sbostic break;
93034597Sbostic
93134597Sbostic case '5': /* increase might */
93234597Sbostic if (Player.p_magiclvl < ML_INCRMIGHT)
93334597Sbostic ILLSPELL();
93434597Sbostic else if (Player.p_mana < MM_INCRMIGHT)
93534597Sbostic NOMANA();
93634597Sbostic else
93734597Sbostic {
93834597Sbostic Player.p_mana -= MM_INCRMIGHT;
93934597Sbostic Player.p_might +=
94034597Sbostic (1.2 * (Player.p_strength + Player.p_sword)
94134597Sbostic + 5.0 - Player.p_might) / 2.0;
94234597Sbostic mvprintw(5, 0, "New strength: %.0f\n", Player.p_might);
94334597Sbostic }
94434597Sbostic break;
94534597Sbostic
94634597Sbostic case '6': /* invisible */
94734597Sbostic if (Player.p_magiclvl < ML_INVISIBLE)
94834597Sbostic ILLSPELL();
94934597Sbostic else if (Player.p_mana < MM_INVISIBLE)
95034597Sbostic NOMANA();
95134597Sbostic else
95234597Sbostic {
95334597Sbostic Player.p_mana -= MM_INVISIBLE;
95434597Sbostic Player.p_speed +=
95534597Sbostic (1.2 * (Player.p_quickness + Player.p_quksilver)
95634597Sbostic + 5.0 - Player.p_speed) / 2.0;
95734597Sbostic mvprintw(5, 0, "New quickness: %.0f\n", Player.p_speed);
95834597Sbostic }
95934597Sbostic break;
96034597Sbostic
96134597Sbostic case '7': /* transport */
96234597Sbostic if (Player.p_magiclvl < ML_XPORT)
96334597Sbostic ILLSPELL();
96434597Sbostic else if (Player.p_mana < MM_XPORT)
96534597Sbostic NOMANA();
96634597Sbostic else
96734597Sbostic {
96834597Sbostic Player.p_mana -= MM_XPORT;
96934597Sbostic if (Player.p_brains + Player.p_magiclvl
97034597Sbostic < Curmonster.m_experience / 200.0 * drandom())
97134597Sbostic {
97234597Sbostic mvaddstr(5, 0, "Transport backfired!\n");
97334597Sbostic altercoordinates(0.0, 0.0, A_FAR);
97434597Sbostic cancelmonster();
97534597Sbostic }
97634597Sbostic else
97734597Sbostic {
97834597Sbostic mvprintw(5, 0, "%s is transported.\n", Enemyname);
97934597Sbostic if (drandom() < 0.3)
98034597Sbostic /* monster didn't drop its treasure */
98134597Sbostic Curmonster.m_treasuretype = 0;
98234597Sbostic
98334597Sbostic Curmonster.m_energy = 0.0;
98434597Sbostic }
98534597Sbostic }
98634597Sbostic break;
98734597Sbostic
98834597Sbostic case '8': /* paralyze */
98934597Sbostic if (Player.p_magiclvl < ML_PARALYZE)
99034597Sbostic ILLSPELL();
99134597Sbostic else if (Player.p_mana < MM_PARALYZE)
99234597Sbostic NOMANA();
99334597Sbostic else
99434597Sbostic {
99534597Sbostic Player.p_mana -= MM_PARALYZE;
99634597Sbostic if (Player.p_magiclvl >
99734597Sbostic Curmonster.m_experience / 1000.0 * drandom())
99834597Sbostic {
99934597Sbostic mvprintw(5, 0, "%s is held.\n", Enemyname);
100034597Sbostic Curmonster.m_speed = -2.0;
100134597Sbostic }
100234597Sbostic else
100334597Sbostic mvaddstr(5, 0, "Monster unaffected.\n");
100434597Sbostic }
100534597Sbostic break;
100634597Sbostic
100734597Sbostic case '9': /* specify */
100834597Sbostic if (Player.p_specialtype < SC_COUNCIL)
100934597Sbostic ILLSPELL();
101034597Sbostic else if (Player.p_mana < MM_SPECIFY)
101134597Sbostic NOMANA();
101234597Sbostic else
101334597Sbostic {
101434597Sbostic Player.p_mana -= MM_SPECIFY;
101534597Sbostic mvaddstr(5, 0, "Which monster do you want [0-99] ? ");
101634597Sbostic Whichmonster = (int) infloat();
101734597Sbostic Whichmonster = MAX(0, MIN(99, Whichmonster));
101834597Sbostic longjmp(Fightenv, 0);
101934597Sbostic /*NOTREACHED*/
102034597Sbostic }
102134597Sbostic break;
102234597Sbostic }
102334597Sbostic }
102434597Sbostic /**/
102534597Sbostic /************************************************************************
102634597Sbostic /
102734597Sbostic / FUNCTION NAME: callmonster()
102834597Sbostic /
102934597Sbostic / FUNCTION: read monster from file, and fill structure
103034597Sbostic /
103134597Sbostic / AUTHOR: E. A. Estes, 2/25/86
103234597Sbostic /
103334597Sbostic / ARGUMENTS:
103434597Sbostic / int which - which monster to call
103534597Sbostic /
103634597Sbostic / RETURN VALUE: none
103734597Sbostic /
103834597Sbostic / MODULES CALLED: truncstring(), fread(), fseek(), floor(), drandom(),
103934597Sbostic / strcpy()
104034597Sbostic /
104134597Sbostic / GLOBAL INPUTS: Curmonster, Circle, Player, *Monstfp
104234597Sbostic /
104334597Sbostic / GLOBAL OUTPUTS: Curmonster, Player, *Enemyname
104434597Sbostic /
104534597Sbostic / DESCRIPTION:
104634597Sbostic / Read specified monster from monster database and fill up
104734597Sbostic / current monster structure.
104834597Sbostic / Adjust statistics based upon current size.
104934597Sbostic / Handle some special monsters.
105034597Sbostic /
105134597Sbostic /************************************************************************/
105234597Sbostic
callmonster(which)105334597Sbostic callmonster(which)
105434597Sbostic int which;
105534597Sbostic {
105634597Sbostic struct monster Othermonster; /* to find a name for mimics */
105734597Sbostic
105834597Sbostic which = MIN(which, 99); /* make sure within range */
105934597Sbostic
106034597Sbostic /* fill structure */
106134597Sbostic fseek(Monstfp, (long) which * (long) SZ_MONSTERSTRUCT, 0);
106234597Sbostic fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
106334597Sbostic
106434597Sbostic /* handle some special monsters */
106534597Sbostic if (Curmonster.m_type == SM_MODNAR)
106634597Sbostic {
106734597Sbostic if (Player.p_specialtype < SC_COUNCIL)
106834597Sbostic /* randomize some stats */
106934597Sbostic {
107034597Sbostic Curmonster.m_strength *= drandom() + 0.5;
107134597Sbostic Curmonster.m_brains *= drandom() + 0.5;
107234597Sbostic Curmonster.m_speed *= drandom() + 0.5;
107334597Sbostic Curmonster.m_energy *= drandom() + 0.5;
107434597Sbostic Curmonster.m_experience *= drandom() + 0.5;
107534597Sbostic Curmonster.m_treasuretype =
107634597Sbostic (int) ROLL(0.0, (double) Curmonster.m_treasuretype);
107734597Sbostic }
107834597Sbostic else
107934597Sbostic /* make Modnar into Morgoth */
108034597Sbostic {
108134597Sbostic strcpy(Curmonster.m_name, "Morgoth");
108234597Sbostic Curmonster.m_strength = drandom() * (Player.p_maxenergy + Player.p_shield) / 1.4
108334597Sbostic + drandom() * (Player.p_maxenergy + Player.p_shield) / 1.5;
108434597Sbostic Curmonster.m_brains = Player.p_brains;
108534597Sbostic Curmonster.m_energy = Player.p_might * 30.0;
108634597Sbostic Curmonster.m_type = SM_MORGOTH;
108734597Sbostic Curmonster.m_speed = Player.p_speed * 1.1
108834597Sbostic + (Player.p_specialtype == SC_EXVALAR) ? Player.p_speed : 0.0;
108934597Sbostic Curmonster.m_flock = 0.0;
109034597Sbostic Curmonster.m_treasuretype = 0;
109134597Sbostic Curmonster.m_experience = 0.0;
109234597Sbostic }
109334597Sbostic }
109434597Sbostic else if (Curmonster.m_type == SM_MIMIC)
109534597Sbostic /* pick another name */
109634597Sbostic {
109734597Sbostic which = (int) ROLL(0.0, 100.0);
109834597Sbostic fseek(Monstfp, (long) which * (long) SZ_MONSTERSTRUCT, 0);
109934597Sbostic fread(&Othermonster, SZ_MONSTERSTRUCT, 1, Monstfp);
110034597Sbostic strcpy(Curmonster.m_name, Othermonster.m_name);
110134597Sbostic }
110234597Sbostic
110334597Sbostic truncstring(Curmonster.m_name);
110434597Sbostic
110534597Sbostic if (Curmonster.m_type != SM_MORGOTH)
110634597Sbostic /* adjust stats based on which circle player is in */
110734597Sbostic {
110834597Sbostic Curmonster.m_strength *= (1.0 + Circle / 2.0);
110934597Sbostic Curmonster.m_brains *= Circle;
111034597Sbostic Curmonster.m_speed += Circle * 1.e-9;
111134597Sbostic Curmonster.m_energy *= Circle;
111234597Sbostic Curmonster.m_experience *= Circle;
111334597Sbostic }
111434597Sbostic
111534597Sbostic if (Player.p_blindness)
111634597Sbostic /* cannot see monster if blind */
111734597Sbostic Enemyname = "A monster";
111834597Sbostic else
111934597Sbostic Enemyname = Curmonster.m_name;
112034597Sbostic
112134597Sbostic if (Player.p_speed <= 0.0)
112234597Sbostic /* make Player.p_speed positive */
112334597Sbostic {
112434597Sbostic Curmonster.m_speed += -Player.p_speed;
112534597Sbostic Player.p_speed = 1.0;
112634597Sbostic }
112734597Sbostic
112834597Sbostic /* fill up the rest of the structure */
112934597Sbostic Curmonster.m_o_strength = Curmonster.m_strength;
113034597Sbostic Curmonster.m_o_speed = Curmonster.m_maxspeed = Curmonster.m_speed;
113134597Sbostic Curmonster.m_o_energy = Curmonster.m_energy;
113234597Sbostic Curmonster.m_melee = Curmonster.m_skirmish = 0.0;
113334597Sbostic }
113434597Sbostic /**/
113534597Sbostic /************************************************************************
113634597Sbostic /
113734597Sbostic / FUNCTION NAME: awardtreasure()
113834597Sbostic /
113934597Sbostic / FUNCTION: select a treasure
114034597Sbostic /
114134597Sbostic / AUTHOR: E. A. Estes, 12/4/85
114234597Sbostic /
114334597Sbostic / ARGUMENTS: none
114434597Sbostic /
114534597Sbostic / RETURN VALUE: none
114634597Sbostic /
114734597Sbostic / MODULES CALLED: pickmonster(), collecttaxes(), more(), cursedtreasure(),
114834597Sbostic / floor(), wmove(), drandom(), sscanf(), printw(), altercoordinates(),
114934597Sbostic / longjmp(), infloat(), waddstr(), getanswer(), getstring(), wclrtobot()
115034597Sbostic /
115134597Sbostic / GLOBAL INPUTS: Somebetter[], Curmonster, Whichmonster, Circle, Player,
115234597Sbostic / *stdscr, Databuf[], *Statptr, Fightenv[]
115334597Sbostic /
115434597Sbostic / GLOBAL OUTPUTS: Whichmonster, Shield, Player
115534597Sbostic /
115634597Sbostic / DESCRIPTION:
115734597Sbostic / Roll up a treasure based upon monster type and size, and
115834597Sbostic / certain player statistics.
115934597Sbostic / Handle cursed treasure.
116034597Sbostic /
116134597Sbostic /************************************************************************/
116234597Sbostic
awardtreasure()116334597Sbostic awardtreasure()
116434597Sbostic {
116534597Sbostic register int whichtreasure; /* calculated treasure to grant */
116634597Sbostic int temp; /* temporary */
116734597Sbostic int ch; /* input */
116834597Sbostic double treasuretype; /* monster's treasure type */
116934597Sbostic double gold = 0.0; /* gold awarded */
117034597Sbostic double gems = 0.0; /* gems awarded */
117134597Sbostic double dtemp; /* for temporary calculations */
117234597Sbostic
117334597Sbostic whichtreasure = (int) ROLL(1.0, 3.0); /* pick a treasure */
117434597Sbostic treasuretype = (double) Curmonster.m_treasuretype;
117534597Sbostic
117634597Sbostic move(4, 0);
117734597Sbostic clrtobot();
117834597Sbostic move(6, 0);
117934597Sbostic
118034597Sbostic if (drandom() > 0.65)
118134597Sbostic /* gold and gems */
118234597Sbostic {
118334597Sbostic if (Curmonster.m_treasuretype > 7)
118434597Sbostic /* gems */
118534597Sbostic {
118634597Sbostic gems = ROLL(1.0, (treasuretype - 7.0)
118734597Sbostic * (treasuretype - 7.0) * (Circle - 1.0) / 4.0);
118834597Sbostic printw("You have discovered %.0f gems!", gems);
118934597Sbostic }
119034597Sbostic else
119134597Sbostic /* gold */
119234597Sbostic {
119334597Sbostic gold = ROLL(treasuretype * 10.0, treasuretype
119434597Sbostic * treasuretype * 10.0 * (Circle - 1.0));
119534597Sbostic printw("You have found %.0f gold pieces.", gold);
119634597Sbostic }
119734597Sbostic
119834597Sbostic addstr(" Do you want to pick them up ? ");
119934597Sbostic ch = getanswer("NY", FALSE);
120034597Sbostic addstr("\n\n");
120134597Sbostic
120234597Sbostic if (ch == 'Y')
120334597Sbostic if (drandom() < treasuretype / 35.0 + 0.04)
120434597Sbostic /* cursed */
120534597Sbostic {
120634597Sbostic addstr("They were cursed!\n");
120734597Sbostic cursedtreasure();
120834597Sbostic }
120934597Sbostic else
121034597Sbostic collecttaxes(gold, gems);
121134597Sbostic
121234597Sbostic return;
121334597Sbostic }
121434597Sbostic else
121534597Sbostic /* other treasures */
121634597Sbostic {
121734597Sbostic addstr("You have found some treasure. Do you want to inspect it ? ");
121834597Sbostic ch = getanswer("NY", FALSE);
121934597Sbostic addstr("\n\n");
122034597Sbostic
122134597Sbostic if (ch != 'Y')
122234597Sbostic return;
122334597Sbostic else
122434597Sbostic if (drandom() < 0.08 && Curmonster.m_treasuretype != 4)
122534597Sbostic {
122634597Sbostic addstr("It was cursed!\n");
122734597Sbostic cursedtreasure();
122834597Sbostic return;
122934597Sbostic }
123034597Sbostic else
123134597Sbostic switch (Curmonster.m_treasuretype)
123234597Sbostic {
123334597Sbostic case 1: /* treasure type 1 */
123434597Sbostic switch (whichtreasure)
123534597Sbostic {
123634597Sbostic case 1:
123734597Sbostic addstr("You've discovered a power booster!\n");
123834597Sbostic Player.p_mana += ROLL(Circle * 4.0, Circle * 30.0);
123934597Sbostic break;
124034597Sbostic
124134597Sbostic case 2:
124234597Sbostic addstr("You have encountered a druid.\n");
124334597Sbostic Player.p_experience +=
124434597Sbostic ROLL(0.0, 2000.0 + Circle * 400.0);
124534597Sbostic break;
124634597Sbostic
124734597Sbostic case 3:
124834597Sbostic addstr("You have found a holy orb.\n");
124934597Sbostic Player.p_sin = MAX(0.0, Player.p_sin - 0.25);
125034597Sbostic break;
125134597Sbostic }
125234597Sbostic break;
125334597Sbostic /* end treasure type 1 */
125434597Sbostic
125534597Sbostic case 2: /* treasure type 2 */
125634597Sbostic switch (whichtreasure)
125734597Sbostic {
125834597Sbostic case 1:
125934597Sbostic addstr("You have found an amulet.\n");
126034597Sbostic ++Player.p_amulets;
126134597Sbostic break;
126234597Sbostic
126334597Sbostic case 2:
126434597Sbostic addstr("You've found some holy water!\n");
126534597Sbostic ++Player.p_holywater;
126634597Sbostic break;
126734597Sbostic
126834597Sbostic case 3:
126934597Sbostic addstr("You've met a hermit!\n");
127034597Sbostic Player.p_sin *= 0.75;
127134597Sbostic Player.p_mana += 12.0 * Circle;
127234597Sbostic break;
127334597Sbostic }
127434597Sbostic break;
127534597Sbostic /* end treasure type 2 */
127634597Sbostic
127734597Sbostic case 3: /* treasure type 3 */
127834597Sbostic switch (whichtreasure)
127934597Sbostic {
128034597Sbostic case 1:
128134597Sbostic dtemp = ROLL(7.0, 30.0 + Circle / 10.0);
128234597Sbostic printw("You've found a +%.0f shield!\n", dtemp);
128334597Sbostic if (dtemp >= Player.p_shield)
128434597Sbostic Player.p_shield = dtemp;
128534597Sbostic else
128634597Sbostic SOMEBETTER();
128734597Sbostic break;
128834597Sbostic
128934597Sbostic case 2:
129034597Sbostic addstr("You have rescued a virgin. Will you be honorable ? ");
129134597Sbostic ch = getanswer("NY", FALSE);
129234597Sbostic addstr("\n\n");
129334597Sbostic if (ch == 'Y')
129434597Sbostic Player.p_virgin = TRUE;
129534597Sbostic else
129634597Sbostic {
129734597Sbostic Player.p_experience += 2000.0 * Circle;
129834597Sbostic ++Player.p_sin;
129934597Sbostic }
130034597Sbostic break;
130134597Sbostic
130234597Sbostic case 3:
130334597Sbostic addstr("You've discovered some athelas!\n");
130434597Sbostic --Player.p_poison;
130534597Sbostic break;
130634597Sbostic }
130734597Sbostic break;
130834597Sbostic /* end treasure type 3 */
130934597Sbostic
131034597Sbostic case 4: /* treasure type 4 */
131134597Sbostic addstr("You've found a scroll. Will you read it ? ");
131234597Sbostic ch = getanswer("NY", FALSE);
131334597Sbostic addstr("\n\n");
131434597Sbostic
131534597Sbostic if (ch == 'Y')
131634597Sbostic switch ((int) ROLL(1, 6))
131734597Sbostic {
131834597Sbostic case 1:
131934597Sbostic addstr("It throws up a shield for you next monster.\n");
132034597Sbostic getyx(stdscr, whichtreasure, ch);
132134597Sbostic more(whichtreasure);
132234597Sbostic Shield =
132334597Sbostic (Player.p_maxenergy + Player.p_energy) * 5.5 + Circle * 50.0;
132434597Sbostic Whichmonster = pickmonster();
132534597Sbostic longjmp(Fightenv, 0);
132634597Sbostic /*NOTREACHED*/
132734597Sbostic
132834597Sbostic case 2:
132934597Sbostic addstr("It makes you invisible for you next monster.\n");
133034597Sbostic getyx(stdscr, whichtreasure, ch);
133134597Sbostic more(whichtreasure);
133234597Sbostic Player.p_speed = 1e6;
133334597Sbostic Whichmonster = pickmonster();
133434597Sbostic longjmp(Fightenv, 0);
133534597Sbostic /*NOTREACHED*/
133634597Sbostic
133734597Sbostic case 3:
133834597Sbostic addstr("It increases your strength ten fold to fight your next monster.\n");
133934597Sbostic getyx(stdscr, whichtreasure, ch);
134034597Sbostic more(whichtreasure);
134134597Sbostic Player.p_might *= 10.0;
134234597Sbostic Whichmonster = pickmonster();
134334597Sbostic longjmp(Fightenv, 0);
134434597Sbostic /*NOTREACHED*/
134534597Sbostic
134634597Sbostic case 4:
134734597Sbostic addstr("It is a general knowledge scroll.\n");
134834597Sbostic Player.p_brains += ROLL(2.0, Circle);
134934597Sbostic Player.p_magiclvl += ROLL(1.0, Circle / 2.0);
135034597Sbostic break;
135134597Sbostic
135234597Sbostic case 5:
135334597Sbostic addstr("It tells you how to pick your next monster.\n");
135434597Sbostic addstr("Which monster do you want [0-99] ? ");
135534597Sbostic Whichmonster = (int) infloat();
135634597Sbostic Whichmonster = MIN(99, MAX(0, Whichmonster));
135734597Sbostic longjmp(Fightenv, 0);
135834597Sbostic
135934597Sbostic case 6:
136034597Sbostic addstr("It was cursed!\n");
136134597Sbostic cursedtreasure();
136234597Sbostic break;
136334597Sbostic }
136434597Sbostic break;
136534597Sbostic /* end treasure type 4 */
136634597Sbostic
136734597Sbostic case 5: /* treasure type 5 */
136834597Sbostic switch (whichtreasure)
136934597Sbostic {
137034597Sbostic case 1:
137134597Sbostic dtemp = ROLL(Circle / 4.0 + 5.0, Circle / 2.0 + 9.0);
137234597Sbostic printw("You've discovered a +%.0f dagger.\n", dtemp);
137334597Sbostic if (dtemp >= Player.p_sword)
137434597Sbostic Player.p_sword = dtemp;
137534597Sbostic else
137634597Sbostic SOMEBETTER();
137734597Sbostic break;
137834597Sbostic
137934597Sbostic case 2:
138034597Sbostic dtemp = ROLL(7.5 + Circle * 3.0, Circle * 2.0 + 160.0);
138134597Sbostic printw("You have found some +%.0f armour!\n", dtemp);
138234597Sbostic if (dtemp >= Player.p_shield)
138334597Sbostic Player.p_shield = dtemp;
138434597Sbostic else
138534597Sbostic SOMEBETTER();
138634597Sbostic break;
138734597Sbostic
138834597Sbostic case 3:
138934597Sbostic addstr("You've found a tablet.\n");
139034597Sbostic Player.p_brains += 4.5 * Circle;
139134597Sbostic break;
139234597Sbostic }
139334597Sbostic break;
139434597Sbostic /* end treasure type 5 */
139534597Sbostic
139634597Sbostic case 6: /* treasure type 6 */
139734597Sbostic switch (whichtreasure)
139834597Sbostic {
139934597Sbostic case 1:
140034597Sbostic addstr("You've found a priest.\n");
140134597Sbostic Player.p_energy = Player.p_maxenergy + Player.p_shield;
140234597Sbostic Player.p_sin /= 2.0;
140334597Sbostic Player.p_mana += 24.0 * Circle;
140434597Sbostic Player.p_brains += Circle;
140534597Sbostic break;
140634597Sbostic
140734597Sbostic case 2:
140834597Sbostic addstr("You have come upon Robin Hood!\n");
140934597Sbostic Player.p_shield += Circle * 2.0;
141034597Sbostic Player.p_strength += Circle / 2.5 + 1.0;
141134597Sbostic break;
141234597Sbostic
141334597Sbostic case 3:
141434597Sbostic dtemp = ROLL(2.0 + Circle / 4.0, Circle / 1.2 + 10.0);
141534597Sbostic printw("You have found a +%.0f axe!\n", dtemp);
141634597Sbostic if (dtemp >= Player.p_sword)
141734597Sbostic Player.p_sword = dtemp;
141834597Sbostic else
141934597Sbostic SOMEBETTER();
142034597Sbostic break;
142134597Sbostic }
142234597Sbostic break;
142334597Sbostic /* end treasure type 6 */
142434597Sbostic
142534597Sbostic case 7: /* treasure type 7 */
142634597Sbostic switch (whichtreasure)
142734597Sbostic {
142834597Sbostic case 1:
142934597Sbostic addstr("You've discovered a charm!\n");
143034597Sbostic ++Player.p_charms;
143134597Sbostic break;
143234597Sbostic
143334597Sbostic case 2:
143434597Sbostic addstr("You have encountered Merlyn!\n");
143534597Sbostic Player.p_brains += Circle + 5.0;
143634597Sbostic Player.p_magiclvl += Circle / 3.0 + 5.0;
143734597Sbostic Player.p_mana += Circle * 10.0;
143834597Sbostic break;
143934597Sbostic
144034597Sbostic case 3:
144134597Sbostic dtemp = ROLL(5.0 + Circle / 3.0, Circle / 1.5 + 20.0);
144234597Sbostic printw("You have found a +%.0f war hammer!\n", dtemp);
144334597Sbostic if (dtemp >= Player.p_sword)
144434597Sbostic Player.p_sword = dtemp;
144534597Sbostic else
144634597Sbostic SOMEBETTER();
144734597Sbostic break;
144834597Sbostic }
144934597Sbostic break;
145034597Sbostic /* end treasure type 7 */
145134597Sbostic
145234597Sbostic case 8: /* treasure type 8 */
145334597Sbostic switch (whichtreasure)
145434597Sbostic {
145534597Sbostic case 1:
145634597Sbostic addstr("You have found a healing potion.\n");
145734597Sbostic Player.p_poison = MIN(-2.0, Player.p_poison - 2.0);
145834597Sbostic break;
145934597Sbostic
146034597Sbostic case 2:
146134597Sbostic addstr("You have discovered a transporter. Do you wish to go anywhere ? ");
146234597Sbostic ch = getanswer("NY", FALSE);
146334597Sbostic addstr("\n\n");
146434597Sbostic if (ch == 'Y')
146534597Sbostic {
146634597Sbostic double x, y;
146734597Sbostic
146834597Sbostic addstr("X Y Coordinates ? ");
146934597Sbostic getstring(Databuf, SZ_DATABUF);
147034613Sbostic sscanf(Databuf, "%lf %lf", &x, &y);
147134597Sbostic altercoordinates(x, y, A_FORCED);
147234597Sbostic }
147334597Sbostic break;
147434597Sbostic
147534597Sbostic case 3:
147634597Sbostic dtemp = ROLL(10.0 + Circle / 1.2, Circle * 3.0 + 30.0);
147734597Sbostic printw("You've found a +%.0f sword!\n", dtemp);
147834597Sbostic if (dtemp >= Player.p_sword)
147934597Sbostic Player.p_sword = dtemp;
148034597Sbostic else
148134597Sbostic SOMEBETTER();
148234597Sbostic break;
148334597Sbostic }
148434597Sbostic break;
148534597Sbostic /* end treasure type 8 */
148634597Sbostic
148734597Sbostic case 10:
148834597Sbostic case 11:
148934597Sbostic case 12:
149034597Sbostic case 13: /* treasure types 10 - 13 */
149134597Sbostic if (drandom() < 0.33)
149234597Sbostic {
149334597Sbostic if (Curmonster.m_treasuretype == 10)
149434597Sbostic {
149534597Sbostic addstr("You've found a pair of elven boots!\n");
149634597Sbostic Player.p_quickness += 2.0;
149734597Sbostic break;
149834597Sbostic }
149934597Sbostic else if (Curmonster.m_treasuretype == 11
150034597Sbostic && !Player.p_palantir)
150134597Sbostic {
150234597Sbostic addstr("You've acquired Saruman's palantir.\n");
150334597Sbostic Player.p_palantir = TRUE;
150434597Sbostic break;
150534597Sbostic }
150634597Sbostic else if (Player.p_ring.ring_type == R_NONE
150734597Sbostic && Player.p_specialtype < SC_COUNCIL
150834597Sbostic && (Curmonster.m_treasuretype == 12
150934597Sbostic || Curmonster.m_treasuretype == 13))
151034597Sbostic /* roll up a ring */
151134597Sbostic {
151234597Sbostic if (drandom() < 0.8)
151334597Sbostic /* regular rings */
151434597Sbostic {
151534597Sbostic if (Curmonster.m_treasuretype == 12)
151634597Sbostic {
151734597Sbostic whichtreasure = R_NAZREG;
151834597Sbostic temp = 35;
151934597Sbostic }
152034597Sbostic else
152134597Sbostic {
152234597Sbostic whichtreasure = R_DLREG;
152334597Sbostic temp = 0;
152434597Sbostic }
152534597Sbostic }
152634597Sbostic else
152734597Sbostic /* bad rings */
152834597Sbostic {
152934597Sbostic whichtreasure = R_BAD;
153034597Sbostic temp = 15 + Statptr->c_ringduration + (int) ROLL(0,5);
153134597Sbostic }
153234597Sbostic
153334597Sbostic addstr("You've discovered a ring. Will you pick it up ? ");
153434597Sbostic ch = getanswer("NY", FALSE);
153534597Sbostic addstr("\n\n");
153634597Sbostic
153734597Sbostic if (ch == 'Y')
153834597Sbostic {
153934597Sbostic Player.p_ring.ring_type = whichtreasure;
154034597Sbostic Player.p_ring.ring_duration = temp;
154134597Sbostic }
154234597Sbostic
154334597Sbostic break;
154434597Sbostic }
154534597Sbostic }
154634597Sbostic /* end treasure types 10 - 13 */
154734597Sbostic /* fall through to treasure type 9 if no treasure from above */
154834597Sbostic
154934597Sbostic case 9: /* treasure type 9 */
155034597Sbostic switch (whichtreasure)
155134597Sbostic {
155234597Sbostic case 1:
155334597Sbostic if (Player.p_level <= 1000.0
155434597Sbostic && Player.p_crowns <= 3
155534597Sbostic && Player.p_level >= 10.0)
155634597Sbostic {
155734597Sbostic addstr("You have found a golden crown!\n");
155834597Sbostic ++Player.p_crowns;
155934597Sbostic break;
156034597Sbostic }
156134597Sbostic /* fall through otherwise */
156234597Sbostic
156334597Sbostic case 2:
156434597Sbostic addstr("You've been blessed!\n");
156534597Sbostic Player.p_blessing = TRUE;
156634597Sbostic Player.p_sin /= 3.0;
156734597Sbostic Player.p_energy = Player.p_maxenergy + Player.p_shield;
156834597Sbostic Player.p_mana += 100.0 * Circle;
156934597Sbostic break;
157034597Sbostic
157134597Sbostic case 3:
157234597Sbostic dtemp = ROLL(1.0, Circle / 5.0 + 5.0);
157334597Sbostic dtemp = MIN(dtemp, 99.0);
157434597Sbostic printw("You have discovered some +%.0f quicksilver!\n",dtemp);
157534597Sbostic if (dtemp >= Player.p_quksilver)
157634597Sbostic Player.p_quksilver = dtemp;
157734597Sbostic else
157834597Sbostic SOMEBETTER();
157934597Sbostic break;
158034597Sbostic }
158134597Sbostic break;
158234597Sbostic /* end treasure type 9 */
158334597Sbostic }
158434597Sbostic }
158534597Sbostic }
158634597Sbostic /**/
158734597Sbostic /************************************************************************
158834597Sbostic /
158934597Sbostic / FUNCTION NAME: cursedtreasure()
159034597Sbostic /
159134597Sbostic / FUNCTION: take care of cursed treasure
159234597Sbostic /
159334597Sbostic / AUTHOR: E. A. Estes, 12/4/85
159434597Sbostic /
159534597Sbostic / ARGUMENTS: none
159634597Sbostic /
159734597Sbostic / RETURN VALUE: none
159834597Sbostic /
159934597Sbostic / MODULES CALLED: waddstr()
160034597Sbostic /
160134597Sbostic / GLOBAL INPUTS: Player, *stdscr
160234597Sbostic /
160334597Sbostic / GLOBAL OUTPUTS: Player
160434597Sbostic /
160534597Sbostic / DESCRIPTION:
160634597Sbostic / Handle cursed treasure. Look for amulets and charms to save
160734597Sbostic / the player from the curse.
160834597Sbostic /
160934597Sbostic /************************************************************************/
161034597Sbostic
cursedtreasure()161134597Sbostic cursedtreasure()
161234597Sbostic {
161334597Sbostic if (Player.p_charms > 0)
161434597Sbostic {
161534597Sbostic addstr("But your charm saved you!\n");
161634597Sbostic --Player.p_charms;
161734597Sbostic }
161834597Sbostic else if (Player.p_amulets > 0)
161934597Sbostic {
162034597Sbostic addstr("But your amulet saved you!\n");
162134597Sbostic --Player.p_amulets;
162234597Sbostic }
162334597Sbostic else
162434597Sbostic {
162534597Sbostic Player.p_energy = (Player.p_maxenergy + Player.p_shield) / 10.0;
162634597Sbostic Player.p_poison += 0.25;
162734597Sbostic }
162834597Sbostic }
162934597Sbostic /**/
163034597Sbostic /************************************************************************
163134597Sbostic /
163234597Sbostic / FUNCTION NAME: scramblestats()
163334597Sbostic /
163434597Sbostic / FUNCTION: scramble some selected statistics
163534597Sbostic /
163634597Sbostic / AUTHOR: E. A. Estes, 12/4/85
163734597Sbostic /
163834597Sbostic / ARGUMENTS: none
163934597Sbostic /
164034597Sbostic / RETURN VALUE: none
164134597Sbostic /
164234597Sbostic / MODULES CALLED: floor(), drandom()
164334597Sbostic /
164434597Sbostic / GLOBAL INPUTS: Player
164534597Sbostic /
164634597Sbostic / GLOBAL OUTPUTS: Player
164734597Sbostic /
164834597Sbostic / DESCRIPTION:
164934597Sbostic / Swap a few player statistics randomly.
165034597Sbostic /
165134597Sbostic /************************************************************************/
165234597Sbostic
scramblestats()165334597Sbostic scramblestats()
165434597Sbostic {
165534597Sbostic double dbuf[6]; /* to put statistic in */
165634597Sbostic double dtemp1, dtemp2; /* for swapping values */
165734597Sbostic register int first, second; /* indices for swapping */
165834597Sbostic register double *dptr; /* pointer for filling and emptying buf[] */
165934597Sbostic
166034597Sbostic /* fill buffer */
166134597Sbostic dptr = &dbuf[0];
166234597Sbostic *dptr++ = Player.p_strength;
166334597Sbostic *dptr++ = Player.p_mana;
166434597Sbostic *dptr++ = Player.p_brains;
166534597Sbostic *dptr++ = Player.p_magiclvl;
166634597Sbostic *dptr++ = Player.p_energy;
166734597Sbostic *dptr = Player.p_sin;
166834597Sbostic
166934597Sbostic /* pick values to swap */
167034597Sbostic first = (int) ROLL(0, 5);
167134597Sbostic second = (int) ROLL(0, 5);
167234597Sbostic
167334597Sbostic /* swap values */
167434597Sbostic dptr = &dbuf[0];
167534597Sbostic dtemp1 = dptr[first];
167634597Sbostic /* this expression is split to prevent a compiler loop on some compilers */
167734597Sbostic dtemp2 = dptr[second];
167834597Sbostic dptr[first] = dtemp2;
167934597Sbostic dptr[second] = dtemp1;
168034597Sbostic
168134597Sbostic /* empty buffer */
168234597Sbostic Player.p_strength = *dptr++;
168334597Sbostic Player.p_mana = *dptr++;
168434597Sbostic Player.p_brains = *dptr++;
168534597Sbostic Player.p_magiclvl = *dptr++;
168634597Sbostic Player.p_energy = *dptr++;
168734597Sbostic Player.p_sin = *dptr;
168834597Sbostic }
1689