1*34598Sbostic /*
2*34598Sbostic  * interplayer.c - player to player routines for Phantasia
3*34598Sbostic  */
4*34598Sbostic 
5*34598Sbostic #include "include.h"
6*34598Sbostic 
7*34598Sbostic /************************************************************************
8*34598Sbostic /
9*34598Sbostic / FUNCTION NAME: checkbattle()
10*34598Sbostic /
11*34598Sbostic / FUNCTION: check to see if current player should battle another
12*34598Sbostic /
13*34598Sbostic / AUTHOR: E. A. Estes, 12/4/85
14*34598Sbostic /
15*34598Sbostic / ARGUMENTS: none
16*34598Sbostic /
17*34598Sbostic / RETURN VALUE: none
18*34598Sbostic /
19*34598Sbostic / MODULES CALLED: battleplayer(), fread(), fseek()
20*34598Sbostic /
21*34598Sbostic / GLOBAL INPUTS: Other, Users, Player, Fileloc, *Playersfp
22*34598Sbostic /
23*34598Sbostic / GLOBAL OUTPUTS: Users
24*34598Sbostic /
25*34598Sbostic / DESCRIPTION:
26*34598Sbostic /	Seach player file for a foe at the same coordinates as the
27*34598Sbostic /	current player.
28*34598Sbostic /	Also update user count.
29*34598Sbostic /
30*34598Sbostic /************************************************************************/
31*34598Sbostic 
32*34598Sbostic checkbattle()
33*34598Sbostic {
34*34598Sbostic long	foeloc = 0L;		/* location in file of person to fight */
35*34598Sbostic 
36*34598Sbostic     Users = 0;
37*34598Sbostic     fseek(Playersfp, 0L, 0);
38*34598Sbostic 
39*34598Sbostic     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
40*34598Sbostic 	{
41*34598Sbostic 	if (Other.p_status != S_OFF
42*34598Sbostic 	    && Other.p_status != S_NOTUSED
43*34598Sbostic 	    && Other.p_status != S_HUNGUP
44*34598Sbostic 	    && (Other.p_status != S_CLOAKED || Other.p_specialtype != SC_VALAR))
45*34598Sbostic 	    /* player is on and not a cloaked valar */
46*34598Sbostic 	    {
47*34598Sbostic 	    ++Users;
48*34598Sbostic 
49*34598Sbostic 	    if (Player.p_x == Other.p_x
50*34598Sbostic 		&& Player.p_y == Other.p_y
51*34598Sbostic 		/* same coordinates */
52*34598Sbostic 		&& foeloc != Fileloc
53*34598Sbostic 		/* not self */
54*34598Sbostic 		&& Player.p_status == S_PLAYING
55*34598Sbostic 		&& (Other.p_status == S_PLAYING || Other.p_status == S_INBATTLE)
56*34598Sbostic 		/* both are playing */
57*34598Sbostic 		&& Other.p_specialtype != SC_VALAR
58*34598Sbostic 		&& Player.p_specialtype != SC_VALAR)
59*34598Sbostic 		/* neither is valar */
60*34598Sbostic 		{
61*34598Sbostic 		battleplayer(foeloc);
62*34598Sbostic 		return;
63*34598Sbostic 		}
64*34598Sbostic 	    }
65*34598Sbostic 	foeloc += SZ_PLAYERSTRUCT;
66*34598Sbostic 	}
67*34598Sbostic }
68*34598Sbostic /**/
69*34598Sbostic /************************************************************************
70*34598Sbostic /
71*34598Sbostic / FUNCTION NAME: battleplayer()
72*34598Sbostic /
73*34598Sbostic / FUNCTION: inter-terminal battle with another player
74*34598Sbostic /
75*34598Sbostic / AUTHOR: E. A. Estes, 2/15/86
76*34598Sbostic /
77*34598Sbostic / ARGUMENTS:
78*34598Sbostic /	long foeplace - location in player file of person to battle
79*34598Sbostic /
80*34598Sbostic / RETURN VALUE: none
81*34598Sbostic /
82*34598Sbostic / MODULES CALLED: readrecord(), readmessage(), writerecord(), collecttaxes(),
83*34598Sbostic /	displaystats(), fabs(), more(), death(), sleep(), wmove(), waddch(), printw(),
84*34598Sbostic /	myturn(), altercoordinates(), waddstr(), wrefresh(), mvprintw(),
85*34598Sbostic /	getanswer(), wclrtoeol(), wclrtobot()
86*34598Sbostic /
87*34598Sbostic / GLOBAL INPUTS: Foestrikes, LINES, Lines, Other, Shield, Player, *stdscr,
88*34598Sbostic /	Fileloc, *Enemyname
89*34598Sbostic /
90*34598Sbostic / GLOBAL OUTPUTS: Foestrikes, Lines, Shield, Player, Luckout, *Enemyname
91*34598Sbostic /
92*34598Sbostic / DESCRIPTION:
93*34598Sbostic /	Inter-terminal battle is a very fragile and slightly klugy thing.
94*34598Sbostic /	At any time, one player is master and the other is slave.
95*34598Sbostic /	We pick who is master first by speed and level.  After that,
96*34598Sbostic /	the slave waits for the master to relinquish its turn, and
97*34598Sbostic /	the slave becomes master, and so on.
98*34598Sbostic /
99*34598Sbostic /	The items in the player structure which control the handshake are:
100*34598Sbostic /	    p_tampered:
101*34598Sbostic /		master increments this to relinquish control
102*34598Sbostic /	    p_istat:
103*34598Sbostic /		master sets this to specify particular action
104*34598Sbostic /	    p_1scratch:
105*34598Sbostic /		set to total damage inflicted so far; changes to indicate action
106*34598Sbostic /
107*34598Sbostic /************************************************************************/
108*34598Sbostic 
109*34598Sbostic battleplayer(foeplace)
110*34598Sbostic long	foeplace;
111*34598Sbostic {
112*34598Sbostic double	dtemp;		/* for temporary calculations */
113*34598Sbostic double	oldhits = 0.0;	/* previous damage inflicted by foe */
114*34598Sbostic register int	loop;	/* for timing out */
115*34598Sbostic int	ch;		/* input */
116*34598Sbostic short	oldtampered;	/* old value of foe's p_tampered */
117*34598Sbostic 
118*34598Sbostic     Lines = 8;
119*34598Sbostic     Luckout = FALSE;
120*34598Sbostic     mvaddstr(4, 0, "Preparing for battle!\n");
121*34598Sbostic     refresh();
122*34598Sbostic 
123*34598Sbostic #ifdef SYS5
124*34598Sbostic     flushinp();
125*34598Sbostic #endif
126*34598Sbostic 
127*34598Sbostic     /* set up variables, file, etc. */
128*34598Sbostic     Player.p_status = S_INBATTLE;
129*34598Sbostic     Shield = Player.p_energy;
130*34598Sbostic 
131*34598Sbostic     /* if p_tampered is not 0, someone else may try to change it (king, etc.) */
132*34598Sbostic     Player.p_tampered = oldtampered = 1;
133*34598Sbostic     Player.p_1scratch = 0.0;
134*34598Sbostic     Player.p_istat = I_OFF;
135*34598Sbostic 
136*34598Sbostic     readrecord(&Other, foeplace);
137*34598Sbostic     if (fabs(Player.p_level - Other.p_level) > 20.0)
138*34598Sbostic 	/* see if players are greatly mismatched */
139*34598Sbostic 	{
140*34598Sbostic 	dtemp = (Player.p_level - Other.p_level) / MAX(Player.p_level, Other.p_level);
141*34598Sbostic 	if (dtemp < -0.5)
142*34598Sbostic 	    /* foe outweighs this one */
143*34598Sbostic 	    Player.p_speed *= 2.0;
144*34598Sbostic 	}
145*34598Sbostic 
146*34598Sbostic     writerecord(&Player, Fileloc);		/* write out all our info */
147*34598Sbostic 
148*34598Sbostic     if (Player.p_blindness)
149*34598Sbostic 	Enemyname = "someone";
150*34598Sbostic     else
151*34598Sbostic 	Enemyname = Other.p_name;
152*34598Sbostic 
153*34598Sbostic     mvprintw(6, 0, "You have encountered %s   Level: %.0f\n", Enemyname, Other.p_level);
154*34598Sbostic     refresh();
155*34598Sbostic 
156*34598Sbostic     for (loop = 0; Other.p_status != S_INBATTLE && loop < 30; ++loop)
157*34598Sbostic 	/* wait for foe to respond */
158*34598Sbostic 	{
159*34598Sbostic 	readrecord(&Other, foeplace);
160*34598Sbostic 	sleep(1);
161*34598Sbostic 	}
162*34598Sbostic 
163*34598Sbostic     if (Other.p_status != S_INBATTLE)
164*34598Sbostic 	/* foe did not respond */
165*34598Sbostic 	{
166*34598Sbostic 	mvprintw(5, 0, "%s is not responding.\n", Enemyname);
167*34598Sbostic 	goto LEAVE;
168*34598Sbostic 	}
169*34598Sbostic     /* else, we are ready to battle */
170*34598Sbostic 
171*34598Sbostic     move(4, 0);
172*34598Sbostic     clrtoeol();
173*34598Sbostic 
174*34598Sbostic     /*
175*34598Sbostic      * determine who is first master
176*34598Sbostic      * if neither player is faster, check level
177*34598Sbostic      * if neither level is greater, battle is not allowed
178*34598Sbostic      * (this should never happen, but we have to handle it)
179*34598Sbostic      */
180*34598Sbostic     if (Player.p_speed > Other.p_speed)
181*34598Sbostic 	Foestrikes = FALSE;
182*34598Sbostic     else if (Other.p_speed > Player.p_speed)
183*34598Sbostic 	Foestrikes = TRUE;
184*34598Sbostic     else if (Player.p_level > Other.p_level)
185*34598Sbostic 	Foestrikes = FALSE;
186*34598Sbostic     else if (Other.p_level > Player.p_level)
187*34598Sbostic 	Foestrikes = TRUE;
188*34598Sbostic     else
189*34598Sbostic 	/* no one is faster */
190*34598Sbostic 	{
191*34598Sbostic 	printw("You can't fight %s yet.", Enemyname);
192*34598Sbostic 	goto LEAVE;
193*34598Sbostic 	}
194*34598Sbostic 
195*34598Sbostic     for (;;)
196*34598Sbostic 	{
197*34598Sbostic 	displaystats();
198*34598Sbostic 	readmessage();
199*34598Sbostic 	mvprintw(1, 26, "%20.0f", Shield);	/* overprint energy */
200*34598Sbostic 
201*34598Sbostic 	if (!Foestrikes)
202*34598Sbostic 	    /* take action against foe */
203*34598Sbostic 	    myturn();
204*34598Sbostic 	else
205*34598Sbostic 	    /* wait for foe to take action */
206*34598Sbostic 	    {
207*34598Sbostic 	    mvaddstr(4, 0, "Waiting...\n");
208*34598Sbostic 	    clrtoeol();
209*34598Sbostic 	    refresh();
210*34598Sbostic 
211*34598Sbostic 	    for (loop = 0; loop < 20; ++loop)
212*34598Sbostic 		/* wait for foe to act */
213*34598Sbostic 		{
214*34598Sbostic 		readrecord(&Other, foeplace);
215*34598Sbostic 		if (Other.p_1scratch != oldhits)
216*34598Sbostic 		    /* p_1scratch changes to indicate action */
217*34598Sbostic 		    break;
218*34598Sbostic 		else
219*34598Sbostic 		    /* wait and try again */
220*34598Sbostic 		    {
221*34598Sbostic 		    sleep(1);
222*34598Sbostic 		    addch('.');
223*34598Sbostic 		    refresh();
224*34598Sbostic 		    }
225*34598Sbostic 		}
226*34598Sbostic 
227*34598Sbostic 	    if (Other.p_1scratch == oldhits)
228*34598Sbostic 		{
229*34598Sbostic 		/* timeout */
230*34598Sbostic 		mvaddstr(22, 0, "Timeout: waiting for response.  Do you want to wait ? ");
231*34598Sbostic 		ch = getanswer("NY", FALSE);
232*34598Sbostic 		move(22, 0);
233*34598Sbostic 		clrtobot();
234*34598Sbostic 		if (ch == 'Y')
235*34598Sbostic 		    continue;
236*34598Sbostic 		else
237*34598Sbostic 		    break;
238*34598Sbostic 		}
239*34598Sbostic 	    else
240*34598Sbostic 		/* foe took action */
241*34598Sbostic 		{
242*34598Sbostic 		switch (Other.p_istat)
243*34598Sbostic 		    {
244*34598Sbostic 		    case I_RAN:		/* foe ran away */
245*34598Sbostic 			mvprintw(Lines++, 0, "%s ran away!", Enemyname);
246*34598Sbostic 			break;
247*34598Sbostic 
248*34598Sbostic 		    case I_STUCK:	/* foe tried to run, but couldn't */
249*34598Sbostic 			mvprintw(Lines++, 0, "%s tried to run away.", Enemyname);
250*34598Sbostic 			break;
251*34598Sbostic 
252*34598Sbostic 		    case I_BLEWIT:	/* foe tried to luckout, but didn't */
253*34598Sbostic 			mvprintw(Lines++, 0, "%s tried to luckout!", Enemyname);
254*34598Sbostic 			break;
255*34598Sbostic 
256*34598Sbostic 		    default:
257*34598Sbostic 			dtemp = Other.p_1scratch - oldhits;
258*34598Sbostic 			mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, dtemp);
259*34598Sbostic 			Shield -= dtemp;
260*34598Sbostic 			break;
261*34598Sbostic 		    }
262*34598Sbostic 
263*34598Sbostic 		oldhits = Other.p_1scratch;	/* keep track of old hits */
264*34598Sbostic 
265*34598Sbostic 		if (Other.p_tampered != oldtampered)
266*34598Sbostic 		    /* p_tampered changes to relinquish turn */
267*34598Sbostic 		    {
268*34598Sbostic 		    oldtampered = Other.p_tampered;
269*34598Sbostic 		    Foestrikes = FALSE;
270*34598Sbostic 		    }
271*34598Sbostic 		}
272*34598Sbostic 	    }
273*34598Sbostic 
274*34598Sbostic 	/* decide what happens next */
275*34598Sbostic 	refresh();
276*34598Sbostic 	if (Lines > LINES - 2)
277*34598Sbostic 	    {
278*34598Sbostic 	    more(Lines);
279*34598Sbostic 	    move(Lines = 8, 0);
280*34598Sbostic 	    clrtobot();
281*34598Sbostic 	    }
282*34598Sbostic 
283*34598Sbostic 	if (Other.p_istat == I_KILLED || Shield < 0.0)
284*34598Sbostic 	    /* we died */
285*34598Sbostic 	    {
286*34598Sbostic 	    Shield = -2.0;		/* insure this value is negative */
287*34598Sbostic 	    break;
288*34598Sbostic 	    }
289*34598Sbostic 
290*34598Sbostic 	if (Player.p_istat == I_KILLED)
291*34598Sbostic 	    /* we killed foe; award treasre */
292*34598Sbostic 	    {
293*34598Sbostic 	    mvprintw(Lines++, 0, "You killed %s!", Enemyname);
294*34598Sbostic 	    Player.p_experience += Other.p_experience;
295*34598Sbostic 	    Player.p_crowns += (Player.p_level < 1000.0) ? Other.p_crowns : 0;
296*34598Sbostic 	    Player.p_amulets += Other.p_amulets;
297*34598Sbostic 	    Player.p_charms += Other.p_charms;
298*34598Sbostic 	    collecttaxes(Other.p_gold, Other.p_gems);
299*34598Sbostic 	    Player.p_sword = MAX(Player.p_sword, Other.p_sword);
300*34598Sbostic 	    Player.p_shield = MAX(Player.p_shield, Other.p_shield);
301*34598Sbostic 	    Player.p_quksilver = MAX(Player.p_quksilver, Other.p_quksilver);
302*34598Sbostic 	    if (Other.p_virgin && !Player.p_virgin)
303*34598Sbostic 		{
304*34598Sbostic 		mvaddstr(Lines++, 0, "You have rescued a virgin.  Will you be honorable ? ");
305*34598Sbostic 		if ((ch = getanswer("YN", FALSE)) == 'Y')
306*34598Sbostic 		    Player.p_virgin = TRUE;
307*34598Sbostic 		else
308*34598Sbostic 		    {
309*34598Sbostic 		    ++Player.p_sin;
310*34598Sbostic 		    Player.p_experience += 8000.0;
311*34598Sbostic 		    }
312*34598Sbostic 		}
313*34598Sbostic 	    sleep(3);     		/* give other person time to die */
314*34598Sbostic 	    break;
315*34598Sbostic 	    }
316*34598Sbostic 	else if (Player.p_istat == I_RAN || Other.p_istat == I_RAN)
317*34598Sbostic 	    /* either player ran away */
318*34598Sbostic 	    break;
319*34598Sbostic 	}
320*34598Sbostic 
321*34598Sbostic LEAVE:
322*34598Sbostic     /* clean up things and leave */
323*34598Sbostic     writerecord(&Player, Fileloc);	/* update a final time */
324*34598Sbostic     altercoordinates(0.0, 0.0, A_NEAR);	/* move away from battle site */
325*34598Sbostic     Player.p_energy = Shield;		/* set energy to actual value */
326*34598Sbostic     Player.p_tampered = T_OFF;		/* clear p_tampered */
327*34598Sbostic 
328*34598Sbostic     more(Lines);			/* pause */
329*34598Sbostic 
330*34598Sbostic     move(4, 0);
331*34598Sbostic     clrtobot();				/* clear bottom area of screen */
332*34598Sbostic 
333*34598Sbostic     if (Player.p_energy < 0.0)
334*34598Sbostic 	/* we are dead */
335*34598Sbostic 	death("Interterminal battle");
336*34598Sbostic }
337*34598Sbostic /**/
338*34598Sbostic /************************************************************************
339*34598Sbostic /
340*34598Sbostic / FUNCTION NAME: myturn()
341*34598Sbostic /
342*34598Sbostic / FUNCTION: process players action against foe in battle
343*34598Sbostic /
344*34598Sbostic / AUTHOR: E. A. Estes, 2/7/86
345*34598Sbostic /
346*34598Sbostic / ARGUMENTS: none
347*34598Sbostic /
348*34598Sbostic / RETURN VALUE: none
349*34598Sbostic /
350*34598Sbostic / MODULES CALLED: writerecord(), inputoption(), floor(), wmove(), drandom(),
351*34598Sbostic /	waddstr(), wrefresh(), mvprintw(), wclrtoeol(), wclrtobot()
352*34598Sbostic /
353*34598Sbostic / GLOBAL INPUTS: Lines, Other, Player, *stdscr, Fileloc, Luckout,
354*34598Sbostic /	*Enemyname
355*34598Sbostic /
356*34598Sbostic / GLOBAL OUTPUTS: Foestrikes, Lines, Player, Luckout
357*34598Sbostic /
358*34598Sbostic / DESCRIPTION:
359*34598Sbostic /	Take action action against foe, and decide who is master
360*34598Sbostic /	for next iteration.
361*34598Sbostic /
362*34598Sbostic /************************************************************************/
363*34598Sbostic 
364*34598Sbostic myturn()
365*34598Sbostic {
366*34598Sbostic double	dtemp;		/* for temporary calculations */
367*34598Sbostic int	ch;		/* input */
368*34598Sbostic 
369*34598Sbostic     mvaddstr(7, 0, "1:Fight  2:Run Away!  3:Power Blast  ");
370*34598Sbostic     if (Luckout)
371*34598Sbostic 	clrtoeol();
372*34598Sbostic     else
373*34598Sbostic 	addstr("4:Luckout  ");
374*34598Sbostic 
375*34598Sbostic     ch = inputoption();
376*34598Sbostic     move(Lines = 8, 0);
377*34598Sbostic     clrtobot();
378*34598Sbostic 
379*34598Sbostic     switch (ch)
380*34598Sbostic 	{
381*34598Sbostic 	default:	/* fight */
382*34598Sbostic 	    dtemp = ROLL(2.0, Player.p_might);
383*34598Sbostic HIT:
384*34598Sbostic 	    mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, dtemp);
385*34598Sbostic 	    Player.p_sin += 0.5;
386*34598Sbostic 	    Player.p_1scratch += dtemp;
387*34598Sbostic 	    Player.p_istat = I_OFF;
388*34598Sbostic 	    break;
389*34598Sbostic 
390*34598Sbostic 	case '2':	/* run away */
391*34598Sbostic 	    Player.p_1scratch -= 1.0;	/* change this to indicate action */
392*34598Sbostic 	    if (drandom() > 0.25)
393*34598Sbostic 		{
394*34598Sbostic 		mvaddstr(Lines++, 0, "You got away!");
395*34598Sbostic 		Player.p_istat = I_RAN;
396*34598Sbostic 		}
397*34598Sbostic 	    else
398*34598Sbostic 		{
399*34598Sbostic 		mvprintw(Lines++, 0, "%s is still after you!", Enemyname);
400*34598Sbostic 		Player.p_istat = I_STUCK;
401*34598Sbostic 		}
402*34598Sbostic 	    break;
403*34598Sbostic 
404*34598Sbostic 	case '3':	/* power blast */
405*34598Sbostic 	    dtemp = MIN(Player.p_mana, Player.p_level * 5.0);
406*34598Sbostic 	    Player.p_mana -= dtemp;
407*34598Sbostic 	    dtemp *= (drandom() + 0.5) * Player.p_magiclvl * 0.2 + 2.0;
408*34598Sbostic 	    mvprintw(Lines++, 0, "You blasted %s !", Enemyname);
409*34598Sbostic 	    goto HIT;
410*34598Sbostic 
411*34598Sbostic 	case '4':	/* luckout */
412*34598Sbostic 	    if (Luckout || drandom() > 0.1)
413*34598Sbostic 		{
414*34598Sbostic 		if (Luckout)
415*34598Sbostic 		    mvaddstr(Lines++, 0, "You already tried that!");
416*34598Sbostic 		else
417*34598Sbostic 		    {
418*34598Sbostic 		    mvaddstr(Lines++, 0, "Not this time . . .");
419*34598Sbostic 		    Luckout = TRUE;
420*34598Sbostic 		    }
421*34598Sbostic 
422*34598Sbostic 		Player.p_1scratch -= 1.0;
423*34598Sbostic 		Player.p_istat = I_BLEWIT;
424*34598Sbostic 		}
425*34598Sbostic 	    else
426*34598Sbostic 		{
427*34598Sbostic 		mvaddstr(Lines++, 0, "You just lucked out!");
428*34598Sbostic 		Player.p_1scratch = Other.p_energy * 1.1;
429*34598Sbostic 		}
430*34598Sbostic 	    break;
431*34598Sbostic 	}
432*34598Sbostic 
433*34598Sbostic     refresh();
434*34598Sbostic     Player.p_1scratch = floor(Player.p_1scratch);	/* clean up any mess */
435*34598Sbostic 
436*34598Sbostic     if (Player.p_1scratch > Other.p_energy)
437*34598Sbostic 	Player.p_istat = I_KILLED;
438*34598Sbostic     else if (drandom() * Player.p_speed < drandom() * Other.p_speed)
439*34598Sbostic 	/* relinquish control */
440*34598Sbostic 	{
441*34598Sbostic 	++Player.p_tampered;
442*34598Sbostic 	Foestrikes = TRUE;
443*34598Sbostic 	}
444*34598Sbostic 
445*34598Sbostic     writerecord(&Player, Fileloc);			/* let foe know what we did */
446*34598Sbostic }
447*34598Sbostic /**/
448*34598Sbostic /************************************************************************
449*34598Sbostic /
450*34598Sbostic / FUNCTION NAME: checktampered()
451*34598Sbostic /
452*34598Sbostic / FUNCTION: check if current player has been tampered with
453*34598Sbostic /
454*34598Sbostic / AUTHOR: E. A. Estes, 12/4/85
455*34598Sbostic /
456*34598Sbostic / ARGUMENTS: none
457*34598Sbostic /
458*34598Sbostic / RETURN VALUE: none
459*34598Sbostic /
460*34598Sbostic / MODULES CALLED: readrecord(), fread(), fseek(), tampered(), writevoid()
461*34598Sbostic /
462*34598Sbostic / GLOBAL INPUTS: *Energyvoidfp, Other, Player, Fileloc, Enrgyvoid
463*34598Sbostic /
464*34598Sbostic / GLOBAL OUTPUTS: Enrgyvoid
465*34598Sbostic /
466*34598Sbostic / DESCRIPTION:
467*34598Sbostic /	Check for energy voids, holy grail, and tampering by other
468*34598Sbostic /	players.
469*34598Sbostic /
470*34598Sbostic /************************************************************************/
471*34598Sbostic 
472*34598Sbostic checktampered()
473*34598Sbostic {
474*34598Sbostic long	loc = 0L;		/* location in energy void file */
475*34598Sbostic 
476*34598Sbostic     /* first check for energy voids */
477*34598Sbostic     fseek(Energyvoidfp, 0L, 0);
478*34598Sbostic     while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
479*34598Sbostic 	if (Enrgyvoid.ev_active
480*34598Sbostic 	    && Enrgyvoid.ev_x == Player.p_x
481*34598Sbostic 	    && Enrgyvoid.ev_y == Player.p_y)
482*34598Sbostic 	    /* sitting on one */
483*34598Sbostic 	    {
484*34598Sbostic 	    if (loc > 0L)
485*34598Sbostic 		/* not the holy grail; inactivate energy void */
486*34598Sbostic 		{
487*34598Sbostic 		Enrgyvoid.ev_active = FALSE;
488*34598Sbostic 		writevoid(&Enrgyvoid, loc);
489*34598Sbostic 		tampered(T_NRGVOID, 0.0, 0.0);
490*34598Sbostic 		}
491*34598Sbostic 	    else if (Player.p_status != S_CLOAKED)
492*34598Sbostic 		/* holy grail */
493*34598Sbostic 		tampered(T_GRAIL, 0.0, 0.0);
494*34598Sbostic 	    break;
495*34598Sbostic 	    }
496*34598Sbostic 	else
497*34598Sbostic 	    loc += SZ_VOIDSTRUCT;
498*34598Sbostic 
499*34598Sbostic     /* now check for other things */
500*34598Sbostic     readrecord(&Other, Fileloc);
501*34598Sbostic     if (Other.p_tampered != T_OFF)
502*34598Sbostic 	tampered(Other.p_tampered, Other.p_1scratch, Other.p_2scratch);
503*34598Sbostic }
504*34598Sbostic /**/
505*34598Sbostic /************************************************************************
506*34598Sbostic /
507*34598Sbostic / FUNCTION NAME: tampered()
508*34598Sbostic /
509*34598Sbostic / FUNCTION: take care of tampering by other players
510*34598Sbostic /
511*34598Sbostic / AUTHOR: E. A. Estes, 12/4/85
512*34598Sbostic /
513*34598Sbostic / ARGUMENTS:
514*34598Sbostic /	int what - what type of tampering
515*34598Sbostic /	double arg1, arg2 - rest of tampering info
516*34598Sbostic /
517*34598Sbostic / RETURN VALUE: none
518*34598Sbostic /
519*34598Sbostic / MODULES CALLED: writerecord(), more(), fread(), death(), fseek(), sleep(),
520*34598Sbostic /	floor(), wmove(), waddch(), drandom(), printw(), altercoordinates(),
521*34598Sbostic /	waddstr(), wrefresh(), encounter(), writevoid()
522*34598Sbostic /
523*34598Sbostic / GLOBAL INPUTS: Other, Player, *stdscr, Enrgyvoid, *Playersfp
524*34598Sbostic /
525*34598Sbostic / GLOBAL OUTPUTS: Other, Player, Changed, Enrgyvoid
526*34598Sbostic /
527*34598Sbostic / DESCRIPTION:
528*34598Sbostic /	Take care of energy voids, holy grail, decree and intervention
529*34598Sbostic /	action on current player.
530*34598Sbostic /
531*34598Sbostic /************************************************************************/
532*34598Sbostic 
533*34598Sbostic tampered(what, arg1, arg2)
534*34598Sbostic int	what;
535*34598Sbostic double	arg1;
536*34598Sbostic double	arg2;
537*34598Sbostic {
538*34598Sbostic long	loc;			/* location in file of other players */
539*34598Sbostic 
540*34598Sbostic     Changed = TRUE;
541*34598Sbostic     move(4,0);
542*34598Sbostic 
543*34598Sbostic     Player.p_tampered = T_OFF;	/* no longer tampered with */
544*34598Sbostic 
545*34598Sbostic     switch (what)
546*34598Sbostic 	{
547*34598Sbostic 	case T_NRGVOID:
548*34598Sbostic 	    addstr("You've hit an energy void !\n");
549*34598Sbostic 	    Player.p_mana /= 3.0;
550*34598Sbostic 	    Player.p_energy /= 2.0;
551*34598Sbostic 	    Player.p_gold = floor(Player.p_gold/1.25) + 0.1;
552*34598Sbostic 	    altercoordinates(0.0, 0.0, A_NEAR);
553*34598Sbostic 	    break;
554*34598Sbostic 
555*34598Sbostic 	case T_TRANSPORT:
556*34598Sbostic 	    addstr("The king transported you !  ");
557*34598Sbostic 	    if (Player.p_charms > 0)
558*34598Sbostic 		{
559*34598Sbostic 		addstr("But your charm saved you. . .\n");
560*34598Sbostic 		--Player.p_charms;
561*34598Sbostic 		}
562*34598Sbostic 	    else
563*34598Sbostic 		{
564*34598Sbostic 		altercoordinates(0.0, 0.0, A_FAR);
565*34598Sbostic 		addch('\n');
566*34598Sbostic 		}
567*34598Sbostic 	    break;
568*34598Sbostic 
569*34598Sbostic 	case T_BESTOW:
570*34598Sbostic 	    printw("The king has bestowed %.0f gold pieces on you !\n", arg1);
571*34598Sbostic 	    Player.p_gold += arg1;
572*34598Sbostic 	    break;
573*34598Sbostic 
574*34598Sbostic 	case T_CURSED:
575*34598Sbostic 	    addstr("You've been cursed !  ");
576*34598Sbostic 	    if (Player.p_blessing)
577*34598Sbostic 		{
578*34598Sbostic 		addstr("But your blessing saved you. . .\n");
579*34598Sbostic 		Player.p_blessing = FALSE;
580*34598Sbostic 		}
581*34598Sbostic 	    else
582*34598Sbostic 		{
583*34598Sbostic 		addch('\n');
584*34598Sbostic 		Player.p_poison += 2.0;
585*34598Sbostic 		Player.p_energy = 10.0;
586*34598Sbostic 		Player.p_maxenergy  *= 0.95;
587*34598Sbostic 		Player.p_status = S_PLAYING;	/* no longer cloaked */
588*34598Sbostic 		}
589*34598Sbostic 	    break;
590*34598Sbostic 
591*34598Sbostic 	case T_VAPORIZED:
592*34598Sbostic 	    addstr("You have been vaporized!\n");
593*34598Sbostic 	    more(7);
594*34598Sbostic 	    death("Vaporization");
595*34598Sbostic 	    break;
596*34598Sbostic 
597*34598Sbostic 	case T_MONSTER:
598*34598Sbostic 	    addstr("The Valar zapped you with a monster!\n");
599*34598Sbostic 	    more(7);
600*34598Sbostic 	    encounter((int) arg1);
601*34598Sbostic 	    return;
602*34598Sbostic 
603*34598Sbostic 	case T_BLESSED:
604*34598Sbostic 	    addstr("The Valar has blessed you!\n");
605*34598Sbostic 	    Player.p_energy = (Player.p_maxenergy *= 1.05) + Player.p_shield;
606*34598Sbostic 	    Player.p_mana += 500.0;
607*34598Sbostic 	    Player.p_strength += 0.5;
608*34598Sbostic 	    Player.p_brains += 0.5;
609*34598Sbostic 	    Player.p_magiclvl += 0.5;
610*34598Sbostic 	    Player.p_poison = MIN(0.5, Player.p_poison);
611*34598Sbostic 	    break;
612*34598Sbostic 
613*34598Sbostic 	case T_RELOCATE:
614*34598Sbostic 	    addstr("You've been relocated. . .\n");
615*34598Sbostic 	    altercoordinates(arg1, arg2, A_FORCED);
616*34598Sbostic 	    break;
617*34598Sbostic 
618*34598Sbostic 	case T_HEAL:
619*34598Sbostic 	    addstr("You've been healed!\n");
620*34598Sbostic 	    Player.p_poison -=  0.25;
621*34598Sbostic 	    Player.p_energy = Player.p_maxenergy + Player.p_shield;
622*34598Sbostic 	    break;
623*34598Sbostic 
624*34598Sbostic 	case T_EXVALAR:
625*34598Sbostic 	    addstr("You are no longer Valar!\n");
626*34598Sbostic 	    Player.p_specialtype = SC_COUNCIL;
627*34598Sbostic 	    break;
628*34598Sbostic 
629*34598Sbostic 	case T_GRAIL:
630*34598Sbostic 	    addstr("You have found The Holy Grail!!\n");
631*34598Sbostic 	    if (Player.p_specialtype < SC_COUNCIL)
632*34598Sbostic 		/* must be council of wise to behold grail */
633*34598Sbostic 		{
634*34598Sbostic 		addstr("However, you are not experienced enough to behold it.\n");
635*34598Sbostic 		Player.p_sin *= Player.p_sin;
636*34598Sbostic 		Player.p_mana +=  1000;
637*34598Sbostic 		}
638*34598Sbostic 	    else if (Player.p_specialtype == SC_VALAR
639*34598Sbostic 		|| Player.p_specialtype == SC_EXVALAR)
640*34598Sbostic 		{
641*34598Sbostic 		addstr("You have made it to the position of Valar once already.\n");
642*34598Sbostic 		addstr("The Grail is of no more use to you now.\n");
643*34598Sbostic 		}
644*34598Sbostic 	    else
645*34598Sbostic 		{
646*34598Sbostic 		addstr("It is now time to see if you are worthy to behold it. . .\n");
647*34598Sbostic 		refresh();
648*34598Sbostic 		sleep(4);
649*34598Sbostic 
650*34598Sbostic 		if (drandom() / 2.0 < Player.p_sin)
651*34598Sbostic 		    {
652*34598Sbostic 		    addstr("You have failed!\n");
653*34598Sbostic 		    Player.p_strength =
654*34598Sbostic 		    Player.p_mana =
655*34598Sbostic 		    Player.p_energy =
656*34598Sbostic 		    Player.p_maxenergy =
657*34598Sbostic 		    Player.p_magiclvl =
658*34598Sbostic 		    Player.p_brains =
659*34598Sbostic 		    Player.p_experience =
660*34598Sbostic 		    Player.p_quickness = 1.0;
661*34598Sbostic 
662*34598Sbostic 		    altercoordinates(1.0, 1.0, A_FORCED);
663*34598Sbostic 		    Player.p_level = 0.0;
664*34598Sbostic 		    }
665*34598Sbostic 		else
666*34598Sbostic 		    {
667*34598Sbostic 		    addstr("You made to position of Valar!\n");
668*34598Sbostic 		    Player.p_specialtype = SC_VALAR;
669*34598Sbostic 		    Player.p_lives = 5;
670*34598Sbostic 		    fseek(Playersfp, 0L, 0);
671*34598Sbostic 		    loc = 0L;
672*34598Sbostic 		    while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
673*34598Sbostic 			/* search for existing valar */
674*34598Sbostic 			if (Other.p_specialtype == SC_VALAR
675*34598Sbostic 			    && Other.p_status != S_NOTUSED)
676*34598Sbostic 			    /* found old valar */
677*34598Sbostic 			    {
678*34598Sbostic 			    Other.p_tampered = T_EXVALAR;
679*34598Sbostic 			    writerecord(&Other, loc);
680*34598Sbostic 			    break;
681*34598Sbostic 			    }
682*34598Sbostic 			else
683*34598Sbostic 			    loc += SZ_PLAYERSTRUCT;
684*34598Sbostic 		    }
685*34598Sbostic 		}
686*34598Sbostic 
687*34598Sbostic 	    /* move grail to new location */
688*34598Sbostic 	    Enrgyvoid.ev_active = TRUE;
689*34598Sbostic 	    Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
690*34598Sbostic 	    Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
691*34598Sbostic 	    writevoid(&Enrgyvoid, 0L);
692*34598Sbostic 	    break;
693*34598Sbostic 	}
694*34598Sbostic     refresh();
695*34598Sbostic     sleep(2);
696*34598Sbostic }
697*34598Sbostic /**/
698*34598Sbostic /************************************************************************
699*34598Sbostic /
700*34598Sbostic / FUNCTION NAME: userlist()
701*34598Sbostic /
702*34598Sbostic / FUNCTION: print list of players and locations
703*34598Sbostic /
704*34598Sbostic / AUTHOR: E. A. Estes, 2/28/86
705*34598Sbostic /
706*34598Sbostic / ARGUMENTS:
707*34598Sbostic /	bool ingameflag - set if called while playing
708*34598Sbostic /
709*34598Sbostic / RETURN VALUE: none
710*34598Sbostic /
711*34598Sbostic / MODULES CALLED: descrstatus(), descrlocation(), more(), fread(), fseek(),
712*34598Sbostic /	floor(), wmove(), printw(), waddstr(), distance(), wrefresh(),
713*34598Sbostic /	descrtype(), wclrtobot()
714*34598Sbostic /
715*34598Sbostic / GLOBAL INPUTS: LINES, Other, Circle, Wizard, Player, *stdscr, *Playersfp
716*34598Sbostic /
717*34598Sbostic / GLOBAL OUTPUTS: none
718*34598Sbostic /
719*34598Sbostic / DESCRIPTION:
720*34598Sbostic /	We can only see the coordinate of those closer to the origin
721*34598Sbostic /	from us.
722*34598Sbostic /	Kings and council of the wise can see and can be seen by everyone.
723*34598Sbostic /	Palantirs are good for seeing everyone; and the valar can use
724*34598Sbostic /	one to see through a 'cloak' spell.
725*34598Sbostic /	The valar has no coordinates, and is completely invisible if
726*34598Sbostic /	cloaked.
727*34598Sbostic /
728*34598Sbostic /************************************************************************/
729*34598Sbostic 
730*34598Sbostic userlist(ingameflag)
731*34598Sbostic bool	ingameflag;
732*34598Sbostic {
733*34598Sbostic register int	numusers = 0;	/* number of users on file */
734*34598Sbostic 
735*34598Sbostic     if (ingameflag && Player.p_blindness)
736*34598Sbostic 	{
737*34598Sbostic 	mvaddstr(8, 0, "You cannot see anyone.\n");
738*34598Sbostic 	return;
739*34598Sbostic 	}
740*34598Sbostic 
741*34598Sbostic     fseek(Playersfp, 0L, 0);
742*34598Sbostic     mvaddstr(8, 0,
743*34598Sbostic 	"Name                         X         Y    Lvl Type Login    Status\n");
744*34598Sbostic 
745*34598Sbostic     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
746*34598Sbostic 	{
747*34598Sbostic 	if (Other.p_status == S_NOTUSED
748*34598Sbostic 	    /* record is unused */
749*34598Sbostic 	    || (Other.p_specialtype == SC_VALAR && Other.p_status == S_CLOAKED))
750*34598Sbostic 	    /* cloaked valar */
751*34598Sbostic 	    {
752*34598Sbostic 	    if (!Wizard)
753*34598Sbostic 		/* wizard can see everything on file */
754*34598Sbostic 		continue;
755*34598Sbostic 	    }
756*34598Sbostic 
757*34598Sbostic 	    ++numusers;
758*34598Sbostic 
759*34598Sbostic 	    if (ingameflag &&
760*34598Sbostic 		/* must be playing for the rest of these conditions */
761*34598Sbostic 		(Player.p_specialtype >= SC_KING
762*34598Sbostic 		/* kings and higher can see others */
763*34598Sbostic 		|| Other.p_specialtype >= SC_KING
764*34598Sbostic 		/* kings and higher can be seen by others */
765*34598Sbostic 		|| Circle >= CIRCLE(Other.p_x, Other.p_y)
766*34598Sbostic 		/* those nearer the origin can be seen */
767*34598Sbostic 		|| Player.p_palantir)
768*34598Sbostic 		/* palantir enables one to see others */
769*34598Sbostic 		&& (Other.p_status != S_CLOAKED
770*34598Sbostic 		    || (Player.p_specialtype == SC_VALAR && Player.p_palantir))
771*34598Sbostic 		/* not cloaked; valar can see through cloak with a palantir */
772*34598Sbostic 		&& Other.p_specialtype != SC_VALAR)
773*34598Sbostic 		/* not a valar */
774*34598Sbostic 		/* coordinates should be printed */
775*34598Sbostic 		printw("%-20s  %8.0f  %8.0f ",
776*34598Sbostic 		    Other.p_name, Other.p_x, Other.p_y);
777*34598Sbostic 	    else
778*34598Sbostic 		/* cannot see player's coordinates */
779*34598Sbostic 		printw("%-20s %19.19s ",
780*34598Sbostic 		    Other.p_name, descrlocation(&Other, TRUE));
781*34598Sbostic 
782*34598Sbostic 	printw("%6.0f %s  %-9.9s%s\n", Other.p_level, descrtype(&Other, TRUE),
783*34598Sbostic 	    Other.p_login, descrstatus(&Other));
784*34598Sbostic 
785*34598Sbostic 	if ((numusers % (LINES - 10)) == 0)
786*34598Sbostic 	    {
787*34598Sbostic 	    more(LINES - 1);
788*34598Sbostic 	    move(9, 0);
789*34598Sbostic 	    clrtobot();
790*34598Sbostic 	    }
791*34598Sbostic 	}
792*34598Sbostic 
793*34598Sbostic     printw("Total players on file = %d\n", numusers);
794*34598Sbostic     refresh();
795*34598Sbostic }
796*34598Sbostic /**/
797*34598Sbostic /************************************************************************
798*34598Sbostic /
799*34598Sbostic / FUNCTION NAME: throneroom()
800*34598Sbostic /
801*34598Sbostic / FUNCTION: king stuff upon entering throne
802*34598Sbostic /
803*34598Sbostic / AUTHOR: E. A. Estes, 12/16/85
804*34598Sbostic /
805*34598Sbostic / ARGUMENTS: none
806*34598Sbostic /
807*34598Sbostic / RETURN VALUE: none
808*34598Sbostic /
809*34598Sbostic / MODULES CALLED: writerecord(), fread(), fseek(), fopen(), wmove(), fclose(),
810*34598Sbostic /	fwrite(), altercoordinates(), waddstr(), fprintf()
811*34598Sbostic /
812*34598Sbostic / GLOBAL INPUTS: *Energyvoidfp, Other, Player, *stdscr, Voidfile[],
813*34598Sbostic /	Messfile[], Enrgyvoid, *Playersfp
814*34598Sbostic /
815*34598Sbostic / GLOBAL OUTPUTS: Other, Player, Changed
816*34598Sbostic /
817*34598Sbostic / DESCRIPTION:
818*34598Sbostic /	If player is not already king, make him/her so if the old king
819*34598Sbostic /	is not playing.
820*34598Sbostic /	Clear energy voids with new king.
821*34598Sbostic /	Print 'decree' prompt.
822*34598Sbostic /
823*34598Sbostic /************************************************************************/
824*34598Sbostic 
825*34598Sbostic throneroom()
826*34598Sbostic {
827*34598Sbostic FILE	*fp;			/* to clear energy voids */
828*34598Sbostic long	loc = 0L;		/* location of old king in player file */
829*34598Sbostic 
830*34598Sbostic     if (Player.p_specialtype < SC_KING)
831*34598Sbostic 	/* not already king -- assumes crown */
832*34598Sbostic 	{
833*34598Sbostic 	fseek(Playersfp, 0L, 0);
834*34598Sbostic 	while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
835*34598Sbostic 	    if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED)
836*34598Sbostic 		/* found old king */
837*34598Sbostic 		{
838*34598Sbostic 		if (Other.p_status != S_OFF)
839*34598Sbostic 		    /* old king is playing */
840*34598Sbostic 		    {
841*34598Sbostic 		    mvaddstr( 4, 0, "The king is playing, so you cannot steal his throne\n");
842*34598Sbostic 		    altercoordinates(0.0, 0.0, A_NEAR);
843*34598Sbostic 		    move(6, 0);
844*34598Sbostic 		    return;
845*34598Sbostic 		    }
846*34598Sbostic 		else
847*34598Sbostic 		    /* old king is not playing - remove him/her */
848*34598Sbostic 		    {
849*34598Sbostic 		    Other.p_specialtype = SC_NONE;
850*34598Sbostic 		    if (Other.p_crowns)
851*34598Sbostic 			--Other.p_crowns;
852*34598Sbostic 		    writerecord(&Other, loc);
853*34598Sbostic 		    break;
854*34598Sbostic 		    }
855*34598Sbostic 		}
856*34598Sbostic 	    else
857*34598Sbostic 		loc += SZ_PLAYERSTRUCT;
858*34598Sbostic 
859*34598Sbostic 	/* make player new king */
860*34598Sbostic 	Changed = TRUE;
861*34598Sbostic 	Player.p_specialtype = SC_KING;
862*34598Sbostic 	mvaddstr(4, 0, "You have become king!\n");
863*34598Sbostic 
864*34598Sbostic 	/* let everyone else know */
865*34598Sbostic 	fp = fopen(Messfile, "w");
866*34598Sbostic 	fprintf(fp, "All hail the new king!");
867*34598Sbostic 	fclose(fp);
868*34598Sbostic 
869*34598Sbostic 	/* clear all energy voids; retain location of holy grail */
870*34598Sbostic 	fseek(Energyvoidfp, 0L, 0);
871*34598Sbostic 	fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
872*34598Sbostic 	fp = fopen(Voidfile, "w");
873*34598Sbostic 	fwrite((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, fp);
874*34598Sbostic 	fclose(fp);
875*34598Sbostic 	}
876*34598Sbostic 
877*34598Sbostic     mvaddstr(6, 0, "0:Decree  ");
878*34598Sbostic }
879*34598Sbostic /**/
880*34598Sbostic /************************************************************************
881*34598Sbostic /
882*34598Sbostic / FUNCTION NAME: dotampered()
883*34598Sbostic /
884*34598Sbostic / FUNCTION: king and valar special options
885*34598Sbostic /
886*34598Sbostic / AUTHOR: E. A. Estes, 2/28/86
887*34598Sbostic /
888*34598Sbostic / ARGUMENTS: none
889*34598Sbostic /
890*34598Sbostic / RETURN VALUE: none
891*34598Sbostic /
892*34598Sbostic / MODULES CALLED: writerecord(), truncstring(), fread(), fseek(), fopen(),
893*34598Sbostic /	floor(), wmove(), drandom(), fclose(), fwrite(), sscanf(), strcmp(),
894*34598Sbostic /	infloat(), waddstr(), findname(), distance(), userlist(), mvprintw(),
895*34598Sbostic /	allocvoid(), getanswer(), getstring(), wclrtoeol(), writevoid()
896*34598Sbostic /
897*34598Sbostic / GLOBAL INPUTS: *Energyvoidfp, Other, Illcmd[], Wizard, Player, *stdscr,
898*34598Sbostic /	Databuf[], Goldfile[], Enrgyvoid
899*34598Sbostic /
900*34598Sbostic / GLOBAL OUTPUTS: Other, Player, Enrgyvoid
901*34598Sbostic /
902*34598Sbostic / DESCRIPTION:
903*34598Sbostic /	Tamper with other players.  Handle king/valar specific options.
904*34598Sbostic /
905*34598Sbostic /************************************************************************/
906*34598Sbostic 
907*34598Sbostic dotampered()
908*34598Sbostic {
909*34598Sbostic short	tamper;			/* value for tampering with other players */
910*34598Sbostic char	*option;			/* pointer to option description */
911*34598Sbostic double	temp1 = 0.0, temp2 = 0.0;	/* other tampering values */
912*34598Sbostic int	ch;				/* input */
913*34598Sbostic long	loc;				/* location in energy void file */
914*34598Sbostic FILE	*fp;				/* for opening gold file */
915*34598Sbostic 
916*34598Sbostic     move(6, 0);
917*34598Sbostic     clrtoeol();
918*34598Sbostic     if (Player.p_specialtype < SC_COUNCIL && !Wizard)
919*34598Sbostic 	/* king options */
920*34598Sbostic 	{
921*34598Sbostic 	addstr("1:Transport  2:Curse  3:Energy Void  4:Bestow  5:Collect Taxes  ");
922*34598Sbostic 
923*34598Sbostic 	ch = getanswer(" ", TRUE);
924*34598Sbostic 	move(6, 0);
925*34598Sbostic 	clrtoeol();
926*34598Sbostic 	move(4, 0);
927*34598Sbostic 	switch (ch)
928*34598Sbostic 	    {
929*34598Sbostic 	    case '1':	/* transport someone */
930*34598Sbostic 		tamper = T_TRANSPORT;
931*34598Sbostic 		option = "transport";
932*34598Sbostic 		break;
933*34598Sbostic 
934*34598Sbostic 	    case '2':	/* curse another */
935*34598Sbostic 		tamper = T_CURSED;
936*34598Sbostic 		option = "curse";
937*34598Sbostic 		break;
938*34598Sbostic 
939*34598Sbostic 	    case '3':	/* create energy void */
940*34598Sbostic 		if ((loc = allocvoid()) > 20L * SZ_VOIDSTRUCT)
941*34598Sbostic 		    /* can only have 20 void active at once */
942*34598Sbostic 		    mvaddstr(5, 0, "Sorry, void creation limit reached.\n");
943*34598Sbostic 		else
944*34598Sbostic 		    {
945*34598Sbostic 		    addstr("Enter the X Y coordinates of void ? ");
946*34598Sbostic 		    getstring(Databuf, SZ_DATABUF);
947*34598Sbostic 		    sscanf(Databuf, "%F %F", &temp1, &temp2);
948*34598Sbostic 		    Enrgyvoid.ev_x = floor(temp1);
949*34598Sbostic 		    Enrgyvoid.ev_y = floor(temp2);
950*34598Sbostic 		    Enrgyvoid.ev_active = TRUE;
951*34598Sbostic 		    writevoid(&Enrgyvoid, loc);
952*34598Sbostic 		    mvaddstr(5, 0, "It is done.\n");
953*34598Sbostic 		    }
954*34598Sbostic 		return;
955*34598Sbostic 
956*34598Sbostic 	    case '4':	/* bestow gold to subject */
957*34598Sbostic 		tamper = T_BESTOW;
958*34598Sbostic 		addstr("How much gold to bestow ? ");
959*34598Sbostic 		temp1 = infloat();
960*34598Sbostic 		if (temp1 > Player.p_gold || temp1 < 0)
961*34598Sbostic 		    {
962*34598Sbostic 		    mvaddstr(5, 0, "You don't have that !\n");
963*34598Sbostic 		    return;
964*34598Sbostic 		    }
965*34598Sbostic 
966*34598Sbostic 		/* adjust gold after we are sure it will be given to someone */
967*34598Sbostic 		option = "give gold to";
968*34598Sbostic 		break;
969*34598Sbostic 
970*34598Sbostic 	    case '5':	/* collect accumulated taxes */
971*34598Sbostic 		if ((fp = fopen(Goldfile, "r+")) != NULL)
972*34598Sbostic 		    /* collect taxes */
973*34598Sbostic 		    {
974*34598Sbostic 		    fread((char *) &temp1, sizeof(double), 1, fp);
975*34598Sbostic 		    fseek(fp, 0L, 0);
976*34598Sbostic 		    /* clear out value */
977*34598Sbostic 		    temp2 = 0.0;
978*34598Sbostic 		    fwrite((char *) &temp2, sizeof(double), 1, fp);
979*34598Sbostic 		    fclose(fp);
980*34598Sbostic 		    }
981*34598Sbostic 
982*34598Sbostic 		mvprintw(4, 0, "You have collected %.0f in gold.\n", temp1);
983*34598Sbostic 		Player.p_gold += floor(temp1);
984*34598Sbostic 		return;
985*34598Sbostic 
986*34598Sbostic 	    default:
987*34598Sbostic 		return;
988*34598Sbostic 	    }
989*34598Sbostic 	/* end of king options */
990*34598Sbostic 	}
991*34598Sbostic     else
992*34598Sbostic 	/* council of wise, valar, wizard options */
993*34598Sbostic 	{
994*34598Sbostic 	addstr("1:Heal  ");
995*34598Sbostic 	if (Player.p_palantir || Wizard)
996*34598Sbostic 	    addstr("2:Seek Grail  ");
997*34598Sbostic 	if (Player.p_specialtype == SC_VALAR || Wizard)
998*34598Sbostic 	    addstr("3:Throw Monster  4:Relocate  5:Bless  ");
999*34598Sbostic 	if (Wizard)
1000*34598Sbostic 	    addstr("6:Vaporize  ");
1001*34598Sbostic 
1002*34598Sbostic 	ch = getanswer(" ", TRUE);
1003*34598Sbostic 	if (!Wizard)
1004*34598Sbostic 	    {
1005*34598Sbostic 	    if (ch > '2' && Player.p_specialtype != SC_VALAR)
1006*34598Sbostic 		{
1007*34598Sbostic 		ILLCMD();
1008*34598Sbostic 		return;
1009*34598Sbostic 		}
1010*34598Sbostic 
1011*34598Sbostic 	    if (Player.p_mana < MM_INTERVENE)
1012*34598Sbostic 		{
1013*34598Sbostic 		mvaddstr(5, 0, "No mana left.\n");
1014*34598Sbostic 		return;
1015*34598Sbostic 		}
1016*34598Sbostic 	    else
1017*34598Sbostic 		Player.p_mana -= MM_INTERVENE;
1018*34598Sbostic 	    }
1019*34598Sbostic 
1020*34598Sbostic 	switch (ch)
1021*34598Sbostic 	    {
1022*34598Sbostic 	    case '1':	/* heal another */
1023*34598Sbostic 		tamper = T_HEAL;
1024*34598Sbostic 		option = "heal";
1025*34598Sbostic 		break;
1026*34598Sbostic 
1027*34598Sbostic 	    case '2':	/* seek grail */
1028*34598Sbostic 		if (Player.p_palantir)
1029*34598Sbostic 		    /* need a palantir to seek */
1030*34598Sbostic 		    {
1031*34598Sbostic 		    fseek(Energyvoidfp, 0L, 0);
1032*34598Sbostic 		    fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
1033*34598Sbostic 		    temp1 = distance(Player.p_x, Enrgyvoid.ev_x, Player.p_y, Enrgyvoid.ev_y);
1034*34598Sbostic 		    temp1 += ROLL(-temp1 / 10.0, temp1 / 5.0);	/* add some error */
1035*34598Sbostic 		    mvprintw(5, 0, "The palantir says the Grail is about %.0f away.\n", temp1);
1036*34598Sbostic 		    }
1037*34598Sbostic 		else
1038*34598Sbostic 		    /* no palantir */
1039*34598Sbostic 		    mvaddstr(5, 0, "You need a palantir to seek the Grail.\n");
1040*34598Sbostic 		return;
1041*34598Sbostic 
1042*34598Sbostic 	    case '3':	/* lob monster at someone */
1043*34598Sbostic 		mvaddstr(4, 0, "Which monster [0-99] ? ");
1044*34598Sbostic 		temp1 = infloat();
1045*34598Sbostic 		temp1 = MAX(0.0, MIN(99.0, temp1));
1046*34598Sbostic 		tamper = T_MONSTER;
1047*34598Sbostic 		option = "throw a monster at";
1048*34598Sbostic 		break;
1049*34598Sbostic 
1050*34598Sbostic 	    case '4':	/* move another player */
1051*34598Sbostic 		mvaddstr(4, 0, "New X Y coordinates ? ");
1052*34598Sbostic 		getstring(Databuf, SZ_DATABUF);
1053*34598Sbostic 		sscanf(Databuf, "%F %F", &temp1, &temp2);
1054*34598Sbostic 		tamper = T_RELOCATE;
1055*34598Sbostic 		option = "relocate";
1056*34598Sbostic 		break;
1057*34598Sbostic 
1058*34598Sbostic 	    case '5':	/* bless a player */
1059*34598Sbostic 		tamper = T_BLESSED;
1060*34598Sbostic 		option = "bless";
1061*34598Sbostic 		break;
1062*34598Sbostic 
1063*34598Sbostic 	    case '6':	/* kill off a player */
1064*34598Sbostic 		if (Wizard)
1065*34598Sbostic 		    {
1066*34598Sbostic 		    tamper = T_VAPORIZED;
1067*34598Sbostic 		    option = "vaporize";
1068*34598Sbostic 		    break;
1069*34598Sbostic 		    }
1070*34598Sbostic 		else
1071*34598Sbostic 		    return;
1072*34598Sbostic 
1073*34598Sbostic 	    default:
1074*34598Sbostic 		return;
1075*34598Sbostic 	    }
1076*34598Sbostic 
1077*34598Sbostic 	/* adjust age after we are sure intervention will be done */
1078*34598Sbostic 	/* end of valar, etc. options */
1079*34598Sbostic 	}
1080*34598Sbostic 
1081*34598Sbostic     for (;;)
1082*34598Sbostic 	/* prompt for player to affect */
1083*34598Sbostic 	{
1084*34598Sbostic 	mvprintw(4, 0, "Who do you want to %s ? ", option);
1085*34598Sbostic 	getstring(Databuf, SZ_DATABUF);
1086*34598Sbostic 	truncstring(Databuf);
1087*34598Sbostic 
1088*34598Sbostic 	if (Databuf[0] == '\0')
1089*34598Sbostic 	    userlist(TRUE);
1090*34598Sbostic 	else
1091*34598Sbostic 	    break;
1092*34598Sbostic 	}
1093*34598Sbostic 
1094*34598Sbostic     if (strcmp(Player.p_name, Databuf) != 0)
1095*34598Sbostic 	/* name other than self */
1096*34598Sbostic 	{
1097*34598Sbostic 	if ((loc = findname(Databuf, &Other)) >= 0L)
1098*34598Sbostic 	    {
1099*34598Sbostic 	    if (Other.p_tampered != T_OFF)
1100*34598Sbostic 		{
1101*34598Sbostic 		mvaddstr(5, 0, "That person has something pending already.\n");
1102*34598Sbostic 		return;
1103*34598Sbostic 		}
1104*34598Sbostic 	    else
1105*34598Sbostic 		{
1106*34598Sbostic 		if (tamper == T_RELOCATE
1107*34598Sbostic 		    && CIRCLE(temp1, temp2) < CIRCLE(Other.p_x, Other.p_y)
1108*34598Sbostic 		    && !Wizard)
1109*34598Sbostic 		    mvaddstr(5, 0, "Cannot move someone closer to the Lord's Chamber.\n");
1110*34598Sbostic 		else
1111*34598Sbostic 		    {
1112*34598Sbostic 		    if (tamper == T_BESTOW) Player.p_gold -= floor(temp1);
1113*34598Sbostic 		    if (!Wizard && (tamper == T_HEAL || tamper == T_MONSTER ||
1114*34598Sbostic 			tamper == T_RELOCATE || tamper == T_BLESSED))
1115*34598Sbostic 	    			Player.p_age += N_AGE;	/* age penalty */
1116*34598Sbostic 		    Other.p_tampered = tamper;
1117*34598Sbostic 		    Other.p_1scratch = floor(temp1);
1118*34598Sbostic 		    Other.p_2scratch = floor(temp2);
1119*34598Sbostic 		    writerecord(&Other, loc);
1120*34598Sbostic 		    mvaddstr(5, 0, "It is done.\n");
1121*34598Sbostic 		    }
1122*34598Sbostic 		return;
1123*34598Sbostic 		}
1124*34598Sbostic 	    }
1125*34598Sbostic 	else
1126*34598Sbostic 	    /* player not found */
1127*34598Sbostic 	    mvaddstr(5, 0, "There is no one by that name.\n");
1128*34598Sbostic 	}
1129*34598Sbostic     else
1130*34598Sbostic 	/* self */
1131*34598Sbostic 	mvaddstr(5, 0, "You may not do it to yourself!\n");
1132*34598Sbostic }
1133*34598Sbostic /**/
1134*34598Sbostic /************************************************************************
1135*34598Sbostic /
1136*34598Sbostic / FUNCTION NAME: writevoid()
1137*34598Sbostic /
1138*34598Sbostic / FUNCTION: update energy void entry in energy void file
1139*34598Sbostic /
1140*34598Sbostic / AUTHOR: E. A. Estes, 12/4/85
1141*34598Sbostic /
1142*34598Sbostic / ARGUMENTS:
1143*34598Sbostic /	struct energyvoid *vp - pointer to structure to write to file
1144*34598Sbostic /	long loc - location in file to update
1145*34598Sbostic /
1146*34598Sbostic / RETURN VALUE: none
1147*34598Sbostic /
1148*34598Sbostic / MODULES CALLED: fseek(), fwrite(), fflush()
1149*34598Sbostic /
1150*34598Sbostic / GLOBAL INPUTS: *Energyvoidfp
1151*34598Sbostic /
1152*34598Sbostic / GLOBAL OUTPUTS: none
1153*34598Sbostic /
1154*34598Sbostic / DESCRIPTION:
1155*34598Sbostic /	Write out energy void structure at specified location.
1156*34598Sbostic /
1157*34598Sbostic /************************************************************************/
1158*34598Sbostic 
1159*34598Sbostic writevoid(vp, loc)
1160*34598Sbostic register struct energyvoid	*vp;
1161*34598Sbostic long	loc;
1162*34598Sbostic {
1163*34598Sbostic 
1164*34598Sbostic     fseek(Energyvoidfp, loc, 0);
1165*34598Sbostic     fwrite((char *) vp, SZ_VOIDSTRUCT, 1, Energyvoidfp);
1166*34598Sbostic     fflush(Energyvoidfp);
1167*34598Sbostic     fseek(Energyvoidfp, 0L, 0);
1168*34598Sbostic }
1169*34598Sbostic /**/
1170*34598Sbostic /************************************************************************
1171*34598Sbostic /
1172*34598Sbostic / FUNCTION NAME: allocvoid()
1173*34598Sbostic /
1174*34598Sbostic / FUNCTION: allocate space for a new energy void
1175*34598Sbostic /
1176*34598Sbostic / AUTHOR: E. A. Estes, 12/4/85
1177*34598Sbostic /
1178*34598Sbostic / ARGUMENTS: none
1179*34598Sbostic /
1180*34598Sbostic / RETURN VALUE: location of new energy void space
1181*34598Sbostic /
1182*34598Sbostic / MODULES CALLED: fread(), fseek()
1183*34598Sbostic /
1184*34598Sbostic / GLOBAL INPUTS: *Energyvoidfp, Enrgyvoid
1185*34598Sbostic /
1186*34598Sbostic / GLOBAL OUTPUTS: none
1187*34598Sbostic /
1188*34598Sbostic / DESCRIPTION:
1189*34598Sbostic /	Search energy void file for an inactive entry and return its
1190*34598Sbostic /	location.
1191*34598Sbostic /	If no inactive ones are found, return one more than last location.
1192*34598Sbostic /
1193*34598Sbostic /************************************************************************/
1194*34598Sbostic 
1195*34598Sbostic long
1196*34598Sbostic allocvoid()
1197*34598Sbostic {
1198*34598Sbostic long	loc = 0L;		/* location of new energy void */
1199*34598Sbostic 
1200*34598Sbostic     fseek(Energyvoidfp, 0L, 0);
1201*34598Sbostic     while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
1202*34598Sbostic 	if (Enrgyvoid.ev_active)
1203*34598Sbostic 	    loc += SZ_VOIDSTRUCT;
1204*34598Sbostic 	else
1205*34598Sbostic 	    break;
1206*34598Sbostic 
1207*34598Sbostic     return(loc);
1208*34598Sbostic }
1209