Home | History | Annotate | Line # | Download | only in phantasia
main.c revision 1.12.4.3
      1  1.12.4.3     tron /*	$NetBSD: main.c,v 1.12.4.3 2005/04/08 21:48:36 tron Exp $	*/
      2       1.2      cgd 
      3       1.1      jtc /*
      4       1.1      jtc  * Phantasia 3.3.2 -- Interterminal fantasy game
      5       1.1      jtc  *
      6       1.1      jtc  * Edward A. Estes
      7       1.1      jtc  * AT&T, March 12, 1986
      8       1.1      jtc  */
      9       1.1      jtc 
     10       1.1      jtc /* DISCLAIMER:
     11       1.1      jtc  *
     12       1.1      jtc  * This game is distributed for free as is.  It is not guaranteed to work
     13       1.1      jtc  * in every conceivable environment.  It is not even guaranteed to work
     14       1.1      jtc  * in ANY environment.
     15       1.1      jtc  *
     16       1.1      jtc  * This game is distributed without notice of copyright, therefore it
     17       1.1      jtc  * may be used in any manner the recipient sees fit.  However, the
     18       1.1      jtc  * author assumes no responsibility for maintaining or revising this
     19       1.1      jtc  * game, in its original form, or any derivitives thereof.
     20       1.1      jtc  *
     21       1.1      jtc  * The author shall not be responsible for any loss, cost, or damage,
     22       1.1      jtc  * including consequential damage, caused by reliance on this material.
     23       1.1      jtc  *
     24       1.1      jtc  * The author makes no warranties, express or implied, including warranties
     25       1.1      jtc  * of merchantability or fitness for a particular purpose or use.
     26       1.1      jtc  *
     27       1.1      jtc  * AT&T is in no way connected with this game.
     28       1.1      jtc  */
     29       1.1      jtc 
     30  1.12.4.3     tron #include <sys/stat.h>
     31       1.1      jtc #include <sys/types.h>
     32       1.1      jtc #include <pwd.h>
     33       1.1      jtc 
     34       1.1      jtc /*
     35       1.1      jtc  * The program allocates as much file space as it needs to store characters,
     36       1.1      jtc  * so the possibility exists for the character file to grow without bound.
     37       1.1      jtc  * The file is purged upon normal entry to try to avoid that problem.
     38       1.1      jtc  * A similar problem exists for energy voids.  To alleviate the problem here,
     39       1.1      jtc  * the void file is cleared with every new king, and a limit is placed
     40       1.1      jtc  * on the size of the energy void file.
     41       1.1      jtc  */
     42       1.1      jtc 
     43       1.1      jtc /*
     44       1.1      jtc  * Put one line of text into the file 'motd' for announcements, etc.
     45       1.1      jtc  */
     46       1.1      jtc 
     47       1.1      jtc /*
     48       1.1      jtc  * The scoreboard file is updated when someone dies, and keeps track
     49       1.1      jtc  * of the highest character to date for that login.
     50       1.1      jtc  * Being purged from the character file does not cause the scoreboard
     51       1.1      jtc  * to be updated.
     52       1.1      jtc  */
     53       1.1      jtc 
     54       1.1      jtc 
     55       1.1      jtc /*
     56       1.1      jtc  * main.c	Main routines for Phantasia
     57       1.1      jtc  */
     58       1.1      jtc 
     59       1.1      jtc #include "include.h"
     60  1.12.4.2     tron #undef bool
     61  1.12.4.1     tron #include <curses.h>
     62       1.1      jtc 
     63      1.11      wiz int	main(int, char **);
     64       1.1      jtc 
     65       1.4    lukem int
     66       1.1      jtc main(argc, argv)
     67       1.4    lukem 	int     argc;
     68       1.4    lukem 	char  **argv;
     69       1.1      jtc {
     70       1.4    lukem 	bool    noheader = FALSE;	/* set if don't want header */
     71       1.4    lukem 	bool    headeronly = FALSE;	/* set if only want header */
     72       1.4    lukem 	bool    examine = FALSE;	/* set if examine a character */
     73       1.4    lukem 	time_t  seconds;		/* for time of day */
     74       1.4    lukem 	double  dtemp;			/* for temporary calculations */
     75       1.4    lukem 
     76       1.4    lukem 	initialstate();			/* init globals */
     77       1.4    lukem 
     78       1.4    lukem 	/* process arguments */
     79       1.4    lukem 	while (--argc && (*++argv)[0] == '-')
     80       1.4    lukem 		switch ((*argv)[1]) {
     81       1.4    lukem 		case 's':	/* short */
     82       1.4    lukem 			noheader = TRUE;
     83       1.4    lukem 			break;
     84       1.4    lukem 
     85       1.4    lukem 		case 'H':	/* Header */
     86       1.4    lukem 			headeronly = TRUE;
     87       1.4    lukem 			break;
     88       1.1      jtc 
     89       1.4    lukem 		case 'a':	/* all users */
     90       1.4    lukem 			activelist();
     91       1.4    lukem 			cleanup(TRUE);
     92       1.4    lukem 			/* NOTREACHED */
     93       1.4    lukem 
     94       1.4    lukem 		case 'p':	/* purge old players */
     95       1.4    lukem 			purgeoldplayers();
     96       1.4    lukem 			cleanup(TRUE);
     97       1.4    lukem 			/* NOTREACHED */
     98       1.1      jtc 
     99       1.4    lukem 		case 'S':	/* set 'Wizard' */
    100       1.4    lukem 			Wizard = !getuid();
    101       1.4    lukem 			break;
    102       1.4    lukem 
    103       1.4    lukem 		case 'x':	/* examine */
    104       1.4    lukem 			examine = TRUE;
    105       1.4    lukem 			break;
    106       1.1      jtc 
    107       1.4    lukem 		case 'm':	/* monsters */
    108       1.4    lukem 			monstlist();
    109       1.4    lukem 			cleanup(TRUE);
    110       1.4    lukem 			/* NOTREACHED */
    111       1.1      jtc 
    112       1.4    lukem 		case 'b':	/* scoreboard */
    113       1.4    lukem 			scorelist();
    114       1.4    lukem 			cleanup(TRUE);
    115       1.4    lukem 			/* NOTREACHED */
    116       1.4    lukem 		}
    117       1.1      jtc 
    118       1.4    lukem 	if (!isatty(0))		/* don't let non-tty's play */
    119       1.1      jtc 		cleanup(TRUE);
    120       1.4    lukem 	/* NOTREACHED */
    121       1.1      jtc 
    122       1.4    lukem 	playinit();		/* set up to catch signals, init curses */
    123       1.1      jtc 
    124       1.4    lukem 	if (examine) {
    125       1.4    lukem 		changestats(FALSE);
    126       1.1      jtc 		cleanup(TRUE);
    127       1.4    lukem 		/* NOTREACHED */
    128       1.1      jtc 	}
    129       1.4    lukem 	if (!noheader) {
    130       1.4    lukem 		titlelist();
    131       1.4    lukem 		purgeoldplayers();	/* clean up old characters */
    132       1.1      jtc 	}
    133       1.4    lukem 	if (headeronly)
    134       1.4    lukem 		cleanup(TRUE);
    135       1.4    lukem 	/* NOTREACHED */
    136       1.1      jtc 
    137       1.4    lukem 	do
    138       1.4    lukem 		/* get the player structure filled */
    139       1.1      jtc 	{
    140       1.4    lukem 		Fileloc = -1L;
    141       1.1      jtc 
    142       1.4    lukem 		mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? ");
    143       1.1      jtc 
    144       1.4    lukem 		switch (getanswer("NYQ", FALSE)) {
    145       1.4    lukem 		case 'Y':
    146       1.4    lukem 			Fileloc = recallplayer();
    147       1.4    lukem 			break;
    148       1.1      jtc 
    149       1.4    lukem 		case 'Q':
    150       1.4    lukem 			cleanup(TRUE);
    151       1.4    lukem 			/* NOTREACHED */
    152       1.1      jtc 
    153       1.4    lukem 		default:
    154       1.4    lukem 			Fileloc = rollnewplayer();
    155       1.4    lukem 			break;
    156       1.4    lukem 		}
    157       1.4    lukem 		clear();
    158       1.1      jtc 	}
    159       1.4    lukem 	while (Fileloc < 0L);
    160       1.1      jtc 
    161       1.4    lukem 	if (Player.p_level > 5.0)
    162       1.4    lukem 		/* low level players have long timeout */
    163       1.4    lukem 		Timeout = TRUE;
    164       1.4    lukem 
    165       1.4    lukem 	/* update some important player statistics */
    166       1.4    lukem 	strcpy(Player.p_login, Login);
    167       1.4    lukem 	time(&seconds);
    168       1.4    lukem 	Player.p_lastused = localtime(&seconds)->tm_yday;
    169       1.4    lukem 	Player.p_status = S_PLAYING;
    170       1.4    lukem 	writerecord(&Player, Fileloc);
    171       1.1      jtc 
    172       1.4    lukem 	Statptr = &Stattable[Player.p_type];	/* initialize pointer */
    173       1.1      jtc 
    174       1.4    lukem 	/* catch interrupts */
    175       1.1      jtc #ifdef	BSD41
    176       1.4    lukem 	sigset(SIGINT, interrupt);
    177       1.1      jtc #endif
    178       1.1      jtc #ifdef	BSD42
    179       1.4    lukem 	signal(SIGINT, interrupt);
    180       1.1      jtc #endif
    181       1.1      jtc #ifdef	SYS3
    182       1.4    lukem 	signal(SIGINT, interrupt);
    183       1.1      jtc #endif
    184       1.1      jtc #ifdef	SYS5
    185       1.4    lukem 	signal(SIGINT, interrupt);
    186       1.1      jtc #endif
    187       1.1      jtc 
    188       1.4    lukem 	altercoordinates(Player.p_x, Player.p_y, A_FORCED);	/* set some flags */
    189       1.1      jtc 
    190       1.4    lukem 	clear();
    191       1.1      jtc 
    192       1.4    lukem 	for (;;)
    193       1.4    lukem 		/* loop forever, processing input */
    194       1.1      jtc 	{
    195       1.1      jtc 
    196       1.4    lukem 		adjuststats();	/* cleanup stats */
    197       1.4    lukem 
    198       1.4    lukem 		if (Throne && Player.p_crowns == 0 && Player.p_specialtype != SC_KING)
    199       1.4    lukem 			/* not allowed on throne -- move */
    200       1.4    lukem 		{
    201       1.4    lukem 			mvaddstr(5, 0, "You're not allowed in the Lord's Chamber without a crown.\n");
    202       1.4    lukem 			altercoordinates(0.0, 0.0, A_NEAR);
    203       1.4    lukem 		}
    204       1.4    lukem 		checktampered();/* check for energy voids, etc. */
    205       1.1      jtc 
    206       1.4    lukem 		if (Player.p_status != S_CLOAKED
    207       1.4    lukem 		/* not cloaked */
    208       1.4    lukem 		    && (dtemp = fabs(Player.p_x)) == fabs(Player.p_y)
    209       1.4    lukem 		/* |x| = |y| */
    210       1.4    lukem 		    && !Throne)
    211       1.4    lukem 			/* not on throne */
    212       1.1      jtc 		{
    213       1.4    lukem 			dtemp = sqrt(dtemp / 100.0);
    214       1.4    lukem 			if (floor(dtemp) == dtemp)
    215       1.4    lukem 				/* |x| / 100 == n*n; at a trading post */
    216       1.4    lukem 			{
    217       1.4    lukem 				tradingpost();
    218       1.4    lukem 				clear();
    219       1.4    lukem 			}
    220       1.1      jtc 		}
    221       1.4    lukem 		checkbattle();	/* check for player to player battle */
    222       1.4    lukem 		neatstuff();	/* gurus, medics, etc. */
    223       1.1      jtc 
    224       1.5    veego 		if (Player.p_status == S_CLOAKED) {
    225       1.4    lukem 			/* costs 3 mana per turn to be cloaked */
    226       1.4    lukem 			if (Player.p_mana > 3.0)
    227       1.4    lukem 				Player.p_mana -= 3.0;
    228       1.4    lukem 			else
    229       1.4    lukem 				/* ran out of mana, uncloak */
    230       1.4    lukem 			{
    231       1.4    lukem 				Player.p_status = S_PLAYING;
    232       1.4    lukem 				Changed = TRUE;
    233       1.4    lukem 			}
    234       1.5    veego 		}
    235       1.1      jtc 
    236       1.4    lukem 		if (Player.p_status != S_PLAYING && Player.p_status != S_CLOAKED)
    237       1.4    lukem 			/* change status back to S_PLAYING */
    238       1.1      jtc 		{
    239       1.4    lukem 			Player.p_status = S_PLAYING;
    240       1.4    lukem 			Changed = TRUE;
    241       1.1      jtc 		}
    242       1.4    lukem 		if (Changed)
    243       1.4    lukem 			/* update file only if important stuff has changed */
    244       1.4    lukem 		{
    245       1.4    lukem 			writerecord(&Player, Fileloc);
    246       1.4    lukem 			Changed = FALSE;
    247       1.4    lukem 			continue;
    248       1.4    lukem 		}
    249       1.4    lukem 		readmessage();	/* read message, if any */
    250       1.4    lukem 
    251       1.4    lukem 		displaystats();	/* print statistics */
    252       1.1      jtc 
    253       1.4    lukem 		move(6, 0);
    254       1.1      jtc 
    255       1.4    lukem 		if (Throne)
    256       1.4    lukem 			/* maybe make king, print prompt, etc. */
    257       1.4    lukem 			throneroom();
    258       1.4    lukem 
    259       1.4    lukem 		/* print status line */
    260       1.4    lukem 		addstr("1:Move  2:Players  3:Talk  4:Stats  5:Quit  ");
    261       1.4    lukem 		if (Player.p_level >= MEL_CLOAK && Player.p_magiclvl >= ML_CLOAK)
    262       1.4    lukem 			addstr("6:Cloak  ");
    263       1.4    lukem 		if (Player.p_level >= MEL_TELEPORT && Player.p_magiclvl >= ML_TELEPORT)
    264       1.4    lukem 			addstr("7:Teleport  ");
    265       1.4    lukem 		if (Player.p_specialtype >= SC_COUNCIL || Wizard)
    266       1.4    lukem 			addstr("8:Intervene  ");
    267       1.4    lukem 
    268       1.4    lukem 		procmain();	/* process input */
    269       1.1      jtc 	}
    270       1.1      jtc }
    271       1.1      jtc 
    272       1.4    lukem void
    273       1.1      jtc initialstate()
    274       1.1      jtc {
    275  1.12.4.3     tron 	struct stat sb;
    276  1.12.4.3     tron 
    277       1.4    lukem 	Beyond = FALSE;
    278       1.4    lukem 	Marsh = FALSE;
    279       1.4    lukem 	Throne = FALSE;
    280       1.4    lukem 	Changed = FALSE;
    281       1.4    lukem 	Wizard = FALSE;
    282       1.4    lukem 	Timeout = FALSE;
    283       1.4    lukem 	Users = 0;
    284       1.4    lukem 	Windows = FALSE;
    285       1.4    lukem 	Echo = TRUE;
    286       1.1      jtc 
    287       1.4    lukem 	/* setup login name */
    288       1.4    lukem 	if ((Login = getlogin()) == NULL)
    289       1.4    lukem 		Login = getpwuid(getuid())->pw_name;
    290       1.4    lukem 
    291       1.4    lukem 	/* open some files */
    292       1.4    lukem 	if ((Playersfp = fopen(_PATH_PEOPLE, "r+")) == NULL)
    293       1.4    lukem 		error(_PATH_PEOPLE);
    294       1.4    lukem 	/* NOTREACHED */
    295       1.9      jsm 	if (fileno(Playersfp) < 3)
    296       1.9      jsm 		exit(1);
    297       1.4    lukem 
    298       1.4    lukem 	if ((Monstfp = fopen(_PATH_MONST, "r+")) == NULL)
    299       1.4    lukem 		error(_PATH_MONST);
    300       1.4    lukem 	/* NOTREACHED */
    301       1.4    lukem 
    302       1.4    lukem 	if ((Messagefp = fopen(_PATH_MESS, "r")) == NULL)
    303       1.4    lukem 		error(_PATH_MESS);
    304       1.4    lukem 	/* NOTREACHED */
    305       1.4    lukem 
    306       1.4    lukem 	if ((Energyvoidfp = fopen(_PATH_VOID, "r+")) == NULL)
    307       1.4    lukem 		error(_PATH_VOID);
    308  1.12.4.3     tron 	if (fstat(fileno(Energyvoidfp), &sb) == -1)
    309  1.12.4.3     tron 		error("stat");
    310  1.12.4.3     tron 	if (sb.st_size == 0) {
    311  1.12.4.3     tron 		/* initialize grail to new location */
    312  1.12.4.3     tron 		Enrgyvoid.ev_active = TRUE;
    313  1.12.4.3     tron 		Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
    314  1.12.4.3     tron 		Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
    315  1.12.4.3     tron 		writevoid(&Enrgyvoid, 0L);
    316  1.12.4.3     tron 	}
    317  1.12.4.3     tron 
    318       1.4    lukem 	/* NOTREACHED */
    319       1.4    lukem 
    320       1.4    lukem 	srandom((unsigned) time(NULL));	/* prime random numbers */
    321       1.1      jtc }
    322       1.1      jtc 
    323       1.1      jtc long
    324       1.1      jtc rollnewplayer()
    325       1.1      jtc {
    326       1.4    lukem 	int     chartype;	/* character type */
    327       1.4    lukem 	int     ch;		/* input */
    328       1.1      jtc 
    329       1.4    lukem 	initplayer(&Player);	/* initialize player structure */
    330       1.1      jtc 
    331       1.4    lukem 	clear();
    332       1.4    lukem 	mvaddstr(4, 21, "Which type of character do you want:");
    333       1.4    lukem 	mvaddstr(8, 4,
    334       1.4    lukem "1:Magic User  2:Fighter  3:Elf  4:Dwarf  5:Halfling  6:Experimento  ");
    335       1.4    lukem 	if (Wizard) {
    336       1.4    lukem 		addstr("7:Super  ? ");
    337       1.4    lukem 		chartype = getanswer("1234567", FALSE);
    338       1.4    lukem 	} else {
    339       1.4    lukem 		addstr("?  ");
    340       1.4    lukem 		chartype = getanswer("123456", FALSE);
    341       1.4    lukem 	}
    342       1.4    lukem 
    343       1.4    lukem 	do {
    344       1.4    lukem 		genchar(chartype);	/* roll up a character */
    345       1.4    lukem 
    346       1.4    lukem 		/* print out results */
    347       1.4    lukem 		mvprintw(12, 14,
    348       1.4    lukem 		    "Strength    :  %2.0f  Quickness:  %2.0f  Mana       :  %2.0f\n",
    349       1.4    lukem 		    Player.p_strength, Player.p_quickness, Player.p_mana);
    350       1.4    lukem 		mvprintw(13, 14,
    351       1.4    lukem 		    "Energy Level:  %2.0f  Brains   :  %2.0f  Magic Level:  %2.0f\n",
    352       1.4    lukem 		    Player.p_energy, Player.p_brains, Player.p_magiclvl);
    353       1.1      jtc 
    354       1.4    lukem 		if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
    355       1.4    lukem 			break;
    356       1.1      jtc 
    357       1.4    lukem 		mvaddstr(14, 14, "Type '1' to keep >");
    358       1.4    lukem 		ch = getanswer(" ", TRUE);
    359       1.4    lukem 	}
    360       1.4    lukem 	while (ch != '1');
    361       1.1      jtc 
    362       1.1      jtc 	if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
    363       1.4    lukem 		/* get coordinates for experimento */
    364       1.4    lukem 		for (;;) {
    365       1.4    lukem 			mvaddstr(16, 0, "Enter the X Y coordinates of your experimento ? ");
    366       1.4    lukem 			getstring(Databuf, SZ_DATABUF);
    367       1.4    lukem 			sscanf(Databuf, "%lf %lf", &Player.p_x, &Player.p_y);
    368       1.1      jtc 
    369       1.4    lukem 			if (fabs(Player.p_x) > D_EXPER || fabs(Player.p_y) > D_EXPER)
    370       1.4    lukem 				mvaddstr(17, 0, "Invalid coordinates.  Try again.\n");
    371       1.4    lukem 			else
    372       1.4    lukem 				break;
    373       1.4    lukem 		}
    374       1.1      jtc 
    375       1.1      jtc 	for (;;)
    376       1.4    lukem 		/* name the new character */
    377       1.1      jtc 	{
    378       1.4    lukem 		mvprintw(18, 0,
    379       1.4    lukem 		    "Give your character a name [up to %d characters] ?  ", SZ_NAME - 1);
    380       1.4    lukem 		getstring(Player.p_name, SZ_NAME);
    381       1.4    lukem 		truncstring(Player.p_name);	/* remove trailing blanks */
    382       1.4    lukem 
    383       1.4    lukem 		if (Player.p_name[0] == '\0')
    384       1.4    lukem 			/* no null names */
    385       1.4    lukem 			mvaddstr(19, 0, "Invalid name.");
    386       1.4    lukem 		else
    387       1.4    lukem 			if (findname(Player.p_name, &Other) >= 0L)
    388       1.4    lukem 				/* cannot have duplicate names */
    389       1.4    lukem 				mvaddstr(19, 0, "Name already in use.");
    390       1.4    lukem 			else
    391       1.4    lukem 				/* name is acceptable */
    392       1.4    lukem 				break;
    393       1.1      jtc 
    394       1.4    lukem 		addstr("  Pick another.\n");
    395       1.1      jtc 	}
    396       1.1      jtc 
    397       1.4    lukem 	/* get a password for character */
    398       1.4    lukem 	Echo = FALSE;
    399       1.1      jtc 
    400       1.4    lukem 	do {
    401       1.4    lukem 		mvaddstr(20, 0, "Give your character a password [up to 8 characters] ? ");
    402       1.4    lukem 		getstring(Player.p_password, SZ_PASSWORD);
    403       1.6  hubertf 		mvaddstr(21, 0, "Enter again to verify: ");
    404       1.4    lukem 		getstring(Databuf, SZ_PASSWORD);
    405       1.1      jtc 	}
    406       1.4    lukem 	while (strcmp(Player.p_password, Databuf) != 0);
    407       1.1      jtc 
    408       1.4    lukem 	Echo = TRUE;
    409       1.1      jtc 
    410       1.4    lukem 	return (allocrecord());
    411       1.1      jtc }
    412       1.1      jtc 
    413       1.4    lukem void
    414       1.1      jtc procmain()
    415       1.1      jtc {
    416       1.4    lukem 	int     ch;		/* input */
    417       1.4    lukem 	double  x;		/* desired new x coordinate */
    418       1.4    lukem 	double  y;		/* desired new y coordinate */
    419       1.4    lukem 	double  temp;		/* for temporary calculations */
    420       1.4    lukem 	FILE   *fp;		/* for opening files */
    421       1.4    lukem 	int     loop;		/* a loop counter */
    422       1.4    lukem 	bool    hasmoved = FALSE;	/* set if player has moved */
    423       1.4    lukem 
    424       1.4    lukem 	ch = inputoption();
    425       1.4    lukem 	mvaddstr(4, 0, "\n\n");	/* clear status area */
    426       1.4    lukem 
    427       1.4    lukem 	move(7, 0);
    428       1.4    lukem 	clrtobot();		/* clear data on bottom area of screen */
    429       1.4    lukem 
    430       1.4    lukem 	if (Player.p_specialtype == SC_VALAR && (ch == '1' || ch == '7'))
    431       1.4    lukem 		/* valar cannot move */
    432       1.4    lukem 		ch = ' ';
    433       1.1      jtc 
    434       1.4    lukem 	switch (ch) {
    435       1.1      jtc 	case 'K':		/* move up/north */
    436       1.1      jtc 	case 'N':
    437       1.4    lukem 		x = Player.p_x;
    438       1.4    lukem 		y = Player.p_y + MAXMOVE();
    439       1.4    lukem 		hasmoved = TRUE;
    440       1.4    lukem 		break;
    441       1.1      jtc 
    442       1.1      jtc 	case 'J':		/* move down/south */
    443       1.1      jtc 	case 'S':
    444       1.4    lukem 		x = Player.p_x;
    445       1.4    lukem 		y = Player.p_y - MAXMOVE();
    446       1.4    lukem 		hasmoved = TRUE;
    447       1.4    lukem 		break;
    448       1.1      jtc 
    449       1.1      jtc 	case 'L':		/* move right/east */
    450       1.1      jtc 	case 'E':
    451       1.4    lukem 		x = Player.p_x + MAXMOVE();
    452       1.4    lukem 		y = Player.p_y;
    453       1.4    lukem 		hasmoved = TRUE;
    454       1.4    lukem 		break;
    455       1.1      jtc 
    456       1.1      jtc 	case 'H':		/* move left/west */
    457       1.1      jtc 	case 'W':
    458       1.4    lukem 		x = Player.p_x - MAXMOVE();
    459       1.4    lukem 		y = Player.p_y;
    460       1.4    lukem 		hasmoved = TRUE;
    461       1.4    lukem 		break;
    462       1.1      jtc 
    463       1.4    lukem 	default:		/* rest */
    464       1.4    lukem 		Player.p_energy += (Player.p_maxenergy + Player.p_shield) / 15.0
    465       1.4    lukem 		    + Player.p_level / 3.0 + 2.0;
    466       1.4    lukem 		Player.p_energy =
    467       1.4    lukem 		    MIN(Player.p_energy, Player.p_maxenergy + Player.p_shield);
    468       1.4    lukem 
    469       1.4    lukem 		if (Player.p_status != S_CLOAKED)
    470       1.4    lukem 			/* cannot find mana if cloaked */
    471       1.4    lukem 		{
    472       1.4    lukem 			Player.p_mana += (Circle + Player.p_level) / 4.0;
    473       1.4    lukem 
    474       1.4    lukem 			if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
    475       1.4    lukem 				/* wandering monster */
    476       1.4    lukem 				encounter(-1);
    477       1.1      jtc 		}
    478       1.4    lukem 		break;
    479       1.1      jtc 
    480       1.1      jtc 	case 'X':		/* change/examine a character */
    481       1.4    lukem 		changestats(TRUE);
    482       1.4    lukem 		break;
    483       1.1      jtc 
    484       1.1      jtc 	case '1':		/* move */
    485       1.4    lukem 		for (loop = 3; loop; --loop) {
    486       1.4    lukem 			mvaddstr(4, 0, "X Y Coordinates ? ");
    487       1.4    lukem 			getstring(Databuf, SZ_DATABUF);
    488       1.1      jtc 
    489       1.4    lukem 			if (sscanf(Databuf, "%lf %lf", &x, &y) != 2)
    490       1.4    lukem 				mvaddstr(5, 0, "Try again\n");
    491       1.4    lukem 			else
    492       1.4    lukem 				if (distance(Player.p_x, x, Player.p_y, y) > MAXMOVE())
    493       1.4    lukem 					ILLMOVE();
    494       1.4    lukem 				else {
    495       1.4    lukem 					hasmoved = TRUE;
    496       1.4    lukem 					break;
    497       1.4    lukem 				}
    498       1.1      jtc 		}
    499       1.4    lukem 		break;
    500       1.1      jtc 
    501       1.1      jtc 	case '2':		/* players */
    502       1.4    lukem 		userlist(TRUE);
    503       1.4    lukem 		break;
    504       1.1      jtc 
    505       1.1      jtc 	case '3':		/* message */
    506       1.4    lukem 		mvaddstr(4, 0, "Message ? ");
    507       1.4    lukem 		getstring(Databuf, SZ_DATABUF);
    508       1.4    lukem 		/* we open the file for writing to erase any data which is
    509       1.4    lukem 		 * already there */
    510       1.4    lukem 		fp = fopen(_PATH_MESS, "w");
    511       1.4    lukem 		if (Databuf[0] != '\0')
    512       1.4    lukem 			fprintf(fp, "%s: %s", Player.p_name, Databuf);
    513       1.4    lukem 		fclose(fp);
    514       1.4    lukem 		break;
    515       1.1      jtc 
    516       1.1      jtc 	case '4':		/* stats */
    517       1.4    lukem 		allstatslist();
    518       1.4    lukem 		break;
    519       1.1      jtc 
    520       1.1      jtc 	case '5':		/* good-bye */
    521       1.4    lukem 		leavegame();
    522       1.4    lukem 		/* NOTREACHED */
    523       1.1      jtc 
    524       1.1      jtc 	case '6':		/* cloak */
    525       1.4    lukem 		if (Player.p_level < MEL_CLOAK || Player.p_magiclvl < ML_CLOAK)
    526       1.4    lukem 			ILLCMD();
    527       1.4    lukem 		else
    528       1.4    lukem 			if (Player.p_status == S_CLOAKED)
    529       1.4    lukem 				Player.p_status = S_PLAYING;
    530       1.1      jtc 			else
    531       1.4    lukem 				if (Player.p_mana < MM_CLOAK)
    532       1.4    lukem 					mvaddstr(5, 0, "No mana left.\n");
    533       1.4    lukem 				else {
    534       1.4    lukem 					Changed = TRUE;
    535       1.4    lukem 					Player.p_mana -= MM_CLOAK;
    536       1.4    lukem 					Player.p_status = S_CLOAKED;
    537       1.4    lukem 				}
    538       1.4    lukem 		break;
    539       1.1      jtc 
    540       1.4    lukem 	case '7':		/* teleport */
    541       1.4    lukem 		/*
    542       1.4    lukem 	         * conditions for teleport
    543       1.4    lukem 	         *	- 20 per (level plus magic level)
    544       1.4    lukem 	         *	- OR council of the wise or valar or ex-valar
    545       1.4    lukem 	         *	- OR transport from throne
    546       1.4    lukem 	         * transports from throne cost no mana
    547       1.4    lukem 	         */
    548       1.4    lukem 		if (Player.p_level < MEL_TELEPORT || Player.p_magiclvl < ML_TELEPORT)
    549       1.4    lukem 			ILLCMD();
    550       1.4    lukem 		else
    551       1.4    lukem 			for (loop = 3; loop; --loop) {
    552       1.4    lukem 				mvaddstr(4, 0, "X Y Coordinates ? ");
    553       1.4    lukem 				getstring(Databuf, SZ_DATABUF);
    554       1.4    lukem 
    555       1.4    lukem 				if (sscanf(Databuf, "%lf %lf", &x, &y) == 2) {
    556       1.4    lukem 					temp = distance(Player.p_x, x, Player.p_y, y);
    557       1.4    lukem 					if (!Throne
    558       1.4    lukem 					/* can transport anywhere from throne */
    559       1.4    lukem 					    && Player.p_specialtype <= SC_COUNCIL
    560       1.4    lukem 					/* council, valar can transport
    561       1.4    lukem 					 * anywhere */
    562       1.4    lukem 					    && temp > (Player.p_level + Player.p_magiclvl) * 20.0)
    563       1.4    lukem 						/* can only move 20 per exp.
    564       1.4    lukem 						 * level + mag. level */
    565       1.4    lukem 						ILLMOVE();
    566       1.4    lukem 					else {
    567       1.4    lukem 						temp = (temp / 75.0 + 1.0) * 20.0;	/* mana used */
    568       1.4    lukem 
    569       1.4    lukem 						if (!Throne && temp > Player.p_mana)
    570       1.4    lukem 							mvaddstr(5, 0, "Not enough power for that distance.\n");
    571       1.4    lukem 						else {
    572       1.4    lukem 							if (!Throne)
    573       1.4    lukem 								Player.p_mana -= temp;
    574       1.4    lukem 							hasmoved = TRUE;
    575       1.4    lukem 							break;
    576       1.4    lukem 						}
    577       1.4    lukem 					}
    578       1.1      jtc 				}
    579       1.1      jtc 			}
    580       1.4    lukem 		break;
    581       1.1      jtc 
    582       1.1      jtc 	case 'C':
    583       1.1      jtc 	case '9':		/* monster */
    584       1.4    lukem 		if (Throne)
    585       1.4    lukem 			/* no monsters while on throne */
    586       1.4    lukem 			mvaddstr(5, 0, "No monsters in the chamber!\n");
    587       1.4    lukem 		else
    588       1.4    lukem 			if (Player.p_specialtype != SC_VALAR)
    589       1.4    lukem 				/* the valar cannot call monsters */
    590       1.4    lukem 			{
    591       1.4    lukem 				Player.p_sin += 1e-6;
    592       1.4    lukem 				encounter(-1);
    593       1.4    lukem 			}
    594       1.4    lukem 		break;
    595       1.1      jtc 
    596       1.1      jtc 	case '0':		/* decree */
    597       1.4    lukem 		if (Wizard || (Player.p_specialtype == SC_KING && Throne))
    598       1.4    lukem 			/* kings must be on throne to decree */
    599       1.4    lukem 			dotampered();
    600       1.4    lukem 		else
    601       1.4    lukem 			ILLCMD();
    602       1.4    lukem 		break;
    603       1.1      jtc 
    604       1.1      jtc 	case '8':		/* intervention */
    605       1.4    lukem 		if (Wizard || Player.p_specialtype >= SC_COUNCIL)
    606       1.4    lukem 			dotampered();
    607       1.4    lukem 		else
    608       1.4    lukem 			ILLCMD();
    609       1.4    lukem 		break;
    610       1.1      jtc 	}
    611       1.1      jtc 
    612       1.4    lukem 	if (hasmoved)
    613       1.4    lukem 		/* player has moved -- alter coordinates, and do random
    614       1.4    lukem 		 * monster */
    615       1.1      jtc 	{
    616       1.4    lukem 		altercoordinates(x, y, A_SPECIFIC);
    617       1.1      jtc 
    618       1.4    lukem 		if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
    619       1.4    lukem 			encounter(-1);
    620       1.1      jtc 	}
    621       1.1      jtc }
    622       1.1      jtc 
    623       1.4    lukem void
    624       1.1      jtc titlelist()
    625       1.1      jtc {
    626       1.4    lukem 	FILE   *fp;		/* used for opening various files */
    627       1.4    lukem 	bool    councilfound = FALSE;	/* set if we find a member of the
    628       1.4    lukem 					 * council */
    629       1.4    lukem 	bool    kingfound = FALSE;	/* set if we find a king */
    630       1.4    lukem 	double  hiexp, nxtexp;	/* used for finding the two highest players */
    631       1.4    lukem 	double  hilvl, nxtlvl;	/* used for finding the two highest players */
    632       1.4    lukem 	char    hiname[21], nxtname[21];	/* used for finding the two
    633       1.4    lukem 						 * highest players */
    634       1.4    lukem 
    635       1.4    lukem 	nxtexp = 0;
    636       1.4    lukem 	mvaddstr(0, 14,
    637       1.4    lukem 	    "W e l c o m e   t o   P h a n t a s i a (vers. 3.3.2)!");
    638       1.4    lukem 
    639       1.4    lukem 	/* print message of the day */
    640       1.4    lukem 	if ((fp = fopen(_PATH_MOTD, "r")) != NULL
    641       1.4    lukem 	    && fgets(Databuf, SZ_DATABUF, fp) != NULL) {
    642       1.4    lukem 		mvaddstr(2, 40 - strlen(Databuf) / 2, Databuf);
    643       1.4    lukem 		fclose(fp);
    644       1.4    lukem 	}
    645       1.4    lukem 	/* search for king */
    646       1.8      jsm 	fseek(Playersfp, 0L, SEEK_SET);
    647       1.4    lukem 	while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
    648       1.4    lukem 		if (Other.p_specialtype == SC_KING &&
    649       1.4    lukem 		    Other.p_status != S_NOTUSED)
    650       1.4    lukem 			/* found the king */
    651       1.4    lukem 		{
    652       1.4    lukem 			sprintf(Databuf, "The present ruler is %s  Level:%.0f",
    653       1.4    lukem 			    Other.p_name, Other.p_level);
    654       1.4    lukem 			mvaddstr(4, 40 - strlen(Databuf) / 2, Databuf);
    655       1.4    lukem 			kingfound = TRUE;
    656       1.4    lukem 			break;
    657       1.4    lukem 		}
    658       1.4    lukem 	if (!kingfound)
    659       1.4    lukem 		mvaddstr(4, 24, "There is no ruler at this time.");
    660       1.4    lukem 
    661       1.4    lukem 	/* search for valar */
    662       1.8      jsm 	fseek(Playersfp, 0L, SEEK_SET);
    663       1.4    lukem 	while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
    664       1.4    lukem 		if (Other.p_specialtype == SC_VALAR && Other.p_status != S_NOTUSED)
    665       1.4    lukem 			/* found the valar */
    666       1.4    lukem 		{
    667       1.4    lukem 			sprintf(Databuf, "The Valar is %s   Login:  %s", Other.p_name, Other.p_login);
    668       1.4    lukem 			mvaddstr(6, 40 - strlen(Databuf) / 2, Databuf);
    669       1.4    lukem 			break;
    670       1.4    lukem 		}
    671       1.4    lukem 	/* search for council of the wise */
    672       1.8      jsm 	fseek(Playersfp, 0L, SEEK_SET);
    673       1.4    lukem 	Lines = 10;
    674       1.4    lukem 	while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
    675       1.4    lukem 		if (Other.p_specialtype == SC_COUNCIL && Other.p_status != S_NOTUSED)
    676       1.4    lukem 			/* found a member of the council */
    677       1.4    lukem 		{
    678       1.4    lukem 			if (!councilfound) {
    679       1.4    lukem 				mvaddstr(8, 30, "Council of the Wise:");
    680       1.4    lukem 				councilfound = TRUE;
    681       1.4    lukem 			}
    682       1.4    lukem 			/* This assumes a finite (<=5) number of C.O.W.: */
    683       1.4    lukem 			sprintf(Databuf, "%s   Login:  %s", Other.p_name, Other.p_login);
    684       1.4    lukem 			mvaddstr(Lines++, 40 - strlen(Databuf) / 2, Databuf);
    685       1.4    lukem 		}
    686       1.4    lukem 	/* search for the two highest players */
    687       1.4    lukem 	nxtname[0] = hiname[0] = '\0';
    688       1.4    lukem 	hiexp = 0.0;
    689       1.4    lukem 	nxtlvl = hilvl = 0;
    690       1.4    lukem 
    691       1.8      jsm 	fseek(Playersfp, 0L, SEEK_SET);
    692       1.4    lukem 	while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
    693       1.4    lukem 		if (Other.p_experience > hiexp && Other.p_specialtype <= SC_KING && Other.p_status != S_NOTUSED)
    694       1.4    lukem 			/* highest found so far */
    695       1.4    lukem 		{
    696       1.4    lukem 			nxtexp = hiexp;
    697       1.4    lukem 			hiexp = Other.p_experience;
    698       1.4    lukem 			nxtlvl = hilvl;
    699       1.4    lukem 			hilvl = Other.p_level;
    700       1.4    lukem 			strcpy(nxtname, hiname);
    701       1.4    lukem 			strcpy(hiname, Other.p_name);
    702       1.4    lukem 		} else
    703       1.4    lukem 			if (Other.p_experience > nxtexp
    704       1.4    lukem 			    && Other.p_specialtype <= SC_KING
    705       1.4    lukem 			    && Other.p_status != S_NOTUSED)
    706       1.4    lukem 				/* next highest found so far */
    707       1.4    lukem 			{
    708       1.4    lukem 				nxtexp = Other.p_experience;
    709       1.4    lukem 				nxtlvl = Other.p_level;
    710       1.4    lukem 				strcpy(nxtname, Other.p_name);
    711       1.4    lukem 			}
    712       1.4    lukem 	mvaddstr(15, 28, "Highest characters are:");
    713       1.4    lukem 	sprintf(Databuf, "%s  Level:%.0f   and   %s  Level:%.0f",
    714       1.4    lukem 	    hiname, hilvl, nxtname, nxtlvl);
    715       1.4    lukem 	mvaddstr(17, 40 - strlen(Databuf) / 2, Databuf);
    716       1.4    lukem 
    717       1.4    lukem 	/* print last to die */
    718       1.4    lukem 	if ((fp = fopen(_PATH_LASTDEAD, "r")) != NULL
    719       1.4    lukem 	    && fgets(Databuf, SZ_DATABUF, fp) != NULL) {
    720       1.4    lukem 		mvaddstr(19, 25, "The last character to die was:");
    721       1.4    lukem 		mvaddstr(20, 40 - strlen(Databuf) / 2, Databuf);
    722       1.4    lukem 		fclose(fp);
    723       1.1      jtc 	}
    724       1.4    lukem 	refresh();
    725       1.1      jtc }
    726       1.1      jtc 
    727       1.1      jtc long
    728       1.1      jtc recallplayer()
    729       1.1      jtc {
    730       1.4    lukem 	long    loc = 0L;	/* location in player file */
    731       1.4    lukem 	int     loop;		/* loop counter */
    732       1.4    lukem 	int     ch;		/* input */
    733       1.1      jtc 
    734       1.4    lukem 	clear();
    735       1.4    lukem 	mvprintw(10, 0, "What was your character's name ? ");
    736       1.4    lukem 	getstring(Databuf, SZ_NAME);
    737       1.4    lukem 	truncstring(Databuf);
    738       1.4    lukem 
    739       1.4    lukem 	if ((loc = findname(Databuf, &Player)) >= 0L)
    740       1.4    lukem 		/* found character */
    741       1.4    lukem 	{
    742       1.4    lukem 		Echo = FALSE;
    743       1.4    lukem 
    744       1.4    lukem 		for (loop = 0; loop < 2; ++loop) {
    745       1.4    lukem 			/* prompt for password */
    746       1.4    lukem 			mvaddstr(11, 0, "Password ? ");
    747       1.4    lukem 			getstring(Databuf, SZ_PASSWORD);
    748       1.4    lukem 			if (strcmp(Databuf, Player.p_password) == 0)
    749       1.4    lukem 				/* password good */
    750       1.4    lukem 			{
    751       1.4    lukem 				Echo = TRUE;
    752       1.1      jtc 
    753       1.4    lukem 				if (Player.p_status != S_OFF)
    754       1.4    lukem 					/* player did not exit normally last
    755       1.4    lukem 					 * time */
    756       1.4    lukem 				{
    757       1.4    lukem 					clear();
    758       1.4    lukem 					addstr("Your character did not exit normally last time.\n");
    759       1.4    lukem 					addstr("If you think you have good cause to have your character saved,\n");
    760       1.4    lukem 					printw("you may quit and mail your reason to 'root'.\n");
    761       1.4    lukem 					addstr("Otherwise, continuing spells certain death.\n");
    762       1.4    lukem 					addstr("Do you want to quit ? ");
    763       1.4    lukem 					ch = getanswer("YN", FALSE);
    764       1.4    lukem 					if (ch == 'Y') {
    765       1.4    lukem 						Player.p_status = S_HUNGUP;
    766       1.4    lukem 						writerecord(&Player, loc);
    767       1.4    lukem 						cleanup(TRUE);
    768       1.4    lukem 						/* NOTREACHED */
    769       1.4    lukem 					}
    770       1.4    lukem 					death("Stupidity");
    771       1.4    lukem 					/* NOTREACHED */
    772       1.4    lukem 				}
    773       1.4    lukem 				return (loc);
    774       1.4    lukem 			} else
    775       1.4    lukem 				mvaddstr(12, 0, "No good.\n");
    776       1.1      jtc 		}
    777       1.1      jtc 
    778       1.4    lukem 		Echo = TRUE;
    779       1.4    lukem 	} else
    780       1.4    lukem 		mvaddstr(11, 0, "Not found.\n");
    781       1.1      jtc 
    782       1.4    lukem 	more(13);
    783       1.4    lukem 	return (-1L);
    784       1.1      jtc }
    785       1.1      jtc 
    786       1.4    lukem void
    787       1.1      jtc neatstuff()
    788       1.1      jtc {
    789       1.4    lukem 	double  temp;		/* for temporary calculations */
    790       1.4    lukem 	int     ch;		/* input */
    791       1.1      jtc 
    792       1.4    lukem 	switch ((int) ROLL(0.0, 100.0)) {
    793       1.1      jtc 	case 1:
    794       1.1      jtc 	case 2:
    795       1.4    lukem 		if (Player.p_poison > 0.0) {
    796       1.4    lukem 			mvaddstr(4, 0, "You've found a medic!  How much will you offer to be cured ? ");
    797       1.4    lukem 			temp = floor(infloat());
    798       1.4    lukem 			if (temp < 0.0 || temp > Player.p_gold)
    799       1.4    lukem 				/* negative gold, or more than available */
    800       1.4    lukem 			{
    801       1.4    lukem 				mvaddstr(6, 0, "He was not amused, and made you worse.\n");
    802       1.4    lukem 				Player.p_poison += 1.0;
    803       1.4    lukem 			} else
    804       1.4    lukem 				if (drandom() / 2.0 > (temp + 1.0) / MAX(Player.p_gold, 1))
    805       1.4    lukem 					/* medic wants 1/2 of available gold */
    806       1.4    lukem 					mvaddstr(5, 0, "Sorry, he wasn't interested.\n");
    807       1.4    lukem 				else {
    808       1.4    lukem 					mvaddstr(5, 0, "He accepted.");
    809       1.4    lukem 					Player.p_poison = MAX(0.0, Player.p_poison - 1.0);
    810       1.4    lukem 					Player.p_gold -= temp;
    811       1.4    lukem 				}
    812       1.1      jtc 		}
    813       1.4    lukem 		break;
    814       1.1      jtc 
    815       1.1      jtc 	case 3:
    816       1.4    lukem 		mvaddstr(4, 0, "You've been caught raping and pillaging!\n");
    817       1.4    lukem 		Player.p_experience += 4000.0;
    818       1.4    lukem 		Player.p_sin += 0.5;
    819       1.4    lukem 		break;
    820       1.1      jtc 
    821       1.1      jtc 	case 4:
    822       1.4    lukem 		temp = ROLL(10.0, 75.0);
    823       1.4    lukem 		mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp);
    824       1.4    lukem 		ch = getanswer("NY", FALSE);
    825       1.4    lukem 
    826       1.4    lukem 		if (ch == 'Y')
    827       1.4    lukem 			collecttaxes(temp, 0.0);
    828       1.4    lukem 		break;
    829       1.1      jtc 
    830       1.1      jtc 	case 5:
    831       1.4    lukem 		if (Player.p_sin > 1.0) {
    832       1.4    lukem 			mvaddstr(4, 0, "You've found a Holy Orb!\n");
    833       1.4    lukem 			Player.p_sin -= 0.25;
    834       1.1      jtc 		}
    835       1.4    lukem 		break;
    836       1.1      jtc 
    837       1.1      jtc 	case 6:
    838       1.4    lukem 		if (Player.p_poison < 1.0) {
    839       1.4    lukem 			mvaddstr(4, 0, "You've been hit with a plague!\n");
    840       1.4    lukem 			Player.p_poison += 1.0;
    841       1.1      jtc 		}
    842       1.4    lukem 		break;
    843       1.1      jtc 
    844       1.1      jtc 	case 7:
    845       1.4    lukem 		mvaddstr(4, 0, "You've found some holy water.\n");
    846       1.4    lukem 		++Player.p_holywater;
    847       1.4    lukem 		break;
    848       1.1      jtc 
    849       1.1      jtc 	case 8:
    850       1.4    lukem 		mvaddstr(4, 0, "You've met a Guru. . .");
    851       1.4    lukem 		if (drandom() * Player.p_sin > 1.0)
    852       1.4    lukem 			addstr("You disgusted him with your sins!\n");
    853       1.4    lukem 		else
    854       1.4    lukem 			if (Player.p_poison > 0.0) {
    855       1.4    lukem 				addstr("He looked kindly upon you, and cured you.\n");
    856       1.4    lukem 				Player.p_poison = 0.0;
    857       1.4    lukem 			} else {
    858       1.4    lukem 				addstr("He rewarded you for your virtue.\n");
    859       1.4    lukem 				Player.p_mana += 50.0;
    860       1.4    lukem 				Player.p_shield += 2.0;
    861       1.4    lukem 			}
    862       1.4    lukem 		break;
    863       1.1      jtc 
    864       1.1      jtc 	case 9:
    865       1.4    lukem 		mvaddstr(4, 0, "You've found an amulet.\n");
    866       1.4    lukem 		++Player.p_amulets;
    867       1.4    lukem 		break;
    868       1.1      jtc 
    869       1.1      jtc 	case 10:
    870       1.4    lukem 		if (Player.p_blindness) {
    871       1.4    lukem 			mvaddstr(4, 0, "You've regained your sight!\n");
    872       1.4    lukem 			Player.p_blindness = FALSE;
    873       1.1      jtc 		}
    874       1.4    lukem 		break;
    875       1.1      jtc 
    876       1.4    lukem 	default:		/* deal with poison */
    877       1.4    lukem 		if (Player.p_poison > 0.0) {
    878       1.4    lukem 			temp = Player.p_poison * Statptr->c_weakness
    879       1.4    lukem 			    * Player.p_maxenergy / 600.0;
    880       1.4    lukem 			if (Player.p_energy > Player.p_maxenergy / 10.0
    881       1.4    lukem 			    && temp + 5.0 < Player.p_energy)
    882       1.4    lukem 				Player.p_energy -= temp;
    883       1.1      jtc 		}
    884       1.4    lukem 		break;
    885       1.1      jtc 	}
    886       1.1      jtc }
    887       1.1      jtc 
    888       1.4    lukem void
    889       1.1      jtc genchar(type)
    890       1.4    lukem 	int     type;
    891       1.1      jtc {
    892       1.4    lukem 	int     subscript;	/* used for subscripting into Stattable */
    893       1.7      jsm 	const struct charstats *statptr; /* for pointing into Stattable */
    894       1.1      jtc 
    895       1.4    lukem 	subscript = type - '1';
    896       1.1      jtc 
    897       1.4    lukem 	if (subscript < C_MAGIC || subscript > C_EXPER)
    898       1.4    lukem 		if (subscript != C_SUPER || !Wizard)
    899       1.4    lukem 			/* fighter is default */
    900       1.4    lukem 			subscript = C_FIGHTER;
    901       1.4    lukem 
    902       1.4    lukem 	statptr = &Stattable[subscript];
    903       1.4    lukem 
    904       1.4    lukem 	Player.p_quickness =
    905       1.4    lukem 	    ROLL(statptr->c_quickness.base, statptr->c_quickness.interval);
    906       1.4    lukem 	Player.p_strength =
    907       1.4    lukem 	    ROLL(statptr->c_strength.base, statptr->c_strength.interval);
    908       1.4    lukem 	Player.p_mana =
    909       1.4    lukem 	    ROLL(statptr->c_mana.base, statptr->c_mana.interval);
    910       1.4    lukem 	Player.p_maxenergy =
    911       1.4    lukem 	    Player.p_energy =
    912       1.4    lukem 	    ROLL(statptr->c_energy.base, statptr->c_energy.interval);
    913       1.4    lukem 	Player.p_brains =
    914       1.4    lukem 	    ROLL(statptr->c_brains.base, statptr->c_brains.interval);
    915       1.4    lukem 	Player.p_magiclvl =
    916       1.4    lukem 	    ROLL(statptr->c_magiclvl.base, statptr->c_magiclvl.interval);
    917       1.4    lukem 
    918       1.4    lukem 	Player.p_type = subscript;
    919       1.4    lukem 
    920       1.4    lukem 	if (Player.p_type == C_HALFLING)
    921       1.4    lukem 		/* give halfling some experience */
    922       1.4    lukem 		Player.p_experience = ROLL(600.0, 200.0);
    923       1.1      jtc }
    924       1.1      jtc 
    925       1.4    lukem void
    926       1.1      jtc playinit()
    927       1.1      jtc {
    928       1.4    lukem 	/* catch/ingnore signals */
    929       1.1      jtc 
    930       1.1      jtc #ifdef	BSD41
    931       1.4    lukem 	sigignore(SIGQUIT);
    932       1.4    lukem 	sigignore(SIGALRM);
    933       1.4    lukem 	sigignore(SIGTERM);
    934       1.4    lukem 	sigignore(SIGTSTP);
    935       1.4    lukem 	sigignore(SIGTTIN);
    936       1.4    lukem 	sigignore(SIGTTOU);
    937       1.4    lukem 	sighold(SIGINT);
    938       1.4    lukem 	sigset(SIGHUP, ill_sig);
    939       1.4    lukem 	sigset(SIGTRAP, ill_sig);
    940       1.4    lukem 	sigset(SIGIOT, ill_sig);
    941       1.4    lukem 	sigset(SIGEMT, ill_sig);
    942       1.4    lukem 	sigset(SIGFPE, ill_sig);
    943       1.4    lukem 	sigset(SIGBUS, ill_sig);
    944       1.4    lukem 	sigset(SIGSEGV, ill_sig);
    945       1.4    lukem 	sigset(SIGSYS, ill_sig);
    946       1.4    lukem 	sigset(SIGPIPE, ill_sig);
    947       1.1      jtc #endif
    948       1.1      jtc #ifdef	BSD42
    949       1.4    lukem 	signal(SIGQUIT, ill_sig);
    950       1.4    lukem 	signal(SIGALRM, SIG_IGN);
    951       1.4    lukem 	signal(SIGTERM, SIG_IGN);
    952       1.4    lukem 	signal(SIGTSTP, SIG_IGN);
    953       1.4    lukem 	signal(SIGTTIN, SIG_IGN);
    954       1.4    lukem 	signal(SIGTTOU, SIG_IGN);
    955       1.4    lukem 	signal(SIGINT, ill_sig);
    956       1.4    lukem 	signal(SIGHUP, SIG_DFL);
    957       1.4    lukem 	signal(SIGTRAP, ill_sig);
    958       1.4    lukem 	signal(SIGIOT, ill_sig);
    959       1.4    lukem 	signal(SIGEMT, ill_sig);
    960       1.4    lukem 	signal(SIGFPE, ill_sig);
    961       1.4    lukem 	signal(SIGBUS, ill_sig);
    962       1.4    lukem 	signal(SIGSEGV, ill_sig);
    963       1.4    lukem 	signal(SIGSYS, ill_sig);
    964       1.4    lukem 	signal(SIGPIPE, ill_sig);
    965       1.1      jtc #endif
    966       1.1      jtc #ifdef	SYS3
    967       1.4    lukem 	signal(SIGINT, SIG_IGN);
    968       1.4    lukem 	signal(SIGQUIT, SIG_IGN);
    969       1.4    lukem 	signal(SIGTERM, SIG_IGN);
    970       1.4    lukem 	signal(SIGALRM, SIG_IGN);
    971       1.4    lukem 	signal(SIGHUP, ill_sig);
    972       1.4    lukem 	signal(SIGTRAP, ill_sig);
    973       1.4    lukem 	signal(SIGIOT, ill_sig);
    974       1.4    lukem 	signal(SIGEMT, ill_sig);
    975       1.4    lukem 	signal(SIGFPE, ill_sig);
    976       1.4    lukem 	signal(SIGBUS, ill_sig);
    977       1.4    lukem 	signal(SIGSEGV, ill_sig);
    978       1.4    lukem 	signal(SIGSYS, ill_sig);
    979       1.4    lukem 	signal(SIGPIPE, ill_sig);
    980       1.1      jtc #endif
    981       1.1      jtc #ifdef	SYS5
    982       1.4    lukem 	signal(SIGINT, SIG_IGN);
    983       1.4    lukem 	signal(SIGQUIT, SIG_IGN);
    984       1.4    lukem 	signal(SIGTERM, SIG_IGN);
    985       1.4    lukem 	signal(SIGALRM, SIG_IGN);
    986       1.4    lukem 	signal(SIGHUP, ill_sig);
    987       1.4    lukem 	signal(SIGTRAP, ill_sig);
    988       1.4    lukem 	signal(SIGIOT, ill_sig);
    989       1.4    lukem 	signal(SIGEMT, ill_sig);
    990       1.4    lukem 	signal(SIGFPE, ill_sig);
    991       1.4    lukem 	signal(SIGBUS, ill_sig);
    992       1.4    lukem 	signal(SIGSEGV, ill_sig);
    993       1.4    lukem 	signal(SIGSYS, ill_sig);
    994       1.4    lukem 	signal(SIGPIPE, ill_sig);
    995       1.1      jtc #endif
    996       1.1      jtc 
    997       1.4    lukem 	initscr();		/* turn on curses */
    998       1.4    lukem 	noecho();		/* do not echo input */
    999      1.10    blymn 	cbreak();		/* do not process erase, kill */
   1000       1.4    lukem 	clear();
   1001       1.4    lukem 	refresh();
   1002       1.4    lukem 	Windows = TRUE;		/* mark the state */
   1003       1.1      jtc }
   1004       1.1      jtc 
   1005       1.4    lukem void
   1006       1.1      jtc cleanup(doexit)
   1007       1.4    lukem 	int    doexit;
   1008       1.1      jtc {
   1009       1.4    lukem 	if (Windows) {
   1010       1.4    lukem 		move(LINES - 2, 0);
   1011       1.4    lukem 		refresh();
   1012      1.10    blymn 		nocbreak();
   1013       1.4    lukem 		endwin();
   1014       1.4    lukem 	}
   1015      1.12      jsm 	if (Playersfp)
   1016      1.12      jsm 		fclose(Playersfp);
   1017      1.12      jsm 	if (Monstfp)
   1018      1.12      jsm 		fclose(Monstfp);
   1019      1.12      jsm 	if (Messagefp)
   1020      1.12      jsm 		fclose(Messagefp);
   1021      1.12      jsm 	if (Energyvoidfp)
   1022      1.12      jsm 		fclose(Energyvoidfp);
   1023       1.4    lukem 
   1024       1.4    lukem 	if (doexit)
   1025       1.4    lukem 		exit(0);
   1026       1.4    lukem 	/* NOTREACHED */
   1027       1.1      jtc }
   1028