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