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.3 2005/05/31 00:06:26 swildner Exp $
11 /* functions which we need to know about */
13 extern void encounter(int);
15 extern int getanswer(const char *, bool);
16 extern void getstring(char *, int);
17 extern double infloat(void);
18 extern int inputoption(void);
19 extern void more(int);
21 extern void altercoordinates(double, double, int);
22 extern void collecttaxes(double, double);
23 extern void death(const char *);
24 extern const char *descrlocation(struct player
*, bool);
25 extern const char *descrstatus(struct player
*);
26 extern const char *descrtype(struct player
*, bool);
27 extern void displaystats(void);
28 extern double distance(double, double, double, double);
29 extern long findname(char *, struct player
*);
30 extern void readmessage(void);
31 extern void readrecord(struct player
*, long);
32 extern void truncstring(char *);
33 extern void writerecord(struct player
*, long);
35 extern double drandom(void);
37 void checkbattle(void);
38 void battleplayer(long);
40 void checktampered(void);
41 void tampered(int, double, double);
43 void throneroom(void);
44 void dotampered(void);
45 void writevoid(struct energyvoid
*, long);
46 size_t allocvoid(void);
48 /************************************************************************
50 / FUNCTION NAME: checkbattle()
52 / FUNCTION: check to see if current player should battle another
54 / AUTHOR: E. A. Estes, 12/4/85
60 / MODULES CALLED: battleplayer(), fread(), fseek()
62 / GLOBAL INPUTS: Other, Users, Player, Fileloc, *Playersfp
64 / GLOBAL OUTPUTS: Users
67 / Seach player file for a foe at the same coordinates as the
69 / Also update user count.
71 *************************************************************************/
76 long foeloc
= 0L; /* location in file of person to fight */
79 fseek(Playersfp
, 0L, 0);
81 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
83 if (Other
.p_status
!= S_OFF
84 && Other
.p_status
!= S_NOTUSED
85 && Other
.p_status
!= S_HUNGUP
86 && (Other
.p_status
!= S_CLOAKED
|| Other
.p_specialtype
!= SC_VALAR
))
87 /* player is on and not a cloaked valar */
91 if (Player
.p_x
== Other
.p_x
92 && Player
.p_y
== Other
.p_y
93 /* same coordinates */
96 && Player
.p_status
== S_PLAYING
97 && (Other
.p_status
== S_PLAYING
|| Other
.p_status
== S_INBATTLE
)
98 /* both are playing */
99 && Other
.p_specialtype
!= SC_VALAR
100 && Player
.p_specialtype
!= SC_VALAR
)
101 /* neither is valar */
103 battleplayer(foeloc
);
107 foeloc
+= SZ_PLAYERSTRUCT
;
111 /************************************************************************
113 / FUNCTION NAME: battleplayer()
115 / FUNCTION: inter-terminal battle with another player
117 / AUTHOR: E. A. Estes, 2/15/86
120 / long foeplace - location in player file of person to battle
124 / MODULES CALLED: readrecord(), readmessage(), writerecord(), collecttaxes(),
125 / displaystats(), fabs(), more(), death(), sleep(), wmove(), waddch(), printw(),
126 / myturn(), altercoordinates(), waddstr(), wrefresh(), mvprintw(),
127 / getanswer(), wclrtoeol(), wclrtobot()
129 / GLOBAL INPUTS: Foestrikes, LINES, Lines, Other, Shield, Player, *stdscr,
130 / Fileloc, *Enemyname
132 / GLOBAL OUTPUTS: Foestrikes, Lines, Shield, Player, Luckout, *Enemyname
135 / Inter-terminal battle is a very fragile and slightly klugy thing.
136 / At any time, one player is master and the other is slave.
137 / We pick who is master first by speed and level. After that,
138 / the slave waits for the master to relinquish its turn, and
139 / the slave becomes master, and so on.
141 / The items in the player structure which control the handshake are:
143 / master increments this to relinquish control
145 / master sets this to specify particular action
147 / set to total damage inflicted so far; changes to indicate action
149 *************************************************************************/
152 battleplayer(long foeplace
)
154 double dtemp
; /* for temporary calculations */
155 double oldhits
= 0.0; /* previous damage inflicted by foe */
156 int loop
; /* for timing out */
158 short oldtampered
; /* old value of foe's p_tampered */
162 mvaddstr(4, 0, "Preparing for battle!\n");
169 /* set up variables, file, etc. */
170 Player
.p_status
= S_INBATTLE
;
171 Shield
= Player
.p_energy
;
173 /* if p_tampered is not 0, someone else may try to change it (king, etc.) */
174 Player
.p_tampered
= oldtampered
= 1;
175 Player
.p_1scratch
= 0.0;
176 Player
.p_istat
= I_OFF
;
178 readrecord(&Other
, foeplace
);
179 if (fabs(Player
.p_level
- Other
.p_level
) > 20.0)
180 /* see if players are greatly mismatched */
182 dtemp
= (Player
.p_level
- Other
.p_level
) / MAX(Player
.p_level
, Other
.p_level
);
184 /* foe outweighs this one */
185 Player
.p_speed
*= 2.0;
188 writerecord(&Player
, Fileloc
); /* write out all our info */
190 if (Player
.p_blindness
)
191 Enemyname
= "someone";
193 Enemyname
= Other
.p_name
;
195 mvprintw(6, 0, "You have encountered %s Level: %.0f\n", Enemyname
, Other
.p_level
);
198 for (loop
= 0; Other
.p_status
!= S_INBATTLE
&& loop
< 30; ++loop
)
199 /* wait for foe to respond */
201 readrecord(&Other
, foeplace
);
205 if (Other
.p_status
!= S_INBATTLE
)
206 /* foe did not respond */
208 mvprintw(5, 0, "%s is not responding.\n", Enemyname
);
211 /* else, we are ready to battle */
217 * determine who is first master
218 * if neither player is faster, check level
219 * if neither level is greater, battle is not allowed
220 * (this should never happen, but we have to handle it)
222 if (Player
.p_speed
> Other
.p_speed
)
224 else if (Other
.p_speed
> Player
.p_speed
)
226 else if (Player
.p_level
> Other
.p_level
)
228 else if (Other
.p_level
> Player
.p_level
)
231 /* no one is faster */
233 printw("You can't fight %s yet.", Enemyname
);
241 mvprintw(1, 26, "%20.0f", Shield
); /* overprint energy */
244 /* take action against foe */
247 /* wait for foe to take action */
249 mvaddstr(4, 0, "Waiting...\n");
253 for (loop
= 0; loop
< 20; ++loop
)
254 /* wait for foe to act */
256 readrecord(&Other
, foeplace
);
257 if (Other
.p_1scratch
!= oldhits
)
258 /* p_1scratch changes to indicate action */
261 /* wait and try again */
269 if (Other
.p_1scratch
== oldhits
)
272 mvaddstr(22, 0, "Timeout: waiting for response. Do you want to wait ? ");
273 ch
= getanswer("NY", FALSE
);
282 /* foe took action */
284 switch (Other
.p_istat
)
286 case I_RAN
: /* foe ran away */
287 mvprintw(Lines
++, 0, "%s ran away!", Enemyname
);
290 case I_STUCK
: /* foe tried to run, but couldn't */
291 mvprintw(Lines
++, 0, "%s tried to run away.", Enemyname
);
294 case I_BLEWIT
: /* foe tried to luckout, but didn't */
295 mvprintw(Lines
++, 0, "%s tried to luckout!", Enemyname
);
299 dtemp
= Other
.p_1scratch
- oldhits
;
300 mvprintw(Lines
++, 0, "%s hit you %.0f times!", Enemyname
, dtemp
);
305 oldhits
= Other
.p_1scratch
; /* keep track of old hits */
307 if (Other
.p_tampered
!= oldtampered
)
308 /* p_tampered changes to relinquish turn */
310 oldtampered
= Other
.p_tampered
;
316 /* decide what happens next */
318 if (Lines
> LINES
- 2)
325 if (Other
.p_istat
== I_KILLED
|| Shield
< 0.0)
328 Shield
= -2.0; /* insure this value is negative */
332 if (Player
.p_istat
== I_KILLED
)
333 /* we killed foe; award treasre */
335 mvprintw(Lines
++, 0, "You killed %s!", Enemyname
);
336 Player
.p_experience
+= Other
.p_experience
;
337 Player
.p_crowns
+= (Player
.p_level
< 1000.0) ? Other
.p_crowns
: 0;
338 Player
.p_amulets
+= Other
.p_amulets
;
339 Player
.p_charms
+= Other
.p_charms
;
340 collecttaxes(Other
.p_gold
, Other
.p_gems
);
341 Player
.p_sword
= MAX(Player
.p_sword
, Other
.p_sword
);
342 Player
.p_shield
= MAX(Player
.p_shield
, Other
.p_shield
);
343 Player
.p_quksilver
= MAX(Player
.p_quksilver
, Other
.p_quksilver
);
344 if (Other
.p_virgin
&& !Player
.p_virgin
)
346 mvaddstr(Lines
++, 0, "You have rescued a virgin. Will you be honorable ? ");
347 if ((ch
= getanswer("YN", FALSE
)) == 'Y')
348 Player
.p_virgin
= TRUE
;
352 Player
.p_experience
+= 8000.0;
355 sleep(3); /* give other person time to die */
358 else if (Player
.p_istat
== I_RAN
|| Other
.p_istat
== I_RAN
)
359 /* either player ran away */
364 /* clean up things and leave */
365 writerecord(&Player
, Fileloc
); /* update a final time */
366 altercoordinates(0.0, 0.0, A_NEAR
); /* move away from battle site */
367 Player
.p_energy
= Shield
; /* set energy to actual value */
368 Player
.p_tampered
= T_OFF
; /* clear p_tampered */
370 more(Lines
); /* pause */
373 clrtobot(); /* clear bottom area of screen */
375 if (Player
.p_energy
< 0.0)
377 death("Interterminal battle");
380 /************************************************************************
382 / FUNCTION NAME: myturn()
384 / FUNCTION: process players action against foe in battle
386 / AUTHOR: E. A. Estes, 2/7/86
392 / MODULES CALLED: writerecord(), inputoption(), floor(), wmove(), drandom(),
393 / waddstr(), wrefresh(), mvprintw(), wclrtoeol(), wclrtobot()
395 / GLOBAL INPUTS: Lines, Other, Player, *stdscr, Fileloc, Luckout,
398 / GLOBAL OUTPUTS: Foestrikes, Lines, Player, Luckout
401 / Take action action against foe, and decide who is master
402 / for next iteration.
404 *************************************************************************/
409 double dtemp
; /* for temporary calculations */
412 mvaddstr(7, 0, "1:Fight 2:Run Away! 3:Power Blast ");
416 addstr("4:Luckout ");
425 dtemp
= ROLL(2.0, Player
.p_might
);
427 mvprintw(Lines
++, 0, "You hit %s %.0f times!", Enemyname
, dtemp
);
429 Player
.p_1scratch
+= dtemp
;
430 Player
.p_istat
= I_OFF
;
433 case '2': /* run away */
434 Player
.p_1scratch
-= 1.0; /* change this to indicate action */
435 if (drandom() > 0.25)
437 mvaddstr(Lines
++, 0, "You got away!");
438 Player
.p_istat
= I_RAN
;
442 mvprintw(Lines
++, 0, "%s is still after you!", Enemyname
);
443 Player
.p_istat
= I_STUCK
;
447 case '3': /* power blast */
448 dtemp
= MIN(Player
.p_mana
, Player
.p_level
* 5.0);
449 Player
.p_mana
-= dtemp
;
450 dtemp
*= (drandom() + 0.5) * Player
.p_magiclvl
* 0.2 + 2.0;
451 mvprintw(Lines
++, 0, "You blasted %s !", Enemyname
);
454 case '4': /* luckout */
455 if (Luckout
|| drandom() > 0.1)
458 mvaddstr(Lines
++, 0, "You already tried that!");
461 mvaddstr(Lines
++, 0, "Not this time . . .");
465 Player
.p_1scratch
-= 1.0;
466 Player
.p_istat
= I_BLEWIT
;
470 mvaddstr(Lines
++, 0, "You just lucked out!");
471 Player
.p_1scratch
= Other
.p_energy
* 1.1;
477 Player
.p_1scratch
= floor(Player
.p_1scratch
); /* clean up any mess */
479 if (Player
.p_1scratch
> Other
.p_energy
)
480 Player
.p_istat
= I_KILLED
;
481 else if (drandom() * Player
.p_speed
< drandom() * Other
.p_speed
)
482 /* relinquish control */
488 writerecord(&Player
, Fileloc
); /* let foe know what we did */
491 /************************************************************************
493 / FUNCTION NAME: checktampered()
495 / FUNCTION: check if current player has been tampered with
497 / AUTHOR: E. A. Estes, 12/4/85
503 / MODULES CALLED: readrecord(), fread(), fseek(), tampered(), writevoid()
505 / GLOBAL INPUTS: *Energyvoidfp, Other, Player, Fileloc, Enrgyvoid
507 / GLOBAL OUTPUTS: Enrgyvoid
510 / Check for energy voids, holy grail, and tampering by other
513 *************************************************************************/
518 long loc
= 0L; /* location in energy void file */
520 /* first check for energy voids */
521 fseek(Energyvoidfp
, 0L, 0);
522 while (fread((char *) &Enrgyvoid
, SZ_VOIDSTRUCT
, 1, Energyvoidfp
) == 1)
523 if (Enrgyvoid
.ev_active
524 && Enrgyvoid
.ev_x
== Player
.p_x
525 && Enrgyvoid
.ev_y
== Player
.p_y
)
529 /* not the holy grail; inactivate energy void */
531 Enrgyvoid
.ev_active
= FALSE
;
532 writevoid(&Enrgyvoid
, loc
);
533 tampered(T_NRGVOID
, 0.0, 0.0);
535 else if (Player
.p_status
!= S_CLOAKED
)
537 tampered(T_GRAIL
, 0.0, 0.0);
541 loc
+= SZ_VOIDSTRUCT
;
543 /* now check for other things */
544 readrecord(&Other
, Fileloc
);
545 if (Other
.p_tampered
!= T_OFF
)
546 tampered(Other
.p_tampered
, Other
.p_1scratch
, Other
.p_2scratch
);
549 /************************************************************************
551 / FUNCTION NAME: tampered()
553 / FUNCTION: take care of tampering by other players
555 / AUTHOR: E. A. Estes, 12/4/85
558 / int what - what type of tampering
559 / double arg1, arg2 - rest of tampering info
563 / MODULES CALLED: writerecord(), more(), fread(), death(), fseek(), sleep(),
564 / floor(), wmove(), waddch(), drandom(), printw(), altercoordinates(),
565 / waddstr(), wrefresh(), encounter(), writevoid()
567 / GLOBAL INPUTS: Other, Player, *stdscr, Enrgyvoid, *Playersfp
569 / GLOBAL OUTPUTS: Other, Player, Changed, Enrgyvoid
572 / Take care of energy voids, holy grail, decree and intervention
573 / action on current player.
575 *************************************************************************/
578 tampered(int what
, double arg1
, double arg2
)
580 long loc
; /* location in file of other players */
585 Player
.p_tampered
= T_OFF
; /* no longer tampered with */
590 addstr("You've hit an energy void !\n");
591 Player
.p_mana
/= 3.0;
592 Player
.p_energy
/= 2.0;
593 Player
.p_gold
= floor(Player
.p_gold
/1.25) + 0.1;
594 altercoordinates(0.0, 0.0, A_NEAR
);
598 addstr("The king transported you ! ");
599 if (Player
.p_charms
> 0)
601 addstr("But your charm saved you. . .\n");
606 altercoordinates(0.0, 0.0, A_FAR
);
612 printw("The king has bestowed %.0f gold pieces on you !\n", arg1
);
613 Player
.p_gold
+= arg1
;
617 addstr("You've been cursed ! ");
618 if (Player
.p_blessing
)
620 addstr("But your blessing saved you. . .\n");
621 Player
.p_blessing
= FALSE
;
626 Player
.p_poison
+= 2.0;
627 Player
.p_energy
= 10.0;
628 Player
.p_maxenergy
*= 0.95;
629 Player
.p_status
= S_PLAYING
; /* no longer cloaked */
634 addstr("You have been vaporized!\n");
636 death("Vaporization");
640 addstr("The Valar zapped you with a monster!\n");
642 encounter((int) arg1
);
646 addstr("The Valar has blessed you!\n");
647 Player
.p_energy
= (Player
.p_maxenergy
*= 1.05) + Player
.p_shield
;
648 Player
.p_mana
+= 500.0;
649 Player
.p_strength
+= 0.5;
650 Player
.p_brains
+= 0.5;
651 Player
.p_magiclvl
+= 0.5;
652 Player
.p_poison
= MIN(0.5, Player
.p_poison
);
656 addstr("You've been relocated. . .\n");
657 altercoordinates(arg1
, arg2
, A_FORCED
);
661 addstr("You've been healed!\n");
662 Player
.p_poison
-= 0.25;
663 Player
.p_energy
= Player
.p_maxenergy
+ Player
.p_shield
;
667 addstr("You are no longer Valar!\n");
668 Player
.p_specialtype
= SC_COUNCIL
;
672 addstr("You have found The Holy Grail!!\n");
673 if (Player
.p_specialtype
< SC_COUNCIL
)
674 /* must be council of wise to behold grail */
676 addstr("However, you are not experienced enough to behold it.\n");
677 Player
.p_sin
*= Player
.p_sin
;
678 Player
.p_mana
+= 1000;
680 else if (Player
.p_specialtype
== SC_VALAR
681 || Player
.p_specialtype
== SC_EXVALAR
)
683 addstr("You have made it to the position of Valar once already.\n");
684 addstr("The Grail is of no more use to you now.\n");
688 addstr("It is now time to see if you are worthy to behold it. . .\n");
692 if (drandom() / 2.0 < Player
.p_sin
)
694 addstr("You have failed!\n");
701 Player
.p_experience
=
702 Player
.p_quickness
= 1.0;
704 altercoordinates(1.0, 1.0, A_FORCED
);
705 Player
.p_level
= 0.0;
709 addstr("You made to position of Valar!\n");
710 Player
.p_specialtype
= SC_VALAR
;
712 fseek(Playersfp
, 0L, 0);
714 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
715 /* search for existing valar */
716 if (Other
.p_specialtype
== SC_VALAR
717 && Other
.p_status
!= S_NOTUSED
)
718 /* found old valar */
720 Other
.p_tampered
= T_EXVALAR
;
721 writerecord(&Other
, loc
);
725 loc
+= SZ_PLAYERSTRUCT
;
729 /* move grail to new location */
730 Enrgyvoid
.ev_active
= TRUE
;
731 Enrgyvoid
.ev_x
= ROLL(-1.0e6
, 2.0e6
);
732 Enrgyvoid
.ev_y
= ROLL(-1.0e6
, 2.0e6
);
733 writevoid(&Enrgyvoid
, 0L);
740 /************************************************************************
742 / FUNCTION NAME: userlist()
744 / FUNCTION: print list of players and locations
746 / AUTHOR: E. A. Estes, 2/28/86
749 / bool ingameflag - set if called while playing
753 / MODULES CALLED: descrstatus(), descrlocation(), more(), fread(), fseek(),
754 / floor(), wmove(), printw(), waddstr(), distance(), wrefresh(),
755 / descrtype(), wclrtobot()
757 / GLOBAL INPUTS: LINES, Other, Circle, Wizard, Player, *stdscr, *Playersfp
759 / GLOBAL OUTPUTS: none
762 / We can only see the coordinate of those closer to the origin
764 / Kings and council of the wise can see and can be seen by everyone.
765 / Palantirs are good for seeing everyone; and the valar can use
766 / one to see through a 'cloak' spell.
767 / The valar has no coordinates, and is completely invisible if
770 *************************************************************************/
773 userlist(bool ingameflag
)
775 int numusers
= 0; /* number of users on file */
777 if (ingameflag
&& Player
.p_blindness
)
779 mvaddstr(8, 0, "You cannot see anyone.\n");
783 fseek(Playersfp
, 0L, 0);
785 "Name X Y Lvl Type Login Status\n");
787 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
789 if (Other
.p_status
== S_NOTUSED
790 /* record is unused */
791 || (Other
.p_specialtype
== SC_VALAR
&& Other
.p_status
== S_CLOAKED
))
795 /* wizard can see everything on file */
802 /* must be playing for the rest of these conditions */
803 (Player
.p_specialtype
>= SC_KING
804 /* kings and higher can see others */
805 || Other
.p_specialtype
>= SC_KING
806 /* kings and higher can be seen by others */
807 || Circle
>= CIRCLE(Other
.p_x
, Other
.p_y
)
808 /* those nearer the origin can be seen */
809 || Player
.p_palantir
)
810 /* palantir enables one to see others */
811 && (Other
.p_status
!= S_CLOAKED
812 || (Player
.p_specialtype
== SC_VALAR
&& Player
.p_palantir
))
813 /* not cloaked; valar can see through cloak with a palantir */
814 && Other
.p_specialtype
!= SC_VALAR
)
816 /* coordinates should be printed */
817 printw("%-20s %8.0f %8.0f ",
818 Other
.p_name
, Other
.p_x
, Other
.p_y
);
820 /* cannot see player's coordinates */
821 printw("%-20s %19.19s ",
822 Other
.p_name
, descrlocation(&Other
, TRUE
));
824 printw("%6.0f %s %-9.9s%s\n", Other
.p_level
, descrtype(&Other
, TRUE
),
825 Other
.p_login
, descrstatus(&Other
));
827 if ((numusers
% (LINES
- 10)) == 0)
835 printw("Total players on file = %d\n", numusers
);
839 /************************************************************************
841 / FUNCTION NAME: throneroom()
843 / FUNCTION: king stuff upon entering throne
845 / AUTHOR: E. A. Estes, 12/16/85
851 / MODULES CALLED: writerecord(), fread(), fseek(), fopen(), wmove(), fclose(),
852 / fwrite(), altercoordinates(), waddstr(), fprintf()
854 / GLOBAL INPUTS: *Energyvoidfp, Other, Player, *stdscr,
855 / Enrgyvoid, *Playersfp
857 / GLOBAL OUTPUTS: Other, Player, Changed
860 / If player is not already king, make him/her so if the old king
862 / Clear energy voids with new king.
863 / Print 'decree' prompt.
865 *************************************************************************/
870 FILE *fp
; /* to clear energy voids */
871 long loc
= 0L; /* location of old king in player file */
873 if (Player
.p_specialtype
< SC_KING
)
874 /* not already king -- assumes crown */
876 fseek(Playersfp
, 0L, 0);
877 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
878 if (Other
.p_specialtype
== SC_KING
&& Other
.p_status
!= S_NOTUSED
)
881 if (Other
.p_status
!= S_OFF
)
882 /* old king is playing */
884 mvaddstr( 4, 0, "The king is playing, so you cannot steal his throne\n");
885 altercoordinates(0.0, 0.0, A_NEAR
);
890 /* old king is not playing - remove him/her */
892 Other
.p_specialtype
= SC_NONE
;
895 writerecord(&Other
, loc
);
900 loc
+= SZ_PLAYERSTRUCT
;
902 /* make player new king */
904 Player
.p_specialtype
= SC_KING
;
905 mvaddstr(4, 0, "You have become king!\n");
907 /* let everyone else know */
908 fp
= fopen(_PATH_MESS
, "w");
909 fprintf(fp
, "All hail the new king!");
912 /* clear all energy voids; retain location of holy grail */
913 fseek(Energyvoidfp
, 0L, 0);
914 fread((char *) &Enrgyvoid
, SZ_VOIDSTRUCT
, 1, Energyvoidfp
);
915 fp
= fopen(_PATH_VOID
, "w");
916 fwrite((char *) &Enrgyvoid
, SZ_VOIDSTRUCT
, 1, fp
);
920 mvaddstr(6, 0, "0:Decree ");
923 /************************************************************************
925 / FUNCTION NAME: dotampered()
927 / FUNCTION: king and valar special options
929 / AUTHOR: E. A. Estes, 2/28/86
935 / MODULES CALLED: writerecord(), truncstring(), fread(), fseek(), fopen(),
936 / floor(), wmove(), drandom(), fclose(), fwrite(), sscanf(), strcmp(),
937 / infloat(), waddstr(), findname(), distance(), userlist(), mvprintw(),
938 / allocvoid(), getanswer(), getstring(), wclrtoeol(), writevoid()
940 / GLOBAL INPUTS: *Energyvoidfp, Other, Illcmd[], Wizard, Player, *stdscr,
941 / Databuf[], Enrgyvoid
943 / GLOBAL OUTPUTS: Other, Player, Enrgyvoid
946 / Tamper with other players. Handle king/valar specific options.
948 *************************************************************************/
953 short tamper
; /* value for tampering with other players */
954 const char *option
; /* pointer to option description */
955 double temp1
= 0.0, temp2
= 0.0; /* other tampering values */
957 long loc
; /* location in energy void file */
958 FILE *fp
; /* for opening gold file */
962 if (Player
.p_specialtype
< SC_COUNCIL
&& !Wizard
)
965 addstr("1:Transport 2:Curse 3:Energy Void 4:Bestow 5:Collect Taxes ");
967 ch
= getanswer(" ", TRUE
);
973 case '1': /* transport someone */
974 tamper
= T_TRANSPORT
;
975 option
= "transport";
978 case '2': /* curse another */
983 case '3': /* create energy void */
984 if ((loc
= allocvoid()) > 20L * (long)SZ_VOIDSTRUCT
)
985 /* can only have 20 void active at once */
986 mvaddstr(5, 0, "Sorry, void creation limit reached.\n");
989 addstr("Enter the X Y coordinates of void ? ");
990 getstring(Databuf
, SZ_DATABUF
);
991 sscanf(Databuf
, "%lf %lf", &temp1
, &temp2
);
992 Enrgyvoid
.ev_x
= floor(temp1
);
993 Enrgyvoid
.ev_y
= floor(temp2
);
994 Enrgyvoid
.ev_active
= TRUE
;
995 writevoid(&Enrgyvoid
, loc
);
996 mvaddstr(5, 0, "It is done.\n");
1000 case '4': /* bestow gold to subject */
1002 addstr("How much gold to bestow ? ");
1004 if (temp1
> Player
.p_gold
|| temp1
< 0)
1006 mvaddstr(5, 0, "You don't have that !\n");
1010 /* adjust gold after we are sure it will be given to someone */
1011 option
= "give gold to";
1014 case '5': /* collect accumulated taxes */
1015 if ((fp
= fopen(_PATH_GOLD
, "r+")) != NULL
)
1018 fread((char *) &temp1
, sizeof(double), 1, fp
);
1020 /* clear out value */
1022 fwrite((char *) &temp2
, sizeof(double), 1, fp
);
1026 mvprintw(4, 0, "You have collected %.0f in gold.\n", temp1
);
1027 Player
.p_gold
+= floor(temp1
);
1033 /* end of king options */
1036 /* council of wise, valar, wizard options */
1039 if (Player
.p_palantir
|| Wizard
)
1040 addstr("2:Seek Grail ");
1041 if (Player
.p_specialtype
== SC_VALAR
|| Wizard
)
1042 addstr("3:Throw Monster 4:Relocate 5:Bless ");
1044 addstr("6:Vaporize ");
1046 ch
= getanswer(" ", TRUE
);
1049 if (ch
> '2' && Player
.p_specialtype
!= SC_VALAR
)
1055 if (Player
.p_mana
< MM_INTERVENE
)
1057 mvaddstr(5, 0, "No mana left.\n");
1061 Player
.p_mana
-= MM_INTERVENE
;
1066 case '1': /* heal another */
1071 case '2': /* seek grail */
1072 if (Player
.p_palantir
)
1073 /* need a palantir to seek */
1075 fseek(Energyvoidfp
, 0L, 0);
1076 fread((char *) &Enrgyvoid
, SZ_VOIDSTRUCT
, 1, Energyvoidfp
);
1077 temp1
= distance(Player
.p_x
, Enrgyvoid
.ev_x
, Player
.p_y
, Enrgyvoid
.ev_y
);
1078 temp1
+= ROLL(-temp1
/ 10.0, temp1
/ 5.0); /* add some error */
1079 mvprintw(5, 0, "The palantir says the Grail is about %.0f away.\n", temp1
);
1083 mvaddstr(5, 0, "You need a palantir to seek the Grail.\n");
1086 case '3': /* lob monster at someone */
1087 mvaddstr(4, 0, "Which monster [0-99] ? ");
1089 temp1
= MAX(0.0, MIN(99.0, temp1
));
1091 option
= "throw a monster at";
1094 case '4': /* move another player */
1095 mvaddstr(4, 0, "New X Y coordinates ? ");
1096 getstring(Databuf
, SZ_DATABUF
);
1097 sscanf(Databuf
, "%lf %lf", &temp1
, &temp2
);
1098 tamper
= T_RELOCATE
;
1099 option
= "relocate";
1102 case '5': /* bless a player */
1107 case '6': /* kill off a player */
1110 tamper
= T_VAPORIZED
;
1111 option
= "vaporize";
1121 /* adjust age after we are sure intervention will be done */
1122 /* end of valar, etc. options */
1126 /* prompt for player to affect */
1128 mvprintw(4, 0, "Who do you want to %s ? ", option
);
1129 getstring(Databuf
, SZ_DATABUF
);
1130 truncstring(Databuf
);
1132 if (Databuf
[0] == '\0')
1138 if (strcmp(Player
.p_name
, Databuf
) != 0)
1139 /* name other than self */
1141 if ((loc
= findname(Databuf
, &Other
)) >= 0L)
1143 if (Other
.p_tampered
!= T_OFF
)
1145 mvaddstr(5, 0, "That person has something pending already.\n");
1150 if (tamper
== T_RELOCATE
1151 && CIRCLE(temp1
, temp2
) < CIRCLE(Other
.p_x
, Other
.p_y
)
1153 mvaddstr(5, 0, "Cannot move someone closer to the Lord's Chamber.\n");
1156 if (tamper
== T_BESTOW
) Player
.p_gold
-= floor(temp1
);
1157 if (!Wizard
&& (tamper
== T_HEAL
|| tamper
== T_MONSTER
||
1158 tamper
== T_RELOCATE
|| tamper
== T_BLESSED
))
1159 Player
.p_age
+= N_AGE
; /* age penalty */
1160 Other
.p_tampered
= tamper
;
1161 Other
.p_1scratch
= floor(temp1
);
1162 Other
.p_2scratch
= floor(temp2
);
1163 writerecord(&Other
, loc
);
1164 mvaddstr(5, 0, "It is done.\n");
1170 /* player not found */
1171 mvaddstr(5, 0, "There is no one by that name.\n");
1175 mvaddstr(5, 0, "You may not do it to yourself!\n");
1178 /************************************************************************
1180 / FUNCTION NAME: writevoid()
1182 / FUNCTION: update energy void entry in energy void file
1184 / AUTHOR: E. A. Estes, 12/4/85
1187 / struct energyvoid *vp - pointer to structure to write to file
1188 / long loc - location in file to update
1190 / RETURN VALUE: none
1192 / MODULES CALLED: fseek(), fwrite(), fflush()
1194 / GLOBAL INPUTS: *Energyvoidfp
1196 / GLOBAL OUTPUTS: none
1199 / Write out energy void structure at specified location.
1201 *************************************************************************/
1204 writevoid(struct energyvoid
*vp
, long loc
)
1207 fseek(Energyvoidfp
, loc
, 0);
1208 fwrite((char *) vp
, SZ_VOIDSTRUCT
, 1, Energyvoidfp
);
1209 fflush(Energyvoidfp
);
1210 fseek(Energyvoidfp
, 0L, 0);
1213 /************************************************************************
1215 / FUNCTION NAME: allocvoid()
1217 / FUNCTION: allocate space for a new energy void
1219 / AUTHOR: E. A. Estes, 12/4/85
1223 / RETURN VALUE: location of new energy void space
1225 / MODULES CALLED: fread(), fseek()
1227 / GLOBAL INPUTS: *Energyvoidfp, Enrgyvoid
1229 / GLOBAL OUTPUTS: none
1232 / Search energy void file for an inactive entry and return its
1234 / If no inactive ones are found, return one more than last location.
1236 *************************************************************************/
1241 size_t loc
= 0; /* location of new energy void */
1243 fseek(Energyvoidfp
, 0L, 0);
1244 while (fread((char *) &Enrgyvoid
, SZ_VOIDSTRUCT
, 1, Energyvoidfp
) == 1)
1245 if (Enrgyvoid
.ev_active
)
1246 loc
+= SZ_VOIDSTRUCT
;