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