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