Home | History | Annotate | Line # | Download | only in larn
main.c revision 1.9
      1  1.3  mycroft #ifndef lint
      2  1.9      mrg static char rcsid[] = "$NetBSD: main.c,v 1.9 1996/05/22 00:36:09 mrg Exp $";
      3  1.3  mycroft #endif /* not lint */
      4  1.3  mycroft 
      5  1.1      cgd /*	main.c		*/
      6  1.1      cgd #include <sys/types.h>
      7  1.1      cgd #include "header.h"
      8  1.1      cgd #include <pwd.h>
      9  1.7      cgd #include <string.h>
     10  1.7      cgd 
     11  1.1      cgd static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";
     12  1.1      cgd int srcount=0;	/* line counter for showstr()	*/
     13  1.1      cgd int dropflag=0; /* if 1 then don't lookforobject() next round */
     14  1.1      cgd int rmst=80;	/*	random monster creation counter		*/
     15  1.1      cgd int userid;		/* the players login user id number */
     16  1.9      mrg uid_t uid, euid;	/* used for security */
     17  1.1      cgd char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */
     18  1.1      cgd static char viewflag=0;
     19  1.1      cgd 	/*	if viewflag then we have done a 99 stay here and don't showcell in the main loop */
     20  1.1      cgd char restorflag=0;	/* 1 means restore has been done	*/
     21  1.1      cgd static char cmdhelp[] = "\
     22  1.1      cgd Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\
     23  1.1      cgd   -s   show the scoreboard\n\
     24  1.1      cgd   -l   show the logfile (wizard id only)\n\
     25  1.1      cgd   -i   show scoreboard with inventories of dead characters\n\
     26  1.1      cgd   -c   create new scoreboard (wizard id only)\n\
     27  1.1      cgd   -n   suppress welcome message on starting game\n\
     28  1.1      cgd   -##  specify level of difficulty (example: -5)\n\
     29  1.1      cgd   -h   print this help text\n\
     30  1.1      cgd   ++   restore game from checkpoint file\n\
     31  1.1      cgd   -o<optsfile>   specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
     32  1.1      cgd ";
     33  1.1      cgd #ifdef VT100
     34  1.1      cgd static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
     35  1.1      cgd 	"vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
     36  1.1      cgd 	"vt341"  };
     37  1.1      cgd #endif VT100
     38  1.1      cgd /*
     39  1.1      cgd 	************
     40  1.1      cgd 	MAIN PROGRAM
     41  1.1      cgd 	************
     42  1.1      cgd  */
     43  1.1      cgd main(argc,argv)
     44  1.1      cgd 	int argc;
     45  1.1      cgd 	char **argv;
     46  1.1      cgd 	{
     47  1.1      cgd 	register int i,j;
     48  1.1      cgd 	int hard;
     49  1.1      cgd 	char *ptr=0,*ttype;
     50  1.1      cgd 	struct passwd *pwe;
     51  1.1      cgd 
     52  1.9      mrg 	euid = geteuid();
     53  1.9      mrg 	uid = getuid();
     54  1.9      mrg 	seteuid(uid);	/* give up "games" if we have it */
     55  1.1      cgd /*
     56  1.1      cgd  *	first task is to identify the player
     57  1.1      cgd  */
     58  1.1      cgd #ifndef VT100
     59  1.1      cgd 	init_term();	/* setup the terminal (find out what type) for termcap */
     60  1.1      cgd #endif VT100
     61  1.1      cgd 	if (((ptr = getlogin()) == 0) || (*ptr==0))	/* try to get login name */
     62  1.1      cgd 	  if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
     63  1.1      cgd 		ptr = pwe->pw_name;
     64  1.1      cgd 	  else
     65  1.1      cgd 	  if ((ptr = getenv("USER")) == 0)
     66  1.1      cgd 		if ((ptr = getenv("LOGNAME")) == 0)
     67  1.1      cgd 		  {
     68  1.1      cgd 		  noone: write(2, "Can't find your logname.  Who Are You?\n",39);
     69  1.1      cgd 		 		 exit();
     70  1.1      cgd 		  }
     71  1.1      cgd 	if (ptr==0) goto noone;
     72  1.1      cgd 	if (strlen(ptr)==0) goto noone;
     73  1.1      cgd /*
     74  1.1      cgd  *	second task is to prepare the pathnames the player will need
     75  1.1      cgd  */
     76  1.1      cgd 	strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
     77  1.1      cgd 	strcpy(logname,ptr);	/* this will be overwritten with the players name */
     78  1.1      cgd 	if ((ptr = getenv("HOME")) == 0) ptr = ".";
     79  1.1      cgd 	strcpy(savefilename, ptr);
     80  1.1      cgd 	strcat(savefilename, "/Larn.sav");	/* save file name in home directory */
     81  1.1      cgd 	sprintf(optsfile, "%s/.larnopts",ptr);	/* the .larnopts filename */
     82  1.1      cgd 
     83  1.1      cgd /*
     84  1.1      cgd  *	now malloc the memory for the dungeon
     85  1.1      cgd  */
     86  1.1      cgd 	cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
     87  1.1      cgd 	if (cell == 0) died(-285);	/* malloc failure */
     88  1.1      cgd 	lpbuf    = malloc((5* BUFBIG)>>2);	/* output buffer */
     89  1.1      cgd 	inbuffer = malloc((5*MAXIBUF)>>2);	/* output buffer */
     90  1.1      cgd 	if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */
     91  1.1      cgd 
     92  1.1      cgd 	lcreat((char*)0);	newgame();		/*	set the initial clock  */ hard= -1;
     93  1.1      cgd 
     94  1.1      cgd #ifdef VT100
     95  1.1      cgd /*
     96  1.1      cgd  *	check terminal type to avoid users who have not vt100 type terminals
     97  1.1      cgd  */
     98  1.1      cgd 	ttype = getenv("TERM");
     99  1.1      cgd 	for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
    100  1.1      cgd 		if (strcmp(ttype,termtypes[i]) == 0) { j=0;  break; }
    101  1.1      cgd 	if (j)
    102  1.1      cgd 		{
    103  1.1      cgd 		lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
    104  1.1      cgd 		exit();
    105  1.1      cgd 		}
    106  1.1      cgd #endif VT100
    107  1.1      cgd 
    108  1.1      cgd /*
    109  1.1      cgd  *	now make scoreboard if it is not there (don't clear)
    110  1.1      cgd  */
    111  1.1      cgd 	if (access(scorefile,0) == -1) /* not there */
    112  1.1      cgd 		makeboard();
    113  1.1      cgd 
    114  1.1      cgd /*
    115  1.1      cgd  *	now process the command line arguments
    116  1.1      cgd  */
    117  1.1      cgd 	for (i=1; i<argc; i++)
    118  1.1      cgd 		{
    119  1.1      cgd 		if (argv[i][0] == '-')
    120  1.1      cgd 		  switch(argv[i][1])
    121  1.1      cgd 			{
    122  1.1      cgd 			case 's': showscores();  exit();  /* show scoreboard   */
    123  1.1      cgd 
    124  1.1      cgd 			case 'l': /* show log file     */
    125  1.1      cgd 						diedlog();		exit();
    126  1.1      cgd 
    127  1.1      cgd 			case 'i': showallscores();  exit();  /* show all scoreboard */
    128  1.1      cgd 
    129  1.1      cgd 			case 'c': 		 /* anyone with password can create scoreboard */
    130  1.1      cgd 					  lprcat("Preparing to initialize the scoreboard.\n");
    131  1.1      cgd 					  if (getpassword() != 0)  /*make new scoreboard*/
    132  1.1      cgd 							{
    133  1.1      cgd 							makeboard(); lprc('\n'); showscores();
    134  1.1      cgd 							}
    135  1.1      cgd 					  exit();
    136  1.1      cgd 
    137  1.1      cgd 			case 'n':	/* no welcome msg	*/ nowelcome=1; argv[i][0]=0; break;
    138  1.1      cgd 
    139  1.1      cgd 			case '0': case '1': case '2': case '3': case '4': case '5':
    140  1.1      cgd 			case '6': case '7': case '8': case '9':	/* for hardness */
    141  1.1      cgd 						sscanf(&argv[i][1],"%d",&hard);
    142  1.1      cgd 						break;
    143  1.1      cgd 
    144  1.1      cgd 			case 'h':	/* print out command line arguments */
    145  1.1      cgd 						write(1,cmdhelp,sizeof(cmdhelp));  exit();
    146  1.1      cgd 
    147  1.1      cgd 			case 'o':	/* specify a .larnopts filename */
    148  1.1      cgd 						strncpy(optsfile,argv[i]+2,127);  break;
    149  1.1      cgd 
    150  1.1      cgd 			default:	printf("Unknown option <%s>\n",argv[i]);  exit();
    151  1.1      cgd 			};
    152  1.1      cgd 
    153  1.1      cgd 		if (argv[i][0] == '+')
    154  1.1      cgd 			{
    155  1.1      cgd 			clear();	restorflag = 1;
    156  1.1      cgd 			if (argv[i][1] == '+')
    157  1.1      cgd 				{
    158  1.1      cgd 				hitflag=1; restoregame(ckpfile); /* restore checkpointed game */
    159  1.1      cgd 				}
    160  1.1      cgd 			i = argc;
    161  1.1      cgd 			}
    162  1.1      cgd 		}
    163  1.1      cgd 
    164  1.1      cgd 	readopts();		/* read the options file if there is one */
    165  1.1      cgd 
    166  1.1      cgd 
    167  1.1      cgd #ifdef UIDSCORE
    168  1.1      cgd 	userid = geteuid();	/* obtain the user's effective id number */
    169  1.1      cgd #else UIDSCORE
    170  1.1      cgd 	userid = getplid(logname);	/* obtain the players id number */
    171  1.1      cgd #endif UIDSCORE
    172  1.1      cgd 	if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); }
    173  1.1      cgd 
    174  1.1      cgd #ifdef HIDEBYLINK
    175  1.1      cgd /*
    176  1.1      cgd  *	this section of code causes the program to look like something else to ps
    177  1.1      cgd  */
    178  1.1      cgd 	if (strcmp(psname,argv[0])) /* if a different process name only */
    179  1.1      cgd 		{
    180  1.1      cgd 		if ((i=access(psname,1)) < 0)
    181  1.1      cgd 			{		/* link not there */
    182  1.1      cgd 			if (link(argv[0],psname)>=0)
    183  1.1      cgd 				{
    184  1.1      cgd 				argv[0] = psname;   execv(psname,argv);
    185  1.1      cgd 				}
    186  1.1      cgd 			}
    187  1.1      cgd 		else
    188  1.1      cgd 			unlink(psname);
    189  1.1      cgd 		}
    190  1.1      cgd 
    191  1.1      cgd 	for (i=1; i<argc; i++)
    192  1.1      cgd 		{
    193  1.1      cgd 		szero(argv[i]);	/* zero the argument to avoid ps snooping */
    194  1.1      cgd 		}
    195  1.1      cgd #endif HIDEBYLINK
    196  1.1      cgd 
    197  1.1      cgd 	if (access(savefilename,0)==0)	/* restore game if need to */
    198  1.1      cgd 		{
    199  1.1      cgd 		clear();	restorflag = 1;
    200  1.1      cgd 		hitflag=1;	restoregame(savefilename);  /* restore last game	*/
    201  1.1      cgd 		}
    202  1.1      cgd 	sigsetup();		/* trap all needed signals	*/
    203  1.1      cgd 	sethard(hard);	/* set up the desired difficulty				*/
    204  1.1      cgd 	setupvt100();	/*	setup the terminal special mode				*/
    205  1.1      cgd 	if (c[HP]==0)	/* create new game */
    206  1.1      cgd 		{
    207  1.1      cgd 		makeplayer();	/*	make the character that will play			*/
    208  1.1      cgd 		newcavelevel(0);/*	make the dungeon						 	*/
    209  1.1      cgd 		predostuff = 1;	/* tell signals that we are in the welcome screen */
    210  1.1      cgd 		if (nowelcome==0) welcome();	 /* welcome the player to the game */
    211  1.1      cgd 		}
    212  1.1      cgd 	drawscreen();	/*	show the initial dungeon					*/
    213  1.1      cgd 	predostuff = 2;	/* tell the trap functions that they must do a showplayer()
    214  1.1      cgd 						from here on */
    215  1.1      cgd 	/* nice(1);	/* games should be run niced */
    216  1.1      cgd 	yrepcount = hit2flag = 0;
    217  1.1      cgd 	while (1)
    218  1.1      cgd 		{
    219  1.1      cgd 		if (dropflag==0) lookforobject(); /* see if there is an object here	*/
    220  1.1      cgd 			else dropflag=0; /* don't show it just dropped an item */
    221  1.1      cgd 		if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); }	/*	move the monsters		*/
    222  1.1      cgd 		if (viewflag==0) showcell(playerx,playery); else viewflag=0;	/*	show stuff around player	*/
    223  1.1      cgd 		if (hit3flag) flushall();
    224  1.1      cgd 		hitflag=hit3flag=0;	nomove=1;
    225  1.1      cgd 		bot_linex();	/* update bottom line */
    226  1.1      cgd 		while (nomove)
    227  1.1      cgd 			{
    228  1.1      cgd 			if (hit3flag) flushall();
    229  1.1      cgd 			nomove=0; parse();
    230  1.1      cgd 			}	/*	get commands and make moves	*/
    231  1.1      cgd 		regen();			/*	regenerate hp and spells			*/
    232  1.1      cgd 		if (c[TIMESTOP]==0)
    233  1.1      cgd 			if (--rmst <= 0)
    234  1.1      cgd 				{ rmst = 120-(level<<2); fillmonst(makemonst(level)); }
    235  1.1      cgd 		}
    236  1.1      cgd 	}
    237  1.1      cgd 
    238  1.1      cgd /*
    240  1.1      cgd 	showstr()
    241  1.1      cgd 
    242  1.1      cgd 	show character's inventory
    243  1.1      cgd  */
    244  1.1      cgd showstr()
    245  1.1      cgd 	{
    246  1.1      cgd 	register int i,number;
    247  1.1      cgd 	for (number=3, i=0; i<26; i++)
    248  1.1      cgd 		if (iven[i]) number++;	/* count items in inventory */
    249  1.1      cgd 	t_setup(number);	qshowstr();	  t_endup(number);
    250  1.1      cgd 	}
    251  1.1      cgd 
    252  1.1      cgd qshowstr()
    253  1.1      cgd 	{
    254  1.1      cgd 	register int i,j,k,sigsav;
    255  1.1      cgd 	srcount=0;  sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
    256  1.1      cgd 	if (c[GOLD]) { lprintf(".)   %d gold pieces",(long)c[GOLD]); srcount++; }
    257  1.1      cgd 	for (k=26; k>=0; k--)
    258  1.1      cgd 	  if (iven[k])
    259  1.1      cgd 		{  for (i=22; i<84; i++)
    260  1.1      cgd 			 for (j=0; j<=k; j++)  if (i==iven[j])  show3(j); k=0; }
    261  1.1      cgd 
    262  1.1      cgd 	lprintf("\nElapsed time is %d.  You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
    263  1.1      cgd 	more();		nosignal=sigsav;
    264  1.1      cgd 	}
    265  1.1      cgd 
    266  1.1      cgd /*
    267  1.1      cgd  *	subroutine to clear screen depending on # lines to display
    268  1.1      cgd  */
    269  1.1      cgd t_setup(count)
    270  1.1      cgd 	register int count;
    271  1.1      cgd 	{
    272  1.1      cgd 	if (count<20)  /* how do we clear the screen? */
    273  1.1      cgd 		{
    274  1.1      cgd 		cl_up(79,count);  cursor(1,1);
    275  1.1      cgd 		}
    276  1.1      cgd 	else
    277  1.1      cgd 		{
    278  1.1      cgd 		resetscroll(); clear();
    279  1.1      cgd 		}
    280  1.1      cgd 	}
    281  1.1      cgd 
    282  1.1      cgd /*
    283  1.1      cgd  *	subroutine to restore normal display screen depending on t_setup()
    284  1.1      cgd  */
    285  1.1      cgd t_endup(count)
    286  1.1      cgd 	register int count;
    287  1.1      cgd 	{
    288  1.1      cgd 	if (count<18)  /* how did we clear the screen? */
    289  1.1      cgd 		draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
    290  1.1      cgd 	else
    291  1.1      cgd 		{
    292  1.1      cgd 		drawscreen(); setscroll();
    293  1.1      cgd 		}
    294  1.1      cgd 	}
    295  1.1      cgd 
    296  1.1      cgd /*
    297  1.1      cgd 	function to show the things player is wearing only
    298  1.1      cgd  */
    299  1.1      cgd showwear()
    300  1.1      cgd 	{
    301  1.1      cgd 	register int i,j,sigsav,count;
    302  1.1      cgd 	sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
    303  1.1      cgd 	srcount=0;
    304  1.1      cgd 
    305  1.1      cgd 	 for (count=2,j=0; j<=26; j++)	 /* count number of items we will display */
    306  1.1      cgd 	   if (i=iven[j])
    307  1.1      cgd 		switch(i)
    308  1.1      cgd 			{
    309  1.1      cgd 			case OLEATHER:	case OPLATE:	case OCHAIN:
    310  1.1      cgd 			case ORING:		case OSTUDLEATHER:	case OSPLINT:
    311  1.1      cgd 			case OPLATEARMOR:	case OSSPLATE:	case OSHIELD:
    312  1.1      cgd 			count++;
    313  1.1      cgd 			};
    314  1.1      cgd 
    315  1.1      cgd 	t_setup(count);
    316  1.1      cgd 
    317  1.1      cgd 	for (i=22; i<84; i++)
    318  1.1      cgd 		 for (j=0; j<=26; j++)
    319  1.1      cgd 		   if (i==iven[j])
    320  1.1      cgd 			switch(i)
    321  1.1      cgd 				{
    322  1.1      cgd 				case OLEATHER:	case OPLATE:	case OCHAIN:
    323  1.1      cgd 				case ORING:		case OSTUDLEATHER:	case OSPLINT:
    324  1.1      cgd 				case OPLATEARMOR:	case OSSPLATE:	case OSHIELD:
    325  1.1      cgd 				show3(j);
    326  1.1      cgd 				};
    327  1.1      cgd 	more();		nosignal=sigsav;	t_endup(count);
    328  1.1      cgd 	}
    329  1.1      cgd 
    330  1.1      cgd /*
    331  1.1      cgd 	function to show the things player can wield only
    332  1.1      cgd  */
    333  1.1      cgd showwield()
    334  1.1      cgd 	{
    335  1.1      cgd 	register int i,j,sigsav,count;
    336  1.1      cgd 	sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
    337  1.1      cgd 	srcount=0;
    338  1.1      cgd 
    339  1.1      cgd 	 for (count=2,j=0; j<=26; j++)	/* count how many items */
    340  1.1      cgd 	   if (i=iven[j])
    341  1.1      cgd 		switch(i)
    342  1.1      cgd 			{
    343  1.1      cgd 			case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
    344  1.1      cgd 			case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
    345  1.1      cgd 			case OSPIRITSCARAB:  case OCUBEofUNDEAD:
    346  1.1      cgd 			case OPOTION:   case OSCROLL:  break;
    347  1.1      cgd 			default:  count++;
    348  1.1      cgd 			};
    349  1.1      cgd 
    350  1.1      cgd 	t_setup(count);
    351  1.1      cgd 
    352  1.1      cgd 	for (i=22; i<84; i++)
    353  1.1      cgd 		 for (j=0; j<=26; j++)
    354  1.1      cgd 		   if (i==iven[j])
    355  1.1      cgd 			switch(i)
    356  1.1      cgd 				{
    357  1.1      cgd 				case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
    358  1.1      cgd 				case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
    359  1.1      cgd 				case OSPIRITSCARAB:  case OCUBEofUNDEAD:
    360  1.1      cgd 				case OPOTION:   case OSCROLL:  break;
    361  1.1      cgd 				default:  show3(j);
    362  1.1      cgd 				};
    363  1.1      cgd 	more();		nosignal=sigsav;	t_endup(count);
    364  1.1      cgd 	}
    365  1.1      cgd 
    366  1.1      cgd /*
    367  1.1      cgd  *	function to show the things player can read only
    368  1.1      cgd  */
    369  1.1      cgd showread()
    370  1.1      cgd 	{
    371  1.1      cgd 	register int i,j,sigsav,count;
    372  1.1      cgd 	sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
    373  1.1      cgd 	srcount=0;
    374  1.1      cgd 
    375  1.1      cgd 	for (count=2,j=0; j<=26; j++)
    376  1.1      cgd 		switch(iven[j])
    377  1.1      cgd 			{
    378  1.1      cgd 			case OBOOK:	case OSCROLL:	count++;
    379  1.1      cgd 			};
    380  1.1      cgd 	t_setup(count);
    381  1.1      cgd 
    382  1.1      cgd 	for (i=22; i<84; i++)
    383  1.1      cgd 		 for (j=0; j<=26; j++)
    384  1.1      cgd 		   if (i==iven[j])
    385  1.1      cgd 			switch(i)
    386  1.1      cgd 				{
    387  1.1      cgd 				case OBOOK:	case OSCROLL:	show3(j);
    388  1.1      cgd 				};
    389  1.1      cgd 	more();		nosignal=sigsav;	t_endup(count);
    390  1.1      cgd 	}
    391  1.1      cgd 
    392  1.1      cgd /*
    393  1.1      cgd  *	function to show the things player can eat only
    394  1.1      cgd  */
    395  1.1      cgd showeat()
    396  1.1      cgd 	{
    397  1.1      cgd 	register int i,j,sigsav,count;
    398  1.1      cgd 	sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
    399  1.1      cgd 	srcount=0;
    400  1.1      cgd 
    401  1.1      cgd 	for (count=2,j=0; j<=26; j++)
    402  1.1      cgd 		switch(iven[j])
    403  1.1      cgd 			{
    404  1.1      cgd 			case OCOOKIE:	count++;
    405  1.1      cgd 			};
    406  1.1      cgd 	t_setup(count);
    407  1.1      cgd 
    408  1.1      cgd 	for (i=22; i<84; i++)
    409  1.1      cgd 		 for (j=0; j<=26; j++)
    410  1.1      cgd 		   if (i==iven[j])
    411  1.1      cgd 			switch(i)
    412  1.1      cgd 				{
    413  1.1      cgd 				case OCOOKIE:	show3(j);
    414  1.1      cgd 				};
    415  1.1      cgd 	more();		nosignal=sigsav;	t_endup(count);
    416  1.1      cgd 	}
    417  1.1      cgd 
    418  1.1      cgd /*
    419  1.1      cgd 	function to show the things player can quaff only
    420  1.1      cgd  */
    421  1.1      cgd showquaff()
    422  1.1      cgd 	{
    423  1.1      cgd 	register int i,j,sigsav,count;
    424  1.1      cgd 	sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
    425  1.1      cgd 	srcount=0;
    426  1.1      cgd 
    427  1.1      cgd 	for (count=2,j=0; j<=26; j++)
    428  1.1      cgd 		switch(iven[j])
    429  1.1      cgd 			{
    430  1.1      cgd 			case OPOTION:	count++;
    431  1.1      cgd 			};
    432  1.1      cgd 	t_setup(count);
    433  1.1      cgd 
    434  1.1      cgd 	for (i=22; i<84; i++)
    435  1.1      cgd 		 for (j=0; j<=26; j++)
    436  1.1      cgd 		   if (i==iven[j])
    437  1.1      cgd 			switch(i)
    438  1.1      cgd 				{
    439  1.1      cgd 				case OPOTION:	show3(j);
    440  1.1      cgd 				};
    441  1.1      cgd 	more();		nosignal=sigsav;		t_endup(count);
    442  1.1      cgd 	}
    443  1.1      cgd 
    444  1.1      cgd show1(idx,str2)
    445  1.1      cgd 	register int idx;
    446  1.1      cgd 	register char *str2[];
    447  1.4  mycroft 	{
    448  1.4  mycroft 	lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
    449  1.1      cgd 	if (str2!=0 && str2[ivenarg[idx]][0]!=0)  lprintf(" of%s",str2[ivenarg[idx]]);
    450  1.1      cgd 	}
    451  1.1      cgd 
    452  1.1      cgd show3(index)
    453  1.1      cgd 	register int index;
    454  1.1      cgd 	{
    455  1.1      cgd 	switch(iven[index])
    456  1.1      cgd 		{
    457  1.1      cgd 		case OPOTION:	show1(index,potionname);  break;
    458  1.1      cgd 		case OSCROLL:	show1(index,scrollname);  break;
    459  1.1      cgd 
    460  1.1      cgd 		case OLARNEYE:		case OBOOK:			case OSPIRITSCARAB:
    461  1.1      cgd 		case ODIAMOND:		case ORUBY:			case OCUBEofUNDEAD:
    462  1.1      cgd 		case OEMERALD:		case OCHEST:		case OCOOKIE:
    463  1.1      cgd 		case OSAPPHIRE:		case ONOTHEFT:		show1(index,(char **)0);  break;
    464  1.1      cgd 
    465  1.1      cgd 		default:		lprintf("\n%c)   %s",index+'a',objectname[iven[index]]);
    466  1.1      cgd 						if (ivenarg[index]>0) lprintf(" + %d",(long)ivenarg[index]);
    467  1.1      cgd 						else if (ivenarg[index]<0) lprintf(" %d",(long)ivenarg[index]);
    468  1.1      cgd 						break;
    469  1.1      cgd 		}
    470  1.1      cgd 	if (c[WIELD]==index) lprcat(" (weapon in hand)");
    471  1.1      cgd 	if ((c[WEAR]==index) || (c[SHIELD]==index))  lprcat(" (being worn)");
    472  1.1      cgd 	if (++srcount>=22) { srcount=0; more(); clear(); }
    473  1.1      cgd 	}
    474  1.1      cgd 
    475  1.1      cgd /*
    476  1.1      cgd 	subroutine to randomly create monsters if needed
    477  1.1      cgd  */
    478  1.1      cgd randmonst()
    479  1.1      cgd 	{
    480  1.1      cgd 	if (c[TIMESTOP]) return;	/*	don't make monsters if time is stopped	*/
    481  1.1      cgd 	if (--rmst <= 0)
    482  1.1      cgd 		{
    483  1.1      cgd 		rmst = 120 - (level<<2);  fillmonst(makemonst(level));
    484  1.1      cgd 		}
    485  1.1      cgd 	}
    486  1.1      cgd 
    487  1.1      cgd 
    488  1.1      cgd /*
    490  1.1      cgd 	parse()
    491  1.1      cgd 
    492  1.1      cgd 	get and execute a command
    493  1.1      cgd  */
    494  1.1      cgd parse()
    495  1.1      cgd 	{
    496  1.1      cgd 	register int i,j,k,flag;
    497  1.1      cgd 	while	(1)
    498  1.1      cgd 		{
    499  1.1      cgd 		k = yylex();
    500  1.1      cgd 		switch(k)	/*	get the token from the input and switch on it	*/
    501  1.1      cgd 			{
    502  1.1      cgd 			case 'h':	moveplayer(4);	return;		/*	west		*/
    503  1.1      cgd 			case 'H':	run(4);			return;		/*	west		*/
    504  1.1      cgd 			case 'l':	moveplayer(2);	return;		/*	east		*/
    505  1.1      cgd 			case 'L':	run(2);			return;		/*	east		*/
    506  1.1      cgd 			case 'j':	moveplayer(1);	return;		/*	south		*/
    507  1.1      cgd 			case 'J':	run(1);			return;		/*	south		*/
    508  1.1      cgd 			case 'k':	moveplayer(3);	return;		/*	north		*/
    509  1.1      cgd 			case 'K':	run(3);			return;		/*	north		*/
    510  1.1      cgd 			case 'u':	moveplayer(5);	return;		/*	northeast	*/
    511  1.1      cgd 			case 'U':	run(5);			return;		/*	northeast	*/
    512  1.1      cgd 			case 'y':	moveplayer(6);  return;		/*	northwest	*/
    513  1.1      cgd 			case 'Y':	run(6);			return;		/*	northwest	*/
    514  1.1      cgd 			case 'n':	moveplayer(7);	return;		/*	southeast	*/
    515  1.1      cgd 			case 'N':	run(7);			return;		/*	southeast	*/
    516  1.1      cgd 			case 'b':	moveplayer(8);	return;		/*	southwest	*/
    517  1.1      cgd 			case 'B':	run(8);			return;		/*	southwest	*/
    518  1.1      cgd 
    519  1.1      cgd 			case '.':	if (yrepcount) viewflag=1; return;		/*	stay here		*/
    520  1.1      cgd 
    521  1.1      cgd 			case 'w':	yrepcount=0;	wield();	return;		/*	wield a weapon */
    522  1.1      cgd 
    523  1.1      cgd 			case 'W':	yrepcount=0;	wear();		return;	/*	wear armor	*/
    524  1.1      cgd 
    525  1.1      cgd 			case 'r':	yrepcount=0;
    526  1.1      cgd 						if (c[BLINDCOUNT]) { cursors(); lprcat("\nYou can't read anything when you're blind!"); } else
    527  1.1      cgd 						if (c[TIMESTOP]==0) readscr(); return;		/*	to read a scroll	*/
    528  1.1      cgd 
    529  1.1      cgd 			case 'q':	yrepcount=0;	if (c[TIMESTOP]==0) quaff();	return;	/*	quaff a potion		*/
    530  1.1      cgd 
    531  1.1      cgd 			case 'd':	yrepcount=0;	if (c[TIMESTOP]==0) dropobj(); return;	/*	to drop an object	*/
    532  1.1      cgd 
    533  1.1      cgd 			case 'c':	yrepcount=0;	cast();		return;		/*	cast a spell	*/
    534  1.1      cgd 
    535  1.1      cgd 			case 'i':	yrepcount=0;	nomove=1;  showstr();	return;		/*	status		*/
    536  1.1      cgd 
    537  1.1      cgd 			case 'e':	yrepcount=0;
    538  1.1      cgd 						if (c[TIMESTOP]==0) eatcookie(); return;	/*	to eat a fortune cookie */
    539  1.1      cgd 
    540  1.1      cgd 			case 'D':	yrepcount=0;	seemagic(0);	nomove=1; return;	/*	list spells and scrolls */
    541  1.1      cgd 
    542  1.1      cgd 			case '?':	yrepcount=0;	help(); nomove=1; return;	/*	give the help screen*/
    543  1.1      cgd 
    544  1.1      cgd 			case 'S':	clear();  lprcat("Saving . . ."); lflush();
    545  1.1      cgd 						savegame(savefilename); wizard=1; died(-257);	/*	save the game - doesn't return	*/
    546  1.1      cgd 
    547  1.1      cgd 			case 'Z':	yrepcount=0;	if (c[LEVEL]>9) { oteleport(1); return; }
    548  1.1      cgd 						cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation");
    549  1.1      cgd 						return;	/*	teleport yourself	*/
    550  1.1      cgd 
    551  1.1      cgd 			case '^':	/* identify traps */  flag=yrepcount=0;  cursors();
    552  1.1      cgd 						lprc('\n');  for (j=playery-1; j<playery+2; j++)
    553  1.1      cgd 							{
    554  1.1      cgd 							if (j < 0) j=0;		if (j >= MAXY) break;
    555  1.1      cgd 							for (i=playerx-1; i<playerx+2; i++)
    556  1.1      cgd 								{
    557  1.1      cgd 								if (i < 0) i=0;	if (i >= MAXX) break;
    558  1.1      cgd 								switch(item[i][j])
    559  1.1      cgd 									{
    560  1.1      cgd 									case OTRAPDOOR:		case ODARTRAP:
    561  1.1      cgd 									case OTRAPARROW:	case OTELEPORTER:
    562  1.1      cgd 										lprcat("\nIts "); lprcat(objectname[item[i][j]]);  flag++;
    563  1.1      cgd 									};
    564  1.1      cgd 								}
    565  1.1      cgd 							}
    566  1.1      cgd 						if (flag==0) lprcat("\nNo traps are visible");
    567  1.1      cgd 						return;
    568  1.1      cgd 
    569  1.1      cgd #if WIZID
    570  1.1      cgd 			case '_':	/*	this is the fudge player password for wizard mode*/
    571  1.1      cgd 						yrepcount=0;	cursors(); nomove=1;
    572  1.1      cgd 						if (userid!=wisid)
    573  1.1      cgd 							{
    574  1.1      cgd 							lprcat("Sorry, you are not empowered to be a wizard.\n");
    575  1.1      cgd 							scbr(); /* system("stty -echo cbreak"); */
    576  1.1      cgd 							lflush();  return;
    577  1.1      cgd 							}
    578  1.1      cgd 						if (getpassword()==0)
    579  1.1      cgd 							{
    580  1.1      cgd 							scbr(); /* system("stty -echo cbreak"); */ return;
    581  1.1      cgd 							}
    582  1.1      cgd 						wizard=1;  scbr(); /* system("stty -echo cbreak"); */
    583  1.1      cgd 						for (i=0; i<6; i++)  c[i]=70;  iven[0]=iven[1]=0;
    584  1.1      cgd 						take(OPROTRING,50);   take(OLANCE,25);  c[WIELD]=1;
    585  1.1      cgd 						c[LANCEDEATH]=1;   c[WEAR] = c[SHIELD] = -1;
    586  1.1      cgd 						raiseexperience(6000000L);  c[AWARENESS] += 25000;
    587  1.1      cgd 						{
    588  1.1      cgd 						register int i,j;
    589  1.1      cgd 						for (i=0; i<MAXY; i++)
    590  1.2  mycroft 							for (j=0; j<MAXX; j++)  know[j][i]=1;
    591  1.2  mycroft 						for (i=0; i<SPNUM; i++)	spelknow[i]=1;
    592  1.1      cgd 						for (i=0; i<MAXSCROLL; i++)  scrollname[i]=scrollhide[i];
    593  1.1      cgd 						for (i=0; i<MAXPOTION; i++)  potionname[i]=potionhide[i];
    594  1.1      cgd 						}
    595  1.1      cgd 						for (i=0; i<MAXSCROLL; i++)
    596  1.1      cgd 						  if (strlen(scrollname[i])>2) /* no null items */
    597  1.1      cgd 							{ item[i][0]=OSCROLL; iarg[i][0]=i; }
    598  1.1      cgd 						for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
    599  1.1      cgd 						  if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
    600  1.1      cgd 							{ item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
    601  1.1      cgd 						for (i=1; i<MAXY; i++)
    602  1.1      cgd 							{ item[0][i]=i; iarg[0][i]=0; }
    603  1.1      cgd 						for (i=MAXY; i<MAXY+MAXX; i++)
    604  1.1      cgd 							{ item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
    605  1.1      cgd 						for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
    606  1.1      cgd 							{ item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; }
    607  1.1      cgd 						c[GOLD]+=25000;	drawscreen();	return;
    608  1.1      cgd #endif
    609  1.1      cgd 
    610  1.1      cgd 			case 'T':	yrepcount=0;	cursors();  if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
    611  1.1      cgd 										if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
    612  1.1      cgd 						else lprcat("\nYou aren't wearing anything");
    613  1.1      cgd 						return;
    614  1.1      cgd 
    615  1.1      cgd 			case 'g':	cursors();
    616  1.1      cgd 						lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
    617  1.1      cgd 			case ' ':	yrepcount=0;	nomove=1;  return;
    618  1.1      cgd 
    619  1.1      cgd 			case 'v':	yrepcount=0;	cursors();
    620  1.1      cgd 						lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]);
    621  1.1      cgd 						if (wizard) lprcat(" Wizard"); nomove=1;
    622  1.1      cgd 						if (cheat) lprcat(" Cheater");
    623  1.1      cgd 						lprcat(copyright);
    624  1.1      cgd 						return;
    625  1.1      cgd 
    626  1.1      cgd 			case 'Q':	yrepcount=0;	quit(); nomove=1;	return;	/*	quit		*/
    627  1.1      cgd 
    628  1.1      cgd 			case 'L'-64:  yrepcount=0;	drawscreen();  nomove=1; return;	/*	look		*/
    629  1.1      cgd 
    630  1.1      cgd #if WIZID
    631  1.1      cgd #ifdef EXTRA
    632  1.1      cgd 			case 'A':	yrepcount=0;	nomove=1; if (wizard) { diag(); return; }  /*	create diagnostic file */
    633  1.1      cgd 						return;
    634  1.1      cgd #endif
    635  1.1      cgd #endif
    636  1.1      cgd 			case 'P':	cursors();
    637  1.1      cgd 						if (outstanding_taxes>0)
    638  1.1      cgd 							lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
    639  1.1      cgd 						else
    640  1.1      cgd 							lprcat("\nYou do not owe any taxes.");
    641  1.1      cgd 						return;
    642  1.1      cgd 			};
    643  1.1      cgd 		}
    644  1.1      cgd 	}
    645  1.1      cgd 
    646  1.1      cgd parse2()
    647  1.1      cgd 	{
    648  1.1      cgd 	if (c[HASTEMONST]) movemonst(); movemonst(); /*	move the monsters		*/
    649  1.1      cgd 	randmonst();	regen();
    650  1.1      cgd 	}
    651  1.1      cgd 
    652  1.1      cgd run(dir)
    653  1.1      cgd 	int dir;
    654  1.1      cgd 	{
    655  1.1      cgd 	register int i;
    656  1.1      cgd 	i=1; while (i)
    657  1.1      cgd 		{
    658  1.1      cgd 		i=moveplayer(dir);
    659  1.1      cgd 		if (i>0) {  if (c[HASTEMONST]) movemonst();  movemonst(); randmonst(); regen(); }
    660  1.1      cgd 		if (hitflag) i=0;
    661  1.1      cgd 		if (i!=0)  showcell(playerx,playery);
    662  1.1      cgd 		}
    663  1.1      cgd 	}
    664  1.1      cgd 
    665  1.1      cgd /*
    666  1.1      cgd 	function to wield a weapon
    667  1.1      cgd  */
    668  1.1      cgd wield()
    669  1.1      cgd 	{
    670  1.1      cgd 	register int i;
    671  1.1      cgd 	while (1)
    672  1.1      cgd 		{
    673  1.1      cgd 		if ((i = whatitem("wield"))=='\33')  return;
    674  1.1      cgd 		if (i != '.')
    675  1.1      cgd 			{
    676  1.1      cgd 			if (i=='*') showwield();
    677  1.1      cgd 			else  if (iven[i-'a']==0) { ydhi(i); return; }
    678  1.1      cgd 			else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
    679  1.1      cgd 			else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
    680  1.1      cgd 			else  if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; }
    681  1.1      cgd 			else  { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0;  bottomline(); return; }
    682  1.1      cgd 			}
    683  1.1      cgd 		}
    684  1.1      cgd 	}
    685  1.1      cgd 
    686  1.1      cgd /*
    687  1.1      cgd 	common routine to say you don't have an item
    688  1.1      cgd  */
    689  1.1      cgd ydhi(x)
    690  1.1      cgd 	int x;
    691  1.1      cgd 	{ cursors();  lprintf("\nYou don't have item %c!",x); }
    692  1.1      cgd ycwi(x)
    693  1.1      cgd 	int x;
    694  1.1      cgd 	{ cursors();  lprintf("\nYou can't wield item %c!",x); }
    695  1.1      cgd 
    696  1.1      cgd /*
    697  1.1      cgd 	function to wear armor
    698  1.1      cgd  */
    699  1.1      cgd wear()
    700  1.1      cgd 	{
    701  1.1      cgd 	register int i;
    702  1.1      cgd 	while (1)
    703  1.1      cgd 		{
    704  1.1      cgd 		if ((i = whatitem("wear"))=='\33')  return;
    705  1.1      cgd 		if (i != '.')
    706  1.1      cgd 			{
    707  1.1      cgd 			if (i=='*') showwear(); else
    708  1.1      cgd 			switch(iven[i-'a'])
    709  1.1      cgd 				{
    710  1.1      cgd 				case 0:  ydhi(i); return;
    711  1.1      cgd 				case OLEATHER:  case OCHAIN:  case OPLATE:	case OSTUDLEATHER:
    712  1.1      cgd 				case ORING:		case OSPLINT:	case OPLATEARMOR:	case OSSPLATE:
    713  1.1      cgd 						if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
    714  1.1      cgd 							c[WEAR]=i-'a';  bottomline(); return;
    715  1.1      cgd 				case OSHIELD:	if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
    716  1.1      cgd 								if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
    717  1.1      cgd 								c[SHIELD] = i-'a';  bottomline(); return;
    718  1.1      cgd 				default:	lprcat("\nYou can't wear that!");
    719  1.1      cgd 				};
    720  1.1      cgd 			}
    721  1.1      cgd 		}
    722  1.1      cgd 	}
    723  1.1      cgd 
    724  1.1      cgd /*
    725  1.1      cgd 	function to drop an object
    726  1.1      cgd  */
    727  1.1      cgd dropobj()
    728  1.1      cgd 	{
    729  1.1      cgd 	register int i;
    730  1.1      cgd 	register char *p;
    731  1.1      cgd 	long amt;
    732  1.1      cgd 	p = &item[playerx][playery];
    733  1.1      cgd 	while (1)
    734  1.1      cgd 		{
    735  1.1      cgd 		if ((i = whatitem("drop"))=='\33')  return;
    736  1.1      cgd 		if (i=='*') showstr(); else
    737  1.1      cgd 			{
    738  1.1      cgd 			if (i=='.')	/* drop some gold */
    739  1.1      cgd 				{
    740  1.1      cgd 				if (*p) { lprcat("\nThere's something here already!"); return; }
    741  1.1      cgd 				lprcat("\n\n");
    742  1.1      cgd 				cl_dn(1,23);
    743  1.1      cgd 				lprcat("How much gold do you drop? ");
    744  1.1      cgd 				if ((amt=readnum((long)c[GOLD])) == 0) return;
    745  1.1      cgd 				if (amt>c[GOLD])
    746  1.1      cgd 					{ lprcat("\nYou don't have that much!"); return; }
    747  1.1      cgd 				if (amt<=32767)
    748  1.1      cgd 					{ *p=OGOLDPILE; i=amt; }
    749  1.1      cgd 				else if (amt<=327670L)
    750  1.1      cgd 					{ *p=ODGOLD; i=amt/10; amt = 10*i; }
    751  1.1      cgd 				else if (amt<=3276700L)
    752  1.1      cgd 					{ *p=OMAXGOLD; i=amt/100; amt = 100*i; }
    753  1.1      cgd 				else if (amt<=32767000L)
    754  1.1      cgd 					{ *p=OKGOLD; i=amt/1000; amt = 1000*i; }
    755  1.1      cgd 				else
    756  1.1      cgd 					{ *p=OKGOLD; i=32767; amt = 32767000L; }
    757  1.1      cgd 				c[GOLD] -= amt;
    758  1.1      cgd 				lprintf("You drop %d gold pieces",(long)amt);
    759  1.1      cgd 				iarg[playerx][playery]=i; bottomgold();
    760  1.1      cgd 				know[playerx][playery]=0; dropflag=1;  return;
    761  1.1      cgd 				}
    762  1.1      cgd 			drop_object(i-'a');
    763  1.1      cgd 			return;
    764  1.1      cgd 			}
    765  1.1      cgd 		}
    766  1.1      cgd 	}
    767  1.1      cgd 
    768  1.1      cgd /*
    769  1.1      cgd  *	readscr()		Subroutine to read a scroll one is carrying
    770  1.1      cgd  */
    771  1.1      cgd readscr()
    772  1.1      cgd 	{
    773  1.1      cgd 	register int i;
    774  1.1      cgd 	while (1)
    775  1.1      cgd 		{
    776  1.1      cgd 		if ((i = whatitem("read"))=='\33')  return;
    777  1.1      cgd 		if (i != '.')
    778  1.1      cgd 			{
    779  1.1      cgd 			if (i=='*') showread(); else
    780  1.1      cgd 				{
    781  1.1      cgd 				if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
    782  1.1      cgd 				if (iven[i-'a']==OBOOK)   { readbook(ivenarg[i-'a']);  iven[i-'a']=0; return; }
    783  1.1      cgd 				if (iven[i-'a']==0) { ydhi(i); return; }
    784  1.1      cgd 				lprcat("\nThere's nothing on it to read");  return;
    785  1.1      cgd 				}
    786  1.1      cgd 			}
    787  1.1      cgd 		}
    788  1.1      cgd 	}
    789  1.1      cgd 
    790  1.1      cgd /*
    791  1.1      cgd  *	subroutine to eat a cookie one is carrying
    792  1.1      cgd  */
    793  1.1      cgd eatcookie()
    794  1.1      cgd {
    795  1.1      cgd register int i;
    796  1.1      cgd char *p;
    797  1.1      cgd while (1)
    798  1.1      cgd 	{
    799  1.1      cgd 	if ((i = whatitem("eat"))=='\33')  return;
    800  1.1      cgd 	if (i != '.')
    801  1.1      cgd 		if (i=='*') showeat(); else
    802  1.1      cgd 			{
    803  1.1      cgd 			if (iven[i-'a']==OCOOKIE)
    804  1.1      cgd 				{
    805  1.1      cgd 				lprcat("\nThe cookie was delicious.");
    806  1.1      cgd 				iven[i-'a']=0;
    807  1.6      cgd 				if (!c[BLINDCOUNT])
    808  1.1      cgd 					{
    809  1.1      cgd 					if (p=fortune())
    810  1.1      cgd 						{
    811  1.1      cgd 						lprcat("  Inside you find a scrap of paper that says:\n");
    812  1.1      cgd 						lprcat(p);
    813  1.1      cgd 						}
    814  1.1      cgd 					}
    815  1.1      cgd 				return;
    816  1.1      cgd 				}
    817  1.1      cgd 			if (iven[i-'a']==0) { ydhi(i); return; }
    818  1.1      cgd 			lprcat("\nYou can't eat that!");  return;
    819  1.1      cgd 			}
    820  1.1      cgd 	}
    821  1.1      cgd }
    822  1.1      cgd 
    823  1.1      cgd /*
    824  1.1      cgd  *	subroutine to quaff a potion one is carrying
    825  1.1      cgd  */
    826  1.1      cgd quaff()
    827  1.1      cgd 	{
    828  1.1      cgd 	register int i;
    829  1.1      cgd 	while (1)
    830  1.1      cgd 		{
    831  1.1      cgd 		if ((i = whatitem("quaff"))=='\33')  return;
    832  1.1      cgd 		if (i != '.')
    833  1.1      cgd 			{
    834  1.1      cgd 			if (i=='*') showquaff(); else
    835  1.1      cgd 				{
    836  1.1      cgd 				if (iven[i-'a']==OPOTION) { quaffpotion(ivenarg[i-'a']); iven[i-'a']=0; return; }
    837  1.1      cgd 				if (iven[i-'a']==0) { ydhi(i); return; }
    838  1.1      cgd 				lprcat("\nYou wouldn't want to quaff that, would you? ");  return;
    839  1.1      cgd 				}
    840  1.1      cgd 			}
    841  1.1      cgd 		}
    842  1.1      cgd 	}
    843  1.1      cgd 
    844  1.1      cgd /*
    845  1.1      cgd 	function to ask what player wants to do
    846  1.1      cgd  */
    847  1.1      cgd whatitem(str)
    848  1.1      cgd 	char *str;
    849  1.1      cgd 	{
    850  1.1      cgd 	int i;
    851  1.1      cgd 	cursors();  lprintf("\nWhat do you want to %s [* for all] ? ",str);
    852  1.1      cgd 	i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
    853  1.1      cgd 	if (i=='\33')  lprcat(" aborted");
    854  1.1      cgd 	return(i);
    855  1.1      cgd 	}
    856  1.1      cgd 
    857  1.1      cgd /*
    858  1.1      cgd 	subroutine to get a number from the player
    859  1.1      cgd 	and allow * to mean return amt, else return the number entered
    860  1.1      cgd  */
    861  1.1      cgd unsigned long readnum(mx)
    862  1.1      cgd 	long mx;
    863  1.1      cgd 	{
    864  1.1      cgd 	register int i;
    865  1.1      cgd 	register unsigned long amt=0;
    866  1.1      cgd 	sncbr();
    867  1.1      cgd 	if ((i=getchar()) == '*')  amt = mx;   /* allow him to say * for all gold */
    868  1.1      cgd 	else
    869  1.1      cgd 		while (i != '\n')
    870  1.1      cgd 			{
    871  1.1      cgd 			if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
    872  1.1      cgd 			if ((i <= '9') && (i >= '0') && (amt<99999999))
    873  1.1      cgd 				amt = amt*10+i-'0';
    874  1.1      cgd 			i = getchar();
    875  1.1      cgd 			}
    876  1.1      cgd 	scbr();  return(amt);
    877  1.1      cgd 	}
    878  1.1      cgd 
    879  1.1      cgd #ifdef HIDEBYLINK
    880  1.1      cgd /*
    881  1.1      cgd  *	routine to zero every byte in a string
    882  1.1      cgd  */
    883  1.1      cgd szero(str)
    884  1.1      cgd 	register char *str;
    885  1.1      cgd 	{
    886  1.1      cgd 	while (*str)
    887  1.1      cgd 		*str++ = 0;
    888               	}
    889               #endif HIDEBYLINK
    890