[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / src / games / larn

File: [local] / src / games / larn / Attic / main.c (download)

Revision 1.11, Wed Aug 2 04:10:45 2000 UTC (23 years, 10 months ago) by millert
Branch: MAIN
CVS Tags: OPENBSD_3_2_BASE, OPENBSD_3_2, OPENBSD_3_1_BASE, OPENBSD_3_1, OPENBSD_3_0_BASE, OPENBSD_3_0, OPENBSD_2_9_BASE, OPENBSD_2_9, OPENBSD_2_8_BASE, OPENBSD_2_8
Changes since 1.10: +6 -4 lines

$HOME paranoia: never use getenv("HOME") w/o checking for NULL and non-zero

/*	$OpenBSD: main.c,v 1.11 2000/08/02 04:10:45 millert Exp $	*/
/*	$NetBSD: main.c,v 1.12 1998/02/12 08:07:49 mikel Exp $	*/

/* main.c		 */
#ifndef lint
static char rcsid[] = "$OpenBSD: main.c,v 1.11 2000/08/02 04:10:45 millert Exp $";
#endif				/* not lint */

#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <pwd.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"
#include "extern.h"

static char	copyright[] = "\nLarn is copyrighted 1986 by Noah Morgan.\n";
int		srcount = 0;	/* line counter for showstr()	 */
int		dropflag = 0;	/* if 1 then don't lookforobject() next round */
int		rmst = 80;	/* random monster creation counter	*/
int		userid;		/* the players login user id number	*/
gid_t		gid, egid;	/* used for security			*/
u_char		nowelcome = 0, nomove = 0;	/* if (nomove) then don't
						 * count next iteration as a
						 * move */
static char	viewflag = 0;
/*
 * if viewflag then we have done a 99 stay here and don't showcell in the
 * main loop
 */
u_char		restorflag = 0;	/* 1 means restore has been done	 */
static char	cmdhelp[] = "\
Cmd line format: larn [-slicnh] [-o<optsfile>] [-##] [++]\n\
  -s   show the scoreboard\n\
  -l   show the logfile (wizards only)\n\
  -i   show scoreboard with inventories of dead characters\n\
  -c   create new scoreboard (wizards only)\n\
  -n   suppress welcome message on starting game\n\
  -##  specify level of difficulty (example: -5)\n\
  -h   print this help text\n\
  ++   restore game from checkpoint file\n\
  -o<optsfile>   specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
";

/*
 *	************
 *	MAIN PROGRAM
 *	************
 */
int
main(argc, argv)
	int	argc;
	char	**argv;
{
	int	i;
	int	hard;
	const char	*ptr = 0;
	struct passwd	*pwe;

	egid = getegid();
	gid = getgid();
	setegid(gid);		/* give up "games" if we have it */
	/*
	 *	first task is to identify the player
	 */
	init_term();		/* setup the terminal (find out what type)
				 * for termcap */
	/* try to get login name */
	if (((ptr = getlogin()) == 0) || (*ptr == 0)) {
		/* can we get it from /etc/passwd? */
		if ((pwe = getpwuid(getuid())) != NULL)
			ptr = pwe->pw_name;
		else
#ifdef NOSPAM
		    if ((ptr = getenv("LOGNAME")) == 0)
			if ((ptr = getenv("USER")) == 0)
#endif
		noone:		errx(1, "can't find your logname.  Who Are You?");
	}
	if (ptr == 0)
		goto noone;
	if (strlen(ptr) == 0)
		goto noone;
	/*
	 *	second task is to prepare the pathnames the player will need
	 */
	strlcpy(loginname, ptr, LOGIN_NAME_MAX);
	/* this will be overwritten with the player's name */
	strlcpy(logname, ptr, LOGNAMESIZE);
	if ((ptr = getenv("HOME")) == NULL) {
		fprintf(stderr, "You have no home directory!\n");
		exit(1);
	}
	if (strlen(ptr) + 9 < sizeof(savefilename)) {
		strcpy(savefilename, ptr);
		strcat(savefilename, "/Larn.sav");	/* save file name in
							 * home directory */
	} else {
		fprintf(stderr, "%s/Larn.sav: %s\n", ptr, strerror(ENAMETOOLONG));
		exit(1);
	}
	if (strlen(ptr) + 10 < sizeof(savefilename)) {
		strcpy(optsfile, ptr);
		strcat(optsfile, "/.larnopts");	/* the .larnopts filename */
	} else {
		fprintf(stderr, "%s/.larnopts: %s\n", ptr, strerror(ENAMETOOLONG));
		exit(1);
	}

	/*
	 *	now malloc the memory for the dungeon
	 */
	cell = (struct cel *) malloc(sizeof(struct cel) * (MAXLEVEL + MAXVLEVEL) * MAXX * MAXY);
	if (cell == 0)
		died(-285);	/* malloc failure */
	lpbuf = malloc((5 * BUFBIG) >> 2);	/* output buffer */
	inbuffer = malloc((5 * MAXIBUF) >> 2);	/* output buffer */
	if ((lpbuf == 0) || (inbuffer == 0))
		died(-285);	/* malloc() failure */

	lcreat((char *) 0);
	newgame();		/* set the initial clock  */
	hard = -1;

	/*
	 *	now make scoreboard if it is not there (don't clear)
	 */
	if (access(scorefile, 0) == -1)	/* not there */
		makeboard();

	/*
	 *	now process the command line arguments
	 */
	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-')
			switch (argv[i][1]) {
			case 's':
				showscores();
				exit(0);	/* show scoreboard	*/

			case 'l':		/* show log file	*/
				diedlog();
				exit(0);

			case 'i':
				showallscores();
				exit(0);	/* show all scoreboard */

			case 'c':	/* anyone with password can create
					 * scoreboard */
				lprcat("Preparing to initialize the scoreboard.\n");
				if (getpassword() != 0) {	/* make new scoreboard */
					makeboard();
					lprc('\n');
					showscores();
				}
				exit(0);

			case 'n':	/* no welcome msg	 */
				nowelcome = 1;
				argv[i][0] = 0;
				break;

			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':	/* for hardness */
				sscanf(&argv[i][1], "%d", &hard);
				break;

			case 'h':	/* print out command line arguments */
				write(1, cmdhelp, sizeof(cmdhelp));
				exit(0);

			case 'o':	/* specify a .larnopts filename */
				strlcpy(optsfile, argv[i] + 2, PATH_MAX);
				break;

			default:
				printf("Unknown option <%s>\n", argv[i]);
				exit(1);
			};

		if (argv[i][0] == '+') {
			clear();
			restorflag = 1;
			if (argv[i][1] == '+') {
				hitflag = 1;
				restoregame(ckpfile);	/* restore checkpointed
							 * game */
			}
			i = argc;
		}
	}

	readopts();		/* read the options file if there is one */


#ifdef UIDSCORE
	userid = geteuid();	/* obtain the user's effective id number */
#else	/* UIDSCORE */
	userid = getplid(logname);	/* obtain the players id number */
#endif	/* UIDSCORE */
	if (userid < 0) {
		write(2, "Can't obtain playerid\n", 22);
		exit(1);
	}

	if (access(savefilename, 0) == 0) {	/* restore game if need to */
		clear();
		restorflag = 1;
		hitflag = 1;
		restoregame(savefilename);	/* restore last game	 */
	}
	sigsetup();		/* trap all needed signals		*/
	sethard(hard);		/* set up the desired difficulty	*/
	setupvt100();		/* setup the terminal special mode	*/
	if (c[HP] == 0) {	/* create new game			*/
		makeplayer();	/* make the character that will play	*/
		newcavelevel(0);/* make the dungeon			*/
		predostuff = 1;	/* tell signals that we are in the welcome
				 * screen */
		if (nowelcome == 0)
			welcome();	/* welcome the player to the game */
	}
	drawscreen();		/* show the initial dungeon		*/
	predostuff = 2;		/* tell the trap functions that they must do
				 * a showplayer() from here on */
#if 0
	nice(1);		/* games should be run niced		*/
#endif
	yrepcount = hit2flag = 0;
	while (1) {
		if (dropflag == 0)
			lookforobject();	/* see if there is an object
						 * here	 */
		else
			dropflag = 0;	/* don't show it just dropped an item */
		if (hitflag == 0) {
			if (c[HASTEMONST])
				movemonst();
			movemonst();
		}		/* move the monsters		 */
		if (viewflag == 0)
			showcell(playerx, playery);
		else
			viewflag = 0;	/* show stuff around player	 */
		if (hit3flag)
			flushall();
		hitflag = hit3flag = 0;
		nomove = 1;
		bot_linex();	/* update bottom line */
		while (nomove) {
			if (hit3flag)
				flushall();
			nomove = 0;
			parse();
		}		/* get commands and make moves	*/
		regen();	/* regenerate hp and spells	*/
		if (c[TIMESTOP] == 0)
			if (--rmst <= 0) {
				rmst = 120 - (level << 2);
				fillmonst(makemonst(level));
			}
	}
}


/*
 *	showstr()
 *
 *	show character's inventory
 */
void
showstr()
{
	int	i, number;

	for (number = 3, i = 0; i < 26; i++)
		if (iven[i])
			number++;	/* count items in inventory */
	t_setup(number);
	qshowstr();
	t_endup(number);
}

void
qshowstr()
{
	int	i, j, k, sigsav;

	srcount = 0;
	sigsav = nosignal;
	nosignal = 1;		/* don't allow ^c etc */
	if (c[GOLD]) {
		lprintf(".)   %d gold pieces", (long) c[GOLD]);
		srcount++;
	}
	for (k = 26; k >= 0; k--)
		if (iven[k]) {
			for (i = 22; i < 84; i++)
				for (j = 0; j <= k; j++)
					if (i == iven[j])
						show3(j);
			k = 0;
		}
	lprintf("\nElapsed time is %d.  You have %d mobuls left", (long) ((gltime + 99) / 100 + 1), (long) ((TIMELIMIT - gltime) / 100));
	more();
	nosignal = sigsav;
}

/*
 *	subroutine to clear screen depending on # lines to display
 */
void
t_setup(count)
	int	count;
{
	if (count < 20) {	/* how do we clear the screen? */
		cl_up(79, count);
		cursor(1, 1);
	} else {
		resetscroll();
		clear();
	}
}

/*
 *	subroutine to restore normal display screen depending on t_setup()
 */
void
t_endup(count)
	int	count;
{
	if (count < 18)		/* how did we clear the screen? */
		draws(0, MAXX, 0, (count > MAXY) ? MAXY : count);
	else {
		drawscreen();
		setscroll();
	}
}

/*
 *	function to show the things player is wearing only
 */
void
showwear()
{
	int	i, j, sigsav, count;

	sigsav = nosignal;
	nosignal = 1;		/* don't allow ^c etc */
	srcount = 0;

	for (count = 2, j = 0; j <= 26; j++)	/* count number of items we
						 * will display */
		if ((i = iven[j]) != 0)
			switch (i) {
			case OLEATHER:
			case OPLATE:
			case OCHAIN:
			case ORING:
			case OSTUDLEATHER:
			case OSPLINT:
			case OPLATEARMOR:
			case OSSPLATE:
			case OSHIELD:
				count++;
			};

	t_setup(count);

	for (i = 22; i < 84; i++)
		for (j = 0; j <= 26; j++)
			if (i == iven[j])
				switch (i) {
				case OLEATHER:
				case OPLATE:
				case OCHAIN:
				case ORING:
				case OSTUDLEATHER:
				case OSPLINT:
				case OPLATEARMOR:
				case OSSPLATE:
				case OSHIELD:
					show3(j);
				};
	more();
	nosignal = sigsav;
	t_endup(count);
}

/*
 *	function to show the things player can wield only
 */
void
showwield()
{
	int	i, j, sigsav, count;

	sigsav = nosignal;
	nosignal = 1;		/* don't allow ^c etc */
	srcount = 0;

	for (count = 2, j = 0; j <= 26; j++)	/* count how many items */
		if ((i = iven[j]) != 0)
			switch (i) {
			case ODIAMOND:
			case ORUBY:
			case OEMERALD:
			case OSAPPHIRE:
			case OBOOK:
			case OCHEST:
			case OLARNEYE:
			case ONOTHEFT:
			case OSPIRITSCARAB:
			case OCUBEofUNDEAD:
			case OPOTION:
			case OSCROLL:
				break;
			default:
				count++;
			};

	t_setup(count);

	for (i = 22; i < 84; i++)
		for (j = 0; j <= 26; j++)
			if (i == iven[j])
				switch (i) {
				case ODIAMOND:
				case ORUBY:
				case OEMERALD:
				case OSAPPHIRE:
				case OBOOK:
				case OCHEST:
				case OLARNEYE:
				case ONOTHEFT:
				case OSPIRITSCARAB:
				case OCUBEofUNDEAD:
				case OPOTION:
				case OSCROLL:
					break;
				default:
					show3(j);
				};
	more();
	nosignal = sigsav;
	t_endup(count);
}

/*
 *	function to show the things player can read only
 */
void
showread()
{
	int	i, j, sigsav, count;

	sigsav = nosignal;
	nosignal = 1;		/* don't allow ^c etc */
	srcount = 0;

	for (count = 2, j = 0; j <= 26; j++)
		switch (iven[j]) {
		case OBOOK:
		case OSCROLL:
			count++;
		};
	t_setup(count);

	for (i = 22; i < 84; i++)
		for (j = 0; j <= 26; j++)
			if (i == iven[j])
				switch (i) {
				case OBOOK:
				case OSCROLL:
					show3(j);
				};
	more();
	nosignal = sigsav;
	t_endup(count);
}

/*
 *	function to show the things player can eat only
 */
void
showeat()
{
	int	i, j, sigsav, count;

	sigsav = nosignal;
	nosignal = 1;		/* don't allow ^c etc */
	srcount = 0;

	for (count = 2, j = 0; j <= 26; j++)
		switch (iven[j]) {
		case OCOOKIE:
			count++;
		};
	t_setup(count);

	for (i = 22; i < 84; i++)
		for (j = 0; j <= 26; j++)
			if (i == iven[j])
				switch (i) {
				case OCOOKIE:
					show3(j);
				};
	more();
	nosignal = sigsav;
	t_endup(count);
}

/*
 *	function to show the things player can quaff only
 */
void
showquaff()
{
	int	i, j, sigsav, count;

	sigsav = nosignal;
	nosignal = 1;		/* don't allow ^c etc */
	srcount = 0;

	for (count = 2, j = 0; j <= 26; j++)
		switch (iven[j]) {
		case OPOTION:
			count++;
		};
	t_setup(count);

	for (i = 22; i < 84; i++)
		for (j = 0; j <= 26; j++)
			if (i == iven[j])
				switch (i) {
				case OPOTION:
					show3(j);
				};
	more();
	nosignal = sigsav;
	t_endup(count);
}

void
show1(idx, str2)
	int	idx;
	char	*str2[];
{
	lprintf("\n%c)   %s", idx + 'a', objectname[iven[idx]]);
	if (str2 != 0 && str2[ivenarg[idx]][0] != 0)
		lprintf(" of%s", str2[ivenarg[idx]]);
}

void
show3(index)
	int	index;
{
	switch (iven[index]) {
	case OPOTION:
		show1(index, potionname);
		break;
	case OSCROLL:
		show1(index, scrollname);
		break;

	case OLARNEYE:
	case OBOOK:
	case OSPIRITSCARAB:
	case ODIAMOND:
	case ORUBY:
	case OCUBEofUNDEAD:
	case OEMERALD:
	case OCHEST:
	case OCOOKIE:
	case OSAPPHIRE:
	case ONOTHEFT:
		show1(index, (char **) 0);
		break;

	default:
		lprintf("\n%c)   %s", index + 'a', objectname[iven[index]]);
		if (ivenarg[index] > 0)
			lprintf(" + %d", (long) ivenarg[index]);
		else if (ivenarg[index] < 0)
			lprintf(" %d", (long) ivenarg[index]);
		break;
	}
	if (c[WIELD] == index)
		lprcat(" (weapon in hand)");
	if ((c[WEAR] == index) || (c[SHIELD] == index))
		lprcat(" (being worn)");
	if (++srcount >= 22) {
		srcount = 0;
		more();
		clear();
	}
}

/*
 *	subroutine to randomly create monsters if needed
 */
void
randmonst()
{
	if (c[TIMESTOP])
		return;		/* don't make monsters if time is stopped */
	if (--rmst <= 0) {
		rmst = 120 - (level << 2);
		fillmonst(makemonst(level));
	}
}



/*
 *	parse()
 *
 *	get and execute a command
 */
void
parse()
{
	int	i, j, k, flag;

	while (1) {
		k = yylex();
		switch (k) {	/* get the token from the input	 */
		case 'h':
			moveplayer(4);
			return;	/* west		*/
		case 'H':
			run(4);
			return;	/* west		*/
		case 'l':
			moveplayer(2);
			return;	/* east		*/
		case 'L':
			run(2);
			return;	/* east		*/
		case 'j':
			moveplayer(1);
			return;	/* south	*/
		case 'J':
			run(1);
			return;	/* south	*/
		case 'k':
			moveplayer(3);
			return;	/* north	*/
		case 'K':
			run(3);
			return;	/* north	*/
		case 'u':
			moveplayer(5);
			return;	/* northeast	*/
		case 'U':
			run(5);
			return;	/* northeast	 */
		case 'y':
			moveplayer(6);
			return;	/* northwest	*/
		case 'Y':
			run(6);
			return;	/* northwest	*/
		case 'n':
			moveplayer(7);
			return;	/* southeast	*/
		case 'N':
			run(7);
			return;	/* southeast	*/
		case 'b':
			moveplayer(8);
			return;	/* southwest	*/
		case 'B':
			run(8);
			return;	/* southwest	*/

		case '.':
			if (yrepcount)
				viewflag = 1;
			return;	/* stay here	*/

		case 'w':
			yrepcount = 0;
			wield();
			return;	/* wield a weapon */

		case 'W':
			yrepcount = 0;
			wear();
			return;	/* wear armor	*/

		case 'r':
			yrepcount = 0;
			if (c[BLINDCOUNT]) {
				cursors();
				lprcat("\nYou can't read anything when you're blind!");
			} else if (c[TIMESTOP] == 0)
				readscr();
			return;	/* to read a scroll	*/

		case 'q':
			yrepcount = 0;
			if (c[TIMESTOP] == 0)
				quaff();
			return;	/* quaff a potion	*/

		case 'd':
			yrepcount = 0;
			if (c[TIMESTOP] == 0)
				dropobj();
			return;	/* to drop an object	*/

		case 'c':
			yrepcount = 0;
			cast();
			return;	/* cast a spell		*/

		case 'i':
			yrepcount = 0;
			nomove = 1;
			showstr();
			return;	/* status		*/

		case 'e':
			yrepcount = 0;
			if (c[TIMESTOP] == 0)
				eatcookie();
			return;	/* to eat a fortune cookie */

		case 'D':
			yrepcount = 0;
			seemagic(0);
			nomove = 1;
			return;	/* list spells and scrolls */

		case '?':
			yrepcount = 0;
			help();
			nomove = 1;
			return;	/* give the help screen */

		case 'S':
			clear();
			lprcat("Saving . . .");
			lflush();
			if (savegame(savefilename) < 0)
				return;
			wizard = 1;
			died(-257);	/* save the game - doesn't return */

		case 'Z':
			yrepcount = 0;
			if (c[LEVEL] > 9) {
				oteleport(1);
				return;
			}
			cursors();
			lprcat("\nAs yet, you don't have enough experience to use teleportation");
			return;	/* teleport yourself	 */

		case '^':	/* identify traps */
			flag = yrepcount = 0;
			cursors();
			lprc('\n');
			for (j = playery - 1; j < playery + 2; j++) {
				if (j < 0)
					j = 0;
				if (j >= MAXY)
					break;
				for (i = playerx - 1; i < playerx + 2; i++) {
					if (i < 0)
						i = 0;
					if (i >= MAXX)
						break;
					switch (item[i][j]) {
					case OTRAPDOOR:
					case ODARTRAP:
					case OTRAPARROW:
					case OTELEPORTER:
						lprcat("\nIts ");
						lprcat(objectname[item[i][j]]);
						flag++;
					};
				}
			}
			if (flag == 0)
				lprcat("\nNo traps are visible");
			return;

#if WIZID
		case '_':	/* this is the fudge player password for
				 * wizard mode */
			yrepcount = 0;
			cursors();
			nomove = 1;
			if (userid != wisid) {
				lprcat("Sorry, you are not empowered to be a wizard.\n");
				scbr();	/* system("stty -echo cbreak"); */
				lflush();
				return;
			}
			if (getpassword() == 0) {
				scbr();	/* system("stty -echo cbreak"); */
				return;
			}
			wizard = 1;
			scbr();	/* system("stty -echo cbreak"); */
			for (i = 0; i < 6; i++)
				c[i] = 70;
			iven[0] = iven[1] = 0;
			take(OPROTRING, 50);
			take(OLANCE, 25);
			c[WIELD] = 1;
			c[LANCEDEATH] = 1;
			c[WEAR] = c[SHIELD] = -1;
			raiseexperience(6000000L);
			c[AWARENESS] += 25000;
			{
				int	i, j;
				for (i = 0; i < MAXY; i++)
					for (j = 0; j < MAXX; j++)
						know[j][i] = 1;
				for (i = 0; i < SPNUM; i++)
					spelknow[i] = 1;
				for (i = 0; i < MAXSCROLL; i++)
					scrollname[i] = scrollhide[i];
				for (i = 0; i < MAXPOTION; i++)
					potionname[i] = potionhide[i];
			}
			for (i = 0; i < MAXSCROLL; i++)
				if (strlen(scrollname[i]) > 2) {	/* no null items */
					item[i][0] = OSCROLL;
					iarg[i][0] = i;
				}
			for (i = MAXX - 1; i > MAXX - 1 - MAXPOTION; i--)
				if (strlen(potionname[i - MAXX + MAXPOTION]) > 2) {	/* no null items */
					item[i][0] = OPOTION;
					iarg[i][0] = i - MAXX + MAXPOTION;
				}
			for (i = 1; i < MAXY; i++) {
				item[0][i] = i;
				iarg[0][i] = 0;
			}
			for (i = MAXY; i < MAXY + MAXX; i++) {
				item[i - MAXY][MAXY - 1] = i;
				iarg[i - MAXY][MAXY - 1] = 0;
			}
			for (i = MAXX + MAXY; i < MAXX + MAXY + MAXY; i++) {
				item[MAXX - 1][i - MAXX - MAXY] = i;
				iarg[MAXX - 1][i - MAXX - MAXY] = 0;
			}
			c[GOLD] += 25000;
			drawscreen();
			return;
#endif

		case 'T':
			yrepcount = 0;
			cursors();
			if (c[SHIELD] != -1) {
				c[SHIELD] = -1;
				lprcat("\nYour shield is off");
				bottomline();
			} else if (c[WEAR] != -1) {
				c[WEAR] = -1;
				lprcat("\nYour armor is off");
				bottomline();
			} else
				lprcat("\nYou aren't wearing anything");
			return;

		case 'g':
			cursors();
			lprintf("\nThe stuff you are carrying presently weighs %d pounds", (long) packweight());
		case ' ':
			yrepcount = 0;
			nomove = 1;
			return;

		case 'v':
			yrepcount = 0;
			cursors();
			lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d", (long) VERSION, (long) SUBVERSION, (long) c[HARDGAME]);
			if (wizard)
				lprcat(" Wizard");
			nomove = 1;
			if (cheat)
				lprcat(" Cheater");
			lprcat(copyright);
			return;

		case 'Q':
			yrepcount = 0;
			quit();
			nomove = 1;
			return;	/* quit		 */

		case 'L' - 64:
			yrepcount = 0;
			drawscreen();
			nomove = 1;
			return;	/* look		 */

#if WIZID
#ifdef EXTRA
		case 'A':
			yrepcount = 0;
			nomove = 1;
			if (wizard) {
				diag();
				return;
			}	/* create diagnostic file */
			return;
#endif
#endif
		case 'P':
			cursors();
			if (outstanding_taxes > 0)
				lprintf("\nYou presently owe %d gp in taxes.", (long) outstanding_taxes);
			else
				lprcat("\nYou do not owe any taxes.");
			return;
		};
	}
}

void
parse2()
{
	if (c[HASTEMONST])
		movemonst();
	movemonst();		/* move the monsters		 */
	randmonst();
	regen();
}

void
run(dir)
	int	dir;
{
	int	i;

	i = 1;
	while (i) {
		i = moveplayer(dir);
		if (i > 0) {
			if (c[HASTEMONST])
				movemonst();
			movemonst();
			randmonst();
			regen();
		}
		if (hitflag)
			i = 0;
		if (i != 0)
			showcell(playerx, playery);
	}
}

/*
	function to wield a weapon
 */
void
wield()
{
	int	i;

	while (1) {
		if ((i = whatitem("wield")) == '\33')
			return;
		if (i != '.') {
			if (i == '*')
				showwield();
			else if (iven[i - 'a'] == 0) {
				ydhi(i);
				return;
			} else if (iven[i - 'a'] == OPOTION) {
				ycwi(i);
				return;
			} else if (iven[i - 'a'] == OSCROLL) {
				ycwi(i);
				return;
			} else if ((c[SHIELD] != -1) && (iven[i - 'a'] == O2SWORD)) {
				lprcat("\nBut one arm is busy with your shield!");
				return;
			} else {
				c[WIELD] = i - 'a';
				if (iven[i - 'a'] == OLANCE)
					c[LANCEDEATH] = 1;
				else
					c[LANCEDEATH] = 0;
				bottomline();
				return;
			}
		}
	}
}

/*
 *	common routine to say you don't have an item
 */
void
ydhi(x)
	int	x;
{
	cursors();
	lprintf("\nYou don't have item %c!", x);
}

void
ycwi(x)
	int	x;
{
	cursors();
	lprintf("\nYou can't wield item %c!", x);
}

/*
 *	function to wear armor
 */
void
wear()
{
	int	i;

	while (1) {
		if ((i = whatitem("wear")) == '\33')
			return;
		if (i != '.') {
			if (i == '*')
				showwear();
			else
				switch (iven[i - 'a']) {
				case 0:
					ydhi(i);
					return;
				case OLEATHER:
				case OCHAIN:
				case OPLATE:
				case OSTUDLEATHER:
				case ORING:
				case OSPLINT:
				case OPLATEARMOR:
				case OSSPLATE:
					if (c[WEAR] != -1) {
						lprcat("\nYou're already wearing some armor");
						return;
					}
					c[WEAR] = i - 'a';
					bottomline();
					return;
				case OSHIELD:
					if (c[SHIELD] != -1) {
						lprcat("\nYou are already wearing a shield");
						return;
					}
					if (iven[c[WIELD]] == O2SWORD) {
						lprcat("\nYour hands are busy with the two handed sword!");
						return;
					}
					c[SHIELD] = i - 'a';
					bottomline();
					return;
				default:
					lprcat("\nYou can't wear that!");
				};
		}
	}
}

/*
 *	function to drop an object
 */
void
dropobj()
{
	int	i;
	char	*p;
	long	amt;

	p = &item[playerx][playery];
	while (1) {
		if ((i = whatitem("drop")) == '\33')
			return;
		if (i == '*')
			showstr();
		else {
			if (i == '.') {	/* drop some gold */
				if (*p) {
					lprcat("\nThere's something here already!");
					return;
				}
				lprcat("\n\n");
				cl_dn(1, 23);
				lprcat("How much gold do you drop? ");
				if ((amt = readnum((long) c[GOLD])) == 0)
					return;
				if (amt > c[GOLD]) {
					lprcat("\nYou don't have that much!");
					return;
				}
				if (amt <= 32767) {
					*p = OGOLDPILE;
					i = amt;
				} else if (amt <= 327670L) {
					*p = ODGOLD;
					i = amt / 10;
					amt = 10 * i;
				} else if (amt <= 3276700L) {
					*p = OMAXGOLD;
					i = amt / 100;
					amt = 100 * i;
				} else if (amt <= 32767000L) {
					*p = OKGOLD;
					i = amt / 1000;
					amt = 1000 * i;
				} else {
					*p = OKGOLD;
					i = 32767;
					amt = 32767000L;
				}
				c[GOLD] -= amt;
				lprintf("You drop %d gold pieces", (long) amt);
				iarg[playerx][playery] = i;
				bottomgold();
				know[playerx][playery] = 0;
				dropflag = 1;
				return;
			}
			drop_object(i - 'a');
			return;
		}
	}
}

/*
 *	readscr()		Subroutine to read a scroll one is carrying
 */
void
readscr()
{
	int	i;

	while (1) {
		if ((i = whatitem("read")) == '\33')
			return;
		if (i != '.') {
			if (i == '*')
				showread();
			else {
				if (iven[i - 'a'] == OSCROLL) {
					read_scroll(ivenarg[i - 'a']);
					iven[i - 'a'] = 0;
					return;
				}
				if (iven[i - 'a'] == OBOOK) {
					readbook(ivenarg[i - 'a']);
					iven[i - 'a'] = 0;
					return;
				}
				if (iven[i - 'a'] == 0) {
					ydhi(i);
					return;
				}
				lprcat("\nThere's nothing on it to read");
				return;
			}
		}
	}
}

/*
 *	subroutine to eat a cookie one is carrying
 */
void
eatcookie()
{
	int	i;
	char	*p;

	while (1) {
		if ((i = whatitem("eat")) == '\33')
			return;
		if (i != '.') {
			if (i == '*')
				showeat();
			else {
				if (iven[i - 'a'] == OCOOKIE) {
					lprcat("\nThe cookie was delicious.");
					iven[i - 'a'] = 0;
					if (!c[BLINDCOUNT]) {
						if ((p = fortune()) != NULL) {
							lprcat("  Inside you find a scrap of paper that says:\n");
							lprcat(p);
						}
					}
					return;
				}
				if (iven[i - 'a'] == 0) {
					ydhi(i);
					return;
				}
				lprcat("\nYou can't eat that!");
				return;
			}
		}
	}
}

/*
 *	subroutine to quaff a potion one is carrying
 */
void
quaff()
{
	int	i;

	while (1) {
		if ((i = whatitem("quaff")) == '\33')
			return;
		if (i != '.') {
			if (i == '*')
				showquaff();
			else {
				if (iven[i - 'a'] == OPOTION) {
					quaffpotion(ivenarg[i - 'a']);
					iven[i - 'a'] = 0;
					return;
				}
				if (iven[i - 'a'] == 0) {
					ydhi(i);
					return;
				}
				lprcat("\nYou wouldn't want to quaff that, would you? ");
				return;
			}
		}
	}
}

/*
 *	function to ask what player wants to do
 */
int
whatitem(str)
	char	*str;
{
	int	i;

	cursors();
	lprintf("\nWhat do you want to %s [* for all] ? ", str);
	i = 0;
	while (i > 'z' || (i < 'a' && i != '*' && i != '\33' && i != '.'))
		i = lgetchar();
	if (i == '\33')
		lprcat(" aborted");
	return (i);
}

/*
 *	subroutine to get a number from the player
 *	and allow * to mean return amt, else return the number entered
 */
unsigned long 
readnum(mx)
	long	mx;
{
	int	i;

	unsigned long amt = 0;
	sncbr();
	if ((i = lgetchar()) == '*')
		amt = mx;	/* allow him to say * for all gold */
	else
		while (i != '\n') {
			if (i == '\033') {
				scbr();
				lprcat(" aborted");
				return (0);
			}
			if ((i <= '9') && (i >= '0') && (amt < 99999999))
				amt = amt * 10 + i - '0';
			i = lgetchar();
		}
	scbr();
	return (amt);
}