[comp.sources.games] v11i084: larn - dungeon type adventure game, Part01/11

billr@saab.CNA.TEK.COM (Bill Randle) (12/19/90)

Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 11, Issue 84
Archive-name: larn/Part01
Environment: Unix, VMS, MS-DOS, termcap

	[This is the source for Larn V12.2, an enhancement of the
	 original Larn (written by Noah Morgan) by Kevin Routley.
	 This version is different than Ularn which was previously
	 posted in volume 7 and is closer to the original in
	 "look and feel". It is known to compile on Unix, VMS and
	 MS-DOS. PC executables were previously posted to
	 comp.binaries.ibm.pc.  -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 11)."
# Contents:  README MANIFEST descrip.mms main.c
# Wrapped by billr@saab on Tue Dec 18 10:14:12 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1362 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XAs promised, here is the source to Larn V12.2, the executables for which were
Xposted earlier this year to comp.binaries.ibm.pc.
X
XThe source correctly compiles and executes under DEC Ultrix, using the cc
Xcompiler.  The enclosed Makefile is for U*ix systems.
X
XThe source correctly compiles and executes under VAX/VMS, using the VAX C V3.x
Xcompiler.  The enclosed descrip.mms is a MMS file for building under VAX/VMS.
X
XThe source correctly compiles and executes under MS-DOS, using Turbo C V2.0 or
XTurbo C++ V1.0.  The LARN.PRJ file is for Turbo C V2.0, but unfortunately I am
Xunable to properly distribute the Turbo C++ project file and setup files.  To
Xcompiler under MS-DOS, you must define the MSDOS, DGK, SYSV, DGK_MSDOS and
XNOVARARGS defines.
X
XI am interested in receiving source changes that allow Larn to be ported to
Xother architectures or operating systems.  I am also interested in constructive
Xchanges or additions to improve the game.  I am _not_ interested in arbitrary
Xmods, a la UltraLarn.
X
XBug fixes, bug reports, and requests welcome.
X
XI am reachable at tle.enet.dec.com!routley or routley@tle.enet.dec.com.
XBecause I am right in the middle of moving at the moment, all USmail should be
Xsent to:
X
XKevin Routley
XDigital Equipment Corporation
XZKO2-3/N30
X110 Spitbrook Road
XNashua, NH  03060
X
Xinstead of the address listed in the documentation file.
END_OF_FILE
if test 1362 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(2286 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	This shipping list
X Makefile                   5	Makefile for U*ix.
X README                     1	
X action.c                   9	
X bill.c                     7	
X config.c                  11	
X create.c                   8	
X data.c                     2	
X descrip.mms                1	MMS build file for VAX/VMS
X diag.c                     8	
X display.c                  2	
X fgetlr.c                  11	Termcap support for VMS/MS-DOS.
X fortune.c                 11	
X global.c                   7	
X header.h                   8	
X help.c                    11	
X io.c                       7	
X larn.ftn                  11	Fortune File
X larn.maz                   6	Maze file
X larn.opt                   2	Simple options file.  Rename to .larnopts for U*ix.
X larn.prj                   2	Turbo C V2.0 Project File
X larn122.doc                6	Documentation for Larn V12.2
X larn122.fix               11	List of changes since Larn V12.0
X larn_hlp.uue               9	Uuencoded help file with ansi escape sequences
X larnhlp.txt               10	Help file without ansi escape sequences
X main.c                     1	
X monster.c                  4	
X moreobj.c                  9	
X movem.c                    5	
X msdos.c                   10	MS-DOS Specific code.
X nansi.doc                  8	Documentation for NANSI.SYS, a MS-DOS ANSI.SYS replacement
X nansisys.uue              11	UUENCODED NANSI.SYS
X nap.c                     11	
X object.c                   4	
X regen.c                    9	
X savelev.c                  5	
X scores.c                   3	
X signal.c                  11	
X spells.c                   5	
X spheres.c                 10	
X store.c                    3	
X termcap.pc                 4	Termcap file for MS-DOS.
X termcap.vms               11	Termcap file for VMS.
X tgetent.c                  9	Termcap support for VMS/MS-DOS.
X tgetstr.c                  6	Termcap support for VMS/MS-DOS.
X tgoto.c                   10	Termcap support for VMS/MS-DOS.
X tok.c                     10	
X tputs.c                   10	Termcap support for VMS/MS-DOS.
X vms.c                     10	VMS Specific code.
X vmsreadme.txt             11	Readme file for VMS.
END_OF_FILE
if test 2286 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'descrip.mms' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'descrip.mms'\"
else
echo shar: Extracting \"'descrip.mms'\" \(1579 characters\)
sed "s/^X//" >'descrip.mms' <<'END_OF_FILE'
XSOURCES = 	BILL.C, CONFIG.C, CREATE.C, DATA.C, DIAG.C, DISPLAY.C, -
X		FORTUNE.C, GLOBAL.C, HELP.C, IO.C, MAIN.C, MONSTER.C, -
X		MOREOBJ.C, MOVEM.C, NAP.C, OBJECT.C, REGEN.C, SAVELEV.C, -
X		SCORES.C, SIGNAL.C, STORE.C, TOK.C, VMS.C, -
X		ACTION.C, FGETLR.C, TGETENT.C, TGETSTR.C, TGOTO.C, TPUTS.C
X
XOBJECTS =	BILL.OBJ, CONFIG.OBJ, CREATE.OBJ, DATA.OBJ, DIAG.OBJ, -
X		DISPLAY.OBJ, FORTUNE.OBJ, GLOBAL.OBJ, HELP.OBJ, IO.OBJ, -
X		MAIN.OBJ, MONSTER.OBJ, MOREOBJ.OBJ, MOVEM.OBJ, NAP.OBJ, -
X		OBJECT.OBJ, REGEN.OBJ, SAVELEV.OBJ, SCORES.OBJ, SIGNAL.OBJ, -
X		STORE.OBJ, TOK.OBJ, VMS.OBJ, -
X		ACTION.OBJ, FGETLR.OBJ, TGETENT.OBJ, TGETSTR.OBJ, TGOTO.OBJ, -
X		TPUTS.OBJ
X
XDOBJECTS =	BILL.DBJ, CONFIG.DBJ, CREATE.DBJ, DATA.DBJ, DIAG.DBJ, -
X		DISPLAY.DBJ, FORTUNE.DBJ, GLOBAL.DBJ, HELP.DBJ, IO.DBJ, -
X		MAIN.DBJ, MONSTER.DBJ, MOREOBJ.DBJ, MOVEM.DBJ, NAP.DBJ, -
X		OBJECT.DBJ, REGEN.DBJ, SAVELEV.DBJ, SCORES.DBJ, SIGNAL.DBJ, -
X		STORE.DBJ, TOK.DBJ, VMS.DBJ, -
X		ACTION.DBJ, FGETLR.DBJ, TGETENT.DBJ, TGETSTR.DBJ, TGOTO.DBJ, -
X		TPUTS.DBJ
X
XCDEFS =	/DEFINE=(LARNHOME="""larndir:""",DGK)
X
X.SUFFIXES
X.SUFFIXES .OBJ .DBJ .C
X
XLARN.EXE : $(OBJECTS)
X	LINK /NODEBUG/EXEC=LARN.EXE $(OBJECTS), sys$library:vaxcrtl.olb/libr
X
XLARND.EXE : $(DOBJECTS)
X	LINK /DEBUG/EXEC=LARND.EXE $(DOBJECTS), sys$library:vaxcrtl.olb/libr
X
XLARNPCA.EXE : $(DOBJECTS), TERMCAP.OLB
X        LINK /DEBUG=SYS$LIBRARY:PCA$OBJ.OBJ/EXEC=LARNPCA.EXE $(DOBJECTS),-
X             SYS$LIBRARY:VAXCRTL.OLB/LIBR
X
X$(OBJECTS),$(DOBJECTS) : HEADER.H
X
X.C.OBJ
X	CC $(CDEFS) /NODEB/OPTIM/OBJ=$*.OBJ $*.C
X
X.C.DBJ
X	CC $(CDEFS) /DEBUG/NOOPT/OBJ=$*.DBJ $*.C
END_OF_FILE
if test 1579 -ne `wc -c <'descrip.mms'`; then
    echo shar: \"'descrip.mms'\" unpacked with wrong size!
fi
# end of 'descrip.mms'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(45396 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/*  main.c      */
X
X#ifdef MSDOS
X#include "errno.h"
X#include "setjmp.h"
X#include "stdlib.h"
X#endif
X
X#include "header.h"
X#ifndef MSDOS
X# ifndef VMS
X#  include <pwd.h>
X# endif VMS
X#endif MSDOS
X
Xstatic char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";
Xint srcount=0;  /* line counter for showstr()   */
Xint dropflag=0; /* if 1 then don't lookforobject() next round */
Xint rmst=80;    /*  random monster creation counter     */
Xint userid;     /* the players login user id number */
Xchar nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a
X                              move */
Xstatic char viewflag=0;    /* if viewflag then we have done a 99 stay here 
X                              and don't showcell in the main loop */
Xchar restorflag=0;         /* 1 means restore has been done    */
Xchar prompt_mode = 0;         /* 1 if prompting for actions */
X
X#ifndef MSDOS
X# ifndef VMS
Xint ospeed = 0;
Xchar PC = 0;
X# endif VMS
X#endif MSDOS
X
X#ifdef MSDOS
X
Xstatic char cmdhelp[] = "\
XCmd line format: larn [-slicnhp] [-o<optsifle>] [-##] [++]\n\
X  -s   show the scoreboard\n\
X  -l   show the logfile (wizard id only)\n\
X  -i   show scoreboard with inventories of dead characters\n\
X  -c   create new scoreboard (wizard id only)\n\
X  -n   suppress welcome message on starting game\n\
X  -##  specify level of difficulty (example: -5)\n\
X  -h   print this help text\n\
X  -p   prompt for actions on objects\n\
X  ++   restore game from checkpoint file\n\
X  -o<optsfile>   specify larnopts filename to be used instead of \"larn.opt\"\n\
X";
X
X# else
X
Xstatic char cmdhelp[] = "\
XCmd line format: larn [-slicnhp] [-o<optsifle>] [-##] [++]\n\
X  -s   show the scoreboard\n\
X  -l   show the logfile (wizard id only)\n\
X  -i   show scoreboard with inventories of dead characters\n\
X  -c   create new scoreboard (wizard id only)\n\
X  -n   suppress welcome message on starting game\n\
X  -##  specify level of difficulty (example: -5)\n\
X  -h   print this help text\n\
X  -p   prompt for actions on objects\n\
X  ++   restore game from checkpoint file\n\
X  -o<optsfile>   specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
X";
X
X# endif
X
X#ifdef DGK_MSDOS
Xint save_mode = 0;      /* 1 if doing a save game */
Xjmp_buf save_jbuf;      /* To recover from disk full errors */
X#endif
X
X#ifdef VT100
Xstatic char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
X    "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
X    "vt341"  };
X#endif
X/*
X    ************
X    MAIN PROGRAM
X    ************
X*/
Xmain(argc,argv)
X    int argc;
X    char **argv;
X    {
X    register int i,j;
X    int hard = -1;
X    char *ptr=0,*ttype;
X#ifndef MSDOS
X    struct passwd *pwe,*getpwuid();
X#endif
X
X/*
X *  first task is to identify the player
X */
X#ifndef VT100
X    init_term();    /* setup the terminal (find out what type) for termcap */
X#endif
X#ifdef MSDOS
X    ptr = "PLAYER";
X#else
X#ifdef VMS
X    ptr = getenv("USER");
X#else
X    if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */
X      if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
X        ptr = pwe->pw_name;
X      else
X      if ((ptr = getenv("USER")) == 0)
X        if ((ptr = getenv("LOGNAME")) == 0)
X          {
X          noone: write(2, "Can't find your logname.  Who Are You?\n",39);
X                 exit();
X          }
X    if (ptr==0) goto noone;
X    if (strlen(ptr)==0) goto noone;
X#endif
X#endif
X
X/*
X *  second task is to prepare the pathnames the player will need
X */
X    strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
X    strcpy(logname,ptr);    /* this will be overwritten with the players name */
X
X/* Set up the input and output buffers.
X */
X    lpbuf    = (char *)malloc((5* BUFBIG)>>2);  /* output buffer */
X    inbuffer = (char *)malloc((5*MAXIBUF)>>2);  /* output buffer */
X    if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */
X
X# ifdef DGK_MSDOS
X    /* LARNHOME now comes from the options file, so it must be read in
X     * before constructing the other file names.  Unfortunately we have
X     * to look for the -o option now.
X     */
X    strcpy(optsfile, LARNOPTS);
X    for (i = 1; i < argc; i++)
X        if (strncmp(argv[i], "-o", 2) == 0) {
X            argv[i][0] = 0;         /* remove this argv */
X            if (argv[i][2] != '\0')
X                strncpy(optsfile, &argv[i][2], PATHLEN);
X            else {
X                strncpy(optsfile, argv[i + 1], PATHLEN);
X                argv[i + 1][0] = 0; /* and this argv */
X            }
X            optsfile[PATHLEN - 1] = 0;
X            break;
X        }
X    readopts();
X    append_slash(larndir);
X
X    /* Savefile and swapfile can be given explicitly as options
X     */
X    if (!savefilename[0]) {
X        strcpy(savefilename, larndir);
X        strcat(savefilename, SAVEFILE);
X    }
X    if (!swapfile[0]) {
X        strcpy(swapfile, larndir);
X        strcat(swapfile, SWAPFILE);
X    }
X    strcpy(scorefile, larndir);
X    strcpy(logfile, larndir);
X    strcpy(helpfile, larndir);
X    strcpy(larnlevels, larndir);
X    strcpy(fortfile, larndir);
X    strcpy(playerids, larndir);
X    strcpy(ckpfile, larndir);
X
X# else /* DGK_MSDOS */
X
X    if ((ptr = getenv("HOME")) == 0) ptr = ".";
X#ifdef SAVEINHOME
X    /* save file name in home directory */
X# ifdef VMS
X    sprintf(savefilename, "%s%s",ptr, SAVEFILE);
X# else
X    sprintf(savefilename, "%s/%s",ptr, SAVEFILE);
X# endif VMS
X#else
X    strcat(savefilename,logname);   /* prepare savefile name */
X    strcat(savefilename,".sav");    /* prepare savefile name */
X#endif
X#ifdef VMS
X    sprintf(optsfile, "%s%s",ptr, LARNOPTS);   /* the options filename */
X#else
X    sprintf(optsfile, "%s/%s",ptr, LARNOPTS);   /* the options filename */
X#endif VMS
X
X# endif /* DGK_MSDOS */
X
X    strcat(scorefile, SCORENAME);   /* the larn scoreboard filename */
X    strcat(logfile, LOGFNAME);      /* larn activity logging filename */
X    strcat(helpfile, HELPNAME);     /* the larn on-line help file */
X    strcat(larnlevels, LEVELSNAME); /* the pre-made cave level data file */
X    strcat(fortfile, FORTSNAME);    /* the fortune data file name */
X    strcat(playerids, PLAYERIDS);   /* the playerid data file name */
X    strcat(ckpfile, CKPFILE);
X
X# ifdef TIMECHECK
X    strcat(holifile, HOLIFILE);     /* the holiday data file name */
X# endif
X
X#ifdef VT100
X/*
X *  check terminal type to avoid users who have not vt100 type terminals
X */
X    ttype = getenv("TERM");
X    for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
X        if (strcmp(ttype,termtypes[i]) == 0) { j=0;  break; }
X    if (j)
X        {
X        lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
X        exit();
X        }
X#endif
X
X/*
X *  now make scoreboard if it is not there (don't clear) 
X */
X    if (access(scorefile,0) == -1) /* not there */
X        makeboard();
X
X/*
X *  now process the command line arguments 
X */
X    for (i=1; i<argc; i++)
X        {
X        if (argv[i][0] == '-')
X          switch(argv[i][1])
X            {
X	    case 's':          /* show scoreboard   */
X		showscores();
X#ifdef VMS
X		exit();
X#else
X		exit(0);
X#endif
X
X            case 'l': /* show log file     */
X			diedlog();
X#ifdef VMS
X		exit();
X#else
X		exit(0);
X#endif
X
X	    case 'i': showallscores();
X	    /* show all scoreboard */
X#ifdef VMS
X		exit();
X#else
X		exit(0);
X#endif
X
X            case 'c':        /* anyone with password can create scoreboard */
X                      lprcat("Preparing to initialize the scoreboard.\n");
X                      if (getpassword() != 0)  /*make new scoreboard*/
X                            {
X                            makeboard(); lprc('\n'); showscores();
X                            }
X#ifdef VMS
X		exit();
X#else
X		exit(0);
X#endif
X
X            case 'n':   /* no welcome msg   */ nowelcome=1; argv[i][0]=0; break;
X
X            case '0': case '1': case '2': case '3': case '4': case '5':
X            case '6': case '7': case '8': case '9': /* for hardness */
X                hard = atoi(&argv[i][1]);
X                break;
X
X            case 'h':   /* print out command line arguments */
X			write(1,cmdhelp,sizeof(cmdhelp));
X#ifdef VMS
X		exit();
X#else
X		exit(0);
X#endif
X
X            case 'o':   /* specify a .larnopts filename */
X                        strncpy(optsfile,argv[i]+2,127);  break;
X
X            case 'p':   /* set 'prompt_mode' flag */
X                prompt_mode = 1 ;
X                break ;
X
X	    default:    printf("Unknown option <%s>\n",argv[i]);
X#ifdef VMS
X		exit();
X#else
X		exit(0);
X#endif
X            };
X
X        if (strcmp(argv[i], "++") == 0)
X            restorflag = 1;
X    }
X
X#ifndef DGK_MSDOS
X    readopts();     /* read the options file if there is one */
X#endif
X
X#ifdef TIMECHECK
X/*
X *  this section of code checks to see if larn is allowed during working hours
X */
X    if (dayplay==0) /* check for not-during-daytime-hours */
X      if (playable())
X        {
X        write(2,"Sorry, Larn can not be played during working hours.\n",52);
X        exit();
X        }
X#endif TIMECHECK
X
X#ifdef UIDSCORE
X    userid = geteuid(); /* obtain the user's effective id number */
X#else UIDSCORE
X    userid = getplid(logname);  /* obtain the players id number */
X#endif UIDSCORE
X#ifdef VMS
X    wisid = userid;
X#endif
X    if (userid < 0) { write(2,"Can't obtain playerid\n",22);
X#ifdef VMS
X		exit();
X#else
X		exit(0);
X#endif
X    }
X
X#ifdef HIDEBYLINK
X/*
X *  this section of code causes the program to look like something else to ps
X */
X    if (strcmp(psname,argv[0])) /* if a different process name only */
X        {
X        if ((i=access(psname,1)) < 0)
X            {       /* link not there */
X            if (link(argv[0],psname)>=0)
X                {
X                argv[0] = psname;   execv(psname,argv);
X                }
X            }
X        else
X            unlink(psname);
X        }
X
X    for (i=1; i<argc; i++)
X        {
X        szero(argv[i]); /* zero the argument to avoid ps snooping */
X        }
X#endif HIDEBYLINK
X
X/*
X *  He really wants to play, so malloc the memory for the dungeon.
X */
X# ifdef MSDOS
X    allocate_memory();
X# else
X    cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
X    if (cell == 0) died(-285);  /* malloc failure */
X# endif
X    lcreat((char*)0);   newgame();      /*  set the initial clock  */
X
X    if (restorflag == 1) {          /* restore checkpoint file */
X        clear();
X        hitflag = 1;
X        restoregame(ckpfile);
X    } else if (access(savefilename,0)==0)   /* restore game if need to */
X        {
X        clear();    restorflag = 1;
X        hitflag=1;  restoregame(savefilename);  /* restore last game    */
X        }
X    sigsetup();     /* trap all needed signals  */
X    setupvt100();   /*  setup the terminal special mode             */
X    sethard(hard);  /* set up the desired difficulty                */
X    if (c[HP]==0)   /* create new game */
X        {
X        makeplayer();   /*  make the character that will play           */
X        newcavelevel(0);/*  make the dungeon                            */
X        predostuff = 1; /* tell signals that we are in the welcome screen */
X        if (nowelcome==0) welcome();     /* welcome the player to the game */
X# ifdef DGK_MSDOS
X        /* Display their mail if they've just won the previous game
X         */
X        checkmail();
X# endif
X        }
X
X    lprc(T_INIT);   /* Reinit the screen because of welcome and check mail
X             * having embedded escape sequences.*/
X    drawscreen();   /*  show the initial dungeon                    */
X    predostuff = 2; /* tell the trap functions that they must do a showplayer()
X               from here on */
X#if 0
X    /* nice(1); /* games should be run niced */
X#endif
X    yrepcount = hit2flag = 0;
X    while (1)
X        {
X        if (dropflag==0)
X            /* see if there is an object here.
X
X	       If in prompt mode, identify and prompt; else
X	       identify, pickup if ( auto pickup and not move-no-pickup ),
X	       never prompt.
X	    */
X	    if (prompt_mode)
X		lookforobject( TRUE, FALSE, TRUE );
X	    else
X		lookforobject( TRUE, ( auto_pickup ), FALSE );
X        else
X            dropflag=0; /* don't show it just dropped an item */
X
X	/* Move the monsters
X	*/
X	if (hitflag==0)
X	    {
X	    if (c[HASTEMONST])
X		movemonst();
X	    movemonst();
X	    }
X
X	/* show stuff around the player
X	*/
X	if (viewflag==0)
X	    showcell(playerx,playery);
X	else
X	    viewflag=0;
X
X	if (hit3flag) flushall();
X        hitflag=hit3flag=0; nomove=1;
X        bot_linex();    /* update bottom line */
X        while (nomove)
X            {
X            if (hit3flag) flushall();
X            nomove=0; parse();
X            }   /*  get commands and make moves */
X        regen();            /*  regenerate hp and spells            */
X        if (c[TIMESTOP]==0)
X            if (--rmst <= 0)
X                { rmst = 120-(level<<2); fillmonst(makemonst(level)); }
X        }
X    }
X
X/*
X    showstr()
X
X    show character's inventory
X */
Xshowstr()
X    {
X    register int i,number;
X    for (number=3, i=0; i<26; i++)
X        if (iven[i]) number++;  /* count items in inventory */
X    t_setup(number);    qshowstr();   t_endup(number);
X    }
X
Xqshowstr()
X    {
X    register int i,j,k,sigsav;
X    srcount=0;  sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
X    if (c[GOLD]) { lprintf(".)   %d gold pieces",(long)c[GOLD]); srcount++; }
X    for (k=25; k>=0; k--)   /* bug fix - dgk */
X/*  for (k=26; k>=0; k--)            */
X      if (iven[k])
X        {  for (i=22; i<84; i++)
X             for (j=0; j<=k; j++)  if (i==iven[j])  show3(j); k=0; }
X
X    lprintf("\nElapsed time is %d.  You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
X    more();     nosignal=sigsav;
X    }
X
X/*
X *  subroutine to clear screen depending on # lines to display
X */
Xt_setup(count)
X    register int count;
X    {
X    if (count<20)  /* how do we clear the screen? */
X        {
X        cl_up(79,count);  cursor(1,1);
X        }
X    else
X        {
X        resetscroll(); clear();
X        }
X    }
X
X/*
X *  subroutine to restore normal display screen depending on t_setup()
X */
Xt_endup(count)
X    register int count;
X    {
X    if (count<18)  /* how did we clear the screen? */
X        draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
X    else
X        {
X        drawscreen(); setscroll();
X        }
X    }
X
X/*
X    function to show the things player is wearing only
X */
Xshowwear()
X    {
X    register int i,j,sigsav,count;
X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
X    srcount=0;
X
X     for (count=2,j=0; j<=26; j++)   /* count number of items we will display */
X       if (i=iven[j])
X        switch(i)
X            {
X            case OLEATHER:  case OPLATE:    case OCHAIN:
X            case ORING:     case OSTUDLEATHER:  case OSPLINT:
X            case OPLATEARMOR:   case OSSPLATE:  case OSHIELD:
X            count++;
X            };
X
X    t_setup(count);
X
X    for (i=22; i<84; i++)
X         for (j=0; j<=26; j++)
X           if (i==iven[j])
X            switch(i)
X                {
X                case OLEATHER:  case OPLATE:    case OCHAIN:
X                case ORING:     case OSTUDLEATHER:  case OSPLINT:
X                case OPLATEARMOR:   case OSSPLATE:  case OSHIELD:
X                show3(j);
X                };
X    more();     nosignal=sigsav;    t_endup(count);
X    }
X
X/*
X    function to show the things player can wield only
X */
Xshowwield()
X    {
X    register int i,j,sigsav,count;
X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
X    srcount=0;
X
X     for (count=2,j=0; j<=26; j++)  /* count how many items */
X       if (i=iven[j])
X        switch(i)
X            {
X            case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
X            case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
X            case OSPIRITSCARAB:  case OCUBEofUNDEAD:
X            case OPOTION:   case OSCROLL:  break;
X            default:  count++;
X            };
X
X    t_setup(count);
X
X    for (i=22; i<84; i++)
X         for (j=0; j<=26; j++)
X           if (i==iven[j])
X            switch(i)
X                {
X                case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
X                case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
X                case OSPIRITSCARAB:  case OCUBEofUNDEAD:
X                case OPOTION:   case OSCROLL:  break;
X                default:  show3(j);
X                };
X    more();     nosignal=sigsav;    t_endup(count);
X    }
X
X/*
X *  function to show the things player can read only
X */
Xshowread()
X    {
X    register int i,j,sigsav,count;
X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
X    srcount=0;
X
X    for (count=2,j=0; j<=26; j++)
X        switch(iven[j])
X            {
X            case OBOOK: case OSCROLL:   count++;
X            };
X    t_setup(count);
X
X    for (i=22; i<84; i++)
X         for (j=0; j<=26; j++)
X           if (i==iven[j])
X            switch(i)
X                {
X                case OBOOK: case OSCROLL:   show3(j);
X                };
X    more();     nosignal=sigsav;    t_endup(count);
X    }
X
X/*
X *  function to show the things player can eat only
X */
Xshoweat()
X    {
X    register int i,j,sigsav,count;
X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
X    srcount=0;
X
X    for (count=2,j=0; j<=26; j++)
X        switch(iven[j])
X            {
X            case OCOOKIE:   count++;
X            };
X    t_setup(count);
X
X    for (i=22; i<84; i++)
X         for (j=0; j<=26; j++)
X           if (i==iven[j])
X            switch(i)
X                {
X                case OCOOKIE:   show3(j);
X                };
X    more();     nosignal=sigsav;    t_endup(count);
X    }
X
X/*
X    function to show the things player can quaff only
X */
Xshowquaff()
X    {
X    register int i,j,sigsav,count;
X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
X    srcount=0;
X
X    for (count=2,j=0; j<=26; j++)
X        switch(iven[j])
X            {
X            case OPOTION:   count++;
X            };
X    t_setup(count);
X
X    for (i=22; i<84; i++)
X         for (j=0; j<=26; j++)
X           if (i==iven[j])
X            switch(i)
X                {
X                case OPOTION:   show3(j);
X                };
X    more();     nosignal=sigsav;        t_endup(count);
X    }
X
Xshow1(idx,str2)
X    register int idx;
X    register char *str2[];
X    {
X        lprc('\n');
X        cltoeoln();
X    if (str2==0)
X        lprintf("%c)   %s",idx+'a',objectname[iven[idx]]);
X    else if (*str2[ivenarg[idx]]==0)
X        lprintf("%c)   %s",idx+'a',objectname[iven[idx]]);
X    else
X        lprintf("%c)   %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]);
X    }
X
Xshow3(index)
X    register int index;
X    {
X    switch(iven[index])
X        {
X        case OPOTION:   show1(index,potionname);  break;
X        case OSCROLL:   show1(index,scrollname);  break;
X
X        case OLARNEYE:      case OBOOK:         case OSPIRITSCARAB:
X        case ODIAMOND:      case ORUBY:         case OCUBEofUNDEAD:
X        case OEMERALD:      case OCHEST:        case OCOOKIE:
X        case OSAPPHIRE:     case ONOTHEFT:      show1(index,(char **)0);  break;
X
X        default:
X        lprc('\n');
X        cltoeoln();
X        lprintf("%c)   %s",index+'a',objectname[iven[index]]);
X        if (ivenarg[index]>0)
X            lprintf(" + %d",(long)ivenarg[index]);
X        else if (ivenarg[index]<0)
X            lprintf(" %d",(long)ivenarg[index]);
X        break;
X        }
X    if (c[WIELD]==index) lprcat(" (weapon in hand)");
X    if ((c[WEAR]==index) || (c[SHIELD]==index))  lprcat(" (being worn)");
X    if (++srcount>=22) { srcount=0; more(); clear(); }
X    }
X
X/*
X    subroutine to randomly create monsters if needed
X */
Xrandmonst()
X    {
X    if (c[TIMESTOP]) return;    /*  don't make monsters if time is stopped  */
X    if (--rmst <= 0)
X        {
X        rmst = 120 - (level<<2);  fillmonst(makemonst(level));
X        }
X    }
X
X
X/*
X    parse()
X
X    get and execute a command
X */
Xparse()
X    {
X    register int i,j,k,flag;
X
X    while   (1)
X        {
X        k = yylex();
X        switch(k)   /*  get the token from the input and switch on it   */
X            {
X            case 'h':   moveplayer(4);  return;     /*  west        */
X            case 'H':   run(4);         return;     /*  west        */
X            case 'l':   moveplayer(2);  return;     /*  east        */
X            case 'L':   run(2);         return;     /*  east        */
X            case 'j':   moveplayer(1);  return;     /*  south       */
X            case 'J':   run(1);         return;     /*  south       */
X            case 'k':   moveplayer(3);  return;     /*  north       */
X            case 'K':   run(3);         return;     /*  north       */
X            case 'u':   moveplayer(5);  return;     /*  northeast   */
X            case 'U':   run(5);         return;     /*  northeast   */
X            case 'y':   moveplayer(6);  return;     /*  northwest   */
X            case 'Y':   run(6);         return;     /*  northwest   */
X            case 'n':   moveplayer(7);  return;     /*  southeast   */
X            case 'N':   run(7);         return;     /*  southeast   */
X            case 'b':   moveplayer(8);  return;     /*  southwest   */
X            case 'B':   run(8);         return;     /*  southwest   */
X
X            case '.':                               /*  stay here       */
X                if (yrepcount) viewflag=1;
X                return; 
X
X            case 'c':
X                yrepcount=0;    
X                cast();     
X                return;     /*  cast a spell    */
X
X            case 'd':
X                yrepcount=0;
X                if (c[TIMESTOP]==0)
X                    dropobj();
X                return; /*  to drop an object   */
X
X            case 'e':
X                yrepcount=0;
X                if (c[TIMESTOP]==0) 
X                    eatcookie(); 
X                return; /*  to eat a fortune cookie */
X
X            case 'g':   
X                yrepcount = 0 ;
X                cursors();
X                lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
X                break ;
X
X            case 'i':
X                yrepcount=0;    
X                nomove=1;  
X                showstr();  
X                return;     /*  status      */
X
X        case 'p':           /* pray at an altar */
X        yrepcount = 0;
X        if (!prompt_mode)
X            pray_at_altar();
X        else
X            nomove = 1;
X        return;
X
X            case 'q':           /* quaff a potion */
X                yrepcount=0;
X                if (c[TIMESTOP]==0)
X                    quaff();
X                return; 
X
X            case 'r':
X                yrepcount=0;
X                if (c[BLINDCOUNT])
X                    { 
X                    cursors(); 
X                    lprcat("\nYou can't read anything when you're blind!");
X                    }
X                else if (c[TIMESTOP]==0)
X                    readscr();
X                return;     /*  to read a scroll    */
X
X            case 's':
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    sit_on_throne();
X        else
X            nomove = 1;
X                return ;
X
X            case 't':                       /* Tidy up at fountain */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    wash_fountain() ;
X        else
X            nomove = 1;
X                return ;
X
X            case 'v':   
X        yrepcount=0;    
X        cursors();
X                lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]);
X                if (wizard) lprcat(" Wizard"); nomove=1;
X                if (cheat) lprcat(" Cheater");
X                lprcat(copyright);
X                return;
X
X            case 'w':                       /*  wield a weapon */
X                yrepcount=0;
X                wield();
X                return;
X
X        case 'A':
X        yrepcount = 0;
X        if (!prompt_mode)
X            desecrate_altar();
X        else
X            nomove = 1;
X        return;
X
X            case 'C':                       /* Close something */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    close_something();
X        else
X            nomove = 1;
X                return;
X
X            case 'D':                       /* Drink at fountain */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    drink_fountain() ;
X        else
X            nomove = 1;
X                return ;
X
X            case 'E':               /* Enter a building */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    enter() ;
X        else
X            nomove = 1;
X                break ;
X
X            case 'G':               /* Give the stairs a kick */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    kick_stairs();
X        else
X            nomove = 1;
X                return ;
X
X            case 'I':              /*  list spells and scrolls */
X                yrepcount=0;
X                seemagic(0);
X                nomove=1;
X                return;
X
X            case 'O':               /* Open something */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    open_something();
X        else
X            nomove = 1;
X                return;
X
X            case 'P':   
X        cursors();
X                if (outstanding_taxes>0)
X                    lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
X                else
X                    lprcat("\nYou do not owe any taxes.");
X                return;
X
X            case 'Q':    /*  quit        */
X        yrepcount=0;
X        quit(); 
X        nomove=1;   
X        return;
X
X            case 'R' :          /* remove gems from a throne */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    remove_gems( );
X        else
X            nomove = 1;
X                return ;
X
X# ifdef DGK_MSDOS
X            case 'S':
X                /* Set up error recovery
X                 */
X                if (setjmp(save_jbuf) != 0) {
X
X                    /* can't use lwclose!
X                     */
X                    if (lfd > 2)
X                        close(lfd);
X                    lcreat(NULL);
X                    setscroll();
X                    cursors();
X                    lprcat("\nSave failed !\n");
X                    if (errno == ENOSPC)
X                        lprcat("Disk is full !\n");
X                    beep();
X                    (void) unlink(savefilename);
X                    save_mode = 0;
X                    yrepcount = 0;
X                    nomove = 1;
X                    break;
X                }
X
X                /* And do the save.
X                 */
X                cursors();
X                lprintf("\nSaving to `%s' . . . ", savefilename);
X                lflush();
X                save_mode = 1;
X                savegame(savefilename);
X                clear();
X                lflush();
X                wizard=1;
X                died(-257); /* doesn't return */
X                break;
X# else
X            case 'S':   clear();  lprcat("Saving . . ."); lflush();  
X                        savegame(savefilename); wizard=1; died(-257);   /*  save the game - doesn't return  */
X# endif DGK_MSDOS
X
X            case 'T':   yrepcount=0;    cursors();  if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
X                                        if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
X                        else lprcat("\nYou aren't wearing anything");
X                        return;
X
X            case 'W':
X                yrepcount=0;
X                wear();
X                return; /*  wear armor  */
X
X            case 'Z':   
X                yrepcount=0;
X                if (c[LEVEL]>9) 
X                    { 
X                    oteleport(1);
X                    return; 
X                    }
X                cursors(); 
X                lprcat("\nAs yet, you don't have enough experience to use teleportation");
X                return; /*  teleport yourself   */
X
X            case ' ':   yrepcount=0;    nomove=1;  return;
X
X# ifdef DGK_MSDOS
X            case 'V':
X                yrepcount = 0;
X                nomove = 1;
X                cursors();
X                lprcat("\nMSDOS version 12a by Don Kneller, Berkeley CA.\n");
X                lprcat("Version 12.1 by Kevin Routley\n");
X                return;
X
X            case 'D'-64:
X                yrepcount = 0;
X                nomove = 1;
X                levelinfo();
X                return;
X# endif
X
X            case 'L'-64:  yrepcount=0;  drawscreen();  nomove=1; return;    /*  look        */
X
X#if WIZID
X#ifdef EXTRA
X            case 'A'-64:    yrepcount=0;    nomove=1; if (wizard) { diag(); return; }  /*   create diagnostic file */
X                        return;
X#endif
X#endif
X            case '<':                       /* Go up stairs or vol shaft */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    up_stairs();
X        else
X            nomove = 1;
X                return ;
X
X            case '>':                       /* Go down stairs or vol shaft*/
X                yrepcount = 0 ;
X                if (!prompt_mode)
X                    down_stairs();
X        else
X            nomove = 1;
X                return ;
X
X            case '?':                       /* give the help screen */
X                yrepcount=0;    
X                help(); 
X                nomove=1;
X                return; 
X
X        case ',':                       /* pick up an item */
X            yrepcount = 0 ;
X            if (!prompt_mode)
X            /* pickup, don't identify or prompt for action */
X            lookforobject( FALSE, TRUE, FALSE );
X        else
X            nomove = 1;
X        return;
X
X            case ':':                       /* look at object */
X                yrepcount = 0 ;
X                if (!prompt_mode)
X		    /* identify, don't pick up or prompt for action */
X                    lookforobject( TRUE, FALSE, FALSE );
X                nomove = 1;  /* assumes look takes no time */
X                return;
X
X	    case '@':		/* toggle auto-pickup */
X		yrepcount = 0 ;
X		nomove = 1;
X		cursors();
X		lprcat("\nAuto pickup: ");
X		auto_pickup = !auto_pickup;
X		if (auto_pickup)
X		    lprcat("On.");
X		else
X		    lprcat("Off.");
X		return;
X
X	    case '^':                       /* identify traps */
X                flag = yrepcount = 0;
X                cursors();
X                lprc('\n');
X                for (j=playery-1; j<playery+2; j++)
X                    {
X                    if (j < 0) 
X                        j=0;        
X                    if (j >= MAXY)
X                        break;
X                    for (i=playerx-1; i<playerx+2; i++)
X                        {
X                        if (i < 0) 
X                            i=0;
X                        if (i >= MAXX) 
X                            break;
X                        switch(item[i][j])
X                            {
X                            case OTRAPDOOR:     case ODARTRAP:
X                            case OTRAPARROW:    case OTELEPORTER:
X                            case OPIT:
X                                lprcat("\nIts ");
X                                lprcat(objectname[item[i][j]]);  
X                                flag++;
X                            };
X                        }
X                    }
X                if (flag==0) 
X                    lprcat("\nNo traps are visible");
X                return;
X
X#if WIZID
X            case '_':   /*  this is the fudge player password for wizard mode*/
X                        yrepcount=0;    cursors(); nomove=1;
X# ifndef MSDOS
X                        if (userid!=wisid)
X                            {
X                            lprcat("Sorry, you are not empowered to be a wizard.\n");
X                            scbr(); /* system("stty -echo cbreak"); */
X                            lflush();  return;
X                            }
X# endif
X                        if (getpassword()==0)
X                            {
X                            scbr(); /* system("stty -echo cbreak"); */ return;
X                            }
X                        wizard=1;  scbr(); /* system("stty -echo cbreak"); */
X                        for (i=0; i<6; i++)  c[i]=70;  iven[0]=iven[1]=0;
X                        take(OPROTRING,50);   take(OLANCE,25);  c[WIELD]=1;
X                        c[LANCEDEATH]=1;   c[WEAR] = c[SHIELD] = -1;
X                        raiseexperience(6000000L);  c[AWARENESS] += 25000;
X                        {
X                        register int i,j;
X                        for (i=0; i<MAXY; i++)
X                            for (j=0; j<MAXX; j++)  know[j][i]=KNOWALL;
X                        for (i=0; i<SPNUM; i++) spelknow[i]=1;
X                        for (i=0; i<MAXSCROLL; i++)  scrollname[i][0]=' ';
X                        for (i=0; i<MAXPOTION; i++)  potionname[i][0]=' ';
X                        }
X                        for (i=0; i<MAXSCROLL; i++)
X                          if (strlen(scrollname[i])>2) /* no null items */
X                            { item[i][0]=OSCROLL; iarg[i][0]=i; }
X                        for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
X                          if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
X                            { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
X                        for (i=1; i<MAXY; i++)
X                            { item[0][i]=i; iarg[0][i]=0; }
X                        for (i=MAXY; i<MAXY+MAXX; i++)
X                            { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
X			for (i=MAXX+MAXY; i<MAXOBJECT; i++)
X			    {
X			    item[MAXX-1][i-MAXX-MAXY]=i;
X			    iarg[MAXX-1][i-MAXX-MAXY]=0;
X			    }
X                        c[GOLD]+=250000;    drawscreen();   return;
X#endif
X
X            };
X        }
X    }
X
Xparse2()
X    {
X    if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters       */
X    randmonst();    regen();
X    }
X
Xrun(dir)
X    int dir;
X    {
X    register int i;
X    i=1; while (i)
X        {
X        i=moveplayer(dir);
X        if (i>0) {  if (c[HASTEMONST]) movemonst();  movemonst(); randmonst(); regen(); }
X        if (hitflag) i=0;
X        if (i!=0)  showcell(playerx,playery);
X        }
X    }
X
X/*
X    function to wield a weapon
X */
Xwield()
X    {
X    register int i;
X    while (1)
X        {
X	if ((i = whatitem("wield (- for nothing)"))=='\33')  return;
X        if (i != '.')
X            {
X            if (i=='*') showwield();
X	    else if ( i == '-' ) { c[WIELD] = -1 ; return; }
X	    else if (iven[i-'a']==0) { ydhi(i); return; }
X            else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
X            else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
X            else  if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; }
X            else  { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0;  bottomline(); return; }
X            }
X        }
X    }
X
X/*
X    common routine to say you don't have an item
X */
Xydhi(x)
X    int x;
X    { cursors();  lprintf("\nYou don't have item %c!",x); }
Xycwi(x)
X    int x;
X    { cursors();  lprintf("\nYou can't wield item %c!",x); }
X
X/*
X    function to wear armor
X */
Xwear()
X    {
X    register int i;
X    while (1)
X        {
X        if ((i = whatitem("wear"))=='\33')  return;
X	if (i != '.' && i != '-')
X            {
X            if (i=='*') showwear(); else
X            switch(iven[i-'a'])
X                {
X                case 0:  ydhi(i); return;
X                case OLEATHER:  case OCHAIN:  case OPLATE:  case OSTUDLEATHER:
X                case ORING:     case OSPLINT:   case OPLATEARMOR:   case OSSPLATE:
X                        if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
X                            c[WEAR]=i-'a';  bottomline(); return;
X                case OSHIELD:   if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
X                                if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
X                                c[SHIELD] = i-'a';  bottomline(); return;
X                default:    lprcat("\nYou can't wear that!");
X                };
X            }
X        }
X    }
X
X/*
X    function to drop an object
X */
Xdropobj()
X    {
X    register int i;
X    register char *p;
X    long amt;
X    p = &item[playerx][playery];
X    while (1)
X        {
X        if ((i = whatitem("drop"))=='\33')  return;
X	if (i=='*') showstr();
X	else if ( i != '-' )
X            {
X            if (i=='.') /* drop some gold */
X                {
X                if (*p) { lprcat("\nThere's something here already!"); return; }
X                lprcat("\n\n");
X                cl_dn(1,23);
X                lprcat("How much gold do you drop? ");
X                if ((amt=readnum((long)c[GOLD])) == 0) return;
X                if (amt>c[GOLD])
X                    {
X#ifdef VMS
X            lprcat("You don't have that much!");
X#else
X            lprcat("\nYou don't have that much!");
X#endif VMS
X            return; }
X                if (amt<=32767)
X                    { *p=OGOLDPILE; i=amt; }
X                else if (amt<=327670L)
X                    { *p=ODGOLD; i=amt/10; amt = 10L*i; }
X                else if (amt<=3276700L)
X                    { *p=OMAXGOLD; i=amt/100; amt = 100L*i; }
X                else if (amt<=32767000L)
X                    { *p=OKGOLD; i=amt/1000; amt = 1000L*i; }
X                else
X                    { *p=OKGOLD; i=32767; amt = 32767000L; }
X                c[GOLD] -= amt;
X#ifdef VMS
X                lprintf("You drop %d gold pieces",(long)amt);
X#else
X                lprintf("\nYou drop %d gold pieces",(long)amt);
X#endif VMS
X                iarg[playerx][playery]=i; bottomgold();
X                know[playerx][playery]=0; dropflag=1;  return;
X                }
X            drop_object(i-'a');
X            return;
X            }
X        }
X    }
X
X/*
X    readscr(), eatcookie(), quaff() could all be common code
X*/
X/*
X *  readscr()       Subroutine to read a scroll one is carrying
X */
Xreadscr()
X    {
X    register int i;
X    char tempc;
X
X    /* check for player standing on a book/scroll.  If he is, prompt for
X       and let him read it.  If player ESCs from prompt, quit the Read
X       command.
X    */
X    cursors();
X    i = item[playerx][playery];
X    if ((i == OSCROLL) ||
X        (i == OBOOK))
X        {
X        lprintf("\nThere is %s", objectname[i]); 
X        if (i==OSCROLL)
X            if (scrollname[iarg[playerx][playery]][0] != 0 )
X                lprintf(" of%s", scrollname[iarg[playerx][playery]] );
X        lprcat(" here.  Read it?");
X        if ((tempc = getyn()) == 'y')
X            {
X        if (i==OBOOK)
X                readbook( iarg[playerx][playery] );
X        else
X        read_scroll( iarg[playerx][playery] );
X        forget();
X            return;
X            }
X        else if (tempc != 'n' )
X            return;
X        }
X
X    while (1)
X        {
X        if ((i = whatitem("read"))=='\33')  return;
X	if (i != '.' && i != '-')
X            {
X            if (i=='*') showread(); else
X                {
X                if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
X                if (iven[i-'a']==OBOOK)   { readbook(ivenarg[i-'a']);  iven[i-'a']=0; return; }
X                if (iven[i-'a']==0) { ydhi(i); return; }
X                lprcat("\nThere's nothing on it to read");  return;
X                }
X            }
X        }
X    }
X
X/*
X *  subroutine to eat a cookie one is carrying
X */
Xeatcookie()
X{
Xregister int i;
Xchar *p;
Xwhile (1)
X    {
X    char tempc;
X
X    /* check for player standing on a cookie.  If he is, prompt for 
X       and let him eat it.  If player ESCs from prompt, quit the Eat
X       command.
X    */
X    cursors();
X    i = item[playerx][playery];
X    if (i == OCOOKIE)
X        {
X        lprcat("\nThere is a fortune cookie here.  Eat it?");
X        if ((tempc = getyn()) == 'y')
X            {
X/* THIS COULD BE COMMON CODE !!! */
X            lprcat("\nThe cookie was delicious.");
X        forget();
X            if (!c[BLINDCOUNT])
X                {
X# ifdef MSDOS
X                outfortune();
X# else
X                if (p=fortune(fortfile))
X                    {
X                    lprcat("  Inside you find a scrap of paper that says:\n");
X                    lprcat(p);
X                    }
X# endif
X        }
X            return;
X            }
X        else if (tempc != 'n' )
X            return;
X        }
X
X    if ((i = whatitem("eat"))=='\33')  return;
X    if (i != '.' && i != '-' )
X        if (i=='*') showeat(); else
X            {
X            if (iven[i-'a']==OCOOKIE)
X                {
X                lprcat("\nThe cookie was delicious.");
X                iven[i-'a']=0;
X                if (!c[BLINDCOUNT])
X                    {
X# ifdef MSDOS
X                    outfortune();
X# else
X                    if (p=fortune(fortfile))
X                        {
X                        lprcat("  Inside you find a scrap of paper that says:\n");
X                        lprcat(p);
X                        }
X# endif
X                    }
X                return;
X                }
X            if (iven[i-'a']==0) { ydhi(i); return; }
X            lprcat("\nYou can't eat that!");  return;
X            }
X    }
X}
X
X/*
X *  subroutine to quaff a potion one is carrying
X */
Xquaff()
X    {
X    register int i;
X    char tempc;
X
X    /* check for player standing on a potion.  If he is, prompt for
X       and let him quaff it.  If player ESCs from prompt, quit the Quaff
X       command.
X    */
X    cursors();
X    i = item[playerx][playery];
X    if (i == OPOTION)
X        {
X        lprintf("\nThere is %s", objectname[i]); 
X        if (potionname[iarg[playerx][playery]][0] != 0 )
X            lprintf(" of%s", potionname[iarg[playerx][playery]] );
X        lprcat(" here.  Quaff it?");
X        if ((tempc = getyn()) == 'y')
X            {
X        quaffpotion( iarg[playerx][playery] );
X        forget();
X            return;
X            }
X        else if (tempc != 'n' )
X            return;
X        }
X
X    while (1)
X        {
X        if ((i = whatitem("quaff"))=='\33')
X            return;
X	if (i != '.' && i != '-' )
X            {
X            if (i=='*')
X                showquaff();
X            else
X                {
X                if (iven[i-'a']==OPOTION)
X                    {
X                    quaffpotion(ivenarg[i-'a'], TRUE);
X                    iven[i-'a']=0;
X                    return;
X                    }
X                if (iven[i-'a']==0) 
X                    { 
X                    ydhi(i); 
X                    return;
X                    }
X                lprcat("\nYou wouldn't want to quaff that, would you? ");
X                return;
X                }
X            }
X        }
X    }
X
X/*
X    function to ask what player wants to do
X */
Xstatic whatitem(str)
X    char *str;
X    {
X    int i;
X    cursors();  lprintf("\nWhat do you want to %s [* for all] ? ",str);
X    i=0; while (i>'z' || (i<'a' && i!='-' && i!='*' && i!='\33' && i!='.'))
X	i=ttgetch();
X    if (i=='\33')  lprcat(" aborted");
X    return(i);
X    }
X
X/*
X    subroutine to get a number from the player
X    and allow * to mean return amt, else return the number entered
X */
Xunsigned long readnum(mx)
X    long mx;
X    {
X    register int i;
X    register unsigned long amt=0;
X
X    sncbr();
X    /* allow him to say * for all gold 
X    */
X    if ((i=ttgetch()) == '*')
X        amt = mx;
X    else
X        /* read chars into buffer, deleting when requested */
X    while (i != '\n')
X            {
X        if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
X        if ((i <= '9') && (i >= '0') && (amt<999999999))
X            amt = amt*10+i-'0';
X        if ((i=='\010') || (i=='\177'))
X            amt = (long)(amt / 10) ;
X        i = ttgetch();
X        }
X    scbr();  
X    return(amt);
X    }
X
X#ifdef HIDEBYLINK
X/*
X *  routine to zero every byte in a string
X */
Xszero(str)
X    register char *str;
X    {
X    while (*str)
X        *str++ = 0;
X    }
X#endif HIDEBYLINK
X
X#ifdef TIMECHECK
X/*
X *  routine to check the time of day and return 1 if its during work hours
X *  checks the file ".holidays" for forms like "mmm dd comment..."
X */
Xint playable()
X    {
X    long g_time,time();
X    int hour,day,year;
X    char *date,*month,*p;
X
X    time(&g_time);  /* get the time and date */
X    date = ctime(&g_time); /* format: Fri Jul  4 00:27:56 EDT 1986 */
X    year = atoi(date+20);
X    hour = (date[11]-'0')*10 + date[12]-'0';
X    day  = (date[8]!=' ') ? ((date[8]-'0')*10 + date[9]-'0') : (date[9]-'0');
X    month = date+4;  date[7]=0; /* point to and NULL terminate month */
X
X    if (((hour>=8 && hour<17)) /* 8AM - 5PM */
X        && strncmp("Sat",date,3)!=0     /* not a Saturday */
X        && strncmp("Sun",date,3)!=0)    /* not a Sunday */
X            {
X        /* now check for a .holidays datafile */
X            lflush();
X            if (lopen(holifile) >= 0)
X                for ( ; ; )
X                    {
X                    if ((p=lgetw())==0) break;
X                    if (strlen(p)<6) continue;
X                    if ((strncmp(p,month,3)==0) && (day==atoi(p+4)) && (year==atoi(p+7)))
X                        return(0); /* a holiday */
X                    }
X            lrclose();  lcreat((char*)0);
X            return(1);
X            }
X    return(0);
X    }
X#endif TIMECHECK
END_OF_FILE
if test 45396 -ne `wc -c <'main.c'`; then
    echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
echo shar: End of archive 1 \(of 11\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0