2 * interplayer.c - player to player routines for Phantasia
4 * $FreeBSD: src/games/phantasia/interplayer.c,v 1.6 1999/11/16 02:57:33 billf Exp $
5 * $DragonFly: src/games/phantasia/interplayer.c,v 1.2 2003/06/17 04:25:24 dillon Exp $
11 /************************************************************************
13 / FUNCTION NAME: checkbattle()
15 / FUNCTION: check to see if current player should battle another
17 / AUTHOR: E. A. Estes, 12/4/85
23 / MODULES CALLED: battleplayer(), fread(), fseek()
25 / GLOBAL INPUTS: Other, Users, Player, Fileloc, *Playersfp
27 / GLOBAL OUTPUTS: Users
30 / Seach player file for a foe at the same coordinates as the
32 / Also update user count.
34 *************************************************************************/
38 long foeloc = 0L; /* location in file of person to fight */
41 fseek(Playersfp, 0L, 0);
43 while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
45 if (Other.p_status != S_OFF
46 && Other.p_status != S_NOTUSED
47 && Other.p_status != S_HUNGUP
48 && (Other.p_status != S_CLOAKED || Other.p_specialtype != SC_VALAR))
49 /* player is on and not a cloaked valar */
53 if (Player.p_x == Other.p_x
54 && Player.p_y == Other.p_y
55 /* same coordinates */
58 && Player.p_status == S_PLAYING
59 && (Other.p_status == S_PLAYING || Other.p_status == S_INBATTLE)
60 /* both are playing */
61 && Other.p_specialtype != SC_VALAR
62 && Player.p_specialtype != SC_VALAR)
63 /* neither is valar */
69 foeloc += SZ_PLAYERSTRUCT;
73 /************************************************************************
75 / FUNCTION NAME: battleplayer()
77 / FUNCTION: inter-terminal battle with another player
79 / AUTHOR: E. A. Estes, 2/15/86
82 / long foeplace - location in player file of person to battle
86 / MODULES CALLED: readrecord(), readmessage(), writerecord(), collecttaxes(),
87 / displaystats(), fabs(), more(), death(), sleep(), wmove(), waddch(), printw(),
88 / myturn(), altercoordinates(), waddstr(), wrefresh(), mvprintw(),
89 / getanswer(), wclrtoeol(), wclrtobot()
91 / GLOBAL INPUTS: Foestrikes, LINES, Lines, Other, Shield, Player, *stdscr,
94 / GLOBAL OUTPUTS: Foestrikes, Lines, Shield, Player, Luckout, *Enemyname
97 / Inter-terminal battle is a very fragile and slightly klugy thing.
98 / At any time, one player is master and the other is slave.
99 / We pick who is master first by speed and level. After that,
100 / the slave waits for the master to relinquish its turn, and
101 / the slave becomes master, and so on.
103 / The items in the player structure which control the handshake are:
105 / master increments this to relinquish control
107 / master sets this to specify particular action
109 / set to total damage inflicted so far; changes to indicate action
111 *************************************************************************/
113 battleplayer(foeplace)
116 double dtemp; /* for temporary calculations */
117 double oldhits = 0.0; /* previous damage inflicted by foe */
118 int loop; /* for timing out */
120 short oldtampered; /* old value of foe's p_tampered */
124 mvaddstr(4, 0, "Preparing for battle!\n");
131 /* set up variables, file, etc. */
132 Player.p_status = S_INBATTLE;
133 Shield = Player.p_energy;
135 /* if p_tampered is not 0, someone else may try to change it (king, etc.) */
136 Player.p_tampered = oldtampered = 1;
137 Player.p_1scratch = 0.0;
138 Player.p_istat = I_OFF;
140 readrecord(&Other, foeplace);
141 if (fabs(Player.p_level - Other.p_level) > 20.0)
142 /* see if players are greatly mismatched */
144 dtemp = (Player.p_level - Other.p_level) / MAX(Player.p_level, Other.p_level);
146 /* foe outweighs this one */
147 Player.p_speed *= 2.0;
150 writerecord(&Player, Fileloc); /* write out all our info */
152 if (Player.p_blindness)
153 Enemyname = "someone";
155 Enemyname = Other.p_name;
157 mvprintw(6, 0, "You have encountered %s Level: %.0f\n", Enemyname, Other.p_level);
160 for (loop = 0; Other.p_status != S_INBATTLE && loop < 30; ++loop)
161 /* wait for foe to respond */
163 readrecord(&Other, foeplace);
167 if (Other.p_status != S_INBATTLE)
168 /* foe did not respond */
170 mvprintw(5, 0, "%s is not responding.\n", Enemyname);
173 /* else, we are ready to battle */
179 * determine who is first master
180 * if neither player is faster, check level
181 * if neither level is greater, battle is not allowed
182 * (this should never happen, but we have to handle it)
184 if (Player.p_speed > Other.p_speed)
186 else if (Other.p_speed > Player.p_speed)
188 else if (Player.p_level > Other.p_level)
190 else if (Other.p_level > Player.p_level)
193 /* no one is faster */
195 printw("You can't fight %s yet.", Enemyname);
203 mvprintw(1, 26, "%20.0f", Shield); /* overprint energy */
206 /* take action against foe */
209 /* wait for foe to take action */
211 mvaddstr(4, 0, "Waiting...\n");
215 for (loop = 0; loop < 20; ++loop)
216 /* wait for foe to act */
218 readrecord(&Other, foeplace);
219 if (Other.p_1scratch != oldhits)
220 /* p_1scratch changes to indicate action */
223 /* wait and try again */
231 if (Other.p_1scratch == oldhits)
234 mvaddstr(22, 0, "Timeout: waiting for response. Do you want to wait ? ");
235 ch = getanswer("NY", FALSE);
244 /* foe took action */
246 switch (Other.p_istat)
248 case I_RAN: /* foe ran away */
249 mvprintw(Lines++, 0, "%s ran away!", Enemyname);
252 case I_STUCK: /* foe tried to run, but couldn't */
253 mvprintw(Lines++, 0, "%s tried to run away.", Enemyname);
256 case I_BLEWIT: /* foe tried to luckout, but didn't */
257 mvprintw(Lines++, 0, "%s tried to luckout!", Enemyname);
261 dtemp = Other.p_1scratch - oldhits;
262 mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, dtemp);
267 oldhits = Other.p_1scratch; /* keep track of old hits */
269 if (Other.p_tampered != oldtampered)
270 /* p_tampered changes to relinquish turn */
272 oldtampered = Other.p_tampered;
278 /* decide what happens next */
280 if (Lines > LINES - 2)
287 if (Other.p_istat == I_KILLED || Shield < 0.0)
290 Shield = -2.0; /* insure this value is negative */
294 if (Player.p_istat == I_KILLED)
295 /* we killed foe; award treasre */
297 mvprintw(Lines++, 0, "You killed %s!", Enemyname);
298 Player.p_experience += Other.p_experience;
299 Player.p_crowns += (Player.p_level < 1000.0) ? Other.p_crowns : 0;
300 Player.p_amulets += Other.p_amulets;
301 Player.p_charms += Other.p_charms;
302 collecttaxes(Other.p_gold, Other.p_gems);
303 Player.p_sword = MAX(Player.p_sword, Other.p_sword);
304 Player.p_shield = MAX(Player.p_shield, Other.p_shield);
305 Player.p_quksilver = MAX(Player.p_quksilver, Other.p_quksilver);
306 if (Other.p_virgin && !Player.p_virgin)
308 mvaddstr(Lines++, 0, "You have rescued a virgin. Will you be honorable ? ");
309 if ((ch = getanswer("YN", FALSE)) == 'Y')
310 Player.p_virgin = TRUE;
314 Player.p_experience += 8000.0;
317 sleep(3); /* give other person time to die */
320 else if (Player.p_istat == I_RAN || Other.p_istat == I_RAN)
321 /* either player ran away */
326 /* clean up things and leave */
327 writerecord(&Player, Fileloc); /* update a final time */
328 altercoordinates(0.0, 0.0, A_NEAR); /* move away from battle site */
329 Player.p_energy = Shield; /* set energy to actual value */
330 Player.p_tampered = T_OFF; /* clear p_tampered */
332 more(Lines); /* pause */
335 clrtobot(); /* clear bottom area of screen */
337 if (Player.p_energy < 0.0)
339 death("Interterminal battle");
342 /************************************************************************
344 / FUNCTION NAME: myturn()
346 / FUNCTION: process players action against foe in battle
348 / AUTHOR: E. A. Estes, 2/7/86
354 / MODULES CALLED: writerecord(), inputoption(), floor(), wmove(), drandom(),
355 / waddstr(), wrefresh(), mvprintw(), wclrtoeol(), wclrtobot()
357 / GLOBAL INPUTS: Lines, Other, Player, *stdscr, Fileloc, Luckout,
360 / GLOBAL OUTPUTS: Foestrikes, Lines, Player, Luckout
363 / Take action action against foe, and decide who is master
364 / for next iteration.
366 *************************************************************************/
370 double dtemp; /* for temporary calculations */
373 mvaddstr(7, 0, "1:Fight 2:Run Away! 3:Power Blast ");
377 addstr("4:Luckout ");
386 dtemp = ROLL(2.0, Player.p_might);
388 mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, dtemp);
390 Player.p_1scratch += dtemp;
391 Player.p_istat = I_OFF;
394 case '2': /* run away */
395 Player.p_1scratch -= 1.0; /* change this to indicate action */
396 if (drandom() > 0.25)
398 mvaddstr(Lines++, 0, "You got away!");
399 Player.p_istat = I_RAN;
403 mvprintw(Lines++, 0, "%s is still after you!", Enemyname);
404 Player.p_istat = I_STUCK;
408 case '3': /* power blast */
409 dtemp = MIN(Player.p_mana, Player.p_level * 5.0);
410 Player.p_mana -= dtemp;
411 dtemp *= (drandom() + 0.5) * Player.p_magiclvl * 0.2 + 2.0;
412 mvprintw(Lines++, 0, "You blasted %s !", Enemyname);
415 case '4': /* luckout */
416 if (Luckout || drandom() > 0.1)
419 mvaddstr(Lines++, 0, "You already tried that!");
422 mvaddstr(Lines++, 0, "Not this time . . .");
426 Player.p_1scratch -= 1.0;
427 Player.p_istat = I_BLEWIT;
431 mvaddstr(Lines++, 0, "You just lucked out!");
432 Player.p_1scratch = Other.p_energy * 1.1;
438 Player.p_1scratch = floor(Player.p_1scratch); /* clean up any mess */
440 if (Player.p_1scratch > Other.p_energy)
441 Player.p_istat = I_KILLED;
442 else if (drandom() * Player.p_speed < drandom() * Other.p_speed)
443 /* relinquish control */
449 writerecord(&Player, Fileloc); /* let foe know what we did */
452 /************************************************************************
454 / FUNCTION NAME: checktampered()
456 / FUNCTION: check if current player has been tampered with
458 / AUTHOR: E. A. Estes, 12/4/85
464 / MODULES CALLED: readrecord(), fread(), fseek(), tampered(), writevoid()
466 / GLOBAL INPUTS: *Energyvoidfp, Other, Player, Fileloc, Enrgyvoid
468 / GLOBAL OUTPUTS: Enrgyvoid
471 / Check for energy voids, holy grail, and tampering by other
474 *************************************************************************/
478 long loc = 0L; /* location in energy void file */
480 /* first check for energy voids */
481 fseek(Energyvoidfp, 0L, 0);
482 while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
483 if (Enrgyvoid.ev_active
484 && Enrgyvoid.ev_x == Player.p_x
485 && Enrgyvoid.ev_y == Player.p_y)
489 /* not the holy grail; inactivate energy void */
491 Enrgyvoid.ev_active = FALSE;
492 writevoid(&Enrgyvoid, loc);
493 tampered(T_NRGVOID, 0.0, 0.0);
495 else if (Player.p_status != S_CLOAKED)
497 tampered(T_GRAIL, 0.0, 0.0);
501 loc += SZ_VOIDSTRUCT;
503 /* now check for other things */
504 readrecord(&Other, Fileloc);
505 if (Other.p_tampered != T_OFF)
506 tampered(Other.p_tampered, Other.p_1scratch, Other.p_2scratch);
509 /************************************************************************
511 / FUNCTION NAME: tampered()
513 / FUNCTION: take care of tampering by other players
515 / AUTHOR: E. A. Estes, 12/4/85
518 / int what - what type of tampering
519 / double arg1, arg2 - rest of tampering info
523 / MODULES CALLED: writerecord(), more(), fread(), death(), fseek(), sleep(),
524 / floor(), wmove(), waddch(), drandom(), printw(), altercoordinates(),
525 / waddstr(), wrefresh(), encounter(), writevoid()
527 / GLOBAL INPUTS: Other, Player, *stdscr, Enrgyvoid, *Playersfp
529 / GLOBAL OUTPUTS: Other, Player, Changed, Enrgyvoid
532 / Take care of energy voids, holy grail, decree and intervention
533 / action on current player.
535 *************************************************************************/
537 tampered(what, arg1, arg2)
542 long loc; /* location in file of other players */
547 Player.p_tampered = T_OFF; /* no longer tampered with */
552 addstr("You've hit an energy void !\n");
553 Player.p_mana /= 3.0;
554 Player.p_energy /= 2.0;
555 Player.p_gold = floor(Player.p_gold/1.25) + 0.1;
556 altercoordinates(0.0, 0.0, A_NEAR);
560 addstr("The king transported you ! ");
561 if (Player.p_charms > 0)
563 addstr("But your charm saved you. . .\n");
568 altercoordinates(0.0, 0.0, A_FAR);
574 printw("The king has bestowed %.0f gold pieces on you !\n", arg1);
575 Player.p_gold += arg1;
579 addstr("You've been cursed ! ");
580 if (Player.p_blessing)
582 addstr("But your blessing saved you. . .\n");
583 Player.p_blessing = FALSE;
588 Player.p_poison += 2.0;
589 Player.p_energy = 10.0;
590 Player.p_maxenergy *= 0.95;
591 Player.p_status = S_PLAYING; /* no longer cloaked */
596 addstr("You have been vaporized!\n");
598 death("Vaporization");
602 addstr("The Valar zapped you with a monster!\n");
604 encounter((int) arg1);
608 addstr("The Valar has blessed you!\n");
609 Player.p_energy = (Player.p_maxenergy *= 1.05) + Player.p_shield;
610 Player.p_mana += 500.0;
611 Player.p_strength += 0.5;
612 Player.p_brains += 0.5;
613 Player.p_magiclvl += 0.5;
614 Player.p_poison = MIN(0.5, Player.p_poison);
618 addstr("You've been relocated. . .\n");
619 altercoordinates(arg1, arg2, A_FORCED);
623 addstr("You've been healed!\n");
624 Player.p_poison -= 0.25;
625 Player.p_energy = Player.p_maxenergy + Player.p_shield;
629 addstr("You are no longer Valar!\n");
630 Player.p_specialtype = SC_COUNCIL;
634 addstr("You have found The Holy Grail!!\n");
635 if (Player.p_specialtype < SC_COUNCIL)
636 /* must be council of wise to behold grail */
638 addstr("However, you are not experienced enough to behold it.\n");
639 Player.p_sin *= Player.p_sin;
640 Player.p_mana += 1000;
642 else if (Player.p_specialtype == SC_VALAR
643 || Player.p_specialtype == SC_EXVALAR)
645 addstr("You have made it to the position of Valar once already.\n");
646 addstr("The Grail is of no more use to you now.\n");
650 addstr("It is now time to see if you are worthy to behold it. . .\n");
654 if (drandom() / 2.0 < Player.p_sin)
656 addstr("You have failed!\n");
663 Player.p_experience =
664 Player.p_quickness = 1.0;
666 altercoordinates(1.0, 1.0, A_FORCED);
667 Player.p_level = 0.0;
671 addstr("You made to position of Valar!\n");
672 Player.p_specialtype = SC_VALAR;
674 fseek(Playersfp, 0L, 0);
676 while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
677 /* search for existing valar */
678 if (Other.p_specialtype == SC_VALAR
679 && Other.p_status != S_NOTUSED)
680 /* found old valar */
682 Other.p_tampered = T_EXVALAR;
683 writerecord(&Other, loc);
687 loc += SZ_PLAYERSTRUCT;
691 /* move grail to new location */
692 Enrgyvoid.ev_active = TRUE;
693 Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
694 Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
695 writevoid(&Enrgyvoid, 0L);
702 /************************************************************************
704 / FUNCTION NAME: userlist()
706 / FUNCTION: print list of players and locations
708 / AUTHOR: E. A. Estes, 2/28/86
711 / bool ingameflag - set if called while playing
715 / MODULES CALLED: descrstatus(), descrlocation(), more(), fread(), fseek(),
716 / floor(), wmove(), printw(), waddstr(), distance(), wrefresh(),
717 / descrtype(), wclrtobot()
719 / GLOBAL INPUTS: LINES, Other, Circle, Wizard, Player, *stdscr, *Playersfp
721 / GLOBAL OUTPUTS: none
724 / We can only see the coordinate of those closer to the origin
726 / Kings and council of the wise can see and can be seen by everyone.
727 / Palantirs are good for seeing everyone; and the valar can use
728 / one to see through a 'cloak' spell.
729 / The valar has no coordinates, and is completely invisible if
732 *************************************************************************/
737 int numusers = 0; /* number of users on file */
739 if (ingameflag && Player.p_blindness)
741 mvaddstr(8, 0, "You cannot see anyone.\n");
745 fseek(Playersfp, 0L, 0);
747 "Name X Y Lvl Type Login Status\n");
749 while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
751 if (Other.p_status == S_NOTUSED
752 /* record is unused */
753 || (Other.p_specialtype == SC_VALAR && Other.p_status == S_CLOAKED))
757 /* wizard can see everything on file */
764 /* must be playing for the rest of these conditions */
765 (Player.p_specialtype >= SC_KING
766 /* kings and higher can see others */
767 || Other.p_specialtype >= SC_KING
768 /* kings and higher can be seen by others */
769 || Circle >= CIRCLE(Other.p_x, Other.p_y)
770 /* those nearer the origin can be seen */
771 || Player.p_palantir)
772 /* palantir enables one to see others */
773 && (Other.p_status != S_CLOAKED
774 || (Player.p_specialtype == SC_VALAR && Player.p_palantir))
775 /* not cloaked; valar can see through cloak with a palantir */
776 && Other.p_specialtype != SC_VALAR)
778 /* coordinates should be printed */
779 printw("%-20s %8.0f %8.0f ",
780 Other.p_name, Other.p_x, Other.p_y);
782 /* cannot see player's coordinates */
783 printw("%-20s %19.19s ",
784 Other.p_name, descrlocation(&Other, TRUE));
786 printw("%6.0f %s %-9.9s%s\n", Other.p_level, descrtype(&Other, TRUE),
787 Other.p_login, descrstatus(&Other));
789 if ((numusers % (LINES - 10)) == 0)
797 printw("Total players on file = %d\n", numusers);
801 /************************************************************************
803 / FUNCTION NAME: throneroom()
805 / FUNCTION: king stuff upon entering throne
807 / AUTHOR: E. A. Estes, 12/16/85
813 / MODULES CALLED: writerecord(), fread(), fseek(), fopen(), wmove(), fclose(),
814 / fwrite(), altercoordinates(), waddstr(), fprintf()
816 / GLOBAL INPUTS: *Energyvoidfp, Other, Player, *stdscr,
817 / Enrgyvoid, *Playersfp
819 / GLOBAL OUTPUTS: Other, Player, Changed
822 / If player is not already king, make him/her so if the old king
824 / Clear energy voids with new king.
825 / Print 'decree' prompt.
827 *************************************************************************/
831 FILE *fp; /* to clear energy voids */
832 long loc = 0L; /* location of old king in player file */
834 if (Player.p_specialtype < SC_KING)
835 /* not already king -- assumes crown */
837 fseek(Playersfp, 0L, 0);
838 while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
839 if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED)
842 if (Other.p_status != S_OFF)
843 /* old king is playing */
845 mvaddstr( 4, 0, "The king is playing, so you cannot steal his throne\n");
846 altercoordinates(0.0, 0.0, A_NEAR);
851 /* old king is not playing - remove him/her */
853 Other.p_specialtype = SC_NONE;
856 writerecord(&Other, loc);
861 loc += SZ_PLAYERSTRUCT;
863 /* make player new king */
865 Player.p_specialtype = SC_KING;
866 mvaddstr(4, 0, "You have become king!\n");
868 /* let everyone else know */
869 fp = fopen(_PATH_MESS, "w");
870 fprintf(fp, "All hail the new king!");
873 /* clear all energy voids; retain location of holy grail */
874 fseek(Energyvoidfp, 0L, 0);
875 fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
876 fp = fopen(_PATH_VOID, "w");
877 fwrite((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, fp);
881 mvaddstr(6, 0, "0:Decree ");
884 /************************************************************************
886 / FUNCTION NAME: dotampered()
888 / FUNCTION: king and valar special options
890 / AUTHOR: E. A. Estes, 2/28/86
896 / MODULES CALLED: writerecord(), truncstring(), fread(), fseek(), fopen(),
897 / floor(), wmove(), drandom(), fclose(), fwrite(), sscanf(), strcmp(),
898 / infloat(), waddstr(), findname(), distance(), userlist(), mvprintw(),
899 / allocvoid(), getanswer(), getstring(), wclrtoeol(), writevoid()
901 / GLOBAL INPUTS: *Energyvoidfp, Other, Illcmd[], Wizard, Player, *stdscr,
902 / Databuf[], Enrgyvoid
904 / GLOBAL OUTPUTS: Other, Player, Enrgyvoid
907 / Tamper with other players. Handle king/valar specific options.
909 *************************************************************************/
913 short tamper; /* value for tampering with other players */
914 char *option; /* pointer to option description */
915 double temp1 = 0.0, temp2 = 0.0; /* other tampering values */
917 long loc; /* location in energy void file */
918 FILE *fp; /* for opening gold file */
922 if (Player.p_specialtype < SC_COUNCIL && !Wizard)
925 addstr("1:Transport 2:Curse 3:Energy Void 4:Bestow 5:Collect Taxes ");
927 ch = getanswer(" ", TRUE);
933 case '1': /* transport someone */
934 tamper = T_TRANSPORT;
935 option = "transport";
938 case '2': /* curse another */
943 case '3': /* create energy void */
944 if ((loc = allocvoid()) > 20L * SZ_VOIDSTRUCT)
945 /* can only have 20 void active at once */
946 mvaddstr(5, 0, "Sorry, void creation limit reached.\n");
949 addstr("Enter the X Y coordinates of void ? ");
950 getstring(Databuf, SZ_DATABUF);
951 sscanf(Databuf, "%lf %lf", &temp1, &temp2);
952 Enrgyvoid.ev_x = floor(temp1);
953 Enrgyvoid.ev_y = floor(temp2);
954 Enrgyvoid.ev_active = TRUE;
955 writevoid(&Enrgyvoid, loc);
956 mvaddstr(5, 0, "It is done.\n");
960 case '4': /* bestow gold to subject */
962 addstr("How much gold to bestow ? ");
964 if (temp1 > Player.p_gold || temp1 < 0)
966 mvaddstr(5, 0, "You don't have that !\n");
970 /* adjust gold after we are sure it will be given to someone */
971 option = "give gold to";
974 case '5': /* collect accumulated taxes */
975 if ((fp = fopen(_PATH_GOLD, "r+")) != NULL)
978 fread((char *) &temp1, sizeof(double), 1, fp);
980 /* clear out value */
982 fwrite((char *) &temp2, sizeof(double), 1, fp);
986 mvprintw(4, 0, "You have collected %.0f in gold.\n", temp1);
987 Player.p_gold += floor(temp1);
993 /* end of king options */
996 /* council of wise, valar, wizard options */
999 if (Player.p_palantir || Wizard)
1000 addstr("2:Seek Grail ");
1001 if (Player.p_specialtype == SC_VALAR || Wizard)
1002 addstr("3:Throw Monster 4:Relocate 5:Bless ");
1004 addstr("6:Vaporize ");
1006 ch = getanswer(" ", TRUE);
1009 if (ch > '2' && Player.p_specialtype != SC_VALAR)
1015 if (Player.p_mana < MM_INTERVENE)
1017 mvaddstr(5, 0, "No mana left.\n");
1021 Player.p_mana -= MM_INTERVENE;
1026 case '1': /* heal another */
1031 case '2': /* seek grail */
1032 if (Player.p_palantir)
1033 /* need a palantir to seek */
1035 fseek(Energyvoidfp, 0L, 0);
1036 fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
1037 temp1 = distance(Player.p_x, Enrgyvoid.ev_x, Player.p_y, Enrgyvoid.ev_y);
1038 temp1 += ROLL(-temp1 / 10.0, temp1 / 5.0); /* add some error */
1039 mvprintw(5, 0, "The palantir says the Grail is about %.0f away.\n", temp1);
1043 mvaddstr(5, 0, "You need a palantir to seek the Grail.\n");
1046 case '3': /* lob monster at someone */
1047 mvaddstr(4, 0, "Which monster [0-99] ? ");
1049 temp1 = MAX(0.0, MIN(99.0, temp1));
1051 option = "throw a monster at";
1054 case '4': /* move another player */
1055 mvaddstr(4, 0, "New X Y coordinates ? ");
1056 getstring(Databuf, SZ_DATABUF);
1057 sscanf(Databuf, "%lf %lf", &temp1, &temp2);
1058 tamper = T_RELOCATE;
1059 option = "relocate";
1062 case '5': /* bless a player */
1067 case '6': /* kill off a player */
1070 tamper = T_VAPORIZED;
1071 option = "vaporize";
1081 /* adjust age after we are sure intervention will be done */
1082 /* end of valar, etc. options */
1086 /* prompt for player to affect */
1088 mvprintw(4, 0, "Who do you want to %s ? ", option);
1089 getstring(Databuf, SZ_DATABUF);
1090 truncstring(Databuf);
1092 if (Databuf[0] == '\0')
1098 if (strcmp(Player.p_name, Databuf) != 0)
1099 /* name other than self */
1101 if ((loc = findname(Databuf, &Other)) >= 0L)
1103 if (Other.p_tampered != T_OFF)
1105 mvaddstr(5, 0, "That person has something pending already.\n");
1110 if (tamper == T_RELOCATE
1111 && CIRCLE(temp1, temp2) < CIRCLE(Other.p_x, Other.p_y)
1113 mvaddstr(5, 0, "Cannot move someone closer to the Lord's Chamber.\n");
1116 if (tamper == T_BESTOW) Player.p_gold -= floor(temp1);
1117 if (!Wizard && (tamper == T_HEAL || tamper == T_MONSTER ||
1118 tamper == T_RELOCATE || tamper == T_BLESSED))
1119 Player.p_age += N_AGE; /* age penalty */
1120 Other.p_tampered = tamper;
1121 Other.p_1scratch = floor(temp1);
1122 Other.p_2scratch = floor(temp2);
1123 writerecord(&Other, loc);
1124 mvaddstr(5, 0, "It is done.\n");
1130 /* player not found */
1131 mvaddstr(5, 0, "There is no one by that name.\n");
1135 mvaddstr(5, 0, "You may not do it to yourself!\n");
1138 /************************************************************************
1140 / FUNCTION NAME: writevoid()
1142 / FUNCTION: update energy void entry in energy void file
1144 / AUTHOR: E. A. Estes, 12/4/85
1147 / struct energyvoid *vp - pointer to structure to write to file
1148 / long loc - location in file to update
1150 / RETURN VALUE: none
1152 / MODULES CALLED: fseek(), fwrite(), fflush()
1154 / GLOBAL INPUTS: *Energyvoidfp
1156 / GLOBAL OUTPUTS: none
1159 / Write out energy void structure at specified location.
1161 *************************************************************************/
1164 struct energyvoid *vp;
1168 fseek(Energyvoidfp, loc, 0);
1169 fwrite((char *) vp, SZ_VOIDSTRUCT, 1, Energyvoidfp);
1170 fflush(Energyvoidfp);
1171 fseek(Energyvoidfp, 0L, 0);
1174 /************************************************************************
1176 / FUNCTION NAME: allocvoid()
1178 / FUNCTION: allocate space for a new energy void
1180 / AUTHOR: E. A. Estes, 12/4/85
1184 / RETURN VALUE: location of new energy void space
1186 / MODULES CALLED: fread(), fseek()
1188 / GLOBAL INPUTS: *Energyvoidfp, Enrgyvoid
1190 / GLOBAL OUTPUTS: none
1193 / Search energy void file for an inactive entry and return its
1195 / If no inactive ones are found, return one more than last location.
1197 *************************************************************************/
1202 long loc = 0L; /* location of new energy void */
1204 fseek(Energyvoidfp, 0L, 0);
1205 while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
1206 if (Enrgyvoid.ev_active)
1207 loc += SZ_VOIDSTRUCT;