xref: /csrg-svn/games/phantasia/fight.c (revision 41446)
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