]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - phantasia/main.c
1 /* $NetBSD: main.c,v 1.2 1995/03/24 03:58:54 cgd Exp $ */
4 * Phantasia 3.3.2 -- Interterminal fantasy game
12 * This game is distributed for free as is. It is not guaranteed to work
13 * in every conceivable environment. It is not even guaranteed to work
16 * This game is distributed without notice of copyright, therefore it
17 * may be used in any manner the recipient sees fit. However, the
18 * author assumes no responsibility for maintaining or revising this
19 * game, in its original form, or any derivitives thereof.
21 * The author shall not be responsible for any loss, cost, or damage,
22 * including consequential damage, caused by reliance on this material.
24 * The author makes no warranties, express or implied, including warranties
25 * of merchantability or fitness for a particular purpose or use.
27 * AT&T is in no way connected with this game.
30 #include <sys/types.h>
34 * The program allocates as much file space as it needs to store characters,
35 * so the possibility exists for the character file to grow without bound.
36 * The file is purged upon normal entry to try to avoid that problem.
37 * A similar problem exists for energy voids. To alleviate the problem here,
38 * the void file is cleared with every new king, and a limit is placed
39 * on the size of the energy void file.
43 * Put one line of text into the file 'motd' for announcements, etc.
47 * The scoreboard file is updated when someone dies, and keeps track
48 * of the highest character to date for that login.
49 * Being purged from the character file does not cause the scoreboard
54 * All source files are set up for 'vi' with shiftwidth=4, tabstop=8.
60 * main.c Main routines for Phantasia
65 /***************************************************************************
66 / FUNCTION NAME: main()
68 / FUNCTION: initialize state, and call main process
70 / AUTHOR: E. A. Estes, 12/4/85
73 / int argc - argument count
74 / char **argv - argument vector
78 / MODULES CALLED: monstlist(), checkenemy(), activelist(),
79 / throneroom(), checkbattle(), readmessage(), changestats(), writerecord(),
80 / tradingpost(), adjuststats(), recallplayer(), displaystats(), checktampered(),
81 / fabs(), rollnewplayer(), time(), exit(), sqrt(), floor(), wmove(),
82 / signal(), strcat(), purgeoldplayers(), getuid(), isatty(), wclear(),
83 / strcpy(), system(), altercoordinates(), cleanup(), waddstr(), procmain(),
84 / playinit(), leavegame(), localtime(), getanswer(), neatstuff(), initialstate(),
85 / scorelist(), titlelist()
87 / GLOBAL INPUTS: *Login, Throne, Wizard, Player, *stdscr, Changed, Databuf[],
88 / Fileloc, Stattable[]
90 / GLOBAL OUTPUTS: Wizard, Player, Changed, Fileloc, Timeout, *Statptr
93 / Process arguments, initialize program, and loop forever processing
96 /***************************************************************************/
102 bool noheader
= FALSE
; /* set if don't want header */
103 bool headeronly
= FALSE
; /* set if only want header */
104 bool examine
= FALSE
; /* set if examine a character */
105 long seconds
; /* for time of day */
106 double dtemp
; /* for temporary calculations */
108 initialstate(); /* init globals */
110 /* process arguments */
111 while (--argc
&& (*++argv
)[0] == '-')
114 case 's': /* short */
118 case 'H': /* Header */
122 case 'a': /* all users */
127 case 'p': /* purge old players */
132 case 'S': /* set 'Wizard' */
136 case 'x': /* examine */
140 case 'm': /* monsters */
145 case 'b': /* scoreboard */
151 if (!isatty(0)) /* don't let non-tty's play */
155 playinit(); /* set up to catch signals, init curses */
167 purgeoldplayers(); /* clean up old characters */
175 /* get the player structure filled */
179 mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? ");
181 switch (getanswer("NYQ", FALSE
))
184 Fileloc
= recallplayer();
192 Fileloc
= rollnewplayer();
197 while (Fileloc
< 0L);
199 if (Player
.p_level
> 5.0)
200 /* low level players have long timeout */
203 /* update some important player statistics */
204 strcpy(Player
.p_login
, Login
);
206 Player
.p_lastused
= localtime(&seconds
)->tm_yday
;
207 Player
.p_status
= S_PLAYING
;
208 writerecord(&Player
, Fileloc
);
210 Statptr
= &Stattable
[Player
.p_type
]; /* initialize pointer */
212 /* catch interrupts */
214 sigset(SIGINT
, interrupt
);
217 signal(SIGINT
, interrupt
);
220 signal(SIGINT
, interrupt
);
223 signal(SIGINT
, interrupt
);
226 altercoordinates(Player
.p_x
, Player
.p_y
, A_FORCED
); /* set some flags */
231 /* loop forever, processing input */
234 adjuststats(); /* cleanup stats */
236 if (Throne
&& Player
.p_crowns
== 0 && Player
.p_specialtype
!= SC_KING
)
237 /* not allowed on throne -- move */
239 mvaddstr(5,0,"You're not allowed in the Lord's Chamber without a crown.\n");
240 altercoordinates(0.0, 0.0, A_NEAR
);
243 checktampered(); /* check for energy voids, etc. */
245 if (Player
.p_status
!= S_CLOAKED
247 && (dtemp
= fabs(Player
.p_x
)) == fabs(Player
.p_y
)
252 dtemp
= sqrt(dtemp
/ 100.0);
253 if (floor(dtemp
) == dtemp
)
254 /* |x| / 100 == n*n; at a trading post */
261 checkbattle(); /* check for player to player battle */
262 neatstuff(); /* gurus, medics, etc. */
264 if (Player
.p_status
== S_CLOAKED
)
265 /* costs 3 mana per turn to be cloaked */
266 if (Player
.p_mana
> 3.0)
267 Player
.p_mana
-= 3.0;
269 /* ran out of mana, uncloak */
271 Player
.p_status
= S_PLAYING
;
275 if (Player
.p_status
!= S_PLAYING
&& Player
.p_status
!= S_CLOAKED
)
276 /* change status back to S_PLAYING */
278 Player
.p_status
= S_PLAYING
;
283 /* update file only if important stuff has changed */
285 writerecord(&Player
, Fileloc
);
290 readmessage(); /* read message, if any */
292 displaystats(); /* print statistics */
297 /* maybe make king, print prompt, etc. */
300 /* print status line */
301 addstr("1:Move 2:Players 3:Talk 4:Stats 5:Quit ");
302 if (Player
.p_level
>= MEL_CLOAK
&& Player
.p_magiclvl
>= ML_CLOAK
)
304 if (Player
.p_level
>= MEL_TELEPORT
&& Player
.p_magiclvl
>= ML_TELEPORT
)
305 addstr("7:Teleport ");
306 if (Player
.p_specialtype
>= SC_COUNCIL
|| Wizard
)
307 addstr("8:Intervene ");
309 procmain(); /* process input */
313 /************************************************************************
315 / FUNCTION NAME: initialstate()
317 / FUNCTION: initialize some important global variable
319 / AUTHOR: E. A. Estes, 12/4/85
325 / MODULES CALLED: time(), fopen(), srandom(), error(), getuid(), getlogin(),
330 / GLOBAL OUTPUTS: *Energyvoidfp, Echo, Marsh, *Login, Users, Beyond,
331 / Throne, Wizard, Changed, Okcount, Timeout, Windows, *Monstfp, *Messagefp,
335 / Set global flags, and open files which remain open.
337 /************************************************************************/
351 /* setup login name */
352 if ((Login
= getlogin()) == NULL
)
353 Login
= getpwuid(getuid())->pw_name
;
355 /* open some files */
356 if ((Playersfp
= fopen(_PATH_PEOPLE
, "r+")) == NULL
)
360 if ((Monstfp
= fopen(_PATH_MONST
, "r+")) == NULL
)
364 if ((Messagefp
= fopen(_PATH_MESS
, "r")) == NULL
)
368 if ((Energyvoidfp
= fopen(_PATH_VOID
, "r+")) == NULL
)
372 srandom((unsigned) time((long *) NULL
)); /* prime random numbers */
375 /************************************************************************
377 / FUNCTION NAME: rollnewplayer()
379 / FUNCTION: roll up a new character
381 / AUTHOR: E. A. Estes, 12/4/85
387 / MODULES CALLED: initplayer(), allocrecord(), truncstring(), fabs(), wmove(),
388 / wclear(), sscanf(), strcmp(), genchar(), waddstr(), findname(), mvprintw(),
389 / getanswer(), getstring()
391 / GLOBAL INPUTS: Other, Wizard, Player, *stdscr, Databuf[]
393 / GLOBAL OUTPUTS: Echo
396 / Prompt player, and roll up new character.
398 /************************************************************************/
403 int chartype
; /* character type */
406 initplayer(&Player
); /* initialize player structure */
409 mvaddstr(4, 21, "Which type of character do you want:");
410 mvaddstr(8, 4, "1:Magic User 2:Fighter 3:Elf 4:Dwarf 5:Halfling 6:Experimento ");
412 addstr("7:Super ? ");
413 chartype
= getanswer("1234567", FALSE
);
417 chartype
= getanswer("123456", FALSE
);
422 genchar(chartype
); /* roll up a character */
424 /* print out results */
426 "Strength : %2.0f Quickness: %2.0f Mana : %2.0f\n",
427 Player
.p_strength
, Player
.p_quickness
, Player
.p_mana
);
429 "Energy Level: %2.0f Brains : %2.0f Magic Level: %2.0f\n",
430 Player
.p_energy
, Player
.p_brains
, Player
.p_magiclvl
);
432 if (Player
.p_type
== C_EXPER
|| Player
.p_type
== C_SUPER
)
435 mvaddstr(14, 14, "Type '1' to keep >");
436 ch
= getanswer(" ", TRUE
);
440 if (Player
.p_type
== C_EXPER
|| Player
.p_type
== C_SUPER
)
441 /* get coordinates for experimento */
444 mvaddstr(16, 0, "Enter the X Y coordinates of your experimento ? ");
445 getstring(Databuf
, SZ_DATABUF
);
446 sscanf(Databuf
, "%lf %lf", &Player
.p_x
, &Player
.p_y
);
448 if (fabs(Player
.p_x
) > D_EXPER
|| fabs(Player
.p_y
) > D_EXPER
)
449 mvaddstr(17, 0, "Invalid coordinates. Try again.\n");
455 /* name the new character */
458 "Give your character a name [up to %d characters] ? ", SZ_NAME
- 1);
459 getstring(Player
.p_name
, SZ_NAME
);
460 truncstring(Player
.p_name
); /* remove trailing blanks */
462 if (Player
.p_name
[0] == '\0')
464 mvaddstr(19, 0, "Invalid name.");
465 else if (findname(Player
.p_name
, &Other
) >= 0L)
466 /* cannot have duplicate names */
467 mvaddstr(19, 0, "Name already in use.");
469 /* name is acceptable */
472 addstr(" Pick another.\n");
475 /* get a password for character */
480 mvaddstr(20, 0, "Give your character a password [up to 8 characters] ? ");
481 getstring(Player
.p_password
, SZ_PASSWORD
);
482 mvaddstr(21, 0, "One more time to verify ? ");
483 getstring(Databuf
, SZ_PASSWORD
);
485 while (strcmp(Player
.p_password
, Databuf
) != 0);
489 return(allocrecord());
492 /************************************************************************
494 / FUNCTION NAME: procmain()
496 / FUNCTION: process input from player
498 / AUTHOR: E. A. Estes, 12/4/85
504 / MODULES CALLED: dotampered(), changestats(), inputoption(), allstatslist(),
505 / fopen(), wmove(), drandom(), sscanf(), fclose(), altercoordinates(),
506 / waddstr(), fprintf(), distance(), userlist(), leavegame(), encounter(),
507 / getstring(), wclrtobot()
509 / GLOBAL INPUTS: Circle, Illcmd[], Throne, Wizard, Player, *stdscr,
510 / Databuf[], Illmove[]
512 / GLOBAL OUTPUTS: Player, Changed
515 / Process main menu options.
517 /************************************************************************/
522 double x
; /* desired new x coordinate */
523 double y
; /* desired new y coordinate */
524 double temp
; /* for temporary calculations */
525 FILE *fp
; /* for opening files */
526 register int loop
; /* a loop counter */
527 bool hasmoved
= FALSE
; /* set if player has moved */
530 mvaddstr(4, 0, "\n\n"); /* clear status area */
533 clrtobot(); /* clear data on bottom area of screen */
535 if (Player
.p_specialtype
== SC_VALAR
&& (ch
== '1' || ch
== '7'))
536 /* valar cannot move */
541 case 'K': /* move up/north */
544 y
= Player
.p_y
+ MAXMOVE();
548 case 'J': /* move down/south */
551 y
= Player
.p_y
- MAXMOVE();
555 case 'L': /* move right/east */
557 x
= Player
.p_x
+ MAXMOVE();
562 case 'H': /* move left/west */
564 x
= Player
.p_x
- MAXMOVE();
570 Player
.p_energy
+= (Player
.p_maxenergy
+ Player
.p_shield
) / 15.0
571 + Player
.p_level
/ 3.0 + 2.0;
573 MIN(Player
.p_energy
, Player
.p_maxenergy
+ Player
.p_shield
);
575 if (Player
.p_status
!= S_CLOAKED
)
576 /* cannot find mana if cloaked */
578 Player
.p_mana
+= (Circle
+ Player
.p_level
) / 4.0;
580 if (drandom() < 0.2 && Player
.p_status
== S_PLAYING
&& !Throne
)
581 /* wandering monster */
586 case 'X': /* change/examine a character */
591 for (loop
= 3; loop
; --loop
)
593 mvaddstr(4, 0, "X Y Coordinates ? ");
594 getstring(Databuf
, SZ_DATABUF
);
596 if (sscanf(Databuf
, "%lf %lf", &x
, &y
) != 2)
597 mvaddstr(5, 0, "Try again\n");
598 else if (distance(Player
.p_x
, x
, Player
.p_y
, y
) > MAXMOVE())
608 case '2': /* players */
612 case '3': /* message */
613 mvaddstr(4, 0, "Message ? ");
614 getstring(Databuf
, SZ_DATABUF
);
615 /* we open the file for writing to erase any data which is already there */
616 fp
= fopen(_PATH_MESS
, "w");
617 if (Databuf
[0] != '\0')
618 fprintf(fp
, "%s: %s", Player
.p_name
, Databuf
);
622 case '4': /* stats */
626 case '5': /* good-bye */
630 case '6': /* cloak */
631 if (Player
.p_level
< MEL_CLOAK
|| Player
.p_magiclvl
< ML_CLOAK
)
633 else if (Player
.p_status
== S_CLOAKED
)
634 Player
.p_status
= S_PLAYING
;
635 else if (Player
.p_mana
< MM_CLOAK
)
636 mvaddstr(5, 0, "No mana left.\n");
640 Player
.p_mana
-= MM_CLOAK
;
641 Player
.p_status
= S_CLOAKED
;
645 case '7': /* teleport */
647 * conditions for teleport
648 * - 20 per (level plus magic level)
649 * - OR council of the wise or valar or ex-valar
650 * - OR transport from throne
651 * transports from throne cost no mana
653 if (Player
.p_level
< MEL_TELEPORT
|| Player
.p_magiclvl
< ML_TELEPORT
)
656 for (loop
= 3; loop
; --loop
)
658 mvaddstr(4, 0, "X Y Coordinates ? ");
659 getstring(Databuf
, SZ_DATABUF
);
661 if (sscanf(Databuf
, "%lf %lf", &x
, &y
) == 2)
663 temp
= distance(Player
.p_x
, x
, Player
.p_y
, y
);
665 /* can transport anywhere from throne */
666 && Player
.p_specialtype
<= SC_COUNCIL
667 /* council, valar can transport anywhere */
668 && temp
> (Player
.p_level
+ Player
.p_magiclvl
) * 20.0)
669 /* can only move 20 per exp. level + mag. level */
673 temp
= (temp
/ 75.0 + 1.0) * 20.0; /* mana used */
675 if (!Throne
&& temp
> Player
.p_mana
)
676 mvaddstr(5, 0, "Not enough power for that distance.\n");
680 Player
.p_mana
-= temp
;
690 case '9': /* monster */
692 /* no monsters while on throne */
693 mvaddstr(5, 0, "No monsters in the chamber!\n");
694 else if (Player
.p_specialtype
!= SC_VALAR
)
695 /* the valar cannot call monsters */
697 Player
.p_sin
+= 1e-6;
702 case '0': /* decree */
703 if (Wizard
|| Player
.p_specialtype
== SC_KING
&& Throne
)
704 /* kings must be on throne to decree */
710 case '8': /* intervention */
711 if (Wizard
|| Player
.p_specialtype
>= SC_COUNCIL
)
719 /* player has moved -- alter coordinates, and do random monster */
721 altercoordinates(x
, y
, A_SPECIFIC
);
723 if (drandom() < 0.2 && Player
.p_status
== S_PLAYING
&& !Throne
)
728 /************************************************************************
730 / FUNCTION NAME: titlelist()
732 / FUNCTION: print title page
734 / AUTHOR: E. A. Estes, 12/4/85
740 / MODULES CALLED: fread(), fseek(), fopen(), fgets(), wmove(), strcpy(),
741 / fclose(), strlen(), waddstr(), sprintf(), wrefresh()
743 / GLOBAL INPUTS: Lines, Other, *stdscr, Databuf[], *Playersfp
745 / GLOBAL OUTPUTS: Lines
748 / Print important information about game, players, etc.
750 /************************************************************************/
754 register FILE *fp
; /* used for opening various files */
755 bool councilfound
= FALSE
; /* set if we find a member of the council */
756 bool kingfound
= FALSE
; /* set if we find a king */
757 double hiexp
, nxtexp
; /* used for finding the two highest players */
758 double hilvl
, nxtlvl
; /* used for finding the two highest players */
759 char hiname
[21], nxtname
[21];/* used for finding the two highest players */
761 mvaddstr(0, 14, "W e l c o m e t o P h a n t a s i a (vers. 3.3.2)!");
763 /* print message of the day */
764 if ((fp
= fopen(_PATH_MOTD
, "r")) != NULL
765 && fgets(Databuf
, SZ_DATABUF
, fp
) != NULL
)
767 mvaddstr(2, 40 - strlen(Databuf
) / 2, Databuf
);
771 /* search for king */
772 fseek(Playersfp
, 0L, 0);
773 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
774 if (Other
.p_specialtype
== SC_KING
&& Other
.p_status
!= S_NOTUSED
)
777 sprintf(Databuf
, "The present ruler is %s Level:%.0f",
778 Other
.p_name
, Other
.p_level
);
779 mvaddstr(4, 40 - strlen(Databuf
) / 2, Databuf
);
785 mvaddstr(4, 24, "There is no ruler at this time.");
787 /* search for valar */
788 fseek(Playersfp
, 0L, 0);
789 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
790 if (Other
.p_specialtype
== SC_VALAR
&& Other
.p_status
!= S_NOTUSED
)
791 /* found the valar */
793 sprintf(Databuf
, "The Valar is %s Login: %s", Other
.p_name
, Other
.p_login
);
794 mvaddstr(6, 40 - strlen(Databuf
) / 2 , Databuf
);
798 /* search for council of the wise */
799 fseek(Playersfp
, 0L, 0);
801 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
802 if (Other
.p_specialtype
== SC_COUNCIL
&& Other
.p_status
!= S_NOTUSED
)
803 /* found a member of the council */
807 mvaddstr(8, 30, "Council of the Wise:");
811 /* This assumes a finite (<=5) number of C.O.W.: */
812 sprintf(Databuf
, "%s Login: %s", Other
.p_name
, Other
.p_login
);
813 mvaddstr(Lines
++, 40 - strlen(Databuf
) / 2, Databuf
);
816 /* search for the two highest players */
817 nxtname
[0] = hiname
[0] = '\0';
821 fseek(Playersfp
, 0L, 0);
822 while (fread((char *) &Other
, SZ_PLAYERSTRUCT
, 1, Playersfp
) == 1)
823 if (Other
.p_experience
> hiexp
&& Other
.p_specialtype
<= SC_KING
&& Other
.p_status
!= S_NOTUSED
)
824 /* highest found so far */
827 hiexp
= Other
.p_experience
;
829 hilvl
= Other
.p_level
;
830 strcpy(nxtname
, hiname
);
831 strcpy(hiname
, Other
.p_name
);
833 else if (Other
.p_experience
> nxtexp
834 && Other
.p_specialtype
<= SC_KING
835 && Other
.p_status
!= S_NOTUSED
)
836 /* next highest found so far */
838 nxtexp
= Other
.p_experience
;
839 nxtlvl
= Other
.p_level
;
840 strcpy(nxtname
, Other
.p_name
);
843 mvaddstr(15, 28, "Highest characters are:");
844 sprintf(Databuf
, "%s Level:%.0f and %s Level:%.0f",
845 hiname
, hilvl
, nxtname
, nxtlvl
);
846 mvaddstr(17, 40 - strlen(Databuf
) / 2, Databuf
);
848 /* print last to die */
849 if ((fp
= fopen(_PATH_LASTDEAD
,"r")) != NULL
850 && fgets(Databuf
, SZ_DATABUF
, fp
) != NULL
)
852 mvaddstr(19, 25, "The last character to die was:");
853 mvaddstr(20, 40 - strlen(Databuf
) / 2,Databuf
);
860 /************************************************************************
862 / FUNCTION NAME: recallplayer()
864 / FUNCTION: find a character on file
866 / AUTHOR: E. A. Estes, 12/4/85
872 / MODULES CALLED: writerecord(), truncstring(), more(), death(), wmove(),
873 / wclear(), strcmp(), printw(), cleanup(), waddstr(), findname(), mvprintw(),
874 / getanswer(), getstring()
876 / GLOBAL INPUTS: Player, *stdscr, Databuf[]
878 / GLOBAL OUTPUTS: Echo, Player
881 / Search for a character of a certain name, and check password.
883 /************************************************************************/
888 long loc
= 0L; /* location in player file */
889 register int loop
; /* loop counter */
893 mvprintw(10, 0, "What was your character's name ? ");
894 getstring(Databuf
, SZ_NAME
);
895 truncstring(Databuf
);
897 if ((loc
= findname(Databuf
, &Player
)) >= 0L)
898 /* found character */
902 for (loop
= 0; loop
< 2; ++loop
)
904 /* prompt for password */
905 mvaddstr(11, 0, "Password ? ");
906 getstring(Databuf
, SZ_PASSWORD
);
907 if (strcmp(Databuf
, Player
.p_password
) == 0)
912 if (Player
.p_status
!= S_OFF
)
913 /* player did not exit normally last time */
916 addstr("Your character did not exit normally last time.\n");
917 addstr("If you think you have good cause to have your character saved,\n");
918 printw("you may quit and mail your reason to 'root'.\n");
919 addstr("Otherwise, continuing spells certain death.\n");
920 addstr("Do you want to quit ? ");
921 ch
= getanswer("YN", FALSE
);
924 Player
.p_status
= S_HUNGUP
;
925 writerecord(&Player
, loc
);
935 mvaddstr(12, 0, "No good.\n");
941 mvaddstr(11, 0, "Not found.\n");
947 /************************************************************************
949 / FUNCTION NAME: neatstuff()
951 / FUNCTION: do random stuff
953 / AUTHOR: E. A. Estes, 3/3/86
959 / MODULES CALLED: collecttaxes(), floor(), wmove(), drandom(), infloat(),
960 / waddstr(), mvprintw(), getanswer()
962 / GLOBAL INPUTS: Player, *stdscr, *Statptr
964 / GLOBAL OUTPUTS: Player
967 / Handle gurus, medics, etc.
969 /************************************************************************/
973 double temp
; /* for temporary calculations */
976 switch ((int) ROLL(0.0, 100.0))
980 if (Player
.p_poison
> 0.0)
982 mvaddstr(4, 0, "You've found a medic! How much will you offer to be cured ? ");
983 temp
= floor(infloat());
984 if (temp
< 0.0 || temp
> Player
.p_gold
)
985 /* negative gold, or more than available */
987 mvaddstr(6, 0, "He was not amused, and made you worse.\n");
988 Player
.p_poison
+= 1.0;
990 else if (drandom() / 2.0 > (temp
+ 1.0) / MAX(Player
.p_gold
, 1))
991 /* medic wants 1/2 of available gold */
992 mvaddstr(5, 0, "Sorry, he wasn't interested.\n");
995 mvaddstr(5, 0, "He accepted.");
996 Player
.p_poison
= MAX(0.0, Player
.p_poison
- 1.0);
997 Player
.p_gold
-= temp
;
1003 mvaddstr(4, 0, "You've been caught raping and pillaging!\n");
1004 Player
.p_experience
+= 4000.0;
1005 Player
.p_sin
+= 0.5;
1009 temp
= ROLL(10.0, 75.0);
1010 mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp
);
1011 ch
= getanswer("NY", FALSE
);
1014 collecttaxes(temp
, 0.0);
1018 if (Player
.p_sin
> 1.0)
1020 mvaddstr(4, 0, "You've found a Holy Orb!\n");
1021 Player
.p_sin
-= 0.25;
1026 if (Player
.p_poison
< 1.0)
1028 mvaddstr(4, 0, "You've been hit with a plague!\n");
1029 Player
.p_poison
+= 1.0;
1034 mvaddstr(4, 0, "You've found some holy water.\n");
1035 ++Player
.p_holywater
;
1039 mvaddstr(4, 0, "You've met a Guru. . .");
1040 if (drandom() * Player
.p_sin
> 1.0)
1041 addstr("You disgusted him with your sins!\n");
1042 else if (Player
.p_poison
> 0.0)
1044 addstr("He looked kindly upon you, and cured you.\n");
1045 Player
.p_poison
= 0.0;
1049 addstr("He rewarded you for your virtue.\n");
1050 Player
.p_mana
+= 50.0;
1051 Player
.p_shield
+= 2.0;
1056 mvaddstr(4, 0, "You've found an amulet.\n");
1061 if (Player
.p_blindness
)
1063 mvaddstr(4, 0, "You've regained your sight!\n");
1064 Player
.p_blindness
= FALSE
;
1068 default: /* deal with poison */
1069 if (Player
.p_poison
> 0.0)
1071 temp
= Player
.p_poison
* Statptr
->c_weakness
1072 * Player
.p_maxenergy
/ 600.0;
1073 if (Player
.p_energy
> Player
.p_maxenergy
/ 10.0
1074 && temp
+ 5.0 < Player
.p_energy
)
1075 Player
.p_energy
-= temp
;
1081 /************************************************************************
1083 / FUNCTION NAME: genchar()
1085 / FUNCTION: generate a random character
1087 / AUTHOR: E. A. Estes, 12/4/85
1090 / int type - ASCII value of character type to generate
1092 / RETURN VALUE: none
1094 / MODULES CALLED: floor(), drandom()
1096 / GLOBAL INPUTS: Wizard, Player, Stattable[]
1098 / GLOBAL OUTPUTS: Player
1101 / Use the lookup table for rolling stats.
1103 /************************************************************************/
1108 register int subscript
; /* used for subscripting into Stattable */
1109 register struct charstats
*statptr
;/* for pointing into Stattable */
1111 subscript
= type
- '1';
1113 if (subscript
< C_MAGIC
|| subscript
> C_EXPER
)
1114 if (subscript
!= C_SUPER
|| !Wizard
)
1115 /* fighter is default */
1116 subscript
= C_FIGHTER
;
1118 statptr
= &Stattable
[subscript
];
1120 Player
.p_quickness
=
1121 ROLL(statptr
->c_quickness
.base
, statptr
->c_quickness
.interval
);
1123 ROLL(statptr
->c_strength
.base
, statptr
->c_strength
.interval
);
1125 ROLL(statptr
->c_mana
.base
, statptr
->c_mana
.interval
);
1126 Player
.p_maxenergy
=
1128 ROLL(statptr
->c_energy
.base
, statptr
->c_energy
.interval
);
1130 ROLL(statptr
->c_brains
.base
, statptr
->c_brains
.interval
);
1132 ROLL(statptr
->c_magiclvl
.base
, statptr
->c_magiclvl
.interval
);
1134 Player
.p_type
= subscript
;
1136 if (Player
.p_type
== C_HALFLING
)
1137 /* give halfling some experience */
1138 Player
.p_experience
= ROLL(600.0, 200.0);
1141 /************************************************************************
1143 / FUNCTION NAME: playinit()
1145 / FUNCTION: initialize for playing game
1147 / AUTHOR: E. A. Estes, 12/4/85
1151 / RETURN VALUE: none
1153 / MODULES CALLED: signal(), wclear(), noecho(), crmode(), initscr(),
1156 / GLOBAL INPUTS: *stdscr, ill_sig()
1158 / GLOBAL OUTPUTS: Windows
1161 / Catch a bunch of signals, and turn on curses stuff.
1163 /************************************************************************/
1167 /* catch/ingnore signals */
1177 sigset(SIGHUP
, ill_sig
);
1178 sigset(SIGTRAP
, ill_sig
);
1179 sigset(SIGIOT
, ill_sig
);
1180 sigset(SIGEMT
, ill_sig
);
1181 sigset(SIGFPE
, ill_sig
);
1182 sigset(SIGBUS
, ill_sig
);
1183 sigset(SIGSEGV
, ill_sig
);
1184 sigset(SIGSYS
, ill_sig
);
1185 sigset(SIGPIPE
, ill_sig
);
1188 signal(SIGQUIT
, ill_sig
);
1189 signal(SIGALRM
, SIG_IGN
);
1190 signal(SIGTERM
, SIG_IGN
);
1191 signal(SIGTSTP
, SIG_IGN
);
1192 signal(SIGTTIN
, SIG_IGN
);
1193 signal(SIGTTOU
, SIG_IGN
);
1194 signal(SIGINT
, ill_sig
);
1195 signal(SIGHUP
, SIG_DFL
);
1196 signal(SIGTRAP
, ill_sig
);
1197 signal(SIGIOT
, ill_sig
);
1198 signal(SIGEMT
, ill_sig
);
1199 signal(SIGFPE
, ill_sig
);
1200 signal(SIGBUS
, ill_sig
);
1201 signal(SIGSEGV
, ill_sig
);
1202 signal(SIGSYS
, ill_sig
);
1203 signal(SIGPIPE
, ill_sig
);
1206 signal(SIGINT
, SIG_IGN
);
1207 signal(SIGQUIT
, SIG_IGN
);
1208 signal(SIGTERM
, SIG_IGN
);
1209 signal(SIGALRM
, SIG_IGN
);
1210 signal(SIGHUP
, ill_sig
);
1211 signal(SIGTRAP
, ill_sig
);
1212 signal(SIGIOT
, ill_sig
);
1213 signal(SIGEMT
, ill_sig
);
1214 signal(SIGFPE
, ill_sig
);
1215 signal(SIGBUS
, ill_sig
);
1216 signal(SIGSEGV
, ill_sig
);
1217 signal(SIGSYS
, ill_sig
);
1218 signal(SIGPIPE
, ill_sig
);
1221 signal(SIGINT
, SIG_IGN
);
1222 signal(SIGQUIT
, SIG_IGN
);
1223 signal(SIGTERM
, SIG_IGN
);
1224 signal(SIGALRM
, SIG_IGN
);
1225 signal(SIGHUP
, ill_sig
);
1226 signal(SIGTRAP
, ill_sig
);
1227 signal(SIGIOT
, ill_sig
);
1228 signal(SIGEMT
, ill_sig
);
1229 signal(SIGFPE
, ill_sig
);
1230 signal(SIGBUS
, ill_sig
);
1231 signal(SIGSEGV
, ill_sig
);
1232 signal(SIGSYS
, ill_sig
);
1233 signal(SIGPIPE
, ill_sig
);
1236 initscr(); /* turn on curses */
1237 noecho(); /* do not echo input */
1238 crmode(); /* do not process erase, kill */
1241 Windows
= TRUE
; /* mark the state */
1245 /************************************************************************
1247 / FUNCTION NAME: cleanup()
1249 / FUNCTION: close some files, and maybe exit
1251 / AUTHOR: E. A. Estes, 12/4/85
1254 / bool doexit - exit flag
1256 / RETURN VALUE: none
1258 / MODULES CALLED: exit(), wmove(), fclose(), endwin(), nocrmode(), wrefresh()
1260 / GLOBAL INPUTS: *Energyvoidfp, LINES, *stdscr, Windows, *Monstfp,
1261 / *Messagefp, *Playersfp
1263 / GLOBAL OUTPUTS: none
1266 / Close all open files. If we are "in curses" terminate curses.
1267 / If 'doexit' is set, exit, otherwise return.
1269 /************************************************************************/
1285 fclose(Energyvoidfp
);