Home | History | Annotate | Line # | Download | only in larn
main.c revision 1.24
      1  1.24  dholland /*	$NetBSD: main.c,v 1.24 2009/08/12 08:04:05 dholland Exp $	*/
      2  1.11  christos 
      3  1.11  christos /* main.c		 */
      4  1.11  christos #include <sys/cdefs.h>
      5   1.3   mycroft #ifndef lint
      6  1.24  dholland __RCSID("$NetBSD: main.c,v 1.24 2009/08/12 08:04:05 dholland Exp $");
      7  1.11  christos #endif				/* not lint */
      8   1.3   mycroft 
      9   1.1       cgd #include <sys/types.h>
     10  1.11  christos #include <stdio.h>
     11   1.1       cgd #include <pwd.h>
     12  1.11  christos #include <unistd.h>
     13  1.11  christos #include <stdlib.h>
     14   1.7       cgd #include <string.h>
     15  1.11  christos #include "header.h"
     16  1.11  christos #include "extern.h"
     17   1.7       cgd 
     18  1.24  dholland static void showstr(void);
     19  1.24  dholland static void t_setup(int);
     20  1.24  dholland static void t_endup(int);
     21  1.24  dholland static void showwear(void);
     22  1.24  dholland static void showwield(void);
     23  1.24  dholland static void showread(void);
     24  1.24  dholland static void showeat(void);
     25  1.24  dholland static void showquaff(void);
     26  1.24  dholland static void show1(int, const char *[]);
     27  1.24  dholland static void randmonst(void);
     28  1.24  dholland static void parse(void);
     29  1.24  dholland static void run(int);
     30  1.24  dholland static void wield(void);
     31  1.24  dholland static void ydhi(int);
     32  1.24  dholland static void ycwi(int);
     33  1.24  dholland static void wear(void);
     34  1.24  dholland static void dropobj(void);
     35  1.24  dholland static void readscr(void);
     36  1.24  dholland static void eatcookie(void);
     37  1.24  dholland static void quaff(void);
     38  1.22  dholland static int whatitem(const char *);
     39  1.22  dholland 
     40  1.11  christos static char     copyright[] = "\nLarn is copyrighted 1986 by Noah Morgan.\n";
     41  1.11  christos int             srcount = 0;	/* line counter for showstr()	 */
     42  1.11  christos int             dropflag = 0;	/* if 1 then don't lookforobject() next round */
     43  1.11  christos int             rmst = 80;	/* random monster creation counter		 */
     44  1.11  christos int             userid;		/* the players login user id number */
     45  1.21  dholland gid_t           gid, egid;	/* used for security */
     46  1.11  christos u_char          nowelcome = 0, nomove = 0;	/* if (nomove) then don't
     47  1.11  christos 						 * count next iteration as a
     48  1.11  christos 						 * move */
     49  1.11  christos static char     viewflag = 0;
     50  1.11  christos /*
     51  1.11  christos  * if viewflag then we have done a 99 stay here and don't showcell in the
     52  1.11  christos  * main loop
     53  1.11  christos  */
     54  1.11  christos u_char          restorflag = 0;	/* 1 means restore has been done	 */
     55  1.11  christos static char     cmdhelp[] = "\
     56  1.12     mikel Cmd line format: larn [-slicnh] [-o<optsfile>] [-##] [++]\n\
     57   1.1       cgd   -s   show the scoreboard\n\
     58   1.1       cgd   -l   show the logfile (wizard id only)\n\
     59   1.1       cgd   -i   show scoreboard with inventories of dead characters\n\
     60   1.1       cgd   -c   create new scoreboard (wizard id only)\n\
     61   1.1       cgd   -n   suppress welcome message on starting game\n\
     62   1.1       cgd   -##  specify level of difficulty (example: -5)\n\
     63   1.1       cgd   -h   print this help text\n\
     64   1.1       cgd   ++   restore game from checkpoint file\n\
     65   1.1       cgd   -o<optsfile>   specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
     66   1.1       cgd ";
     67   1.1       cgd #ifdef VT100
     68  1.11  christos static char    *termtypes[] = {"vt100", "vt101", "vt102", "vt103", "vt125",
     69   1.1       cgd 	"vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
     70  1.11  christos "vt341"};
     71  1.11  christos #endif	/* VT100 */
     72   1.1       cgd /*
     73   1.1       cgd 	************
     74   1.1       cgd 	MAIN PROGRAM
     75   1.1       cgd 	************
     76   1.1       cgd  */
     77  1.11  christos int
     78  1.11  christos main(argc, argv)
     79  1.11  christos 	int             argc;
     80  1.11  christos 	char          **argv;
     81  1.11  christos {
     82  1.11  christos 	int    i;
     83  1.11  christos 	int             hard;
     84  1.13   mycroft 	const char     *ptr = 0;
     85  1.11  christos 	struct passwd  *pwe;
     86   1.1       cgd 
     87  1.15     blymn 	i = 0;
     88  1.21  dholland 	egid = getegid();
     89  1.21  dholland 	gid = getgid();
     90  1.21  dholland 	setegid(gid);		/* give up "games" if we have it */
     91  1.11  christos 	/*
     92  1.11  christos 	 *	first task is to identify the player
     93  1.11  christos 	 */
     94   1.1       cgd #ifndef VT100
     95  1.11  christos 	init_term();		/* setup the terminal (find out what type)
     96  1.11  christos 				 * for termcap */
     97  1.11  christos #endif	/* VT100 */
     98  1.14     veego 	/* try to get login name */
     99  1.14     veego 	if (((ptr = getlogin()) == 0) || (*ptr == 0)) {
    100  1.14     veego 		/* can we get it from /etc/passwd? */
    101  1.14     veego 		if ((pwe = getpwuid(getuid())) != NULL)
    102  1.11  christos 			ptr = pwe->pw_name;
    103  1.11  christos 		else if ((ptr = getenv("USER")) == 0)
    104  1.11  christos 			if ((ptr = getenv("LOGNAME")) == 0) {
    105  1.11  christos 		noone:		write(2, "Can't find your logname.  Who Are You?\n", 39);
    106  1.11  christos 				exit(1);
    107  1.11  christos 			}
    108  1.14     veego 	}
    109  1.11  christos 	if (ptr == 0)
    110  1.11  christos 		goto noone;
    111  1.11  christos 	if (strlen(ptr) == 0)
    112  1.11  christos 		goto noone;
    113  1.11  christos 	/*
    114  1.11  christos 	 *	second task is to prepare the pathnames the player will need
    115  1.11  christos 	 */
    116  1.11  christos 	strcpy(loginname, ptr);	/* save loginname of the user for logging
    117  1.11  christos 				 * purposes */
    118  1.11  christos 	strcpy(logname, ptr);	/* this will be overwritten with the players
    119  1.11  christos 				 * name */
    120  1.11  christos 	if ((ptr = getenv("HOME")) == NULL)
    121  1.11  christos 		ptr = ".";
    122   1.1       cgd 	strcpy(savefilename, ptr);
    123  1.11  christos 	strcat(savefilename, "/Larn.sav");	/* save file name in home
    124  1.11  christos 						 * directory */
    125  1.16  christos 	snprintf(optsfile, sizeof(optsfile), "%s/.larnopts", ptr);
    126  1.16  christos 	/* the .larnopts filename */
    127  1.11  christos 
    128  1.11  christos 	/*
    129  1.11  christos 	 *	now malloc the memory for the dungeon
    130  1.11  christos 	 */
    131  1.11  christos 	cell = (struct cel *) malloc(sizeof(struct cel) * (MAXLEVEL + MAXVLEVEL) * MAXX * MAXY);
    132  1.11  christos 	if (cell == 0)
    133  1.11  christos 		died(-285);	/* malloc failure */
    134  1.11  christos 	lpbuf = malloc((5 * BUFBIG) >> 2);	/* output buffer */
    135  1.11  christos 	inbuffer = malloc((5 * MAXIBUF) >> 2);	/* output buffer */
    136  1.11  christos 	if ((lpbuf == 0) || (inbuffer == 0))
    137  1.11  christos 		died(-285);	/* malloc() failure */
    138  1.11  christos 
    139  1.11  christos 	lcreat((char *) 0);
    140  1.11  christos 	newgame();		/* set the initial clock  */
    141  1.11  christos 	hard = -1;
    142   1.1       cgd 
    143   1.1       cgd #ifdef VT100
    144  1.11  christos 	/*
    145  1.11  christos 	 *	check terminal type to avoid users who have not vt100 type terminals
    146  1.11  christos 	 */
    147   1.1       cgd 	ttype = getenv("TERM");
    148  1.11  christos 	for (j = 1, i = 0; i < sizeof(termtypes) / sizeof(char *); i++)
    149  1.11  christos 		if (strcmp(ttype, termtypes[i]) == 0) {
    150  1.11  christos 			j = 0;
    151  1.11  christos 			break;
    152   1.1       cgd 		}
    153  1.11  christos 	if (j) {
    154  1.17       snj 		lprcat("Sorry, Larn needs a VT100 family terminal for all its features.\n");
    155  1.11  christos 		lflush();
    156  1.11  christos 		exit(1);
    157  1.11  christos 	}
    158  1.11  christos #endif	/* VT100 */
    159  1.11  christos 
    160  1.11  christos 	/*
    161  1.11  christos 	 *	now make scoreboard if it is not there (don't clear)
    162  1.11  christos 	 */
    163  1.11  christos 	if (access(scorefile, 0) == -1)	/* not there */
    164   1.1       cgd 		makeboard();
    165   1.1       cgd 
    166  1.11  christos 	/*
    167  1.11  christos 	 *	now process the command line arguments
    168  1.11  christos 	 */
    169  1.11  christos 	for (i = 1; i < argc; i++) {
    170   1.1       cgd 		if (argv[i][0] == '-')
    171  1.11  christos 			switch (argv[i][1]) {
    172  1.11  christos 			case 's':
    173  1.11  christos 				showscores();
    174  1.11  christos 				exit(0);	/* show scoreboard   */
    175  1.11  christos 
    176  1.11  christos 			case 'l':	/* show log file     */
    177  1.11  christos 				diedlog();
    178  1.11  christos 				exit(0);
    179  1.11  christos 
    180  1.11  christos 			case 'i':
    181  1.11  christos 				showallscores();
    182  1.11  christos 				exit(0);	/* show all scoreboard */
    183  1.11  christos 
    184  1.11  christos 			case 'c':	/* anyone with password can create
    185  1.11  christos 					 * scoreboard */
    186  1.11  christos 				lprcat("Preparing to initialize the scoreboard.\n");
    187  1.11  christos 				if (getpassword() != 0) {	/* make new scoreboard */
    188  1.11  christos 					makeboard();
    189  1.11  christos 					lprc('\n');
    190  1.11  christos 					showscores();
    191  1.11  christos 				}
    192  1.11  christos 				exit(0);
    193   1.1       cgd 
    194  1.11  christos 			case 'n':	/* no welcome msg	 */
    195  1.11  christos 				nowelcome = 1;
    196  1.11  christos 				argv[i][0] = 0;
    197  1.11  christos 				break;
    198  1.11  christos 
    199  1.11  christos 			case '0':
    200  1.11  christos 			case '1':
    201  1.11  christos 			case '2':
    202  1.11  christos 			case '3':
    203  1.11  christos 			case '4':
    204  1.11  christos 			case '5':
    205  1.11  christos 			case '6':
    206  1.11  christos 			case '7':
    207  1.11  christos 			case '8':
    208  1.11  christos 			case '9':	/* for hardness */
    209  1.11  christos 				sscanf(&argv[i][1], "%d", &hard);
    210  1.11  christos 				break;
    211   1.1       cgd 
    212   1.1       cgd 			case 'h':	/* print out command line arguments */
    213  1.11  christos 				write(1, cmdhelp, sizeof(cmdhelp));
    214  1.11  christos 				exit(0);
    215   1.1       cgd 
    216   1.1       cgd 			case 'o':	/* specify a .larnopts filename */
    217  1.11  christos 				strncpy(optsfile, argv[i] + 2, 127);
    218  1.11  christos 				break;
    219   1.1       cgd 
    220  1.11  christos 			default:
    221  1.11  christos 				printf("Unknown option <%s>\n", argv[i]);
    222  1.11  christos 				exit(1);
    223   1.1       cgd 			};
    224   1.1       cgd 
    225  1.11  christos 		if (argv[i][0] == '+') {
    226  1.11  christos 			clear();
    227  1.11  christos 			restorflag = 1;
    228  1.11  christos 			if (argv[i][1] == '+') {
    229  1.11  christos 				hitflag = 1;
    230  1.11  christos 				restoregame(ckpfile);	/* restore checkpointed
    231  1.11  christos 							 * game */
    232  1.11  christos 			}
    233   1.1       cgd 			i = argc;
    234   1.1       cgd 		}
    235  1.11  christos 	}
    236   1.1       cgd 
    237   1.1       cgd 	readopts();		/* read the options file if there is one */
    238   1.1       cgd 
    239   1.1       cgd 
    240   1.1       cgd #ifdef UIDSCORE
    241   1.1       cgd 	userid = geteuid();	/* obtain the user's effective id number */
    242  1.11  christos #else	/* UIDSCORE */
    243   1.1       cgd 	userid = getplid(logname);	/* obtain the players id number */
    244  1.11  christos #endif	/* UIDSCORE */
    245  1.11  christos 	if (userid < 0) {
    246  1.11  christos 		write(2, "Can't obtain playerid\n", 22);
    247  1.11  christos 		exit(1);
    248  1.11  christos 	}
    249   1.1       cgd #ifdef HIDEBYLINK
    250  1.11  christos 	/*
    251  1.11  christos 	 *	this section of code causes the program to look like something else to ps
    252  1.11  christos 	 */
    253  1.11  christos 	if (strcmp(psname, argv[0])) {	/* if a different process name only */
    254  1.11  christos 		if ((i = access(psname, 1)) < 0) {	/* link not there */
    255  1.11  christos 			if (link(argv[0], psname) >= 0) {
    256  1.11  christos 				argv[0] = psname;
    257  1.11  christos 				execv(psname, argv);
    258   1.1       cgd 			}
    259  1.11  christos 		} else
    260   1.1       cgd 			unlink(psname);
    261  1.11  christos 	}
    262  1.11  christos 	for (i = 1; i < argc; i++) {
    263   1.1       cgd 		szero(argv[i]);	/* zero the argument to avoid ps snooping */
    264  1.11  christos 	}
    265  1.11  christos #endif	/* HIDEBYLINK */
    266   1.1       cgd 
    267  1.11  christos 	if (access(savefilename, 0) == 0) {	/* restore game if need to */
    268  1.11  christos 		clear();
    269  1.11  christos 		restorflag = 1;
    270  1.11  christos 		hitflag = 1;
    271  1.11  christos 		restoregame(savefilename);	/* restore last game	 */
    272  1.11  christos 	}
    273  1.11  christos 	sigsetup();		/* trap all needed signals	 */
    274  1.11  christos 	sethard(hard);		/* set up the desired difficulty				 */
    275  1.11  christos 	setupvt100();		/* setup the terminal special mode				 */
    276  1.11  christos 	if (c[HP] == 0) {	/* create new game */
    277  1.11  christos 		makeplayer();	/* make the character that will play			 */
    278  1.11  christos 		newcavelevel(0);/* make the dungeon						 	 */
    279  1.11  christos 		predostuff = 1;	/* tell signals that we are in the welcome
    280  1.11  christos 				 * screen */
    281  1.11  christos 		if (nowelcome == 0)
    282  1.11  christos 			welcome();	/* welcome the player to the game */
    283  1.11  christos 	}
    284  1.11  christos 	drawscreen();		/* show the initial dungeon					 */
    285  1.11  christos 	predostuff = 2;		/* tell the trap functions that they must do
    286  1.11  christos 				 * a showplayer() from here on */
    287  1.11  christos #if 0
    288  1.11  christos 	nice(1);		/* games should be run niced */
    289  1.11  christos #endif
    290   1.1       cgd 	yrepcount = hit2flag = 0;
    291  1.11  christos 	while (1) {
    292  1.11  christos 		if (dropflag == 0)
    293  1.11  christos 			lookforobject();	/* see if there is an object
    294  1.11  christos 						 * here	 */
    295  1.11  christos 		else
    296  1.11  christos 			dropflag = 0;	/* don't show it just dropped an item */
    297  1.11  christos 		if (hitflag == 0) {
    298  1.11  christos 			if (c[HASTEMONST])
    299  1.11  christos 				movemonst();
    300  1.11  christos 			movemonst();
    301  1.11  christos 		}		/* move the monsters		 */
    302  1.11  christos 		if (viewflag == 0)
    303  1.11  christos 			showcell(playerx, playery);
    304  1.11  christos 		else
    305  1.11  christos 			viewflag = 0;	/* show stuff around player	 */
    306  1.11  christos 		if (hit3flag)
    307  1.11  christos 			flushall();
    308  1.11  christos 		hitflag = hit3flag = 0;
    309  1.11  christos 		nomove = 1;
    310   1.1       cgd 		bot_linex();	/* update bottom line */
    311  1.11  christos 		while (nomove) {
    312  1.11  christos 			if (hit3flag)
    313  1.11  christos 				flushall();
    314  1.11  christos 			nomove = 0;
    315  1.11  christos 			parse();
    316  1.11  christos 		}		/* get commands and make moves	 */
    317  1.11  christos 		regen();	/* regenerate hp and spells			 */
    318  1.11  christos 		if (c[TIMESTOP] == 0)
    319  1.11  christos 			if (--rmst <= 0) {
    320  1.11  christos 				rmst = 120 - (level << 2);
    321  1.11  christos 				fillmonst(makemonst(level));
    322  1.11  christos 			}
    323   1.1       cgd 	}
    324  1.11  christos }
    325  1.11  christos 
    326  1.11  christos 
    327   1.1       cgd /*
    328   1.1       cgd 	showstr()
    329   1.1       cgd 
    330   1.1       cgd 	show character's inventory
    331   1.1       cgd  */
    332  1.24  dholland static void
    333   1.1       cgd showstr()
    334  1.11  christos {
    335  1.11  christos 	int    i, number;
    336  1.11  christos 	for (number = 3, i = 0; i < 26; i++)
    337  1.11  christos 		if (iven[i])
    338  1.11  christos 			number++;	/* count items in inventory */
    339  1.11  christos 	t_setup(number);
    340  1.11  christos 	qshowstr();
    341  1.11  christos 	t_endup(number);
    342  1.11  christos }
    343   1.1       cgd 
    344  1.11  christos void
    345   1.1       cgd qshowstr()
    346  1.11  christos {
    347  1.11  christos 	int    i, j, k, sigsav;
    348  1.11  christos 	srcount = 0;
    349  1.11  christos 	sigsav = nosignal;
    350  1.11  christos 	nosignal = 1;		/* don't allow ^c etc */
    351  1.11  christos 	if (c[GOLD]) {
    352  1.19  dholland 		lprintf(".)   %ld gold pieces", (long) c[GOLD]);
    353  1.11  christos 		srcount++;
    354  1.11  christos 	}
    355  1.11  christos 	for (k = 26; k >= 0; k--)
    356  1.11  christos 		if (iven[k]) {
    357  1.11  christos 			for (i = 22; i < 84; i++)
    358  1.11  christos 				for (j = 0; j <= k; j++)
    359  1.11  christos 					if (i == iven[j])
    360  1.11  christos 						show3(j);
    361  1.11  christos 			k = 0;
    362  1.11  christos 		}
    363  1.19  dholland 	lprintf("\nElapsed time is %ld.  You have %ld mobuls left", (long) ((gltime + 99) / 100 + 1), (long) ((TIMELIMIT - gltime) / 100));
    364  1.11  christos 	more();
    365  1.11  christos 	nosignal = sigsav;
    366  1.11  christos }
    367   1.1       cgd 
    368   1.1       cgd /*
    369   1.1       cgd  *	subroutine to clear screen depending on # lines to display
    370   1.1       cgd  */
    371  1.24  dholland static void
    372   1.1       cgd t_setup(count)
    373  1.11  christos 	int    count;
    374  1.11  christos {
    375  1.11  christos 	if (count < 20) {	/* how do we clear the screen? */
    376  1.11  christos 		cl_up(79, count);
    377  1.11  christos 		cursor(1, 1);
    378  1.11  christos 	} else {
    379  1.11  christos 		resetscroll();
    380  1.11  christos 		clear();
    381   1.1       cgd 	}
    382  1.11  christos }
    383   1.1       cgd 
    384   1.1       cgd /*
    385   1.1       cgd  *	subroutine to restore normal display screen depending on t_setup()
    386   1.1       cgd  */
    387  1.24  dholland static void
    388   1.1       cgd t_endup(count)
    389  1.11  christos 	int    count;
    390  1.11  christos {
    391  1.11  christos 	if (count < 18)		/* how did we clear the screen? */
    392  1.11  christos 		draws(0, MAXX, 0, (count > MAXY) ? MAXY : count);
    393  1.11  christos 	else {
    394  1.11  christos 		drawscreen();
    395  1.11  christos 		setscroll();
    396   1.1       cgd 	}
    397  1.11  christos }
    398   1.1       cgd 
    399   1.1       cgd /*
    400   1.1       cgd 	function to show the things player is wearing only
    401   1.1       cgd  */
    402  1.24  dholland static void
    403   1.1       cgd showwear()
    404  1.11  christos {
    405  1.11  christos 	int    i, j, sigsav, count;
    406  1.11  christos 	sigsav = nosignal;
    407  1.11  christos 	nosignal = 1;		/* don't allow ^c etc */
    408  1.11  christos 	srcount = 0;
    409  1.11  christos 
    410  1.11  christos 	for (count = 2, j = 0; j <= 26; j++)	/* count number of items we
    411  1.11  christos 						 * will display */
    412  1.11  christos 		if ((i = iven[j]) != 0)
    413  1.11  christos 			switch (i) {
    414  1.11  christos 			case OLEATHER:
    415  1.11  christos 			case OPLATE:
    416  1.11  christos 			case OCHAIN:
    417  1.11  christos 			case ORING:
    418  1.11  christos 			case OSTUDLEATHER:
    419  1.11  christos 			case OSPLINT:
    420  1.11  christos 			case OPLATEARMOR:
    421  1.11  christos 			case OSSPLATE:
    422  1.11  christos 			case OSHIELD:
    423  1.11  christos 				count++;
    424   1.1       cgd 			};
    425   1.1       cgd 
    426   1.1       cgd 	t_setup(count);
    427   1.1       cgd 
    428  1.11  christos 	for (i = 22; i < 84; i++)
    429  1.11  christos 		for (j = 0; j <= 26; j++)
    430  1.11  christos 			if (i == iven[j])
    431  1.11  christos 				switch (i) {
    432  1.11  christos 				case OLEATHER:
    433  1.11  christos 				case OPLATE:
    434  1.11  christos 				case OCHAIN:
    435  1.11  christos 				case ORING:
    436  1.11  christos 				case OSTUDLEATHER:
    437  1.11  christos 				case OSPLINT:
    438  1.11  christos 				case OPLATEARMOR:
    439  1.11  christos 				case OSSPLATE:
    440  1.11  christos 				case OSHIELD:
    441  1.11  christos 					show3(j);
    442   1.1       cgd 				};
    443  1.11  christos 	more();
    444  1.11  christos 	nosignal = sigsav;
    445  1.11  christos 	t_endup(count);
    446  1.11  christos }
    447   1.1       cgd 
    448   1.1       cgd /*
    449  1.11  christos 	function to show the things player can wield only
    450   1.1       cgd  */
    451  1.24  dholland static void
    452   1.1       cgd showwield()
    453  1.11  christos {
    454  1.11  christos 	int    i, j, sigsav, count;
    455  1.11  christos 	sigsav = nosignal;
    456  1.11  christos 	nosignal = 1;		/* don't allow ^c etc */
    457  1.11  christos 	srcount = 0;
    458  1.11  christos 
    459  1.11  christos 	for (count = 2, j = 0; j <= 26; j++)	/* count how many items */
    460  1.11  christos 		if ((i = iven[j]) != 0)
    461  1.11  christos 			switch (i) {
    462  1.11  christos 			case ODIAMOND:
    463  1.11  christos 			case ORUBY:
    464  1.11  christos 			case OEMERALD:
    465  1.11  christos 			case OSAPPHIRE:
    466  1.11  christos 			case OBOOK:
    467  1.11  christos 			case OCHEST:
    468  1.11  christos 			case OLARNEYE:
    469  1.11  christos 			case ONOTHEFT:
    470  1.11  christos 			case OSPIRITSCARAB:
    471  1.11  christos 			case OCUBEofUNDEAD:
    472  1.11  christos 			case OPOTION:
    473  1.11  christos 			case OSCROLL:
    474  1.11  christos 				break;
    475  1.11  christos 			default:
    476  1.11  christos 				count++;
    477   1.1       cgd 			};
    478   1.1       cgd 
    479   1.1       cgd 	t_setup(count);
    480   1.1       cgd 
    481  1.11  christos 	for (i = 22; i < 84; i++)
    482  1.11  christos 		for (j = 0; j <= 26; j++)
    483  1.11  christos 			if (i == iven[j])
    484  1.11  christos 				switch (i) {
    485  1.11  christos 				case ODIAMOND:
    486  1.11  christos 				case ORUBY:
    487  1.11  christos 				case OEMERALD:
    488  1.11  christos 				case OSAPPHIRE:
    489  1.11  christos 				case OBOOK:
    490  1.11  christos 				case OCHEST:
    491  1.11  christos 				case OLARNEYE:
    492  1.11  christos 				case ONOTHEFT:
    493  1.11  christos 				case OSPIRITSCARAB:
    494  1.11  christos 				case OCUBEofUNDEAD:
    495  1.11  christos 				case OPOTION:
    496  1.11  christos 				case OSCROLL:
    497  1.11  christos 					break;
    498  1.11  christos 				default:
    499  1.11  christos 					show3(j);
    500   1.1       cgd 				};
    501  1.11  christos 	more();
    502  1.11  christos 	nosignal = sigsav;
    503  1.11  christos 	t_endup(count);
    504  1.11  christos }
    505   1.1       cgd 
    506   1.1       cgd /*
    507   1.1       cgd  *	function to show the things player can read only
    508   1.1       cgd  */
    509  1.24  dholland static void
    510   1.1       cgd showread()
    511  1.11  christos {
    512  1.11  christos 	int    i, j, sigsav, count;
    513  1.11  christos 	sigsav = nosignal;
    514  1.11  christos 	nosignal = 1;		/* don't allow ^c etc */
    515  1.11  christos 	srcount = 0;
    516  1.11  christos 
    517  1.11  christos 	for (count = 2, j = 0; j <= 26; j++)
    518  1.11  christos 		switch (iven[j]) {
    519  1.11  christos 		case OBOOK:
    520  1.11  christos 		case OSCROLL:
    521  1.11  christos 			count++;
    522  1.11  christos 		};
    523   1.1       cgd 	t_setup(count);
    524   1.1       cgd 
    525  1.11  christos 	for (i = 22; i < 84; i++)
    526  1.11  christos 		for (j = 0; j <= 26; j++)
    527  1.11  christos 			if (i == iven[j])
    528  1.11  christos 				switch (i) {
    529  1.11  christos 				case OBOOK:
    530  1.11  christos 				case OSCROLL:
    531  1.11  christos 					show3(j);
    532   1.1       cgd 				};
    533  1.11  christos 	more();
    534  1.11  christos 	nosignal = sigsav;
    535  1.11  christos 	t_endup(count);
    536  1.11  christos }
    537   1.1       cgd 
    538   1.1       cgd /*
    539   1.1       cgd  *	function to show the things player can eat only
    540   1.1       cgd  */
    541  1.24  dholland static void
    542   1.1       cgd showeat()
    543  1.11  christos {
    544  1.11  christos 	int    i, j, sigsav, count;
    545  1.11  christos 	sigsav = nosignal;
    546  1.11  christos 	nosignal = 1;		/* don't allow ^c etc */
    547  1.11  christos 	srcount = 0;
    548  1.11  christos 
    549  1.11  christos 	for (count = 2, j = 0; j <= 26; j++)
    550  1.11  christos 		switch (iven[j]) {
    551  1.11  christos 		case OCOOKIE:
    552  1.11  christos 			count++;
    553  1.11  christos 		};
    554   1.1       cgd 	t_setup(count);
    555   1.1       cgd 
    556  1.11  christos 	for (i = 22; i < 84; i++)
    557  1.11  christos 		for (j = 0; j <= 26; j++)
    558  1.11  christos 			if (i == iven[j])
    559  1.11  christos 				switch (i) {
    560  1.11  christos 				case OCOOKIE:
    561  1.11  christos 					show3(j);
    562   1.1       cgd 				};
    563  1.11  christos 	more();
    564  1.11  christos 	nosignal = sigsav;
    565  1.11  christos 	t_endup(count);
    566  1.11  christos }
    567   1.1       cgd 
    568   1.1       cgd /*
    569   1.1       cgd 	function to show the things player can quaff only
    570   1.1       cgd  */
    571  1.24  dholland static void
    572   1.1       cgd showquaff()
    573  1.11  christos {
    574  1.11  christos 	int    i, j, sigsav, count;
    575  1.11  christos 	sigsav = nosignal;
    576  1.11  christos 	nosignal = 1;		/* don't allow ^c etc */
    577  1.11  christos 	srcount = 0;
    578  1.11  christos 
    579  1.11  christos 	for (count = 2, j = 0; j <= 26; j++)
    580  1.11  christos 		switch (iven[j]) {
    581  1.11  christos 		case OPOTION:
    582  1.11  christos 			count++;
    583  1.11  christos 		};
    584   1.1       cgd 	t_setup(count);
    585   1.1       cgd 
    586  1.11  christos 	for (i = 22; i < 84; i++)
    587  1.11  christos 		for (j = 0; j <= 26; j++)
    588  1.11  christos 			if (i == iven[j])
    589  1.11  christos 				switch (i) {
    590  1.11  christos 				case OPOTION:
    591  1.11  christos 					show3(j);
    592   1.1       cgd 				};
    593  1.11  christos 	more();
    594  1.11  christos 	nosignal = sigsav;
    595  1.11  christos 	t_endup(count);
    596  1.11  christos }
    597   1.1       cgd 
    598  1.24  dholland static void
    599  1.11  christos show1(idx, str2)
    600  1.11  christos 	int    idx;
    601  1.20  dholland 	const char  *str2[];
    602  1.11  christos {
    603  1.11  christos 	lprintf("\n%c)   %s", idx + 'a', objectname[iven[idx]]);
    604  1.11  christos 	if (str2 != 0 && str2[ivenarg[idx]][0] != 0)
    605  1.11  christos 		lprintf(" of%s", str2[ivenarg[idx]]);
    606  1.11  christos }
    607   1.1       cgd 
    608  1.11  christos void
    609  1.20  dholland show3(int indx)
    610  1.11  christos {
    611  1.20  dholland 	switch (iven[indx]) {
    612  1.11  christos 	case OPOTION:
    613  1.20  dholland 		show1(indx, potionname);
    614  1.11  christos 		break;
    615  1.11  christos 	case OSCROLL:
    616  1.20  dholland 		show1(indx, scrollname);
    617  1.11  christos 		break;
    618  1.11  christos 
    619  1.11  christos 	case OLARNEYE:
    620  1.11  christos 	case OBOOK:
    621  1.11  christos 	case OSPIRITSCARAB:
    622  1.11  christos 	case ODIAMOND:
    623  1.11  christos 	case ORUBY:
    624  1.11  christos 	case OCUBEofUNDEAD:
    625  1.11  christos 	case OEMERALD:
    626  1.11  christos 	case OCHEST:
    627  1.11  christos 	case OCOOKIE:
    628  1.11  christos 	case OSAPPHIRE:
    629  1.11  christos 	case ONOTHEFT:
    630  1.20  dholland 		show1(indx, NULL);
    631  1.11  christos 		break;
    632  1.11  christos 
    633  1.11  christos 	default:
    634  1.20  dholland 		lprintf("\n%c)   %s", indx + 'a', objectname[iven[indx]]);
    635  1.20  dholland 		if (ivenarg[indx] > 0)
    636  1.20  dholland 			lprintf(" + %ld", (long) ivenarg[indx]);
    637  1.20  dholland 		else if (ivenarg[indx] < 0)
    638  1.20  dholland 			lprintf(" %ld", (long) ivenarg[indx]);
    639  1.11  christos 		break;
    640  1.11  christos 	}
    641  1.20  dholland 	if (c[WIELD] == indx)
    642  1.11  christos 		lprcat(" (weapon in hand)");
    643  1.20  dholland 	if ((c[WEAR] == indx) || (c[SHIELD] == indx))
    644  1.11  christos 		lprcat(" (being worn)");
    645  1.11  christos 	if (++srcount >= 22) {
    646  1.11  christos 		srcount = 0;
    647  1.11  christos 		more();
    648  1.11  christos 		clear();
    649   1.1       cgd 	}
    650  1.11  christos }
    651   1.1       cgd 
    652   1.1       cgd /*
    653   1.1       cgd 	subroutine to randomly create monsters if needed
    654   1.1       cgd  */
    655  1.24  dholland static void
    656   1.1       cgd randmonst()
    657  1.11  christos {
    658  1.11  christos 	if (c[TIMESTOP])
    659  1.11  christos 		return;		/* don't make monsters if time is stopped	 */
    660  1.11  christos 	if (--rmst <= 0) {
    661  1.11  christos 		rmst = 120 - (level << 2);
    662  1.11  christos 		fillmonst(makemonst(level));
    663   1.1       cgd 	}
    664  1.11  christos }
    665  1.11  christos 
    666  1.11  christos 
    667   1.1       cgd 
    668   1.1       cgd /*
    669   1.1       cgd 	parse()
    670   1.1       cgd 
    671   1.1       cgd 	get and execute a command
    672   1.1       cgd  */
    673  1.24  dholland static void
    674   1.1       cgd parse()
    675  1.11  christos {
    676  1.11  christos 	int    i, j, k, flag;
    677  1.11  christos 	while (1) {
    678   1.1       cgd 		k = yylex();
    679  1.11  christos 		switch (k) {	/* get the token from the input and switch on
    680  1.11  christos 				 * it	 */
    681  1.11  christos 		case 'h':
    682  1.11  christos 			moveplayer(4);
    683  1.11  christos 			return;	/* west		 */
    684  1.11  christos 		case 'H':
    685  1.11  christos 			run(4);
    686  1.11  christos 			return;	/* west		 */
    687  1.11  christos 		case 'l':
    688  1.11  christos 			moveplayer(2);
    689  1.11  christos 			return;	/* east		 */
    690  1.11  christos 		case 'L':
    691  1.11  christos 			run(2);
    692  1.11  christos 			return;	/* east		 */
    693  1.11  christos 		case 'j':
    694  1.11  christos 			moveplayer(1);
    695  1.11  christos 			return;	/* south		 */
    696  1.11  christos 		case 'J':
    697  1.11  christos 			run(1);
    698  1.11  christos 			return;	/* south		 */
    699  1.11  christos 		case 'k':
    700  1.11  christos 			moveplayer(3);
    701  1.11  christos 			return;	/* north		 */
    702  1.11  christos 		case 'K':
    703  1.11  christos 			run(3);
    704  1.11  christos 			return;	/* north		 */
    705  1.11  christos 		case 'u':
    706  1.11  christos 			moveplayer(5);
    707  1.11  christos 			return;	/* northeast	 */
    708  1.11  christos 		case 'U':
    709  1.11  christos 			run(5);
    710  1.11  christos 			return;	/* northeast	 */
    711  1.11  christos 		case 'y':
    712  1.11  christos 			moveplayer(6);
    713  1.11  christos 			return;	/* northwest	 */
    714  1.11  christos 		case 'Y':
    715  1.11  christos 			run(6);
    716  1.11  christos 			return;	/* northwest	 */
    717  1.11  christos 		case 'n':
    718  1.11  christos 			moveplayer(7);
    719  1.11  christos 			return;	/* southeast	 */
    720  1.11  christos 		case 'N':
    721  1.11  christos 			run(7);
    722  1.11  christos 			return;	/* southeast	 */
    723  1.11  christos 		case 'b':
    724  1.11  christos 			moveplayer(8);
    725  1.11  christos 			return;	/* southwest	 */
    726  1.11  christos 		case 'B':
    727  1.11  christos 			run(8);
    728  1.11  christos 			return;	/* southwest	 */
    729  1.11  christos 
    730  1.11  christos 		case '.':
    731  1.11  christos 			if (yrepcount)
    732  1.11  christos 				viewflag = 1;
    733  1.11  christos 			return;	/* stay here		 */
    734  1.11  christos 
    735  1.11  christos 		case 'w':
    736  1.11  christos 			yrepcount = 0;
    737  1.11  christos 			wield();
    738  1.11  christos 			return;	/* wield a weapon */
    739  1.11  christos 
    740  1.11  christos 		case 'W':
    741  1.11  christos 			yrepcount = 0;
    742  1.11  christos 			wear();
    743  1.11  christos 			return;	/* wear armor	 */
    744  1.11  christos 
    745  1.11  christos 		case 'r':
    746  1.11  christos 			yrepcount = 0;
    747  1.11  christos 			if (c[BLINDCOUNT]) {
    748  1.11  christos 				cursors();
    749  1.11  christos 				lprcat("\nYou can't read anything when you're blind!");
    750  1.11  christos 			} else if (c[TIMESTOP] == 0)
    751  1.11  christos 				readscr();
    752  1.11  christos 			return;	/* to read a scroll	 */
    753  1.11  christos 
    754  1.11  christos 		case 'q':
    755  1.11  christos 			yrepcount = 0;
    756  1.11  christos 			if (c[TIMESTOP] == 0)
    757  1.11  christos 				quaff();
    758  1.11  christos 			return;	/* quaff a potion		 */
    759  1.11  christos 
    760  1.11  christos 		case 'd':
    761  1.11  christos 			yrepcount = 0;
    762  1.11  christos 			if (c[TIMESTOP] == 0)
    763  1.11  christos 				dropobj();
    764  1.11  christos 			return;	/* to drop an object	 */
    765  1.11  christos 
    766  1.11  christos 		case 'c':
    767  1.11  christos 			yrepcount = 0;
    768  1.11  christos 			cast();
    769  1.11  christos 			return;	/* cast a spell	 */
    770  1.11  christos 
    771  1.11  christos 		case 'i':
    772  1.11  christos 			yrepcount = 0;
    773  1.11  christos 			nomove = 1;
    774  1.11  christos 			showstr();
    775  1.11  christos 			return;	/* status		 */
    776  1.11  christos 
    777  1.11  christos 		case 'e':
    778  1.11  christos 			yrepcount = 0;
    779  1.11  christos 			if (c[TIMESTOP] == 0)
    780  1.11  christos 				eatcookie();
    781  1.11  christos 			return;	/* to eat a fortune cookie */
    782  1.11  christos 
    783  1.11  christos 		case 'D':
    784  1.11  christos 			yrepcount = 0;
    785  1.11  christos 			seemagic(0);
    786  1.11  christos 			nomove = 1;
    787  1.11  christos 			return;	/* list spells and scrolls */
    788  1.11  christos 
    789  1.11  christos 		case '?':
    790  1.11  christos 			yrepcount = 0;
    791  1.11  christos 			help();
    792  1.11  christos 			nomove = 1;
    793  1.11  christos 			return;	/* give the help screen */
    794  1.11  christos 
    795  1.11  christos 		case 'S':
    796  1.11  christos 			clear();
    797  1.11  christos 			lprcat("Saving . . .");
    798  1.11  christos 			lflush();
    799  1.11  christos 			savegame(savefilename);
    800  1.11  christos 			wizard = 1;
    801  1.11  christos 			died(-257);	/* save the game - doesn't return	 */
    802  1.11  christos 
    803  1.11  christos 		case 'Z':
    804  1.11  christos 			yrepcount = 0;
    805  1.11  christos 			if (c[LEVEL] > 9) {
    806  1.11  christos 				oteleport(1);
    807  1.11  christos 				return;
    808  1.11  christos 			}
    809  1.11  christos 			cursors();
    810  1.11  christos 			lprcat("\nAs yet, you don't have enough experience to use teleportation");
    811  1.11  christos 			return;	/* teleport yourself	 */
    812  1.11  christos 
    813  1.11  christos 		case '^':	/* identify traps */
    814  1.11  christos 			flag = yrepcount = 0;
    815  1.11  christos 			cursors();
    816  1.11  christos 			lprc('\n');
    817  1.11  christos 			for (j = playery - 1; j < playery + 2; j++) {
    818  1.11  christos 				if (j < 0)
    819  1.11  christos 					j = 0;
    820  1.11  christos 				if (j >= MAXY)
    821  1.11  christos 					break;
    822  1.11  christos 				for (i = playerx - 1; i < playerx + 2; i++) {
    823  1.11  christos 					if (i < 0)
    824  1.11  christos 						i = 0;
    825  1.11  christos 					if (i >= MAXX)
    826  1.11  christos 						break;
    827  1.11  christos 					switch (item[i][j]) {
    828  1.11  christos 					case OTRAPDOOR:
    829  1.11  christos 					case ODARTRAP:
    830  1.11  christos 					case OTRAPARROW:
    831  1.11  christos 					case OTELEPORTER:
    832  1.18     mouse 						lprcat("\nIt's ");
    833  1.11  christos 						lprcat(objectname[item[i][j]]);
    834  1.11  christos 						flag++;
    835  1.11  christos 					};
    836  1.11  christos 				}
    837  1.11  christos 			}
    838  1.11  christos 			if (flag == 0)
    839  1.11  christos 				lprcat("\nNo traps are visible");
    840  1.11  christos 			return;
    841   1.1       cgd 
    842   1.1       cgd #if WIZID
    843  1.11  christos 		case '_':	/* this is the fudge player password for
    844  1.11  christos 				 * wizard mode */
    845  1.11  christos 			yrepcount = 0;
    846  1.11  christos 			cursors();
    847  1.11  christos 			nomove = 1;
    848  1.11  christos 			if (userid != wisid) {
    849  1.11  christos 				lprcat("Sorry, you are not empowered to be a wizard.\n");
    850  1.11  christos 				scbr();	/* system("stty -echo cbreak"); */
    851  1.11  christos 				lflush();
    852  1.11  christos 				return;
    853  1.11  christos 			}
    854  1.11  christos 			if (getpassword() == 0) {
    855  1.11  christos 				scbr();	/* system("stty -echo cbreak"); */
    856  1.11  christos 				return;
    857  1.11  christos 			}
    858  1.11  christos 			wizard = 1;
    859  1.11  christos 			scbr();	/* system("stty -echo cbreak"); */
    860  1.11  christos 			for (i = 0; i < 6; i++)
    861  1.11  christos 				c[i] = 70;
    862  1.11  christos 			iven[0] = iven[1] = 0;
    863  1.11  christos 			take(OPROTRING, 50);
    864  1.11  christos 			take(OLANCE, 25);
    865  1.11  christos 			c[WIELD] = 1;
    866  1.11  christos 			c[LANCEDEATH] = 1;
    867  1.11  christos 			c[WEAR] = c[SHIELD] = -1;
    868  1.11  christos 			raiseexperience(6000000L);
    869  1.11  christos 			c[AWARENESS] += 25000;
    870  1.11  christos 			{
    871  1.11  christos 				int    i, j;
    872  1.11  christos 				for (i = 0; i < MAXY; i++)
    873  1.11  christos 					for (j = 0; j < MAXX; j++)
    874  1.11  christos 						know[j][i] = 1;
    875  1.11  christos 				for (i = 0; i < SPNUM; i++)
    876  1.11  christos 					spelknow[i] = 1;
    877  1.11  christos 				for (i = 0; i < MAXSCROLL; i++)
    878  1.11  christos 					scrollname[i] = scrollhide[i];
    879  1.11  christos 				for (i = 0; i < MAXPOTION; i++)
    880  1.11  christos 					potionname[i] = potionhide[i];
    881  1.11  christos 			}
    882  1.11  christos 			for (i = 0; i < MAXSCROLL; i++)
    883  1.11  christos 				if (strlen(scrollname[i]) > 2) {	/* no null items */
    884  1.11  christos 					item[i][0] = OSCROLL;
    885  1.11  christos 					iarg[i][0] = i;
    886  1.11  christos 				}
    887  1.11  christos 			for (i = MAXX - 1; i > MAXX - 1 - MAXPOTION; i--)
    888  1.11  christos 				if (strlen(potionname[i - MAXX + MAXPOTION]) > 2) {	/* no null items */
    889  1.11  christos 					item[i][0] = OPOTION;
    890  1.11  christos 					iarg[i][0] = i - MAXX + MAXPOTION;
    891  1.11  christos 				}
    892  1.11  christos 			for (i = 1; i < MAXY; i++) {
    893  1.11  christos 				item[0][i] = i;
    894  1.11  christos 				iarg[0][i] = 0;
    895  1.11  christos 			}
    896  1.11  christos 			for (i = MAXY; i < MAXY + MAXX; i++) {
    897  1.11  christos 				item[i - MAXY][MAXY - 1] = i;
    898  1.11  christos 				iarg[i - MAXY][MAXY - 1] = 0;
    899  1.11  christos 			}
    900  1.11  christos 			for (i = MAXX + MAXY; i < MAXX + MAXY + MAXY; i++) {
    901  1.11  christos 				item[MAXX - 1][i - MAXX - MAXY] = i;
    902  1.11  christos 				iarg[MAXX - 1][i - MAXX - MAXY] = 0;
    903  1.11  christos 			}
    904  1.11  christos 			c[GOLD] += 25000;
    905  1.11  christos 			drawscreen();
    906  1.11  christos 			return;
    907   1.1       cgd #endif
    908   1.1       cgd 
    909  1.11  christos 		case 'T':
    910  1.11  christos 			yrepcount = 0;
    911  1.11  christos 			cursors();
    912  1.11  christos 			if (c[SHIELD] != -1) {
    913  1.11  christos 				c[SHIELD] = -1;
    914  1.11  christos 				lprcat("\nYour shield is off");
    915  1.11  christos 				bottomline();
    916  1.11  christos 			} else if (c[WEAR] != -1) {
    917  1.11  christos 				c[WEAR] = -1;
    918  1.11  christos 				lprcat("\nYour armor is off");
    919  1.11  christos 				bottomline();
    920  1.11  christos 			} else
    921  1.11  christos 				lprcat("\nYou aren't wearing anything");
    922  1.11  christos 			return;
    923   1.1       cgd 
    924  1.11  christos 		case 'g':
    925  1.11  christos 			cursors();
    926  1.19  dholland 			lprintf("\nThe stuff you are carrying presently weighs %ld pounds", (long) packweight());
    927  1.11  christos 		case ' ':
    928  1.11  christos 			yrepcount = 0;
    929  1.11  christos 			nomove = 1;
    930  1.11  christos 			return;
    931   1.1       cgd 
    932  1.11  christos 		case 'v':
    933  1.11  christos 			yrepcount = 0;
    934  1.11  christos 			cursors();
    935  1.19  dholland 			lprintf("\nCaverns of Larn, Version %ld.%ld, Diff=%ld",
    936  1.19  dholland 				(long) VERSION, (long) SUBVERSION,
    937  1.19  dholland 				(long) c[HARDGAME]);
    938  1.11  christos 			if (wizard)
    939  1.11  christos 				lprcat(" Wizard");
    940  1.11  christos 			nomove = 1;
    941  1.11  christos 			if (cheat)
    942  1.11  christos 				lprcat(" Cheater");
    943  1.11  christos 			lprcat(copyright);
    944  1.11  christos 			return;
    945   1.1       cgd 
    946  1.11  christos 		case 'Q':
    947  1.11  christos 			yrepcount = 0;
    948  1.11  christos 			quit();
    949  1.11  christos 			nomove = 1;
    950  1.11  christos 			return;	/* quit		 */
    951  1.11  christos 
    952  1.11  christos 		case 'L' - 64:
    953  1.11  christos 			yrepcount = 0;
    954  1.11  christos 			drawscreen();
    955  1.11  christos 			nomove = 1;
    956  1.11  christos 			return;	/* look		 */
    957   1.1       cgd 
    958   1.1       cgd #if WIZID
    959   1.1       cgd #ifdef EXTRA
    960  1.11  christos 		case 'A':
    961  1.11  christos 			yrepcount = 0;
    962  1.11  christos 			nomove = 1;
    963  1.11  christos 			if (wizard) {
    964  1.11  christos 				diag();
    965  1.11  christos 				return;
    966  1.11  christos 			}	/* create diagnostic file */
    967  1.11  christos 			return;
    968   1.1       cgd #endif
    969   1.1       cgd #endif
    970  1.11  christos 		case 'P':
    971  1.11  christos 			cursors();
    972  1.11  christos 			if (outstanding_taxes > 0)
    973  1.19  dholland 				lprintf("\nYou presently owe %ld gp in taxes.",
    974  1.19  dholland 					(long) outstanding_taxes);
    975  1.11  christos 			else
    976  1.11  christos 				lprcat("\nYou do not owe any taxes.");
    977  1.11  christos 			return;
    978  1.11  christos 		};
    979   1.1       cgd 	}
    980  1.11  christos }
    981   1.1       cgd 
    982  1.11  christos void
    983   1.1       cgd parse2()
    984  1.11  christos {
    985  1.11  christos 	if (c[HASTEMONST])
    986  1.11  christos 		movemonst();
    987  1.11  christos 	movemonst();		/* move the monsters		 */
    988  1.11  christos 	randmonst();
    989  1.11  christos 	regen();
    990  1.11  christos }
    991   1.1       cgd 
    992  1.24  dholland static void
    993   1.1       cgd run(dir)
    994  1.11  christos 	int             dir;
    995  1.11  christos {
    996  1.11  christos 	int    i;
    997  1.11  christos 	i = 1;
    998  1.11  christos 	while (i) {
    999  1.11  christos 		i = moveplayer(dir);
   1000  1.11  christos 		if (i > 0) {
   1001  1.11  christos 			if (c[HASTEMONST])
   1002  1.11  christos 				movemonst();
   1003  1.11  christos 			movemonst();
   1004  1.11  christos 			randmonst();
   1005  1.11  christos 			regen();
   1006   1.1       cgd 		}
   1007  1.11  christos 		if (hitflag)
   1008  1.11  christos 			i = 0;
   1009  1.11  christos 		if (i != 0)
   1010  1.11  christos 			showcell(playerx, playery);
   1011   1.1       cgd 	}
   1012  1.11  christos }
   1013   1.1       cgd 
   1014   1.1       cgd /*
   1015   1.1       cgd 	function to wield a weapon
   1016   1.1       cgd  */
   1017  1.24  dholland static void
   1018  1.11  christos wield()
   1019  1.11  christos {
   1020  1.11  christos 	int    i;
   1021  1.11  christos 	while (1) {
   1022  1.11  christos 		if ((i = whatitem("wield")) == '\33')
   1023  1.11  christos 			return;
   1024  1.11  christos 		if (i != '.') {
   1025  1.11  christos 			if (i == '*')
   1026  1.11  christos 				showwield();
   1027  1.11  christos 			else if (iven[i - 'a'] == 0) {
   1028  1.11  christos 				ydhi(i);
   1029  1.11  christos 				return;
   1030  1.11  christos 			} else if (iven[i - 'a'] == OPOTION) {
   1031  1.11  christos 				ycwi(i);
   1032  1.11  christos 				return;
   1033  1.11  christos 			} else if (iven[i - 'a'] == OSCROLL) {
   1034  1.11  christos 				ycwi(i);
   1035  1.11  christos 				return;
   1036  1.11  christos 			} else if ((c[SHIELD] != -1) && (iven[i - 'a'] == O2SWORD)) {
   1037  1.11  christos 				lprcat("\nBut one arm is busy with your shield!");
   1038  1.11  christos 				return;
   1039  1.11  christos 			} else {
   1040  1.11  christos 				c[WIELD] = i - 'a';
   1041  1.11  christos 				if (iven[i - 'a'] == OLANCE)
   1042  1.11  christos 					c[LANCEDEATH] = 1;
   1043  1.11  christos 				else
   1044  1.11  christos 					c[LANCEDEATH] = 0;
   1045  1.11  christos 				bottomline();
   1046  1.11  christos 				return;
   1047   1.1       cgd 			}
   1048   1.1       cgd 		}
   1049   1.1       cgd 	}
   1050  1.11  christos }
   1051   1.1       cgd 
   1052   1.1       cgd /*
   1053   1.1       cgd 	common routine to say you don't have an item
   1054   1.1       cgd  */
   1055  1.24  dholland static void
   1056   1.1       cgd ydhi(x)
   1057  1.11  christos 	int             x;
   1058  1.11  christos {
   1059  1.11  christos 	cursors();
   1060  1.11  christos 	lprintf("\nYou don't have item %c!", x);
   1061  1.11  christos }
   1062  1.24  dholland static void
   1063   1.1       cgd ycwi(x)
   1064  1.11  christos 	int             x;
   1065  1.11  christos {
   1066  1.11  christos 	cursors();
   1067  1.11  christos 	lprintf("\nYou can't wield item %c!", x);
   1068  1.11  christos }
   1069   1.1       cgd 
   1070   1.1       cgd /*
   1071   1.1       cgd 	function to wear armor
   1072   1.1       cgd  */
   1073  1.24  dholland static void
   1074   1.1       cgd wear()
   1075  1.11  christos {
   1076  1.11  christos 	int    i;
   1077  1.11  christos 	while (1) {
   1078  1.11  christos 		if ((i = whatitem("wear")) == '\33')
   1079  1.11  christos 			return;
   1080  1.11  christos 		if (i != '.') {
   1081  1.11  christos 			if (i == '*')
   1082  1.11  christos 				showwear();
   1083  1.11  christos 			else
   1084  1.11  christos 				switch (iven[i - 'a']) {
   1085  1.11  christos 				case 0:
   1086  1.11  christos 					ydhi(i);
   1087  1.11  christos 					return;
   1088  1.11  christos 				case OLEATHER:
   1089  1.11  christos 				case OCHAIN:
   1090  1.11  christos 				case OPLATE:
   1091  1.11  christos 				case OSTUDLEATHER:
   1092  1.11  christos 				case ORING:
   1093  1.11  christos 				case OSPLINT:
   1094  1.11  christos 				case OPLATEARMOR:
   1095  1.11  christos 				case OSSPLATE:
   1096  1.11  christos 					if (c[WEAR] != -1) {
   1097  1.11  christos 						lprcat("\nYou're already wearing some armor");
   1098  1.11  christos 						return;
   1099  1.11  christos 					}
   1100  1.11  christos 					c[WEAR] = i - 'a';
   1101  1.11  christos 					bottomline();
   1102  1.11  christos 					return;
   1103  1.11  christos 				case OSHIELD:
   1104  1.11  christos 					if (c[SHIELD] != -1) {
   1105  1.11  christos 						lprcat("\nYou are already wearing a shield");
   1106  1.11  christos 						return;
   1107  1.11  christos 					}
   1108  1.11  christos 					if (iven[c[WIELD]] == O2SWORD) {
   1109  1.11  christos 						lprcat("\nYour hands are busy with the two handed sword!");
   1110  1.11  christos 						return;
   1111  1.11  christos 					}
   1112  1.11  christos 					c[SHIELD] = i - 'a';
   1113  1.11  christos 					bottomline();
   1114  1.11  christos 					return;
   1115  1.11  christos 				default:
   1116  1.11  christos 					lprcat("\nYou can't wear that!");
   1117   1.1       cgd 				};
   1118   1.1       cgd 		}
   1119   1.1       cgd 	}
   1120  1.11  christos }
   1121   1.1       cgd 
   1122   1.1       cgd /*
   1123   1.1       cgd 	function to drop an object
   1124   1.1       cgd  */
   1125  1.24  dholland static void
   1126   1.1       cgd dropobj()
   1127  1.11  christos {
   1128  1.11  christos 	int    i;
   1129  1.20  dholland 	unsigned char  *p;
   1130  1.11  christos 	long            amt;
   1131   1.1       cgd 	p = &item[playerx][playery];
   1132  1.11  christos 	while (1) {
   1133  1.11  christos 		if ((i = whatitem("drop")) == '\33')
   1134  1.11  christos 			return;
   1135  1.11  christos 		if (i == '*')
   1136  1.11  christos 			showstr();
   1137  1.11  christos 		else {
   1138  1.11  christos 			if (i == '.') {	/* drop some gold */
   1139  1.11  christos 				if (*p) {
   1140  1.11  christos 					lprcat("\nThere's something here already!");
   1141  1.11  christos 					return;
   1142  1.11  christos 				}
   1143   1.1       cgd 				lprcat("\n\n");
   1144  1.11  christos 				cl_dn(1, 23);
   1145   1.1       cgd 				lprcat("How much gold do you drop? ");
   1146  1.11  christos 				if ((amt = readnum((long) c[GOLD])) == 0)
   1147  1.11  christos 					return;
   1148  1.11  christos 				if (amt > c[GOLD]) {
   1149  1.11  christos 					lprcat("\nYou don't have that much!");
   1150  1.11  christos 					return;
   1151  1.11  christos 				}
   1152  1.11  christos 				if (amt <= 32767) {
   1153  1.11  christos 					*p = OGOLDPILE;
   1154  1.11  christos 					i = amt;
   1155  1.11  christos 				} else if (amt <= 327670L) {
   1156  1.11  christos 					*p = ODGOLD;
   1157  1.11  christos 					i = amt / 10;
   1158  1.11  christos 					amt = 10 * i;
   1159  1.11  christos 				} else if (amt <= 3276700L) {
   1160  1.11  christos 					*p = OMAXGOLD;
   1161  1.11  christos 					i = amt / 100;
   1162  1.11  christos 					amt = 100 * i;
   1163  1.11  christos 				} else if (amt <= 32767000L) {
   1164  1.11  christos 					*p = OKGOLD;
   1165  1.11  christos 					i = amt / 1000;
   1166  1.11  christos 					amt = 1000 * i;
   1167  1.11  christos 				} else {
   1168  1.11  christos 					*p = OKGOLD;
   1169  1.11  christos 					i = 32767;
   1170  1.11  christos 					amt = 32767000L;
   1171   1.1       cgd 				}
   1172  1.11  christos 				c[GOLD] -= amt;
   1173  1.19  dholland 				lprintf("You drop %ld gold pieces", (long)amt);
   1174  1.11  christos 				iarg[playerx][playery] = i;
   1175  1.11  christos 				bottomgold();
   1176  1.11  christos 				know[playerx][playery] = 0;
   1177  1.11  christos 				dropflag = 1;
   1178  1.11  christos 				return;
   1179  1.11  christos 			}
   1180  1.11  christos 			drop_object(i - 'a');
   1181   1.1       cgd 			return;
   1182   1.1       cgd 		}
   1183   1.1       cgd 	}
   1184  1.11  christos }
   1185   1.1       cgd 
   1186   1.1       cgd /*
   1187   1.1       cgd  *	readscr()		Subroutine to read a scroll one is carrying
   1188   1.1       cgd  */
   1189  1.24  dholland static void
   1190   1.1       cgd readscr()
   1191  1.11  christos {
   1192  1.11  christos 	int    i;
   1193  1.11  christos 	while (1) {
   1194  1.11  christos 		if ((i = whatitem("read")) == '\33')
   1195  1.11  christos 			return;
   1196  1.11  christos 		if (i != '.') {
   1197  1.11  christos 			if (i == '*')
   1198  1.11  christos 				showread();
   1199  1.11  christos 			else {
   1200  1.11  christos 				if (iven[i - 'a'] == OSCROLL) {
   1201  1.11  christos 					read_scroll(ivenarg[i - 'a']);
   1202  1.11  christos 					iven[i - 'a'] = 0;
   1203  1.11  christos 					return;
   1204  1.11  christos 				}
   1205  1.11  christos 				if (iven[i - 'a'] == OBOOK) {
   1206  1.11  christos 					readbook(ivenarg[i - 'a']);
   1207  1.11  christos 					iven[i - 'a'] = 0;
   1208  1.11  christos 					return;
   1209  1.11  christos 				}
   1210  1.11  christos 				if (iven[i - 'a'] == 0) {
   1211  1.11  christos 					ydhi(i);
   1212  1.11  christos 					return;
   1213   1.1       cgd 				}
   1214  1.11  christos 				lprcat("\nThere's nothing on it to read");
   1215  1.11  christos 				return;
   1216   1.1       cgd 			}
   1217   1.1       cgd 		}
   1218   1.1       cgd 	}
   1219  1.11  christos }
   1220   1.1       cgd 
   1221   1.1       cgd /*
   1222   1.1       cgd  *	subroutine to eat a cookie one is carrying
   1223   1.1       cgd  */
   1224  1.24  dholland static void
   1225  1.20  dholland eatcookie(void)
   1226   1.1       cgd {
   1227  1.20  dholland 	const char *p;
   1228  1.20  dholland 	int i;
   1229  1.20  dholland 
   1230  1.11  christos 	while (1) {
   1231  1.11  christos 		if ((i = whatitem("eat")) == '\33')
   1232  1.11  christos 			return;
   1233  1.14     veego 		if (i != '.') {
   1234  1.11  christos 			if (i == '*')
   1235  1.11  christos 				showeat();
   1236  1.11  christos 			else {
   1237  1.11  christos 				if (iven[i - 'a'] == OCOOKIE) {
   1238  1.11  christos 					lprcat("\nThe cookie was delicious.");
   1239  1.11  christos 					iven[i - 'a'] = 0;
   1240  1.11  christos 					if (!c[BLINDCOUNT]) {
   1241  1.11  christos 						if ((p = fortune()) != NULL) {
   1242  1.11  christos 							lprcat("  Inside you find a scrap of paper that says:\n");
   1243  1.11  christos 							lprcat(p);
   1244   1.1       cgd 						}
   1245   1.1       cgd 					}
   1246  1.11  christos 					return;
   1247  1.11  christos 				}
   1248  1.11  christos 				if (iven[i - 'a'] == 0) {
   1249  1.11  christos 					ydhi(i);
   1250  1.11  christos 					return;
   1251  1.11  christos 				}
   1252  1.11  christos 				lprcat("\nYou can't eat that!");
   1253   1.1       cgd 				return;
   1254   1.1       cgd 			}
   1255  1.14     veego 		}
   1256   1.1       cgd 	}
   1257   1.1       cgd }
   1258   1.1       cgd 
   1259   1.1       cgd /*
   1260   1.1       cgd  *	subroutine to quaff a potion one is carrying
   1261   1.1       cgd  */
   1262  1.24  dholland static void
   1263   1.1       cgd quaff()
   1264  1.11  christos {
   1265  1.11  christos 	int    i;
   1266  1.11  christos 	while (1) {
   1267  1.11  christos 		if ((i = whatitem("quaff")) == '\33')
   1268  1.11  christos 			return;
   1269  1.11  christos 		if (i != '.') {
   1270  1.11  christos 			if (i == '*')
   1271  1.11  christos 				showquaff();
   1272  1.11  christos 			else {
   1273  1.11  christos 				if (iven[i - 'a'] == OPOTION) {
   1274  1.11  christos 					quaffpotion(ivenarg[i - 'a']);
   1275  1.11  christos 					iven[i - 'a'] = 0;
   1276  1.11  christos 					return;
   1277  1.11  christos 				}
   1278  1.11  christos 				if (iven[i - 'a'] == 0) {
   1279  1.11  christos 					ydhi(i);
   1280  1.11  christos 					return;
   1281   1.1       cgd 				}
   1282  1.11  christos 				lprcat("\nYou wouldn't want to quaff that, would you? ");
   1283  1.11  christos 				return;
   1284   1.1       cgd 			}
   1285   1.1       cgd 		}
   1286   1.1       cgd 	}
   1287  1.11  christos }
   1288   1.1       cgd 
   1289   1.1       cgd /*
   1290   1.1       cgd 	function to ask what player wants to do
   1291   1.1       cgd  */
   1292  1.22  dholland static int
   1293  1.20  dholland whatitem(const char *str)
   1294  1.11  christos {
   1295  1.11  christos 	int             i;
   1296  1.11  christos 	cursors();
   1297  1.11  christos 	lprintf("\nWhat do you want to %s [* for all] ? ", str);
   1298  1.11  christos 	i = 0;
   1299  1.11  christos 	while (i > 'z' || (i < 'a' && i != '*' && i != '\33' && i != '.'))
   1300  1.23  dholland 		i = ttgetch();
   1301  1.11  christos 	if (i == '\33')
   1302  1.11  christos 		lprcat(" aborted");
   1303  1.11  christos 	return (i);
   1304  1.11  christos }
   1305   1.1       cgd 
   1306   1.1       cgd /*
   1307   1.1       cgd 	subroutine to get a number from the player
   1308   1.1       cgd 	and allow * to mean return amt, else return the number entered
   1309   1.1       cgd  */
   1310  1.11  christos unsigned long
   1311  1.11  christos readnum(mx)
   1312  1.11  christos 	long            mx;
   1313  1.11  christos {
   1314  1.11  christos 	int    i;
   1315  1.11  christos 	unsigned long amt = 0;
   1316   1.1       cgd 	sncbr();
   1317  1.23  dholland 	if ((i = ttgetch()) == '*')
   1318  1.11  christos 		amt = mx;	/* allow him to say * for all gold */
   1319   1.1       cgd 	else
   1320  1.11  christos 		while (i != '\n') {
   1321  1.11  christos 			if (i == '\033') {
   1322  1.11  christos 				scbr();
   1323  1.11  christos 				lprcat(" aborted");
   1324  1.11  christos 				return (0);
   1325  1.11  christos 			}
   1326  1.11  christos 			if ((i <= '9') && (i >= '0') && (amt < 99999999))
   1327  1.11  christos 				amt = amt * 10 + i - '0';
   1328  1.23  dholland 			i = ttgetch();
   1329  1.11  christos 		}
   1330  1.11  christos 	scbr();
   1331  1.11  christos 	return (amt);
   1332  1.11  christos }
   1333   1.1       cgd 
   1334   1.1       cgd #ifdef HIDEBYLINK
   1335   1.1       cgd /*
   1336   1.1       cgd  *	routine to zero every byte in a string
   1337   1.1       cgd  */
   1338  1.11  christos void
   1339   1.1       cgd szero(str)
   1340  1.11  christos 	char  *str;
   1341  1.11  christos {
   1342   1.1       cgd 	while (*str)
   1343   1.1       cgd 		*str++ = 0;
   1344  1.11  christos }
   1345  1.11  christos #endif	/* HIDEBYLINK */
   1346