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