[ includes uuencoded help file, screen, and nansi.sys (for msdos, I suppose),
but does not include an executable ...tad ]
V12.2 Ported to the amiga by Simon J Raybould in Dec 1990
V12.3 re-port done 28th April 1991.
I still haven't got round to doing shell escape!!
Any amiga specific problems to 's...@fulcrum.bt.co.uk'.
This code has been compiled with SAS C V5.10
Have fun
Sie.
LARN is a dungeon type adventure game similar in concept to HACK, ROGUE
or MORIA, but with a different feel and winning criteria. LARN was
released for the UNIX environment in 1986 by Noah Morgan. It was
subsequently ported to the MS-DOS environment by Don Kneller. Kevin
Routley has been working on enhancements to LARN on and off for the
past two years.
#!/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 17)."
# Contents: AmigaReadMe MANIFEST Makefile.unix POSTER README
# adoslarn.lnk amiga.mk config.c descrip.mms fgetlr.c help.c
# larn.ftn larn.opt larn.pid larn.scr.uu makefile.os2 monsters.h
# nansi.sys.uu nap.c objects.h os2larn.def os2larn.lnk patchlev.h
# player.h termcap.pc tlink.rsp vmsreadme.txt
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:52 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'AmigaReadMe' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'AmigaReadMe'\"
else
echo shar: Extracting \"'AmigaReadMe'\" \(318 characters\)
sed "s/^X//" >'AmigaReadMe' <<'END_OF_FILE'
XV12.2 Ported to the amiga by Simon J Raybould in Dec 1990
X
XV12.3 re-port done 28th April 1991.
X
XI still haven't got round to doing shell escape!!
X
XAny amiga specific problems to 's...@fulcrum.bt.co.uk'.
X
XAny general larn bugs to wherever the main docs say.
X
XThis code has been compiled with SAS C V5.10
X
XHave fun
X
XSie.
END_OF_FILE
if test 318 -ne `wc -c <'AmigaReadMe'`; then
echo shar: \"'AmigaReadMe'\" unpacked with wrong size!
fi
# end of 'AmigaReadMe'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(2692 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X File Name Archive # Description
X-----------------------------------------------------------
X MANIFEST 1 This shipping list
X Makefile.unix 2 Makefile for U*ix.
X README 1 General readme
X action.c 9
X bill.c 8
X config.c 12
X create.c 8
X data.c 4
X descrip.mms 12 MMS build file for VAX/VMS
X diag.c 9
X display.c 5
X fgetlr.c 12 Termcap support for VMS/MS-DOS.
X fortune.c 10
X global.c 2
X header.h 12
X help.c 12
X io.c 3
X iventory.c 10
X larn.ftn 12 Fortune File
X larn.maz 7 Maze file
X larn.opt 12 Sample options file. Rename to .larnopts for U*ix.
X larn123.doc 7 Documentation for Larn V12.3
X larn123.fix 11 List of changes since Larn V12.0
X larndefs.h 12
X larnhlp.txt 9 Help file without ansi escape sequences
X larnhlp.uue 10 Uuencoded help file with ansi escape sequences
X main.c 1
X makefile.os2 12 OS/2-Microsoft C Makefile
X makefile.pc 11 MS-DOS, Turbo C++ Makefile
X monster.c 6
X monsters.h 9
X moreobj.c 3
X movem.c 4
X msdos.c 10 MS-DOS Specific code.
X nansi.doc 11 Docs for NANSI.SYS, a MS-DOS ANSI.SYS replacement
X nansisys.uue 12 UUENCODED NANSI.SYS
X nap.c 12
X object.c 2
X objects.h 12
X os2larn.def 5 OS/2 Build support
X os2larn.lnk 4 OS/2 Build support
X patchlev.h 3
X player.h 12
X regen.c 11
X savelev.c 12
X scores.c 8
X signal.c 11
X spells.c 6
X spheres.c 11
X store.c 5
X termcap.pc 5 Termcap file for MS-DOS.
X termcap.vms 12 Termcap file for VMS.
X tgetent.c 10 Termcap support for VMS/MS-DOS.
X tgetstr.c 11 Termcap support for VMS/MS-DOS.
X tgoto.c 1 Termcap support for VMS/MS-DOS.
X tlink.rsp 4 Turbo C++ MS-DOS Build support
X tok.c 9
X tputs.c 7 Termcap support for VMS/MS-DOS.
X vms.c 11 VMS Specific code.
X vmsreadme.txt 6 VMS Specific Readme
END_OF_FILE
if test 2692 -ne `wc -c <'MANIFEST'`; then
echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile.unix' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile.unix'\"
else
echo shar: Extracting \"'Makefile.unix'\" \(589 characters\)
sed "s/^X//" >'Makefile.unix' <<'END_OF_FILE'
X#
XOBJ= action.o bill.o config.o create.o data.o diag.o display.o \
X fortune.o global.o help.o io.o iventory.o main.o monster.o \
X moreobj.o movem.o msdos.o nap.o object.o regen.o savelev.o \
X scores.o signal.o spells.o spheres.o store.o \
X tok.o vms.o
X#
X#
X
X# Add -DSIG_RTNS_INT to the CFLAGS line for older Unixes that return
X# int ptr rather than void ptr from the call to signal().
X#
XCFLAGS= -DBSD -D'LARNHOME="/usr/users/routley/larncc/"'
X
Xlarn123: $(OBJ)
X cc -o larn123 $(OBJ) -ltermcap
X
X.c.o:
X cc $(CFLAGS) -c $*.c
X
X.c: header.h larndefs.h player.h monsters.h objects.h patchlev.h
X
END_OF_FILE
if test 589 -ne `wc -c <'Makefile.unix'`; then
echo shar: \"'Makefile.unix'\" unpacked with wrong size!
fi
# end of 'Makefile.unix'
fi
if test -f 'POSTER' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'POSTER'\"
else
echo shar: Extracting \"'POSTER'\" \(515 characters\)
sed "s/^X//" >'POSTER' <<'END_OF_FILE'
XFrom: bi...@saab.CNA.TEK.COM (Bill Randle)
XNewsgroups: comp.sources.games
XSubject: v12i054: larn2 - dungeon type adventure game (V12.3), Part01/12
XDate: 23 Apr 91 20:56:39 GMT
X
XSubmitted-by: rou...@tle.ENET.DEC.COM (Kevin Routley)
XPosting-number: Volume 12, Issue 54
XArchive-name: larn2/Part01
XSupersedes: larn: Volume 11, Issue 84-94
XEnvironment: Unix, VMS, MS-DOS, OS/2, termcap
X
X [This is an update of the larn game posted earlier. This
X includes patches, enhancements and additional support for
X OS/2. -br]
X
END_OF_FILE
if test 515 -ne `wc -c <'POSTER'`; then
echo shar: \"'POSTER'\" unpacked with wrong size!
fi
# end of 'POSTER'
fi
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1841 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
XHere is the source to Larn V12.3. I had made a number of changes without
Xchanging the save file format, so I decided to make another distribution
Xbefore making the big leap to V14.0.
X
XThis distribution incorporates all the changes distributed as Patches to V12.2,
Xa few others that were suggested but not sent out as patches, plus my own
Xdevelopment. See LARN123.FIX for a partial list.
X
XThe source correctly compiles and executes under DEC Ultrix (BSD), using the cc
Xcompiler. The enclosed makefile.unix is for U*ix systems (rename to Makefile).
XI've endevoured to make Larn buildable under SYSV, and it builds/runs correctly
Xwith Ultrix V3.1's SYSTEM_FIVE environment, so I expect its fairly close to
Xbeing usable under SYSV as well.
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.
XSee the VMSREADME.TXT for some more VMS-related information.
X
XThe source correctly compiles and executes under MS-DOS, using Turbo C++ V1.0.
XI am no longer able to verify that it compiles using Turbo C V2.0. The
Xmakefile.pc and tlink.rsp are for building the MS-DOS Larn.
X
XThe source correctly compiles and executes under OS/2, using Microsoft C.
XThe makefile.os2, os2larn.def and os2larn.lnk are for building the OS/2 Larn.
X
XI am interested in receiving source changes that allow Larn to be ported or
Xbuilt correctly on other architectures or operating systems. I am also
Xinterested in constructive changes or additions to improve the game.
X
XBug fixes, bug reports, and requests welcome.
X
XI am reachable at tle.enet.dec.com!routley or rou...@tle.enet.dec.com.
XBecause I cannot provide a stable mail address, all USmail should be sent to:
X
XKevin Routley
XDigital Equipment Corporation
XZKO2-3/N30
X110 Spitbrook Road
XNashua, NH 03060
X
END_OF_FILE
if test 1841 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'adoslarn.lnk' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'adoslarn.lnk'\"
else
echo shar: Extracting \"'adoslarn.lnk'\" \(315 characters\)
sed "s/^X//" >'adoslarn.lnk' <<'END_OF_FILE'
XFROM
XLIB:c.o
Xaction.o amiga.o bill.o config.o create.o data.o diag.o display.o
Xiventory.o fortune.o global.o help.o io.o main.o monster.o
Xmoreobj.o movem.o msdos.o nap.o object.o regen.o savelev.o
Xscores.o signal.o spells.o spheres.o store.o tok.o vms.o
XTO larn
XLIB LIB:termlib.lib LIB:lc.lib LIB:amiga.lib
XVERBOSE
END_OF_FILE
if test 315 -ne `wc -c <'adoslarn.lnk'`; then
echo shar: \"'adoslarn.lnk'\" unpacked with wrong size!
fi
# end of 'adoslarn.lnk'
fi
if test -f 'amiga.mk' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'amiga.mk'\"
else
echo shar: Extracting \"'amiga.mk'\" \(362 characters\)
sed "s/^X//" >'amiga.mk' <<'END_OF_FILE'
XCC= lc
XCFLAGS= -ba -cw -dDGK
X
X#
XOBJ= action.o amiga.o bill.o config.o create.o data.o diag.o display.o \
X iventory.o fortune.o global.o help.o io.o main.o monster.o \
X moreobj.o movem.o msdos.o nap.o object.o regen.o savelev.o \
X scores.o signal.o spells.o spheres.o store.o \
X tok.o vms.o
X#
X#
X
X
Xlarn: $(OBJ)
X blink with adoslarn.lnk
X
Xclean:
X -delete \#?.o TAGS
END_OF_FILE
if test 362 -ne `wc -c <'amiga.mk'`; then
echo shar: \"'amiga.mk'\" unpacked with wrong size!
fi
# end of 'amiga.mk'
fi
if test -f 'config.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'config.c'\"
else
echo shar: Extracting \"'config.c'\" \(2916 characters\)
sed "s/^X//" >'config.c' <<'END_OF_FILE'
X/*
X * config.c -- This defines the installation dependent variables.
X * Some strings are modified later. ANSI C would
X * allow compile time string concatenation, we must
X * do runtime concatenation, in main.
X */
X#include "header.h"
X#include "larndefs.h"
X
X#ifndef LARNHOME
X#define LARNHOME "/usr/games/larn/" /* normally supplied by a Makefile */
X#endif
X
X#ifndef WIZID
X#define WIZID 0
X#endif
X
X/*
X * All these strings will be appended to in main() to be complete filenames
X */
X
X# ifndef MSDOS
X /* the game save filename */
Xchar savefilename[SAVEFILENAMESIZE] = LARNHOME;
X
X /* the score file */
Xchar scorefile[sizeof(LARNHOME)+sizeof(SCORENAME)] = LARNHOME;
X
X /* the logging file */
Xchar logfile[sizeof(LARNHOME)+sizeof(LOGFNAME)] = LARNHOME;
X
X /* the help text file */
Xchar helpfile[sizeof(LARNHOME)+sizeof(HELPNAME)] = LARNHOME;
X
X /* the maze data file */
Xchar larnlevels[sizeof(LARNHOME)+sizeof(LEVELSNAME)] = LARNHOME;
X
X /* the fortune data file */
Xchar fortfile[sizeof(LARNHOME)+sizeof(FORTSNAME)] = LARNHOME;
X
X /* the .larnopts filename */
Xchar optsfile[128]; /* the option file */
X
X /* the player id datafile name */
Xchar playerids[sizeof(LARNHOME)+sizeof(PLAYERIDS)] = LARNHOME;
X
X# ifdef TIMECHECK
X /* the holiday datafile */
Xchar holifile[sizeof(LARNHOME)+sizeof(HOLIFILE)] = LARNHOME;
X# endif
X
Xchar ckpfile[sizeof(LARNHOME)+sizeof(CKPFILE)] = LARNHOME;
X
X# ifdef EXTRA
Xchar diagfile[] ="Diagfile"; /* the diagnostic filename */
X# endif
X
X# else /* ndef MSDOS */
X
X/* For MSDOS, use fixed length files because of a bug in sizeof.
X */
X# ifdef MSDOS
X/* Make LARNHOME readable from the larnopt file into a lardir variable.
X */
Xchar savefilename[PATHLEN];
Xchar scorefile[PATHLEN];
Xchar logfile[PATHLEN];
Xchar helpfile[PATHLEN];
Xchar larnlevels[PATHLEN];
Xchar fortfile[PATHLEN];
Xchar optsfile[PATHLEN];
Xchar playerids[PATHLEN];
Xchar ckpfile[PATHLEN];
Xchar swapfile[PATHLEN];
Xchar larndir[DIRLEN] = LARNHOME;
X# else
Xchar savefilename[PATHLEN] = LARNHOME;
Xchar scorefile[PATHLEN] = LARNHOME;
Xchar logfile[PATHLEN] = LARNHOME;
Xchar helpfile[PATHLEN] = LARNHOME;
Xchar larnlevels[PATHLEN] = LARNHOME;
Xchar fortfile[PATHLEN] = LARNHOME;
Xchar optsfile[PATHLEN] = LARNHOME;
Xchar playerids[PATHLEN] = LARNHOME;
Xchar swapfile[PATHLEN] = LARNHOME;
Xchar ckpfile[PATHLEN] = LARNHOME;
X# endif
X# endif /* ndef MSDOS */
X
Xchar *password ="pvnert(x)"; /* the wizards password <=32*/
X#ifndef MSDOS
X#if WIZID == -1
Xint wisid=0; /* the user id of the only person who can be wizard */
X#else
Xint wisid=WIZID; /* the user id of the only person who can be wizard */
X#endif
Xchar psname[PSNAMESIZE]="larn"; /* the process name */
X#endif MSDOS
END_OF_FILE
if test 2916 -ne `wc -c <'config.c'`; then
echo shar: \"'config.c'\" unpacked with wrong size!
fi
# end of 'config.c'
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'\" \(1809 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 SPELLS.C, SPHERES.C, IVENTORY.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, SPELLS.OBJ, SPHERES.OBJ, IVENTORY.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, SPELLS.DBJ, SPHERES.DBJ, IVENTORY.DBJ
X
XCDEFS = /DEFINE=(LARNHOME="""larndir:""")
X
X.SUFFIXES
X.SUFFIXES .OBJ .DBJ .C
X
XLARN.EXE : $(OBJECTS) vaxcrtl.opt
X LINK /NODEBUG/EXEC=LARN.EXE $(OBJECTS), vaxcrtl.opt/options
X
XLARND.EXE : $(DOBJECTS)
X LINK/MAP/DEBUG/EXE=LARND.EXE $(DOBJECTS), sys$library:vaxcrtl.olb/libr
X
XLARNPCA.EXE : $(DOBJECTS)
X LINK /DEBUG=SYS$LIBRARY:PCA$OBJ.OBJ/EXEC=LARNPCA.EXE $(DOBJECTS),-
X SYS$LIBRARY:VAXCRTL.OLB/LIBR
X
X$(OBJECTS),$(DOBJECTS) : HEADER.H LARNDEFS.H MONSTERS.H PLAYER.H OBJECTS.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
X
Xvaxcrtl.opt :
X open/write f vaxcrtl.opt
X write f "sys$share:vaxcrtl/share"
X close f
X
END_OF_FILE
if test 1809 -ne `wc -c <'descrip.mms'`; then
echo shar: \"'descrip.mms'\" unpacked with wrong size!
fi
# end of 'descrip.mms'
fi
if test -f 'fgetlr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fgetlr.c'\"
else
echo shar: Extracting \"'fgetlr.c'\" \(2942 characters\)
sed "s/^X//" >'fgetlr.c' <<'END_OF_FILE'
X/************************************************************************
X * *
X * Copyright (c) 1982, Fred Fish *
X * All Rights Reserved *
X * *
X * This software and/or documentation is released for public *
X * distribution for personal, non-commercial use only. *
X * Limited rights to use, modify, and redistribute are hereby *
X * granted for non-commercial purposes, provided that all *
X * copyright notices remain intact and all changes are clearly *
X * documented. The author makes no warranty of any kind with *
X * respect to this product and explicitly disclaims any implied *
X * warranties of merchantability or fitness for any particular *
X * purpose. *
X * *
X ************************************************************************
X */
X
X
X/*
X * LIBRARY FUNCTION
X *
X * fgetlr get logical record from a file
X *
X * KEY WORDS
X *
X * fgetlr
X * string functions
X *
X * SYNOPSIS
X *
X * char *fgetlr(bp,bpsize,fp)
X * char *bp;
X * int bpsize;
X * FILE *fp;
X *
X * DESCRIPTION
X *
X * Reads the next logical record from stream "fp" into buffer "bp"
X * until next unescaped newline, "bpsize" minus one characters
X * have been read, end of file, or read error.
X * The last character read is followed by a NULL.
X *
X * A logical record may span several physical records by having
X * each newline escaped with the standard C escape character
X * (backslash).
X *
X * This is particularly useful for things like the termcap
X * file, where a single entry is too long for one physical
X * line, yet needs to be treated as a single record.
X *
X * Returns its first argument unless an end of file or read
X * error occurs prior to any characters being read.
X *
X * BUGS
X *
X * The only way to know if read was terminated due to buffer size
X * limitation is to test for a newline before the terminating
X * null.
X *
X */
X
X#include <stdio.h>
X
X/*
X * PSEUDO CODE
X *
X * Begin fgetlr
X * If read fails then
X * Return NULL.
X * Else
X * Find out how many characters were read.
X * Initialize pointer to terminating null.
X * If last char read was newline then
X * If newline was escaped then
X * Replace backslash with the newline.
X * Replace newline with null.
X * Read and append more.
X * End if
X * End if
X * Return buffer pointer.
X * End if
X * End fgetlr
X *
X */
X
Xchar *fgetlr(bp,bpsize,fp)
Xchar *bp;
Xint bpsize;
XFILE *fp;
X{
X int numch;
X char *cp;
X
X if (fgets(bp,bpsize,fp) == NULL) {
X return(NULL);
X } else {
X numch = strlen(bp);
X cp = &bp[numch];
X if (*--cp == '\n') {
X if (numch > 1 && *--cp == '\\') {
X *cp++ = '\n';
X *cp = (char) NULL;
X fgetlr(cp,bpsize-numch+1,fp);
X }
X }
X return(bp);
X }
X}
END_OF_FILE
if test 2942 -ne `wc -c <'fgetlr.c'`; then
echo shar: \"'fgetlr.c'\" unpacked with wrong size!
fi
# end of 'fgetlr.c'
fi
if test -f 'help.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help.c'\"
else
echo shar: Extracting \"'help.c'\" \(2982 characters\)
sed "s/^X//" >'help.c' <<'END_OF_FILE'
X/* help.c */
X#include "header.h"
X#include "larndefs.h"
X
X/*
X * help function to display the help info
X *
X * format of the .larn.help file
X *
X * 1st character of file: # of pages of help available (ascii digit)
X * page (23 lines) for the introductory message (not counted in above)
X * pages of help text (23 lines per page)
X */
Xextern char helpfile[];
Xhelp()
X {
X register int i,j,maxj;
X#ifndef VT100
X#ifndef MSDOS
X char tmbuf[128]; /* intermediate translation buffer when not a VT100 */
X#endif
X#endif
X
X /* open the help file and get # pages
X */
X if ((j=openhelp()) < 0)
X return;
X
X /* skip over intro message
X */
X for (i=0; i<23; i++)
X lgetl();
X
X /* if command mode, skip over the second page (prompt mode help)
X */
X if (!prompt_mode)
X {
X for (i=0; i<23; i++)
X lgetl();
X j--;
X }
X
X for (maxj = j; j>0; j--)
X {
X clear();
X for (i=0; i<23; i++)
X#if (defined(VT100) || defined(MSDOS))
X lprcat(lgetl()); /* print out each line that we read in */
X#else
X {
X tmcapcnv(tmbuf,lgetl());
X lprcat(tmbuf);
X } /* intercept \33's */
X#endif
X if (j>1)
X {
X lprcat(" ---- Press "); standout("return");
X lprcat(" to exit, "); standout("space");
X lprcat(" for more help ---- ");
X i=0; while ((i!=' ') && (i!='\n') && (i!='\33')) i=ttgetch();
X if ((i=='\n') || (i=='\33'))
X {
X lrclose();
X setscroll();
X drawscreen();
X return;
X }
X }
X
X /* For prompt mode, skip over the third page (command mode help)
X This could be done more efficiently, but its not worth the trouble.
X */
X if ((prompt_mode) && (j==maxj))
X {
X for (i=0; i<23; i++)
X lgetl();
X j--;
X }
X
X }
X lrclose();
X retcont();
X drawscreen();
X }
X
X/*
X * function to display the welcome message and background
X */
Xwelcome()
X {
X register int i;
X#ifndef VT100
X char tmbuf[128]; /* intermediate translation buffer when not a VT100 */
X#endif
X if (openhelp() < 0) return; /* open the help file */
X clear();
X for(i=0; i<23; i++)
X#ifdef VT100
X lprcat(lgetl()); /* print out each line that we read in */
X#else
X { tmcapcnv(tmbuf,lgetl()); lprcat(tmbuf); } /* intercept \33's */
X#endif
X lrclose(); retcont(); /* press return to continue */
X }
X
X/*
X * function to say press return to continue and reset scroll when done
X */
Xretcont()
X {
X cursor(1,24); lprcat("Press "); standout("return");
X lprcat(" to continue: "); while (ttgetch() != '\n');
X setscroll();
X }
X
X/*
X * routine to open the help file and return the first character - '0'
X */
Xstatic openhelp()
X {
X if (lopen(helpfile)<0)
X {
X lprintf("Can't open help file \"%s\" ",helpfile);
X lflush(); sleep(4); drawscreen(); setscroll(); return(-1);
X }
X resetscroll(); return(lgetc() - '0');
X }
END_OF_FILE
if test 2982 -ne `wc -c <'help.c'`; then
echo shar: \"'help.c'\" unpacked with wrong size!
fi
# end of 'help.c'
fi
if test -f 'larn.ftn' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn.ftn'\"
else
echo shar: Extracting \"'larn.ftn'\" \(1382 characters\)
sed "s/^X//" >'larn.ftn' <<'END_OF_FILE'
Xgem value = gem * 2 ^ perfection
Xsitting down can have unexpected results
Xdon't pry into the affairs of others
Xdrinking can be hazardous to your health
Xbeware of the gusher!
Xsome monsters are greedy
Xnymphs have light fingers
Xtry kissing a disenchantress!
Xthe Eye of Larn improves with time
Xhammers and brains don't mix
Xwhat does a potion of cure dianthroritis taste like?
Xhit point gain/loss when raising a level depends on constitution
Xhealing a mighty wizard can be exhilarating
Xbe sure to pay your taxes
Xare Vampires afraid of something?
Xsome dragons can fly
Xdos thou strive for perfection?
Xpatience is a virtue, unless your daughter dies
Xwhat does the Eye of Larn see in its guardian?
Xa level 25 player casts like crazy!
Xenergy rings affect spell regeneration
Xmy, aren't you clever!
Xdifficulty affects regeneration
Xcontrol of the pesty spirits is most helpful
Xdon't fall into a bottomless pit
Xdexterity allows you to carry more
Xyou can get 2 points of WC for the price of one
Xnever enter the dungeon naked! the monsters will laugh at you!
Xdid someone put itching powder in your armor?
Xyou klutz!
Xavoid opening doors. you never know whats on the other side.
Xinfinite regeneration ---> temptation
Xthe greatest weapon in the game has not the highest Weapon Class
Xyou can't buy the most powerful scroll
Xidentify things before you use them
Xthere's more than one way through a wall
END_OF_FILE
if test 1382 -ne `wc -c <'larn.ftn'`; then
echo shar: \"'larn.ftn'\" unpacked with wrong size!
fi
# end of 'larn.ftn'
fi
if test -f 'larn.opt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn.opt'\"
else
echo shar: Extracting \"'larn.opt'\" \(1467 characters\)
sed "s/^X//" >'larn.opt' <<'END_OF_FILE'
X#
X# This is a sample LARN.OPT (.larnopts on Unix) options file. It shows
X# all the possible options and provides examples. For information about each
X# option, see the LARN.DOC file. You can edit this sample file to produce a
X# real options file.
X#
X# The '#' character is a comment character; any line in the options file that
X# begins with this character will be ignored when the options file is read.
X#
X# Note that case-sensitivity is important when specifying options.
X#
X# The following options are allowed on MS-DOS and OS/2 only:
X#
X# cursor: 1 9
X# DECRainbow
X# graphics: 176 46
X# keypad
X# larndir: c:\games\larn
X# ramlevels
X# rawio
X# swapfile: c:\games\larn\larn.swp
X#
X# The following options can be used on all systems:
X#
X# auto-pickup
X# bold-objects
X# enable-checkpointing
X# highlight-objects
X# inverse-objects
X# You can rename monsters. The first letter indicates
X# which monster changes. The two examples have changed
X# the name of the Ant and Centaur, respectively.
X# monster: Aardvark
X# monster: "Charlie Chan"
X# You can specify your character's name.
X# name: Shogun
X# Note that names with spaces must be quoted
X# name: "Mr. Wizard"
X# original-objects
X# no-beep
X# no-introduction
X# prompt-on-objects
X# savefile: c:\games\larn\mygame.sav
X#
X# The following options are not allowed on MS-DOS or OS/2:
X#
X# play-day-play
X# process-name
END_OF_FILE
if test 1467 -ne `wc -c <'larn.opt'`; then
echo shar: \"'larn.opt'\" unpacked with wrong size!
fi
# end of 'larn.opt'
fi
if test -f 'larn.pid' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn.pid'\"
else
echo shar: Extracting \"'larn.pid'\" \(12 characters\)
sed "s/^X//" >'larn.pid' <<'END_OF_FILE'
X1000
XAMIGAN
END_OF_FILE
if test 12 -ne `wc -c <'larn.pid'`; then
echo shar: \"'larn.pid'\" unpacked with wrong size!
fi
# end of 'larn.pid'
fi
if test -f 'larn.scr.uu' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn.scr.uu'\"
else
echo shar: Extracting \"'larn.scr.uu'\" \(2418 characters\)
sed "s/^X//" >'larn.scr.uu' <<'END_OF_FILE'
Xbegin 644 larn.scr
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````0``````````````!
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````@``````````````````````````````````````````````````"
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````P``````````````````````````#
XM`````````````````````````````````````````````````````````````
XM````````````````````````````````````````````````````````!```$
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM````````````````````!0``````````````````````````````````````%
XM`````````````````````````````````````````````````````````````
XM````````````````````````````````````````````!@``````````````&
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM````````!P``````````````````````````````````````````````````'
XM`````````````````````````````````````````````````````````````
XM````````````````````````````````"```````````````````````````(
XM`````````````````````````````````````````````````````````````
XM````````````````````````````````````````````````````````"0``)
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````0``````````!
XM`````````````````````````````````````````````````````````````
XM```````````"````````````````````````````````````````````````"
XM``````````````````````````````````,`````````````````````````#
XM````````````````````````````````````````````````````````!```$
XM`````````````````````````````````````````````````````````````
XM```````````````````%````````````````````````````````````````%
XM``````````````````````````````````````````8`````````````````&
XM`````````````````````````````````````````````````````````````
XM````!P``````````````````````````````````````````````````````'
XM```````````````````````````(````````````````````````````````(
XM``````````````````````````````````````````````````D`````````)
XC`````````````````````````````````````````````````
X``
Xend
Xsize 1700
END_OF_FILE
if test 2418 -ne `wc -c <'larn.scr.uu'`; then
echo shar: \"'larn.scr.uu'\" unpacked with wrong size!
fi
# end of 'larn.scr.uu'
fi
if test -f 'makefile.os2' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.os2'\"
else
echo shar: Extracting \"'makefile.os2'\" \(2576 characters\)
sed "s/^X//" >'makefile.os2' <<'END_OF_FILE'
X#
X# This is a makefile for OS/2 LARN V12.3
X#
X# This is written for MSC V6.00; it assumes NMAKE.
X#
X# This could probably build a DOS larn also, if the definition
X# of OS2LARN was removed from the cc command.
X#
X#
XOBJ = obj\
XCDEFS = -DOS2LARN -DDGK -DMSDOS -DSYSV -DDGK_MSDOS -DNOVARARGS
Xcc = cl $(CDEFS) -nologo -Zi -c -AL -Fo$(OBJ)
X
XOBJS = $(OBJ)action.obj $(OBJ)bill.obj \
X $(OBJ)config.obj $(OBJ)create.obj \
X $(OBJ)data.obj $(OBJ)diag.obj \
X $(OBJ)display.obj $(OBJ)fgetlr.obj \
X $(OBJ)fortune.obj $(OBJ)global.obj \
X $(OBJ)help.obj $(OBJ)io.obj \
X $(OBJ)main.obj $(OBJ)monster.obj \
X $(OBJ)moreobj.obj $(OBJ)movem.obj \
X $(OBJ)msdos.obj $(OBJ)nap.obj \
X $(OBJ)object.obj $(OBJ)regen.obj \
X $(OBJ)savelev.obj $(OBJ)scores.obj \
X $(OBJ)signal.obj $(OBJ)spells.obj \
X $(OBJ)spheres.obj $(OBJ)store.obj \
X $(OBJ)tgetent.obj $(OBJ)tgetstr.obj \
X $(OBJ)tgoto.obj $(OBJ)tputs.obj \
X $(OBJ)tok.obj $(OBJ)vms.obj \
X $(OBJ)iventory.obj
X
Xlarn.exe : $(OBJS)
X link /CODEVIEW @os2larn.lnk
X
X$(OBJ)action.obj : action.c
X $(cc) action.c
X
X$(OBJ)bill.obj : bill.c
X $(cc) bill.c
X
X$(OBJ)config.obj : config.c
X $(cc) config.c
X
X$(OBJ)create.obj : create.c
X $(cc) create.c
X
X$(OBJ)data.obj : data.c
X $(cc) data.c
X
X$(OBJ)diag.obj : diag.c
X $(cc) diag.c
X
X$(OBJ)display.obj : display.c
X $(cc) display.c
X
X$(OBJ)fgetlr.obj : fgetlr.c
X $(cc) fgetlr.c
X
X$(OBJ)fortune.obj : fortune.c
X $(cc) fortune.c
X
X$(OBJ)global.obj : global.c
X $(cc) global.c
X
X$(OBJ)help.obj : help.c
X $(cc) help.c
X
X$(OBJ)io.obj : io.c
X $(cc) io.c
X
X$(OBJ)iventory.obj : iventory.c
X $(cc) iventory.c
X
X$(OBJ)main.obj : main.c
X $(cc) main.c
X
X$(OBJ)monster.obj : monster.c
X $(cc) monster.c
X
X$(OBJ)moreobj.obj : moreobj.c
X $(cc) moreobj.c
X
X$(OBJ)movem.obj : movem.c
X $(cc) movem.c
X
X$(OBJ)msdos.obj : msdos.c
X $(cc) msdos.c
X
X$(OBJ)nap.obj : nap.c
X $(cc) nap.c
X
X$(OBJ)object.obj : object.c
X $(cc) object.c
X
X$(OBJ)regen.obj : regen.c
X $(cc) regen.c
X
X$(OBJ)savelev.obj : savelev.c
X $(cc) savelev.c
X
X$(OBJ)scores.obj : scores.c
X $(cc) scores.c
X
X$(OBJ)signal.obj : signal.c
X $(cc) signal.c
X
X$(OBJ)spells.obj : spells.c
X $(cc) spells.c
X
X$(OBJ)spheres.obj : spheres.c
X $(cc) spheres.c
X
X$(OBJ)store.obj : store.c
X $(cc) store.c
X
X$(OBJ)tgetent.obj : tgetent.c
X $(cc) tgetent.c
X
X$(OBJ)tgetstr.obj : tgetstr.c
X $(cc) tgetstr.c
X
X$(OBJ)tgoto.obj : tgoto.c
X $(cc) tgoto.c
X
X$(OBJ)tputs.obj : tputs.c
X $(cc) tputs.c
X
X$(OBJ)tok.obj : tok.c
X $(cc) tok.c
X
X$(OBJ)vms.obj : vms.c
X $(cc) vms.c
END_OF_FILE
if test 2576 -ne `wc -c <'makefile.os2'`; then
echo shar: \"'makefile.os2'\" unpacked with wrong size!
fi
# end of 'makefile.os2'
fi
if test -f 'monsters.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'monsters.h'\"
else
echo shar: Extracting \"'monsters.h'\" \(1741 characters\)
sed "s/^X//" >'monsters.h' <<'END_OF_FILE'
X/*
X Monster related definitions
X*/
X
X#define MAXMONST 56 /* maximum # monsters in the dungeon */
X
X/* this is the structure definition of the monster data
X*/
Xstruct monst
X {
X char *name;
X char level;
X short armorclass;
X char damage;
X char attack;
X char defense;
X char genocided;
X char intelligence; /* monsters intelligence -- used to choose movement */
X short gold;
X short hitpoints;
X unsigned long experience;
X };
X
Xextern struct monst monster[];
X
X/* defines for the monsters as objects
X*/
X#define BAT 1
X#define GNOME 2
X#define HOBGOBLIN 3
X#define JACKAL 4
X#define KOBOLD 5
X#define ORC 6
X#define SNAKE 7
X#define CENTIPEDE 8
X#define JACULI 9
X#define TROGLODYTE 10
X#define ANT 11
X#define EYE 12
X#define LEPRECHAUN 13
X#define NYMPH 14
X#define QUASIT 15
X#define RUSTMONSTER 16
X#define ZOMBIE 17
X#define ASSASSINBUG 18
X#define BUGBEAR 19
X#define HELLHOUND 20
X#define ICELIZARD 21
X#define CENTAUR 22
X#define TROLL 23
X#define YETI 24
X#define WHITEDRAGON 25
X#define ELF 26
X#define CUBE 27
X#define METAMORPH 28
X#define VORTEX 29
X#define ZILLER 30
X#define VIOLETFUNGI 31
X#define WRAITH 32
X#define FORVALAKA 33
X#define LAMANOBE 34
X#define OSEQUIP 35
X#define ROTHE 36
X#define XORN 37
X#define VAMPIRE 38
X#define INVISIBLESTALKER 39
X#define POLTERGEIST 40
X#define DISENCHANTRESS 41
X#define SHAMBLINGMOUND 42
X#define YELLOWMOLD 43
X#define UMBERHULK 44
X#define GNOMEKING 45
X#define MIMIC 46
X#define WATERLORD 47
X#define BRONZEDRAGON 48
X#define GREENDRAGON 49
X#define PURPLEWORM 50
X#define XVART 51
X#define SPIRITNAGA 52
X#define SILVERDRAGON 53
X#define PLATINUMDRAGON 54
X#define GREENURCHIN 55
X#define REDDRAGON 56
X#define DEMONLORD 57
X#define DEMONPRINCE 64
END_OF_FILE
if test 1741 -ne `wc -c <'monsters.h'`; then
echo shar: \"'monsters.h'\" unpacked with wrong size!
fi
# end of 'monsters.h'
fi
if test -f 'nansi.sys.uu' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'nansi.sys.uu'\"
else
echo shar: Extracting \"'nansi.sys.uu'\" \(3541 characters\)
sed "s/^X//" >'nansi.sys.uu' <<'END_OF_FILE'
Xbegin 666 nansi.sys
XM_____Q.`RP#6`$-/3B`@("`@&ULR2DYA;G-I+G-Y<R!V,BXR.B!.97<@04Y36
XM22!D<FEV97(@*$,I($1A;FEE;"!+96=E;"P@4&%S861E;F$L($-!(#$Y.#8-<
XM"AH``````0```QA/```````'```````````````#````````````6QL``'@`'
XM````````=P``````H64`B]BT`)**Q[0`*]!"BL/^P/8F9P`"QX#4``/`E\-P@
XM"2,!(P$?`28!-0%)`50!F`&8`2,!(P$NB1Y<`"Z,!EX`R_M04U%25597'@8N6
XMQ1Y<`(I'`L1W#HM/$CP,=R"3T>.,R([8_Y>S`"[%'EP`#0`!B4<#!Q]?7EU:8
XM65M8R^@*`.OF+L<&BP`!`,^X$PC#,\##XPJ+_E'HXP)9JN+X,\##Z",#=`O%U
XM'EP`B$<-,\#K`[@``L/H#P.X``)T`C/`PS/`HX,`HX<`HXL`HX\`N$``CL`FC
XMH1H`)J,<`#/`PP#['@904U%25597N0$`C,N.PX[;OG(!B`3H"@!?7EU:65M8W
XM!Q_/C`9O`+A``([8H4D`+J)C`/[,+H@F90"@8@"8`\"3BX=0`"ZC9@"A8P`NW
XMHW,`H4X`T>C1Z-'HT>B`Q+`N@#YC``=T`X#$"`X?HVT`CL#HJ_[H%`%R`^B?+
XM`8L>=0"*)FL`CAYO`/SC(RZ#/F$``'50Z/4`<@/I#`&L/!QR(B[7JTK@]70$3
XMZP3@YW1HC,B.V*!E`/[`*L*B9@#H+0$SP,,\&W0:/`UT+SP*=&`\"70+/`ATV
XM$#P'=!CIP@#K>9#II`+IE`(N.A9E`'<#3T]"Z[CH(@(*P.NQ+J!E`/[`*L*TO
XM`"OX*_@NBA9E`$(NBB9K``P!ZY1!+O8&8``!=05/3T+KABZ*%F4`0BOZ*_HN4
XMH&0`+C@&9P!R!>@%`>L0+OX&9P`NH&4`M`!``\`#^"Z*)FL`#`'I4O\NH&4`X
XM_L`JPE&U`(K(@.$']MF`P0@KT9RP(.@6`','\ZN=6>DL_P/1Z#P`2N+ZG5GI'
XM'_\N@#YC``1R"BZ`/F,`!W0"^,/YP^CI_W,(Z?G^K#P<<@TNU^@.`$K@\W0&P
XMZ?7^Z0;_Z5?_4E%34"Z@90#^P"K"+J)F`"Z+%F8`,]NT`LT0N0$`6%"*W+<`W
XMM`G-$%A;65K#Z)S_<RJ+W]'KBQ9S`+`.[NL`0HK'[NL`2K`/[NL`0HK#[KA`W
XM`([8+J%F`*-0`,.X%H_HGO_#M`#H9/]S%RZ*)FL`@.1_+H`^8P`'=0>`_`%UO
XM`K0'PU!345+HVO^*_+`!M`:Q`+4`+HH690`NBC9D`,T06EE;6,.+-N`$"L!T,
XM`K0`.S;>!'8.BPP[1/YT"X/N!"OQZ^P+]NL'@^X"*_$ZP,.Y!`"[?P"#PP2+3
XM-POVX??#Z.W_="G_#TZ+;P(^B@*#[@%R&8'[@P!T$PK`=0__#SZ*(L<&@P`!`
XM`(@F>`#K&[0`S18+P'3XZ(W_=0J)#H\`B3:1`.N[/`!TV</HH_]T"4Z+;P(^D
XMB@+K&K0!S19T%PO`=0:T`,T6Z_#H6_]U!0/QBD3_@,P!PQ0%`P!04U%25597=
XML+:Z0P#N2BZAAP3K`.Z&X.L`[KIA`.L`[%`,`^L`[@:X0`".P":+'FP`+@,>-
XMB02Y__\FH6P`.\-_`N+V!U@D_.Y?7EU:65M8PP``,#`P,#`NB1YQ`"ZC80#I/
XM-/TNBQYQ`"[_)F$`Z9D`X@6X`@7KX*P\6W7Q+HL>W`0NQ@<`+L8&VP0`X@6XS
XM'07KQ:P\/70'/#]T`T[K!^(%N#`%Z[*L/#!R%CPY=Q(L,"Z(!R[&!ML$`>)BJ
XMN*@%ZY<\(G0$/"=U="ZB:@#B!;A>!>N$K"XZ!FH`=!,NB`<N.Q[>!(/3`.+K(
XMN%X%Z6G_+L8'`.(&N(4%Z5W_K#P[=`)!3N*BN#`%Z4[_+L<&80```"Z*)FL`*
XM+HL>=0#I:_VL/#!R&CPY=Q8L,"Z&!U*R"O;B6BX`!^+GN*@%Z1O_/#MU$"X[E
XM'MX$@],`+L8&VP0`ZYX\0'*U/'IWL3Q:=@8\87*I+`9641X.'RQ`F`/`!44&^
XMB\LNBS;<!"O.+O8&VP0!=`%!DZ!E`$`JPJ)F`+0`K`K`=0%`_Q<?65XNBB9K_
XM`"Z+'G4`+L<&80````O2Z>7[U`H%,#"&X*J&X*K#30@`!_H&YP;M!J\&KP:O)
XM!K`&KP9/!T8'(P@?"*\&KP91"*\&KP:O!J\&KP:O!J\&KP:O!J\&KP:O!J\&:
XMKP:O!K`&KP:2"*\&KP:O!@H)'`=S!Z\&J`>O!J\�>O!A0'KP:O!J\&#@FO5
XM!L,*P'0!2*)G`#/`@_D"<@:L"L!T`4BB9@"A9@`Z!F4`=@:@90"B9@`Z)F0`V
XM=@:@9`"B9P#HK?G#``9F`.O;*`9F`',%Q@9F``#KS@`&9P#KR"@&9P!S!<8&\
XM9P``Z[NA9@"C:`##H6@`HV8`ZZQ."\EU!,8$`$&L4;D6`)"[*PF#PP,Z!^#Y?
XM=0N+1P$@!FL`""9K`%GBX,-2BPYF`(KUZQ0\`G4?QP9F````Z#?Y4C/)BC9DY
XM`.@P_(K\BA9E`+@`!LT06L-74@:,R([`_;^``*!G`/[`Z+/^L#NJH&8`_L#H#
XMJ/ZP4JJP#8D^B0"JN((`*\>CAP#\!UI?PPO)=%G\3DE)K0K`=`)!3E<&45;]8
XM'@?H%OQU%H/!!(LNW@0!#MX$3HO^`_F+SBO-\Z1>68L^W@2#[P2+WRO9@^L0]
XM.Q[<!'(2B4T#B44!XP:D@\8"XOJ)/MX$!U_\PP8>!_V+/N`$N`$`J[@`<JNPE
XM$*J)/MX$!^ODM`;K`K0'BCYD`"H^9P`ZQW8"L`!0Z%_[BOQ8L0"*+F<`4HH6Q
XM90"*-F0`S1!:P[4!ZP*U`.BI^G,Y.L)V`HK"5Y&+Z;4`B_<#\0/Q]MD"RK4`=
XM_/;$`70,A_[]B\%(`\`#^`/P!A_SI8O-Z`O[L"#SJ_Q?P['_/`=U!H@.8`#K<
XM:SPK=4*T$KL0_\T0]\/\_G5:Z$WZ<U6T`*!C`,T0N!(1LP#-$+@`$K,@S1"T=
XM`;D'!\T0BQ9S`+`*[NL`0K`'[L8&9``JZPFT`,T0Q@9D`!BX0``>CMBA20`??
XMHF,`_LR()F4`QP9F````Z(KWP[$`ZX:+'G4`XP].K4EU`HK@`MB`UP"()\,SN
XMP(@'0_[`=?GK]```!P'_"`3X`07_@`?X<`B(`![X`!_X!"#X`B'X!B+X`2/X,
XM!23X`R7X!RB/`"F/0"J/("N/8"R/$"V/4"Z/,"^/<#/`CMB[;`#'!Q<!C$\"?
XMNZ0`QP=S`8Q/`@X?#@?\OW`)B3[<!(''``*)/MX$1[`0JK@`<JNX`0")/N`$X
X9JXD^=0`SP*K^P'7[,\#%-EP`B7P.C$P0PP*)%
X``
Xend
Xsize 2500
END_OF_FILE
if test 3541 -ne `wc -c <'nansi.sys.uu'`; then
echo shar: \"'nansi.sys.uu'\" unpacked with wrong size!
fi
# end of 'nansi.sys.uu'
fi
if test -f 'nap.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'nap.c'\"
else
echo shar: Extracting \"'nap.c'\" \(3719 characters\)
sed "s/^X//" >'nap.c' <<'END_OF_FILE'
X/* nap.c */
X#ifdef VMS
X#include <signal.h>
X#include <types.h>
X#include <time.h>
X#else
X#include <signal.h>
X#include <sys/types.h>
X#ifdef SYSV
X# ifdef MSDOS
X# ifdef OS2LARN
X# define INCL_BASE
X# include <os2.h>
X# define sleep(x) DosSleep(x*1000L)
X# endif
X# include <dos.h>
X# else
X# include <sys/times.h>
X# endif
X#else
X#ifdef BSD
X#include <sys/timeb.h>
X#endif BSD
X#endif SYSV
X#endif
X/*
X * routine to take a nap for n milliseconds
X */
Xnap(x)
X register int x;
X {
X if (x<=0) return; /* eliminate chance for infinite loop */
X lflush();
X if (x > 999) sleep(x/1000); else napms(x);
X }
X
X#ifdef NONAP
Xstatic napms(x) /* do nothing */
X int x;
X {
X }
X#else NONAP
X#ifdef SYSV
X/* napms - sleep for time milliseconds - uses times() */
X/* this assumes that times returns a relative time in 60ths of a second */
X/* this will do horrible things if your times() returns seconds! */
X
X#ifdef MSDOS
Xunsigned long
Xstatic dosgetms()
X{
X#ifdef OS2LARN
X DATETIME dt;
X DosGetDateTime(&dt);
X
X /* return hundreths of seconds */
X return ( 360000L * dt.hours +
X 6000L * dt.minutes +
X 100L * dt.seconds + dt.hundredths );
X#else
X union REGS regs;
X
X regs.h.ah = 0x2C;
X intdos(®s, ®s);
X
X /* return hundreths of seconds
X */
X return ( 360000L * regs.h.ch +
X 6000L * regs.h.cl +
X 100L * regs.h.dh + regs.h.dl );
X#endif
X}
X
Xstatic napms(time)
Xint time;
X{
X unsigned long matchclock;
X
X if (time <= 0)
X time = 1; /* eliminate chance of infinite loop */
X matchclock = dosgetms() + (time + 5) / 10;
X if (matchclock > 8640000L) /* total 100ths-of-seconds in 24 hrs */
X return;
X
X while (matchclock > dosgetms())
X ;
X}
X
X# else
Xstatic napms(time)
X int time;
X {
X long matchclock, times();
X struct tms stats;
X
X if (time<=0) time=1; /* eliminate chance for infinite loop */
X if ((matchclock = times(&stats)) == -1 || matchclock == 0)
X return; /* error, or BSD style times() */
X matchclock += (time / 17); /*17 ms/tic is 1000 ms/sec / 60 tics/sec */
X
X while(matchclock < times(&stats))
X ;
X }
X# endif /* MSDOS */
X
X#else not SYSV
X#ifdef BSD
X#ifdef SIGVTALRM
X/* This must be BSD 4.2! */
X#include <sys/time.h>
X#define bit(_a) (1<<((_a)-1))
X
Xstatic void nullf()
X {
X }
X
X/* napms - sleep for time milliseconds - uses setitimer() */
Xstatic napms(time)
X int time;
X {
X struct itimerval timeout;
X#ifdef SIG_RTNS_INT
X int (*oldhandler) ();
X#else
X void (*oldhandler) ();
X#endif
X int oldsig;
X
X if (time <= 0) return;
X
X timerclear(&timeout.it_interval);
X timeout.it_value.tv_sec = time / 1000;
X timeout.it_value.tv_usec = (time % 1000) * 1000;
X
X oldsig = sigblock(bit(SIGALRM));
X setitimer(ITIMER_REAL, &timeout, (struct itimerval *)0);
X oldhandler = signal(SIGALRM, nullf);
X sigpause(oldsig);
X signal(SIGALRM, oldhandler);
X sigsetmask(oldsig);
X }
X
X#else
X/* napms - sleep for time milliseconds - uses ftime() */
X
Xstatic napms(time)
X int time;
X {
X /* assumed to be BSD UNIX */
X struct timeb _gtime;
X time_t matchtime;
X unsigned short matchmilli;
X register struct timeb *tp = & _gtime;
X
X if (time <= 0) return;
X ftime(tp);
X matchmilli = tp->millitm + time;
X matchtime = tp->time;
X while (matchmilli >= 1000)
X {
X ++matchtime;
X matchmilli -= 1000;
X }
X
X while(1)
X {
X ftime(tp);
X if ((tp->time > matchtime) ||
X ((tp->time == matchtime) && (tp->millitm >= matchmilli)))
X break;
X }
X }
X#endif
X#else not BSD
Xstatic napms(time) int time; {} /* do nothing, forget it */
X#endif BSD
X#endif SYSV
X#endif NONAP
END_OF_FILE
if test 3719 -ne `wc -c <'nap.c'`; then
echo shar: \"'nap.c'\" unpacked with wrong size!
fi
# end of 'nap.c'
fi
if test -f 'objects.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'objects.h'\"
else
echo shar: Extracting \"'objects.h'\" \(2633 characters\)
sed "s/^X//" >'objects.h' <<'END_OF_FILE'
X/*
X Object definitions
X*/
X#define MAXSCROLL 28 /* maximum number of scrolls that are possible */
X#define MAXPOTION 35 /* maximum number of potions that are possible */
X
X#define MAXOBJ 93 /* the maximum number of objects n < MAXOBJ */
X
X/* this is the structure definition for the items in the dnd store */
Xstruct _itm
X {
X short price;
X char **mem;
X char obj;
X char arg;
X char qty;
X };
X
Xextern struct _itm itm[];
X
X/* defines for the objects in the game */
X#define MAXOBJECT 92
X
X#define OALTAR 1
X#define OTHRONE 2
X#define OORB 3
X#define OPIT 4
X#define OSTAIRSUP 5
X#define OELEVATORUP 6
X#define OFOUNTAIN 7
X#define OSTATUE 8
X#define OTELEPORTER 9
X#define OSCHOOL 10
X#define OMIRROR 11
X#define ODNDSTORE 12
X#define OSTAIRSDOWN 13
X#define OELEVATORDOWN 14
X#define OBANK2 15
X#define OBANK 16
X#define ODEADFOUNTAIN 17
X#define OMAXGOLD 70
X#define OGOLDPILE 18
X#define OOPENDOOR 19
X#define OCLOSEDDOOR 20
X#define OWALL 21
X#define OTRAPARROW 66
X#define OTRAPARROWIV 67
X
X#define OLARNEYE 22
X
X#define OPLATE 23
X#define OCHAIN 24
X#define OLEATHER 25
X#define ORING 60
X#define OSTUDLEATHER 61
X#define OSPLINT 62
X#define OPLATEARMOR 63
X#define OSSPLATE 64
X#define OSHIELD 68
X#define OELVENCHAIN 92
X
X#define OSWORDofSLASHING 26
X#define OHAMMER 27
X#define OSWORD 28
X#define O2SWORD 29
X#define OSPEAR 30
X#define ODAGGER 31
X#define OBATTLEAXE 57
X#define OLONGSWORD 58
X#define OFLAIL 59
X#define OLANCE 65
X#define OVORPAL 90
X#define OSLAYER 91
X
X#define ORINGOFEXTRA 32
X#define OREGENRING 33
X#define OPROTRING 34
X#define OENERGYRING 35
X#define ODEXRING 36
X#define OSTRRING 37
X#define OCLEVERRING 38
X#define ODAMRING 39
X
X#define OBELT 40
X
X#define OSCROLL 41
X#define OPOTION 42
X#define OBOOK 43
X#define OCHEST 44
X#define OAMULET 45
X
X#define OORBOFDRAGON 46
X#define OSPIRITSCARAB 47
X#define OCUBEofUNDEAD 48
X#define ONOTHEFT 49
X
X#define ODIAMOND 50
X#define ORUBY 51
X#define OEMERALD 52
X#define OSAPPHIRE 53
X
X#define OENTRANCE 54
X#define OVOLDOWN 55
X#define OVOLUP 56
X#define OHOME 69
X
X#define OKGOLD 71
X#define ODGOLD 72
X#define OIVDARTRAP 73
X#define ODARTRAP 74
X#define OTRAPDOOR 75
X#define OIVTRAPDOOR 76
X#define OTRADEPOST 77
X#define OIVTELETRAP 78
X#define ODEADTHRONE 79
X#define OANNIHILATION 80 /* sphere of annihilation */
X#define OTHRONE2 81
X#define OLRS 82 /* Larn Revenue Service */
X#define OCOOKIE 83
X#define OURN 84
X#define OBRASSLAMP 85
X#define OHANDofFEAR 86 /* hand of fear */
X#define OSPHTAILSMAN 87 /* tailsman of the sphere */
X#define OWWAND 88 /* wand of wonder */
X#define OPSTAFF 89 /* staff of power */
X/* used up to 92 */
END_OF_FILE
if test 2633 -ne `wc -c <'objects.h'`; then
echo shar: \"'objects.h'\" unpacked with wrong size!
fi
# end of 'objects.h'
fi
if test -f 'os2larn.def' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'os2larn.def'\"
else
echo shar: Extracting \"'os2larn.def'\" \(70 characters\)
sed "s/^X//" >'os2larn.def' <<'END_OF_FILE'
XNAME LARN WINDOWCOMPAT LONGNAMES
X
XDESCRIPTION 'LARN for OS/2 V12.3.0'
END_OF_FILE
if test 70 -ne `wc -c <'os2larn.def'`; then
echo shar: \"'os2larn.def'\" unpacked with wrong size!
fi
# end of 'os2larn.def'
fi
if test -f 'os2larn.lnk' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'os2larn.lnk'\"
else
echo shar: Extracting \"'os2larn.lnk'\" \(567 characters\)
sed "s/^X//" >'os2larn.lnk' <<'END_OF_FILE'
Xobj\action.obj+
Xobj\bill.obj+
Xobj\config.obj+
Xobj\create.obj+
Xobj\data.obj+
Xobj\diag.obj+
Xobj\display.obj+
Xobj\fgetlr.obj+
Xobj\fortune.obj+
Xobj\global.obj+
Xobj\help.obj+
Xobj\io.obj+
Xobj\iventory.obj+
Xobj\main.obj+
Xobj\monster.obj+
Xobj\moreobj.obj+
Xobj\movem.obj+
Xobj\msdos.obj+
Xobj\nap.obj+
Xobj\object.obj+
Xobj\regen.obj+
Xobj\savelev.obj+
Xobj\scores.obj+
Xobj\signal.obj+
Xobj\spells.obj+
Xobj\spheres.obj+
Xobj\store.obj+
Xobj\tgetent.obj+
Xobj\tgetstr.obj+
Xobj\tgoto.obj+
Xobj\tputs.obj+
Xobj\tok.obj+
Xobj\vms.obj
Xlarn123.exe
Xlarn123.map/map /line
Xdoscalls.lib
Xos2larn.def
END_OF_FILE
if test 567 -ne `wc -c <'os2larn.lnk'`; then
echo shar: \"'os2larn.lnk'\" unpacked with wrong size!
fi
# end of 'os2larn.lnk'
fi
if test -f 'patchlev.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'patchlev.h'\"
else
echo shar: Extracting \"'patchlev.h'\" \(77 characters\)
sed "s/^X//" >'patchlev.h' <<'END_OF_FILE'
X/* indicate which patches have been applied to Larn.
X*/
X#define PATCHLEVEL 0
END_OF_FILE
if test 77 -ne `wc -c <'patchlev.h'`; then
echo shar: \"'patchlev.h'\" unpacked with wrong size!
fi
# end of 'patchlev.h'
fi
if test -f 'player.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'player.h'\"
else
echo shar: Extracting \"'player.h'\" \(1895 characters\)
sed "s/^X//" >'player.h' <<'END_OF_FILE'
X/* defines for the character attribute array c[]
X*/
X#define STRENGTH 0 /* characters physical strength not due to objects */
X#define INTELLIGENCE 1
X#define WISDOM 2
X#define CONSTITUTION 3
X#define DEXTERITY 4
X#define CHARISMA 5
X#define HPMAX 6
X#define HP 7
X#define GOLD 8
X#define EXPERIENCE 9
X#define LEVEL 10
X#define REGEN 11
X#define WCLASS 12
X#define AC 13
X#define BANKACCOUNT 14
X#define SPELLMAX 15
X#define SPELLS 16
X#define ENERGY 17
X#define ECOUNTER 18
X#define MOREDEFENSES 19
X#define WEAR 20
X#define PROTECTIONTIME 21
X#define WIELD 22
X#define AMULET 23
X#define REGENCOUNTER 24
X#define MOREDAM 25
X#define DEXCOUNT 26
X#define STRCOUNT 27
X#define BLINDCOUNT 28
X#define CAVELEVEL 29
X#define CONFUSE 30
X#define ALTPRO 31
X#define HERO 32
X#define CHARMCOUNT 33
X#define INVISIBILITY 34
X#define CANCELLATION 35
X#define HASTESELF 36
X#define EYEOFLARN 37
X#define AGGRAVATE 38
X#define GLOBE 39
X#define TELEFLAG 40
X#define SLAYING 41
X#define NEGATESPIRIT 42
X#define SCAREMONST 43
X#define AWARENESS 44
X#define HOLDMONST 45
X#define TIMESTOP 46
X#define HASTEMONST 47
X#define CUBEofUNDEAD 48
X#define GIANTSTR 49
X#define FIRERESISTANCE 50
X#define BESSMANN 51
X#define NOTHEFT 52
X#define HARDGAME 53
X#define CPUTIME 54
X#define BYTESIN 55
X#define BYTESOUT 56
X#define MOVESMADE 57
X#define MONSTKILLED 58
X#define SPELLSCAST 59
X#define LANCEDEATH 60
X#define SPIRITPRO 61
X#define UNDEADPRO 62
X#define SHIELD 63
X#define STEALTH 64
X#define ITCHING 65
X#define LAUGHING 66
X#define DRAINSTRENGTH 67
X#define CLUMSINESS 68
X#define INFEEBLEMENT 69
X#define HALFDAM 70
X#define SEEINVISIBLE 71
X#define FILLROOM 72
X#define RANDOMWALK 73
X#define SPHCAST 74 /* nz if an active sphere of annihilation */
X#define WTW 75 /* walk through walls */
X#define STREXTRA 76 /* character strength due to objects or enchantments */
X#define TMP 77 /* misc scratch space */
X#define LIFEPROT 78 /* life protection counter */
END_OF_FILE
if test 1895 -ne `wc -c <'player.h'`; then
echo shar: \"'player.h'\" unpacked with wrong size!
fi
# end of 'player.h'
fi
if test -f 'termcap.pc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'termcap.pc'\"
else
echo shar: Extracting \"'termcap.pc'\" \(439 characters\)
sed "s/^X//" >'termcap.pc' <<'END_OF_FILE'
X#
X# Monochrome IBMPC.
X# This is a termcap for the NANSI.SYS device driver.
X# It is the same as the ANSI termcap, except NANSI supports
X# line insert (al) and delete (dl) while ANSI does not.
X#
Xibmpc-mono:\
X :co#80:\
X :li#24:\
X :cl=\E[;H\E[2J:\
X :bs:\
X :ho=\E[H:\
X :cm=\E[%i%2;%2H:\
X :up=\E[A:\
X :xd=\E[B:\
X :nd=\E[C:\
X :bc=\E[D:\
X :ce=\E[K:\
X :ti=\E[m:\
X :te=\E[m:\
X :so=\E[1m:\
X :se=\E[m:\
X :us=\E[4m:\
X :ue=\E[m:\
X :al=\E[L:\
X :dl=\E[M:
END_OF_FILE
if test 439 -ne `wc -c <'termcap.pc'`; then
echo shar: \"'termcap.pc'\" unpacked with wrong size!
fi
# end of 'termcap.pc'
fi
if test -f 'tlink.rsp' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tlink.rsp'\"
else
echo shar: Extracting \"'tlink.rsp'\" \(373 characters\)
sed "s/^X//" >'tlink.rsp' <<'END_OF_FILE'
Xmain.obj object.obj create.obj tok.obj display.obj +
Xglobal.obj data.obj io.obj monster.obj action.obj +
Xiventory.obj vms.obj store.obj diag.obj help.obj +
Xconfig.obj nap.obj bill.obj scores.obj signal.obj +
Xmoreobj.obj spheres.obj spells.obj movem.obj +
Xregen.obj fortune.obj savelev.obj msdos.obj +
Xfgetlr.obj tgoto.obj tgetent.obj tgetstr.obj tputs.obj
END_OF_FILE
if test 373 -ne `wc -c <'tlink.rsp'`; then
echo shar: \"'tlink.rsp'\" unpacked with wrong size!
fi
# end of 'tlink.rsp'
fi
if test -f 'vmsreadme.txt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vmsreadme.txt'\"
else
echo shar: Extracting \"'vmsreadme.txt'\" \(1388 characters\)
sed "s/^X//" >'vmsreadme.txt' <<'END_OF_FILE'
XThis is a VMS version of LARN 12.3. To run it, larndir must be defined as a
Xlogical name that points to the directory containing the support files
X(LARN.MAZ, LARN.HLP, etc). Larn looks for LARN.OPT in SYS$LOGIN. VMS Version
X5.x may be required.
X
XThe first entry in the larn.pid file (1000) can be the wizard if the password is
Xknown (same password as in MS-DOS edition; see LARN122.DOC).
X
XThe sources have been compiled with termcap. It will look for the
Xtermcap file either through the logical name "termcap", in the current
Xdirectory as "termcap.", or as "sys$library:termcap." If there is
Xa symbol or logical called "term" then the value of that will
Xbe used for the terminal, otherwise the value from "terminal" will be
Xused.
X
XThis version includes VMS Keypad support on VT class terminals. The keypad
Xkeys must be set to application mode (SET TERM/APPLICATION) in order for LARN
Xto recognise the keys. It is not necessary to set the KEYPAD option in the
XLARN.OPT file. The key mappings are:
X
X PF1 PF2 PF3 PF4
X '@'
X KP7 KP8 KP9 KP-
X 'y' 'k' 'u'
X KP4 KP5 KP6 KP,
X 'h' '.' 'l' ','
X ^ KP1 KP2 KP3 KP
X 'K' 'b' 'j' 'n' Enter
X < v > KP0 KP.
X 'H' 'J' 'L' 'i' '.'
X
XKeypad mode occasionally seems flakey, especially on DECTerms. Until I can
Xre-work it, this will have to do. Customization of the keypad is not
Xcurrently supported.
X
X Kevin Routley
END_OF_FILE
if test 1388 -ne `wc -c <'vmsreadme.txt'`; then
echo shar: \"'vmsreadme.txt'\" unpacked with wrong size!
fi
# end of 'vmsreadme.txt'
fi
echo shar: End of archive 1 \(of 17\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 17 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
--
Mail submissions (sources or binaries) to <am...@uunet.uu.net>.
Mail comments to the moderator at <amiga-...@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.
#!/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 6 (of 17)."
# Contents: create.c diag.c tok.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:53 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'create.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'create.c'\"
else
echo shar: Extracting \"'create.c'\" \(15884 characters\)
sed "s/^X//" >'create.c' <<'END_OF_FILE'
X/* create.c */
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X/*
X makeplayer()
X
X subroutine to create the player and the players attributes
X this is called at the beginning of a game and at no other time
X */
Xmakeplayer()
X {
X register int i;
X scbr(); clear();
X c[HPMAX]=c[HP]=10; /* start player off with 15 hit points */
X c[LEVEL]=1; /* player starts at level one */
X c[SPELLMAX]=c[SPELLS]=1; /* total # spells starts off as 3 */
X c[REGENCOUNTER]=16; c[ECOUNTER]=96; /*start regeneration correctly*/
X c[SHIELD] = c[WEAR] = c[WIELD] = -1;
X for (i=0; i<26; i++) iven[i]=0;
X spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/
X if (c[HARDGAME]<=0)
X {
X iven[0]=OLEATHER; iven[1]=ODAGGER; iven[2] = 0;
X ivenarg[1]=ivenarg[0]=c[WEAR]=0; c[WIELD]=1;
X }
X playerx=rnd(MAXX-2); playery=rnd(MAXY-2);
X regen_bottom = TRUE ;
X for (i=0; i<6; i++) c[i]=12; /* make the attributes, ie str, int, etc. */
X recalc();
X }
X
X/*
X newcavelevel(level)
X int level;
X
X function to enter a new level. This routine must be called anytime the
X player changes levels. If that level is unknown it will be created.
X A new set of monsters will be created for a new level, and existing
X levels will get a few more monsters.
X Note that it is here we remove genocided monsters from the present level.
X */
Xnewcavelevel(x)
X register int x;
X {
X register int i,j;
X if (beenhere[level]) savelevel(); /* put the level back into storage */
X level = x; /* get the new level and put in working storage */
X if (beenhere[x])
X {
X getlevel();
X sethp(0);
X positionplayer();
X checkgen();
X return;
X }
X
X /* fill in new level
X */
X for (i=0; i<MAXY; i++)
X for (j=0; j<MAXX; j++)
X know[j][i]=mitem[j][i]=0;
X makemaze(x);
X makeobject(x);
X beenhere[x]=1;
X sethp(1);
X positionplayer();
X checkgen(); /* wipe out any genocided monsters */
X
X#if WIZID
X if (wizard || x==0)
X#else
X if (x==0)
X#endif
X for (j=0; j<MAXY; j++)
X for (i=0; i<MAXX; i++)
X know[i][j] = KNOWALL;
X }
X
X/*
X makemaze(level)
X int level;
X
X subroutine to make the caverns for a given level. only walls are made.
X */
Xstatic int mx,mxl,mxh,my,myl,myh,tmp2;
Xstatic makemaze(k)
X int k;
X {
X register int i,j,tmp;
X int z;
X if (k > 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1))
X {
X if (cannedlevel(k)); return; /* read maze from data file */
X }
X if (k==0) tmp=0; else tmp=OWALL;
X for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) item[j][i]=tmp;
X if (k==0) return; eat(1,1);
X if (k==1) item[33][MAXY-1] = OENTRANCE;
X
X/* now for open spaces -- not on level 10 */
X if (k != MAXLEVEL-1)
X {
X tmp2 = rnd(3)+3;
X for (tmp=0; tmp<tmp2; tmp++)
X {
X my = rnd(11)+2; myl = my - rnd(2); myh = my + rnd(2);
X if (k < MAXLEVEL)
X {
X mx = rnd(44)+5; mxl = mx - rnd(4); mxh = mx + rnd(12)+3;
X z=0;
X }
X else
X {
X mx = rnd(60)+3; mxl = mx - rnd(2); mxh = mx + rnd(2);
X z = makemonst(k);
X }
X for (i=mxl; i<mxh; i++) for (j=myl; j<myh; j++)
X { item[i][j]=0;
X if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints;
X }
X }
X }
X if (k!=MAXLEVEL-1) { my=rnd(MAXY-2); for (i=1; i<MAXX-1; i++) item[i][my] = 0; }
X if (k>1) treasureroom(k);
X }
X
X/*
X function to eat away a filled in maze
X */
Xeat(xx,yy)
X register int xx,yy;
X {
X register int dir,try;
X dir = rnd(4); try=2;
X while (try)
X {
X switch(dir)
X {
X case 1: if (xx <= 2) break; /* west */
X if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break;
X item[xx-1][yy] = item[xx-2][yy] = 0;
X eat(xx-2,yy); break;
X
X case 2: if (xx >= MAXX-3) break; /* east */
X if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break;
X item[xx+1][yy] = item[xx+2][yy] = 0;
X eat(xx+2,yy); break;
X
X case 3: if (yy <= 2) break; /* south */
X if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break;
X item[xx][yy-1] = item[xx][yy-2] = 0;
X eat(xx,yy-2); break;
X
X case 4: if (yy >= MAXY-3 ) break; /* north */
X if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break;
X item[xx][yy+1] = item[xx][yy+2] = 0;
X eat(xx,yy+2); break;
X };
X if (++dir > 4) { dir=1; --try; }
X }
X }
X
X/*
X * function to read in a maze from a data file
X *
X * Format of maze data file: 1st character = # of mazes in file (ascii digit)
X * For each maze: 18 lines (1st 17 used) 67 characters per line
X *
X * Special characters in maze data file:
X *
X * # wall D door . random monster
X * ~ eye of larn ! cure dianthroritis
X * - random object
X */
Xstatic cannedlevel(k)
X int k;
X {
X char *row,*lgetl();
X register int i,j;
X int it,arg,mit,marg;
X if (lopen(larnlevels)<0)
X {
X write(1,"Can't open the maze data file\n",30); died(-282); return(0);
X }
X i=lgetc(); if (i<='0') { died(-282); return(0); }
X for (i=18*rund(i-'0'); i>0; i--) lgetl(); /* advance to desired maze */
X for (i=0; i<MAXY; i++)
X {
X row = lgetl();
X for (j=0; j<MAXX; j++)
X {
X it = mit = arg = marg = 0;
X switch(*row++)
X {
X case '#': it = OWALL; break;
X case 'D': it = OCLOSEDDOOR; arg = rnd(30); break;
X case '~': if (k!=MAXLEVEL-1) break;
X it = OLARNEYE;
X mit = rund(8)+DEMONLORD;
X marg = monster[mit].hitpoints; break;
X case '!': if (k!=MAXLEVEL+MAXVLEVEL-1) break;
X it = OPOTION; arg = 21;
X mit = DEMONLORD+7;
X marg = monster[mit].hitpoints; break;
X case '.': if (k<MAXLEVEL) break;
X mit = makemonst(k+1);
X marg = monster[mit].hitpoints; break;
X case '-': it = newobject(k+1,&arg); break;
X };
X item[j][i] = it; iarg[j][i] = arg;
X mitem[j][i] = mit; hitp[j][i] = marg;
X
X#if WIZID
X know[j][i] = (wizard) ? KNOWALL : 0;
X#else
X know[j][i] = 0;
X#endif
X }
X }
X lrclose();
X return(1);
X }
X
X/*
X function to make a treasure room on a level
X level 10's treasure room has the eye in it and demon lords
X level V3 has potion of cure dianthroritis and demon prince
X */
Xstatic treasureroom(lv)
X register int lv;
X {
X register int tx,ty,xsize,ysize;
X
X for (tx=1+rnd(10); tx<MAXX-10; tx+=10)
X if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2)
X {
X xsize = rnd(6)+3; ysize = rnd(3)+3;
X ty = rnd(MAXY-9)+1; /* upper left corner of room */
X if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1)
X troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6);
X else troom(lv,xsize,ysize,tx,ty,rnd(9));
X }
X }
X
X/*
X * subroutine to create a treasure room of any size at a given location
X * room is filled with objects and monsters
X * the coordinate given is that of the upper left corner of the room
X */
Xstatic troom(lv,xsize,ysize,tx,ty,glyph)
X int lv,xsize,ysize,tx,ty,glyph;
X {
X register int i,j;
X int tp1,tp2;
X for (j=ty-1; j<=ty+ysize; j++)
X for (i=tx-1; i<=tx+xsize; i++) /* clear out space for room */
X item[i][j]=0;
X for (j=ty; j<ty+ysize; j++)
X for (i=tx; i<tx+xsize; i++) /* now put in the walls */
X {
X item[i][j]=OWALL; mitem[i][j]=0;
X }
X for (j=ty+1; j<ty+ysize-1; j++)
X for (i=tx+1; i<tx+xsize-1; i++) /* now clear out interior */
X item[i][j]=0;
X
X switch(rnd(2)) /* locate the door on the treasure room */
X {
X case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR;
X iarg[i][j] = glyph; /* on horizontal walls */
X break;
X case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR;
X iarg[i][j] = glyph; /* on vertical walls */
X break;
X };
X
X tp1=playerx; tp2=playery; playery=ty+(ysize>>1);
X if (c[HARDGAME]<2)
X for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
X for (i=0, j=rnd(6); i<=j; i++)
X { something(lv+2); createmonster(makemonst(lv+1)); }
X else
X for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
X for (i=0, j=rnd(4); i<=j; i++)
X { something(lv+2); createmonster(makemonst(lv+3)); }
X
X playerx=tp1; playery=tp2;
X }
X
X/*
X ***********
X MAKE_OBJECT
X ***********
X subroutine to create the objects in the maze for the given level
X */
Xstatic makeobject(j)
X register int j;
X {
X register int i;
X if (j==0)
X {
X fillroom(OENTRANCE,0); /* entrance to dungeon */
X fillroom(ODNDSTORE,0); /* the DND STORE */
X fillroom(OSCHOOL,0); /* college of Larn */
X fillroom(OBANK,0); /* 1st national bank of larn */
X fillroom(OVOLDOWN,0); /* volcano shaft to temple */
X fillroom(OHOME,0); /* the players home & family */
X fillroom(OTRADEPOST,0); /* the trading post */
X fillroom(OLRS,0); /* the larn revenue service */
X return;
X }
X
X if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */
X
X/* make the fixed objects in the maze STAIRS */
X if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
X fillroom(OSTAIRSDOWN,0);
X if ((j > 1) && (j != MAXLEVEL))
X fillroom(OSTAIRSUP,0);
X
X/* make the random objects in the maze */
X
X fillmroom(rund(3),OBOOK,j);
X fillmroom(rund(3),OALTAR,0);
X fillmroom(rund(3),OSTATUE,0);
X fillmroom(rund(3),OPIT,0);
X fillmroom(rund(3),OFOUNTAIN,0);
X fillmroom( rnd(3)-2,OIVTELETRAP,0);
X fillmroom(rund(2),OTHRONE,0);
X fillmroom(rund(2),OMIRROR,0);
X fillmroom(rund(2),OTRAPARROWIV,0);
X fillmroom( rnd(3)-2,OIVDARTRAP,0);
X fillmroom(rund(3),OCOOKIE,0);
X if (j==1)
X fillmroom(1,OCHEST,j);
X else
X fillmroom(rund(2),OCHEST,j);
X if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
X fillmroom(rund(2),OIVTRAPDOOR,0);
X if (j<=10)
X {
X fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10);
X fillmroom(rund(2),ORUBY,rnd(6*j+1)+6);
X fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4);
X fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2);
X }
X for (i=0; i<rnd(4)+3; i++)
X fillroom(OPOTION,newpotion()); /* make a POTION */
X for (i=0; i<rnd(5)+3; i++)
X fillroom(OSCROLL,newscroll()); /* make a SCROLL */
X for (i=0; i<rnd(12)+11; i++)
X fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */
X if (j==5)
X fillroom(OBANK2,0); /* branch office of the bank */
X froom(2,ORING,0); /* a ring mail */
X froom(1,OSTUDLEATHER,0); /* a studded leather */
X froom(3,OSPLINT,0); /* a splint mail */
X froom(5,OSHIELD,rund(3)); /* a shield */
X froom(2,OBATTLEAXE,rund(3)); /* a battle axe */
X froom(5,OLONGSWORD,rund(3)); /* a long sword */
X froom(5,OFLAIL,rund(3)); /* a flail */
X froom(4,OREGENRING,rund(3)); /* ring of regeneration */
X froom(1,OPROTRING,rund(3)); /* ring of protection */
X froom(2,OSTRRING,1+rnd(3)); /* ring of strength */
X froom(7,OSPEAR,rnd(5)); /* a spear */
X froom(3,OORBOFDRAGON,0); /* orb of dragon slaying*/
X froom(4,OSPIRITSCARAB,0); /* scarab of negate spirit*/
X froom(4,OCUBEofUNDEAD,0); /* cube of undead control */
X froom(2,ORINGOFEXTRA,0); /* ring of extra regen */
X froom(3,ONOTHEFT,0); /* device of antitheft */
X froom(2,OSWORDofSLASHING,0); /* sword of slashing */
X if (c[BESSMANN]==0)
X {
X froom(4,OHAMMER,0);/*Bessman's flailing hammer*/
X c[BESSMANN]=1;
X }
X if (c[HARDGAME]<3 || (rnd(4)==3))
X {
X if (j>3)
X {
X froom(3,OSWORD,3); /* sunsword + 3 */
X froom(5,O2SWORD,rnd(4)); /* a two handed sword */
X froom(3,OBELT,4); /* belt of striking */
X froom(3,OENERGYRING,3); /* energy ring */
X froom(4,OPLATE,5); /* platemail + 5 */
X froom(3,OCLEVERRING,1+rnd(2)); /* ring of cleverness */
X }
X }
X }
X
X/*
X subroutine to fill in a number of objects of the same kind
X */
X
Xstatic fillmroom(n,what,arg)
X int n,arg;
X char what;
X {
X register int i;
X for (i=0; i<n; i++) fillroom(what,arg);
X }
Xstatic froom(n,itm,arg)
X int n,arg;
X char itm;
X { if (rnd(151) < n) fillroom(itm,arg); }
X
X/*
X subroutine to put an object into an empty room
X * uses a random walk
X */
Xstatic fillroom(what,arg)
X int arg;
X char what;
X {
X register int x,y;
X
X#ifdef EXTRA
X c[FILLROOM]++;
X#endif
X
X x=rnd(MAXX-2); y=rnd(MAXY-2);
X while (item[x][y])
X {
X
X#ifdef EXTRA
X c[RANDOMWALK]++; /* count up these random walks */
X#endif
X
X x += rnd(3)-2; y += rnd(3)-2;
X if (x > MAXX-2) x=1; if (x < 1) x=MAXX-2;
X if (y > MAXY-2) y=1; if (y < 1) y=MAXY-2;
X }
X item[x][y]=what; iarg[x][y]=arg;
X }
X
X/*
X subroutine to put monsters into an empty room without walls or other
X monsters
X */
Xfillmonst(what)
X char what;
X {
X register int x,y,trys;
X for (trys=5; trys>0; --trys) /* max # of creation attempts */
X {
X x=rnd(MAXX-2); y=rnd(MAXY-2);
X if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y)))
X {
X mitem[x][y] = what; know[x][y] &= ~KNOWHERE;
X hitp[x][y] = monster[what].hitpoints; return(0);
X }
X }
X return(-1); /* creation failure */
X }
X
X/*
X creates an entire set of monsters for a level
X must be done when entering a new level
X if sethp(1) then wipe out old monsters else leave them there
X */
Xstatic sethp(flg)
X int flg;
X {
X register int i,j;
X if (flg) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0;
X if (level==0) { c[TELEFLAG]=0; return; } /* if teleported and found level 1 then know level we are on */
X if (flg) j = rnd(12) + 2 + (level>>1); else j = (level>>1) + 1;
X for (i=0; i<j; i++) fillmonst(makemonst(level));
X }
X
X/*
X * Function to destroy all genocided monsters on the present level
X */
Xstatic checkgen()
X {
X register int x,y;
X for (y=0; y<MAXY; y++)
X for (x=0; x<MAXX; x++)
X if (monster[mitem[x][y]].genocided)
X mitem[x][y]=0; /* no more monster */
X }
END_OF_FILE
if test 15884 -ne `wc -c <'create.c'`; then
echo shar: \"'create.c'\" unpacked with wrong size!
fi
# end of 'create.c'
fi
if test -f 'diag.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'diag.c'\"
else
echo shar: Extracting \"'diag.c'\" \(14227 characters\)
sed "s/^X//" >'diag.c' <<'END_OF_FILE'
X/* diag.c */
X#ifdef VMS
X# include <types.h>
X# include <stat.h>
X#else
X# include <sys/types.h>
X# include <sys/stat.h>
X#endif VMS
X
X#ifndef AMIGA
X# ifndef MSDOS
X# ifndef VMS
X# include <sys/times.h>
X static struct tms cputime;
X# endif VMS
X# endif MSDOS
X#endif AMIGA
X
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
Xextern long int initialtime;
Xextern int rmst,maxitm,lasttime;
Xextern char nosignal;
X
X/*
X ***************************
X DIAG -- dungeon diagnostics
X ***************************
X
X subroutine to print out data for debugging
X */
X#ifdef EXTRA
Xstatic int rndcount[16];
Xdiag()
X {
X register int i,j;
X int hit,dam;
X cursors(); lwclose();
X if (lcreat(diagfile) < 0) /* open the diagnostic file */
X {
X lcreat((char*)0); lprcat("\ndiagnostic failure\n"); return(-1);
X }
X
X write(1,"\nDiagnosing . . .\n",18);
X lprcat("\n\nBeginning of DIAG diagnostics ----------\n");
X
X/* for the character attributes */
X
X lprintf("\n\nPlayer attributes:\n\nHit points: %2d(%2d)",(long)c[HP],(long)c[HPMAX]);
X lprintf("\ngold: %d Experience: %d Character level: %d Level in caverns: %d",
X (long)c[GOLD],(long)c[EXPERIENCE],(long)c[LEVEL],(long)level);
X lprintf("\nTotal types of monsters: %d",(long)MAXMONST+8);
X
X lprcat("\f\nHere's the dungeon:\n\n");
X
X i=level;
X for (j=0; j<MAXLEVEL+MAXVLEVEL; j++)
X {
X newcavelevel(j);
X lprintf("\nMaze for level %s:\n",levelname[level]);
X diagdrawscreen();
X }
X newcavelevel(i);
X
X lprcat("\f\nNow for the monster data:\n\n");
X lprcat(" Monster Name LEV AC DAM ATT DEF GOLD HP EXP \n");
X lprcat("--------------------------------------------------------------------------\n");
X for (i=0; i<=MAXMONST+8; i++)
X {
X lprintf("%19s %2d %3d ",monster[i].name,(long)monster[i].level,(long)monster[i].armorclass);
X lprintf(" %3d %3d %3d ",(long)monster[i].damage,(long)monster[i].attack,(long)monster[i].defense);
X lprintf("%6d %3d %6d\n",(long)monster[i].gold,(long)monster[i].hitpoints,(long)monster[i].experience);
X }
X
X lprcat("\n\nHere's a Table for the to hit percentages\n");
X lprcat("\n We will be assuming that players level = 2 * monster level");
X lprcat("\n and that the players dexterity and strength are 16.");
X lprcat("\n to hit: if (rnd(22) < (2[monst AC] + your level + dex + WC/8 -1)/2) then hit");
X lprcat("\n damage = rund(8) + WC/2 + STR - c[HARDGAME] - 4");
X lprcat("\n to hit: if rnd(22) < to hit then player hits\n");
X lprcat("\n Each entry is as follows: to hit / damage / number hits to kill\n");
X lprcat("\n monster WC = 4 WC = 20 WC = 40");
X lprcat("\n---------------------------------------------------------------");
X for (i=0; i<=MAXMONST+8; i++)
X {
X hit = 2*monster[i].armorclass+2*monster[i].level+16;
X dam = 16 - c[HARDGAME];
X lprintf("\n%20s %2d/%2d/%2d %2d/%2d/%2d %2d/%2d/%2d",
X monster[i].name,
X (long)(hit/2),(long)max(0,dam+2),(long)(monster[i].hitpoints/(dam+2)+1),
X (long)((hit+2)/2),(long)max(0,dam+10),(long)(monster[i].hitpoints/(dam+10)+1),
X (long)((hit+5)/2),(long)max(0,dam+20),(long)(monster[i].hitpoints/(dam+20)+1));
X }
X
X lprcat("\n\nHere's the list of available potions:\n\n");
X for (i=0; i<MAXPOTION; i++) lprintf("%20s\n",&potionname[i][1]);
X lprcat("\n\nHere's the list of available scrolls:\n\n");
X for (i=0; i<MAXSCROLL; i++) lprintf("%20s\n",&scrollname[i][1]);
X lprcat("\n\nHere's the spell list:\n\n");
X lprcat("spell name description\n");
X lprcat("-------------------------------------------------------------------------------------------\n\n");
X for (j=0; j<SPNUM; j++)
X {
X lprc(' '); lprcat(spelcode[j]);
X lprintf(" %21s %s\n",spelname[j],speldescript[j]);
X }
X
X lprcat("\n\nFor the c[] array:\n");
X for (j=0; j<100; j+=10)
X {
X lprintf("\nc[%2d] = ",(long)j); for (i=0; i<9; i++) lprintf("%5d ",(long)c[i+j]);
X }
X
X lprcat("\n\nTest of random number generator ----------------");
X lprcat("\n for 25,000 calls divided into 16 slots\n\n");
X
X for (i=0; i<16; i++) rndcount[i]=0;
X for (i=0; i<25000; i++) rndcount[rund(16)]++;
X for (i=0; i<16; i++) { lprintf(" %5d",(long)rndcount[i]); if (i==7) lprc('\n'); }
X
X lprcat("\n\n"); lwclose();
X lcreat((char*)0); lprcat("Done Diagnosing . . .");
X return(0);
X }
X/*
X subroutine to count the number of occurrences of an object
X */
Xdcount(l)
X int l;
X {
X register int i,j,p;
X int k;
X k=0;
X for (i=0; i<MAXX; i++)
X for (j=0; j<MAXY; j++)
X for (p=0; p<MAXLEVEL; p++)
X if (cell[(long) p*MAXX*MAXY+i*MAXY+j].item == l) k++;
X return(k);
X }
X
X/*
X subroutine to draw the whole screen as the player knows it
X */
Xdiagdrawscreen()
X {
X register int i,j,k;
X
X for (i=0; i<MAXY; i++)
X
X/* for the east west walls of this line */
X {
X for (j=0; j<MAXX; j++) if (k=mitem[j][i]) lprc(monstnamelist[k]); else
X lprc(objnamelist[item[j][i]]);
X lprc('\n');
X }
X }
X#endif
X
X/*
X to save the game in a file
X */
Xstatic long int zzz=0;
Xsavegame(fname)
X char *fname;
X {
X extern char lastmonst[], course[];
X register int i,k;
X register struct sphere *sp;
X struct stat statbuf;
X# ifdef MSDOS
X struct cel buf[MAXX];
X RAMBLOCK *rp;
X DISKBLOCK *dp;
X# endif
X
X nosignal=1; lflush(); savelevel();
X ointerest();
X if (lcreat(fname) < 0)
X {
X lcreat((char*)0); lprintf("\nCan't open file <%s> to save game\n",fname);
X nosignal=0; return(-1);
X }
X
X set_score_output();
X
X# ifdef MSDOS
X lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X
X /* Some levels may be out on disk, some are in memory.
X */
X for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++)
X if (beenhere[k]) {
X
X /* Is the level in memory already ?
X */
X for (rp = ramblks; rp; rp = rp->next)
X if (rp->level == k)
X break;
X if (rp != NULL) {
X lwrite((char *) &rp->gtime, sizeof (long));
X warn(" %d", k);
X# ifdef ndef
X warn("From memory\n", k);
X# endif
X lwrite((char *) rp->cell, sizeof rp->cell);
X continue;
X }
X
X /* Is it on disk ?
X */
X for (dp = diskblks; dp; dp = dp->next)
X if (dp->level == k)
X break;
X
X if (dp == NULL) {
X levelinfo();
X error("Level %d is neither in memory nor on disk\n", k);
X }
X
X /* Copy the contents of the SWAPFILE */
X lwrite((char *) &dp->gtime, sizeof (long));
X# ifdef ndef
X warn("From swap file...\n", k);
X# endif
X warn(" %ds", k);
X if (lseek(swapfd, dp->fpos, 0) < 0) {
X warn("Can't seek to %ld\n", dp->fpos);
X return -1;
X }
X for (i = 0; i < MAXY; i++) {
X# ifdef ndef
X warn("Copying swap file...\n");
X# endif
X if (vread(swapfd, (char *) buf, sizeof buf) !=
X sizeof buf) {
X warn("Swap file short!\n");
X return -1;
X }
X lwrite((char *) buf, sizeof buf);
X }
X }
X# else
X lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
X if (beenhere[k])
X lwrite((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
X# endif
X
X#ifndef AMIGA
X# ifndef VMS
X# ifndef MSDOS
X times(&cputime); /* get cpu time */
X c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60;
X# endif MSDOS
X# endif VMS
X#endif AMIGA
X
X lwrite((char*)&c[0],100*sizeof(long));
X lprint((long)gtime); lprc(level);
X lprc(playerx); lprc(playery);
X lwrite((char*)iven,26); lwrite((char*)ivenarg,26*sizeof(short));
X for (k=0; k<MAXSCROLL; k++) lprc(scrollname[k][0]);
X for (k=0; k<MAXPOTION; k++) lprc(potionname[k][0]);
X lwrite((char*)spelknow,SPNUM); lprc(wizard);
X lprc(rmst); /* random monster generation counter */
X for (i=0; i<90; i++) lprc(itm[i].qty);
X lwrite((char*)course,25); lprc(cheat); lprc(VERSION);
X for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */
X for (sp=spheres; sp; sp=sp->p)
X lwrite((char*)sp,sizeof(struct sphere)); /* save spheres of annihilation */
X time(&zzz); lprint((long)(zzz-initialtime));
X lwrite((char*)&zzz,sizeof(long));
X# ifndef MSDOS
X#ifdef AMIGA
X if(stat(fname, &statbuf) < 0)
X#else
X if(fstat(lfd,&statbuf) < 0)
X#endif /* AMIGA */
X lprint(0L);
X else lprint((long)statbuf.st_ino); /* inode # */
X# endif
X
X lwclose(); lastmonst[0] = 0;
X#ifndef VT100
X setscroll();
X#endif VT100
X lcreat((char*)0); nosignal=0;
X return(0);
X }
X
Xrestoregame(fname)
X char *fname;
X {
X register int i,k;
X register struct sphere *sp,*sp2;
X struct stat filetimes;
X# ifdef MSDOS
X RAMBLOCK *rp, *getramblk();
X# endif
X
X cursors(); lprcat("\nRestoring . . ."); lflush();
X if (lopen(fname) <= 0)
X {
X lcreat((char*)0); lprintf("\nCan't open file <%s>to restore game\n",fname);
X nap(2000); c[GOLD]=c[BANKACCOUNT]=0; died(-265); return;
X }
X lrfill((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X
X# ifdef MSDOS
X /* As levels get read in from the save file, store them away
X * by calling putsavelevel.
X */
X for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++)
X if (beenhere[k]) {
X rp = getramblk(k);
X lrfill((char *) &rp->gtime, sizeof (long));
X lrfill((char *) rp->cell, sizeof rp->cell);
X rp->level = k;
X }
X# else
X for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
X if (beenhere[k])
X lrfill((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
X# endif
X
X lrfill((char*)&c[0],100*sizeof(long)); gtime = lrint();
X level = c[CAVELEVEL] = lgetc();
X playerx = lgetc(); playery = lgetc();
X lrfill((char*)iven,26); lrfill((char*)ivenarg,26*sizeof(short));
X for (k=0; k<MAXSCROLL; k++) scrollname[k][0] = lgetc();
X for (k=0; k<MAXPOTION; k++) potionname[k][0] = lgetc();
X lrfill((char*)spelknow,SPNUM); wizard = lgetc();
X rmst = lgetc(); /* random monster creation flag */
X
X for (i=0; i<90; i++) itm[i].qty = lgetc();
X lrfill((char*)course,25); cheat = lgetc();
X if (VERSION != lgetc()) /* version number */
X {
X cheat=1;
X lprcat("Sorry, But your save file is for an older version of larn\n");
X nap(2000); c[GOLD]=c[BANKACCOUNT]=0; died(-266); return;
X }
X
X for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc(); /* genocide info */
X for (sp=0,i=0; i<c[SPHCAST]; i++)
X {
X sp2 = sp;
X sp = (struct sphere *)malloc(sizeof(struct sphere));
X if (sp==0) { write(2,"Can't malloc() for sphere space\n",32); break; }
X lrfill((char*)sp,sizeof(struct sphere)); /* get spheres of annihilation */
X sp->p=0; /* null out pointer */
X if (i==0) spheres=sp; /* beginning of list */
X else sp2->p = sp;
X }
X
X time(&zzz);
X initialtime = zzz-lrint();
X#ifdef AMIGA
X stat(fname, &filetimes);
X#else
X fstat(fd,&filetimes); /* get the creation and modification time of file */
X#endif /* AMIGA */
X lrfill((char*)&zzz,sizeof(long)); zzz += 6;
X if (filetimes.st_ctime > zzz) fsorry(); /* file create time */
X else if (filetimes.st_mtime > zzz) fsorry(); /* file modify time */
X if (c[HP]<0) { died(284); return; } /* died a post mortem death */
X
X oldx = oldy = 0;
X#ifndef VMS
X# ifndef MSDOS
X i = lrint(); /* inode # */
X if (i && (filetimes.st_ino!=i)) fsorry();
X# endif MSDOS
X#endif VMS
X lrclose();
X if (strcmp(fname,ckpfile) == 0)
X {
X if (lappend(fname) < 0) fcheat(); else { lprc(' '); lwclose(); }
X lcreat((char*)0);
X }
X else if (unlink(fname) < 0) fcheat(); /* can't unlink save file */
X/* for the greedy cheater checker */
X for (k=0; k<6; k++) if (c[k]>99) greedy();
X if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy();
X if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) /* if patch up lev 25 player */
X {
X long tmp;
X tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
X c[EXPERIENCE] = skill[24];
X raiseexperience((long)tmp);
X }
X getlevel(); lasttime=gtime;
X }
X
X/*
X subroutine to not allow greedy cheaters
X */
Xstatic greedy()
X {
X#if WIZID
X if (wizard) return;
X#endif
X
X lprcat("\n\nI am so sorry, but your character is a little TOO good! Since this\n");
X lprcat("cannot normally happen from an honest game, I must assume that you cheated.\n");
X lprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n");
X lprcat("to continue.\n"); nap(5000); c[GOLD]=c[BANKACCOUNT]=0; died(-267); return;
X }
X
X/*
X subroutine to not allow altered save files and terminate the attempted
X restart
X */
Xstatic fsorry()
X {
X lprcat("\nSorry, but your savefile has been altered.\n");
X lprcat("However, seeing as I am a good sport, I will let you play.\n");
X lprcat("Be advised though, you won't be placed on the normal scoreboard.");
X cheat = 1; nap(4000);
X }
X
X/*
X subroutine to not allow game if save file can't be deleted
X */
Xstatic fcheat()
X {
X#if WIZID
X if (wizard) return;
X#endif
X
X lprcat("\nSorry, but your savefile can't be deleted. This can only mean\n");
X lprcat("that you tried to CHEAT by protecting the directory the savefile\n");
X lprcat("is in. Since this is unfair to the rest of the larn community, I\n");
X lprcat("cannot let you play this game.\n");
X nap(5000); c[GOLD]=c[BANKACCOUNT]=0; died(-268); return;
X }
END_OF_FILE
if test 14227 -ne `wc -c <'diag.c'`; then
echo shar: \"'diag.c'\" unpacked with wrong size!
fi
# end of 'diag.c'
fi
if test -f 'tok.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tok.c'\"
else
echo shar: Extracting \"'tok.c'\" \(13574 characters\)
sed "s/^X//" >'tok.c' <<'END_OF_FILE'
X/* tok.c */
X/*
X yylex()
X flushall()
X sethard()
X readopts()
X actual_readopts()
X*/
X#ifdef VMS
X#include <types.h>
X#include <file.h>
X#include <iodef.h>
X#else VMS
X#include <sys/types.h>
X#ifdef SYSV
X#include <fcntl.h>
X# ifndef MSDOS
X# include <termio.h>
X# endif
X#else SYSV
X# ifndef AMIGA
X# ifndef MSDOS
X# include <sys/ioctl.h>
X# endif MSDOS
X# endif AMIGA
X#endif SYSV
X#endif VMS
X
X#include <ctype.h>
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X#ifdef __STDC__
Xstatic void actual_readopts( char*, char* );
X#else
Xstatic void actual_readopts();
X#endif
X
X# define CHKPTINT 400
X
Xstatic char lastok=0;
Xint yrepcount=0;
Xchar move_no_pickup = FALSE ;
X
X#ifdef TIMECHECK
Xint dayplay=0;
X#endif TIMECHECK
X
X#ifndef FLUSHNO
X#define FLUSHNO 5
X#endif FLUSHNO
Xstatic int flushno=FLUSHNO; /* input queue flushing threshold */
X#define MAXUM 52 /* maximum number of user re-named monsters */
X#define MAXMNAME 40 /* max length of a monster re-name */
Xstatic char usermonster[MAXUM][MAXMNAME]; /* the user named monster name goes here */
Xstatic char usermpoint=0; /* the user monster pointer */
X#ifdef MSDOS
X extern int rawio;
X#endif
X
X/*
X lexical analyzer for larn
X */
Xyylex()
X {
X char cc;
X int ic;
X char firsttime = TRUE;
X
X if (hit2flag)
X {
X hit2flag=0;
X yrepcount=0;
X return(' ');
X }
X if (yrepcount>0)
X {
X --yrepcount;
X return(lastok);
X }
X else
X yrepcount=0;
X if (yrepcount==0)
X {
X bottomdo();
X showplayer(); /* show where the player is */
X move_no_pickup = FALSE; /* clear 'm' flag */
X }
X
X lflush();
X while (1)
X {
X c[BYTESIN]++;
X if (ckpflag)
X if ((c[BYTESIN] % CHKPTINT) == 0) /* check for periodic checkpointing */
X {
X#ifndef DOCHECKPOINTS
X#ifdef MSDOS|AMIGA
X cursors();
X lprcat("\nCheckpointing . . .");
X savegame(ckpfile);
X lprcat("\nDone\n");
X showplayer();
X lflush();
X lflushall(); /* Kill any stored key strokes */
X#else
X#ifdef VMS
X savegame(ckpfile);
X#else
X wait(0); /* wait for other forks to finish */
X if (fork() == 0) { savegame(ckpfile); exit(); }
X#endif
X#endif
X#else
X#ifdef VMS
X savegame(ckpfile);
X#else
X wait(0); /* wait for other forks to finish */
X if (fork() == 0) { savegame(ckpfile); exit(); }
X#endif
X#endif
X
X#ifdef TIMECHECK
X if (dayplay==0)
X if (playable())
X {
X cursor(1,19);
X lprcat("\nSorry, but it is now time for work. Your game has been saved.\n"); beep();
X lflush();
X savegame(savefilename);
X wizard=nomove=1;
X sleep(4);
X died(-257);
X }
X#endif TIMECHECK
X
X }
X# ifdef AMIGA
X FlushKBD();
X# else
X# ifndef MSDOS
X# ifdef VMS
X /* If keyboard input buffer is too big then flush some? RDE */
X /* Check this! but for now just ignore it... */
X# else
X# ifndef SYSV
X do /* if keyboard input buffer is too big, flush some of it */
X {
X ioctl(0,FIONREAD,&ic);
X if (ic>flushno) read(0,&cc,1);
X }
X while (ic>flushno);
X# endif SYSV
X# endif VMS
X# endif MSDOS
X# endif AMIGA
X
X# ifdef AMIGA
X cc = AmGetch();
X# else
X# ifdef MSDOS
X cc = ttgetch();
X# else MSDOS
X# ifdef VMS
X cc = ttgetch();
X# else
X if (read(0,&cc,1) != 1)
X return(lastok = -1);
X# endif VMS
X# endif MSDOS
X# endif AMIGA
X if (cc == '!') /* ! shell escape */
X {
X resetscroll(); /* scrolling region, home, clear, no attributes */
X clear();
X# ifdef AMIGA
X DoShell();
X# else
X# ifdef MSDOS
X doshell();
X# else MSDOS
X# ifdef VMS
X lflush();
X sncbr();
X oneliner("");
X scbr();
X# else VMS
X lflush();
X sncbr();
X if ((ic=fork())==0) /* child */
X {
X#ifdef SYSV
X char *s, *getenv();
X if ((s=getenv("SHELL")) == (char *) 0)
X s = "/bin/sh";
X execl(s,"larn-shell", (char *)0);
X exit();
X#else
X execl("/bin/csh",0);
X exit();
X wait(0);
X#endif
X }
X if (ic<0) /* error */
X {
X write(2,"Can't fork off a shell!\n",25);
X sleep(2);
X }
X#ifdef SYSV
X else
X wait( (int *)0 );
X#endif SYSV
X# endif VMS
X# endif MSDOS
X# endif AMIGA
X setscroll();
X return(lastok = 'L'-64); /* redisplay screen */
X }
X
X /* get repeat count, showing to player
X */
X if ((cc <= '9') && (cc >= '0'))
X {
X yrepcount = yrepcount*10 + cc - '0';
X
X /* show count to player for feedback
X */
X if ( yrepcount >= 10 )
X {
X cursors();
X if (firsttime)
X lprcat("\n");
X lprintf("count: %d", (long)yrepcount );
X firsttime=FALSE;
X lflush(); /* show count */
X }
X }
X else
X {
X /* check for multi-character commands in command mode, and handle.
X */
X if ( cc == 'm' && !prompt_mode )
X {
X move_no_pickup = TRUE ;
X cc = ttgetch();
X }
X if ( yrepcount > 0 )
X --yrepcount;
X return(lastok = cc);
X }
X }
X }
X
X/*
X * flushall() Function to flush all type-ahead in the input buffer
X */
Xlflushall()
X {
X# ifdef AMIGA
X FlushKBD();
X# else AMIGA
X# ifdef MSDOS
X while (kbhit())
X getch();
X# else MSDOS
X# ifdef VMS
X /* Flush all type-ahead -- RDE */
X extern int iochan; /* defined in IO.C */
X int c;
X
X SYS$QIOW(0,iochan,IO$_READLBLK|IO$M_TIMED|IO$M_PURGE,0,0,0,&c,1,0,0,0,0);
X
X# else VMS
X#ifdef SYSV
X ioctl(0,TCFLSH,0);
X#else
X char cc;
X int ic;
X for (;;) { /* if keyboard input buffer is too big, flush some of it */
X ioctl(0,FIONREAD,&ic);
X if (ic<=0)
X return;
X while (ic>0) {
X read(0,&cc,1);
X --ic;
X } /* gobble up the byte */
X }
X# endif SYSV
X# endif VMS
X# endif MSDOS
X# endif AMIGA
X}
X
X/*
X function to set the desired hardness
X enter with hard= -1 for default hardness, else any desired hardness
X */
Xsethard(hard)
Xint hard;
X{
X register int j,k;
X long i;
X struct monst *mp;
X
X j=c[HARDGAME]; hashewon();
X if (restorflag==0) /* don't set c[HARDGAME] if restoring game */
X {
X if (hard >= 0) c[HARDGAME]= hard;
X }
X else c[HARDGAME]=j; /* set c[HARDGAME] to proper value if restoring game */
X
X if (k=c[HARDGAME])
X for (j=0; j<=MAXMONST+8; j++) {
X mp = &monster[j];
X i = ((6+k) * mp->hitpoints + 1)/6;
X mp->hitpoints = (i<0) ? 32767 : i;
X i = ((6+k) * mp->damage + 1) / 5;
X mp->damage = (i>127) ? 127 : i;
X i = (10 * mp->gold)/(10+k);
X mp->gold = (i>32767) ? 32767 : i;
X i = mp->armorclass - k;
X mp->armorclass = (i< -127) ? -127 : i;
X i = (7*mp->experience)/(7+k) + 1;
X mp->experience = (i<=0) ? 1 : i;
X }
X}
X
X
X/*
X function to read and process the larn options file
X*/
Xreadopts()
X {
X register int j;
X char original_objects = FALSE ;
X char namenotchanged = TRUE; /* set to 0 if a name is specified */
X
X# ifdef MSDOS
X if (plopen(optsfile) < 0)
X# else
X if (lopen(optsfile) < 0)
X# endif
X {
X lprintf("Can't open options file \"%s\"\n", optsfile);
X lflush();
X sleep(1);
X }
X else
X actual_readopts(&namenotchanged, &original_objects);
X
X if (namenotchanged)
X strcpy(logname,loginname);
X
X /* original objects require object highlighting to be ON (in order
X to distinguish between objects and monsters). set up object list
X properly.
X */
X if (original_objects)
X {
X boldobjects = TRUE ;
X strncpy( objnamelist, original_objnamelist, MAXOBJECT );
X }
X else
X strncpy( objnamelist, hacklike_objnamelist, MAXOBJECT );
X objnamelist[MAXOBJECT] = '\0' ;
X
X /* now set all the invisible objects and monsters to have the
X same appearance as the floor (as defined by the user)
X */
X objnamelist[OWALL] = wallc;
X
X objnamelist[0] =
X objnamelist[OIVTELETRAP] =
X objnamelist[OTRAPARROWIV] =
X objnamelist[OIVDARTRAP] =
X objnamelist[OIVTRAPDOOR] = floorc;
X monstnamelist[0] =
X monstnamelist[INVISIBLESTALKER] = floorc;
X for (j=DEMONLORD; j<=DEMONPRINCE; j++)
X monstnamelist[j] = floorc;
X }
X
Xstatic void actual_readopts( namenotchanged, original_objects )
Xchar *namenotchanged;
Xchar *original_objects;
X {
X register char *i;
X register int j,k;
X
X i = " ";
X while (*i)
X {
X /* check for EOF
X */
X if ((i=(char *)lgetw()) == 0)
X return;
X#if 0
X while (*i && ((*i==' ') || (*i=='\t'))) i++; /* eat leading whitespace */
X#endif
X /* leading # a comment, eat the rest of the line. Handle multiple
X comment lines in a row.
X */
X while (*i == '#')
X {
X char cc;
X do
X cc = (char)lgetc();
X while ( ( cc != '\n' ) && ( cc != NULL));
X if ((i = (char *)lgetw()) == 0)
X return;
X }
X
X if (strcmp(i,"bold-objects") == 0)
X boldon=1;
X else if (strcmp(i,"enable-checkpointing") == 0)
X ckpflag=1;
X else if (strcmp(i,"inverse-objects") == 0)
X boldon=0;
X else if (strcmp(i,"prompt-on-objects") == 0 )
X prompt_mode = TRUE ;
X else if (strcmp(i,"auto-pickup") == 0 )
X auto_pickup = TRUE ;
X else if (strcmp(i,"highlight-objects") == 0 )
X boldobjects = TRUE ;
X else if (strcmp(i,"original-objects") == 0 )
X *original_objects = TRUE ;
X else if (strcmp(i,"female") == 0)
X sex=0; /* male or female */
X# ifdef MSDOS
X else if (strcmp(i, "graphics:") == 0)
X {
X wallc = atoi(lgetw());
X floorc = atoi(lgetw());
X }
X else if (strcmp(i, "larndir:") == 0)
X {
X if ((i=lgetw())==0)
X break;
X strncpy(larndir, i, DIRLEN);
X larndir[DIRLEN - 1] = 0;
X }
X else if (strcmp(i, "rawio") == 0)
X rawio = 1;
X else if (strcmp(i, "swapfile:") == 0)
X {
X if ((i = (char *)lgetw()) == 0)
X break;
X strncpy(swapfile, i, PATHLEN);
X swapfile[PATHLEN - 1] = 0;
X }
X else if (strcmp(i, "ramlevels:") == 0)
X ramlevels = atoi(lgetw());
X else if (strcmp(i, "cursor:") == 0)
X {
X cursorset = 1;
X cursorstart = (unsigned char) atoi(lgetw());
X cursorend = (unsigned char) atoi(lgetw());
X }
X else if (strcmp(i, "keypad") == 0)
X keypad = 1;
X else if (strcmp(i, "DECRainbow") == 0)
X DECRainbow = 1;
X# endif
X else if (strcmp(i,"monster:")== 0) /* name favorite monster */
X {
X if ((i=(char *)lgetw())==0)
X break;
X if (strlen(i)>=MAXMNAME)
X i[MAXMNAME-1]=0;
X strcpy(usermonster[usermpoint],i);
X if (usermpoint >= MAXUM)
X break; /* defined all of em */
X if (isalpha(j=usermonster[usermpoint][0]))
X {
X for (k=1; k<MAXMONST+8; k++) /* find monster */
X if (monstnamelist[k] == j)
X {
X monster[k].name = &usermonster[usermpoint++][0];
X break;
X }
X }
X }
X else if (strcmp(i,"male") == 0)
X sex=1;
X else if (strcmp(i,"name:") == 0) /* defining players name */
X {
X if ((i=lgetw())==0)
X break;
X if (strlen(i)>=LOGNAMESIZE)
X i[LOGNAMESIZE-1]=0;
X strcpy(logname,i);
X *namenotchanged = FALSE;
X# ifdef MSDOS
X strcpy(loginname,i);
X# endif
X }
X else if (strcmp(i,"no-introduction") == 0)
X nowelcome=1;
X else if (strcmp(i,"no-beep") == 0)
X nobeep=1;
X# ifndef MSDOS
X else if (strcmp(i,"process-name:")== 0)
X {
X if ((i=lgetw())==0)
X break;
X if (strlen(i)>=PSNAMESIZE)
X i[PSNAMESIZE-1]=0;
X strcpy(psname,i);
X }
X else if (strcmp(i,"play-day-play") == 0)
X# ifdef TIMECHECK
X dayplay=1;
X# else
X ;
X# endif
X# endif
X else if (strcmp(i,"savefile:") == 0) /* defining savefilename */
X {
X if ((i=lgetw())==0)
X break;
X if (strlen(i)>=SAVEFILENAMESIZE) /* avoid overflow */
X i[SAVEFILENAMESIZE-1]=0;
X strcpy(savefilename,i);
X }
X else
X {
X lprintf("Unknown option \"%s\"\n", i);
X lflush();
X sleep(1);
X }
X }
X }
END_OF_FILE
if test 13574 -ne `wc -c <'tok.c'`; then
echo shar: \"'tok.c'\" unpacked with wrong size!
fi
# end of 'tok.c'
fi
echo shar: End of archive 6 \(of 17\).
cp /dev/null ark6isdone
#!/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 3 (of 17)."
# Contents: amiga.c larn123.fix makefile.pc nansi.doc spheres.c
# tgetstr.c vms.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:52 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'amiga.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'amiga.c'\"
else
echo shar: Extracting \"'amiga.c'\" \(6717 characters\)
sed "s/^X//" >'amiga.c' <<'END_OF_FILE'
X#ifdef AMIGA
X
X#include <intuition/intuition.h>
X
X/*
X *
X * Author : Simon J Raybould. (s...@fulcrum.bt.co.uk).
X *
X * Date : 25th January 1991.
X *
X * Desc : Amiga specific code for Larn
X *
X */
X
X
Xstruct NewWindow nw = {
X 0, 0, 640,256, -1,-1,
X NULL,
X WINDOWDEPTH|WINDOWDRAG|SMART_REFRESH|ACTIVATE|BORDERLESS,
X NULL,
X NULL,
X "Larn V12.3 Amiga Port by S.J.Raybould Apr 1991",
X NULL,
X NULL,
X 0,0,
X 0,0,
X WBENCHSCREEN
X};
X
X
X/* Opens/allocations we'll need to clean up */
Xstruct Library *IntuitionBase = NULL;
Xstruct Window *win = NULL, *OpenWindow();
Xstruct IOStdReq *writeReq = NULL; /* I/O request block pointer */
Xstruct MsgPort *writePort = NULL; /* replyport for writes */
Xstruct IOStdReq *readReq = NULL; /* I/O request block pointer */
Xstruct MsgPort *readPort = NULL; /* replyport for reads */
Xstruct MsgPort *CreatePort();
XBOOL OpenedConsole = FALSE;
X
X#define AM_ECHO 1
X#define AM_CBREAK 2
X
Xvoid CloseConsole(), ConPuts(), QueueRead(), AmEnd();
XBYTE OpenConsole();
XUBYTE ibuf, GetchFlags = AM_ECHO;
X
Xvoid AmInit()
X{
X ULONG conreadsig, windowsig;
X BYTE error;
X
X if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0))) {
X printf("Can't open intuition\n");
X AmEnd();
X exit(10);
X }
X
X /* Create reply port and io block for writing to console */
X if(!(writePort = CreatePort("LARN.console.write",0))) {
X printf("Can't create write port\n");
X AmEnd();
X exit(10);
X }
X
X if(!(writeReq = (struct IOStdReq *)
X CreateExtIO(writePort,(LONG)sizeof(struct IOStdReq)))) {
X printf("Can't create write request\n");
X AmEnd();
X exit(10);
X }
X
X /* Create reply port and io block for reading from console */
X if(!(readPort = CreatePort("LARN.console.read",0))) {
X printf("Can't create read port\n");
X AmEnd();
X exit(10);
X }
X
X if(!(readReq = (struct IOStdReq *)
X CreateExtIO(readPort,(LONG)sizeof(struct IOStdReq)))) {
X printf("Can't create read request\n");
X AmEnd();
X exit(10);
X }
X
X /* Open a window */
X if(!(win = OpenWindow(&nw))) {
X printf("Can't open window\n");
X AmEnd();
X exit(10);
X }
X
X /* Now, attach a console to the window */
X if(error = OpenConsole(writeReq,readReq,win)) {
X printf("Can't open console.device\n");
X AmEnd();
X exit(10);
X } else
X OpenedConsole = TRUE;
X
X QueueRead(readReq,&ibuf); /* send the first console read request */
X conreadsig = 1 << readPort->mp_SigBit;
X windowsig = 1 << win->UserPort->mp_SigBit;
X}
X
Xvoid AmEnd()
X{
X if(!(CheckIO(readReq))) AbortIO(readReq);
X WaitIO(readReq);
X if(OpenedConsole) CloseConsole(writeReq);
X if(readReq) DeleteExtIO(readReq);
X if(readPort) DeletePort(readPort);
X if(writeReq) DeleteExtIO(writeReq);
X if(writePort) DeletePort(writePort);
X if(win) CloseWindow(win);
X if(IntuitionBase) CloseLibrary(IntuitionBase);
X}
X
X
X/* Attach console device to an open Intuition window.
X * This function returns a value of 0 if the console
X * device opened correctly and a nonzero value (the error
X * returned from OpenDevice) if there was an error.
X */
XBYTE OpenConsole(writereq, readreq, window)
X struct IOStdReq *writereq;
X struct IOStdReq *readreq;
X struct Window *window;
X{
X BYTE error;
X
X writereq->io_Data = (APTR) window;
X writereq->io_Length = sizeof(struct Window);
X error = OpenDevice("console.device", 0, writereq, 0);
X readreq->io_Device = writereq->io_Device; /* clone required parts */
X readreq->io_Unit = writereq->io_Unit;
X return(error);
X}
X
Xvoid CloseConsole(struct IOStdReq *writereq)
X{
X CloseDevice(writereq);
X}
X
X/* Output a single character to a specified console
X */
Xvoid ConPutChar(struct IOStdReq *writereq, UBYTE character)
X{
X writereq->io_Command = CMD_WRITE;
X writereq->io_Data = (APTR)&character;
X writereq->io_Length = 1;
X DoIO(writereq);
X /* command works because DoIO blocks until command is done
X * (otherwise ptr to the character could become invalid)
X */
X}
X
X
X/* Output a stream of known length to a console
X */
Xvoid ConWrite(struct IOStdReq *writereq, UBYTE *string, LONG length)
X{
X writereq->io_Command = CMD_WRITE;
X writereq->io_Data = (APTR)string;
X writereq->io_Length = length;
X DoIO(writereq);
X /* command works because DoIO blocks until command is done
X * (otherwise ptr to string could become invalid in the meantime)
X */
X}
X
X
X/* Output a NULL-terminated string of characters to a console
X */
Xvoid ConPuts(struct IOStdReq *writereq,UBYTE *string)
X{
X writereq->io_Command = CMD_WRITE;
X writereq->io_Data = (APTR)string;
X writereq->io_Length = -1; /* means print till terminating null */
X DoIO(writereq);
X}
X
X/* Queue up a read request to console, passing it pointer
X * to a buffer into which it can read the character
X */
Xvoid QueueRead(struct IOStdReq *readreq, UBYTE *whereto)
X{
X readreq->io_Command = CMD_READ;
X readreq->io_Data = (APTR)whereto;
X readreq->io_Length = 1;
X SendIO(readreq);
X}
X
X/* Check if a character has been received.
X * If none, return -1
X */
XLONG ConMayGetChar(struct MsgPort *msgport, UBYTE *whereto)
X{
X register temp;
X struct IOStdReq *readreq;
X
X if (!(readreq = (struct IOStdReq *)GetMsg(msgport))) return(-1);
X temp = *whereto; /* get the character */
X QueueRead(readreq,whereto); /* then re-use the request block */
X return(temp);
X}
X
X/* Wait for a character
X */
XUBYTE ConGetChar(struct MsgPort *msgport, UBYTE *whereto)
X{
X register temp;
X struct IOStdReq *readreq;
X
X WaitPort(msgport);
X readreq = (struct IOStdReq *)GetMsg(msgport);
X temp = *whereto; /* get the character */
X QueueRead(readreq,whereto); /* then re-use the request block*/
X return((UBYTE)temp);
X}
X
Xsleep(int n)
X{
X Delay(50*n);
X return 0;
X}
X
XDoShell()
X{
X printf("DoShell() - NOT IMPLEMENTED\n");
X}
X
Xvoid WriteConsole(char *Ptr, int Len)
X{
X ConWrite(writeReq, Ptr, Len);
X}
X
Xchar AmGetch()
X{
X static char Buffer[256];
X static int WPos = 0, RPos = 0;
X
X if(GetchFlags & AM_CBREAK) {
X RPos = WPos = 0;
X *Buffer = ConGetChar(readPort, &ibuf);
X return *Buffer;
X } else {
X if(RPos>=WPos) {
X /* Reset buffer markers */
X RPos = WPos = 0;
X /* Buffer up till CR spotted */
X do
X Buffer[WPos] = ConGetChar(readPort, &ibuf);
X while(Buffer[WPos++] != '\r');
X }
X return Buffer[RPos++];
X }
X}
X
XAmCBreak(int Flag)
X{
X if(Flag)
X GetchFlags |= AM_CBREAK;
X else
X GetchFlags &= ~AM_CBREAK;
X}
X
XAmEcho(int Flag)
X{
X if(Flag)
X GetchFlags |= AM_ECHO;
X else
X GetchFlags &= ~AM_ECHO;
X}
X
XFlushKBD()
X{
X /* TODO */
X}
X
X/*
X * Missing unix system calls.
X */
X
Xfork()
X{
X return -1;
X}
X
Xgetpid()
X{
X return FindTask(0L);
X}
X
Xkill()
X{
X return 0;
X}
X
X#endif /* AMIGA */
END_OF_FILE
if test 6717 -ne `wc -c <'amiga.c'`; then
echo shar: \"'amiga.c'\" unpacked with wrong size!
fi
# end of 'amiga.c'
fi
if test -f 'larn123.fix' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn123.fix'\"
else
echo shar: Extracting \"'larn123.fix'\" \(7408 characters\)
sed "s/^X//" >'larn123.fix' <<'END_OF_FILE'
XThis is a list of the fixes and enhancements made to create Larn V12.3 from
XLarn 12.2. SPOILER ALERT!
X
X1. The player's position is now marked with an ampersand, instead of just with
X the cursor.
X
X2. The 'G' command ("give the stairs a kick") has been removed. Since you can
X tell the stairs apart (as opposed to the original Larn 12.0), this command
X doesn't make sense anymore.
X
X3. The 'V' command has been removed and its information incorporated into the
X 'v' command.
X
X4. An idea from Ultra-Larn: when the player enters the 5th level branch of the
X bank after teleporting, the '?' in the level display is changed to a '5'.
X
X5. Larn -? can be used to print command line arguments.
X
X6. The player is no longer positioned near the shaft of the volcano when
X climbing down to the first volcano level.
X
X7. A couple of pauses were eliminated, making some actions very fast now.
X
X8. The player can no longer escape punishment by donating more gold then he
X possesses when praying at the altar.
X
X9. When performing an action and doing an inventory list, a character typed at
X the "press space for more" prompt is taken as the inventory item to select.
X That is, if you say 'q' for quaff, '*' to see all the potions you can quaff,
X Larn used to require that you type a space before you could select a potion,
X causing the list to disappear. You can now select an item in the list while
X the list is displayed. You can also use Escape and Return in place of a
X space.
X
X10. The spells/potions/scrolls inventory ('I' command) are now sorted.
X
X11. The '/' command has been added, to allow the user to identify objects.
X You can choose to either type a character or move the cursor around to
X select a character to identify (a la Hack). The only limitation is that
X characters that have several objects (weapons, gems, dragons, etc) display
X all the matching object names.
X
X12. The potion of gold detection has been changed into the potion of object
X detection. It will find scrolls, books, potions, weapons, armor, and
X artifacts. If you have an old savefile, all gold detection potions get
X turned into object detection potions.
X
X13. It is now possible to find rings of cleverness in the dungeon.
X
X14. It is now possible for killed monsters to drop splint mail, battle axes,
X cookies, and rings of cleverness.
X
X15. Source cleanup, reduction in the size of the executable and the memory
X required, performance improvements.
X
X16. Fix problems with positioning the player when entering or leaving the
X dungeon. You will no longer find yourself on the opposite side of the
X town level when leaving the dungeon. You will no longer be able to enter
X the dungeon on top of a monster.
X
X17. Prevented monsters from moving into the dungeon entrance, causing them to
X be destroyed when the player exits the dungeon. The top dungeon level now
X has the dungeon entrance character where there used to be a space.
X
X18. If you are standing on a chest and try and open it, you will no longer pick
X it up immediately if you have auto-pickup on.
X
X19. Added the capability to add comments to the options file.
X
X20. Fixed the bug where a missing options file prevented anything from being
X displayed.
X
X21. There is now a visible repeat count when greater than 10 (a la Hack). You
X can also edit the repeat count.
X
X22. The 'm' command has been added to move onto an object without picking it
X up (a la Hack).
X
X23. Fixed a problem where the a) item in the inventory couldn't be dulled.
X
X25. Allow a space between '-o' and the option filename.
X
X26. Fix possible errors when looking at the inventory.
X
X27. Prevent the player from changing levels into a level from the maze file with
X a space that had no means of exit.
X
X================================================================================
X
XThis is a list of the fixes and enhancements made to create Larn V12.2 from
XLarn 12.0. SPOILER ALERT!
X
XChanges made to create version 12.2 from 12.1:
X
X1. Add messages to improve feedback to the user.
X
X2. Improved screen drawing performance again.
X
X3. Flying monsters (bats, floating eyes) are no longer affected by traps.
X
X4. Added HACK-like objects, with 'original-objects' option.
X
X5. Added 'bold-objects' option.
X
X6. Fixed a bug where the game would apparently 'hang' for a long period of
X time, especially just after killing a monster with a missile spell.
X
X7. Prevented invulnerability when doing VPR on a throne or altar.
X
X8. Scrolls of pulverization now have the same affect when directed against
X an altar or fountain as they did directed against a throne. VPR spell
X cause a waterlord to appear when used near a fountain.
X
X9. Added the '@' command and 'auto-pickup' option.
X
X10. Added 'prompt-on-objects' option.
X
X11. Improved monster movement performance again.
X
X12. You can now weild '-' to unweild your weapon.
X
X13. Waterlords can now be found in the dungeon, not just when washing at a
X fountain.
X
X14. The Eye of Larn can now be sold in the Trading Post.
X
X15. Spells can now bounce off mirrors at an angle.
X
X
XChanges made to create version 12.1 from 12.0:
X
X1. When drinking at a fountain, "improved sight" caused the "see invisible"
X potion to be known by the player. The player must now identify the potion
X in the usual manner.
X
X2. Falling through a pit told you the damage you received, but falling through
X a trap door did not. Made trap doors act the same as pits.
X
X3. If you dropped a ring of dexterity/strength/cleverness that had been dulled
X to a negative amount, the corresponding stat was permanently increased. No
X longer.
X
X4. The potion of monster location would show invisible monsters as the floor
X character on new levels. Now prevented.
X
X5. Selling all your gems at the bank could destroy items in your inventory.
X
X6. Monster creation was being allowed on closed doors. This was particularly
X a problem with treasure rooms, since it meant that a monster much too
X powerful for the player to handle was loose in the maze. Monsters cannot
X now be created on closed doors.
X
X7. When entering a number (when entering gold amounts) you could not use the
X backspace key to delete digits. Fixed.
X
X8. To make it more convenient when selling items in the Larn Trading Post, a
X display of those items in the players inventory that can be sold has been
X added.
X
X9. Performance of the display has been improved slightly.
X
X10. Monster movement has been improved for large numbers of monsters. It is
X somewhat better on PC's, even with aggravation.
X
X11. I have added new mazes to LARN.MAZ.
X
X12. A Rogue-like command mode has been added, and is the default. The
X version 12.0 prompting mode has been preserved for those who like it,
X accessible via a command line option. Command letters have been added
X to provide the ability to perform all the same actions as the prompt mode.
X The help file and command line help have been updated. When in command
X mode, the player will automatically pick up objects, and can read, quaff,
X eat, look at, and pick up objects that you are standing on.
X
X In order to implement the new commands, the A and D commands from version
X 12.0 have been changed. They are now ^A and I. For consistancy, to see
X the list of known spells at the spell prompt, 'I' also shows all known
X spells.
END_OF_FILE
if test 7408 -ne `wc -c <'larn123.fix'`; then
echo shar: \"'larn123.fix'\" unpacked with wrong size!
fi
# end of 'larn123.fix'
fi
if test -f 'makefile.pc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.pc'\"
else
echo shar: Extracting \"'makefile.pc'\" \(6666 characters\)
sed "s/^X//" >'makefile.pc' <<'END_OF_FILE'
X############################################################################
X#
X# A list of available compile-time defines:
X#
X# BSD - use BSD specific features (mostly timer and signal stuff)
X# BSD4.1 - use BSD4.1 to avoid some 4.2 dependencies (must be used with
X# BSD above; do not mix with SYSV)
X# DECRainbow - DEC Rainbow specific display code.
X# DOCHECKPOINTS - if not defined, checkpoint files are periodically written
X# by the larn process (no forking) if enabled in the .larnopts
X# description file. Checkpointing is handy on an unreliable
X# system, but takes CPU. Inclusion of DOCHECKPOINTS will cause
X# fork()ing to perform the checkpoints (again if enabled in
X# the .larnopts file). This usually avoids pauses in larn
X# while the checkpointing is being done (on large machines).
X# EXTRA - incorporates code to gather additional performance stats
X# FLUSHNO=# - Set the input queue excess flushing threshold (default 5)
X# HIDEBYLINK - if defined, the program attempts to hide from ps
X# MACRORND - Define to use macro version of rnd() and rund() (fast & big)
X# MAIL - system supports mail messages (see bill.c). Not useful on
X# non-networked machines.
X# MSDOS - MS-DOS specific code.
X# OS2LARN - OS/2 Specific code. MSDOS must be defined.
X# NONAP - causes napms() to return immediately instead of delaying
X# n milliseconds. This define may be needed on some systems
X# if the nap stuff does not work correctly (possible hang).
X# nap() is primarilly used to delay for effect when casting
X# missile type spells.
X# NOVARARGS - Define for systems that don't have varargs (a default
X# varargs will be used).
X# RFCMAIL - mail messages are RFC822 conformant. Must be used with
X# MAIL above.
X# SAVEINHOME - put save files in users HOME instead of LARNHOME (default)
X# SYSV - use system III/V (instead of V7) type ioctl calls
X# TIMECHECK - incorporates code to disable play during working hours (8-5)
X# UIDSCORE - Define to use user id's to manage scoreboard. Leaving this
X# out will cause player id's from the file ".playerids" to
X# be used instead. (.playerids is created upon demand).
X# Only one entry per id # is allowed in each scoreboard
X# (winning & non-winning).
X# VT100 - Compile for using vt100 family of terminals. Omission of
X# this define will cause larn to use termcap.
X# WIZID=xxx - this is the userid (or playerid) of the wizard. Default is
X# zero (superuser), which disables all wizard functions.
X# Players must have this userid (or playerid) in order to
X# become the non-scoring wizard player. Definition of WIZID
X# to non-zero will enable the special wizard debugging
X# commands. For root to become wizard, use WIZID= -1.
X#
X############################################################################
X#
X# Configuration options
X# LARNHOME is the directory where the larn data files will be installed.
X# BINDIR is the directory where the larn binary will be installed.
X#
XLARNHOME = # The current directory unless changed in larn.opt
XBINDIR = c:\games
XCC= tcc
XOPTIONS = -DSYSV -DMSDOS -DNOVARARGS
X
X########################################################################
X#
XOBJS= action.obj \
X bill.obj \
X config.obj \
X create.obj \
X data.obj \
X diag.obj \
X display.obj \
X fgetlr.obj \
X fortune.obj \
X global.obj \
X help.obj \
X iventory.obj\
X io.obj \
X main.obj \
X monster.obj \
X moreobj.obj \
X movem.obj \
X msdos.obj \
X nap.obj \
X object.obj \
X regen.obj \
X savelev.obj \
X scores.obj \
X signal.obj \
X spheres.obj \
X spells.obj \
X store.obj \
X tgetent.obj \
X tgetstr.obj \
X tgoto.obj \
X tok.obj \
X tputs.obj \
X vms.obj
X
XDOTFILES= larn.hlp larn.maz larn.ftn # larn.opt
X
X# merge literal strings
X# large memory model
X# include file directory pointer
X# use extended memory during compile
X#
XFLAGS= $(OPTIONS) -d -ml -I\TCPP\INCLUDE -Qx
X
X# case-sensitive link, no map file
X#
Xlarn: larn123.exe
Xlarn123.exe: $(OBJS)
X tlink \TCPP\LIB\C0L @tlink.rsp, larn123,,\TCPP\LIB\EMU \TCPP\LIB\MATHL \TCPP\LIB\CL /c /x
X
X.c.obj:
X $(CC) -c $(FLAGS) $<
X
Xaction.obj: action.c header.h larndefs.h monsters.h objects.h player.h
Xbill.obj: bill.c header.h larndefs.h
Xconfig.obj: config.c header.h larndefs.h
Xcreate.obj: create.c header.h larndefs.h monsters.h objects.h player.h
Xdata.obj: data.c header.h monsters.h objects.h
Xdiag.obj: diag.c header.h larndefs.h monsters.h objects.h player.h
Xdisplay.obj: display.c header.h larndefs.h objects.h player.h
Xfgetlr.obj: fgetlr.c
Xfortune.obj: fortune.c header.h
Xglobal.obj: global.c header.h larndefs.h monsters.h objects.h player.h
Xhelp.obj: help.c header.h larndefs.h
Xiventory.obj: iventory.c header.h larndefs.h objects.h player.h
Xio.obj: io.c header.h larndefs.h
Xmain.obj: main.c header.h larndefs.h monsters.h objects.h player.h patchlev.h
Xmonster.obj: monster.c header.h larndefs.h monsters.h objects.h player.h
Xmoreobj.obj: moreobj.c header.h larndefs.h monsters.h objects.h player.h
Xmovem.obj: movem.c header.h larndefs.h monsters.h objects.h player.h
Xmsdos.obj: msdos.c header.h larndefs.h
Xnap.obj: nap.c
Xobject.obj: object.c header.h larndefs.h monsters.h objects.h player.h
Xregen.obj: regen.c header.h larndefs.h monsters.h player.h
Xsavelev.obj: savelev.c header.h larndefs.h
Xscores.obj: scores.c header.h larndefs.h monsters.h objects.h player.h
Xsignal.obj: signal.c header.h larndefs.h
Xspheres.obj: spheres.c header.h larndefs.h monsters.h objects.h player.h
Xspells.obj: spells.c header.h larndefs.h monsters.h objects.h player.h
Xstore.obj: store.c header.h larndefs.h objects.h player.h
Xtgetent.obj: tgetent.c
Xtgetstr.obj: tgetstr.c
Xtgoto.obj: tgoto.c
Xtok.obj: tok.c header.h larndefs.h monsters.h objects.h player.h
Xtputs.obj: tputs.c
Xvms.obj: vms.c header.h larndefs.h
X
Xinstall:
X exepack larn123.exe $(BINDIR)\larn123.exe
X exemod $(BINDIR)\larn123.exe /max 1
END_OF_FILE
if test 6666 -ne `wc -c <'makefile.pc'`; then
echo shar: \"'makefile.pc'\" unpacked with wrong size!
fi
# end of 'makefile.pc'
fi
if test -f 'nansi.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'nansi.doc'\"
else
echo shar: Extracting \"'nansi.doc'\" \(6967 characters\)
sed "s/^X//" >'nansi.doc' <<'END_OF_FILE'
XSYNOPSIS
X Include in \config.sys the line
X device=nansi.sys
X
XDESCRIPTION
X Nansi.sys is a console driver which understands ANSI control
X sequences. It has several advantages over ANSI.SYS (the driver
X supplied with DOS):
X 1. It supports new escape sequences (see below).
X 2. It provides MUCH faster output under certain conditions.
X 3. It supports the 43-line mode of the EGA.
X 4. The darned bell is now 1/4 second instead of 1/2 second long.
X
X What a console driver does:
X When you, for example, type
X C:> type foo.txt
X COMMAND.COM opens the file foo.txt, reads it, and writes it to
X the console driver, which puts it up on the screen.
X
X Both ansi.sys and nansi.sys use IBM Video BIOS to control the screen.
X However, nansi.sys bypasses BIOS if the screen is in a text mode; this
X allows much faster operation under certain conditions.
X
X While putting text up on the screen, (n)ansi.sys keeps a lookout for
X the escape character (chr(27), known as ESC); this character signals
X the start of a terminal control sequence.
X Terminal control sequences follow the format
X ESC [ param; param; ...; param cmd
X where
X ESC is the escape character chr$(27).
X [ is the left bracket character.
X param is an ASCII decimal number, or a string in quotes.
X cmd is a case-specific letter identifying the command.
X Usually, zero, one, or two parameters are given. If parameters
X are omitted, they usually default to 1; however, some commands
X (KKR and DKOCT) treat the no-parameter case specially.
X Spaces are not allowed between parameters.
X
X For example, both ESC[1;1H and ESC[H send the cursor to the home
X position (1,1), which is the upper left.
X
X Either single or double quotes may be used to quote a string.
X Each character inside a quoted string is equivalent to one numeric
X parameter. Quoted strings are normally used only for the Keyboard
X Key Reassignment command.
X
XControl Sequences
X The following table lists the sequences understood by nansi.sys.
X Differences between nansi.sys and the standard ansi.sys are marked
X with a vertical bar (|).
X
XCursor Positioning
XShort Long name Format Notes
XCUP cursor position ESC[y;xH Sets cursor position.
XHVP cursor position ESC[y;xf Same as CUP; not recommended.
XCUU cursor up ESC[nA n = # of lines to move
XCUD cursor down ESC[nB
XCUF cursor forward ESC[nC n = # of columns to move
XCUB cursor backward ESC[nD
XDSR Device Status, Report! ESC[6n Find out cursor position.
XCPR Cursor Position report ESC[y;xR Response to DSR, as if typed.
XSCP Save Cursor Position ESC[s Not nestable.
XRCP Restore Cursor Position ESC[u
X
XEditing
XED Erase in Display ESC[2J Clears screen.
XEL Erase in Line ESC[K Clears to end of line.
XIL | Insert Lines ESC[nL Inserts n blank lines at cursor line.
XDL | Delete Lines ESC[nM Deletes n lines including cursor line.
XICH | Insert Characters ESC[n@ Inserts n blank chars at cursor.
XDCH | Delete Characters ESC[nP Deletes n chars including cursor char.
X
X
XMode-Setting
XSGR Set Graphics Rendition ESC[n;n;...nm See character attribute table.
XSM Set Mode ESC[=nh See screen mode table.
XRM Reset Mode ESC[=nl See screen mode table.
XIBMKKR Keyboard Key Reass. ESC["string"p
X The first char of the string gives the key to redefine; the rest
X of the string is the key's new value.
X To specify unprintable chars, give the ASCII value of the char
X outside of quotes, as a normal parameter.
X IBM function keys are two byte strings; see the IBM Basic manual.
X For instance, ESC[0;";dir a:";13;p redefines function key 1 to
X have the value "dir a:" followed by the ENTER key.
X | If no parameters given, all keys are reset to their default values.
X
XDKOCT | Output char translate ESC[n;ny
X | When first char is encountered in output request, it is replaced with
X | the second char. This might be useful for previewing text before
X | sending it to a printer with a funny print wheel.
X | If no parameters are given, all chars are reset to normal.
X
X
XCharacter Attributes
X The Set Graphics Rendition command is used to select foreground
X and background colors or attributes.
X When you use multiple parameters, they are executed in sequence, and
X the effects are cumulative.
X Attrib code Value
X 0 All attributes off (normal white on black)
X 1 Bold
X 4 Underline
X 5 Blink
X 7 Reverse Video
X 8 Invisible (but why?)
X 30-37 foregnd blk/red/grn/yel/blu/magenta/cyan/white
X 40-47 background
X
XScreen Modes
X The IBM BIOS supports several video modes; the codes given in the
X BIOS documentation are used as parameters to the Set Mode command.
X | (In bitmap modes, the cursor is simulated with a small blob (^V).)
X Mode Code Value
X 0 text 40x25 Black & White
X 1 text 40x25 Color
X 2 text 80x25 Black & White
X 3 text 80x25 Color
X 4 bitmap 320x200 4 bits/pixel
X 5 bitmap 320x200 1 bit/pixel
X 6 bitmap 640x200 1 bit/pixel
X 7 (cursor wrap kludge)
X 13 (EGA) bitmap 320x200 4 bits/pixel ?
X 14 (EGA) bitmap 640x200 4 bits/pixel
X 16 (EGA) bitmap 640x350 4 bits/pixel
X Mode 7 is an unfortunate kludge; Setting mode 7 tells the cursor
X to wrap around to the next line when it passes the end of a line;
X Resetting mode 7 tells the cursor to not wrap, but rather stay put.
X | If your computer has the Enhanced Graphics Adaptor, modes between
X | 8 and 15 are also supported; see the EGA BIOS for info.
X | The EGA also lets you use a shorter character cell in text modes
X | in order to squeeze 43 lines of text out of the 25-line text modes.
X | To enter 43 line mode, set the desired 25-line text mode (0 to 3),
X | then Set Mode 43. For instance: ESC[=3h ESC[=43h.
X | To exit 43 line mode, set the desired 25-line text mode again.
X | Nansi.sys ignores mode 43 unless there is an EGA on your computer.
X
XFaster Output
X | Any program that sets the console to RAW mode, and buffers its
X | output properly, can achieve extremely high screen update speeds in
X | return for giving up the special functions of the keys ^C, ^S, and ^P.
X | See IOCTL in the MS-DOS 3.x Technical Reference for more info.
X Also, a small improvement in speed may be noticed with some
X programs that use the DOS console in normal mode, as this driver
X efficiently implements the (standard but undocumented) INT 29h
X most-favored-device putchar used by DOS.
X
XBUGS
X Insert and delete character do not work in graphics modes.
X Graphics mode writing is slow.
X The simulated cursor in graphics mode slows down single-char
X writes by a factor of 3; it should be disable-able.
X Does not support erase-to-end-of-screen and other useful functions.
X
XVersion
X This version, 2.2, created February 1986. Problems should
X be reported to Daniel Kegel, 1-60 CIT, Pasadena, CA 91126
X (or, after June 1986, 2648 169th Ave SE, Bellevue, Wa. 98008).
X Your suggestions for improvement would be most welcome.
X
XNOTE
X This program may be distributed for educational and personal use
X only. Commercial use is verboten; get in touch with the author.
END_OF_FILE
if test 6967 -ne `wc -c <'nansi.doc'`; then
echo shar: \"'nansi.doc'\" unpacked with wrong size!
fi
# end of 'nansi.doc'
fi
if test -f 'spheres.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'spheres.c'\"
else
echo shar: Extracting \"'spheres.c'\" \(6636 characters\)
sed "s/^X//" >'spheres.c' <<'END_OF_FILE'
X/*
X newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation
X rmsphere(x,y) Function to delete a sphere of annihilation from list
X sphboom(x,y) Function to perform the effects of a sphere detonation
X movsphere() Function to look for and move spheres of annihilation
X*/
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
X/*
X * newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation
X * int x,y,dir,lifetime;
X *
X * Enter with the coordinates of the sphere in x,y
X * the direction (0-8 diroffx format) in dir, and the lifespan of the
X * sphere in lifetime (in turns)
X * Returns the number of spheres currently in existence
X */
Xnewsphere(x,y,dir,life)
X int x,y,dir,life;
X {
X int m;
X struct sphere *sp;
X if (((sp=(struct sphere *)malloc(sizeof(struct sphere)))) == 0)
X return(c[SPHCAST]); /* can't malloc, therefore failure */
X if (dir>=9) dir=0; /* no movement if direction not found */
X if (level==0) vxy(&x,&y); /* don't go out of bounds */
X else
X {
X if (x<1) x=1; if (x>=MAXX-1) x=MAXX-2;
X if (y<1) y=1; if (y>=MAXY-1) y=MAXY-2;
X }
X if ((m=mitem[x][y]) >= DEMONLORD+4) /* demons dispel spheres */
X {
X show1cell(x,y); /* show the demon (ha ha) */
X cursors(); lprintf("\nThe %s dispels the sphere!",monster[m].name);
X beep(); rmsphere(x,y); /* remove any spheres that are here */
X return(c[SPHCAST]);
X }
X if (m==DISENCHANTRESS) /* disenchantress cancels spheres */
X {
X cursors(); lprintf("\nThe %s causes cancellation of the sphere!",monster[m].name); beep();
Xboom: sphboom(x,y); /* blow up stuff around sphere */
X rmsphere(x,y); /* remove any spheres that are here */
X return(c[SPHCAST]);
X }
X if (c[CANCELLATION]) /* cancellation cancels spheres */
X {
X cursors(); lprcat("\nAs the cancellation takes effect, you hear a great earth shaking blast!"); beep();
X goto boom;
X }
X if (item[x][y]==OANNIHILATION) /* collision of spheres detonates spheres */
X {
X cursors(); lprcat("\nTwo spheres of annihilation collide! You hear a great earth shaking blast!"); beep();
X rmsphere(x,y);
X goto boom;
X }
X if (playerx==x && playery==y) /* collision of sphere and player! */
X {
X cursors();
X lprcat("\nYou have been enveloped by the zone of nothingness!\n");
X beep(); rmsphere(x,y); /* remove any spheres that are here */
X nap(4000); died(258);
X }
X item[x][y]=OANNIHILATION; mitem[x][y]=0; know[x][y]=1;
X show1cell(x,y); /* show the new sphere */
X sp->x=x; sp->y=y; sp->lev=level; sp->dir=dir; sp->lifetime=life; sp->p=0;
X if (spheres==0) spheres=sp; /* if first node in the sphere list */
X else /* add sphere to beginning of linked list */
X {
X sp->p = spheres; spheres = sp;
X }
X return(++c[SPHCAST]); /* one more sphere in the world */
X }
X
X/*
X * rmsphere(x,y) Function to delete a sphere of annihilation from list
X * int x,y;
X *
X * Enter with the coordinates of the sphere (on current level)
X * Returns the number of spheres currently in existence
X */
Xrmsphere(x,y)
X int x,y;
X {
X register struct sphere *sp,*sp2=0;
X for (sp=spheres; sp; sp2=sp,sp=sp->p)
X if (level==sp->lev) /* is sphere on this level? */
X if ((x==sp->x) && (y==sp->y)) /* locate sphere at this location */
X {
X item[x][y]=mitem[x][y]=0; know[x][y]=1;
X show1cell(x,y); /* show the now missing sphere */
X --c[SPHCAST];
X if (sp==spheres) { sp2=sp; spheres=sp->p; free((char*)sp2); }
X else
X { sp2->p = sp->p; free((char*)sp); }
X break;
X }
X return(c[SPHCAST]); /* return number of spheres in the world */
X }
X
X/*
X * sphboom(x,y) Function to perform the effects of a sphere detonation
X * int x,y;
X *
X * Enter with the coordinates of the blast, Returns no value
X */
Xstatic sphboom(x,y)
X int x,y;
X {
X register int i,j;
X if (c[HOLDMONST]) c[HOLDMONST]=1;
X if (c[CANCELLATION]) c[CANCELLATION]=1;
X for (j=max(1,x-2); j<min(x+3,MAXX-1); j++)
X for (i=max(1,y-2); i<min(y+3,MAXY-1); i++)
X {
X item[j][i]=mitem[j][i]=0;
X show1cell(j,i);
X if (playerx==j && playery==i)
X {
X cursors(); beep();
X lprcat("\nYou were too close to the sphere!");
X nap(3000);
X died(283); /* player killed in explosion */
X }
X }
X }
X
X/*
X * movsphere() Function to look for and move spheres of annihilation
X *
X * This function works on the sphere linked list, first duplicating the list
X * (the act of moving changes the list), then processing each sphere in order
X * to move it. They eat anything in their way, including stairs, volcanic
X * shafts, potions, etc, except for upper level demons, who can dispel
X * spheres.
X * No value is returned.
X */
X#define SPHMAX 20 /* maximum number of spheres movsphere can handle */
Xmovsphere()
X {
X register int x,y,dir,len;
X register struct sphere *sp,*sp2;
X struct sphere sph[SPHMAX];
X
X /* first duplicate sphere list */
X for (sp=0,x=0,sp2=spheres; sp2; sp2=sp2->p) /* look through sphere list */
X if (sp2->lev == level) /* only if this level */
X {
X sph[x] = *sp2; sph[x++].p = 0; /* copy the struct */
X if (x>1) sph[x-2].p = &sph[x-1]; /* link pointers */
X }
X if (x) sp= sph; /* if any spheres, point to them */
X else return; /* no spheres */
X
X for (sp=sph; sp; sp=sp->p) /* look through sphere list */
X {
X x = sp->x; y = sp->y;
X if (item[x][y]!=OANNIHILATION) continue; /* not really there */
X if (--(sp->lifetime) < 0) /* has sphere run out of gas? */
X {
X rmsphere(x,y); /* delete sphere */
X continue;
X }
X switch(rnd((int)max(7,c[INTELLIGENCE]>>1))) /* time to move the sphere */
X {
X case 1:
X case 2: /* change direction to a random one */
X sp->dir = rnd(8);
X default: /* move in normal direction */
X dir = sp->dir; len = sp->lifetime;
X rmsphere(x,y);
X newsphere(x+diroffx[dir],y+diroffy[dir],dir,len);
X };
X }
X }
END_OF_FILE
if test 6636 -ne `wc -c <'spheres.c'`; then
echo shar: \"'spheres.c'\" unpacked with wrong size!
fi
# end of 'spheres.c'
fi
if test -f 'tgetstr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tgetstr.c'\"
else
echo shar: Extracting \"'tgetstr.c'\" \(6825 characters\)
sed "s/^X//" >'tgetstr.c' <<'END_OF_FILE'
X/************************************************************************
X * *
X * Copyright (c) 1982, Fred Fish *
X * All Rights Reserved *
X * *
X * This software and/or documentation is released for public *
X * distribution for personal, non-commercial use only. *
X * Limited rights to use, modify, and redistribute are hereby *
X * granted for non-commercial purposes, provided that all *
X * copyright notices remain intact and all changes are clearly *
X * documented. The author makes no warranty of any kind with *
X * respect to this product and explicitly disclaims any implied *
X * warranties of merchantability or fitness for any particular *
X * purpose. *
X * *
X ************************************************************************
X */
X
X
X/*
X * LIBRARY FUNCTION
X *
X * tgetstr extract string capability from termcap entry
X *
X * KEY WORDS
X *
X * termcap
X *
X * SYNOPSIS
X *
X * char *tgetstr(id,area)
X * char *id;
X * char **area;
X *
X * DESCRIPTION
X *
X * Gets the string capability for <id>, placing it in
X * the buffer at *area, and advancing *area to point
X * to next available storage.
X *
X * For example, if the following capabilities are
X * in the termcap file:
X *
X * ZZ=zzzz
X * YY=yyyyyy
X * WW=www
X *
X * then successive calls using YY, ZZ, and WW will
X * build the following buffer:
X *
X * yyyyyy0zzzz0www0
X *
X * The first call will return a pointer to yyyyyy, the
X * second will return a pointer to zzzz and the third
X * will return a pointer to www. Note that each
X * string is null terminated, as are all C strings.
X *
X * Characters preceded by the carot character (\136)
X * are mapped into the corresponding control character.
X * For example, the two character sequence ^A becomes
X * a single control-A (\001) character.
X *
X * The escape character is the normal C backslash and
X * the normal C escape sequences are recognized, along
X * with a special sequence for the ASCII escape character
X * (\033). The recognized sequences are:
X *
X * \E => '\033' (ASCII escape character)
X * \b => '\010' (ASCII backspace character)
X * \f => '\014' (ASCII form feed character)
X * \n => '\012' (ASCII newline/linefeed char)
X * \r => '\015' (ASCII carriage return char)
X * \t => '\011' (ASCII tab character)
X * \ddd => '\ddd' (arbitrary ASCII digit)
X * \x => 'x' (ordinary ASCII character)
X *
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#ifdef VMS
X# define index strchr
X#endif
X#ifdef ULTRIX
X# include <strings.h>
X#endif
X
Xextern char *_tcpbuf; /* Termcap entry buffer pointer */
X
X#ifdef MSDOS
X extern char *index();
X#endif
X
X/*
X * PSEUDO CODE
X *
X * Begin tgetstr
X * Initialize pointer to the termcap entry buffer.
X * While there is a field to process
X * Skip over the field separator character.
X * If this is the entry we want then
X * If the entry is not a string then
X * Return NULL.
X * Else
X * Transfer string and rtn pointer.
X * End if
X * End if
X * End while
X * Return NULL
X * End tgetstr
X *
X */
X
Xchar *tgetstr(id,area)
Xchar *id;
Xchar **area;
X{
X char *bp;
X char *decode();
X
X bp = _tcpbuf;
X while ((bp = index(bp,':')) != NULL) {
X bp++;
X if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
X if (*bp != NULL && *bp++ != '=') {
X return(NULL);
X } else {
X return(decode(bp,area));
X }
X }
X }
X return(NULL);
X}
X
X/*
X * INTERNAL FUNCTION
X *
X * decode transfer string capability, decoding escapes
X *
X * SYNOPSIS
X *
X * static char *decode(bp,area)
X * char *bp;
X * char **area;
X *
X * DESCRIPTION
X *
X * Transfers the string capability, up to the next ':'
X * character, or null, to the buffer pointed to by
X * the pointer in *area. Note that the initial
X * value of *area and *area is updated to point
X * to the next available location after the null
X * terminating the transfered string.
X *
X * BUGS
X *
X * There is no overflow checking done on the destination
X * buffer, so it better be large enough to hold
X * all expected strings.
X *
X */
X
X/*
X * PSEUDO CODE
X *
X * Begin decode
X * Initialize the transfer pointer.
X * While there is an input character left to process
X * Switch on input character
X * Case ESCAPE:
X * Decode and xfer the escaped sequence.
X * Break
X * Case CONTROLIFY:
X * Controlify and xfer the next character.
X * Advance the buffer pointer.
X * Break
X * Default:
X * Xfer a normal character.
X * End switch
X * End while
X * Null terminate the output string.
X * Remember where the output string starts.
X * Update the output buffer pointer.
X * Return pointer to the output string.
X * End decode
X *
X */
X
Xstatic char *decode(bp,area)
Xchar *bp;
Xchar **area;
X{
X char *cp, *bgn;
X char *do_esc();
X
X cp = *area;
X while (*bp != NULL && *bp != ':') {
X switch(*bp) {
X case '\\':
X bp = do_esc(cp++,++bp);
X break;
X case '^':
X *cp++ = *++bp & 037;
X bp++;
X break;
X default:
X *cp++ = *bp++;
X break;
X }
X }
X *cp++ = (char) NULL;
X bgn = *area;
X *area = cp;
X return(bgn);
X}
X
X/*
X * INTERNAL FUNCTION
X *
X * do_esc process an escaped sequence
X *
X * SYNOPSIS
X *
X * char *do_esc(out,in);
X * char *out;
X * char *in;
X *
X * DESCRIPTION
X *
X * Processes an escape sequence pointed to by
X * in, transfering it to location pointed to
X * by out, and updating the pointer to in.
X *
X */
X
X/*
X * PSEUDO CODE
X *
X * Begin do_esc
X * If the first character is not a NULL then
X * If is a digit then
X * Set value to zero.
X * For up to 3 digits
X * Accumulate the sum.
X * End for
X * Transfer the sum.
X * Else if character is in remap list then
X * Transfer the remapped character.
X * Advance the input pointer once.
X * Else
X * Simply transfer the character.
X * End if
X * End if
X * Return updated input pointer.
X * End do_esc
X *
X */
X
Xstatic char *maplist = {
X "E\033b\bf\fn\nr\rt\t"
X};
X
Xchar *do_esc(out,in)
Xchar *out;
Xchar *in;
X{
X int count;
X char ch;
X char *cp;
X
X if (*in != NULL) {
X if (isdigit(*in)) {
X ch = 0;
X for (count = 0; count < 3 && isdigit(*in); in++) {
X ch <<= 3;
X ch |= (*in - '0');
X }
X *out++ = ch;
X } else if ((cp = index(maplist,*in)) != NULL) {
X *out++ = *++cp;
X in++;
X } else {
X *out++ = *in++;
X }
X }
X return(in);
X}
END_OF_FILE
if test 6825 -ne `wc -c <'tgetstr.c'`; then
echo shar: \"'tgetstr.c'\" unpacked with wrong size!
fi
# end of 'tgetstr.c'
fi
if test -f 'vms.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vms.c'\"
else
echo shar: Extracting \"'vms.c'\" \(6704 characters\)
sed "s/^X//" >'vms.c' <<'END_OF_FILE'
X#ifdef VMS
X#include "header.h"
X
X#include <file.h>
X#include <stat.h>
X#include <stdio.h>
X#include <stsdef.h>
X#include <ssdef.h>
X#include <descrip.h>
X#include <iodef.h>
X#include <ttdef.h>
X#include <tt2def.h>
X
X/*
X * Read until end of file or until buffer is full.
X * don't let the vms read (which stops once per record)
X * fool the program.
X */
Xvread(fd, buf, size)
Xint fd;
Xchar *buf;
Xint size;
X{
X int csize; /* cumulative size */
X int isize; /* incremental size */
X
X csize = 0;
X do {
X isize = read(fd, buf, size);
X if (isize > 0) {
X csize += isize;
X buf += isize;
X size -= isize;
X }
X } while (isize > 0);
X return (csize);
X}
X
X#else VMS
X
X#ifndef vread /* if not done as a macro in header.h */
Xvread(fd, buf, size)
Xint fd;
Xchar *buf;
Xint size;
X{
X return (read(fd, buf, size));
X}
X#endif vread
X#endif VMS
X
X#ifdef VMS
X/*
X * Run a command in a subjob. Used for mailing the winners congratulations,
X * tax bills, etc. Used for the shell escape command (!). Conditionalized
X * for VMS wherever used (un*x has the right primitives).
X */
Xlong
Xoneliner(cstr)
Xchar *cstr;
X{
X struct dsc$descriptor cdsc;
X register long sts;
X register long pstat;
X
X cdsc.dsc$a_pointer = cstr;
X cdsc.dsc$w_length = strlen(cstr);
X cdsc.dsc$b_dtype = DSC$K_DTYPE_T;
X cdsc.dsc$b_class = DSC$K_CLASS_S;
X sts = LIB$SPAWN(&cdsc, 0, 0, 0, 0, 0, &pstat, 0, 0, 0, 0, 0);
X if (sts != SS$_NORMAL)
X return (sts);
X else
X return (pstat);
X}
X
X/*
X Data to convert the escape codes produced by VT style keypad keys to things
X that LARN will understand.
X*/
X#define MAX_KP_CONV 19
Xstruct
X {
X char *inp_str;
X char *out_str;
X } keypad_conv[MAX_KP_CONV] = { { "\x1BOp", "i" }, /* KP0 */
X { "\x1BOq", "b" }, /* KP1 */
X { "\x1BOr", "j" }, /* KP2 */
X { "\x1BOs", "n" }, /* KP3 */
X { "\x1BOt", "h" }, /* KP4 */
X { "\x1BOu", "." }, /* KP5 */
X { "\x1BOv", "l" }, /* KP6 */
X { "\x1BOw", "y" }, /* KP7 */
X { "\x1BOx", "k" }, /* KP8 */
X { "\x1BOy", "u" }, /* KP9 */
X { "\x1BOn", "." }, /* KP. */
X { "\x1BOl", "," }, /* KP, */
X { "\x1B[A", "K" }, /* uparrow */
X { "\x1B[B", "J" }, /* downarrow*/
X { "\x1B[C", "L" }, /* right arrow */
X { "\x1B[D", "H" }, /* left arrow */
X { "\x1BOP", "m" }, /* PF1 */
X { "\x1BOS", "@" }, /* PF4 */
X { "\x1B[23~", "\x1B" } /* (ESC) */
X };
X
X/*
X VMS-specific terminal character read. Gets a character from the terminal,
X translating keypad as necessary. Assumes VT-class terminals.
X*/
Xvms_ttgetch()
X {
X
X#define BUFFLEN 10
X
X char *i;
X int j;
X register int incount;
X static char buffer[BUFFLEN];
X static char *bufptr = buffer;
X static char *bufend = buffer;
X
X lflush(); /* be sure output buffer is flushed */
X
X /* Read the first char from the user
X */
X if (bufptr >= bufend)
X {
X bufptr = bufend = buffer;
X incount = vmsread(buffer, BUFFLEN, 0);
X while ( incount <= 0 )
X incount = vmsread(buffer, 1, 2);
X bufend = &buffer[incount];
X }
X
X /* If the first char was an ESCAPE, get the characters from an
X escape sequence (eg pressing a key that generates such a
X sequence). If it was a plain old escape, the vmsread() call
X will return TIMEOUT.
X */
X if (*bufptr == '\x1B' )
X {
X incount = vmsread( bufend, (BUFFLEN - 1), 0 );
X if (incount >= 0)
X bufend += incount ;
X }
X
X /* Make sure the buffer is zero-terminated, since vmsread()
X doesn't zero-terminate the characters read.
X */
X *bufend = '\0' ;
X
X /* run through the keypad conversion table to convert keypad
X keys (escape sequences) and other supported escape sequences
X to Larn command characters.
X */
X for ( j = 0; j < MAX_KP_CONV ; j++ )
X if (strcmp( &buffer, keypad_conv[j].inp_str ) == 0 )
X {
X strcpy( &buffer, keypad_conv[j].out_str );
X bufend = &buffer[strlen(&buffer)];
X break;
X }
X
X /* If after running through the table the first character is still
X ESCAPE, then we probably didn't get a match. Force unsupported
X keys that generate escape sequences to just return an ESCAPE.
X Effectively prevents key translations that generate escape
X sequences.
X */
X if (*bufptr == '\x1B' )
X {
X bufend = &buffer[1] ;
X }
X *bufend = '\0' ;
X
X if (*bufptr == '\r')
X *bufptr = '\n';
X
X return (*bufptr++ & 0xFF);
X }
X
Xtypedef struct
X {
X short int status;
X short int term_offset;
X short int terminator;
X short int term_size;
X } IOSTAB;
X
Xint vmsread(buffer, size, timeout)
Xchar *buffer;
Xint size;
Xint timeout;
X {
X
X#define TIMEOUT (-2)
X#define ERROR (-1)
X
X extern int iochan;
X
X register int status;
X IOSTAB iostab;
X static long termset[2] = { 0, 0 }; /* No terminator */
X
X status = SYS$QIOW(
X 0, /* Event flag */
X iochan, /* Input channel */
X IO$_READLBLK | IO$M_NOFILTR | IO$M_TIMED,
X /* Read, no echo, no translate */
X &iostab, /* I/O status block */
X NULL, /* AST block (none) */
X 0, /* AST parameter */
X buffer, /* P1 - input buffer */
X size, /* P2 - buffer length */
X timeout, /* P3 - timeout */
X &termset, /* P4 - terminator set */
X NULL, /* P5 - ignored (prompt buffer) */
X 0 /* P6 - ignored (prompt size) */
X );
X if (status == SS$_TIMEOUT)
X return (TIMEOUT);
X else if (status != SS$_NORMAL)
X return (ERROR);
X else
X {
X if ((status = iostab.term_offset + iostab.term_size) > 0)
X return (status);
X return (TIMEOUT);
X }
X }
X
X#endif VMS
END_OF_FILE
if test 6704 -ne `wc -c <'vms.c'`; then
echo shar: \"'vms.c'\" unpacked with wrong size!
fi
# end of 'vms.c'
fi
echo shar: End of archive 3 \(of 17\).
cp /dev/null ark3isdone
#!/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 5 (of 17)."
# Contents: action.c iventory.c larn.hlp.uu
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:53 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'action.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'action.c'\"
else
echo shar: Extracting \"'action.c'\" \(13563 characters\)
sed "s/^X//" >'action.c' <<'END_OF_FILE'
X/*
X action.c
X
X Routines to perform the actual actions associated with various
X player entered commands.
X
X act_remove_gems remove gems from a throne
X act_sit_throne sit on a throne
X act_up_stairs go up stairs
X act_down_stairs go down stairs
X act_drink_fountain drink from a fountain
X act_wash_fountain wash at a fountain
X act_up_shaft up volcanic shaft
X act_down_shaft down volcanic shaft
X volshaft_climbed place player near volcanic shaft
X act_desecrate_altar desecrate an altar
X act_donation_pray pray, donating money
X act_just_pray pray, not donating money
X act_prayer_heard prayer was heard
X act_ignore_altar ignore an altar
X act_open_chest open a chest
X act_open_door open a door
X*/
X
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X/*
X act_remove_gems
X
X Remove gems from a throne.
X
X arg is zero if there is a gnome king associated with the throne
X
X Assumes that cursors() has been called previously, and that a check
X has been made that the throne actually has gems.
X*/
Xact_remove_gems( arg )
Xint arg ;
X {
X int i, k ;
X
X k=rnd(101);
X if (k<25)
X {
X for (i=0; i<rnd(4); i++)
X creategem(); /* gems pop off the throne */
X item[playerx][playery]=ODEADTHRONE;
X know[playerx][playery]=0;
X }
X else if (k<40 && arg==0)
X {
X createmonster(GNOMEKING);
X item[playerx][playery]=OTHRONE2;
X know[playerx][playery]=0;
X }
X else
X lprcat("\nNothing happens");
X
X return ;
X }
X
X/*
X act_sit_throne
X
X Sit on a throne.
X
X arg is zero if there is a gnome king associated with the throne
X
X Assumes that cursors() has been called previously.
X*/
Xact_sit_throne( arg )
Xint arg ;
X {
X int k ;
X
X k=rnd(101);
X if (k<30 && arg==0)
X {
X createmonster(GNOMEKING);
X item[playerx][playery]=OTHRONE2;
X know[playerx][playery]=0;
X }
X else if (k<35)
X {
X lprcat("\nZaaaappp! You've been teleported!\n");
X beep();
X oteleport(0);
X }
X else
X lprcat("\nNothing happens");
X
X return ;
X }
X
X/*
X assumes that cursors() has been called and that a check has been made that
X the user is actually standing at a set of up stairs.
X*/
Xact_up_stairs()
X {
X if (level >= 2 && level != 11)
X {
X newcavelevel( level - 1 ) ;
X draws( 0, MAXX, 0, MAXY );
X bot_linex() ;
X }
X else
X lprcat("\nThe stairs lead to a dead end!") ;
X return ;
X }
X
X/*
X assumes that cursors() has been called and that a check has been made that
X the user is actually standing at a set of down stairs.
X*/
Xact_down_stairs()
X {
X if (level != 0 && level != 10 && level != 13)
X {
X newcavelevel( level + 1 ) ;
X draws( 0, MAXX, 0, MAXY );
X bot_linex() ;
X }
X else
X lprcat("\nThe stairs lead to a dead end!") ;
X return ;
X }
X
X/*
X Code to perform the action of drinking at a fountian. Assumes that
X cursors() has already been called, and that a check has been made that
X the player is actually standing at a live fountain.
X*/
Xact_drink_fountain()
X {
X int x ;
X
X if (rnd(1501)<2)
X {
X lprcat("\nOops! You seem to have caught the dreadful sleep!");
X beep();
X lflush();
X sleep(3);
X died(280);
X return;
X }
X
X x = rnd(100);
X if (x<7)
X {
X c[HALFDAM] += 200 + rnd(200);
X lprcat("\nYou feel a sickness coming on");
X }
X
X else if (x < 13)
X quaffpotion(23, FALSE ); /* see invisible,but don't know the potion */
X
X else if (x < 45)
X lprcat("\nnothing seems to have happened");
X
X else if (rnd(3) != 2)
X fntchange(1); /* change char levels upward */
X
X else
X fntchange(-1); /* change char levels downward */
X
X if (rnd(12)<3)
X {
X lprcat("\nThe fountains bubbling slowly quiets");
X item[playerx][playery]=ODEADFOUNTAIN; /* dead fountain */
X know[playerx][playery]=0;
X }
X return;
X }
X
X/*
X Code to perform the action of washing at a fountain. Assumes that
X cursors() has already been called and that a check has been made that
X the player is actually standing at a live fountain.
X*/
Xact_wash_fountain()
X {
X int x ;
X
X if (rnd(100) < 11)
X {
X x=rnd((level<<2)+2);
X lprintf("\nOh no! The water was foul! You suffer %d hit points!",(long)x);
X lastnum=273;
X losehp(x);
X bottomline();
X cursors();
X }
X
X else if (rnd(100) < 29)
X lprcat("\nYou got the dirt off!");
X
X else if (rnd(100) < 31)
X lprcat("\nThis water seems to be hard water! The dirt didn't come off!");
X
X else if (rnd(100) < 34)
X createmonster(WATERLORD); /* make water lord */
X
X else
X lprcat("\nnothing seems to have happened");
X
X return;
X }
X
X/*
X Perform the act of climbing down the volcanic shaft. Assumes
X cursors() has been called and that a check has been made that
X are actually at a down shaft.
X*/
Xact_down_shaft()
X {
X if (level!=0)
X {
X lprcat("\nThe shaft only extends 5 feet downward!");
X return;
X }
X
X if (packweight() > 45+3*(c[STRENGTH]+c[STREXTRA]))
X {
X lprcat("\nYou slip and fall down the shaft");
X beep();
X lastnum=275;
X losehp(30+rnd(20));
X bottomhp();
X }
X else if (prompt_mode)
X lprcat("climb down");
X
X newcavelevel(MAXLEVEL);
X draws(0,MAXX,0,MAXY);
X bot_linex();
X return;
X }
X
X/*
X Perform the action of climbing up the volcanic shaft. Assumes
X cursors() has been called and that a check has been made that
X are actually at an up shaft.
X
X*/
Xact_up_shaft()
X {
X if (level!=11)
X {
X lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!");
X return;
X }
X
X if (packweight() > 45+5*(c[STRENGTH]+c[STREXTRA]))
X {
X lprcat("\nYou slip and fall down the shaft");
X beep();
X lastnum=275;
X losehp(15+rnd(20));
X bottomhp();
X return;
X }
X
X if (prompt_mode)
X lprcat("climb up");
X lflush();
X newcavelevel(0);
X volshaft_climbed( OVOLDOWN );
X return;
X }
X
X/*
X Perform the action of placing the player near the volcanic shaft
X after it has been climbed.
X
X Takes one parameter: the volcanic shaft object to be found. If have
X climbed up, search for OVOLDOWN, otherwise search for OVOLUP.
X*/
Xstatic volshaft_climbed(object)
Xint object;
X {
X int i,j ;
X
X /* place player near the volcanic shaft */
X for (i=0; i<MAXY; i++)
X for (j=0; j<MAXX; j++)
X if (item[j][i] == object)
X {
X playerx=j;
X playery=i;
X positionplayer();
X i=MAXY;
X break;
X }
X draws(0,MAXX,0,MAXY);
X bot_linex();
X return ;
X }
X
X/*
X Perform the actions associated with Altar desecration.
X*/
Xact_desecrate_altar()
X {
X if (rnd(100)<60)
X {
X createmonster(makemonst(level+2)+8);
X c[AGGRAVATE] += 2500;
X }
X else if (rnd(101)<30)
X {
X lprcat("\nThe altar crumbles into a pile of dust before your eyes");
X forget(); /* remember to destroy the altar */
X }
X else
X lprcat("\nnothing happens");
X return ;
X }
X
X/*
X Perform the actions associated with praying at an altar and giving a
X donation.
X*/
Xact_donation_pray()
X {
X unsigned long k,temp ;
X
X while (1)
X {
X lprcat("\n\n");
X cursor(1,24);
X cltoeoln();
X cursor(1,23);
X cltoeoln();
X lprcat("how much do you donate? ");
X k = readnum((long)c[GOLD]);
X
X /* VMS has a problem with echo mode input (used in readnum()) such that the
X next carriage return will shift the screen up one line. To get around
X this, if we are VMS, don't print the next carriage return. Otherwise,
X print the carriage return needed by all following messages.
X Turns out that all but MS-DOS (which has 25 lines) has this problem.
X */
X#ifdef MSDOS
X lprcat("\n");
X#endif
X
X /* make giving zero gold equivalent to 'just pray'ing. Allows player to
X 'just pray' in command mode, without having to add yet another command.
X */
X if (k == 0)
X {
X act_just_pray();
X return;
X }
X
X if (c[GOLD] >= k)
X {
X temp = c[GOLD] / 10 ;
X c[GOLD] -= k;
X bottomline();
X
X /* if player gave less than 10% of _original_ gold, make a monster
X */
X if (k < temp || k < rnd(50))
X {
X createmonster(makemonst(level+1));
X c[AGGRAVATE] += 200;
X return;
X }
X if (rnd(101) > 50)
X {
X act_prayer_heard();
X return;
X }
X if (rnd(43) == 5)
X {
X if (c[WEAR])
X lprcat("You feel your armor vibrate for a moment");
X enchantarmor();
X return;
X }
X if (rnd(43) == 8)
X {
X if (c[WIELD])
X lprcat("You feel your weapon vibrate for a moment");
X enchweapon();
X return;
X }
X
X lprcat("Thank You.");
X return ;
X }
X
X /* Player donates more gold than they have. Loop back around so
X player can't escape the altar for free.
X */
X lprcat("You don't have that much!");
X }
X }
X
X/*
X Performs the actions associated with 'just praying' at the altar. Called
X when the user responds 'just pray' when in prompt mode, or enters 0 to
X the money prompt when praying.
X
X Assumes cursors(), and that any leading \n have been printed (to get
X around VMS echo mode problem.
X*/
Xact_just_pray()
X {
X if (rnd(100)<75)
X lprcat("nothing happens");
X else if (rnd(43) == 10)
X {
X if (c[WEAR])
X lprcat("You feel your armor vibrate for a moment");
X enchantarmor();
X return;
X }
X else if (rnd(43) == 10)
X {
X if (c[WIELD])
X lprcat("You feel your weapon vibrate for a moment");
X enchweapon();
X return;
X }
X else
X createmonster(makemonst(level+1));
X return;
X }
X
X/*
X function to cast a +3 protection on the player
X */
Xstatic act_prayer_heard()
X {
X lprcat("You have been heard!");
X if (c[ALTPRO]==0)
X c[MOREDEFENSES]+=3;
X c[ALTPRO] += 500; /* protection field */
X bottomline();
X }
X
X/*
X Performs the act of ignoring an altar.
X
X Assumptions: cursors() has been called.
X*/
Xact_ignore_altar()
X {
X if (rnd(100)<30)
X {
X createmonster(makemonst(level+1));
X c[AGGRAVATE] += rnd(450);
X }
X else
X lprcat("\nNothing happens");
X return;
X }
X
X/*
X Performs the act of opening a chest.
X
X Parameters: x,y location of the chest to open.
X Assumptions: cursors() has been called previously
X*/
Xact_open_chest(x,y)
Xint x,y ;
X {
X int i,k;
X
X k=rnd(101);
X if (k<40)
X {
X lprcat("\nThe chest explodes as you open it"); beep();
X i = rnd(10); lastnum=281; /* in case he dies */
X lprintf("\nYou suffer %d hit points damage!",(long)i);
X checkloss(i);
X switch(rnd(10)) /* see if he gets a curse */
X {
X case 1: c[ITCHING]+= rnd(1000)+100;
X lprcat("\nYou feel an irritation spread over your skin!");
X beep();
X break;
X
X case 2: c[CLUMSINESS]+= rnd(1600)+200;
X lprcat("\nYou begin to lose hand to eye coordination!");
X beep();
X break;
X
X case 3: c[HALFDAM]+= rnd(1600)+200;
X beep();
X lprcat("\nA sickness engulfs you!"); break;
X };
X item[x][y]=know[x][y]=0; /* destroy the chest */
X if (rnd(100)<69) creategem(); /* gems from the chest */
X dropgold(rnd(110*iarg[playerx][playery]+200));
X for (i=0; i<rnd(4); i++) something(iarg[playerx][playery]+2);
X }
X else
X lprcat("\nNothing happens");
X return;
X }
X
X/*
X Perform the actions common to command and prompt mode when opening a
X door. Assumes cursors().
X
X Parameters: the X,Y location of the door to open.
X Return value: TRUE if successful in opening the door, false if not.
X*/
Xact_open_door( x, y )
Xint x ;
Xint y ;
X {
X if (rnd(11)<7)
X {
X switch(iarg[x][y])
X {
X case 6: c[AGGRAVATE] += rnd(400); break;
X
X case 7: lprcat("\nYou are jolted by an electric shock ");
X lastnum=274; losehp(rnd(20)); bottomline(); break;
X
X case 8: loselevel(); break;
X
X case 9: lprcat("\nYou suddenly feel weaker ");
X if (c[STRENGTH]>3) c[STRENGTH]--;
X bottomline(); break;
X
X default: break;
X }
X return( 0 );
X }
X else
X {
X know[x][y]=0;
X item[x][y]=OOPENDOOR;
X return( 1 );
X }
X }
END_OF_FILE
if test 13563 -ne `wc -c <'action.c'`; then
echo shar: \"'action.c'\" unpacked with wrong size!
fi
# end of 'action.c'
fi
if test -f 'iventory.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'iventory.c'\"
else
echo shar: Extracting \"'iventory.c'\" \(12705 characters\)
sed "s/^X//" >'iventory.c' <<'END_OF_FILE'
X#include "header.h"
X#include "larndefs.h"
X#include "objects.h"
X#include "player.h"
X
X#ifdef __STDC__
X show1( int, char*[] );
X show3( int );
Xstatic show2( int );
Xstatic void t_setup( int );
Xstatic void t_endup( int );
X
X#define SIGNED signed
X#else
X show1( );
X show3( );
Xstatic show2( );
Xstatic void t_setup( );
Xstatic void t_endup( );
X
X#define SIGNED
X#endif
X
Xstatic int qshowstr();
Xshowwear();
Xshowwield();
Xshowread();
Xshowquaff();
Xshoweat();
Xextern int dropflag;
X
X/* Allow only 26 items (a to z) in the player's inventory */
X#define MAXINVEN 26
X
X/* The starting limit to the number of items the player can carry.
X The limit should probably be based on player strength and the
X weight of the items.
X*/
X#define MIN_LIMIT 15
X
X/* define a sentinel to place at the end of the sorted inventory.
X (speeds up display reads )
X*/
X#define END_SENTINEL 255
X
X/* declare the player's inventory. These should only be referenced
X in this module.
X iven - objects in the player's inventory
X ivenarg - attribute of each item ( + values, etc )
X ivensort - sorted inventory (so we don't sort each time)
X*/
Xchar iven[MAXINVEN];
XSIGNED short ivenarg[MAXINVEN];
Xunsigned char ivensort[MAXINVEN+1]; /* extra is for sentinel */
X
Xstatic char srcount = 0 ; /* line counter for showstr() */
X
X/*
X Initialize the player's inventory
X*/
Xvoid init_inventory( )
X {
X int i;
X
X for ( i = 0; i < MAXINVEN ; i++ )
X {
X iven[i] = ivenarg[i] = 0;
X ivensort[i] = END_SENTINEL ;
X }
X ivensort[MAXINVEN] = END_SENTINEL;
X
X /* For zero difficulty games, start the player out with armor and weapon.
X We can sort the inventory right away because a dagger is 'later' than
X leather armor.
X */
X if (c[HARDGAME] <= 0)
X {
X iven[0] = OLEATHER;
X iven[1] = ODAGGER;
X ivenarg[0] = ivenarg[1] = c[WEAR] = ivensort[0] = 0;
X ivensort[1] = c[WIELD] = 1;
X }
X }
X
X/*
X show character's inventory
X*/
Xshowstr(select_allowed)
Xchar select_allowed;
X {
X register int i,number, item_select;
X
X for (number=3, i=0; i<MAXINVEN; i++)
X if (iven[i])
X number++; /* count items in inventory */
X t_setup(number);
X item_select = qshowstr(select_allowed);
X t_endup(number);
X return( item_select );
X }
X
Xstatic int qshowstr(select_allowed)
Xchar select_allowed;
X {
X register int i,j,k,sigsav,itemselect=0;
X
X srcount=0;
X sigsav=nosignal;
X nosignal=1; /* don't allow ^c etc */
X if (c[GOLD])
X {
X lprintf(".) %d gold pieces",(long)c[GOLD]);
X srcount++;
X }
X for (k=(MAXINVEN-1); k>=0; k--)
X if (iven[k])
X {
X for (i=22; i<84; i++)
X for (j=0; j<=k; j++)
X if (i==iven[j])
X {
X itemselect = show2(j);
X if (itemselect && select_allowed)
X goto quitit;
X }
X k=0;
X }
X
X lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
X itemselect = more(select_allowed);
Xquitit:
X nosignal=sigsav;
X if (select_allowed)
X return( (itemselect > 0) ? itemselect : 0 );
X else
X return( 0 );
X }
X
X/*
X subroutine to clear screen depending on # lines to display
X
X*/
Xstatic void t_setup(count)
Xregister int count;
X {
X if (count<20) /* how do we clear the screen? */
X {
X cl_up(79,count);
X cursor(1,1);
X }
X else
X {
X resetscroll();
X clear();
X }
X }
X
X/*
X subroutine to restore normal display screen depending on t_setup()
X
X*/
Xstatic void t_endup(count)
Xregister 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();
X 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,itemselect=0;
X
X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
X srcount=0;
X
X for (count=2,j=0; j< MAXINVEN; 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< MAXINVEN; 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 if (itemselect = show2(j))
X goto quitit;
X };
X itemselect = more(TRUE);
Xquitit:
X nosignal=sigsav;
X t_endup(count);
X return( (itemselect > 1) ? itemselect : 0 );
X }
X
X/*
X function to show the things player can wield only
X */
Xshowwield()
X {
X register int i,j,sigsav,count,itemselect=0;
X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
X srcount=0;
X
X for (count=2,j=0; j< MAXINVEN; 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< MAXINVEN; 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:
X break;
X default:
X if (itemselect = show2(j))
X goto quitit;
X };
X itemselect = more(TRUE);
Xquitit:
X nosignal=sigsav;
X t_endup(count);
X return( (itemselect > 1) ? itemselect : 0 );
X }
X
X/*
X * function to show the things player can read only
X */
Xshowread()
X {
X register int i,j,sigsav,count,itemselect = 0;
X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
X srcount=0;
X
X for (count=2,j=0; j< MAXINVEN; 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< MAXINVEN; j++)
X if (i==iven[j])
X switch(i)
X {
X case OBOOK: case OSCROLL:
X if (itemselect = show2(j))
X goto quitit;
X };
X itemselect = more(TRUE);
Xquitit:
X nosignal=sigsav;
X t_endup(count);
X return((itemselect > 1) ? itemselect : 0 );
X }
X
X/*
X * function to show the things player can eat only
X */
Xshoweat()
X {
X register int i,j,sigsav,count,itemselect=0;
X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
X srcount=0;
X
X for (count=2,j=0; j< MAXINVEN; 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< MAXINVEN; j++)
X if (i==iven[j])
X switch(i)
X {
X case OCOOKIE:
X if (itemselect=show2(j))
X goto quitit;
X };
X itemselect = more(TRUE);
Xquitit:
X nosignal=sigsav;
X t_endup(count);
X return( (itemselect > 1) ? itemselect : 0 );
X }
X
X/*
X function to show the things player can quaff only
X */
Xshowquaff()
X {
X register int i,j,sigsav,count,itemselect=0;
X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
X srcount=0;
X
X for (count=2,j=0; j< MAXINVEN; 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< MAXINVEN; j++)
X if (i==iven[j])
X switch(i)
X {
X case OPOTION:
X if (itemselect=show2(j))
X goto quitit;
X };
X itemselect = more(TRUE);
Xquitit:
X nosignal=sigsav;
X t_endup(count);
X return( (itemselect > 1 ) ? itemselect : 0 );
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)
Xregister int index ;
X {
X srcount=0;
X return( show2(index) );
X }
X
Xstatic int show2(index)
Xregister int index;
X {
X register int itemselect = 0;
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)
X {
X srcount=0;
X itemselect = more(TRUE);
X clear();
X }
X return( itemselect );
X }
X
X/*
X function to put something in the players inventory
X returns 0 if success, 1 if a failure
X*/
Xtake(itm,arg)
X int itm,arg;
X {
X register int i,limit;
X/* cursors(); */
X if ((limit = 15+(c[LEVEL]>>1)) > MAXINVEN)
X limit=MAXINVEN;
X for (i=0; i<limit; i++)
X if (iven[i]==0)
X {
X iven[i] = itm; ivenarg[i] = arg; limit=0;
X switch(itm)
X {
X case OPROTRING: case ODAMRING: case OBELT: limit=1; break;
X case ODEXRING: c[DEXTERITY] += ivenarg[i]+1; limit=1; break;
X case OSTRRING: c[STREXTRA] += ivenarg[i]+1; limit=1; break;
X case OCLEVERRING: c[INTELLIGENCE] += ivenarg[i]+1; limit=1; break;
X case OHAMMER: c[DEXTERITY] += 10; c[STREXTRA]+=10;
X c[INTELLIGENCE]-=10; limit=1; break;
X
X case OORBOFDRAGON: c[SLAYING]++; break;
X case OSPIRITSCARAB: c[NEGATESPIRIT]++; break;
X case OCUBEofUNDEAD: c[CUBEofUNDEAD]++; break;
X case ONOTHEFT: c[NOTHEFT]++; break;
X case OSWORDofSLASHING: c[DEXTERITY] +=5; limit=1; break;
X };
X lprcat("\nYou pick up:"); show3(i);
X if (limit) bottomline(); return(0);
X }
X lprcat("\nYou can't carry anything else"); return(1);
X }
X
X/*
X subroutine to drop an object returns 1 if something there already else 0
X */
Xdrop_object(k)
X int k;
X {
X int itm;
X if ((k<0) || (k>=MAXINVEN))
X return(0);
X itm = iven[k]; cursors();
X if (itm==0) { lprintf("\nYou don't have item %c! ",k+'a'); return(1); }
X if (item[playerx][playery])
X { beep(); lprcat("\nThere's something here already"); return(1); }
X if (playery==MAXY-1 && playerx==33) return(1); /* not in entrance */
X item[playerx][playery] = itm;
X iarg[playerx][playery] = ivenarg[k];
X lprcat("\n You drop:"); show3(k); /* show what item you dropped*/
X know[playerx][playery] = 0; iven[k]=0;
X if (c[WIELD]==k) c[WIELD]= -1; if (c[WEAR]==k) c[WEAR] = -1;
X if (c[SHIELD]==k) c[SHIELD]= -1;
X adjustcvalues(itm,ivenarg[k]);
X dropflag=1; /* say dropped an item so wont ask to pick it up right away */
X return(0);
X }
X
X/*
X routine to tell if player can carry one more thing
X returns 1 if pockets are full, else 0
X*/
Xpocketfull()
X {
X register int i,limit;
X if ((limit = MIN_LIMIT + (c[LEVEL]>>1) ) > MAXINVEN )
X limit = MAXINVEN;
X for (i=0; i<limit; i++)
X if (iven[i]==0)
X return(0);
X return(1);
X }
END_OF_FILE
if test 12705 -ne `wc -c <'iventory.c'`; then
echo shar: \"'iventory.c'\" unpacked with wrong size!
fi
# end of 'iventory.c'
fi
if test -f 'larn.hlp.uu' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn.hlp.uu'\"
else
echo shar: Extracting \"'larn.hlp.uu'\" \(11935 characters\)
sed "s/^X//" >'larn.hlp.uu' <<'END_OF_FILE'
Xbegin 644 larn.hlp
XM-R`@("!796QC;VUE('1O('1H92!G86UE(&]F($QA<FXN("!!="!T:&ES(&UOZ
XM;65N="P@>6]U(&9A8V4@82!G<F5A="!P<F]B;&5M+@I9;W5R(&1A=6=H=&5RL
XM(&AA<R!C;VYT<F%C=&5D(&$@<W1R86YG92!D:7-E87-E+"!A;F0@;F]N92!O4
XM9B!Y;W5R(&AO;64@<F5M961I97,*<V5E;2!T;R!H879E(&%N>2!E9F9E8W0NJ
XM("!9;W4@<V5N<V4@=&AA="!S:&4@:7,@:6X@;6]R=&%L(&1A;F=E<BP@86YD>
XM('EO=2!M=7-T"G1R>2!T;R!S879E(&AE<BX@(%1I;64@86=O('EO=2!H96%R1
XM9"!O9B!A(&QA;F0@;V8@9W)E870@9&%N9V5R(&%N9"!O<'!O<G1U;FET>2X*:
XM4&5R:&%P<R!H97)E(&ES('1H92!S;VQU=&EO;B!Y;W4@;F5E9"X*"B`@("!)5
XM="!H87,@8F5E;B!S86ED('1H870@=&AE<F4@;VYC92!W87,@82!G<F5A="!M%
XM86=I8VEA;B!W:&\@8V%L;&5D(&AI;7-E;&8*4&]L:6YN96%U<RX@($UA;GD@2
XM>65A<G,@86=O+"!A9G1E<B!H879I;F<@;6%N>2!M:7)A8W5L;W5S('-U8V-EB
XM<W-E<RP@4&]L:6YN96%U<PIR971I<F5D('1O('1H92!C879E<FYS(&]F($QA9
XM<FXL('=H97)E(&AE(&1E=F]T960@;6]S="!O9B!H:7,@=&EM92!T;R!T:&4*X
XM8W)E871I;VX@;V8@;6%G:6,N("`@4G5M;W)S(&AA=F4@:70@=&AA="!O;F4@5
XM9&%Y(%!O;&EN;F5A=7,@<V5T(&]U="!T;R!D:7-P96P*86X@871T86-K:6YGS
XM(&%R;7D@:6X@82!F;W)E<W0@<V]M92!D:7-T86YC92!T;R!T:&4@;F]R=&@N@
XM("!)="!I<R!B96QI979E9"!T:&%T"FAE<F4@:&4@;65T(&AI<R!D96UI<V4N4
XM"@H@("`@5&AE(&-A=F5R;G,@;V8@3&%R;BP@:70@:7,@=&AO=6=H="P@;75S2
XM="!B92!M86=N:69I8V5N="!I;B!D97-I9VXL"F%N9"!C;VYT86EN(&UU8V@@S
XM;6%G:6,@86YD('1R96%S=7)E+B`@3VYE(&]P=&EO;B!Y;W4@:&%V92!I<R!TY
XM;R!U;F1E<G1A:V4@80IJ;W5R;F5Y(&EN=&\@=&AE<V4@8V%V97)N<RX*"@H@Z
XM("`@1V]O9"!,=6-K(2`@66]U)W)E(&=O:6YG('1O(&YE960@:70A"@H*"@H@7
XM("`@("`@("`@("`@("`@&ULW;4AE;'`@1FEL92!F;W(@5&AE($-A=F5R;G,@=
XM;V8@3&%R;BP@4')O;7!T($UO9&4;6VT*"F(@(&UO=F4@<V]U=&AW97-T("`@[
XM("`@("`@($(@(')U;B!S;W5T:'=E<W0@("`@("`@("`@("!3("!S879E('1H+
XM92!G86UE"F@@(&UO=F4@;&5F="`@("`@("`@("`@("`@($@@(')U;B!L969T;
XM("`@("`@("`@("`@("`@("`N("!S=&%Y(&AE<F4*:B`@;6]V92!D;W=N("`@V
XM("`@("`@("`@("`@2B`@<G5N(&1O=VX@("`@("`@("`@("`@("`@(%X@(&ED"
XM96YT:69Y(&$@=')A<`IK("!M;W9E('5P("`@("`@("`@("`@("`@("!+("!RU
XM=6X@=7`@("`@("`@("`@("`@("`@("`@5"`@=&%K92!O9F8@87)M;W(*;"`@3
XM;6]V92!R:6=H="`@("`@("`@("`@("`@3"`@<G5N(')I9VAT"FX@(&UO=F4@C
XM<V]U=&AE87-T("`@("`@("`@($X@(')U;B!S;W5T:&5A<W0*=2`@;6]V92!N'
XM;W)T:&5A<W0@("`@("`@("`@52`@<G5N(&YO<G1H96%S=`IY("!M;W9E(&YO#
XM<G1H=V5S="`@("`@("`@("!9("!R=6X@;F]R=&AW97-T("`@("`@("`@("`@-
XM7DP@<F5D<F%W('1H92!S8W)E96X*8R`@8V%S="!A('-P96QL("`@("`@("`@)
XM("`@6B`@=&5L97!O<G0@>6]U<G-E;&8*9"`@9')O<"!A;B!I=&5M("`@("`@C
XM("`@("`@92`@96%T('-O;65T:&EN9PIG("!G970@<')E<V5N="!P86-K('=E:
XM:6=H="!0("!G:79E('1A>"!S=&%T=7,*:2`@:6YV96YT;W)Y('EO=7(@<&]CJ
XM:V5T<R`@22`@;&ES="!A;&P@:71E;7,@9F]U;F0@("`@(#\@('1H:7,@:&5L#
XM<"!S8W)E96X*<2`@<75A9F8@82!P;W1I;VX@("`@("`@("`@42`@<75I="!T`
XM:&4@9V%M90IR("!R96%D(&$@<V-R;VQL("`@("`@("`@("!V("!P<FEN="!PB
XM<F]G<F%M('9E<G-I;VX*=R`@=VEE;&0@82!W96%P;VX@("`@("`@("`@5R`@&
XM=V5A<B!A<FUO<B`@("`@("`@("`@("`@(%Y,(')E9')A=R!T:&4@<V-R965N@
XM"@H*"@H*"B`@("`@("`@("`@("`@("`;6S=M2&5L<"!&:6QE(&9O<B!4:&4@1
XM0V%V97)N<R!O9B!,87)N+"!#;VUM86YD($UO9&4;6VT*"F(@(&UO=F4@<V]UK
XM=&AW97-T("`@("`@("`@($(@(')U;B!S;W5T:'=E<W0@("`@("`@("`@("!!-
XM("!D97-E8W)A=&4@86X@86QT87(*8R`@8V%S="!A('-P96QL("`@("`@("`@,
XM("`@0R`@8VQO<V4@82!D;V]R("`@("`@("`@("`@(%H@('1E;&5P;W)T('EO_
XM=7)S96QF"F0@(&1R;W`@86X@:71E;2`@("`@("`@("`@($0@(&1R:6YK(&%T#
XM(&$@9F]U;G1A:6X@("`@("`\("!G;R!U<"!S=&%I<G,@;W(*92`@96%T('-O^
XM;65T:&EN9R`@("`@("`@("`@12`@96YT97(@82!S=&]R92P@9'5N9V5O;B`@Y
XM("`@('9O;&-A;FEC('-H869T"F<@(&=E="!P<F5S96YT('!A8VL@=V5I9VAT^
XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`^("!G;R!D;W=N('-T86ER/
XM<R!O<@IH("!M;W9E(&QE9G0@("`@("`@("`@("`@("!(("!R=6X@;&5F="`@P
XM("`@("`@("`@("`@("`@("`@=F]L8V%N:6,@<VAA9G0*:2`@:6YV96YT;W)YF
XM('EO=7(@<&]C:V5T<R`@22`@;&ES="!A;&P@:71E;7,@9F]U;F0@("`@(#\@C
XM('1H:7,@:&5L<"!S8W)E96X*:B`@;6]V92!D;W=N("`@("`@("`@("`@("`@D
XM2B`@<G5N(&1O=VX@("`@("`@("`@("`@("`@(%X@(&ED96YT:69Y(&$@=')AY
XM<`IK("!M;W9E('5P("`@("`@("`@("`@("`@("!+("!R=6X@=7`@("`@("`@&
XM("`@("`@("`@("`@+"`@<&EC:R!U<"!I=&5M"FP@(&UO=F4@<FEG:'0@("`@2
XM("`@("`@("`@($P@(')U;B!R:6=H="`@("`@("`@("`@("`@("`Z("!L;V]K.
XM(&%T(&]B:F5C="!Y;W4*;B`@;6]V92!S;W5T:&5A<W0@("`@("`@("`@3B`@&
XM<G5N('-O=71H96%S="`@("`@("`@("`@("`@(&%R92!S=&%N9&EN9R!O;@H@,
XM("`@("`@("`@("`@("`@("`@("`@("`@("!/("!O<&5N(&$@9&]O<B!O<B!C:
XM:&5S="`@("`@+B`@<W1A>2!H97)E"G`@('!R87D@870@86X@86QT87(@("`@5
XM("`@(%`@(&=I=F4@=&%X('-T871U<R`@("`@("`@("!M("!M;W9E('=I=&AO;
XM=70@<&EC:VEN9PIQ("!Q=6%F9B!A('!O=&EO;B`@("`@("`@("!1("!Q=6ET*
XM('1H92!G86UE("`@("`@("`@("`@("`@=7`@86X@;V)J96-T"G(@(')E860@>
XM82!S8W)O;&P@("`@("`@("`@(%(@(')E;6]V92!G96US(&9R;VT@=&AR;VYE@
XM("!`("!T;V=G;&4@875T;RUP:6-K=7`*<R`@<VET(&]N(&$@=&AR;VYE("`@O
XM("`@("`@4R`@<V%V92!T:&4@9V%M92`@("`@("`@("`@("\@(&ED96YT:69YH
XM(&]B:F5C=',@:6X*="`@=&ED>2!U<"!A="!A(&9O=6YT86EN("`@5"`@=&%KL
XM92!O9F8@87)M;W(@("`@("`@("`@("`@('1H92!G86UE"G4@(&UO=F4@;F]RA
XM=&AE87-T("`@("`@("`@(%4@(')U;B!N;W)T:&5A<W0*=B`@<')I;G0@<')O)
XM9W)A;2!V97)S:6]N"G<@('=I96QD(&$@=V5A<&]N("`@("`@("`@(%<@('=E!
XM87(@87)M;W(*>2`@;6]V92!N;W)T:'=E<W0@("`@("`@("`@62`@<G5N(&YO'
XM<G1H=V5S="`@("`@("`@("`@(%Y,(')E9')A=R!T:&4@<V-R965N"B`@("`@+
XM("`@("`@("`@("`;6S=M4W!E8VEA;"!.;W1E<QM;;0H*5VAE;B`;6S=M9')OL
XM<'!I;F<@9V]L9!M;;2P@:68@>6]U('1Y<&4@)RHG(&%S('EO=7(@86UO=6YTP
XM+"!A;&P@>6]U<B!G;VQD(&=E=',@9')O<'!E9"X*26X@9V5N97)A;"P@='EPQ
XM:6YG(&EN("<J)R!M96%N<R!A;&P@;V8@=VAA="!Y;W5R(&EN=&5R97-T960@)
XM:6XN("!4:&ES(&ES('1R=64*=VAE;B!V:7-I=&EN9R!T:&4@8F%N:RP@;W(@L
XM=VAE;B!C;VYT<FEB=71I;F<@870@86QT87)S+@H*3&%R;B!N965D<R!T:&4@%
XM04Y322Y365,@*&]R('!R969E<F%B;'DL('1H92!.04Y322Y365,I(&1E=FECT
XM92!D<FEV97(@:6YS=&%L;&5D"FEN('EO=7(@0T].1DE'+E-94R!F:6QE+B`@R
XM5&AE('-U<'!L:65D(")T97)M8V%P(B!F:6QE(&1E<V-R:6)E<R!T:&4@97-C'
XM87!E"G-E<75E;F-E<R!T;R!C:&%N9V4@=FED96\@;6]D97,@*'-E92!C:"`Q%
XM,R!O9B!T:&4@1$]3(#(N,"!M86YU86PI+B`@4V5E('1H90HB5$5234-!4"(@L
XM<V5C=&EO;B!I;B!,05).+D1/0R!F;W(@9G5R=&AE<B!D971A:6QS+@H*5VAEP
XM;B!I;B!T:&4@<W1O<F4L('1R861I;F<@<&]S="P@<V-H;V]L+"!O<B!H;VUEX
XM+"!A;B`;6S=M/&5S8V%P93X;6VT@=VEL;"!G970@>6]U(&]U="X*"E=H96X@$
XM8V%S=&EN9R!A('-P96QL+"!I9B!Y;W4@;F5E9"!A(&QI<W0@;V8@<W!E;&QS#
XM('EO=2!C86X@8V%S="P@='EP92`G&ULW;4D;6VTG(&%S"G1H92!F:7)S="!LO
XM971T97(@;V8@>6]U<B!S<&5L;"X@(%1H92!A=F%I;&%B;&4@;&ES="!O9B!S\
XM<&5L;',@=VEL;"!B92!S:&]W;BP*869T97(@=VAI8V@@>6]U(&UA>2!E;G1E9
XM<B!T:&4@<W!E;&P@8V]D92X@(%1H:7,@;VYL>2!W;W)K<R!O;B!T:&4@,7-TB
XM(&QE='1E<@IO9B!T:&4@<W!E;&P@>6]U(&%R92!C87-T:6YG+@H*5VAE;B!AC
XM;B!I;G9E;G1O<GD@;&ES="!I<R!O;B!T:&4@<V-R965N(&9R;VT@82!D<F]P\
XM+"!Q=6%F9BP@<F5A9"P@;W(@<VEM:6QA<@IC;VUM86YD+"!Y;W4@8V%N('1YV
XM<&4@=&AE(&QE='1E<B!O9B!T:&4@;V)J96-T('1H870@>6]U('=I<V@@=&\@?
XM86-T(&%P;VXL"G=I=&AO=70@:&%V:6YG('1O('1Y<&4@82!S<&%C92!T;R!G)
XM970@8F%C:R!T;R!T:&4@<')O;7!T+@H*5&AI<R!V97)S:6]N(&]F($QA<FX@R
XM:7,@8GD@2V5V:6X@4F]U=&QE>2X*("`@("`@("`@("`@("`@("`@("`@("`@`
XM&ULW;4QA<FX@0V]M;6%N9"!,:6YE($]P=&EO;G,;6VT*"FQA<FX@*RL@("`@4
XM("`@("`@("`@("`@(')E<W1O<F4@8VAE8VMP;VEN=&5D(&=A;64*;&%R;B`MS
XM<R`@("`@("`@("`@("`@("`@;&ES="!T:&4@<V-O<F5B;V%R9`IL87)N("UIA
XM("`@("`@("`@("`@("`@("!L:7-T('-C;W)E<R!W:71H(&EN=F5N=&]R:65S]
XM"FQA<FX@+6X@("`@("`@("`@("`@("`@('-U<'!R97-S('=E;&-O;64@;65S(
XM<V%G92!W:&5N(&)E9VEN;FEN9R!A(&=A;64*;&%R;B`M:"`@("`@("`@("`@*
XM("`@("`@<')I;G0@;W5T(&%L;"!T:&4@8V]M;6%N9"!L:6YE(&]P=&EO;G,*<
XM;&%R;B`M/R`@("`@("`@("`@("`@("`@<')I;G0@;W5T(&%L;"!T:&4@8V]M7
XM;6%N9"!L:6YE(&]P=&EO;G,*;&%R;B`M/&YU;6)E<CX@("`@("`@("`@<W!EC
XM8VEF>2!D:69F:6-U;'1Y(&]F('1H92!G86UE"FQA<FX@+6\\;W!T<V9I;&4^A
XM("`@("`@('-P96-I9GD@=&AE(&]P=&EO;B!F:6QE('1O(&)E('5S960*;&%RQ
XM;B`M8R`@("`@("`@("`@("`@("`@8W)E871E(&YE=R!S8V]R96)O87)D<R`M@
XM+2!P<F]M<'1S(&9O<B!A('!A<W-W;W)D"FQA<FX@+6P@("`@("`@("`@("`@M
XM("`@('!R:6YT(&]U="!T:&4@;&%R;B!L;V<@9FEL90IL87)N("UP("`@("`@I
XM("`@("`@("`@("!P;&%Y(&EN('!R;VUP="!M;V1E"@H*"@H*"@H*"@H@("`@"
XM("`@("`@("`;6S=M0F%C:V=R;W5N9"!);F9O<FUA=&EO;B!F;W(@3&%R;AM;*
XM;0H*("`@(%=E;&-O;64@=&\@=&AE(&=A;64@;V8@3&%R;BX@($%T('1H:7,@H
XM;6]M96YT+"!Y;W4@9F%C92!A(&=R96%T('!R;V)L96TN"EEO=7(@9&%U9VATQ
XM97(@:&%S(&-O;G1R86-T960@82!S=')A;F=E(&1I<V5A<V4L(&%N9"!N;VYE<
XM(&]F('EO=7(@:&]M92!R96UE9&EE<PIS965M('1O(&AA=F4@86YY(&5F9F5C7
XM="X@(%EO=2!S96YS92!T:&%T('-H92!I<R!I;B!M;W)T86P@9&%N9V5R+"!AN
XM;F0@>6]U(&UU<W0*=')Y('1O('-A=F4@:&5R+B`@5&EM92!A9V\@>6]U(&AE0
XM87)D(&]F(&$@;&%N9"!O9B!G<F5A="!D86YG97(@86YD(&]P<&]R='5N:71YU
XM+@I097)H87!S(&AE<F4@:7,@=&AE('-O;'5T:6]N('EO=2!N965D+@H*("`@D
XM($ET(&AA<R!B965N('-A:60@=&AA="!T:&5R92!O;F-E('=A<R!A(&=R96%TA
XM(&UA9VEC:6%N('=H;R!C86QL960@:&EM<V5L9@I0;VQI;FYE875S+B`@36%N&
XM>2!Y96%R<R!A9V\L(&%F=&5R(&AA=FEN9R!M86YY(&UI<F%C=6QO=7,@<W5CS
XM8V5S<V5S+"!0;VQI;FYE875S"G)E=&ER960@=&\@=&AE(&-A=F5R;G,@;V8@T
XM3&%R;BP@=VAE<F4@:&4@9&5V;W1E9"!M;W-T(&]F(&AI<R!T:6UE('1O('1HV
XM90IC<F5A=&EO;B!O9B!M86=I8RX@("!2=6UO<G,@:&%V92!I="!T:&%T(&]N_
XM92!D87D@4&]L:6YN96%U<R!S970@;W5T('1O(&1I<W!E;`IA;B!A='1A8VMIC
XM;F<@87)M>2!I;B!A(&9O<F5S="!S;VUE(&1I<W1A;F-E('1O('1H92!N;W)T?
XM:"X@($ET(&ES(&)E;&EE=F5D('1H870*:&5R92!H92!M970@:&ES(&1E;6ES7
XM92X*"B`@("!4:&4@8V%V97)N<R!O9B!,87)N+"!I="!I<R!T:&]U9VAT+"!M]
XM=7-T(&)E(&UA9VYI9FEC96YT(&EN(&1E<VEG;BP*86YD(&-O;G1A:6X@;75C3
XM:"!M86=I8R!A;F0@=')E87-U<F4N("!/;F4@;W!T:6]N('EO=2!H879E(&ESM
XM('1O('5N9&5R=&%K92!A"FIO=7)N97D@:6YT;R!T:&5S92!C879E<FYS+@H*D
XM("`@($=O;V0@3'5C:R$@(%EO=2=R92!G;VEN9R!T;R!N965D(&ET(0H*"@H@M
XM("`@("`@("`@("`;6S=M2&]W('1O('5S92!T:&4@;&%R;BYO<'0@;W!T:6]N`
XM(&9I;&4;6VT*"E1H92!F:6QE(")L87)N+F]P="(L(&EF('5S960L('-H;W5L-
XM9"!B92!I;B!A(&1I<F5C=&]R>2!A;&]N9R!Y;W5R(%!!5$@N"D$@<V5Q=65N/
XM8V4@;V8@=V]R9',@=&5R;6EN871E9"!B>2!W:&ET97-P86-E(&ES('5S960@.
XM=&\@<W!E8VEF>2!O<'1I;VYS+@H*("`@(%=O<F0@("`@("`@("`@("`@("`@`
XM("`@("`@365A;FEN9PH@("`@8W5R<V]R.B!L;W=S8V%N(&AI9VAS8V%N("!C`
XM:&%N9V4@=&AE('-H87!E(&]F('1H92!C=7)S;W(*("`@($1%0U)A:6YB;W<@Q
XM("`@("`@("`@("`@("`@=&5L;"!,05).('EO=2!H879E('1H870@8V]M<'5TH
XM97(*("`@(&5N86)L92UC:&5C:W!O:6YT:6YG("`@("`@='5R;B!O;B!P97)IQ
XM;V1I8R!C:&5C:W!O:6YT:6YG"B`@("!G<F%P:&EC<SH@=V%L;&,@9FQO;W)C2
XM("`@('-E;&5C="!G<F%P:&EC<R!M87IE(&-H87)A8W1E<G,*("`@(&ME>7!AB
XM9"`@("`@("`@("`@("`@("`@("`@96YA8FQE('1H92!N=6UE<FEC(&ME>7!AY
XM9"!F;W(@;6]V:6YG"B`@("!L87)N9&ER.B`@9&ER96-T;W)Y("`@("`@('1H\
XM92!D:7)E8W1O<GD@=&\@=7-E(&9O<B!L87)N(&9I;&5S"B`@("!M;VYS=&5R#
XM.B`@(FUO;G-T(&YA;64B("`@(&-H;V]S92!A(&YA;64@9F]R(&$@;6]N<W1E1
XM<@H@("`@;F%M93H@("`@(")Y;W5R(&YA;64B("`@("!C:&]O<V4@>6]U<B!PK
XM;&%Y:6YG(&YA;64*("`@(&YO+6)E97`@("`@("`@("`@("`@("`@("`@9&ES5
XM86)L92!B965P:6YG(&]F('1H92!T97)M:6YA;`H@("`@;F\M:6YT<F]D=6-T0
XM:6]N("`@("`@("`@("!D;R!N;W0@9&ES<&QA>2!I;G1R;R!M97-S86=E"B`@;
XM("!S879E9FEL93H@<V%V92UF:6QE+6YA;64@(&1E9FEN92!W:&%T('1H92!SF
XM879E9V%M92!F:6QE;F%M92!W:6QL(&)E"B`@("!S=V%P9FEL93H@<W=A<"UF#
XM:6QE+6YA;64@(&1E9FEN92!T:&4@;F%M92!O9B!T:&4@<W=A<&9I;&4*"EEO"
XM=7(@;F%M92!A;F0@;6]N<W1E<B!N86UE<R!M=7-T(&)E(&5N8VQO<V5D(&EN+
XM(&1O=6)L92!Q=6]T871I;VX@;6%R:W,@86YD(&UA>0IB92!U<"!T;R`S-"!CZ
XM:&%R86-T97)S(&QO;F<N("!,;VYG97(@;F%M97,@87)E('1R=6YC871E9"X@F
XM($%N>71H:6YG(&5N8VQO<V5D(&EN"G%U;W1A=&EO;B!M87)K<R!I<R!C;VYS!
XM:61E<F5D(&]N92!W;W)D+"!A;F0@;75S="!B92!S97!A<F%T960@9G)O;2!OV
XM=&AE<B!W;W)D<PIB>2!W:&ET97-P86-E+@H@("`@("`@("`@(!M;-VU%>'!L_
XM86YA=&EO;B!O9B!T:&4@3&%R;B!S8V]R96)O87)D(&9A8VEL:71Y&UMM"@H@]
XM("`@3&%R;B!S=7!P;W)T<R!45T\@<V-O<F5B;V%R9',L(&]N92!F;W(@=VEN1
XM;F5R<RP@86YD(&]N92!F;W(@9&5C96%S960*8VAA<F%C=&5R<RX@($5A8V@@W
XM<&QA>65R("AB>2!U<V5R:60@;W(@<&QA>65R:60L('-E92!524130T]212!IG
XM;B!-86ME9FEL92D*:7,@86QL;W=E9"!O;F4@<VQO="!O;B!E86-H('-C;W)EQ
XM8F]A<F0L(&EF('1H92!S8V]R92!I<R!I;B!T:&4@=&]P('1E;B!F;W(*=&AA<
XM="!S8V]R96)O87)D+B`@5&AI<R!D97-I9VX@:&5L<',@:6YS=7)E('1H870@[
XM9G)E<75E;G0@<&QA>65R<R!O9B!,87)N"F1O(&YO="!H;V<@=&AE('-C;W)EU
XM8F]A<F0L(&%N9"!G:79E<R!M;W)E('!L87EE<G,@82!C:&%N8V4@9F]R(&=L5
XM;W)Y+B`@3&5V96P*;V8@9&EF9FEC=6QT>2!I<R!A;'-O(&YO=&5D(&]N('1HP
XM92!S8V]R96)O87)D<RP@86YD('1H:7,@=&%K97,@<')E8V5D96YC90IO=F5R?
XM('-C;W)E(&9O<B!D971E<FUI;FEN9R!W:&%T(&5N=')Y(&ES(&]N('1H92!SL
XM8V]R96)O87)D+B`@1F]R(&5X86UP;&4Z"FEF(")987(L('1H92!"=6<@4VQA>
XM>65R(B!H87,@82!S8V]R92!O9B`Q,C@P,#,@;VX@=&AE('-C;W)E8F]A<F0@0
XM870@9&EF9B`P+`IT:&5N(&$@9V%M92!A="!D:69F(#$@86YD(&$@<V-O<F4@M
XM;V8@-#$Q,B!W;W5L9"!R97!L86-E('1H92!P<F5V:6]U<PIE;G1R>2!O;B!T/
XM:&4@<V-O<F5B;V%R9"X@($YO=&4@=&AA="!W:&5N(&$@<&QA>65R(&1I97,L7
XM('1H92!I;G9E;G1O<GD@:7,*<W1O<F5D(&EN('1H92!S8V]R96)O87)D('-OD
XM('1H870@979E<GEO;F4@8V%N('-E92!W:&%T(&ET96US('1H92!P;&%Y97(@1
XE:&%D"F%T('1H92!T:6UE(&]F(&1E871H+@H*"@H*"@H*"@HN"B!PQ
X``
Xend
Xsize 8497
END_OF_FILE
if test 11935 -ne `wc -c <'larn.hlp.uu'`; then
echo shar: \"'larn.hlp.uu'\" unpacked with wrong size!
fi
# end of 'larn.hlp.uu'
fi
echo shar: End of archive 5 \(of 17\).
cp /dev/null ark5isdone
#!/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 7 (of 17)."
# Contents: global.c larn123.doc
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:53 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'global.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'global.c'\"
else
echo shar: Extracting \"'global.c'\" \(16992 characters\)
sed "s/^X//" >'global.c' <<'END_OF_FILE'
X/* global.c
X *
X * raiselevel() subroutine to raise the player one level
X * loselevel() subroutine to lower the player by one level
X * raiseexperience(x) subroutine to increase experience points
X * loseexperience(x) subroutine to lose experience points
X * losehp(x) subroutine to remove hit points from the player
X * losemhp(x) subroutine to remove max # hit points from the player
X * raisehp(x) subroutine to gain hit points
X * raisemhp(x) subroutine to gain maximum hit points
X * losemspells(x) subroutine to lose maximum spells
X * raisemspells(x) subroutine to gain maximum spells
X * makemonst(lev) function to return monster number for a randomly selected monster
X * positionplayer() function to be sure player is not in a wall
X * recalc() function to recalculate the armor class of the player
X * quit() subroutine to ask if the player really wants to quit
X * more()
X * take()
X * drop_object()
X * enchantarmor()
X * enchweapon()
X * pocketfull()
X * nearbymonst()
X * stealsomething()
X * emptyhanded()
X * creategem()
X * adjustcvalues()
X * gettokstr()
X * getpassword()
X * getyn()
X * packweight()
X */
X
X#include <ctype.h>
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
Xextern int score[],dropflag;
Xextern short playerx,playery,lastnum;
Xextern char cheat,level,monstnamelist[];
Xextern char lastmonst[],*what[],*who[];
Xextern char winner[];
Xextern char logname[],monstlevel[];
Xextern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
X
X#ifdef __STDC__
Xextern void show3( int );
X#else
Xextern void show3();
X#endif
X
X/*
X raiselevel()
X
X subroutine to raise the player one level
X uses the skill[] array to find level boundarys
X uses c[EXPERIENCE] c[LEVEL]
X */
Xraiselevel()
X {
X if (c[LEVEL] < MAXPLEVEL) raiseexperience((long)(skill[c[LEVEL]]-c[EXPERIENCE]));
X }
X
X/*
X loselevel()
X
X subroutine to lower the players character level by one
X */
Xloselevel()
X {
X if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL]-1] + 1));
X }
X
X/*
X raiseexperience(x)
X
X subroutine to increase experience points
X */
Xraiseexperience(x)
X register long x;
X {
X register int i,tmp;
X i=c[LEVEL]; c[EXPERIENCE]+=x;
X while (c[EXPERIENCE] >= skill[c[LEVEL]] && (c[LEVEL] < MAXPLEVEL))
X {
X tmp = (c[CONSTITUTION]-c[HARDGAME])>>1;
X c[LEVEL]++; raisemhp((int)(rnd(3)+rnd((tmp>0)?tmp:1)));
X raisemspells((int)rund(3));
X if (c[LEVEL] < 7-c[HARDGAME]) raisemhp((int)(c[CONSTITUTION]>>2));
X }
X if (c[LEVEL] != i)
X {
X cursors();
X beep(); lprintf("\nWelcome to level %d",(long)c[LEVEL]); /* if we changed levels */
X }
X bottomline();
X }
X
X/*
X loseexperience(x)
X
X subroutine to lose experience points
X */
Xloseexperience(x)
X register long x;
X {
X register int i,tmp;
X i=c[LEVEL]; c[EXPERIENCE]-=x;
X if (c[EXPERIENCE] < 0) c[EXPERIENCE]=0;
X while (c[EXPERIENCE] < skill[c[LEVEL]-1])
X {
X if (--c[LEVEL] <= 1) c[LEVEL]=1; /* down one level */
X tmp = (c[CONSTITUTION]-c[HARDGAME])>>1; /* lose hpoints */
X losemhp((int)rnd((tmp>0)?tmp:1)); /* lose hpoints */
X if (c[LEVEL] < 7-c[HARDGAME]) losemhp((int)(c[CONSTITUTION]>>2));
X losemspells((int)rund(3)); /* lose spells */
X }
X if (i!=c[LEVEL])
X {
X cursors();
X beep(); lprintf("\nYou went down to level %d!",(long)c[LEVEL]);
X }
X bottomline();
X }
X
X/*
X losehp(x)
X losemhp(x)
X
X subroutine to remove hit points from the player
X warning -- will kill player if hp goes to zero
X */
Xlosehp(x)
X register int x;
X {
X if ((c[HP] -= x) <= 0)
X {
X beep(); lprcat("\n"); nap(3000); died(lastnum);
X }
X }
X
Xlosemhp(x)
X register int x;
X {
X c[HP] -= x; if (c[HP] < 1) c[HP]=1;
X c[HPMAX] -= x; if (c[HPMAX] < 1) c[HPMAX]=1;
X }
X
X/*
X raisehp(x)
X raisemhp(x)
X
X subroutine to gain maximum hit points
X */
Xraisehp(x)
X register int x;
X {
X if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX];
X }
X
Xraisemhp(x)
X register int x;
X {
X c[HPMAX] += x; c[HP] += x;
X }
X
X/*
X raisemspells(x)
X
X subroutine to gain maximum spells
X*/
Xraisemspells(x)
X register int x;
X {
X c[SPELLMAX]+=x; c[SPELLS]+=x;
X }
X
X/*
X losemspells(x)
X
X subroutine to lose maximum spells
X*/
Xlosemspells(x)
X register int x;
X {
X if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX]=0;
X if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
X }
X
X/*
X makemonst(lev)
X int lev;
X
X function to return monster number for a randomly selected monster
X for the given cave level
X */
Xmakemonst(lev)
X register int lev;
X {
X register int tmp,x;
X if (lev < 1)
X lev = 1;
X if (lev > 12)
X lev = 12;
X if (lev < 5)
X tmp=rnd((x=monstlevel[lev-1])?x:1);
X else
X tmp=rnd((x=monstlevel[lev-1]-monstlevel[lev-4])?x:1)+monstlevel[lev-4];
X
X while (monster[tmp].genocided && tmp<MAXMONST)
X tmp++; /* genocided? */
X return(tmp);
X }
X
X/*
X positionplayer()
X
X Insure player is not in a wall or on top of a monster. Could be more
X intelligent about what kinds of objects the player can land on.
X */
Xpositionplayer()
X {
X int z, try = 2;
X
X /* set the previous player x,y position to the new one, so that
X clearing the player indicator from the previous location will
X not do the wrong thing.
X */
X oldx = playerx ;
X oldy = playery ;
X
X /* short-circuit the testing if current position empty
X */
X if (!item[playerx][playery] &&
X !mitem[playerx][playery])
X return;
X
X /* make at most two complete passes across the dungeon, looking
X for a clear space. In most situations, should find a clear
X spot right around the current player position.
X */
X do
X {
X
X /* check all around the player position for a clear space.
X */
X for (z=1; z<9 ; z++)
X {
X int tmpx = playerx + diroffx[z];
X int tmpy = playery + diroffy[z];
X if (!item[tmpx][tmpy] &&
X !mitem[tmpx][tmpy])
X {
X playerx = tmpx ;
X playery = tmpy ;
X return;
X }
X }
X
X /* no clear spots around the player. try another position,
X wrapping around the dungeon.
X */
X if (++playerx >= MAXX-1)
X {
X playerx = 1;
X if (++playery >= MAXY-1)
X {
X playery = 1;
X try--;
X }
X }
X }
X while (try);
X
X /* no spot found.
X */
X lprcat("Failure in positionplayer\n");
X }
X
X/*
X recalc() function to recalculate the armor class of the player
X */
Xrecalc()
X {
X register int i,j,k;
X c[AC] = c[MOREDEFENSES];
X if (c[WEAR] >= 0)
X switch(iven[c[WEAR]])
X {
X case OSHIELD: c[AC] += 2 + ivenarg[c[WEAR]]; break;
X case OLEATHER: c[AC] += 2 + ivenarg[c[WEAR]]; break;
X case OSTUDLEATHER: c[AC] += 3 + ivenarg[c[WEAR]]; break;
X case ORING: c[AC] += 5 + ivenarg[c[WEAR]]; break;
X case OCHAIN: c[AC] += 6 + ivenarg[c[WEAR]]; break;
X case OSPLINT: c[AC] += 7 + ivenarg[c[WEAR]]; break;
X case OPLATE: c[AC] += 9 + ivenarg[c[WEAR]]; break;
X case OPLATEARMOR: c[AC] += 10 + ivenarg[c[WEAR]]; break;
X case OSSPLATE: c[AC] += 12 + ivenarg[c[WEAR]]; break;
X }
X
X if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]];
X if (c[WIELD] < 0) c[WCLASS] = 0; else
X {
X i = ivenarg[c[WIELD]];
X switch(iven[c[WIELD]])
X {
X case ODAGGER: c[WCLASS] = 3 + i; break;
X case OBELT: c[WCLASS] = 7 + i; break;
X case OSHIELD: c[WCLASS] = 8 + i; break;
X case OSPEAR: c[WCLASS] = 10 + i; break;
X case OFLAIL: c[WCLASS] = 14 + i; break;
X case OBATTLEAXE: c[WCLASS] = 17 + i; break;
X case OLANCE: c[WCLASS] = 19 + i; break;
X case OLONGSWORD: c[WCLASS] = 22 + i; break;
X case O2SWORD: c[WCLASS] = 26 + i; break;
X case OSWORD: c[WCLASS] = 32 + i; break;
X case OSWORDofSLASHING: c[WCLASS] = 30 + i; break;
X case OHAMMER: c[WCLASS] = 35 + i; break;
X default: c[WCLASS] = 0;
X }
X }
X c[WCLASS] += c[MOREDAM];
X
X/* now for regeneration abilities based on rings */
X c[REGEN]=1; c[ENERGY]=0;
X j=0; for (k=25; k>0; k--) if (iven[k]) {j=k; k=0; }
X for (i=0; i<=j; i++)
X {
X switch(iven[i])
X {
X case OPROTRING: c[AC] += ivenarg[i] + 1; break;
X case ODAMRING: c[WCLASS] += ivenarg[i] + 1; break;
X case OBELT: c[WCLASS] += ((ivenarg[i]<<1)) + 2; break;
X
X case OREGENRING: c[REGEN] += ivenarg[i] + 1; break;
X case ORINGOFEXTRA: c[REGEN] += 5 * (ivenarg[i]+1); break;
X case OENERGYRING: c[ENERGY] += ivenarg[i] + 1; break;
X }
X }
X }
X
X
X/*
X quit()
X
X subroutine to ask if the player really wants to quit
X */
Xquit()
X {
X register int i;
X cursors(); strcpy(lastmonst,"");
X lprcat("\n\nDo you really want to quit?");
X while (1)
X {
X i=ttgetch();
X if ((i == 'y') || (i == 'Y'))
X {
X died(300);
X return;
X }
X if ((i == 'n') || (i == 'N') || (i == '\33'))
X {
X lprcat(" no");
X lflush();
X return;
X }
X lprcat("\n");
X setbold(); lprcat("Yes"); resetbold();
X lprcat(" or ");
X setbold(); lprcat("No"); resetbold();
X lprcat(" please? Do you want to quit? ");
X }
X }
X
X/*
X function to ask --more--. If the user enters a space, returns 0. If user
X enters Escape, returns 1. If user enters alphabetic, then returns that
X value.
X */
Xmore(select_allowed)
Xchar select_allowed;
X {
X register int i;
X
X lprcat("\n --- press "); standout("space"); lprcat(" to continue --- ");
X if (select_allowed)
X lprcat("letter to select --- ");
X
X while (TRUE)
X {
X if ((i=ttgetch()) == ' ' || i == '\n')
X return 0 ;
X if (i== '\x1B')
X return 1 ;
X if (select_allowed)
X {
X if (isupper(i))
X i = tolower(i);
X if ( i >= 'a' && i <= 'z' || i == '.' )
X return i;
X }
X }
X }
X
X/*
X function to enchant armor player is currently wearing
X */
Xenchantarmor()
X {
X register int tmp;
X if (c[WEAR]<0) { if (c[SHIELD] < 0)
X { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
X else { tmp=iven[c[SHIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[SHIELD]]++; bottomline(); } } }
X tmp = iven[c[WEAR]];
X if (tmp!=OSCROLL) if (tmp!=OPOTION) { ivenarg[c[WEAR]]++; bottomline(); }
X }
X
X/*
X function to enchant a weapon presently being wielded
X */
Xenchweapon()
X {
X register int tmp;
X if (c[WIELD]<0)
X { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
X tmp = iven[c[WIELD]];
X if (tmp!=OSCROLL) if (tmp!=OPOTION)
X { ivenarg[c[WIELD]]++;
X if (tmp==OCLEVERRING) c[INTELLIGENCE]++; else
X if (tmp==OSTRRING) c[STREXTRA]++; else
X if (tmp==ODEXRING) c[DEXTERITY]++; bottomline(); }
X }
X
X/*
X function to return 1 if a monster is next to the player else returns 0
X */
Xnearbymonst()
X {
X register int tmp,tmp2;
X for (tmp=playerx-1; tmp<playerx+2; tmp++)
X for (tmp2=playery-1; tmp2<playery+2; tmp2++)
X if (mitem[tmp][tmp2]) return(1); /* if monster nearby */
X return(0);
X }
X
X/*
X function to steal an item from the players pockets
X returns 1 if steals something else returns 0
X */
Xstealsomething()
X {
X register int i,j;
X j=100;
X while (1)
X {
X i=rund(26);
X if (iven[i]) if (c[WEAR]!=i) if (c[WIELD]!=i) if (c[SHIELD]!=i)
X {
X show3(i);
X adjustcvalues(iven[i],ivenarg[i]); iven[i]=0; return(1);
X }
X if (--j <= 0) return(0);
X }
X }
X
X/*
X function to return 1 is player carrys nothing else return 0
X */
Xemptyhanded()
X {
X register int i;
X for (i=0; i<26; i++)
X if (iven[i]) if (i!=c[WIELD]) if (i!=c[WEAR]) if (i!=c[SHIELD]) return(0);
X return(1);
X }
X
X/*
X function to create a gem on a square near the player
X */
Xcreategem()
X {
X register int i,j;
X switch(rnd(4))
X {
X case 1: i=ODIAMOND; j=50; break;
X case 2: i=ORUBY; j=40; break;
X case 3: i=OEMERALD; j=30; break;
X default: i=OSAPPHIRE; j=20; break;
X };
X createitem(i,rnd(j)+j/10);
X }
X
X/*
X function to change character levels as needed when dropping an object
X that affects these characteristics
X */
Xadjustcvalues(itm,arg)
X int itm,arg;
X {
X register int flag;
X flag=0;
X switch(itm)
X {
X case ODEXRING: c[DEXTERITY] -= arg+1; flag=1; break;
X case OSTRRING: c[STREXTRA] -= arg+1; flag=1; break;
X case OCLEVERRING: c[INTELLIGENCE] -= arg+1; flag=1; break;
X case OHAMMER: c[DEXTERITY] -= 10; c[STREXTRA] -= 10;
X c[INTELLIGENCE] += 10; flag=1; break;
X case OSWORDofSLASHING: c[DEXTERITY] -= 5; flag=1; break;
X case OORBOFDRAGON: --c[SLAYING]; return;
X case OSPIRITSCARAB: --c[NEGATESPIRIT]; return;
X case OCUBEofUNDEAD: --c[CUBEofUNDEAD]; return;
X case ONOTHEFT: --c[NOTHEFT]; return;
X case OLANCE: c[LANCEDEATH]=0; return;
X case OPOTION: case OSCROLL: return;
X
X default: flag=1;
X };
X if (flag) bottomline();
X }
X
X/*
X function to ask user for a password (no echo)
X returns 1 if entered correctly, 0 if not
X */
Xstatic char gpwbuf[33];
Xgetpassword()
X {
X register int i,j;
X register char *gpwp;
X extern char *password;
X scbr(); /* system("stty -echo cbreak"); */
X gpwp = gpwbuf; lprcat("\nEnter Password: "); lflush();
X i = strlen(password);
X for (j=0; j<i; j++)
X *gpwp++ = ttgetch();
X gpwbuf[i]=0;
X sncbr(); /* system("stty echo -cbreak"); */
X if (strcmp(gpwbuf,password) != 0)
X { lprcat("\nSorry\n"); lflush(); return(0); }
X else return(1);
X }
X
X/*
X subroutine to get a yes or no response from the user
X returns y or n
X */
Xgetyn()
X {
X register int i=0;
X while (i!='y' && i!='n' && i!='\33')
X i=ttgetch();
X return(i);
X }
X
X/*
X function to calculate the pack weight of the player
X returns the number of pounds the player is carrying
X */
Xpackweight()
X {
X register int i, j=25, k;
X
X k=c[GOLD]/1000;
X while ((iven[j]==0) && (j>0))
X --j;
X for (i=0; i<=j; i++)
X switch(iven[i])
X {
X case 0:
X break;
X case OSSPLATE:
X case OPLATEARMOR:
X k += 40;
X break;
X case OPLATE:
X k += 35;
X break;
X case OHAMMER:
X k += 30;
X break;
X case OSPLINT:
X k += 26;
X break;
X case OSWORDofSLASHING:
X case OCHAIN:
X case OBATTLEAXE:
X case O2SWORD:
X k += 23;
X break;
X case OLONGSWORD:
X case OSWORD:
X case ORING:
X case OFLAIL:
X k += 20;
X break;
X case OLANCE:
X case OSTUDLEATHER:
X k += 15;
X break;
X case OLEATHER:
X case OSPEAR:
X k += 8;
X break;
X case OORBOFDRAGON:
X case OBELT:
X k += 4;
X break;
X case OSHIELD:
X k += 7;
X break;
X case OCHEST:
X k += 30 + ivenarg[i];
X break;
X default:
X k++;
X break;
X };
X return(k);
X }
X
X#ifndef MACRORND
X /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */
Xrnd(x)
X int x;
X {
X return((((lrandx=lrandx*1103515245+12345)>>7)%(x))+1);
X }
X
Xrund(x)
X int x;
X {
X return((((lrandx=lrandx*1103515245+12345)>>7)%(x)) );
X }
X#endif MACRORND
X
X#if 0
X/*
X function to read a string from token input "string"
X returns a pointer to the string
X */
Xgettokstr(str)
X register char *str;
X {
X register int i,j;
X i=50;
X while ((ttgetch() != '"') && (--i > 0));
X i=36;
X while (--i > 0)
X {
X if ((j=ttgetch()) != '"') *str++ = j; else i=0;
X }
X *str = 0;
X i=50;
X if (j != '"') while ((ttgetch() != '"') && (--i > 0)); /* if end due to too long, then find closing quote */
X }
X#endif
END_OF_FILE
if test 16992 -ne `wc -c <'global.c'`; then
echo shar: \"'global.c'\" unpacked with wrong size!
fi
# end of 'global.c'
fi
if test -f 'larn123.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn123.doc'\"
else
echo shar: Extracting \"'larn123.doc'\" \(18665 characters\)
sed "s/^X//" >'larn123.doc' <<'END_OF_FILE'
X
X
X PC LARN version 12.3 for IBM PC Compatibles
X -------------------------------------------
X
X
X Table of contents
X -----------------
X
X
X 1. Introduction
X 2. System requirements
X 3. Files Supplied
X 4. Installation
X 5. Configuration
X 6. Command line options
X 7. TERMCAP
X 8. WIZARD mode
X 9. History and other Information
X
X
X
X
X 1. Introduction
X ---------------
X
X LARN is a dungeon type adventure game similar in concept to HACK, ROGUE
X or MORIA, but with a different feel and winning criteria. LARN was
X released for the UNIX environment in 1986 by Noah Morgan. It was
X subsequently ported to the MS-DOS environment by Don Kneller. Kevin
X Routley has been working on enhancements to LARN on and off for the
X past two years.
X
X
X 2. System requirements
X ----------------------
X
X PC LARN requires:
X
X - MS-DOS or PC-DOS 2.x or above.
X
X - at least 256K of RAM.
X
X - disk storage capacity of at least 360K, although twice that much is
X preferred if you want to "checkpoint" your game to prevent
X accidental lose due to a system failure.
X
X - the ANSI.SYS device driver must be installed (although the NANSI.SYS
X driver is *strongly* preferred and has been included in this
X distribution). You should install either ANSI.SYS or NANSI.SYS, but
X not both. To install NANSI.SYS, put the line "device=NANSI.SYS" in
X your CONFIG.SYS file. See the TERMCAP section for further details.
X
X
X 3. Files supplied
X -----------------
X
X The following files should be included in this LARN123.ZIP file:
X
X LARN123.DOC This documentation.
X
X LARN123.FIX Changes made between LARN V12.2 and V12.3.
X
X LARN123.EXE The executable file.
X
X LARN.FTN Fortune cookie messages.
X
X LARN.HLP A help file, which can be read with the "?"
X command in LARN.
X
X LARN.MAZ Some maze levels are pre-calculated and
X stored here.
X
X LARN.OPT An example LARN.OPT file (see the CONFIGURATION
X section).
X
X TERMCAP A file describing the escape sequences to send
X to the terminal. The supplied TERMCAP file is
X for monochrome systems. See the TERMCAP section
X for details on changing TERMCAP.
X
X NANSI.DOC The documentation for NANSI.SYS.
X
X NANSI.SYS A new ANSI.SYS that is *much* faster than
X ANSI.SYS and supports the line insert and line
X delete escape sequence that LARN uses. This
X excellent product is written by Daniel Kegel.
X See the TERMCAP section and NANSI.DOC for more
X details.
X
X
X 4. Installation
X ---------------
X
X NANSI.SYS or ANSI.SYS must be installed as a device driver on your
X system in order for LARN to work (see System Requirements above).
X
X For a hard disk system I suggest creating a \GAMES\LARN directory and
X placing LARN and the provided support files in that directory. Following
X that, you would place \GAMES\LARN in your PATH.
X
X LARN will create several other files (LARN.SCR, LARN.PID, LARN.LOG)
X in that directory. Also, save files (LARN.SAV) and checkpoint files
X (LARN.CKP) will go in there by default. You will want to set the
X 'larndir:' option in your LARN.OPT file (see the Configuration section
X below) to point to this directory.
X
X For two-floppy systems, I would suggest the following:
X
X o place LARN123.EXE, LARN.OPT and TERMCAP. on disk one.
X
X o place LARN.FTN, LARN.MAZ, and LARN.HLP on disk two. This will
X be the 'larndir:' disk (see the Configuration section below).
X LARN.SCR, LARN.PID, LARN.LOG, save files, and checkpoint files
X will go on this disk.
X
X
X 5. Configuration
X ----------------
X
X PC LARN is configured by options placed in the file LARN.OPT.
X When PC LARN starts up, it looks in the current directory for
X this file, then in directories along your PATH. Here are the
X options that can be put in LARN.OPT.
X
X Options that are followed with a colon, ":", take at least one
X argument. Options without a colon are boolean, meaning you select
X that option merely by mentioning it.
X
X Comments can be entered in the options file by using the '#'
X character.
X
X These options are only in PC LARN:
X
X cursor: start-line end-line
X Normally, LARN uses the standard DOS cursor (the flashing
X underscore) to show where your player is located. This can be
X difficult to see. This option results in a *BIOS* call to change
X the cursor size. For a monochrome display, the normal value of
X start-line and end-line is 11 and 12. Values of 4 and 9 give a
X larger cursor which is not too obtrusive.
X
X If "cursor" is not specified, no BIOS call is made.
X
X DECRainbow
X Put this in LARN.OPT if your computer is a DEC Rainbow and you
X want to use graphics characters for drawing the maze. You can
X use any characters from the ASCII character set and from the
X "line-drawing" character set. To use line-drawing characters,
X take the decimal value of the character and add 128 to it. This
X makes the values of line-drawing characters lie between decimal
X 128 and 255 and tells PC LARN you want a line-drawing character.
X
X Every attempt has been made with PC LARN V12.3 to maintain
X DECRainbow compatibility as provided by Don Kneller.
X Unfortunately, since I do not have access to a Rainbow, I cannot
X make any guarentees.
X
X graphics: wallc floorc
X In UNIX LARN, the wall character is a # and the floor character
X is a blank (which makes it almost impossible to tell where you've
X been). In PC LARN, the default wall character is also a # but
X the default floor character is a period.
X
X This option allows you to change these characters to something
X you like. Suggested characters are 176 (a graphic block) and
X 249 (a central dot).
X
X Almost all ASCII (non-graphics) characters already represent
X objects in LARN, so you should only choose numbers that are
X in the graphics character set (i.e. those with decimal values
X greater than 128).
X
X keypad
X This enables the keypad for use with LARN. A *BIOS* call is used
X to read the keypad. The correspondance between keypad and game
X command is:
X
X Keypad Command
X 7 8 9 u+l(y) up(k) u+r(u)
X \ | / \ | /
X 4 -5- 6 left(h) nothing right(l)
X / | \ / | \
X 1 2 3 d+l(b) down(j) d+r(n)
X Ins inventory(i)
X
X The letter in () is the game command letter. "u+l" means up and
X left. The keypad "7" is translated to the command for moving one
X space up and left. With shift the commands are the same as the
X uppercase letters.
X
X larndir: directory
X Sets "directory" to be the place LARN looks for files. For hard
X disks set this to be \GAMES\LARN. For 2-floppy systems, use B:
X
X If "larndir" is not specified, the current directory is assumed.
X
X ramlevels: number
X This number is the maximum number of levels PC LARN will keep in
X memory. The number can be between 1 and 14. Normally, PC LARN
X will use as much memory as available, but you may want to use
X less so there will be enough memory to start up a second copy of
X COMMAND.COM with the LARN command `!'. If there isn't enough
X memory for COMMAND.COM, LARN will clear the screen and prompt
X with "A>" until return is struck, then go back to the game.
X
X If "ramlevels" is not specified, a value of 14 is used. If
X "number" is less than 14, LARN will use a swapfile to store the
X oldest levels. Note that a level takes about 8K of memory.
X
X rawio
X This option causes the input and output of your computer to be
X switched to "raw" mode. The advantage of this is faster output
X and better handling of special characters ^S and ^P.
X
X =========== WARNING ==========
X Some computers (eg. DEC Rainbows) hang if rawio is attempted.
X ==============================
X
X swapfile: filename
X This is the name of the swap file that will be used if ramlevels
X is less than 14. If all the levels fit in memory, no swap file
X will be used. You may want to put the swapfile on a RAMdisk.
X If "swapfile" is not specified, LARN.SWP in directory larndir
X will be used.
X
X
X
X The following are options usable with UNIX LARN as well:
X
X auto-pickup
X Starts you out in 'automatic pickup' mode. Whenever the player
X moves onto an object, it will be picked up. This mode can be
X toggled with the '@' command while in the game.
X
X bold-objects
X By specifying this option, all objects in the game will be
X highlighted. The 'highlight-objects' and 'inverse-objects'
X specify which highlighting method will be used.
X
X The default is non-bold objects, except if the 'original-objects'
X option is specified, when it is *forced* on (to distinguish
X monsters and objects that are represented by the same
X character).
X
X enable-checkpointing
X With this option, the game is saved every 400 moves. If your
X system crashes it is possible to recover from the last checkpoint
X file (LARN.CPK in the LARN directory) with the command "larn ++".
X
X highlight-objects
X If the 'bold-objects' option is specified, this option causes
X objects to be highlighted with bolding.
X
X inverse-objects
X If the 'bold-objects' option is specified, this option causes
X objects to be highlighted with inverse video. The default is
X 'highlight-objects'.
X
X monster: name
X Sets the name of a monster. If the name has a space in it,
X enclose it in double quotes (eg "tooth fairy"). The leading
X character determines which monster the name goes with (e.g.
X "monster: bee" and "monster: Buzzbomb" change the names of
X bugbears and Bats, respectively).
X
X name: yourname
X Sets the name of the player. If you want a space in your name,
X enclose it in double quotes (eg "Mad Max").
X
X no-introduction
X Skip displaying the opening messages.
X
X no-beep
X Disable sound from the speaker.
X
X original-objects
X Like 'prompting' mode, this mode is provided for compatibility
X with LARN V12.0. By specifying this option, the characters
X used to show objects in the game are the same as in 12.0. The
X default is to use characters that are closer to those used with
X HACK, ROGUE and MORIA.
X
X prompt-on-objects
X By specifying this option, you enable 'prompting' mode. In this
X mode, the player is prompted for the action to perform when
X encountering an object (e.g. 'Eat, pick up, or ignore?').
X Prompting mode is provided for compatibility with LARN V12.0, and
X is off by default.
X
X savefile: filename
X The filename to use for saving the game. The default is LARN.SAV
X in the LARN directory. For a 2-floppy system you might try
X B:LARN.SAV if the LARN directory is on the A disk drive.
X
X
X 6. Command line options
X -----------------------
X
X There are several command line options that can modify the behavior of
X LARN. These are:
X
X -o optionfile Use this as the option file rather than LARN.OPT. As
X with LARN.OPT, the current directory then directories
X along your path are searched for this file which
X supplies configuration information.
X
X -s Show scores.
X
X -l Show log file. You have to know the Wizard's password
X to do this.
X
X -i Show all scores including the inventories of dead
X players.
X
X -c Create a new score file. You have to know the Wizard's
X password to do this. Erasing LARN.SCR has the same
X effect.
X
X -n No welcoming message. Prevents printing of the short
X introduction to LARN. Putting the "no-introduction"
X configuration option in LARN.OPT has the same effect.
X
X -# Where # is a number from 0 to 9. This sets the
X difficulty of LARN to this level. Normally, LARN
X starts out with difficulty 0 and increases in
X difficulty by 1 when you win at the current level.
X Thus the game automatically gets more difficult.
X
X -h, -? A help screen that shows the command line arguments.
X
X -p Prompt for actions on objects. Specifying the
X 'prompt-on-objects' option in LARN.OPT has the same
X affect.
X
X ++ Restore a game from a checkpoint file. If you have
X checkpointing enabled (with the "enable-checkpointing"
X configuration option in LARN.OPT) then LARN writes a
X checkpoint file every 400 moves. Should your system
X crash you can recover the game from the checkpoint file
X with this command line option
X
X For example: "larn -n -o bobslarn.opt" starts up LARN with no
X introductory message and uses bobslarn.opt file for configuration
X options. "larn ++" tries to restore LARN from a checkpoint file.
X
X
X 7. TERMCAP
X ----------
X
X LARN uses the UNIX "termcap" to select escape sequences to be sent to
X the terminal driver (either ANSI.SYS or NANSI.SYS) to change video modes.
X When LARN starts up, it checks in the environment for the variable called
X "TERM". The DOS command:
X set TERM ibmpc-ega
X will give the environment variable "TERM" the value "ibmpc-ega". By
X default, LARN assumes the value of TERM is "ibmpc-mono".
X
X Then LARN looks in the file called "TERMCAP" for a termininiefinition
X with the same name as the value of TERM. LARN first looks for TERMCAP in
X the current directory, then in directory "\ETC" (the normal UNIX place),
X then in directories along your PATH.
X
X The TERMCAP file uses 2 letter codes to describe each escape sequence
X and \E to mean ESC (the escape character is decimal 27). Each entry is
X enclosed in colons. For example, to start underscore mode on a monochrome
X display, we want to send the sequence "ESC[4m". This looks like
X ":us=\E4m:" as a termcap entry.
X
X The following sequences are used by LARN:
X
X ti terminal initialization. You could have something like:
X :ti=\E44;37m:
X which would mean to select blue background and white foreground.
X
X te terminal end. To reset your terminal to white on black:
X :te=\E0m:
X
X so stand out. Select red forground, keeping the blue background:
X :so=\E31m:
X
X se standout end. Back to white on blue:
X :se=\E44;37m:
X
X al insert line. This is *not* available in ANSI.SYS, so remove this
X entry if you're using ANSI.
X
X dl delete line. This is *not* available in ANSI.SYS, so remove this
X entry if you're using ANSI.
X
X If you want to make your own TERMCAP entry, copy the "ibmpc-mono"
X entry, replace the name (eg use "ibmpc-color" or "ibmpc-ega" or whatever),
X then replace the sequences with whatever you please. The possible escape
X sequences are generally listed in the DOS manual in the description of
X ANSI.SYS, as well as in the NANSI.DOC file.
X
X Remember to change the environment variable "TERM" to reflect which
X TERMCAP entry you want! You should probably put a "set TERM=..." line in
X your AUTOEXEC.BAT file.
X
X
X 8. WIZARD mode
X --------------
X
X There is a WIZARD mode for testing features of the game. To get into
X WIZARD mode, type in an underscore "_" and answer the prompt for the
X password with "pvnert(x)" (do not enter the quotes). Wizards are
X non-scoring characters that get enlightenment, everlasting expanded
X awareness and one of every object in the game.
X
X
X 9. History and Other Information
X --------------------------------
X
X Noah Morgan originally created LARN 12.0 and released the UNIX
X version to the USENET in 1986. Don Kneller ported the UNIX
X version to MSDOS (both IBM PCs and DEC Rainbows).
X
X Kevin Routley has been working on LARN enhancements on and off for
X the past two years. Version 12.1 had a limited distribution.
X Version 12.2 was distributed to the Usenet community. Version 12.3
X may be last version from Kevin that will maintain savefile compatibility
X with version 12.0 savefiles. Some future version will be released
X as Shareware.
X
X Other editions of Larn have been distributed by others, namely
X LARN13 and Ultra-Larn.
X
X I hope you enjoy this version of LARN. Please send any questions,
X suggestions, requests, or comments regarding LARN and LARN V12.3
X in particular to:
X
X Kevin Routley
X 9 Aster Court
X Nashua, NH 03062
X ARPA: rou...@tle.dec.com
X BITNET: rou...@tle.dec.com
X
X March 23, 1991
END_OF_FILE
if test 18665 -ne `wc -c <'larn123.doc'`; then
echo shar: \"'larn123.doc'\" unpacked with wrong size!
fi
# end of 'larn123.doc'
fi
echo shar: End of archive 7 \(of 17\).
cp /dev/null ark7isdone
#!/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 8 (of 17)."
# Contents: moreobj.c movem.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:53 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'moreobj.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'moreobj.c'\"
else
echo shar: Extracting \"'moreobj.c'\" \(18865 characters\)
sed "s/^X//" >'moreobj.c' <<'END_OF_FILE'
X/* moreobj.c
X
X Routines in this file:
X
X oaltar()
X othrone()
X odeadthrone()
X ochest()
X ofountain()
X fntchange()
X fch()
X drink_fountain()
X wash_fountain()
X enter()
X remove_gems()
X sit_on_throne()
X up_stairs()
X down_stairs()
X open_something()
X close_something()
X desecrate_altar()
X pray_at_altar()
X*/
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X void specify_object();
Xstatic void specify_obj_nocurs();
Xstatic void specify_obj_cursor();
Xextern int dropflag ;
Xstatic void move_cursor();
X
X/*
X subroutine to process an altar object
X*/
Xoaltar()
X {
X unsigned long k;
X
X lprcat("\nDo you (p) pray (d) desecrate"); iopts();
X while (1) switch(ttgetch())
X {
X case 'p':
X lprcat(" pray\nDo you (m) give money or (j) just pray? ");
X while (1) switch(ttgetch())
X {
X case 'j':
X lprcat("\n");
X act_just_pray();
X return;
X
X case 'm':
X act_donation_pray();
X return;
X
X case '\33':
X return;
X };
X
X case 'd':
X lprcat(" desecrate");
X act_desecrate_altar();
X return;
X
X case 'i':
X case '\33':
X ignore();
X act_ignore_altar();
X return;
X };
X }
X
X/*
X subroutine to process a throne object
X*/
Xothrone(arg)
X int arg;
X {
X
X lprcat("\nDo you (p) pry off jewels, (s) sit down"); iopts();
X while (1)
X {
X while (1) switch(ttgetch())
X {
X case 'p':
X lprcat(" pry off");
X act_remove_gems( arg );
X return;
X
X case 's':
X lprcat(" sit down");
X act_sit_throne( arg );
X return;
X
X case 'i':
X case '\33': ignore(); return;
X };
X }
X }
X
Xodeadthrone()
X {
X lprcat("\nDo you (s) sit down"); iopts();
X while (1)
X {
X while (1) switch(ttgetch())
X {
X case 's':
X lprcat(" sit down");
X act_sit_throne(1);
X return;
X
X case 'i':
X case '\33': ignore(); return;
X };
X }
X }
X
X/*
X subroutine to process a chest object
X*/
Xochest()
X {
X lprcat("\nDo you (t) take it, (o) try to open it"); iopts();
X while (1)
X {
X switch(ttgetch())
X {
X case 'o':
X lprcat(" open it");
X act_open_chest( playerx, playery );
X return;
X
X case 't':
X lprcat(" take");
X if (take(OCHEST,iarg[playerx][playery])==0)
X item[playerx][playery]=know[playerx][playery]=0;
X return;
X
X case 'i':
X case '\33': ignore(); return;
X };
X }
X }
X
X/*
X process a fountain object
X*/
Xofountain()
X {
X cursors();
X lprcat("\nDo you (d) drink, (w) wash yourself"); iopts();
X while (1) switch(ttgetch())
X {
X case 'd':
X act_drink_fountain();
X return;
X
X case '\33':
X case 'i':
X ignore();
X return;
X
X case 'w':
X act_wash_fountain();
X return;
X }
X }
X
X/*
X a subroutine to raise or lower character levels
X if x > 0 they are raised if x < 0 they are lowered
X*/
Xfntchange(how)
X int how;
X {
X register long j;
X lprc('\n');
X switch(rnd(9))
X {
X case 1:
X lprcat("Your strength");
X fch(how,&c[STRENGTH]); break;
X case 2:
X lprcat("Your intelligence");
X fch(how,&c[INTELLIGENCE]); break;
X case 3:
X lprcat("Your wisdom");
X fch(how,&c[WISDOM]); break;
X case 4:
X lprcat("Your constitution");
X fch(how,&c[CONSTITUTION]); break;
X case 5:
X lprcat("Your dexterity");
X fch(how,&c[DEXTERITY]); break;
X case 6:
X lprcat("Your charm");
X fch(how,&c[CHARISMA]); break;
X case 7:
X j=rnd(level+1);
X if (how < 0)
X {
X lprintf("You lose %d hit point",(long)j);
X if (j>1) lprcat("s!"); else lprc('!');
X losemhp((int)j);
X }
X else
X { lprintf("You gain %d hit point",(long)j); if (j>1) lprcat("s!"); else lprc('!'); raisemhp((int)j); }
X bottomline(); break;
X
X case 8: j=rnd(level+1);
X if (how > 0)
X {
X lprintf("You just gained %d spell",(long)j); raisemspells((int)j);
X if (j>1) lprcat("s!"); else lprc('!');
X }
X else
X {
X lprintf("You just lost %d spell",(long)j); losemspells((int)j);
X if (j>1) lprcat("s!"); else lprc('!');
X }
X bottomline(); break;
X
X case 9: j = 5*rnd((level+1)*(level+1));
X if (how < 0)
X {
X lprintf("You just lost %d experience point",(long)j);
X if (j>1) lprcat("s!"); else lprc('!'); loseexperience((long)j);
X }
X else
X {
X lprintf("You just gained %d experience point",(long)j);
X if (j>1) lprcat("s!"); else lprc('!'); raiseexperience((long)j);
X }
X break;
X }
X cursors();
X }
X
X/*
X subroutine to process an up/down of a character attribute for ofountain
X*/
Xstatic fch(how,x)
X int how;
X long *x;
X {
X if (how < 0) { lprcat(" went down by one!"); --(*x); }
X else { lprcat(" went up by one!"); (*x)++; }
X bottomline();
X }
X
X/*
X For command mode. Perform drinking at a fountain.
X*/
Xdrink_fountain()
X {
X cursors() ;
X if (item[playerx][playery] == ODEADFOUNTAIN)
X lprcat("\nThere is no water to drink!") ;
X
X else if (item[playerx][playery] != OFOUNTAIN)
X lprcat("\nI see no fountain to drink from here!") ;
X
X else
X act_drink_fountain();
X return;
X }
X
X/*
X For command mode. Perform washing (tidying up) at a fountain.
X*/
Xwash_fountain()
X {
X cursors() ;
X if (item[playerx][playery] == ODEADFOUNTAIN)
X lprcat("\nThere is no water to wash in!") ;
X
X else if (item[playerx][playery] != OFOUNTAIN)
X lprcat("\nI see no fountain to wash at here!") ;
X
X else
X act_wash_fountain();
X return;
X }
X
X/*
X For command mode. Perform entering a building.
X*/
Xenter()
X {
X cursors() ;
X switch ( item[playerx][playery] )
X {
X case OSCHOOL:
X oschool();
X break ;
X
X case OBANK:
X obank() ;
X break ;
X
X case OBANK2:
X obank2() ;
X break ;
X
X case ODNDSTORE:
X dndstore() ;
X break ;
X
X case OENTRANCE:
X /* place player in front of entrance on level 1. newcavelevel()
X prevents player from landing on a monster/object.
X */
X playerx = 33 ;
X playery = MAXY - 2 ;
X newcavelevel( 1 );
X know[33][MAXY - 1] = KNOWALL ;
X mitem[33][MAXY - 1] = 0 ;
X draws( 0, MAXX, 0, MAXY );
X showcell(playerx, playery); /* to show around player */
X bot_linex() ;
X break ;
X
X case OTRADEPOST:
X otradepost();
X break;
X
X case OLRS:
X olrs();
X break;
X
X case OHOME:
X ohome();
X break;
X
X default :
X lprcat("\nThere is no place to enter here!\n");
X break;
X }
X }
X
X/*
X For command mode. Perform removal of gems from a jeweled throne.
X*/
Xremove_gems ( )
X {
X cursors();
X if (item[playerx][playery] == ODEADTHRONE)
X lprcat("\nThere are no gems to remove!");
X
X else if (item[playerx][playery] == OTHRONE)
X act_remove_gems(0);
X
X else if (item[playerx][playery] == OTHRONE2)
X act_remove_gems(1);
X
X else
X lprcat("\nI see no throne here to remove gems from!");
X return;
X }
X
X/*
X For command mode. Perform sitting on a throne.
X*/
Xsit_on_throne( )
X {
X cursors();
X if (item[playerx][playery] == OTHRONE)
X act_sit_throne(0);
X
X else if ((item[playerx][playery] == OTHRONE2) ||
X (item[playerx][playery] == ODEADTHRONE))
X act_sit_throne(1);
X
X else
X lprcat("\nI see no throne to sit on here!");
X
X return;
X }
X
X/*
X For command mode. Checks that player is actually standing at a set up
X up stairs or volcanic shaft.
X*/
Xup_stairs()
X {
X cursors();
X if (item[playerx][playery] == OSTAIRSDOWN)
X lprcat("\nThe stairs don't go up!");
X
X else if (item[playerx][playery] == OVOLUP)
X act_up_shaft();
X
X else if (item[playerx][playery] != OSTAIRSUP)
X lprcat("\nI see no way to go up here!");
X
X else
X act_up_stairs();
X }
X
X/*
X For command mode. Checks that player is actually standing at a set of
X down stairs or volcanic shaft.
X*/
Xdown_stairs()
X {
X cursors();
X if (item[playerx][playery] == OSTAIRSUP)
X lprcat("\nThe stairs don't go down!");
X
X else if (item[playerx][playery] == OVOLDOWN)
X act_down_shaft();
X
X else if (item[playerx][playery] != OSTAIRSDOWN)
X lprcat("\nI see no way to go down here!");
X
X else
X act_down_stairs();
X }
X
X/*
X For command mode. Perform opening an object (door, chest).
X*/
Xopen_something( )
X {
X int x,y; /* direction to open */
X char tempc; /* result of prompting to open a chest */
X
X cursors();
X /* check for confusion.
X */
X if (c[CONFUSE])
X {
X lprcat("You're too confused!");
X beep();
X return;
X }
X
X /* check for player standing on a chest. If he is, prompt for and
X let him open it. If player ESCs from prompt, quit the Open
X command.
X */
X if (item[playerx][playery] == OCHEST)
X {
X lprcat("There is a chest here. Open it?");
X if ((tempc = getyn()) == 'y')
X {
X act_open_chest( playerx, playery );
X dropflag = 1; /* prevent player from picking back up if fail */
X return;
X }
X else if (tempc != 'n' )
X return;
X }
X
X /* get direction of object to open. test 'openability' of object
X indicated, call common command/prompt mode routines to actually open.
X */
X dirsub( &x, &y );
X switch( item[x][y] )
X {
X case OOPENDOOR:
X lprcat("The door is already open!");
X beep();
X break;
X
X case OCHEST:
X act_open_chest( x, y );
X break;
X
X case OCLOSEDDOOR:
X act_open_door( x, y );
X break;
X
X default:
X lprcat("You can't open that!");
X beep();
X break;
X }
X }
X
X/*
X For command mode. Perform the action of closing something (door).
X*/
Xclose_something()
X {
X int x,y;
X
X cursors();
X /* check for confusion.
X */
X if (c[CONFUSE])
X {
X lprcat("You're too confused!");
X beep();
X return;
X }
X
X /* get direction of object to close. test 'closeability' of object
X indicated.
X */
X dirsub( &x, &y );
X switch( item[x][y] )
X {
X case OCLOSEDDOOR:
X lprcat("The door is already closed!");
X beep();
X break;
X
X case OOPENDOOR:
X if (mitem[x][y])
X {
X lprcat("Theres a monster in the way!");
X return;
X }
X item[x][y] = OCLOSEDDOOR;
X know[x][y] = 0 ;
X iarg[x][y] = 0 ;
X break;
X
X default:
X lprcat("You can't close that!");
X beep();
X break;
X }
X }
X
X/*
X For command mode. Perform the act of descecrating an altar.
X*/
Xdesecrate_altar()
X {
X cursors();
X if (item[playerx][playery] == OALTAR)
X act_desecrate_altar();
X else
X lprcat("\nI see no altar to desecrate here!");
X }
X
X/*
X For command mode. Perform the act of praying at an altar.
X*/
Xpray_at_altar()
X {
X extern char prayed ;
X
X cursors();
X if (item[playerx][playery] != OALTAR)
X lprcat("\nI see no altar to pray at here!");
X else
X act_donation_pray();
X prayed = 1 ;
X }
X
X/*
X Identify objects for the player.
X*/
Xvoid specify_object()
X {
X cursors();
X lprcat("\n\nIdentify unknown object by cursor [ynq]?");
X while (1)
X {
X switch (ttgetch())
X {
X case '\33':
X case 'q':
X return;
X break;
X case 'y':
X case 'Y':
X specify_obj_cursor();
X return;
X break;
X case 'n':
X case 'N':
X specify_obj_nocurs();
X return;
X break;
X default:
X break;
X }
X }
X }
X
X/* perform the actions of identifying the object/monster associated with a
X character typed by the user. assumes cursors().
X*/
Xstatic void specify_obj_nocurs()
X {
X register int i, j, flag;
X
X lprcat("\nType object character:");
X switch (i=ttgetch())
X {
X case '\33':
X case '\n':
X return;
X case '@':
X lprintf("\n@: %s", logname );
X return;
X case ' ':
X lprintf("\n : An as-yet-unseen place in the dungeon" );
X return;
X default:
X if ( i == floorc )
X {
X lprc('\n');
X lprc(floorc);
X lprintf(": the floor of the dungeon");
X return;
X }
X flag = FALSE;
X for (j=0; j < MAXMONST+8 ; j++)
X if (i==monstnamelist[j])
X {
X lprintf("\n%c: %s", i, monster[j].name);
X flag = TRUE;
X }
X /* check for spurious object character
X */
X if (i != '_')
X for (j=0; j < MAXOBJECT; j++)
X if (i==objnamelist[j])
X {
X lprc('\n');
X if (boldobjects)
X {
X setbold();
X lprc(i);
X resetbold();
X }
X else
X lprc(i);
X lprintf(": %s", objectname[j]);
X flag = TRUE;
X }
X if (!flag)
X lprintf("\n%c: unknown monster/object", i );
X return;
X break;
X }
X }
X
Xstatic void specify_obj_cursor()
X {
X#if __STDC__
X signed char objx, objy;
X#else
X char objx, objy;
X#endif
X int i;
X
X lprcat("\nMove the cursor to an unknown item.");
X lprcat("\n(For instructions type a ?)");
X
X objx = playerx ;
X objy = playery ;
X cursor( objx+1, objy+1 );
X/* make cursor visible.
X*/
X while (1)
X {
X switch(ttgetch())
X {
X case '?':
X cursors();
X lprcat("\nUse [hjklnbyu] to move the cursor to the unknown object.");
X lprcat("\nType a . when the cursor is at the desired place.");
X lprcat("\nType q, Return, or Escape to exit.");
X cursor( objx+1, objy+1);
X break;
X
X case '\33':
X case 'q':
X case '\n':
X/* reset cursor
X*/
X cursor( playerx+1, playery+1);
X return;
X case '.':
X/* reset cursor
X*/
X cursor( playerx+1, playery+1);
X cursors();
X
X if ((objx == playerx) &&
X (objy == playery))
X {
X lprintf("\n@: %s", logname );
X return;
X }
X
X i = mitem[objx][objy];
X if ( i && ( know[objx][objy] & KNOWHERE))
X
X /* check for invisible monsters and not display
X */
X if ( monstnamelist[i] != floorc )
X {
X lprintf("\n%c: %s", monstnamelist[i], monster[i].name);
X return;
X }
X
X /* handle floor separately so as not to display traps, etc.
X */
X i = item[objx][objy];
X if ( i == 0 )
X {
X lprc('\n');
X lprc(floorc);
X lprintf(": the floor of the dungeon");
X return;
X }
X
X if ( know[objx][objy] & HAVESEEN )
X {
X lprc('\n');
X if (boldobjects)
X {
X setbold();
X lprc(objnamelist[i]);
X resetbold();
X }
X else
X lprc(objnamelist[i]);
X lprintf(": %s", objectname[i]);
X return;
X }
X
X lprintf("\n : An as-yet-unseen place in the dungeon" );
X return;
X
X case 'H':
X case 'h':
X move_cursor( &objx, &objy, 4);
X break;
X case 'J':
X case 'j':
X move_cursor( &objx, &objy, 1);
X break;
X case 'K':
X case 'k':
X move_cursor( &objx, &objy, 3);
X break;
X case 'L':
X case 'l':
X move_cursor( &objx, &objy, 2);
X break;
X case 'B':
X case 'b':
X move_cursor( &objx, &objy, 8);
X break;
X case 'N':
X case 'n':
X move_cursor( &objx, &objy, 7);
X break;
X case 'Y':
X case 'y':
X move_cursor( &objx, &objy, 6);
X break;
X case 'U':
X case 'u':
X move_cursor( &objx, &objy, 5);
X break;
X default:
X break;
X }
X }
X }
X
Xstatic void move_cursor( xx, yy, cdir )
X#if __STDC__
Xsigned char *xx ;
Xsigned char *yy ;
X#else
Xchar *xx ;
Xchar *yy ;
X#endif
Xunsigned char cdir ;
X {
X *xx += diroffx[cdir];
X *yy += diroffy[cdir];
X if ( *yy < 0 ) *yy = MAXY-1;
X if ( *yy > MAXY-1 ) *yy = 0;
X if ( *xx < 0 ) *xx = MAXX-1;
X if ( *xx > MAXX-1 ) *xx = 0;
X cursor( *xx+1, *yy+1 );
X }
END_OF_FILE
if test 18865 -ne `wc -c <'moreobj.c'`; then
echo shar: \"'moreobj.c'\" unpacked with wrong size!
fi
# end of 'moreobj.c'
fi
if test -f 'movem.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'movem.c'\"
else
echo shar: Extracting \"'movem.c'\" \(18772 characters\)
sed "s/^X//" >'movem.c' <<'END_OF_FILE'
X/*
X * movem.c (move monster)
X *
X * movemonst() Routine to move the monsters toward the player
X * build_proximity_ripple() Build proximity ripple for smart monster move
X * move_scared() Move scared monsters
X * move_smart() Move smart monsters
X * move_dumb() Move dumb monsters
X * mmove(x,y,xd,yd) Function to actually perform the monster movement
X */
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
X void movemonst();
Xstatic void build_proximity_ripple();
Xstatic void move_scared();
Xstatic void move_smart();
Xstatic void move_dumb();
Xstatic void mmove();
X
X#if 0
X# define IDISTNORM 8 /* was 17 - dgk */
X# define IDISTAGGR 20 /* was 40 - dgk */
X#endif
X# define IDISTNORM 17 /* was 17 - dgk */
X# define IDISTAGGR 40 /* was 40 - dgk */
X
Xstatic short w1x[9],w1y[9];
Xstatic int tmp1,tmp2,tmp3,tmp4,distance;
X
X/* list of monsters to move */
Xstatic struct foo { char x ; char y; char smart; } movelist[250] ;
X
X/*
X * movemonst() Routine to move the monsters toward the player
X *
X * This routine has the responsibility to determine which monsters are to
X * move, and call movemt() to do the move.
X * Returns no value.
X */
Xvoid movemonst()
X {
X register int i,j,movecnt=0, smart_count, min_int ;
X if (c[HOLDMONST]) return; /* no action if monsters are held */
X
X if (c[AGGRAVATE]) /* determine window of monsters to move */
X {
X tmp1=playery-5; tmp2=playery+6; tmp3=playerx-10; tmp4=playerx+11;
X distance=IDISTAGGR; /* depth of intelligent monster movement */
X }
X else
X {
X tmp1=playery-3; tmp2=playery+4; tmp3=playerx-5; tmp4=playerx+6;
X distance=IDISTNORM; /* depth of intelligent monster movement */
X }
X
X if (level == 0) /* if on outside level monsters can move in perimeter */
X {
X if (tmp1 < 0) tmp1=0; if (tmp2 > MAXY) tmp2=MAXY;
X if (tmp3 < 0) tmp3=0; if (tmp4 > MAXX) tmp4=MAXX;
X }
X else /* if in a dungeon monsters can't be on the perimeter (wall there) */
X {
X if (tmp1 < 1) tmp1=1; if (tmp2 > MAXY-1) tmp2=MAXY-1;
X if (tmp3 < 1) tmp3=1; if (tmp4 > MAXX-1) tmp4=MAXX-1;
X }
X
X /* We now have a window in which to move monsters. First find all
X monsters in the window, then decide whether or not to move them.
X Its faster that way since the size of the window is usually larger
X than the # of monsters in that window.
X
X Find all monsters in the window. The only time a monster cannot
X move is if: monsters are not aggrevated, AND player is stealthed,
X AND the monster is asleep due to stealth. Split into two
X separate loops in order to simplify the if statement inside the
X loop for the most common case.
X
X Also count # of smart monsters.
X */
X smart_count = 0 ;
X min_int = 10 - c[HARDGAME] ; /* minimum monster intelligence to move smart */
X if ( c[AGGRAVATE] || !c[STEALTH] )
X {
X for ( j = tmp1 ; j < tmp2 ; j++ )
X for ( i = tmp3 ; i < tmp4 ; i++ )
X if (mitem[i][j])
X {
X movelist[movecnt].x = i;
X movelist[movecnt].y = j ;
X if ( monster[mitem[i][j]].intelligence > min_int )
X {
X movelist[movecnt].smart = TRUE ;
X smart_count++;
X }
X else
X movelist[movecnt].smart = FALSE ;
X movecnt++;
X }
X }
X else
X {
X for ( j = tmp1; j < tmp2 ; j++ )
X for ( i = tmp3 ; i < tmp4 ; i++ )
X if ( mitem[i][j] && stealth[i][j] ) /* stealth[x][y] = 1 when AWAKE! */
X {
X movelist[movecnt].x = i;
X movelist[movecnt].y = j ;
X if ( monster[mitem[i][j]].intelligence > min_int )
X {
X movelist[movecnt].smart = TRUE ;
X smart_count++;
X }
X else
X movelist[movecnt].smart = FALSE ;
X movecnt++;
X }
X }
X
X /* now move the monsters in the movelist. If we have at least one
X smart monster, build a proximity ripple and use it for all smart
X monster movement.
X */
X if (movecnt > 0 )
X {
X if ( c[SCAREMONST] )
X for ( i = 0 ; i < movecnt ; i++ )
X move_scared( movelist[i].x, movelist[i].y );
X else
X {
X if ( smart_count > 0 )
X {
X /* I was going to put in code that prevented the rebuilding
X of the proximity ripple if the player had not moved since
X the last turn. Unfortunately, this permits the player to
X blast down doors to treasure rooms and not have a single
X intelligent monster move.
X */
X build_proximity_ripple();
X for ( i = 0 ; i < movecnt ; i++ )
X if ( movelist[i].smart )
X move_smart( movelist[i].x, movelist[i].y );
X else
X move_dumb( movelist[i].x, movelist[i].y );
X }
X else
X for ( i = 0 ; i < movecnt ; i++ )
X move_dumb( movelist[i].x, movelist[i].y );
X }
X }
X
X /* Also check for the last monster hit. This is necessary to prevent
X the player from getting free hits on a monster with long range
X spells or when stealthed.
X */
X if ( c[AGGRAVATE] || !c[STEALTH] )
X {
X /* If the last monster hit is within the move window, its already
X been moved.
X */
X if ( ( ( lasthx < tmp3 || lasthx >= tmp4 ) ||
X ( lasthy < tmp1 || lasthy >= tmp2 ) ) &&
X mitem[lasthx][lasthy] )
X {
X if ( c[SCAREMONST] )
X move_scared( lasthx, lasthy );
X else
X if ( monster[mitem[lasthx][lasthy]].intelligence > min_int )
X {
X if ( smart_count == 0 )
X build_proximity_ripple( );
X move_smart( lasthx, lasthy );
X }
X else
X move_dumb( lasthx, lasthy );
X lasthx = w1x[0]; /* make sure the monster gets moved again */
X lasthy = w1y[0];
X }
X }
X else
X {
X /* If the last monster hit is within the move window, and not
X asleep due to stealth, then it has already been moved.
X Otherwise (monster outside window, asleep due to stealth),
X move the monster and update the lasthit x,y position.
X */
X if ( ( lasthx < tmp3 || lasthx >= tmp4 ) ||
X ( lasthy < tmp1 || lasthy >= tmp2 ) &&
X mitem[lasthx][lasthy] || !stealth[lasthx][lasthy] )
X {
X if ( c[SCAREMONST] )
X move_scared( lasthx, lasthy );
X else
X if ( monster[mitem[lasthx][lasthy]].intelligence > min_int )
X {
X if ( smart_count == 0 )
X build_proximity_ripple( );
X move_smart( lasthx, lasthy );
X }
X else
X move_dumb( lasthx, lasthy );
X lasthx = w1x[0]; /* make sure the monster gets moved again */
X lasthy = w1y[0];
X }
X }
X }
X
Xstatic char screen[MAXX][MAXY]; /* proximity ripple storage */
X
X/* queue for breadth-first 'search' build of proximity ripple.
X*/
X#define MAX_QUEUE 100
Xstatic struct queue_entry
X {
X char x ;
X char y ;
X char distance ;
X } queue[MAX_QUEUE];
Xstatic int queue_head = 0 ;
Xstatic int queue_tail = 0 ;
X
X/* put a location on the proximity ripple queue
X*/
X#define PUTQUEUE( _x, _y, _d ) \
X { \
X queue[queue_tail].x = (_x) ; \
X queue[queue_tail].y = (_y) ; \
X queue[queue_tail].distance = (_d); \
X queue_tail++; \
X if (queue_tail == MAX_QUEUE) \
X queue_tail = 0 ; \
X }
X
X/* take a location from the proximity ripple queue
X*/
X#define GETQUEUE( _x, _y, _d ) \
X { \
X (_x) = queue[queue_head].x ; \
X (_y) = queue[queue_head].y ; \
X (_d) = queue[queue_head].distance ; \
X queue_head++; \
X if (queue_head == MAX_QUEUE) \
X queue_head = 0 ; \
X }
X
X/* check for the proximity ripple queue being empty
X*/
X#define QUEUEEMPTY() (queue_head == queue_tail)
X
X/*
X For smart monster movement, build a proximity ripple from the player's
X position, out to a 'distance' of 20. For example:
X
X W 5 4 4 W W X Player is at position marked 1
X W 5 W 3 3 W W W is a wall. Monsters will attempt
X W 6 W 2 W 4 W to move to a location with a smaller
X W 7 W 1 W 5 W value than their current position.
X W 8 W W W 6 W Note that a monster at location X
X W 9 9 8 7 7 7 will not move at all.
X W W W 8 W W W
X*/
Xstatic void build_proximity_ripple()
X {
X int xl, yl, xh, yh ;
X int k, m, z, tmpx, tmpy;
X int curx, cury, curdist;
X
X xl=tmp3-2; yl=tmp1-2; xh=tmp4+2; yh=tmp2+2;
X vxy(&xl,&yl); vxy(&xh,&yh);
X for (k=yl; k<=yh; k++)
X for (m=xl; m<=xh; m++)
X {
X switch(item[m][k])
X {
X case OWALL:
X case OPIT:
X case OTRAPARROW:
X case ODARTRAP:
X case OCLOSEDDOOR:
X case OTRAPDOOR:
X case OTELEPORTER:
X screen[m][k]=127;
X break;
X case OENTRANCE:
X if (level==1)
X screen[m][k] = 127;
X else
X screen[m][k] = 0;
X break;
X default:
X screen[m][k] = 0;
X break;
X };
X }
X screen[playerx][playery]=1;
X
X/* now perform proximity ripple from playerx,playery to monster */
X xl=tmp3-1; yl=tmp1-1; xh=tmp4+1; yh=tmp2+1;
X vxy(&xl,&yl); vxy(&xh,&yh);
X
X PUTQUEUE( playerx, playery, 1 );
X do
X {
X GETQUEUE( curx, cury, curdist );
X
X /* test all spots around the current one being looked at.
X */
X if ( ( curx >= xl && curx < xh ) &&
X ( cury >= yl && cury < yh ) )
X {
X for (z=1; z<9; z++)
X {
X tmpx = curx + diroffx[z] ;
X tmpy = cury + diroffy[z] ;
X if (screen[tmpx][tmpy] == 0 )
X {
X screen[tmpx][tmpy] = curdist + 1;
X PUTQUEUE( tmpx, tmpy, curdist + 1 );
X }
X }
X }
X }
X while (!QUEUEEMPTY());
X
X }
X
X/*
X Move scared monsters randomly away from the player position.
X*/
Xstatic void move_scared( i, j )
Xint i, j ;
X {
X int xl, yl, tmp, tmpitem ;
X
X /* check for a half-speed monster, and check if not to move. Could be
X done in the monster list build.
X */
X switch(mitem[i][j])
X {
X case TROGLODYTE: case HOBGOBLIN: case METAMORPH: case XVART:
X case INVISIBLESTALKER: case ICELIZARD: if ((gtime & 1) == 1) return;
X };
X
X if ((xl = i+rnd(3)-2) < 0)
X xl=0;
X if (xl >= MAXX)
X xl=MAXX-1;
X if ((yl = j+rnd(3)-2) < 0)
X yl=0;
X if (yl >= MAXY)
X yl=MAXY-1;
X
X if ((tmp=item[xl][yl]) != OWALL)
X if (mitem[xl][yl] == 0)
X if ((mitem[i][j] != VAMPIRE) || (tmp != OMIRROR))
X if (tmp != OCLOSEDDOOR)
X mmove(i,j,xl,yl);
X }
X
X/*
X Move monsters that are moving intelligently, using the proximity
X ripple. Attempt to move to a position in the proximity ripple
X that is closer to the player.
X
X Parameters: the X,Y position of the monster to be moved.
X*/
Xstatic void move_smart( i, j )
Xint i,j ;
X {
X int x,y,z ;
X
X /* check for a half-speed monster, and check if not to move. Could be
X done in the monster list build.
X */
X switch(mitem[i][j])
X {
X case TROGLODYTE: case HOBGOBLIN: case METAMORPH: case XVART:
X case INVISIBLESTALKER: case ICELIZARD: if ((gtime & 1) == 1) return;
X };
X
X /* find an adjoining location in the proximity ripple that is
X closer to the player (has a lower value) than the monster's
X current position.
X */
X if (mitem[i][j] != VAMPIRE)
X for (z=1; z<9; z++) /* go around in a circle */
X {
X x = i + diroffx[z] ;
X y = j + diroffy[z] ;
X if ( screen[x][y] < screen[i][j] )
X if ( !mitem[x][y] )
X {
X mmove(i,j,w1x[0]=x,w1y[0]=y);
X return;
X }
X }
X else
X /* prevent vampires from moving onto mirrors
X */
X for (z=1; z<9; z++) /* go around in a circle */
X {
X x = i + diroffx[z] ;
X y = j + diroffy[z] ;
X if (( screen[x][y] < screen[i][j] ) &&
X ( item[x][y] != OMIRROR ))
X if ( !mitem[x][y] )
X {
X mmove(i,j,w1x[0]=x,w1y[0]=y);
X return;
X }
X }
X
X }
X
X/*
X For monsters that are not moving in an intelligent fashion. Move
X in a direct fashion toward the player's current position.
X
X Parameters: the X,Y position of the monster to move.
X*/
Xstatic void move_dumb( i, j )
Xint i, j ;
X {
X int xl, yl, xh, yh ;
X int k, m, tmp, tmpd, tmpx, tmpy ;
X
X /* check for a half-speed monster, and check if not to move. Could be
X done in the monster list build.
X */
X switch(mitem[i][j])
X {
X case TROGLODYTE: case HOBGOBLIN: case METAMORPH: case XVART:
X case INVISIBLESTALKER: case ICELIZARD: if ((gtime & 1) == 1) return;
X };
X
X /* dumb monsters move here */
X /* set up range of spots to check. instead of checking all points
X around the monster, only check those closest to the player. For
X example, if the player is up and right of the monster, check only
X the three spots up and right of the monster.
X */
X xl=i-1; yl=j-1; xh=i+2; yh=j+2;
X if (i<playerx) xl++; else if (i>playerx) --xh;
X if (j<playery) yl++; else if (j>playery) --yh;
X
X /* check all spots in the range. find the one that is closest to
X the player. if the monster is already next to the player, exit
X the check immediately.
X */
X tmpd = 10000 ;
X tmpx = i ; tmpy = j ;
X for ( k = xl ; k < xh ; k++ )
X for ( m = yl ; m < yh ; m++ )
X if ( k == playerx && m == playery )
X {
X tmpd = 1 ;
X tmpx = k ;
X tmpy = m ;
X break; /* exitloop */
X }
X else if ((item[k][m] != OWALL) &&
X (item[k][m] != OCLOSEDDOOR) &&
X ((mitem[k][m] == 0 ) || (( k == i ) && ( m == j ))) &&
X ((mitem[i][j] != VAMPIRE) || (item[k][m] != OMIRROR)))
X {
X tmp = (playerx-k)*(playerx-k)+(playery-m)*(playery-m);
X if (tmp < tmpd)
X {
X tmpd = tmp;
X tmpx = k;
X tmpy = m;
X } /* end if */
X } /* end if */
X
X /* we have finished checking the spaces around the monster. if
X any can be moved on and are closer to the player than the
X current location, move the monster.
X */
X if ((tmpd < 10000) && ((tmpx != i) || (tmpy != j)))
X {
X mmove( i, j, tmpx, tmpy );
X w1x[0] = tmpx ; /* for last monster hit */
X w1y[0] = tmpy ;
X }
X else
X {
X w1x[0] = i ; /* for last monster hit */
X w1y[0] = j ;
X }
X } /* end move_dumb() */
X
X/*
X * mmove(x,y,xd,yd) Function to actually perform the monster movement
X * int x,y,xd,yd;
X *
X * Enter with the from coordinates in (x,y) and the destination coordinates
X * in (xd,yd).
X */
Xstatic void mmove(aa,bb,cc,dd)
X int aa,bb,cc,dd;
X {
X register int tmp,i,flag;
X char *who,*p;
X flag=0; /* set to 1 if monster hit by arrow trap */
X if ((cc==playerx) && (dd==playery))
X {
X hitplayer(aa,bb);
X return;
X }
X i=item[cc][dd];
X if ((i==OPIT) || (i==OTRAPDOOR))
X switch(mitem[aa][bb])
X {
X case BAT: case EYE:
X case SPIRITNAGA: case PLATINUMDRAGON: case WRAITH:
X case VAMPIRE: case SILVERDRAGON: case POLTERGEIST:
X case DEMONLORD: case DEMONLORD+1: case DEMONLORD+2:
X case DEMONLORD+3: case DEMONLORD+4: case DEMONLORD+5:
X case DEMONLORD+6: case DEMONPRINCE: break;
X
X default: mitem[aa][bb]=0; /* fell in a pit or trapdoor */
X };
X tmp = mitem[aa][bb];
X mitem[cc][dd] = tmp;
X if (i==OANNIHILATION)
X {
X if (tmp>=DEMONLORD+3) /* demons dispel spheres */
X {
X cursors();
X lprintf("\nThe %s dispels the sphere!",monster[tmp].name);
X rmsphere(cc,dd); /* delete the sphere */
X }
X else mitem[cc][dd]=i=tmp=0;
X }
X stealth[cc][dd]=1;
X if ((hitp[cc][dd] = hitp[aa][bb]) < 0) hitp[cc][dd]=1;
X mitem[aa][bb] = 0;
X if (tmp == LEPRECHAUN)
X switch(i)
X {
X case OGOLDPILE: case OMAXGOLD: case OKGOLD: case ODGOLD:
X case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
X item[cc][dd] = 0; /* leprechaun takes gold */
X };
X
X if (tmp == TROLL) /* if a troll regenerate him */
X if ((gtime & 1) == 0)
X if (monster[tmp].hitpoints > hitp[cc][dd]) hitp[cc][dd]++;
X
X if (i==OTRAPARROW) /* arrow hits monster */
X { who = "An arrow"; if ((hitp[cc][dd] -= rnd(10)+level) <= 0)
X { mitem[cc][dd]=0; flag=2; } else flag=1; }
X if (i==ODARTRAP) /* dart hits monster */
X { who = "A dart"; if ((hitp[cc][dd] -= rnd(6)) <= 0)
X { mitem[cc][dd]=0; flag=2; } else flag=1; }
X if (i==OTELEPORTER) /* monster hits teleport trap */
X { flag=3; fillmonst(mitem[cc][dd]); mitem[cc][dd]=0; }
X if (c[BLINDCOUNT]) return; /* if blind don't show where monsters are */
X if (know[cc][dd] & HAVESEEN)
X {
X p=0;
X if (flag) cursors();
X switch(flag)
X {
X case 1: p="\n%s hits the %s"; break;
X case 2: p="\n%s hits and kills the %s"; break;
X case 3: p="\nThe %s%s gets teleported"; who=""; break;
X };
X if (p) { lprintf(p,who,monster[tmp].name); beep(); }
X }
X/* if (yrepcount>1) { know[aa][bb] &= 2; know[cc][dd] &= 2; return; } */
X if (know[aa][bb] & HAVESEEN) show1cell(aa,bb);
X if (know[cc][dd] & HAVESEEN) show1cell(cc,dd);
X }
END_OF_FILE
if test 18772 -ne `wc -c <'movem.c'`; then
echo shar: \"'movem.c'\" unpacked with wrong size!
fi
# end of 'movem.c'
fi
echo shar: End of archive 8 \(of 17\).
cp /dev/null ark8isdone
#!/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 9 (of 17)."
# Contents: display.c monster.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:53 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'display.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'display.c'\"
else
echo shar: Extracting \"'display.c'\" \(21096 characters\)
sed "s/^X//" >'display.c' <<'END_OF_FILE'
X/* display.c */
X#include "header.h"
X#include "larndefs.h"
X#include "objects.h"
X#include "player.h"
X
X#define botsub( _idx, _x, _y, _str ) \
X if ( c[(_idx)] != cbak[(_idx)] ) \
X { \
X cbak[(_idx)] = c[(_idx)]; \
X cursor( (_x), (_y) ); \
X lprintf( (_str), (long)c[(_idx)] ); \
X }
X
Xstatic int minx,maxx,miny,maxy,k;
Xstatic char bot1f=0,bot2f=0,bot3f=0;
Xstatic char always=0;
X char regen_bottom = 0;
X
X/*
X bottomline()
X
X now for the bottom line of the display
X */
Xbottomline()
X { recalc(); bot1f=1; }
Xbottomhp()
X { bot2f=1; }
Xbottomspell()
X { bot3f=1; }
Xbottomdo()
X {
X if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
X if (bot2f) { bot2f=0; bot_hpx(); }
X if (bot3f) { bot3f=0; bot_spellx(); }
X }
X
Xbot_linex()
X {
X register int i;
X if ( regen_bottom || (always))
X {
X regen_bottom = FALSE ;
X cursor( 1,18);
X if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]);
X else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]);
X lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]);
X if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]);
X else lprintf(" %-2d",(long)c[LEVEL]);
X lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]);
X lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
X (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]);
X lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
X (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]);
X
X if ((level==0) || (wizard)) c[TELEFLAG]=0;
X if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
X lprintf(" Gold: %-6d",(long)c[GOLD]);
X always=1; botside();
X c[TMP] = c[STRENGTH]+c[STREXTRA];
X for (i=0; i<100; i++) cbak[i]=c[i];
X return;
X }
X
X botsub(SPELLS,8,18,"%3d");
X if (c[SPELLMAX]>99)
X {
X botsub(SPELLMAX,12,18,"%3d)");
X }
X else
X botsub(SPELLMAX,12,18,"%2d) ");
X botsub(HP,5,19,"%3d");
X botsub(HPMAX,9,19,"%3d");
X botsub(AC,21,18,"%-3d");
X botsub(WCLASS,30,18,"%-3d");
X botsub(EXPERIENCE,49,18,"%-9d");
X if (c[LEVEL] != cbak[LEVEL])
X {
X cursor(59,18);
X lprcat(class[c[LEVEL]-1]);
X }
X if (c[LEVEL]>99)
X {
X botsub(LEVEL,40,18,"%3d");
X }
X else
X botsub(LEVEL,40,18," %-2d");
X c[TMP] = c[STRENGTH]+c[STREXTRA];
X botsub(TMP,18,19,"%-2d");
X botsub(INTELLIGENCE,25,19,"%-2d");
X botsub(WISDOM,32,19,"%-2d");
X botsub(CONSTITUTION,39,19,"%-2d");
X botsub(DEXTERITY,46,19,"%-2d");
X botsub(CHARISMA,53,19,"%-2d");
X if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG]))
X {
X if ((level==0) || (wizard))
X c[TELEFLAG]=0;
X cbak[TELEFLAG] = c[TELEFLAG];
X cbak[CAVELEVEL] = level;
X cursor(59,19);
X if (c[TELEFLAG])
X lprcat(" ?");
X else
X lprcat(levelname[level]);
X }
X botsub(GOLD,69,19,"%-6d");
X botside();
X }
X
X/*
X special subroutine to update only the gold number on the bottomlines
X called from ogold()
X */
Xbottomgold()
X {
X botsub(GOLD,69,19,"%-6d");
X }
X
X/*
X special routine to update hp and level fields on bottom lines
X called in monster.c hitplayer() and spattack()
X */
Xstatic bot_hpx()
X {
X if (c[EXPERIENCE] != cbak[EXPERIENCE])
X {
X recalc();
X bot_linex();
X }
X else
X botsub(HP,5,19,"%3d");
X }
X
X/*
X special routine to update number of spells called from regen()
X */
Xstatic bot_spellx()
X {
X botsub(SPELLS,9,18,"%2d");
X }
X
X/*
X common subroutine for a more economical bottomline()
X */
Xstatic struct bot_side_def
X {
X int typ;
X char *string;
X }
X bot_data[] =
X {
X STEALTH,"stealth", UNDEADPRO,"undead pro", SPIRITPRO,"spirit pro",
X CHARMCOUNT,"Charm", TIMESTOP,"Time Stop", HOLDMONST,"Hold Monst",
X GIANTSTR,"Giant Str", FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity",
X STRCOUNT,"Strength", SCAREMONST,"Scare", HASTESELF,"Haste Self",
X CANCELLATION,"Cancel", INVISIBILITY,"Invisible", ALTPRO,"Protect 3",
X PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk"
X };
X
Xstatic botside()
X {
X register int i,idx;
X for (i=0; i<17; i++)
X {
X idx = bot_data[i].typ;
X if ((always) || (c[idx] != cbak[idx]))
X {
X if ((always) || (cbak[idx] == 0))
X { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else
X if (c[idx]==0) { cursor(70,i+1); lprcat(" "); }
X cbak[idx]=c[idx];
X }
X }
X always=0;
X }
X
X/*
X * subroutine to draw only a section of the screen
X * only the top section of the screen is updated. If entire lines are being
X * drawn, then they will be cleared first.
X */
Xstatic int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
Xdraws(xmin,xmax,ymin,ymax)
X int xmin,xmax,ymin,ymax;
X {
X register int i,idx;
X if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
X {
X if (ymin==0) cl_up(79,ymax);
X else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
X xmin = -1;
X }
X d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */
X drawscreen();
X if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
X {
X for (i=ymin; i<ymax; i++)
X {
X idx = bot_data[i].typ;
X if (c[idx])
X {
X cursor(70,i+1); lprcat(bot_data[i].string);
X }
X cbak[idx]=c[idx];
X }
X }
X }
X
X#ifdef DECRainbow
X static int DECgraphics; /* The graphics mode toggle */
X
X# define DECgraphicsON() if (!DECgraphics) lprc('\16'), DECgraphics = 1
X# define DECgraphicsOFF() if (DECgraphics) lprc('\17'), DECgraphics = 0
X
X/* For debugging on a non-DEC
X# define DECgraphicsON() if (!DECgraphics) lprcat("\33[4m"), DECgraphics = 1
X# define DECgraphicsOFF() if (DECgraphics) lprcat("\33[0m"), DECgraphics = 0
X*/
X
X# define DEClprc(ch) if (ch & 0x80) {\
X DECgraphicsON();\
X lprc(ch ^ 0x80);\
X } else {\
X DECgraphicsOFF();\
X lprc(ch);\
X }
X#define nlprc(_ch) DEClprc(_ch)
X# else
X#define nlprc(_ch) lprc(_ch)
X#endif DECRainbow
X
X/*
X drawscreen()
X
X subroutine to redraw the whole screen as the player knows it
X */
Xstatic char d_flag;
Xdrawscreen()
X {
X register int i,j,k,ileft,iright;
X
X if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY)
X {
X d_flag=1; clear(); /* clear the screen */
X }
X else
X {
X d_flag=0; cursor(1,1);
X }
X if (d_xmin<0)
X d_xmin=0; /* d_xmin=-1 means display all without bottomline */
X
X /* display lines of the screen
X */
X for ( j = d_ymin ; j < d_ymax ; j++ )
X {
X /* When we show a spot of the dungeon, we have 4 cases:
X squares we know nothing about
X - know == 0
X squares we've been at and still know whats there
X - know == KNOWALL (== KNOWHERE | HAVESEEN)
X squares we've been at, but don't still recall because
X something else happened there.
X - know == HAVESEEN
X squares we recall, but haven't been at (an error condition)
X - know == KNOWHERE
X
X to minimize printing of spaces, scan from left of line until
X we reach a location that the user knows.
X */
X ileft = d_xmin - 1;
X while ( ++ileft < d_xmax )
X if (know[ileft][j]) /* instead of know[i][j] != 0 */
X break; /* exitloop while */
X
X /* if not a blank line ... */
X if ( ileft < d_xmax )
X {
X /* scan from right of line until we reach a location that the
X user knows.
X */
X iright = d_xmax ;
X while ( --iright > ileft )
X if (know[iright][j])
X break ; /* exitloop while */
X
X /* now print the line, after positioning the cursor.
X print the line with bold objects in a different
X loop for effeciency
X */
X cursor( ileft+1, j+1 );
X if (boldobjects)
X for ( i=ileft ; i <= iright ; i++ )
X
X /* we still need to check for the location being known,
X for we might have an unknown spot in the middle of
X an otherwise known line.
X */
X if ( know[i][j] == 0 )
X nlprc( ' ' );
X else if ( know[i][j] & HAVESEEN )
X {
X /* if monster there and the user still knows the place,
X then show the monster. Otherwise, show what was
X there before.
X */
X if (( i == playerx ) &&
X ( j == playery ))
X nlprc('@');
X else if (( k = mitem[i][j] ) &&
X ( know[i][j] & KNOWHERE ))
X nlprc( monstnamelist[k] );
X else if (((k=item[i][j]) == OWALL ) ||
X (objnamelist[k] == floorc))
X nlprc( objnamelist[k] );
X else
X {
X setbold();
X nlprc( objnamelist[k] );
X resetbold();
X }
X }
X else
X /* error condition. recover by resetting location
X to an 'unknown' state.
X */
X {
X nlprc( ' ' );
X mitem[i][j] = item[i][j] = 0 ;
X }
X else /* non-bold objects here */
X for ( i=ileft ; i <= iright ; i++ )
X
X /* we still need to check for the location being known,
X for we might have an unknown spot in the middle of
X an otherwise known line.
X */
X if ( know[i][j] == 0 )
X nlprc( ' ' );
X else if ( know[i][j] & HAVESEEN )
X {
X /* if monster there and the user still knows the place,
X then show the monster. Otherwise, show what was
X there before.
X */
X if (( i == playerx ) &&
X ( j == playery ))
X nlprc('@');
X else if (( k = mitem[i][j] ) &&
X ( know[i][j] & KNOWHERE ))
X nlprc( monstnamelist[k] );
X else
X nlprc( objnamelist[item[i][j]] );
X }
X else
X /* error condition. recover by resetting location
X to an 'unknown' state.
X */
X {
X nlprc( ' ' );
X mitem[i][j] = item[i][j] = 0 ;
X }
X } /* if (ileft < d_xmax ) */
X } /* for (j) */
X
X#ifdef DECRainbow
X if (DECRainbow)
X DECgraphicsOFF();
X#endif DECRainbow
X resetbold();
X if (d_flag) { always=1; botside(); always=1; bot_linex(); }
X/*
X oldx=99;
X*/
X d_xmin = d_ymin = 0; d_xmax = MAXX; d_ymax = MAXY; /* for limited screen drawing */
X }
X
X/*
X showcell(x,y)
X
X subroutine to display a cell location on the screen
X */
Xshowcell(x,y)
X int x,y;
X {
X register int i,j,k,m;
X if (c[BLINDCOUNT]) return; /* see nothing if blind */
X if (c[AWARENESS]) { minx = x-3; maxx = x+3; miny = y-3; maxy = y+3; }
X else { minx = x-1; maxx = x+1; miny = y-1; maxy = y+1; }
X
X if (minx < 0) minx=0; if (maxx > MAXX-1) maxx = MAXX-1;
X if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1;
X
X for (j=miny; j<=maxy; j++)
X for (m=minx; m<=maxx; m++)
X if ((know[m][j] & KNOWHERE) == 0)
X {
X cursor(m+1,j+1);
X x=maxx;
X while (know[x][j] & KNOWHERE)
X --x;
X for (i=m; i<=x; i++)
X {
X if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]);
X else switch(k=item[i][j])
X {
X case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
X case OIVDARTRAP: case OIVTRAPDOOR:
X#ifdef DECRainbow
X if (DECRainbow) {
X DEClprc(objnamelist[k]);
X } else
X#endif DECRainbow
X lprc(objnamelist[k]);
X break;
X default:
X if (boldobjects)
X setbold();
X lprc(objnamelist[k]);
X if (boldobjects)
X resetbold();
X break;
X };
X know[i][j] = KNOWALL;
X }
X m = maxx;
X#ifdef DECRainbow
X if (DECRainbow)
X DECgraphicsOFF();
X#endif DECRainbow
X }
X }
X
X/*
X this routine shows only the spot that is given it. the spaces around
X these coordinated are not shown
X used in godirect() in monster.c for missile weapons display
X */
Xshow1cell(x,y)
X int x,y;
X {
X cursor(x+1,y+1);
X
X /* see nothing if blind, but clear previous player position
X */
X if (c[BLINDCOUNT])
X {
X if ((x == oldx) && (y == oldy))
X lprc(' ');
X return;
X }
X
X if ((k=mitem[x][y]))
X lprc(monstnamelist[k]);
X else switch(k=item[x][y])
X {
X case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
X case OIVDARTRAP: case OIVTRAPDOOR:
X# ifdef DECRainbow
X if (DECRainbow) {
X DEClprc(objnamelist[k]);
X DECgraphicsOFF();
X } else
X# endif
X lprc(objnamelist[k]);
X break;
X
X default:
X if (boldobjects)
X setbold();
X lprc(objnamelist[k]);
X if (boldobjects)
X resetbold();
X break;
X };
X know[x][y] = KNOWALL; /* we end up knowing about it */
X }
X
X/*
X showplayer()
X
X subroutine to show where the player is on the screen
X cursor values start from 1 up
X */
Xshowplayer()
X {
X show1cell( oldx, oldy );
X cursor(playerx+1,playery+1);
X lprc('@');
X cursor(playerx+1,playery+1);
X oldx=playerx; oldy=playery;
X }
X
X/*
X moveplayer(dir)
X
X subroutine to move the player from one room to another
X returns 0 if can't move in that direction or hit a monster or on an object
X else returns 1
X nomove is set to 1 to stop the next move (inadvertent monsters hitting
X players when walking into walls) if player walks off screen or into wall
X */
Xshort diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
Xshort diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
Xmoveplayer(dir)
X int dir; /* from = present room # direction = [1-north]
X [2-east] [3-south] [4-west] [5-northeast]
X [6-northwest] [7-southeast] [8-southwest]
X if direction=0, don't move--just show where he is */
X {
X register int k,m,i,j;
X extern char prayed ;
X
X if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
X k = playerx + diroffx[dir]; m = playery + diroffy[dir];
X if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
X i = item[k][m]; j = mitem[k][m];
X
X /* prevent the player from moving onto a wall, or a closed door when
X in command mode, unless the character has Walk-Through-Walls.
X */
X if ((i==OCLOSEDDOOR && !prompt_mode) || (i==OWALL) && c[WTW]==0)
X {
X nomove=1;
X return(yrepcount = 0);
X }
X if (k==33 && m==MAXY-1 && level==1)
X {
X newcavelevel(0);
X for (k=0; k<MAXX; k++)
X for (m=0; m<MAXY; m++)
X if (item[k][m]==OENTRANCE)
X {
X playerx=k;
X playery=m;
X positionplayer();
X drawscreen();
X return(0);
X }
X }
X /* hit a monster
X */
X if (j>0)
X { hitmonster(k,m); return(yrepcount = 0); }
X
X /* check for the player ignoring an altar when in command mode.
X */
X if ((!prompt_mode) &&
X (item[playerx][playery] == OALTAR) &&
X (!prayed))
X {
X cursors();
X lprcat("\nYou have ignored the altar!");
X act_ignore_altar();
X }
X prayed = 0 ;
X
X lastpx = playerx; lastpy = playery;
X playerx = k; playery = m;
X if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR)
X return(yrepcount = 0);
X else
X return(1);
X }
X
X/*
X * function to show what magic items have been discovered thus far
X * enter with -1 for just spells, anything else will give scrolls & potions
X */
Xstatic int lincount,count;
Xseemagic(arg)
X int arg;
X {
X register int i,j,k,number;
X char sort[SPNUM+1]; /* OK as long as SPNUM > MAXSCROLL,MAXPOTION */
X
X count = lincount = 0;
X nosignal=1;
X
X /* count and sort the known spell codes
X */
X for (j=0; j <= SPNUM ; j++ )
X sort[j] = SPNUM ;
X for (number = i = 0 ; i < SPNUM ; i++ )
X if (spelknow[i])
X {
X number++;
X j = 0 ;
X while ( strncmp( spelcode[ sort[j] ], spelcode[ i ], 3 ) < 0 )
X j++ ;
X k = number - 1;
X while ( k > j )
X sort[k] = sort[ k-1 ], k-- ;
X sort[j] = i ;
X }
X
X if (arg == -1) /* if display spells while casting one */
X {
X cl_up(79, ((number + 2) / 3 + 4 )); /* lines needed for display */
X cursor(1,1);
X }
X else
X {
X resetscroll();
X clear();
X }
X
X lprcat("The magic spells you have discovered thus far:\n\n");
X for (i=0; i<number; i++)
X {
X lprintf("%s %-20s ",spelcode[sort[i]],spelname[sort[i]]);
X seepage();
X }
X
X if (arg== -1)
X {
X seepage();
X more(FALSE);
X nosignal=0;
X draws(0,MAXX,0, (( number + 2 ) / 3 + 4 ));
X return;
X }
X
X lincount += 3;
X if (count!=0)
X {
X count=2;
X seepage();
X }
X
X /* count and sort the known scrolls
X */
X for (j=0; j <= MAXSCROLL ; j++ )
X sort[j] = MAXSCROLL ;
X for (number = i = 0 ; i < MAXSCROLL ; i++ )
X if (scrollname[i][0])
X {
X number++;
X j = 0 ;
X while ( strcmp( &scrollname[sort[j]][1], &scrollname[i][1] ) < 0 )
X j++ ;
X k = number - 1;
X while ( k > j )
X sort[k] = sort[ k-1 ], k-- ;
X sort[j] = i ;
X }
X
X lprcat("\nThe magic scrolls you have found to date are:\n\n");
X count=0;
X for (i=0; i < number; i++ )
X {
X lprintf("%-26s", &scrollname[sort[i]][1]);
X seepage();
X }
X
X lincount += 3;
X if ( count != 0 )
X {
X count=2;
X seepage();
X }
X
X /* count and sort the known potions
X */
X for (j=0; j <= MAXPOTION ; j++ )
X sort[j] = MAXPOTION ;
X for (number = i = 0 ; i < MAXPOTION ; i++ )
X if (potionname[i][0])
X {
X number++;
X j = 0 ;
X while ( strcmp( &potionname[sort[j]][1], &potionname[i][1] ) < 0 )
X j++ ;
X k = number - 1;
X while ( k > j )
X sort[k] = sort[ k-1 ], k-- ;
X sort[j] = i ;
X }
X
X lprcat("\nThe magic potions you have found to date are:\n\n");
X count=0;
X for (i=0; i < number; i++)
X {
X lprintf("%-26s",&potionname[sort[i]][1]);
X seepage();
X }
X
X if (lincount!=0)
X more(FALSE);
X nosignal=0;
X setscroll();
X drawscreen();
X }
X
X/*
X * subroutine to paginate the seemagic function
X */
Xstatic seepage()
X {
X if (++count==3)
X {
X lincount++; count=0; lprc('\n');
X if (lincount>17) { lincount=0; more(FALSE); clear(); }
X }
X }
END_OF_FILE
if test 21096 -ne `wc -c <'display.c'`; then
echo shar: \"'display.c'\" unpacked with wrong size!
fi
# end of 'display.c'
fi
if test -f 'monster.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'monster.c'\"
else
echo shar: Extracting \"'monster.c'\" \(22497 characters\)
sed "s/^X//" >'monster.c' <<'END_OF_FILE'
X/*
X * monster.c
X *
X * createmonster(monstno) Function to create a monster next to the player
X * int monstno;
X *
X * int cgood(x,y,itm,monst) Function to check location for emptiness
X * int x,y,itm,monst;
X *
X * createitem(it,arg) Routine to place an item next to the player
X * int it,arg;
X *
X * vxy(x,y) Routine to verify/fix (*x,*y) for being within bounds
X * int *x,*y;
X *
X * hitmonster(x,y) Function to hit a monster at the designated coordinates
X * int x,y;
X *
X * hitm(x,y,amt) Function to just hit a monster at a given coordinates
X * int x,y,amt;
X *
X * hitplayer(x,y) Function for the monster to hit the player from (x,y)
X * int x,y;
X *
X * dropsomething(monst) Function to create an object when a monster dies
X * int monst;
X *
X * dropgold(amount) Function to drop some gold around player
X * int amount;
X *
X * something(level) Function to create a random item around player
X * int level;
X *
X * newobject(lev,i) Routine to return a randomly selected new object
X * int lev,*i;
X *
X * spattack(atckno,xx,yy) Function to process special attacks from monsters
X * int atckno,xx,yy;
X *
X * checkloss(x) Routine to subtract hp from user and flag bottomline display
X * int x;
X *
X */
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X#include <ctype.h>
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
Xextern fullhit(), ifblind();
X
X/*
X * createmonster(monstno) Function to create a monster next to the player
X * int monstno;
X *
X * Enter with the monster number (1 to MAXMONST+8)
X * Returns no value.
X */
Xcreatemonster(mon)
X int mon;
X {
X register int x,y,k,i;
X if (mon<1 || mon>MAXMONST+8) /* check for monster number out of bounds */
X {
X beep(); lprintf("\ncan't createmonst(%d)\n",(long)mon); nap(3000); return;
X }
X while (monster[mon].genocided && mon<MAXMONST) mon++; /* genocided? */
X for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
X {
X if (k>8) k=1; /* wraparound the diroff arrays */
X x = playerx + diroffx[k]; y = playery + diroffy[k];
X if (cgood(x,y,0,1)) /* if we can create here */
X {
X mitem[x][y] = mon;
X hitp[x][y] = monster[mon].hitpoints;
X stealth[x][y]=0;
X know[x][y] &= ~KNOWHERE;
X switch(mon)
X {
X case ROTHE: case POLTERGEIST: case VAMPIRE: stealth[x][y]=1;
X };
X return;
X }
X }
X }
X
X/*
X * int cgood(x,y,itm,monst) Function to check location for emptiness
X * int x,y,itm,monst;
X *
X * Routine to return TRUE if a location does not have itm or monst there
X * returns FALSE (0) otherwise
X * Enter with itm or monst TRUE or FALSE if checking it
X * Example: if itm==TRUE check for no item at this location
X * if monst==TRUE check for no monster at this location
X * This routine will return FALSE if at a wall,door or the dungeon exit
X * on level 1
X */
Xstatic int cgood(x,y,itm,monst)
X register int x,y;
X int itm,monst;
X {
X /* cannot create either monster or item if:
X - out of bounds
X - wall
X - closed door
X - dungeon entrance
X */
X if (((y < 0) || (y > MAXY-1) || (x < 0) || (x > MAXX-1)) ||
X (item[x][y] == OWALL) ||
X (item[x][y] == OCLOSEDDOOR) ||
X ((level == 1) && (x == 33) && (y == MAXY-1)))
X return( FALSE );
X
X /* if checking for an item, return False if one there already
X */
X if ( itm && item[x][y])
X return( FALSE );
X
X /* if checking for a monster, return False if one there already _or_
X there is a pit/trap there.
X */
X if (monst)
X {
X if (mitem[x][y])
X return (FALSE);
X switch(item[x][y])
X {
X /* note: not invisible traps, since monsters are not affected
X by them.
X */
X case OPIT: case OANNIHILATION:
X case OTELEPORTER: case OTRAPARROW:
X case ODARTRAP: case OTRAPDOOR:
X return(FALSE);
X break;
X default:
X break;
X }
X }
X return(TRUE);
X }
X
X/*
X * createitem(it,arg) Routine to place an item next to the player
X * int it,arg;
X *
X * Enter with the item number and its argument (iven[], ivenarg[])
X * Returns no value, thus we don't know about createitem() failures.
X */
Xcreateitem(it,arg)
X int it,arg;
X {
X register int x,y,k,i;
X if (it >= MAXOBJ) return; /* no such object */
X for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
X {
X if (k>8) k=1; /* wraparound the diroff arrays */
X x = playerx + diroffx[k]; y = playery + diroffy[k];
X if (cgood(x,y,1,0)) /* if we can create here */
X {
X item[x][y] = it; know[x][y]=0; iarg[x][y]=arg; return;
X }
X }
X }
X
X
X/*
X * vxy(x,y) Routine to verify/fix coordinates for being within bounds
X * int *x,*y;
X *
X * Function to verify x & y are within the bounds for a level
X * If *x or *y is not within the absolute bounds for a level, fix them so that
X * they are on the level.
X * Returns TRUE if it was out of bounds, and the *x & *y in the calling
X * routine are affected.
X */
Xvxy(x,y)
X int *x,*y;
X {
X int flag=0;
X if (*x<0) { *x=0; flag++; }
X if (*y<0) { *y=0; flag++; }
X if (*x>=MAXX) { *x=MAXX-1; flag++; }
X if (*y>=MAXY) { *y=MAXY-1; flag++; }
X return(flag);
X }
X
X/*
X * hitmonster(x,y) Function to hit a monster at the designated coordinates
X * int x,y;
X *
X * This routine is used for a bash & slash type attack on a monster
X * Enter with the coordinates of the monster in (x,y).
X * Returns no value.
X */
Xhitmonster(x,y)
X int x,y;
X {
X extern char lastmonst[] ;
X register int tmp,monst,damag,flag;
X if (c[TIMESTOP]) return; /* not if time stopped */
X vxy(&x,&y); /* verify coordinates are within range */
X if ((monst = mitem[x][y]) == 0) return;
X hit3flag=1; ifblind(x,y);
X tmp = monster[monst].armorclass + c[LEVEL] + c[DEXTERITY] + c[WCLASS]/4 - 12;
X cursors();
X if ((rnd(20) < tmp-c[HARDGAME]) || (rnd(71) < 5)) /* need at least random chance to hit */
X {
X lprcat("\nYou hit"); flag=1;
X damag = fullhit(1);
X if (damag<9999) damag=rnd(damag)+1;
X }
X else
X {
X lprcat("\nYou missed"); flag=0;
X }
X lprcat(" the "); lprcat(lastmonst);
X if (flag) /* if the monster was hit */
X if ((monst==RUSTMONSTER) || (monst==DISENCHANTRESS) || (monst==CUBE))
X if (c[WIELD]>=0)
X if (ivenarg[c[WIELD]] > -10)
X {
X lprintf("\nYour weapon is dulled by the %s",lastmonst); beep();
X --ivenarg[c[WIELD]];
X
X /* fix for dulled rings of strength,cleverness, and dexterity
X bug.
X */
X switch (iven[c[WIELD]])
X {
X case ODEXRING :
X c[DEXTERITY]--;
X break;
X case OSTRRING :
X c[STREXTRA]--;
X break;
X case OCLEVERRING :
X c[INTELLIGENCE]--;
X break;
X }
X }
X if (flag) hitm(x,y,damag);
X if (monst == VAMPIRE) if (hitp[x][y]<25) { mitem[x][y]=BAT; know[x][y]=0; }
X }
X
X/*
X * hitm(x,y,amt) Function to just hit a monster at a given coordinates
X * int x,y,amt;
X *
X * Returns the number of hitpoints the monster absorbed
X * This routine is used to specifically damage a monster at a location (x,y)
X * Called by hitmonster(x,y)
X */
Xhitm(x,y,amt)
X int x,y;
X register amt;
X {
X extern char lastmonst[] ;
X register int monst;
X int hpoints,amt2;
X vxy(&x,&y); /* verify coordinates are within range */
X amt2 = amt; /* save initial damage so we can return it */
X monst = mitem[x][y];
X if (c[HALFDAM]) amt >>= 1; /* if half damage curse adjust damage points */
X if (amt<=0) amt2 = amt = 1;
X lasthx=x; lasthy=y;
X stealth[x][y]=1; /* make sure hitting monst breaks stealth condition */
X c[HOLDMONST]=0; /* hit a monster breaks hold monster spell */
X switch(monst) /* if a dragon and orb(s) of dragon slaying */
X {
X case WHITEDRAGON: case REDDRAGON: case GREENDRAGON:
X case BRONZEDRAGON: case PLATINUMDRAGON: case SILVERDRAGON:
X amt *= 1+(c[SLAYING]<<1); break;
X }
X/* invincible monster fix is here */
X if (hitp[x][y] > monster[monst].hitpoints)
X hitp[x][y] = monster[monst].hitpoints;
X if ((hpoints = hitp[x][y]) <= amt)
X {
X#ifdef EXTRA
X c[MONSTKILLED]++;
X#endif
X lprintf("\nThe %s died!",lastmonst);
X raiseexperience((long)monster[monst].experience);
X amt = monster[monst].gold; if (amt>0) dropgold(rnd(amt)+amt);
X dropsomething(monst); disappear(x,y); bottomline();
X return(hpoints);
X }
X hitp[x][y] = hpoints-amt; return(amt2);
X }
X
X/*
X * hitplayer(x,y) Function for the monster to hit the player from (x,y)
X * int x,y;
X *
X * Function for the monster to hit the player with monster at location x,y
X * Returns nothing of value.
X */
Xhitplayer(x,y)
X int x,y;
X {
X extern char lastmonst[] ;
X register int dam,tmp,mster,bias;
X vxy(&x,&y); /* verify coordinates are within range */
X lastnum = mster = mitem[x][y];
X/* spirit naga's and poltergeist's do nothing if scarab of negate spirit */
X if (c[NEGATESPIRIT] || c[SPIRITPRO]) if ((mster ==POLTERGEIST) || (mster ==SPIRITNAGA)) return;
X/* if undead and cube of undead control */
X if (c[CUBEofUNDEAD] || c[UNDEADPRO]) if ((mster ==VAMPIRE) || (mster ==WRAITH) || (mster ==ZOMBIE)) return;
X if ((know[x][y] & KNOWHERE) == 0)
X show1cell(x,y);
X bias = (c[HARDGAME]) + 1;
X hitflag = hit2flag = hit3flag = 1;
X yrepcount=0;
X cursors(); ifblind(x,y);
X if (c[INVISIBILITY]) if (rnd(33)<20)
X {
X lprintf("\nThe %s misses wildly",lastmonst); return;
X }
X if (c[CHARMCOUNT]) if (rnd(30)+5*monster[mster].level-c[CHARISMA]<30)
X {
X lprintf("\nThe %s is awestruck at your magnificence!",lastmonst);
X return;
X }
X if (mster==BAT) dam=1;
X else
X {
X dam = monster[mster].damage;
X dam += rnd((int)((dam<1)?1:dam)) + monster[mster].level;
X }
X tmp = 0;
X if (monster[mster].attack>0)
X if (((dam + bias + 8) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
X { if (spattack(monster[mster].attack,x,y)) { lflushall(); return; }
X tmp = 1; bias -= 2; cursors(); }
X if (((dam + bias) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
X {
X lprintf("\n The %s hit you ",lastmonst); tmp = 1;
X if ((dam -= c[AC]) < 0) dam=0;
X if (dam > 0) { losehp(dam); bottomhp(); lflushall(); }
X }
X if (tmp == 0) lprintf("\n The %s missed ",lastmonst);
X }
X
X/*
X * dropsomething(monst) Function to create an object when a monster dies
X * int monst;
X *
X * Function to create an object near the player when certain monsters are killed
X * Enter with the monster number
X * Returns nothing of value.
X */
Xstatic dropsomething(monst)
X int monst;
X {
X switch(monst)
X {
X case ORC: case NYMPH: case ELF: case TROGLODYTE:
X case TROLL: case ROTHE: case VIOLETFUNGI:
X case PLATINUMDRAGON: case GNOMEKING: case REDDRAGON:
X something(level); return;
X
X case LEPRECHAUN: if (rnd(101)>=75) creategem();
X if (rnd(5)==1) dropsomething(LEPRECHAUN); return;
X }
X }
X
X/*
X * dropgold(amount) Function to drop some gold around player
X * int amount;
X *
X * Enter with the number of gold pieces to drop
X * Returns nothing of value.
X */
Xdropgold(amount)
X register int amount;
X {
X if (amount > 250)
X createitem(OMAXGOLD,amount/100);
X else
X createitem(OGOLDPILE,amount);
X }
X
X/*
X * something(level) Function to create a random item around player
X * int level;
X *
X * Function to create an item from a designed probability around player
X * Enter with the cave level on which something is to be dropped
X * Returns nothing of value.
X */
Xsomething(level)
X int level;
X {
X register int j;
X int i;
X if (level<0 || level>MAXLEVEL+MAXVLEVEL) return; /* correct level? */
X if (rnd(101)<8)
X something(level); /* possibly more than one item */
X j = newobject(level,&i);
X createitem(j,i);
X }
X
X/*
X * newobject(lev,i) Routine to return a randomly selected new object
X * int lev,*i;
X *
X * Routine to return a randomly selected object to be created
X * Returns the object number created, and sets *i for its argument
X * Enter with the cave level and a pointer to the items arg
X */
Xstatic char nobjtab[] = { 0, OSCROLL, OSCROLL, OSCROLL, OSCROLL, OPOTION,
X OPOTION, OPOTION, OPOTION, OGOLDPILE, OGOLDPILE, OGOLDPILE, OGOLDPILE,
X OBOOK, OBOOK, OBOOK, OBOOK, ODAGGER, ODAGGER, ODAGGER, OLEATHER, OLEATHER,
X OLEATHER, OREGENRING, OPROTRING, OENERGYRING, ODEXRING, OSTRRING, OSPEAR,
X OBELT, ORING, OSTUDLEATHER, OSHIELD, OCOOKIE, OFLAIL, OCHAIN, OBATTLEAXE,
X OSPLINT, O2SWORD, OCLEVERRING, OPLATE, OLONGSWORD };
X
Xnewobject(lev,i)
X register int lev,*i;
X {
X register int tmp=33,j;
X if (level<0 || level>MAXLEVEL+MAXVLEVEL) return(0); /* correct level? */
X if (lev>6) tmp=41; else if (lev>4) tmp=39;
X j = nobjtab[tmp=rnd(tmp)]; /* the object type */
X switch(tmp)
X {
X case 1: case 2: case 3: case 4: /* scroll */
X *i=newscroll(); break;
X case 5: case 6: case 7: case 8: /* potion */
X *i=newpotion(); break;
X case 9: case 10: case 11: case 12: /* gold */
X *i=rnd((lev+1)*10)+lev*10+10; break;
X case 13: case 14: case 15: case 16: /* book */
X *i=lev; break;
X case 17: case 18: case 19: /* dagger */
X if (!(*i=newdagger())) return(0); break;
X case 20: case 21: case 22: /* leather armor */
X if (!(*i=newleather())) return(0); break;
X case 23: case 32: case 38: /* regen ring, shield, 2-hand sword */
X *i=rund(lev/3+1); break;
X case 24: case 26: /* prot ring, dexterity ring */
X *i=rnd(lev/4+1); break;
X case 25: /* energy ring */
X *i=rund(lev/4+1); break;
X case 27: case 39: /* strength ring, cleverness ring */
X *i=rnd(lev/2+1); break;
X case 30: case 34: /* ring mail, flail */
X *i=rund(lev/2+1); break;
X case 28: case 36: /* spear, battleaxe */
X *i=rund(lev/3+1); if (*i==0) return(0); break;
X case 29: case 31: case 37: /* belt, studded leather, splint */
X *i=rund(lev/2+1); if (*i==0) return(0); break;
X case 33: /* fortune cookie */
X *i=0; break;
X case 35: /* chain mail */
X *i=newchain(); break;
X case 40: /* plate mail */
X *i=newplate(); break;
X case 41: /* longsword */
X *i=newsword(); break;
X }
X return(j);
X }
X
X/*
X * spattack(atckno,xx,yy) Function to process special attacks from monsters
X * int atckno,xx,yy;
X *
X * Enter with the special attack number, and the coordinates (xx,yy)
X * of the monster that is special attacking
X * Returns 1 if must do a show1cell(xx,yy) upon return, 0 otherwise
X *
X * atckno monster effect
X * ---------------------------------------------------
X * 0 none
X * 1 rust monster eat armor
X * 2 hell hound breathe light fire
X * 3 dragon breathe fire
X * 4 giant centipede weakening sing
X * 5 white dragon cold breath
X * 6 wraith drain level
X * 7 waterlord water gusher
X * 8 leprechaun steal gold
X * 9 disenchantress disenchant weapon or armor
X * 10 ice lizard hits with barbed tail
X * 11 umber hulk confusion
X * 12 spirit naga cast spells taken from special attacks
X * 13 platinum dragon psionics
X * 14 nymph steal objects
X * 15 bugbear bite
X * 16 osequip bite
X *
X * char rustarm[ARMORTYPES][2];
X * special array for maximum rust damage to armor from rustmonster
X * format is: { armor type , minimum attribute
X */
X#define ARMORTYPES 6
X#if __STDC__
Xstatic signed char rustarm[ARMORTYPES][2] =
X#else
Xstatic char rustarm[ARMORTYPES][2] =
X#endif
X { OSTUDLEATHER,-2, ORING, -4,
X OCHAIN, -5, OSPLINT, -6,
X OPLATE, -8, OPLATEARMOR,-9 };
Xstatic char spsel[] = { 1, 2, 3, 5, 6, 8, 9, 11, 13, 14 };
Xstatic spattack(x,xx,yy)
X int x,xx,yy;
X {
X extern char lastmonst[] ;
X register int i,j=0,k,m;
X register char *p=0;
X if (c[CANCELLATION]) return(0);
X vxy(&xx,&yy); /* verify x & y coordinates */
X switch(x)
X {
X case 1: /* rust your armor, j=1 when rusting has occurred */
X m = k = c[WEAR];
X if ((i=c[SHIELD]) != -1)
X if (--ivenarg[i] < -1) ivenarg[i]= -1; else j=1;
X if ((j==0) && (k != -1))
X {
X m = iven[k];
X for (i=0; i<ARMORTYPES; i++)
X if (m == rustarm[i][0]) /* find his armor in table */
X {
X if (--ivenarg[k]< rustarm[i][1])
X ivenarg[k]= rustarm[i][1]; else j=1;
X break;
X }
X }
X if (j==0) /* if rusting did not occur */
X switch(m)
X {
X case OLEATHER: p = "\nThe %s hit you -- Your lucky you have leather on";
X break;
X case OSSPLATE: p = "\nThe %s hit you -- Your fortunate to have stainless steel armor!";
X break;
X }
X else { beep(); p = "\nThe %s hit you -- your armor feels weaker"; }
X break;
X
X case 2: i = rnd(15)+8-c[AC];
X spout: p="\nThe %s breathes fire at you!";
X if (c[FIRERESISTANCE])
X p="\nThe %s's flame doesn't phase you!";
X else
X spout2: if (p) { lprintf(p,lastmonst); beep(); }
X checkloss(i);
X return(0);
X
X case 3: i = rnd(20)+25-c[AC]; goto spout;
X
X case 4: if (c[STRENGTH]>3)
X {
X p="\nThe %s stung you! You feel weaker"; beep();
X --c[STRENGTH];
X }
X else p="\nThe %s stung you!";
X break;
X
X case 5: p="\nThe %s blasts you with his cold breath";
X i = rnd(15)+18-c[AC]; goto spout2;
X
X case 6: lprintf("\nThe %s drains you of your life energy!",lastmonst);
X loselevel(); beep(); return(0);
X
X case 7: p="\nThe %s got you with a gusher!";
X i = rnd(15)+25-c[AC]; goto spout2;
X
X case 8: if (c[NOTHEFT]) return(0); /* he has a device of no theft */
X if (c[GOLD])
X {
X p="\nThe %s hit you -- Your purse feels lighter";
X if (c[GOLD]>32767) c[GOLD]>>=1;
X else c[GOLD] -= rnd((int)(1+(c[GOLD]>>1)));
X if (c[GOLD] < 0) c[GOLD]=0;
X }
X else p="\nThe %s couldn't find any gold to steal";
X lprintf(p,lastmonst); disappear(xx,yy); beep();
X bottomgold(); return(1);
X
X case 9: for(j=50; ; ) /* disenchant */
X {
X i=rund(26); m=iven[i]; /* randomly select item */
X if (m>0 && ivenarg[i]>0 && m!=OSCROLL && m!=OPOTION)
X {
X if ((ivenarg[i] -= 3)<0) ivenarg[i]=0;
X lprintf("\nThe %s hits you -- you feel a sense of loss",lastmonst);
X beep(); show3(i); bottomline(); return(0);
X }
X if (--j<=0)
X {
X p="\nThe %s nearly misses"; break;
X }
X break;
X }
X break;
X
X case 10: p="\nThe %s hit you with his barbed tail";
X i = rnd(25)-c[AC]; goto spout2;
X
X case 11: p="\nThe %s has confused you"; beep();
X c[CONFUSE]+= 10+rnd(10); break;
X
X case 12: /* performs any number of other special attacks */
X return(spattack(spsel[rund(10)],xx,yy));
X
X case 13: p="\nThe %s flattens you with his psionics!";
X i = rnd(15)+30-c[AC]; goto spout2;
X
X case 14: if (c[NOTHEFT]) return(0); /* he has device of no theft */
X if (emptyhanded()==1)
X {
X p="\nThe %s couldn't find anything to steal";
X break;
X }
X lprintf("\nThe %s picks your pocket and takes:",lastmonst);
X beep();
X if (stealsomething()==0) lprcat(" nothing"); disappear(xx,yy);
X bottomline(); return(1);
X
X case 15: i= rnd(10)+ 5-c[AC];
X spout3: p="\nThe %s bit you!";
X goto spout2;
X
X case 16: i= rnd(15)+10-c[AC]; goto spout3;
X };
X if (p) { lprintf(p,lastmonst); bottomline(); }
X return(0);
X }
X
X/*
X * checkloss(x) Routine to subtract hp from user and flag bottomline display
X * int x;
X *
X * Routine to subtract hitpoints from the user and flag the bottomline display
X * Enter with the number of hit points to lose
X * Note: if x > c[HP] this routine could kill the player!
X */
Xcheckloss(x)
X int x;
X {
X if (x>0) { losehp(x); bottomhp(); }
X }
END_OF_FILE
if test 22497 -ne `wc -c <'monster.c'`; then
echo shar: \"'monster.c'\" unpacked with wrong size!
fi
# end of 'monster.c'
fi
echo shar: End of archive 9 \(of 17\).
cp /dev/null ark9isdone
#!/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 10 (of 17)."
# Contents: scores.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:54 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'scores.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'scores.c'\"
else
echo shar: Extracting \"'scores.c'\" \(26174 characters\)
sed "s/^X//" >'scores.c' <<'END_OF_FILE'
X/* scores.c
X *
X * readboard() Function to read in the scoreboard into a static buffer
X * writeboard() Function to write the scoreboard from readboard()'s buffer
X * makeboard() Function to create a new scoreboard (wipe out old one)
X * hashewon() Function to return 1 if player has won a game before, else 0
X * long paytaxes(x) Function to pay taxes if any are due
X * winshou() Subroutine to print out the winning scoreboard
X * shou(x) Subroutine to print out the non-winners scoreboard
X * showscores() Function to show the scoreboard on the terminal
X * showallscores() Function to show scores and the iven lists that go with them
X * sortboard() Function to sort the scoreboard
X * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard
X * new1sub(score,i,whoo,taxes) Subroutine to put player into a
X * new2sub(score,i,whoo,whyded) Subroutine to put player into a
X * died(x) Subroutine to record who played larn, and what the score was
X * diedsub(x) Subroutine to print out a line showing player when he is killed
X * diedlog() Subroutine to read a log file and print it out in ascii format
X * getplid(name) Function to get players id # from id file
X */
X#ifdef VMS
X# include <types.h>
X# include <stat.h>
X#else
X# include <sys/types.h>
X# ifndef MSDOS
X# ifndef AMIGA
X# include <sys/times.h>
X# endif AMIGA
X# endif MSDOS
X# include <sys/stat.h>
X#endif
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
Xstruct scofmt /* This is the structure for the scoreboard */
X {
X long score; /* the score of the player */
X long suid; /* the user id number of the player */
X short what; /* the number of the monster that killed player */
X short level; /* the level player was on when he died */
X short hardlev; /* the level of difficulty player played at */
X short order; /* the relative ordering place of this entry */
X char who[40]; /* the name of the character */
X char sciv[26][2]; /* this is the inventory list of the character */
X };
Xstruct wscofmt /* This is the structure for the winning scoreboard */
X {
X long score; /* the score of the player */
X long timeused; /* the time used in mobuls to win the game */
X long taxes; /* taxes he owes to LRS */
X long suid; /* the user id number of the player */
X short hardlev; /* the level of difficulty player played at */
X short order; /* the relative ordering place of this entry */
X# ifndef MAIL /* dgk */
X char hasmail; /* 1 if mail is to be read, 0 otherwise */
X# endif
X char who[40]; /* the name of the character */
X };
X
Xstruct log_fmt /* 102 bytes struct for the log file */
X {
X long score; /* the players score */
X long diedtime; /* time when game was over */
X short cavelev; /* level in caves */
X short diff; /* difficulty player played at */
X#ifdef EXTRA
X long elapsedtime; /* real time of game in seconds */
X long bytout; /* bytes input and output */
X long bytin;
X long moves; /* number of moves made by player */
X short ac; /* armor class of player */
X short hp,hpmax; /* players hitpoints */
X short cputime; /* cpu time needed in seconds */
X short killed,spused;/* monsters killed and spells cast */
X short usage; /* usage of the cpu in % */
X short lev; /* player level */
X#endif
X char who[12]; /* player name */
X char what[46]; /* what happened to player */
X };
X
Xstatic struct scofmt sco[SCORESIZE]; /* the structure for the scoreboard */
Xstatic struct wscofmt winr[SCORESIZE]; /* struct for the winning scoreboard */
Xstatic struct log_fmt logg; /* structure for the log file */
Xstatic char *whydead[] = {
X "quit", "suspended", "self - annihilated", "shot by an arrow",
X "hit by a dart", "fell into a pit", "fell into a bottomless pit",
X "a winner", "trapped in solid rock", "killed by a missing save file",
X "killed by an old save file", "caught by the greedy cheater checker trap",
X "killed by a protected save file","killed his family and committed suicide",
X "erased by a wayward finger", "fell through a bottomless trap door",
X "fell through a trap door", "drank some poisonous water",
X "fried by an electric shock", "slipped on a volcano shaft",
X "killed by a stupid act of frustration", "attacked by a revolting demon",
X "hit by his own magic", "demolished by an unseen attacker",
X "fell into the dreadful sleep", "killed by an exploding chest",
X/*26*/ "killed by a missing maze data file", "annihilated in a sphere",
X "died a post mortem death","wasted by a malloc() failure"
X };
X
X
X/*
X * readboard() Function to read in the scoreboard into a static buffer
X *
X * returns -1 if unable to read in the scoreboard, returns 0 if all is OK
X */
Xstatic readboard()
X {
X if (lopen(scorefile)<0)
X { lprcat("Can't read scoreboard\n"); lflush(); return(-1); }
X lrfill((char*)sco,sizeof(sco)); lrfill((char*)winr,sizeof(winr));
X lrclose(); lcreat((char*)0); return(0);
X }
X
X/*
X * writeboard() Function to write the scoreboard from readboard()'s buffer
X *
X * returns -1 if unable to write the scoreboard, returns 0 if all is OK
X */
Xstatic writeboard()
X {
X set_score_output();
X if (lcreat(scorefile)<0)
X { lprcat("Can't write scoreboard\n"); lflush(); return(-1); }
X lwrite((char*)sco,sizeof(sco)); lwrite((char*)winr,sizeof(winr));
X lwclose(); lcreat((char*)0); return(0);
X }
X
X/*
X * makeboard() Function to create a new scoreboard (wipe out old one)
X *
X * returns -1 if unable to write the scoreboard, returns 0 if all is OK
X */
Xmakeboard()
X {
X register int i;
X for (i=0; i<SCORESIZE; i++)
X {
X winr[i].taxes = winr[i].score = sco[i].score = 0;
X winr[i].order = sco[i].order = i;
X }
X if (writeboard()) return(-1);
X chmod(scorefile,0666);
X return(0);
X }
X
X/*
X * hashewon() Function to return 1 if player has won a game before, else 0
X *
X * This function also sets c[HARDGAME] to appropriate value -- 0 if not a
X * winner, otherwise the next level of difficulty listed in the winners
X * scoreboard. This function also sets outstanding_taxes to the value in
X * the winners scoreboard.
X */
Xhashewon()
X {
X register int i;
X c[HARDGAME] = 0;
X if (readboard() < 0) return(0); /* can't find scoreboard */
X for (i=0; i<SCORESIZE; i++) /* search through winners scoreboard */
X if (winr[i].suid == userid)
X if (winr[i].score > 0)
X {
X c[HARDGAME]=winr[i].hardlev+1; outstanding_taxes=winr[i].taxes;
X return(1);
X }
X return(0);
X }
X
X# ifndef MAIL /* dgk */
Xcheckmail()
X{
X register int i;
X long gold, taxes;
X
X if (readboard() < 0)
X return; /* can't find scoreboard */
X for (i = 0; i < SCORESIZE; i++) /* search through winners scoreboard */
X if (winr[i].suid == userid
X && winr[i].score > 0
X && winr[i].hasmail) {
X winr[i].hasmail = 0;
X gold = taxes = winr[i].taxes;
X writeboard();
X
X /* Intuit the amount of gold -- should have changed
X * the score file, but ... TAXRATE is an fraction.
X */
X while ((gold * TAXRATE) < taxes)
X gold += taxes;
X readmail(gold);
X }
X}
X# endif
X
X
X/*
X * long paytaxes(x) Function to pay taxes if any are due
X *
X * Enter with the amount (in gp) to pay on the taxes.
X * Returns amount actually paid.
X */
Xlong paytaxes(x)
X long x;
X {
X register int i;
X register long amt;
X if (x<0) return(0L);
X if (readboard()<0) return(0L);
X for (i=0; i<SCORESIZE; i++)
X if (winr[i].suid == userid) /* look for players winning entry */
X if (winr[i].score>0) /* search for a winning entry for the player */
X {
X amt = winr[i].taxes;
X if (x < amt) amt=x; /* don't overpay taxes (Ughhhhh) */
X winr[i].taxes -= amt;
X outstanding_taxes -= amt;
X if (writeboard()<0) return(0);
X return(amt);
X }
X return(0L); /* couldn't find user on winning scoreboard */
X }
X
X/*
X * winshou() Subroutine to print out the winning scoreboard
X *
X * Returns the number of players on scoreboard that were shown
X */
Xstatic winshou()
X {
X register struct wscofmt *p;
X register int i,j,count;
X for (count=j=i=0; i<SCORESIZE; i++) /* is there anyone on the scoreboard? */
X if (winr[i].score != 0)
X { j++; break; }
X if (j)
X {
X lprcat("\n Score Difficulty Time Needed Larn Winners List\n");
X
X for (i=0; i<SCORESIZE; i++) /* this loop is needed to print out the */
X for (j=0; j<SCORESIZE; j++) /* winners in order */
X {
X p = &winr[j]; /* pointer to the scoreboard entry */
X if (p->order == i)
X {
X if (p->score)
X {
X count++;
X lprintf("%10d %2d %5d Mobuls %s \n",
X (long)p->score,(long)p->hardlev,(long)p->timeused,p->who);
X }
X break;
X }
X }
X }
X return(count); /* return number of people on scoreboard */
X }
X
X/*
X * shou(x) Subroutine to print out the non-winners scoreboard
X * int x;
X *
X * Enter with 0 to list the scores, enter with 1 to list inventories too
X * Returns the number of players on scoreboard that were shown
X */
Xstatic shou(x)
X int x;
X {
X register int i,j,n,k;
X int count;
X for (count=j=i=0; i<SCORESIZE; i++) /* is the scoreboard empty? */
X if (sco[i].score!= 0)
X { j++; break; }
X if (j)
X {
X lprcat("\n Score Difficulty Larn Visitor Log\n");
X for (i=0; i<SCORESIZE; i++) /* be sure to print them out in order */
X for (j=0; j<SCORESIZE; j++)
X if (sco[j].order == i)
X {
X if (sco[j].score)
X {
X count++;
X lprintf("%10d %2d %s ",
X (long)sco[j].score,(long)sco[j].hardlev,sco[j].who);
X if (sco[j].what < 256) lprintf("killed by a %s",monster[sco[j].what].name);
X else lprintf("%s",whydead[sco[j].what - 256]);
X if (x != 263) lprintf(" on %s",levelname[sco[j].level]);
X if (x)
X {
X for (n=0; n<26; n++) { iven[n]=sco[j].sciv[n][0]; ivenarg[n]=sco[j].sciv[n][1]; }
X for (k=1; k<99; k++)
X for (n=0; n<26; n++)
X if (k==iven[n]) show3(n);
X lprcat("\n\n");
X }
X else lprc('\n');
X }
X j=SCORESIZE;
X }
X }
X return(count); /* return the number of players just shown */
X }
X
X/*
X * showscores() Function to show the scoreboard on the terminal
X *
X * Returns nothing of value
X */
Xstatic char esb[] = "The scoreboard is empty.\n";
Xshowscores()
X {
X register int i,j;
X lflush(); lcreat((char*)0); if (readboard()<0) return;
X i=winshou(); j=shou(0);
X if (i+j == 0) lprcat(esb); else lprc('\n');
X lflush();
X }
X
X/*
X * showallscores() Function to show scores and the iven lists that go with them
X *
X * Returns nothing of value
X */
Xshowallscores()
X {
X register int i,j;
X lflush(); lcreat((char*)0); if (readboard()<0) return;
X c[WEAR] = c[WIELD] = c[SHIELD] = -1; /* not wielding or wearing anything */
X for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
X for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
X i=winshou(); j=shou(1);
X if (i+j==0) lprcat(esb); else lprc('\n');
X lflush();
X }
X
X/*
X * sortboard() Function to sort the scoreboard
X *
X * Returns 0 if no sorting done, else returns 1
X */
Xstatic sortboard()
X {
X register int i,j,pos;
X long jdat;
X for (i=0; i<SCORESIZE; i++) sco[i].order = winr[i].order = -1;
X pos=0; while (pos < SCORESIZE)
X {
X jdat=0;
X for (i=0; i<SCORESIZE; i++)
X if ((sco[i].order < 0) && (sco[i].score >= jdat))
X { j=i; jdat=sco[i].score; }
X sco[j].order = pos++;
X }
X pos=0; while (pos < SCORESIZE)
X {
X jdat=0;
X for (i=0; i<SCORESIZE; i++)
X if ((winr[i].order < 0) && (winr[i].score >= jdat))
X { j=i; jdat=winr[i].score; }
X winr[j].order = pos++;
X }
X return(1);
X }
X
X/*
X * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard
X * int score, winner, whyded;
X * char *whoo;
X *
X * Enter with the total score in gp in score, players name in whoo,
X * died() reason # in whyded, and TRUE/FALSE in winner if a winner
X * ex. newscore(1000, "player 1", 32, 0);
X */
Xstatic newscore(score, whoo, whyded, winner)
X long score;
X int winner, whyded;
X char *whoo;
X {
X register int i;
X long taxes;
X if (readboard() < 0) return; /* do the scoreboard */
X /* if a winner then delete all non-winning scores */
X if (cheat) winner=0; /* if he cheated, don't let him win */
X if (winner)
X {
X for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) sco[i].score=0;
X taxes = score*TAXRATE;
X score += 100000*c[HARDGAME]; /* bonus for winning */
X /* if he has a slot on the winning scoreboard update it if greater score */
X for (i=0; i<SCORESIZE; i++) if (winr[i].suid == userid)
X { new1sub(score,i,whoo,taxes); return; }
X /* he had no entry. look for last entry and see if he has a greater score */
X for (i=0; i<SCORESIZE; i++) if (winr[i].order == SCORESIZE-1)
X { new1sub(score,i,whoo,taxes); return; }
X }
X else if (!cheat) /* for not winning scoreboard */
X {
X /* if he has a slot on the scoreboard update it if greater score */
X for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid)
X { new2sub(score,i,whoo,whyded); return; }
X /* he had no entry. look for last entry and see if he has a greater score */
X for (i=0; i<SCORESIZE; i++) if (sco[i].order == SCORESIZE-1)
X { new2sub(score,i,whoo,whyded); return; }
X }
X }
X
X/*
X * new1sub(score,i,whoo,taxes) Subroutine to put player into a
X * int score,i,whyded,taxes; winning scoreboard entry if his score
X * char *whoo; is high enough
X *
X * Enter with the total score in gp in score, players name in whoo,
X * died() reason # in whyded, and TRUE/FALSE in winner if a winner
X * slot in scoreboard in i, and the tax bill in taxes.
X * Returns nothing of value
X */
Xstatic new1sub(score,i,whoo,taxes)
X long score,taxes;
X int i;
X char *whoo;
X {
X register struct wscofmt *p;
X p = &winr[i];
X p->taxes += taxes;
X if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
X {
X strcpy(p->who,whoo); p->score=score;
X p->hardlev=c[HARDGAME]; p->suid=userid;
X p->timeused=gtime/100;
X# ifndef MAIL /* dgk */
X p->hasmail = 1;
X# endif
X }
X }
X
X/*
X * new2sub(score,i,whoo,whyded) Subroutine to put player into a
X * int score,i,whyded,taxes; non-winning scoreboard entry if his
X * char *whoo; score is high enough
X *
X * Enter with the total score in gp in score, players name in whoo,
X * died() reason # in whyded, and slot in scoreboard in i.
X * Returns nothing of value
X */
Xstatic new2sub(score,i,whoo,whyded)
X long score;
X int i,whyded;
X char *whoo;
X {
X register int j;
X register struct scofmt *p;
X p = &sco[i];
X if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
X {
X strcpy(p->who,whoo); p->score=score;
X p->what=whyded; p->hardlev=c[HARDGAME];
X p->suid=userid; p->level=level;
X for (j=0; j<26; j++)
X { p->sciv[j][0]=iven[j]; p->sciv[j][1]=ivenarg[j]; }
X }
X }
X
X/*
X * died(x) Subroutine to record who played larn, and what the score was
X * int x;
X *
X * if x < 0 then don't show scores
X * died() never returns! (unless c[LIFEPROT] and a reincarnatable death!)
X *
X * < 256 killed by the monster number
X * 256 quit
X * 257 suspended
X * 258 self - annihilated
X * 259 shot by an arrow
X * 260 hit by a dart
X * 261 fell into a pit
X * 262 fell into a bottomless pit
X * 263 a winner
X * 264 trapped in solid rock
X * 265 killed by a missing save file
X * 266 killed by an old save file
X * 267 caught by the greedy cheater checker trap
X * 268 killed by a protected save file
X * 269 killed his family and killed himself
X * 270 erased by a wayward finger
X * 271 fell through a bottomless trap door
X * 272 fell through a trap door
X * 273 drank some poisonous water
X * 274 fried by an electric shock
X * 275 slipped on a volcano shaft
X * 276 killed by a stupid act of frustration
X * 277 attacked by a revolting demon
X * 278 hit by his own magic
X * 279 demolished by an unseen attacker
X * 280 fell into the dreadful sleep
X * 281 killed by an exploding chest
X * 282 killed by a missing maze data file
X * 283 killed by a sphere of annihilation
X * 284 died a post mortem death
X * 285 malloc() failure
X * 300 quick quit -- don't put on scoreboard
X */
X
Xstatic int scorerror;
Xdied(x)
X int x;
X {
X register int f,win;
X char ch,*mod;
X long zzz,i;
X# ifdef EXTRA
X struct tms cputime;
X# endif
X if (c[LIFEPROT]>0) /* if life protection */
X {
X switch((x>0) ? x : -x)
X {
X case 256: case 257: case 262: case 263: case 265: case 266:
X case 267: case 268: case 269: case 271: case 282: case 284:
X case 285: case 300: goto invalid; /* can't be saved */
X };
X --c[LIFEPROT]; c[HP]=1; --c[CONSTITUTION];
X cursors(); lprcat("\nYou feel wiiieeeeerrrrrd all over! "); beep();
X lflush(); sleep(4);
X return; /* only case where died() returns */
X }
Xinvalid:
X clearvt100(); lflush(); f=0;
X if (ckpflag) unlink(ckpfile); /* remove checkpoint file if used */
X# ifdef MSDOS
X if (swapfd) {
X close(swapfd);
X (void) unlink(swapfile);/* Remove swapfile */
X }
X unsetraw();
X# endif
X if (x<0) { f++; x = -x; } /* if we are not to display the scores */
X if ((x == 300) || (x == 257)) exit(); /* for quick exit or saved game */
X if (x == 263) win = 1; else win = 0;
X c[GOLD] += c[BANKACCOUNT]; c[BANKACCOUNT] = 0;
X /* now enter the player at the end of the scoreboard */
X newscore(c[GOLD], logname, x, win);
X diedsub(x); /* print out the score line */ lflush();
X
X set_score_output();
X if ((wizard == 0) && (c[GOLD] > 0)) /* wizards can't score */
X {
X if (lappend(logfile)<0) /* append to file */
X {
X if (lcreat(logfile)<0) /* and can't create new log file */
X {
X lcreat((char*)0);
X lprcat("\nCan't open record file: I can't post your score.\n");
X sncbr(); resetscroll(); lflush(); exit();
X }
X chmod(logfile,0666);
X }
X strcpy(logg.who,loginname);
X logg.score = c[GOLD]; logg.diff = c[HARDGAME];
X if (x < 256)
X {
X ch = *monster[x].name;
X if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
X mod="an"; else mod="a";
X sprintf(logg.what,"killed by %s %s",mod,monster[x].name);
X }
X else sprintf(logg.what,"%s",whydead[x - 256]);
X logg.cavelev=level;
X time(&zzz); /* get cpu time -- write out score info */
X logg.diedtime=zzz;
X#ifdef EXTRA
X times(&cputime); /* get cpu time -- write out score info */
X logg.cputime = i = (cputime.tms_utime + cputime.tms_stime)/60 + c[CPUTIME];
X logg.lev=c[LEVEL]; logg.ac=c[AC];
X logg.hpmax=c[HPMAX]; logg.hp=c[HP];
X logg.elapsedtime=(zzz-initialtime+59)/60;
X logg.usage=(10000*i)/(zzz-initialtime);
X logg.bytin=c[BYTESIN]; logg.bytout=c[BYTESOUT];
X logg.moves=c[MOVESMADE]; logg.spused=c[SPELLSCAST];
X logg.killed=c[MONSTKILLED];
X#endif
X lwrite((char*)&logg,sizeof(struct log_fmt)); lwclose();
X
X/* now for the scoreboard maintenance -- not for a suspended game */
X if (x != 257)
X {
X if (sortboard()) scorerror = writeboard();
X }
X }
X if ((x==256) || (x==257) || (f != 0)) exit();
X if (scorerror == 0) showscores(); /* if we updated the scoreboard */
X# ifdef MAIL
X if (x == 263) mailbill();
X# endif
X exit();
X }
X
X/*
X * diedsub(x) Subroutine to print out the line showing the player when he is killed
X * int x;
X */
Xstatic diedsub(x)
Xint x;
X {
X register char ch,*mod;
X lprintf("Score: %d, Diff: %d, %s ",(long)c[GOLD],(long)c[HARDGAME],logname);
X if (x < 256)
X {
X ch = *monster[x].name;
X if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
X mod="an"; else mod="a";
X lprintf("killed by %s %s",mod,monster[x].name);
X }
X else lprintf("%s",whydead[x - 256]);
X if (x != 263) lprintf(" on %s\n",levelname[level]); else lprc('\n');
X }
X
X/*
X * diedlog() Subroutine to read a log file and print it out in ascii format
X */
Xdiedlog()
X {
X register int n;
X register char *p;
X struct stat stbuf;
X lcreat((char*)0);
X if (lopen(logfile)<0)
X {
X lprintf("Can't locate log file <%s>\n",logfile);
X return;
X }
X#ifdef AMIGA
X if (stat(logfile,&stbuf) < 0)
X#else
X if (fstat(fd,&stbuf) < 0)
X#endif /* AMIGA */
X {
X lprintf("Can't stat log file <%s>\n",logfile);
X return;
X }
X for (n=stbuf.st_size/sizeof(struct log_fmt); n>0; --n)
X {
X lrfill((char*)&logg,sizeof(struct log_fmt));
X p = ctime(&logg.diedtime); p[16]='\n'; p[17]=0;
X lprintf("Score: %d, Diff: %d, %s %s on %d at %s",(long)(logg.score),(long)(logg.diff),logg.who,logg.what,(long)(logg.cavelev),p+4);
X#ifdef EXTRA
X if (logg.moves<=0) logg.moves=1;
X lprintf(" Experience Level: %d, AC: %d, HP: %d/%d, Elapsed Time: %d minutes\n",(long)(logg.lev),(long)(logg.ac),(long)(logg.hp),(long)(logg.hpmax),(long)(logg.elapsedtime));
X lprintf(" CPU time used: %d seconds, Machine usage: %d.%02d%%\n",(long)(logg.cputime),(long)(logg.usage/100),(long)(logg.usage%100));
X lprintf(" BYTES in: %d, out: %d, moves: %d, deaths: %d, spells cast: %d\n",(long)(logg.bytin),(long)(logg.bytout),(long)(logg.moves),(long)(logg.killed),(long)(logg.spused));
X lprintf(" out bytes per move: %d, time per move: %d ms\n",(long)(logg.bytout/logg.moves),(long)((logg.cputime*1000)/logg.moves));
X#endif
X }
X lflush(); lrclose(); return;
X }
X
X#ifndef UIDSCORE
X/*
X * getplid(name) Function to get players id # from id file
X *
X * Enter with the name of the players character in name.
X * Returns the id # of the players character, or -1 if failure.
X * This routine will try to find the name in the id file, if its not there,
X * it will try to make a new entry in the file. Only returns -1 if can't
X * find him in the file, and can't make a new entry in the file.
X * Format of playerids file:
X * Id # in ascii \n character name \n
X */
Xstatic int havepid= -1; /* playerid # if previously done */
Xgetplid(nam)
X char *nam;
X {
X int fd7,high=999,no;
X register char *p,*p2;
X char name[80];
X if (havepid != -1) return(havepid); /* already did it */
X lflush(); /* flush any pending I/O */
X sprintf(name,"%s\n",nam); /* append a \n to name */
X if (lopen(playerids) < 0) /* no file, make it */
X {
X if ((fd7=creat(playerids,0666)) < 0) return(-1); /* can't make it */
X close(fd7); goto addone; /* now append new playerid record to file */
X }
X for (;;) /* now search for the name in the player id file */
X {
X p = lgetl(); if (p==NULL) break; /* EOF? */
X no = atoi(p); /* the id # */
X p2= lgetl(); if (p2==NULL) break; /* EOF? */
X if (no>high) high=no; /* accumulate highest id # */
X if (strcmp(p2,name)==0) /* we found him */
X {
X return(no); /* his id number */
X }
X }
X lrclose();
X /* if we get here, we didn't find him in the file -- put him there */
Xaddone:
X if (lappend(playerids) < 0) return(-1); /* can't open file for append */
X lprintf("%d\n%s",(long)++high,name); /* new id # and name */
X lwclose();
X lcreat((char*)0); /* re-open terminal channel */
X return(high);
X }
X#endif UIDSCORE
END_OF_FILE
if test 26174 -ne `wc -c <'scores.c'`; then
echo shar: \"'scores.c'\" unpacked with wrong size!
fi
# end of 'scores.c'
fi
echo shar: End of archive 10 \(of 17\).
cp /dev/null ark10isdone
#!/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 11 (of 17)."
# Contents: spells.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:54 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'spells.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'spells.c'\"
else
echo shar: Extracting \"'spells.c'\" \(27345 characters\)
sed "s/^X//" >'spells.c' <<'END_OF_FILE'
X/*
X cast() Subroutine called by parse to cast a spell for the user
X speldamage(x) Function to perform spell functions cast by the player
X loseint() Routine to decrement your int (intelligence) if > 3
X isconfuse() Routine to check to see if player is confused
X nospell(x,monst) Routine to return 1 if a spell doesn't affect a monster
X fullhit(xx) Function to return full damage against a monst (aka web)
X direct(spnum,dam,str,arg) Routine to direct spell damage 1 square in 1 dir
X godirect(spnum,dam,str,delay,cshow) Function to perform missile attacks
X ifblind(x,y) Routine to put "monster" or the monster name into lastmosnt
X tdirect(spnum) Routine to teleport away a monster
X omnidirect(sp,dam,str) Routine to damage all monsters 1 square from player
X dirsub(x,y) Routine to ask for direction, then modify x,y for it
X dirpoly(spnum) Routine to ask for a direction and polymorph a monst
X annihilate() Routine to annihilate monsters around player, playerx,playery
X genmonst() Function to ask for monster and genocide from game
X*/
X
X#include "header.h"
X#include "larndefs.h"
X#include "objects.h"
X#include "monsters.h"
X#include "player.h"
X#include <ctype.h>
X
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
Xstruct isave /* used for altar reality */
X {
X char type; /* 0=item, 1=monster */
X char id; /* item number or monster number */
X short arg; /* the type of item or hitpoints of monster */
X };
X
X/* Forward declarations
X*/
Xstatic void create_guardian();
Xextern hitm();
Xextern char spelweird[MAXMONST+8][SPNUM];
X
X/*
X * cast() Subroutine called by parse to cast a spell for the user
X *
X * No arguments and no return value.
X */
Xstatic char eys[] = "\nEnter your spell: ";
Xcast()
X {
X register int i,j,a,b,d;
X cursors();
X if (c[SPELLS]<=0)
X {
X lprcat("\nYou don't have any spells!");
X return;
X }
X lprcat(eys);
X --c[SPELLS];
X while ((a=ttgetch())=='I')
X {
X seemagic(-1);
X cursors();
X lprcat(eys);
X }
X if (a=='\33')
X goto over; /* to escape casting a spell */
X if ((b=ttgetch())=='\33')
X goto over; /* to escape casting a spell */
X if ((d=ttgetch())=='\33')
X {
Xover:
X lprcat(aborted);
X c[SPELLS]++;
X return;
X } /* to escape casting a spell */
X#ifdef EXTRA
X c[SPELLSCAST]++;
X#endif
X for (lprc('\n'),j= -1,i=0; i<SPNUM; i++) /*seq search for his spell, hash?*/
X if ((spelcode[i][0]==a) && (spelcode[i][1]==b) && (spelcode[i][2]==d))
X if (spelknow[i])
X { speldamage(i); j = 1; i=SPNUM; }
X
X if (j == -1) lprcat(" Nothing Happened ");
X bottomline();
X }
X
X/*
X * speldamage(x) Function to perform spell functions cast by the player
X * int x;
X *
X * Enter with the spell number, returns no value.
X * Please insure that there are 2 spaces before all messages here
X */
Xstatic speldamage(x)
X int x;
X {
X register int i,j,clev;
X int xl,xh,yl,yh;
X register char *p,*kn,*pm;
X
X if (x>=SPNUM) return; /* no such spell */
X if (c[TIMESTOP]) { lprcat(" It didn't seem to work"); return; } /* not if time stopped */
X clev = c[LEVEL];
X if ((rnd(23)==7) || (rnd(18) > c[INTELLIGENCE]))
X { lprcat(" It didn't work!"); return; }
X if (clev*3+2 < x)
X {
X lprcat(" Nothing happens. You seem inexperienced at this");
X return;
X }
X
X switch(x)
X {
X/* ----- LEVEL 1 SPELLS ----- */
X
X case 0: if (c[PROTECTIONTIME]==0) c[MOREDEFENSES]+=2; /* protection field +2 */
X c[PROTECTIONTIME] += 250; return;
X
X case 1: i = rnd(((clev+1)<<1)) + clev + 3;
X godirect(x,i,(clev>=2)?" Your missiles hit the %s":" Your missile hit the %s",100,'+'); /* magic missile */
X
X return;
X
X case 2: if (c[DEXCOUNT]==0) c[DEXTERITY]+=3; /* dexterity */
X c[DEXCOUNT] += 400; return;
X
X case 3: i=rnd(3)+1;
X p=" While the %s slept, you smashed it %d times";
X ws: direct(x,fullhit(i),p,i); /* sleep */ return;
X
X case 4: /* charm monster */ c[CHARMCOUNT] += c[CHARISMA]<<1; return;
X
X case 5: godirect(x,rnd(10)+15+clev," The sound damages the %s",70,'@'); /* sonic spear */
X return;
X
X/* ----- LEVEL 2 SPELLS ----- */
X
X case 6: i=rnd(3)+2; p=" While the %s is entangled, you hit %d times";
X goto ws; /* web */
X
X case 7: if (c[STRCOUNT]==0) c[STREXTRA]+=3; /* strength */
X c[STRCOUNT] += 150+rnd(100); return;
X
X case 8: yl = playery-5; /* enlightenment */
X yh = playery+6; xl = playerx-15; xh = playerx+16;
X vxy(&xl,&yl); vxy(&xh,&yh); /* check bounds */
X for (i=yl; i<=yh; i++) /* enlightenment */
X for (j=xl; j<=xh; j++)
X know[j][i]=KNOWALL;
X draws(xl,xh+1,yl,yh+1); return;
X
X case 9: raisehp(20+(clev<<1)); return; /* healing */
X
X case 10: c[BLINDCOUNT]=0; return; /* cure blindness */
X
X case 11: createmonster(makemonst(level+1)+8); return;
X
X case 12: if (rnd(11)+7 <= c[WISDOM]) direct(x,rnd(20)+20+clev," The %s believed!",0);
X else lprcat(" It didn't believe the illusions!");
X return;
X
X case 13: /* if he has the amulet of invisibility then add more time */
X for (j=i=0; i<26; i++)
X if (iven[i]==OAMULET) j+= 1+ivenarg[i];
X c[INVISIBILITY] += (j<<7)+12; return;
X
X/* ----- LEVEL 3 SPELLS ----- */
X
X case 14: godirect(x,rnd(25+clev)+25+clev," The fireball hits the %s",40,'*'); return; /* fireball */
X
X case 15: godirect(x,rnd(25)+20+clev," Your cone of cold strikes the %s",60,'O'); /* cold */
X return;
X
X case 16: dirpoly(x); return; /* polymorph */
X
X case 17: c[CANCELLATION]+= 5+clev; return; /* cancellation */
X
X case 18: c[HASTESELF]+= 7+clev; return; /* haste self */
X
X case 19: omnidirect(x,30+rnd(10)," The %s gasps for air"); /* cloud kill */
X return;
X
X case 20: xh = min(playerx+1,MAXX-2); yh = min(playery+1,MAXY-2);
X for (i=max(playerx-1,1); i<=xh; i++) /* vaporize rock */
X for (j=max(playery-1,1); j<=yh; j++)
X {
X kn = &know[i][j];
X pm = &mitem[i][j];
X switch(*(p= &item[i][j]))
X {
X case OWALL: if (level < MAXLEVEL+MAXVLEVEL-1)
X *p = *kn = 0;
X break;
X
X case OSTATUE: if (c[HARDGAME]<3)
X {
X *p=OBOOK; iarg[i][j]=level; *kn=0;
X }
X break;
X
X case OTHRONE:
X *p= OTHRONE2;
X create_guardian( GNOMEKING, i, j );
X break;
X
X case OALTAR:
X create_guardian( DEMONPRINCE, i, j );
X break;
X
X case OFOUNTAIN:
X create_guardian( WATERLORD, i, j );
X break;
X };
X switch(*pm)
X {
X case XORN: ifblind(i,j); hitm(i,j,200); break; /* Xorn takes damage from vpr */
X }
X }
X return;
X
X/* ----- LEVEL 4 SPELLS ----- */
X
X case 21: direct(x,100+clev," The %s shrivels up",0); /* dehydration */
X return;
X
X case 22: godirect(x,rnd(25)+20+(clev<<1)," A lightning bolt hits the %s",1,'~'); /* lightning */
X return;
X
X case 23: i=min(c[HP]-1,c[HPMAX]/2); /* drain life */
X direct(x,i+i,"",0); c[HP] -= i; return;
X
X case 24: if (c[GLOBE]==0) c[MOREDEFENSES] += 10;
X c[GLOBE] += 200; loseint(); /* globe of invulnerability */
X return;
X
X case 25: omnidirect(x,32+clev," The %s struggles for air in your flood!"); /* flood */
X return;
X
X case 26: if (rnd(151)==63) { beep(); lprcat("\nYour heart stopped!\n"); nap(4000); died(270); return; }
X if (c[WISDOM]>rnd(10)+10) direct(x,2000," The %s's heart stopped",0); /* finger of death */
X else lprcat(" It didn't work"); return;
X
X/* ----- LEVEL 5 SPELLS ----- */
X
X case 27: c[SCAREMONST] += rnd(10)+clev; return; /* scare monster */
X
X case 28: c[HOLDMONST] += rnd(10)+clev; return; /* hold monster */
X
X case 29: c[TIMESTOP] += rnd(20)+(clev<<1); return; /* time stop */
X
X case 30: tdirect(x); return; /* teleport away */
X
X case 31: omnidirect(x,35+rnd(10)+clev," The %s cringes from the flame"); /* magic fire */
X return;
X
X/* ----- LEVEL 6 SPELLS ----- */
X
X case 32: if ((rnd(23)==5) && (wizard==0)) /* sphere of annihilation */
X {
X beep(); lprcat("\nYou have been enveloped by the zone of nothingness!\n");
X nap(4000); died(258); return;
X }
X xl=playerx; yl=playery;
X loseint();
X i=dirsub(&xl,&yl); /* get direction of sphere */
X newsphere(xl,yl,i,rnd(20)+11); /* make a sphere */
X return;
X
X case 33: genmonst(); spelknow[33]=0; /* genocide */
X loseint();
X return;
X
X case 34: /* summon demon */
X if (rnd(100) > 30) { direct(x,150," The demon strikes at the %s",0); return; }
X if (rnd(100) > 15) { lprcat(" Nothing seems to have happened"); return; }
X lprcat(" The demon turned on you and vanished!"); beep();
X i=rnd(40)+30; lastnum=277;
X losehp(i); /* must say killed by a demon */ return;
X
X case 35: /* walk through walls */
X c[WTW] += rnd(10)+5; return;
X
X case 36: /* alter reality */
X {
X struct isave *save; /* pointer to item save structure */
X int sc; sc=0; /* # items saved */
X save = (struct isave *)malloc(sizeof(struct isave)*MAXX*MAXY*2);
X if (save == NULL)
X {
X lprcat("\nPolinneaus won't let you mess with his dungeon!");
X return;
X }
X for (j=0; j<MAXY; j++)
X for (i=0; i<MAXX; i++) /* save all items and monsters */
X {
X xl = item[i][j];
X if (xl && xl!=OWALL && xl!=OANNIHILATION)
X {
X save[sc].type=0; save[sc].id=item[i][j];
X save[sc++].arg=iarg[i][j];
X }
X if (mitem[i][j])
X {
X save[sc].type=1; save[sc].id=mitem[i][j];
X save[sc++].arg=hitp[i][j];
X }
X item[i][j]=OWALL; mitem[i][j]=0;
X if (wizard)
X know[i][j]=KNOWALL;
X else
X know[i][j]=0;
X }
X eat(1,1); if (level==1) item[33][MAXY-1]=OENTRANCE;
X for (j=rnd(MAXY-2), i=1; i<MAXX-1; i++) item[i][j]=0;
X while (sc>0) /* put objects back in level */
X {
X --sc;
X if (save[sc].type == 0)
X {
X int trys;
X for (trys=100, i=j=1; --trys>0 && item[i][j]; i=rnd(MAXX-1), j=rnd(MAXY-1));
X if (trys) { item[i][j]=save[sc].id; iarg[i][j]=save[sc].arg; }
X }
X else
X { /* put monsters back in */
X int trys;
X for (trys=100, i=j=1; --trys>0 && (item[i][j]==OWALL || mitem[i][j]); i=rnd(MAXX-1), j=rnd(MAXY-1));
X if (trys) { mitem[i][j]=save[sc].id; hitp[i][j]=save[sc].arg; }
X }
X }
X loseint();
X draws(0,MAXX,0,MAXY); if (wizard==0) spelknow[36]=0;
X free((char*)save); positionplayer(); return;
X }
X
X case 37: /* permanence */ adjtime(-99999L); spelknow[37]=0; /* forget */
X loseint();
X return;
X
X default: lprintf(" spell %d not available!",(long)x); beep(); return;
X };
X }
X
X/*
X Create a guardian for a throne/altar/fountain, as a result of the player
X using a VPR spell or pulverization scroll on it.
X*/
Xstatic void create_guardian( monst, x, y )
Xint monst; /* monster code for the guardian */
Xint x, y; /* coords of the object being guarded */
X {
X int k ;
X
X /* prevent the guardian from being created on top of the player
X */
X if ((x == playerx) && (y == playery))
X {
X k = rnd(8);
X x += diroffx[k];
X y += diroffy[k];
X }
X know[x][y] = 0;
X mitem[x][y] = monst ;
X hitp[x][y] = monster[monst].hitpoints;
X }
X
X/*
X * loseint() Routine to subtract 1 from your int (intelligence) if > 3
X *
X * No arguments and no return value
X */
Xstatic loseint()
X {
X if (--c[INTELLIGENCE]<3) c[INTELLIGENCE]=3;
X }
X
X/*
X * isconfuse() Routine to check to see if player is confused
X *
X * This routine prints out a message saying "You can't aim your magic!"
X * returns 0 if not confused, non-zero (time remaining confused) if confused
X */
Xstatic isconfuse()
X {
X if (c[CONFUSE]) { lprcat(" You can't aim your magic!"); beep(); }
X return(c[CONFUSE]);
X }
X
X/*
X * nospell(x,monst) Routine to return 1 if a spell doesn't affect a monster
X * int x,monst;
X *
X * Subroutine to return 1 if the spell can't affect the monster
X * otherwise returns 0
X * Enter with the spell number in x, and the monster number in monst.
X */
Xstatic nospell(x,monst)
X int x,monst;
X {
X register int tmp;
X if (x>=SPNUM || monst>=MAXMONST+8 || monst<0 || x<0) return(0); /* bad spell or monst */
X if ((tmp=spelweird[monst-1][x])==0) return(0);
X cursors(); lprc('\n'); lprintf(spelmes[tmp],monster[monst].name); return(1);
X }
X
X/*
X * fullhit(xx) Function to return full damage against a monster (aka web)
X * int xx;
X *
X * Function to return hp damage to monster due to a number of full hits
X * Enter with the number of full hits being done
X */
Xfullhit(xx)
X int xx;
X {
X register int i;
X if (xx<0 || xx>20) return(0); /* fullhits are out of range */
X if (c[LANCEDEATH]) return(10000); /* lance of death */
X i = xx * ((c[WCLASS]>>1)+c[STRENGTH]+c[STREXTRA]-c[HARDGAME]-12+c[MOREDAM]);
X return( (i>=1) ? i : xx );
X }
X
X/*
X * direct(spnum,dam,str,arg) Routine to direct spell damage 1 square in 1 dir
X * int spnum,dam,arg;
X * char *str;
X *
X * Routine to ask for a direction to a spell and then hit the monster
X * Enter with the spell number in spnum, the damage to be done in dam,
X * lprintf format string in str, and lprintf's argument in arg.
X * Returns no value.
X */
Xstatic direct(spnum,dam,str,arg)
X int spnum,dam,arg;
X char *str;
X {
X extern char lastmonst[];
X int x,y;
X register int m;
X if (spnum<0 || spnum>=SPNUM || str==0) return; /* bad arguments */
X if (isconfuse()) return;
X dirsub(&x,&y);
X m = mitem[x][y];
X if (item[x][y]==OMIRROR)
X {
X if (spnum==3) /* sleep */
X {
X lprcat("You fall asleep! "); beep();
X fool:
X arg += 2;
X while (arg-- > 0) { parse2(); nap(1000); }
X return;
X }
X else if (spnum==6) /* web */
X {
X lprcat("You get stuck in your own web! "); beep();
X goto fool;
X }
X else
X {
X lastnum=278;
X lprintf(str,"spell caster (thats you)",(long)arg);
X beep(); losehp(dam); return;
X }
X }
X if (m==0)
X { lprcat(" There wasn't anything there!"); return; }
X ifblind(x,y);
X if (nospell(spnum,m)) { lasthx=x; lasthy=y; return; }
X lprintf(str,lastmonst,(long)arg); hitm(x,y,dam);
X }
X
X/*
X * godirect(spnum,dam,str,delay,cshow) Function to perform missile attacks
X * int spnum,dam,delay;
X * char *str,cshow;
X *
X * Function to hit in a direction from a missile weapon and have it keep
X * on going in that direction until its power is exhausted
X * Enter with the spell number in spnum, the power of the weapon in hp,
X * lprintf format string in str, the # of milliseconds to delay between
X * locations in delay, and the character to represent the weapon in cshow.
X * Returns no value.
X */
Xgodirect(spnum,dam,str,delay,cshow)
X int spnum,dam,delay;
X char *str,cshow;
X {
X extern char lastmonst[] ;
X register char *p;
X register int x,y,m;
X int dx,dy;
X if (spnum<0 || spnum>=SPNUM || str==0 || delay<0) return; /* bad args */
X if (isconfuse()) return;
X dirsub(&dx,&dy); x=dx; y=dy;
X dx = x-playerx; dy = y-playery; x = playerx; y = playery;
X while (dam>0)
X {
X x += dx; y += dy;
X if ((x > MAXX-1) || (y > MAXY-1) || (x < 0) || (y < 0))
X {
X dam=0; break; /* out of bounds */
X }
X if ((x==playerx) && (y==playery)) /* if energy hits player */
X {
X cursors(); lprcat("\nYou are hit my your own magic!"); beep();
X lastnum=278; losehp(dam); return;
X }
X if (c[BLINDCOUNT]==0) /* if not blind show effect */
X {
X cursor(x+1,y+1); lprc(cshow); nap(delay); show1cell(x,y);
X }
X if ((m=mitem[x][y])) /* is there a monster there? */
X {
X ifblind(x,y);
X if (nospell(spnum,m)) { lasthx=x; lasthy=y; return; }
X cursors(); lprc('\n');
X lprintf(str,lastmonst); dam -= hitm(x,y,dam);
X show1cell(x,y); nap(1000); x -= dx; y -= dy;
X }
X else switch (*(p= &item[x][y]))
X {
X case OWALL:
X cursors();
X lprc('\n');
X lprintf(str,"wall");
X if (dam>=50+c[HARDGAME]) /* enough damage? */
X if (level<MAXLEVEL+MAXVLEVEL-1) /* not on V3 */
X if ((x<MAXX-1) && (y<MAXY-1) && (x) && (y))
X {
X lprcat(" The wall crumbles");
X *p=0;
X know[x][y]=0;
X show1cell(x,y);
X }
X dam = 0;
X break;
X
X case OCLOSEDDOOR:
X cursors();
X lprc('\n');
X lprintf(str,"door");
X if (dam>=40)
X {
X lprcat(" The door is blasted apart");
X *p = 0;
X know[x][y] = 0;
X show1cell( x, y );
X }
X dam = 0 ;
X break;
X
X case OSTATUE:
X cursors();
X lprc('\n');
X lprintf(str,"statue");
X if (c[HARDGAME]<3)
X if (dam>44)
X {
X lprcat(" The statue crumbles");
X *p=OBOOK;
X iarg[x][y]=level;
X know[x][y] = 0;
X show1cell( x, y );
X }
X dam = 0 ;
X break;
X
X case OTHRONE:
X cursors();
X lprc('\n');
X lprintf(str,"throne");
X if (dam>39)
X {
X *p = OTHRONE2;
X create_guardian( GNOMEKING, x, y );
X show1cell( x, y );
X }
X dam = 0;
X break;
X
X case OALTAR:
X cursors();
X lprc('\n');
X lprintf(str, "altar");
X if ( dam > 75 - ( c[HARDGAME] >> 2 ))
X {
X create_guardian( DEMONPRINCE, x, y );
X show1cell( x, y );
X }
X dam = 0 ;
X break;
X
X case OFOUNTAIN:
X cursors();
X lprc('\n');
X lprintf(str, "fountain");
X if ( dam > 55 )
X {
X create_guardian( WATERLORD, x, y );
X show1cell( x, y );
X }
X dam = 0 ;
X break;
X
X case OMIRROR:
X {
X int bounce = FALSE, odx=dx, ody=dy ;
X /* spells may bounce directly back or off at an angle
X */
X if (rnd(100) < 50 )
X {
X bounce = TRUE ;
X dx *= -1;
X }
X if (rnd(100) < 50 )
X {
X bounce = TRUE ;
X dy *= -1;
X }
X if (!bounce || ((odx==dx) && (ody==dy))) /* guarentee a bounce */
X {
X dx = -odx;
X dy = -ody;
X }
X }
X break;
X };
X dam -= 3 + (c[HARDGAME]>>1);
X }
X }
X
X/*
X * ifblind(x,y) Routine to put "monster" or the monster name into lastmosnt
X * int x,y;
X *
X * Subroutine to copy the word "monster" into lastmonst if the player is blind
X * Enter with the coordinates (x,y) of the monster
X * Returns no value.
X */
Xifblind(x,y)
X int x,y;
X {
X extern char lastmonst[] ;
X char *p;
X vxy(&x,&y); /* verify correct x,y coordinates */
X if (c[BLINDCOUNT]) { lastnum=279; p="monster"; }
X else { lastnum=mitem[x][y]; p=monster[lastnum].name; }
X strcpy(lastmonst,p);
X }
X
X/*
X * tdirect(spnum) Routine to teleport away a monster
X * int spnum;
X *
X * Routine to ask for a direction to a spell and then teleport away monster
X * Enter with the spell number that wants to teleport away
X * Returns no value.
X */
Xstatic tdirect(spnum)
X int spnum;
X {
X int x,y;
X register int m;
X if (spnum<0 || spnum>=SPNUM) return; /* bad args */
X if (isconfuse()) return;
X dirsub(&x,&y);
X if ((m=mitem[x][y])==0)
X { lprcat(" There wasn't anything there!"); return; }
X ifblind(x,y);
X if (nospell(spnum,m)) { lasthx=x; lasthy=y; return; }
X fillmonst(m); mitem[x][y]=0; know[x][y] &= ~KNOWHERE;
X }
X
X/*
X * omnidirect(sp,dam,str) Routine to damage all monsters 1 square from player
X * int sp,dam;
X * char *str;
X *
X * Routine to cast a spell and then hit the monster in all directions
X * Enter with the spell number in sp, the damage done to wach square in dam,
X * and the lprintf string to identify the spell in str.
X * Returns no value.
X */
Xstatic omnidirect(spnum,dam,str)
X int spnum,dam;
X char *str;
X {
X extern char lastmonst[] ;
X register int x,y,m;
X if (spnum<0 || spnum>=SPNUM || str==0) return; /* bad args */
X for (x=playerx-1; x<playerx+2; x++)
X for (y=playery-1; y<playery+2; y++)
X {
X if (m=mitem[x][y])
X if (nospell(spnum,m) == 0)
X {
X ifblind(x,y);
X cursors(); lprc('\n'); lprintf(str,lastmonst);
X hitm(x,y,dam); nap(800);
X }
X else { lasthx=x; lasthy=y; }
X }
X }
X
X/*
X * dirsub(x,y) Routine to ask for direction, then modify playerx,
X * playery for it
X * int *x,*y;
X *
X * Function to ask for a direction and modify an x,y for that direction
X * Enter with the coordinate destination (x,y).
X * Returns index into diroffx[] (0-8).
X */
Xdirsub(x,y)
X int *x,*y;
X {
X register int i;
X lprcat("\nIn What Direction? ");
X for (i=0; ; )
X switch(ttgetch())
X {
X case 'b': i++;
X case 'n': i++;
X case 'y': i++;
X case 'u': i++;
X case 'h': i++;
X case 'k': i++;
X case 'l': i++;
X case 'j': i++; goto out;
X };
Xout:
X *x = playerx+diroffx[i]; *y = playery+diroffy[i];
X vxy(x,y); return(i);
X }
X
X/*
X * dirpoly(spnum) Routine to ask for a direction and polymorph a monst
X * int spnum;
X *
X * Subroutine to polymorph a monster and ask for the direction its in
X * Enter with the spell number in spmun.
X * Returns no value.
X */
Xstatic dirpoly(spnum)
X int spnum;
X {
X int x,y,m;
X if (spnum<0 || spnum>=SPNUM) return; /* bad args */
X if (isconfuse()) return; /* if he is confused, he can't aim his magic */
X dirsub(&x,&y);
X if (mitem[x][y]==0)
X { lprcat(" There wasn't anything there!"); return; }
X ifblind(x,y);
X if (nospell(spnum,mitem[x][y])) { lasthx=x; lasthy=y; return; }
X# ifdef MSDOS
X do {
X m = rnd(MAXMONST+7);
X mitem[x][y] = m;
X } while ( monster[m].genocided );
X# else
X while ( monster[m = mitem[x][y] = rnd(MAXMONST+7)].genocided );
X# endif
X hitp[x][y] = monster[m].hitpoints;
X show1cell(x,y); /* show the new monster */
X }
X
X/*
X * annihilate() Routine to annihilate all monsters around player (playerx,playery)
X *
X * Gives player experience, but no dropped objects
X * Returns the experience gained from all monsters killed
X */
Xannihilate()
X {
X int i,j;
X register long k;
X register char *p;
X for (k=0, i=playerx-1; i<=playerx+1; i++)
X for (j=playery-1; j<=playery+1; j++)
X if (!vxy(&i,&j)) /* if not out of bounds */
X if (*(p= &mitem[i][j])) /* if a monster there */
X if (*p<DEMONLORD+2)
X {
X k += monster[*p].experience; *p=know[i][j] &= ~KNOWHERE;
X }
X else
X {
X lprintf("\nThe %s barely escapes being annihilated!",monster[*p].name);
X hitp[i][j] = (hitp[i][j]>>1) + 1; /* lose half hit points*/
X }
X if (k>0)
X {
X lprcat("\nYou hear loud screams of agony!"); raiseexperience((long)k);
X }
X return(k);
X }
X
X/*
X * genmonst() Function to ask for monster and genocide from game
X *
X * This is done by setting a flag in the monster[] structure
X */
Xstatic genmonst()
X {
X register int i,j;
X cursors(); lprcat("\nGenocide what monster? ");
X for (i=0; (!isalpha(i)) && (i!=' '); i=ttgetch());
X lprc(i);
X for (j=0; j<MAXMONST; j++) /* search for the monster type */
X if (monstnamelist[j]==i) /* have we found it? */
X {
X monster[j].genocided=1; /* genocided from game */
X lprintf(" There will be no more %s's",monster[j].name);
X /* now wipe out monsters on this level */
X newcavelevel(level); draws(0,MAXX,0,MAXY); bot_linex();
X return;
X }
X lprcat(" You sense failure!");
X }
END_OF_FILE
if test 27345 -ne `wc -c <'spells.c'`; then
echo shar: \"'spells.c'\" unpacked with wrong size!
fi
# end of 'spells.c'
fi
echo shar: End of archive 11 \(of 17\).
cp /dev/null ark11isdone
#!/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 12 (of 17)."
# Contents: larn.maz
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:54 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'larn.maz' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn.maz'\"
else
echo shar: Extracting \"'larn.maz'\" \(27768 characters\)
sed "s/^X//" >'larn.maz' <<'END_OF_FILE'
XD###################################################################
X# # . # # # # # . #
X# D D . . D . #
X###D########################################## # # ###D###
X# -# #. # # ################ . .#
X# ####### ######## ############ D #### # # #
X# ... #.# # # # . # # # #### # ############ # ###D###
X# #.# # # ## # # # ############ #### # #- # # # #. #
X# . # # # # ## #- # # # - D #### # # . D # #.# # ... #
X# # #.# # # # # # . . # # # # # # #-# # ~.! #
X###D### ### #######D## # ############ ###### ########## ### #######
X# # @ .# # ..... ...#
X###D###########################################################D###
X# . #.....# # # # -# # # # # #
X# ..... . D D D D. #
X# #.....# # # # # # .# # # #
X###################################################################
X
X###################################################################
X#.. . D # . # #- #
X############# ######### # ## ### ##### ## #### ###### ####### ### #
X#.#!#~# # # .-# # #- # # # # -# # # #
X# # #.# . # ####### # # # # # # # # # #####
X# # ..# ##### # # # #### # ## ## ## # ###### ####### # #
X# - ..D # D # . D # # # #.##### ## ## # #. #.# #..# # ### #
X####### ####### ### # # # # # # D # D D #..D # #
X#- # # # #### # ###### # ## # #. # #..# #####
X### #######################- # # # ###################### # #
X# ... # . #..# ### # - .. . #. ### #
X# # # # ### #################### # # #
X# ### #
X################################################################# #
X#- D ### # # # #
X# . # # # D #
X###################################################################
X
X###################################################################
X# .. #
X# ############## ############################################## # #
X# # # # # .. # # #
X# #D## # # ############D################# ########### # # #
X######### #- # # # #- D # # ~ # # # # # # #
X# # # # # # # ### # # # D - # # ####### # # # #
X# .... # #### # # # #!# # # ###### .. #.# # # # # # #
X# .... # # # # ### # # # # #########D#### # ### # # # # #
X# .... ######## # # D # #- # #.. # ...#.# # #.# # # # # #
X# # # ### # #### #.- D - #.# #.#.# # # # # #
X#####DD## ######## # # D D. # # # #...# # # # # #
X# # ..# # # # ############################## # ##### # # # # #
X# ......# # # # # # # # # #
X# ####### ###### ################################ ######### # ### #
X# .D. # #
X###################################################################
X
X###################################################################
X# ## ## ### ## #
X# ##### ## ..- ## ##.## ## #
X# # ! ## ## . ## ## .## .. ## #
X# #....###### ## ## ## . ## ## #
X# # - # ## ##D# ## . ## ## #
X# #####D ~ ####### ###........ ## ... ## ## #
X# # # ## ## .... ## . ## ## #
X# #. ######## ## ## . - ####D#### - #
X# #.- #...## ## ... ## ### ...... ## ## #
X# #. #..## ## ######### ## ... ## ### ## .. #
X# #.. #.## ## ## - ## . #### ## ## ##### ## #
X# #####D## ## ## ###### ## ## ####### ## #
X# D -.## #### ######## ##DD## ######## #D #
X# ###### ... ## ########## ## #
X#### . . ###
X###################################################################
X
X###################################################################
X# #
X# ####.########################################## ## ##########
X# # #.#.#.# #.. #. # # #
X####### # # # # # ##### #! # ########### # ### #
X# # # # # # # ##...## # # # # # #-# #
X# ..- D # # # # # ## . ## ####D##### .. ### # # # #
X# # # # ##. ~ .## # # ### # # ##### # #
X############ # # # # ## . . .## #...# .. #.# # # # #
X# .. .# # # # # ## - ## # # D.D # ######### #
X# . D # # # # ##.......## ####D#####.# # #
X# - . # # # # # ## ## # . # ### ########### #
X############ #.#.# # ###D### # . #....# # #
X# # #-# D .. # .# ###....## ##-### #
X#### ########################################## ###### ### #
X# . #
X###################################################################
X
X###################################################################
X# #
X# ###########################D####### ## #
X# ####################### # ##...... ## ## #
X# ########D###### # # !##.... ## ## #
X# ############ ## ## ... # # #...## ~ ## ###### #
X# # # # # ...... # # # .. ##### ## #
X# # - .. # # # ########### # # . ######### ## #
X# ##### ##### # # # # #... ## ## #
X# # # ########## ######## ########DD#### ####### #
X# # # .... # # # # # ## ## #
X# ##### # # ....# # ######### # # ##### ## #
X# #- ######D##########..# # ######### # - #.. ## ## #
X# ##### # # # #... #.....## #
X# # ################### ###############... #### # ######
X# # #
X###################################################################
X
X###################################################################
X# #
X########### ##### ##### #####D#### ##### ###### #
X#.. # #-..D ###### ## # ## # ## ..## ### #### #
X# #### ### ##### # ## # ##### # ## ### ## # # #
X# # # # # # ##### # ## # # #### # #..##### - ### #
X# # # ####### ### #...# # ######## # # #~. .... # #
X# # # # #...# # # ######### ############## #
X# # ###### ####### # ### ### # .. # #
X# # # - # #-#####!# # # #### ## #### # #
X# ###### # ########## #.. ....# # ######## # # # ## ## #
X# -.# ##### ####...## # . .# #..# # ## # #
X# #### ###### #.### #####.#### #### ### ## # #
X# #- #######....#### ...... #.# . # ## # #
X# ####### ##### ###########.############### ### #
X# . #
X###################################################################
X
X###################################################################
X# # #- . # # # # # # # # #
X# # # #####.##### # # # # # # # # # # ###########D########### #
X# # ##### # # ### # # # # # # # # # ### #.... # # # #
X# # # # # # # # # # # # # # #.!. -.. #.##.# # #
X# # . - # # ####### # # # # # # # # # ########## ## # #
X#.####### # # D # . # # #
X#. -# ################################################### #
X# ##### D. . #
X# # ### ###D### ### ### ###D### ### ### ###D### ###.### #
X# # ###### ### .# .# #. # # # # # # # # . # #
X# ### # -# ### .#. - .# # # #...- # # .. # # -..# # . # #
X# # # ### #. ~ .# # # # # # # # .. .# # # #
X#.###### # ### # # #.....# # # # # # # # # #
X# # ####### ####### ####### ####### ####### ####### ####### #
X# # ... .. #
X###################################################################
X
X###################################################################
X# # . # ### # # # # . #
X# D D . # . D . #
X############################################### # # ###D###
X# -# #. # # ################ . .#
X# #######D######## ############ # #### # # #
X# ... #. # #!~ . # # # #--# # ############ #####D###
X# #.# # # ## # # # ############ #--# # #- # # # #. #
X# . # #-# # ## #- # # # - D ## # # # . D #### #.# # ... #
X# # #-# # # # # # . . # # # # # # #-# # -.- #
X###D### ### ####### ## # ############ ###### ########## ### ###D###
X# # @ . ..... ...#
X##################################### ###############D###
X# . #.....# # # # -# # # # #
X# ..... . D D D D. #
X# #.....# # # # # .# # # #
X###################################################################
X
X###################################################################
X#.. . # D . #- #
X### ######### ######### # ## ### ##### ## ########### ####### ### #
X#.# # # # .-# # #- # # # # -# # # #
X# # #.# . # ####### # # # # # # # # # #####
X# # ..####### # # # #### # ## ## ##!# ###### ####### # #
X# - ..D # D # . D # # # #.##### ## ## # #. #.# #..# # ### #
X####### ####### ### # # # # # # D # D D #..D # #
X#- # # # #### # ###### # ## # #. # #..# #####
X### #######################- # # # ###################### # #
X# ... # . #..# ### # - .. . #. ### #
X# # # # #-# #################### # # #
X# # -# #
X################################-################################ #
X#-..... # ####D ### # # # #
X#~..... # # # # D #
X###################################################################
X
X###################################################################
X# .. #
X# ############## ############################################## # #
X# # # # # .. # # #
X# #D## # # ############D################# ########### # # #
X######### #- # # # #- D # #.!..# # # # # # #
X# # # # # # # # ### ## # #....D - # # ####### # # # #
X# .... # #### # # # #~# # # ###### .. #.# # # # # # #
X###....## # # # ###.# # # #########D## # # ### # # # # #
X# .... ######## # # D .# #- # .. # ...#.# # #.# # # # # #
X# # ## # ### .# #### .- D - #.# #.#.# # # # # #
X#####DD## ######## #... .# . # # # #.#. # # # # #
X# # ..# # # ############################## # # ##### # # # #
X# ......# # # # # # # # # # #
X# ####### ###### ################################D# ######### ### #
X# .D. #-.-#
X###################################################################
X
X###################################################################
X# ## ## ## ## ## #
X# ############## ## ..- ## ## . ## ## #
X# # # ## ## . ## ## . ##.. ## #
X# #....###### ## ## ######## ####### . ## ## #
X# # - # ## ## ##D# ## . ## ## #
X# # D###### ###........ ## ... ## ###### #
X# # # ## ## .... ## . ## ## - # #
X# #. ######## ## ## . - ####D####.. D #
X# #.- #...## ## ... ## ### ...... ## ##### #
X# #. #..## ## ######### ## ... ## ### ## .. #
X# #.. #.## ## ## - ## . #### ## ## ##### ## #
X# #####D####### # ## ## ##..## ## ## ## ## ## #
X# D -.## # # #### ##.-.-## ##DD## ### #### ## #
X# ######. ...# #### ## #### ##### ## ##D#
X####~!.... D . . #
X###################################################################
X
X###################################################################
X# #
X# ####.########################################## ## ##########
X# # #.#.#.# #.. . # # #
X####### # # # # # ############# # ########### # ### #
X# # # # # # # --##...##-- # # # # #-# #
X# ..- D # # # # # #-## . ##-# ####D##### .. ### # # # #
X# # # # ###. .### # ~ # ### ### ##### # #
X############ # # # # ## . . .## #...# .. #.# # #
X# .. .# # # # # ## - ## # # D. # ######### #
X# . D # # # # ###.......### ####D#####.# # #
X# - . # # # # # -## ##- # . ### ########### #
X############ #.#.# # ######D###### # . ....# # #
X# #!#-# # .. # . ###....## ##-### #
X#### ############################## ########## ###### ### #
X# D . #
X###################################################################
X
X###################################################################
X# #
X# ###############D####################D# #
X# ####################### # ##...... # #
X# ########D###### # # ##.... # #
X# ############### ## ## ... # # #...## ##### #
X# # ~ # # #!...... # # # .. ##### # #
X# # - .. # # # ########### # # . ######### # #
X# ##### ######## # # # # # #... ## # #
X# # # # ########## ######## ########D #### ###### #
X# # # ....# # # # # # ## # #
X# ##### # ###### # ....# # ######### # # #####D# #
X# #- ## # #######..# # ######### # - #.. #
X# ##### # # # #... #..... #
X# # ################### ###############... #### ######
X# # #
X###################################################################
X
X###################################################################
X# # #
X########### ##### # #####D#### ##### ###### #
X#.. # #~..D ###### ## # ## # ## ..## ### #### #
X# #### ### ##### # ## # ##### # ## ### ## # # #
X# # # # # # ##### # ## # # #### # #..##### - ### #
X# # # ####### ### #...# # ######## # # #!. .... # #
X# # # # #...# # # ######### ############## #
X# # ###### ####### # ### ### # .. # #
X# # # - # #- # # # ######## #### # #
X# # # ########## #.. ....# # ######## # ## ## #
X# # -. ##### ####...## # . .# .. # # #
X# # ###### ##### #####.#### ####### # #
X# # - #######....#### ...... #.# . # ## # #
X# ######### ##### ###########.############### ### #
X# . #
X###################################################################
X
X###################################################################
X# D D #-..........# # # # # #
X#D#D# #####.#####.# # # # # # #############D########### #
X# # ##### #.#~###.# # # # # # ### .... # # # #
X#D# # #.......# # # # # # # . . -.. #. #.# # #
X# # . - # #.####### # # # # # ################## # #
X#D####### #. # D # . # # #
X#. D D -# ################################################### #
X# ###### . . #
X# # D ### ###D### ####### ###D### ####### ###D### ####### #
X# # ###### # # .# .# #. # # # # # # # # . # #
X# ### -# # # .#. - .# # # #...- # # .. # # -..# # . # #
X#DD# # # # #. .# # # # # # # # .. .# # # #
X#.###### # # # # #.....# # # # # # ! # # # #
X# # ####### ####### ### ### ####### ### ### ####### ### ### #
X# # ... .. #
X###################################################################
X
X###################################################################
X# D ## ## ## ## # # #
X# - . # ####### ## -.- ## ## ## #### D #
X#### # #.#-#.# .#. # .## ## # ####### . ### # #
X# # - ##-#.#D ### # ..## ## ##D ### ### ### ##### #
X# . # # # #.# .#. #- ##...##..###### # # # # # #
X# #### ####### ### -## ##--######## #### # -.D #
X# # # # ######D############# ########### # #
X#####D# ########### D D # # # .##D## #
X# # # # # #### # #####D############ ###- D ## ####
X# ##### ####### # #!.#-# # # . D ## # # .# #~.#
X# # # # # #..#####.# # ### # ## ##D###### #..#
X##### # D #.# # - # # # ### ##### # # .# # ##.##..#
X# . # # # # #D## # ####### . # .## .D ## # #
X##### # ####### # # # ### # # ## # -# # D #
X# # # ########### # ### ##### # #
X###################################################################
X
X###################################################################
X# # # # #
X# # D # ######### #########################.#### #
X#####.# # # ####D#### # #.#.#.# # #
X# # # # # ##### # # # # # #D# # # # # # #######
X# # ##### # #...# # . # - # # ## ## # # # # # # . #
X# # ## # - # D.#~#-# # # # ##...## # # # # # D..! #
X# #### ### ###.. #.####D#### # ## ## # # # # # # . #
X# # # # #####.# # # # #. - .# D D D D ############
X# ## # ## # # . # # ## ## # # # # #. .. #
X# ######.### # ## ## # # # ## ## # # # # D . #
X# ## # ## ##..##D#### # ## ## # # # # # . - #
X# #. # #D## ## ## # # #. ### # #.#.# # ############
X# ### ### #### # #-. # #-# # D #
X# # #. # ### # # - # ########D#################### . ####
X# # # # # # # # D #
X###################################################################
X
X###################################################################
X# # - # ## ### # #
X# ## # ################## # ## #### # ##### #D### #
X# . # # # ##### D # # - # .. # # #
X# #### # # ###D### - # -- . D D # ### # # # #
X# ### # ## ## # ###### #### # # # # # # #
X### #### ## ##### # ###### ### # # # # #
X# # ########- ## ## # # ############################## #
X# # ### ## ## ### D . #
X# # ## #### ## ##!# # ###D### ####### ###D### ####### ###D### #
X# # ## ## .###..##### # # #..~..# # # # # # . # #
X###D#D### ##..#..## # # .- .# # . # # .. # # -..# # . # #
X# # # ##...## - # # . .# # # # # # .. .# # # #
X# . # .. ###### # # .# #. # # # # # # # #
X# D ######### # ####### ###D### ####### ###D### ####### #
X# # # D # #
X###################################################################
X
X###################################################################
X# # # # ## ## ## ## D #
X# #. # -# # # # # ####### D##...## ####### ### ###### ###### #
X# # # ## ## #! .##.# ## ## D.# # #~.. D #
X####D###### # # .####...## ## # #######D### #######. # # .### ##
X# # # ## ####D## ## # # ## .. # #### # ##
X# ######## # ## ### ### ## ## #### ### # ## # # #
X# ######## ###### # . ## ### # # ######D############# #
X# . ## - ####### # # #
X# ####### # . ## ### ## D. #####D###########D###
X#####D##### # # ###. ### ##### ### - ## ### # # # # #
X#. -# #.# # ####### ## # # ## # # . - . D #
X#####D##### # # # ## # # ###### # # # # # #
X#- .# # # #####D###### # # . # # #### ######D###########
X##### ##### # # D # # D # # # # #### #
X# D # D # # D # # .. #
X###################################################################
X
X###################################################################
X# D ## ## ## ## # # #
X# - . # ####### ## -.- ## ## ## #### D #
X#### # #.#-#.# .#. # .## ## # ####### . ### # #
X# # - ##-#.#D ### # ..## ## ##D ### ### ### ##### #
X# . # # # #.# .#. #- ##...##..###### # # # # # #
X# #### ####### # ### -## ##--## ##### ### # -.D #
X# # # # ## ######D###### ##### ####D###### # #
X#####D# ########### D D # # ..##D## #
X# # # # # #### # #####D############ ###- D ## ####
X# ##### ####### # # .#-# # # . D ## # # .!# # #
X# # # .. # # #. #####.# # ### # ## ######### . # #
X##### # D #.#~# - # # # ### ##### # # .# # ##D##..#
X# . # # .. # # #D## # ####### . # .## .D ## # #
X##### # ####### # # # ### # # ## # -# # D #
X# # # # # # ### ##### # #
X###################################################################
X
X###################################################################
X# # . # # #
X# # D .!# ######### #########################.#### #
X#####.# . # # ####D#### # #.#.#.# # #
X# # #.. # # ##### # # # # ## #D# ## # # # # # ###D###
X# # ##### # #. # # . # - # # #- ## ## -# # # # # # # . #
X# # ## # - # D.# #-# # # # ##...## # # # # # #..! #
X# #### ### ###. #.######### # ## ## # # # # # # . #
X# # # #~#####.# # # D #. - .# # D D D ############
X# ## # .## # # . # # ## ## # # # # #. .. #
X# ######.### #...## #.. # # # ## ## # # # # D . #
X# ## #..## #####D#### # # ## ## # # # # # # . - #
X# #. # #D## # # # #.## ### ## #.#.# # ############
X# ### ### #### # #-. # #-# # D #
X# # #. # ### # # - # ############################# . ####
X# # # # # # # # D #
X###################################################################
X
X###################################################################
X# # - # # # ### # #
X# ## # ################## # # # #### # ##### #D### #
X# . # # # ##### D # - # .. # # #
X# #### # # ###D##### - # -- . D D # ### # # # #
X# ### # ## ## D # ##### #### # # # # # # #
X### #### ## ##### # ##### ### # # # # #
X# # ########- ## ## # # ############################## #
X# # ###~.## ## ### D . #
X# # ##..#### ## ## # # ###D### ####### ###D### ####### ###D### #
X# #. ## ## .###. ##### # # #. .# # # # # #.....# #
X##D##D### ##. #. ## # # .- .# # . # # .. # # -..# #.....# #
X# # # ##. ## - # # . .# # # # # # .. .# # # #
X# . # .. ###### .. # # .# #. # # # # # # ! # #
X# D #########D## ####### ### ### ####### ### ### ####### #
X# # # D # #
X###################################################################
X
X###################################################################
X# # # # ## ## # # D #
X# #. # -# # # # # ####### D##...## ####### ### ###### ###### #
X# # # # # # ## ## # .. ##.# ## ## D.# # # . D #
X# . # # # .#### ### # # #######D### #######. # # .### ##
X####D###### # ## ####D## # # # # # ##. # #### # ##
X# # # ## ### #### # ## #### ### # # . # # #
X# ##### # ###### # . ## ### # # ######D############# #
X# ##### # . ## - ####### # #
X# ####### # . ## ## # D. ##D###################
X#####D##### # # ###. ### ### # # - ## # # # # # ...#
X#. -# #.# # ####### ## # # ## # . - . D ..!#
X########### # # # ## # ########### # # # # ...#
X#- .# # # #####D###### # # . # # ##D###################
X##### ##### # # D #..# D # # # # # # #
X# D # D #.~# D # # # .. #
X###################################################################
END_OF_FILE
if test 27768 -ne `wc -c <'larn.maz'`; then
echo shar: \"'larn.maz'\" unpacked with wrong size!
fi
# end of 'larn.maz'
fi
echo shar: End of archive 12 \(of 17\).
cp /dev/null ark12isdone
#!/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 13 (of 17)."
# Contents: store.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:54 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'store.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'store.c'\"
else
echo shar: Extracting \"'store.c'\" \(29004 characters\)
sed "s/^X//" >'store.c' <<'END_OF_FILE'
X/* store.c */
X/*
XThis module contains data and routines to handle buildings at the home level.
XRoutines:
X
X dnd_2hed
X dnd_hed
X dndstore The DND store main routine
X handsfull To tell the player he can carry no more
X out_of_stock To tell the player an item is out of stock
X no_gold To tell the player he has no gold
X dnditem Display DND store items
X sch_head print the school header
X oschool main school routine
X obank Larn National Bank
X obank2 5th level branch of the bank
X banktitle bank header
X ointerest accrue interest to bank account
X obanksub bank main subroutine
X otradhead trading post header
X otradepost trading post main function
X cnsitm
X olrs larn revenue service function
X*/
X
X#include "header.h"
X#include "larndefs.h"
X#include "objects.h"
X#include "player.h"
X
Xstatic int dndcount=0,dnditm=0;
X
X/* number of items in the dnd inventory table */
X#define MAXITM 83
X
X/* this is the data for the stuff in the dnd store */
Xstruct _itm itm[90] = {
X/*cost memory iven name iven arg how
X gp pointer iven[] ivenarg[] many */
X
X{ 2, 0, OLEATHER, 0, 3 },
X{ 10, 0, OSTUDLEATHER, 0, 2 },
X{ 40, 0, ORING, 0, 2 },
X{ 85, 0, OCHAIN, 0, 2 },
X{ 220, 0, OSPLINT, 0, 1 },
X{ 400, 0, OPLATE, 0, 1 },
X{ 900, 0, OPLATEARMOR, 0, 1 },
X{ 2600, 0, OSSPLATE, 0, 1 },
X{ 150, 0, OSHIELD, 0, 1 },
X
X/*cost memory iven name iven arg how
X gp pointer iven[] ivenarg[] many */
X
X{ 2, 0, ODAGGER, 0, 3 },
X{ 20, 0, OSPEAR, 0, 3 },
X{ 80, 0, OFLAIL, 0, 2 },
X{ 150, 0, OBATTLEAXE, 0, 2 },
X{ 450, 0, OLONGSWORD, 0, 2 },
X{ 1000, 0, O2SWORD, 0, 2 },
X{ 5000, 0, OSWORD, 0, 1 },
X{ 16500, 0, OLANCE, 0, 1 },
X{ 6000, 0, OSWORDofSLASHING, 0, 0 },
X{ 10000, 0, OHAMMER, 0, 0 },
X
X/*cost memory iven name iven arg how
X gp pointer iven[] ivenarg[] many */
X
X{ 150, 0, OPROTRING, 1, 1 },
X{ 85, 0, OSTRRING, 1, 1 },
X{ 120, 0, ODEXRING, 1, 1 },
X{ 120, 0, OCLEVERRING, 1, 1 },
X{ 180, 0, OENERGYRING, 0, 1 },
X{ 125, 0, ODAMRING, 0, 1 },
X{ 220, 0, OREGENRING, 0, 1 },
X{ 1000, 0, ORINGOFEXTRA, 0, 1 },
X
X{ 280, 0, OBELT, 0, 1 },
X
X{ 400, 0, OAMULET, 0, 1 },
X
X{ 6500, 0, OORBOFDRAGON, 0, 0 },
X{ 5500, 0, OSPIRITSCARAB, 0, 0 },
X{ 5000, 0, OCUBEofUNDEAD, 0, 0 },
X{ 6000, 0, ONOTHEFT, 0, 0 },
X
X{ 590, 0, OCHEST, 6, 1 },
X{ 200, 0, OBOOK, 8, 1 },
X{ 10, 0, OCOOKIE, 0, 3 },
X
X/*cost memory iven name iven arg how
X gp pointer iven[] ivenarg[] many */
X
X{ 20, potionname, OPOTION, 0, 6 },
X{ 90, potionname, OPOTION, 1, 5 },
X{ 520, potionname, OPOTION, 2, 1 },
X{ 100, potionname, OPOTION, 3, 2 },
X{ 50, potionname, OPOTION, 4, 2 },
X{ 150, potionname, OPOTION, 5, 2 },
X{ 70, potionname, OPOTION, 6, 1 },
X{ 30, potionname, OPOTION, 7, 7 },
X{ 200, potionname, OPOTION, 8, 1 },
X{ 50, potionname, OPOTION, 9, 1 },
X{ 80, potionname, OPOTION, 10, 1 },
X
X/*cost memory iven name iven arg how
X gp pointer iven[] ivenarg[] many */
X
X{ 30, potionname, OPOTION, 11, 3 },
X{ 20, potionname, OPOTION, 12, 5 },
X{ 40, potionname, OPOTION, 13, 3 },
X{ 35, potionname, OPOTION, 14, 2 },
X{ 520, potionname, OPOTION, 15, 1 },
X{ 90, potionname, OPOTION, 16, 2 },
X{ 200, potionname, OPOTION, 17, 2 },
X{ 220, potionname, OPOTION, 18, 4 },
X{ 80, potionname, OPOTION, 19, 6 },
X{ 370, potionname, OPOTION, 20, 3 },
X{ 50, potionname, OPOTION, 22, 1 },
X{ 150, potionname, OPOTION, 23, 3 },
X
X/*cost memory iven name iven arg how
X gp pointer iven[] ivenarg[] many */
X
X{ 100, scrollname, OSCROLL, 0, 2 },
X{ 125, scrollname, OSCROLL, 1, 2 },
X{ 60, scrollname, OSCROLL, 2, 4 },
X{ 10, scrollname, OSCROLL, 3, 4 },
X{ 100, scrollname, OSCROLL, 4, 3 },
X{ 200, scrollname, OSCROLL, 5, 2 },
X{ 110, scrollname, OSCROLL, 6, 1 },
X{ 500, scrollname, OSCROLL, 7, 2 },
X{ 200, scrollname, OSCROLL, 8, 2 },
X{ 250, scrollname, OSCROLL, 9, 4 },
X{ 20, scrollname, OSCROLL, 10, 5 },
X{ 30, scrollname, OSCROLL, 11, 3 },
X
X/*cost memory iven name iven arg how
X gp pointer iven[] ivenarg[] many */
X
X{ 340, scrollname, OSCROLL, 12, 1 },
X{ 340, scrollname, OSCROLL, 13, 1 },
X{ 300, scrollname, OSCROLL, 14, 2 },
X{ 400, scrollname, OSCROLL, 15, 2 },
X{ 500, scrollname, OSCROLL, 16, 2 },
X{ 1000, scrollname, OSCROLL, 17, 1 },
X{ 500, scrollname, OSCROLL, 18, 1 },
X{ 340, scrollname, OSCROLL, 19, 2 },
X{ 220, scrollname, OSCROLL, 20, 3 },
X{ 3900, scrollname, OSCROLL, 21, 0 },
X{ 610, scrollname, OSCROLL, 22, 1 },
X{ 3000, scrollname, OSCROLL, 23, 0 }
X };
X
X/*
X for the college of larn
X */
Xchar course[26]; /* the list of courses taken */
Xstatic char coursetime[] = { 10, 15, 10, 20, 10, 10, 10, 5 };
X
X/*
X function for the dnd store
X */
Xstatic dnd_2hed()
X {
X lprcat("Welcome to the Larn Thrift Shoppe. We stock many items explorers find useful\n");
X lprcat(" in their adventures. Feel free to browse to your hearts content.\n");
X lprcat("Also be advised, if you break 'em, you pay for 'em.");
X }
X
Xstatic dnd_hed()
X {
X register int i;
X for (i=dnditm; i<26+dnditm; i++) dnditem(i);
X cursor(50,18); lprcat("You have ");
X }
X
Xdndstore()
X {
X register int i;
X dnditm = 0;
X nosignal = 1; /* disable signals */
X clear(); dnd_2hed();
X if (outstanding_taxes>0)
X {
X lprcat("\n\nThe Larn Revenue Service has ordered us to not do business with tax evaders.\n"); beep();
X lprintf("They have also told us that you owe %d gp in back taxes, and as we must\n",(long)outstanding_taxes);
X lprcat("comply with the law, we cannot serve you at this time. Soo Sorry.\n");
X cursors();
X lprcat("\nPress "); standout("escape"); lprcat(" to leave: "); lflush();
X i=0;
X while (i!='\33') i=ttgetch();
X drawscreen(); nosignal = 0; /* enable signals */ return;
X }
X
X dnd_hed();
X while (1)
X {
X cursor(59,18); lprintf("%d gold pieces",(long)c[GOLD]);
X cltoeoln(); cl_dn(1,20); /* erase to eod */
X lprcat("\nEnter your transaction ["); standout("space");
X lprcat(" for more, "); standout("escape");
X lprcat(" to leave]? ");
X i=0;
X while ((i<'a' || i>'z') && (i!=' ') && (i!='\33') && (i!=12)) i=ttgetch();
X if (i==12) { clear(); dnd_2hed(); dnd_hed(); }
X else if (i=='\33')
X { drawscreen(); nosignal = 0; /* enable signals */ return; }
X else if (i==' ')
X {
X cl_dn(1,4);
X if ((dnditm += 26) >= MAXITM)
X dnditm=0;
X dnd_hed();
X }
X else
X { /* buy something */
X lprc(i); /* echo the byte */
X i += dnditm - 'a';
X if (i>=MAXITM) outofstock(); else
X if (itm[i].qty <= 0) outofstock(); else
X if (pocketfull()) handsfull(); else
X if (c[GOLD] < (long) itm[i].price * 10) nogold(); else
X {
X if (itm[i].mem != 0) *itm[i].mem[itm[i].arg] = ' ';
X c[GOLD] -= (long) itm[i].price * 10;
X itm[i].qty--; take(itm[i].obj,itm[i].arg);
X if (itm[i].qty==0) dnditem(i); nap(1001);
X }
X }
X
X }
X }
X
X/*
X function for the players hands are full
X */
Xstatic handsfull()
X { lprcat("\nYou can't carry anything more!"); lflush(); nap(2200); }
Xstatic outofstock()
X { lprcat("\nSorry, but we are out of that item."); lflush(); nap(2200); }
Xstatic nogold()
X { lprcat("\nYou don't have enough gold to pay for that!"); lflush(); nap(2200); }
X
X/*
X dnditem(index)
X
X to print the item list; used in dndstore() enter with the index into itm
X */
Xstatic dnditem(i)
X register int i;
X {
X register int j,k;
X if (i >= MAXITM) return;
X cursor( (j=(i&1)*40+1) , (k=((i%26)>>1)+5) );
X if (itm[i].qty == 0) { lprintf("%39s",""); return; }
X lprintf("%c) ",(i%26)+'a');
X if (itm[i].obj == OPOTION)
X { lprcat("potion of "); lprintf("%s",&potionname[itm[i].arg][1]); }
X else if (itm[i].obj == OSCROLL)
X { lprcat("scroll of "); lprintf("%s",&scrollname[itm[i].arg][1]); }
X else lprintf("%s",objectname[itm[i].obj]);
X cursor( j+31,k ); lprintf("%6d", (long) itm[i].price * 10);
X }
X
X
X/*
X function to display the header info for the school
X */
Xstatic sch_hed()
X {
X clear();
X lprcat("The College of Larn offers the exciting opportunity of higher education to\n");
X lprcat("all inhabitants of the caves. Here is a list of the class schedule:\n\n\n");
X lprcat("\t\t Course Name \t Time Needed\n\n");
X
X if (course[0]==0) lprcat("\t\ta) Fighters Training I 10 mobuls"); /*line 7 of crt*/
X lprc('\n');
X if (course[1]==0) lprcat("\t\tb) Fighters Training II 15 mobuls");
X lprc('\n');
X if (course[2]==0) lprcat("\t\tc) Introduction to Wizardry 10 mobuls");
X lprc('\n');
X if (course[3]==0) lprcat("\t\td) Applied Wizardry 20 mobuls");
X lprc('\n');
X if (course[4]==0) lprcat("\t\te) Behavioral Psychology 10 mobuls");
X lprc('\n');
X if (course[5]==0) lprcat("\t\tf) Faith for Today 10 mobuls");
X lprc('\n');
X if (course[6]==0) lprcat("\t\tg) Contemporary Dance 10 mobuls");
X lprc('\n');
X if (course[7]==0) lprcat("\t\th) History of Larn 5 mobuls");
X
X lprcat("\n\n\t\tAll courses cost 250 gold pieces.");
X cursor(30,18);
X lprcat("You are presently carrying ");
X }
X
Xoschool()
X {
X register int i;
X long time_used;
X nosignal = 1; /* disable signals */
X sch_hed();
X while (1)
X {
X cursor(57,18); lprintf("%d gold pieces. ",(long)c[GOLD]); cursors();
X lprcat("\nWhat is your choice ["); standout("escape");
X lprcat(" to leave] ? "); yrepcount=0;
X i=0; while ((i<'a' || i>'h') && (i!='\33') && (i!=12)) i=ttgetch();
X if (i==12) { sch_hed(); continue; }
X else if (i=='\33')
X { nosignal = 0; drawscreen(); /* enable signals */ return; }
X lprc(i);
X if (c[GOLD] < 250) nogold(); else
X if (course[i-'a'])
X { lprcat("\nSorry, but that class is filled."); nap(1000); }
X else
X if (i <= 'h')
X {
X c[GOLD] -= 250; time_used=0;
X switch(i)
X {
X case 'a': c[STRENGTH] += 2; c[CONSTITUTION]++;
X lprcat("\nYou feel stronger!");
X cl_line(16,7);
X break;
X
X case 'b': if (course[0]==0)
X {
X lprcat("\nSorry, but this class has a prerequisite of Fighters Training I");
X c[GOLD]+=250; time_used= -10000; break;
X }
X lprcat("\nYou feel much stronger!");
X cl_line(16,8);
X c[STRENGTH] += 2; c[CONSTITUTION] += 2; break;
X
X case 'c': c[INTELLIGENCE] += 2;
X lprcat("\nThe task before you now seems more attainable!");
X cl_line(16,9); break;
X
X case 'd': if (course[2]==0)
X {
X lprcat("\nSorry, but this class has a prerequisite of Introduction to Wizardry");
X c[GOLD]+=250; time_used= -10000; break;
X }
X lprcat("\nThe task before you now seems very attainable!");
X cl_line(16,10);
X c[INTELLIGENCE] += 2; break;
X
X case 'e': c[CHARISMA] += 3;
X lprcat("\nYou now feel like a born leader!");
X cl_line(16,11); break;
X
X case 'f': c[WISDOM] += 2;
X lprcat("\nYou now feel more confident that you can find the potion in time!");
X cl_line(16,12); break;
X
X case 'g': c[DEXTERITY] += 3;
X lprcat("\nYou feel like dancing!");
X cl_line(16,13); break;
X
X case 'h': c[INTELLIGENCE]++;
X lprcat("\nYour instructor told you that the Eye of Larn is rumored to be guarded\n");
X lprcat("by a platinum dragon who possesses psionic abilities. ");
X cl_line(16,14); break;
X }
X time_used += coursetime[i-'a']*100;
X if (time_used > 0)
X {
X gtime += time_used;
X course[i-'a']++; /* remember that he has taken that course */
X c[HP] = c[HPMAX]; c[SPELLS] = c[SPELLMAX]; /* he regenerated */
X
X if (c[BLINDCOUNT]) c[BLINDCOUNT]=1; /* cure blindness too! */
X if (c[CONFUSE]) c[CONFUSE]=1; /* end confusion */
X adjtime((long)time_used); /* adjust parameters for time change */
X }
X nap(1000);
X }
X }
X }
X
X/*
X * for the first national bank of Larn
X */
Xint lasttime=0; /* last time he was in bank */
Xobank()
X {
X banktitle(" Welcome to the First National Bank of Larn.");
X }
Xobank2()
X {
X banktitle("Welcome to the 5th level branch office of the First National Bank of Larn.");
X /* because we state the level in the title, clear the '?' in the
X level display at the bottom, if the user teleported.
X */
X c[TELEFLAG] = 0;
X }
Xstatic banktitle(str)
X char *str;
X {
X nosignal = 1; /* disable signals */
X clear(); lprcat(str);
X if (outstanding_taxes>0)
X {
X register int i;
X lprcat("\n\nThe Larn Revenue Service has ordered that your account be frozen until all\n"); beep();
X lprintf("levied taxes have been paid. They have also told us that you owe %d gp in\n",(long)outstanding_taxes);
X lprcat("taxes, and we must comply with them. We cannot serve you at this time. Sorry.\n");
X lprcat("We suggest you go to the LRS office and pay your taxes.\n");
X cursors();
X lprcat("\nPress "); standout("escape"); lprcat(" to leave: "); lflush();
X i=0;
X while (i!='\33') i=ttgetch();
X drawscreen(); nosignal = 0; /* enable signals */ return;
X }
X lprcat("\n\n\tGemstone\t Appraisal\t\tGemstone\t Appraisal");
X obanksub(); nosignal = 0; /* enable signals */
X drawscreen();
X }
X
X/*
X * function to put interest on your bank account
X */
Xointerest()
X {
X register int i;
X if (c[BANKACCOUNT]<0) c[BANKACCOUNT] = 0;
X else if ((c[BANKACCOUNT]>0) && (c[BANKACCOUNT]<500000))
X {
X i = (gtime-lasttime)/100; /* # mobuls elapsed */
X while ((i-- > 0) && (c[BANKACCOUNT]<500000))
X c[BANKACCOUNT] += c[BANKACCOUNT]/250;
X if (c[BANKACCOUNT]>500000) c[BANKACCOUNT]=500000; /* interest limit */
X }
X lasttime = (gtime/100)*100;
X }
X
Xstatic obanksub()
X {
X short gemorder[26]; /* the reference to screen location for each gem */
X long gemvalue[26]; /* the appraisal of the gems */
X unsigned long amt;
X register int i,k,gems_sold=0;
X
X ointerest(); /* credit any needed interest */
X
X for (k=i=0; i<26; i++)
X switch(iven[i])
X {
X case OLARNEYE: case ODIAMOND: case OEMERALD:
X case ORUBY: case OSAPPHIRE:
X
X if (iven[i]==OLARNEYE)
X {
X gemvalue[i]=250000-((gtime*7)/100)*100;
X if (gemvalue[i]<50000) gemvalue[i]=50000;
X }
X else gemvalue[i] = (255&ivenarg[i])*100;
X gemorder[i]=k;
X cursor( (k%2)*40+1 , (k>>1)+4 );
X lprintf("%c) %s",i+'a',objectname[iven[i]]);
X cursor( (k%2)*40+33 , (k>>1)+4 );
X lprintf("%5d",(long)gemvalue[i]); k++;
X break;
X
X default: /* make sure player can't sell non-existant gems */
X gemvalue[i] = 0 ;
X gemorder[i] = 0 ;
X };
X cursor(31,17); lprintf("You have %8d gold pieces in the bank.",(long)c[BANKACCOUNT]);
X cursor(40,18); lprintf("You have %8d gold pieces",(long)c[GOLD]);
X if (c[BANKACCOUNT]+c[GOLD] >= 500000)
X lprcat("\nNote: Larndom law states that only deposits under 500,000gp can earn interest.");
X while (1)
X {
X cl_dn(1,20);
X lprcat("\nYour wish? [("); standout("d"); lprcat(") deposit, (");
X standout("w"); lprcat(") withdraw, ("); standout("s");
X lprcat(") sell a stone, or "); standout("escape"); lprcat("] ");
X yrepcount=0;
X i=0; while (i!='d' && i!='w' && i!='s' && i!='\33') i=ttgetch();
X switch(i)
X {
X# ifdef MSDOS
X case 'd':
X lprcat("deposit\n");
X cltoeoln();
X lprcat("How much? "); amt = readnum((long)c[GOLD]);
X# else
X case 'd': lprcat("deposit\nHow much? "); amt = readnum((long)c[GOLD]);
X# endif
X if (amt<0) { lprcat("\nSorry, but we can't take negative gold!"); nap(2000); amt=0; } else
X if (amt>c[GOLD])
X { lprcat(" You don't have that much."); nap(2000); }
X else { c[GOLD] -= amt; c[BANKACCOUNT] += amt; }
X break;
X
X case 'w': lprcat("withdraw\nHow much? "); amt = readnum((long)c[BANKACCOUNT]);
X if (amt<0) { lprcat("\nSorry, but we don't have any negative gold!"); nap(2000); amt=0; }
X else if (amt > c[BANKACCOUNT])
X { lprcat("\nYou don't have that much in the bank!"); nap(2000); }
X else { c[GOLD] += amt; c[BANKACCOUNT] -= amt; }
X break;
X
X case 's': lprcat("\nWhich stone would you like to sell? ");
X i=0; while ((i<'a' || i>'z') && i!='*' && i!='\33')
X i=ttgetch();
X if (i=='*')
X {
X for (i=0; i<26; i++)
X {
X if (gemvalue[i])
X {
X gems_sold = TRUE ;
X c[GOLD]+=gemvalue[i]; iven[i]=0;
X gemvalue[i]=0; k = gemorder[i];
X cursor( (k%2)*40+1 , (k>>1)+4 );
X lprintf("%39s","");
X }
X }
X if (!gems_sold)
X {
X lprcat("\nYou have no gems to sell!");
X nap(2000);
X }
X }
X else if ( i != '\33' )
X {
X if (gemvalue[i=i-'a']==0)
X {
X lprintf("\nItem %c is not a gemstone!",i+'a');
X nap(2000); break;
X }
X c[GOLD]+=gemvalue[i]; iven[i]=0;
X gemvalue[i]=0; k = gemorder[i];
X cursor( (k%2)*40+1 , (k>>1)+4 ); lprintf("%39s","");
X }
X break;
X
X case '\33': return;
X };
X cursor(40,17); lprintf("%8d",(long)c[BANKACCOUNT]);
X cursor(49,18); lprintf("%8d",(long)c[GOLD]);
X }
X }
X
X/*
X function for the trading post
X */
Xstatic otradhead()
X {
X clear();
X lprcat("Welcome to the Larn Trading Post. We buy items that explorers no longer find\n");
X lprcat("useful. Since the condition of the items you bring in is not certain,\n");
X lprcat("and we incur great expense in reconditioning the items, we usually pay\n");
X lprcat("only 20% of their value were they to be new. If the items are badly\n");
X lprcat("damaged, we will pay only 10% of their new value.\n\n");
X
X lprcat("Here are the items we would be willing to buy from you:\n");
X }
X
Xstatic short tradorder[26]; /* screen locations for trading post inventory */
Xstatic otradiven()
X {
X int i,j ;
X
X /* Print user's iventory like bank */
X for (j=i=0 ; i<26 ; i++)
X if (iven[i])
X {
X cursor( (j%2)*40+1, (j>>1)+8 );
X tradorder[i] = 0 ; /* init position on screen to zero */
X switch (iven[i])
X {
X case OPOTION:
X if ( potionname[ivenarg[i]][0] != 0 )
X {
X tradorder[i] = j++ ; /* will display only if identified */
X lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X lprintf(" of%s", potionname[ivenarg[i]] );
X }
X break;
X case OSCROLL:
X if ( scrollname[ivenarg[i]][0] != 0 )
X {
X tradorder[i] = j++ ; /* will display only if identified */
X lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X lprintf(" of%s", scrollname[ivenarg[i]] );
X }
X break;
X case OLARNEYE:
X case OBOOK:
X case OSPIRITSCARAB:
X case ODIAMOND:
X case ORUBY:
X case OEMERALD:
X case OCHEST:
X case OSAPPHIRE:
X case OCUBEofUNDEAD:
X case OCOOKIE:
X case ONOTHEFT:
X tradorder[i] = j++ ; /* put on screen */
X lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X break;
X default:
X tradorder[i] = j++ ; /* put on screen */
X lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X if (ivenarg[i] > 0)
X lprintf(" +%d", (long)ivenarg[i] );
X else if (ivenarg[i] < 0)
X lprintf(" %d", (long)ivenarg[i] );
X break;
X }
X }
X else
X tradorder[i] = 0; /* make sure order array is clear */
X }
X
Xstatic cleartradiven( i )
Xint i ;
X {
X int j;
X j = tradorder[i] ;
X cursor( (j%2)*40+1, (j>>1)+8 );
X lprintf( "%39s", "" );
X tradorder[i] = 0;
X }
X
Xotradepost()
X {
X register int i,j,isub,izarg,found;
X register long value;
X
X dnditm = dndcount = 0;
X nosignal = 1; /* disable signals */
X otradhead();
X otradiven();
X
X while (1)
X {
X cl_dn(1,21);
X lprcat("\nWhat item do you want to sell to us [");
X standout("escape"); lprcat("] ? ");
X i=0;
X while ( i>'z' || i<'a' && i!=12 && i!='\33' )
X i=ttgetch();
X if (i == '\33')
X {
X recalc();
X drawscreen();
X nosignal=0; /* enable signals */
X return;
X }
X while (1) /* inner loop for simpler control */
X {
X if (i == 12)
X {
X clear();
X otradhead();
X otradiven();
X break; /* leave inner while */
X }
X
X isub = i - 'a' ;
X if (iven[isub] == 0)
X {
X lprintf("\nYou don't have item %c!",isub+'a');
X nap(2000);
X break; /* leave inner while */
X }
X if (iven[isub]==OSCROLL)
X if (scrollname[ivenarg[isub]][0]==0)
X {
X cnsitm();
X break; /* leave inner while */
X }
X if (iven[isub]==OPOTION)
X if (potionname[ivenarg[isub]][0]==0)
X {
X cnsitm();
X break; /* leave inner while */
X }
X if (iven[isub]==ODIAMOND ||
X iven[isub]==ORUBY ||
X iven[isub]==OEMERALD ||
X iven[isub]==OSAPPHIRE )
X value = 20L * (ivenarg[isub] & 255);
X else if (iven[isub]==OLARNEYE)
X {
X value = 50000 - (((gtime*7) / 100) * 20 );
X if (value < 10000)
X value = 10000;
X }
X else
X {
X /* find object in itm[] list for price info */
X found = MAXITM ;
X for (j=0; j<MAXITM; j++)
X if (itm[j].obj == iven[isub])
X {
X found = j ;
X break; /* leave for loop */
X }
X if (found == MAXITM)
X {
X lprcat("\nSo sorry, but we are not authorized to accept that item.");
X nap(2000);
X break; /* leave inner while */
X }
X if (iven[isub] == OSCROLL ||
X iven[isub] == OPOTION)
X value = 2 * (long)itm[ j + ivenarg[isub]].price ;
X else
X {
X izarg=ivenarg[isub];
X value = itm[j].price;
X /* appreciate if a +n object */
X if (izarg >= 0) value *= 2;
X while ((izarg-- > 0) && ((value=14*(67+value)/10) < 500000));
X }
X }
X /* we have now found the value of the item, and dealt with any error
X cases. Print the object's value, let the user sell it.
X */
X lprintf("\nItem (%c) is worth %d gold pieces to us. Do you want to sell it? ",i,(long)value);
X yrepcount=0;
X if (getyn()=='y')
X {
X lprcat("yes\n"); c[GOLD]+=value;
X if (c[WEAR] == isub) c[WEAR] = -1;
X if (c[WIELD] == isub) c[WIELD] = -1;
X if (c[SHIELD] == isub) c[SHIELD] = -1;
X adjustcvalues(iven[isub],ivenarg[isub]);
X iven[isub]=0;
X cleartradiven( isub );
X }
X else
X {
X lprcat("no thanks.\n");
X nap(500);
X }
X break; /* exit inner while */
X } /* end of inner while */
X } /* end of outer while */
X } /* end of routine */
X
Xstatic cnsitm()
X {
X lprcat("\nSorry, we can't accept unidentified objects.");
X nap(2000);
X }
X
X/*
X * for the Larn Revenue Service
X */
Xolrs()
X {
X register int i,first;
X unsigned long amt;
X first = nosignal = 1; /* disable signals */
X clear(); resetscroll(); cursor(1,4);
X lprcat("Welcome to the Larn Revenue Service district office. How can we help you?");
X while (1)
X {
X if (first) { first=0; goto nxt; }
X setscroll();
X cursors();
X lprcat("\n\nYour wish? [(");
X standout("p");
X lprcat(") pay taxes, or ");
X standout("escape");
X lprcat("] "); yrepcount=0;
X i=0; while (i!='p' && i!='\33') i=ttgetch();
X switch(i)
X {
X case 'p': lprcat("pay taxes\nHow much? "); amt = readnum((long)c[GOLD]);
X if (amt<0) { lprcat("\nSorry, but we can't take negative gold\n"); amt=0; } else
X if (amt>c[GOLD]) lprcat(" You don't have that much.\n");
X else c[GOLD] -= paytaxes((long)amt);
X break;
X
X case '\33': nosignal = 0; /* enable signals */
X setscroll(); drawscreen(); return;
X };
X
Xnxt: cursor(1,6);
X if (outstanding_taxes>0)
X lprintf("You presently owe %d gp in taxes. ",(long)outstanding_taxes);
X else
X lprcat("You do not owe us any taxes. ");
X cursor(1,8);
X if (c[GOLD]>0)
X lprintf("You have %6d gp. ",(long)c[GOLD]);
X else
X lprcat("You have no gold pieces. ");
X }
X }
END_OF_FILE
if test 29004 -ne `wc -c <'store.c'`; then
echo shar: \"'store.c'\" unpacked with wrong size!
fi
# end of 'store.c'
fi
echo shar: End of archive 13 \(of 17\).
cp /dev/null ark13isdone
#!/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 14 (of 17)."
# Contents: data.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:54 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'data.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'data.c'\"
else
echo shar: Extracting \"'data.c'\" \(31296 characters\)
sed "s/^X//" >'data.c' <<'END_OF_FILE'
X#include "header.h"
X#include "monsters.h"
X#include "objects.h"
X
X#define VER 12
X#define SUBVER 3
X
X/*
X class[c[LEVEL]-1] gives the correct name of the players experience level
X*/
Xstatic char aa1[] = " mighty evil master";
Xstatic char aa2[] = "apprentice demi-god";
Xstatic char aa3[] = " minor demi-god ";
Xstatic char aa4[] = " major demi-god ";
Xstatic char aa5[] = " minor deity ";
Xstatic char aa6[] = " major deity ";
Xstatic char aa7[] = " novice guardian ";
Xstatic char aa8[] = "apprentice guardian";
Xstatic char aa9[] = " The Creator ";
Xchar *class[]=
X{ " novice explorer ", "apprentice explorer", " practiced explorer",/* -3*/
X " expert explorer ", " novice adventurer", " adventurer ",/* -6*/
X "apprentice conjurer", " conjurer ", " master conjurer ",/* -9*/
X " apprentice mage ", " mage ", " experienced mage ",/* -12*/
X " master mage ", " apprentice warlord", " novice warlord ",/* -15*/
X " expert warlord ", " master warlord ", " apprentice gorgon ",/* -18*/
X " gorgon ", " practiced gorgon ", " master gorgon ",/* -21*/
X " demi-gorgon ", " evil master ", " great evil master ",/* -24*/
X aa1 , aa1 , aa1 ,/* -27*/
X aa1 , aa1 , aa1 ,/* -30*/
X aa1 , aa1 , aa1 ,/* -33*/
X aa1 , aa1 , aa1 ,/* -36*/
X aa1 , aa1 , aa1 ,/* -39*/
X aa2 , aa2 , aa2 ,/* -42*/
X aa2 , aa2 , aa2 ,/* -45*/
X aa2 , aa2 , aa2 ,/* -48*/
X aa3 , aa3 , aa3 ,/* -51*/
X aa3 , aa3 , aa3 ,/* -54*/
X aa3 , aa3 , aa3 ,/* -57*/
X aa4 , aa4 , aa4 ,/* -60*/
X aa4 , aa4 , aa4 ,/* -63*/
X aa4 , aa4 , aa4 ,/* -66*/
X aa5 , aa5 , aa5 ,/* -69*/
X aa5 , aa5 , aa5 ,/* -72*/
X aa5 , aa5 , aa5 ,/* -75*/
X aa6 , aa6 , aa6 ,/* -78*/
X aa6 , aa6 , aa6 ,/* -81*/
X aa6 , aa6 , aa6 ,/* -84*/
X aa7 , aa7 , aa7 ,/* -87*/
X aa8 , aa8 , aa8 ,/* -90*/
X aa8 , aa8 , aa8 ,/* -93*/
X " earth guardian ", " air guardian ", " fire guardian ",/* -96*/
X " water guardian ", " time guardian ", " ethereal guardian ",/* -99*/
X aa9 , aa9 , aa9 ,/* -102*/
X};
X
X/*
X table of experience needed to be a certain level of player
X skill[c[LEVEL]] is the experience required to attain the next level
X */
X#define MEG 1000000
Xlong skill[] = {
X0, 10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120, /* 1-11 */
X10240, 20480, 40960, 100000, 200000, 400000, 700000, 1*MEG, /* 12-19 */
X2*MEG,3*MEG,4*MEG,5*MEG,6*MEG,8*MEG,10*MEG, /* 20-26 */
X12*MEG,14*MEG,16*MEG,18*MEG,20*MEG,22*MEG,24*MEG,26*MEG,28*MEG, /* 27-35 */
X30*MEG,32*MEG,34*MEG,36*MEG,38*MEG,40*MEG,42*MEG,44*MEG,46*MEG, /* 36-44 */
X48*MEG,50*MEG,52*MEG,54*MEG,56*MEG,58*MEG,60*MEG,62*MEG,64*MEG, /* 45-53 */
X66*MEG,68*MEG,70*MEG,72*MEG,74*MEG,76*MEG,78*MEG,80*MEG,82*MEG, /* 54-62 */
X84*MEG,86*MEG,88*MEG,90*MEG,92*MEG,94*MEG,96*MEG,98*MEG,100*MEG, /* 63-71 */
X105*MEG,110*MEG,115*MEG,120*MEG, 125*MEG, 130*MEG, 135*MEG, 140*MEG, /* 72-79 */
X145*MEG,150*MEG,155*MEG,160*MEG, 165*MEG, 170*MEG, 175*MEG, 180*MEG, /* 80-87 */
X185*MEG,190*MEG,195*MEG,200*MEG, 210*MEG, 220*MEG, 230*MEG, 240*MEG, /* 88-95 */
X250*MEG,260*MEG,270*MEG,280*MEG, 290*MEG, 300*MEG /* 96-101*/
X};
X#undef MEG
X
Xchar *lpbuf,*lpnt,*inbuffer,*lpend; /* input/output pointers to the buffers */
X# ifdef MSDOS
XRAMBLOCK *ramblks;
XDISKBLOCK *diskblks;
X# else
Xstruct cel *cell; /* pointer to the dungeon storage */
X# endif
Xshort hitp[MAXX][MAXY]; /* monster hp on level */
Xshort iarg[MAXX][MAXY]; /* arg for the item array */
Xchar item[MAXX][MAXY]; /* objects in maze if any */
Xchar know[MAXX][MAXY]; /* 1 or 0 if here before */
Xchar mitem[MAXX][MAXY]; /* monster item array */
Xchar stealth[MAXX][MAXY]; /* 0=sleeping 1=awake monst*/
Xchar lastmonst[40]; /* this has the name of the current monster */
Xchar beenhere[MAXLEVEL+MAXVLEVEL]; /* 1 if have been on this level */
Xchar VERSION=VER; /* this is the present version # of the program */
Xchar SUBVERSION=SUBVER;
Xchar nosignal=0; /* set to 1 to disable the signals from doing anything */
Xchar predostuff=0; /* 2 means that the trap handling routines must do a
X showplayer() after a trap. 0 means don't showplayer()
X 0 - we are in create player screen
X 1 - we are in welcome screen
X 2 - we are in the normal game */
Xchar loginname[20]; /* players login name */
Xchar logname[LOGNAMESIZE]; /* players name storage for scoring */
Xchar sex=1; /* default is a man 0=woman */
Xchar boldon=1; /* 1=bold objects 0=inverse objects */
Xchar ckpflag=0; /* 1 if want checkpointing of game, 0 otherwise */
Xchar cheat=0; /* 1 if the player has fudged save file */
Xchar level=0; /* cavelevel player is on = c[CAVELEVEL] */
Xchar wizard=0; /* the wizard mode flag */
Xshort lastnum=0; /* the number of the monster last hitting player */
Xshort hitflag=0; /* flag for if player has been hit when running */
Xshort hit2flag=0; /* flag for if player has been hit when running */
Xshort hit3flag=0; /* flag for if player has been hit flush input */
Xshort playerx,playery; /* the room on the present level of the player */
Xshort lastpx,lastpy; /* 0 --- MAXX-1 or 0 --- MAXY-1 */
Xshort oldx,oldy;
Xchar prayed = 1; /* did player pray at an altar (command mode)? needs
X to be saved, but I don't want to add incompatibility
X right now. KBR 1/11/90 */
Xshort lasthx=0,lasthy=0;/* location of monster last hit by player */
Xshort nobeep=0; /* true if program is not to beep */
Xunsigned long lrandx=33601; /* the random number seed */
Xlong initialtime=0; /* time playing began */
Xlong gtime=0; /* the clock for the game */
Xlong outstanding_taxes=0; /* present tax bill from score file */
Xlong c[100],cbak[100]; /* the character description arrays */
Xint enable_scroll=0; /* constant for enabled/disabled scrolling regn */
Xchar aborted[] = " aborted";
Xstruct sphere *spheres=0; /*pointer to linked list for spheres of annihilation*/
Xchar *levelname[]=
X{ " H"," 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9","10","V1","V2","V3" };
X
Xchar original_objnamelist[]=".AT_P<_F&^+M=>_$$f*OD#~][[)))(((||||||||{?!BC}o:;,@@@@EVV))([[]]](^.[H***.^^.S.tsTLc_____________________________________________";
Xchar hacklike_objnamelist[]=".:\\_^<_{%^6|2>_55}$'+#~[[[))))))========-?!?&~~~~~****899)))[[[[[)^.[1$$$.^^.3./0\\4,____________________________________________";
Xchar objnamelist[MAXOBJECT+1];
Xchar monstnamelist[]=".BGHJKOScjtAELNQRZabhiCTYdegmvzFWflorXV.pqsyUkMwDDPxnDDuD........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,";
Xchar floorc = '.';
Xchar wallc = '#';
Xchar boldobjects = FALSE ;
Xchar auto_pickup = FALSE ;
X
X# ifdef MSDOS
X int DECRainbow, keypad;
X# endif
X
Xchar *objectname[]=
X{ 0,"a holy altar","a handsome jewel encrusted throne","the orb","a pit",
X "a staircase leading upwards","an elevator going up","a bubbling fountain",
X "a great marble statue","a teleport trap","the college of Larn",
X "a mirror","the DND store","a staircase going down","an elevator going down",
X "the bank of Larn","the 5th branch of the Bank of Larn",
X "a dead fountain","gold","an open door","a closed door",
X "a wall","The Eye of Larn","plate mail","chain mail","leather armor",
X "a sword of slashing","Bessman's flailing hammer","a sunsword",
X "a two handed sword","a spear","a dagger",
X "ring of extra regeneration","a ring of regeneration","a ring of protection",
X "an energy ring","a ring of dexterity","a ring of strength",
X "a ring of cleverness","a ring of increase damage","a belt of striking",
X "a magic scroll","a magic potion","a book","a chest",
X "an amulet of invisibility","an orb of dragon slaying",
X "a scarab of negate spirit","a cube of undead control",
X "device of theft prevention","a brilliant diamond","a ruby",
X "an enchanting emerald","a sparkling sapphire","the dungeon entrance",
X "a volcanic shaft leaning downward","the base of a volcanic shaft",
X "a battle axe","a longsword","a flail","ring mail","studded leather armor",
X "splint mail","plate armor","stainless plate armor","a lance of death",
X "an arrow trap","an arrow trap","a shield","your home",
X "gold","gold","gold","a dart trap",
X "a dart trap","a trapdoor","a trapdoor","the local trading post",
X "a teleport trap", "a massive throne",
X "a sphere of annihilation","a handsome jewel encrusted throne",
X "the Larn Revenue Service","a fortune cookie","","","","","","",
X "","","","","","","","","","","","","","","","","","","",""
X };
X
X
X/*
X * for the monster data
X *
X * array to do rnd() to create monsters <= a given level
X */
Xchar monstlevel[] = { 5, 11, 17, 22, 27, 33, 39, 42, 46, 50, 53, 56, 59 };
X
Xstruct monst monster[] = {
X/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
X----------------------------------------------------------------- */
X{ "", 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 },
X{ "bat", 1, 0, 1, 0, 0, 0, 3, 0, 1, 1 },
X{ "gnome", 1, 10, 1, 0, 0, 0, 8, 30, 2, 2 },
X{ "hobgoblin", 1, 14, 2, 0, 0, 0, 5, 25, 3, 2 },
X{ "jackal", 1, 17, 1, 0, 0, 0, 4, 0, 1, 1 },
X{ "kobold", 1, 20, 1, 0, 0, 0, 7, 10, 1, 1 },
X
X{ "orc", 2, 12, 1, 0, 0, 0, 9, 40, 4, 2 },
X{ "snake", 2, 15, 1, 0, 0, 0, 3, 0, 3, 1 },
X{ "giant centipede",2, 14, 0, 4, 0, 0, 3, 0, 1, 2 },
X{ "jaculi", 2, 20, 1, 0, 0, 0, 3, 0, 2, 1 },
X{ "troglodyte", 2, 10, 2, 0, 0, 0, 5, 80, 4, 3 },
X{ "giant ant", 2, 8, 1, 4, 0, 0, 4, 0, 5, 5 },
X
X/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
X----------------------------------------------------------------- */
X
X{ "floating eye", 3, 8, 1, 0, 0, 0, 3, 0, 5, 2 },
X{ "leprechaun", 3, 3, 0, 8, 0, 0, 3,1500, 13, 45 },
X{ "nymph", 3, 3, 0, 14, 0, 0, 9, 0, 18, 45 },
X{ "quasit", 3, 5, 3, 0, 0, 0, 3, 0, 10, 15 },
X{ "rust monster", 3, 4, 0, 1, 0, 0, 3, 0, 18, 25 },
X{ "zombie", 3, 12, 2, 0, 0, 0, 3, 0, 6, 7 },
X
X{ "assassin bug", 4, 9, 3, 0, 0, 0, 3, 0, 20, 15 },
X{ "bugbear", 4, 5, 4, 15, 0, 0, 5, 40, 20, 35 },
X{ "hell hound", 4, 5, 2, 2, 0, 0, 6, 0, 16, 35 },
X{ "ice lizard", 4, 11, 2, 10, 0, 0, 6, 50, 16, 25 },
X{ "centaur", 4, 6, 4, 0, 0, 0, 10, 40, 24, 45 },
X
X/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
X----------------------------------------------------------------- */
X
X{ "troll", 5, 4, 5, 0, 0, 0, 9, 80, 50, 300 },
X{ "yeti", 5, 6, 4, 0, 0, 0, 5, 50, 35, 100 },
X{ "white dragon", 5, 2, 4, 5, 0, 0, 16, 500, 55, 1000},
X{ "elf", 5, 8, 1, 0, 0, 0, 15, 50, 22, 35 },
X{ "gelatinous cube",5, 9, 1, 0, 0, 0, 3, 0, 22, 45 },
X
X{ "metamorph", 6, 7, 3, 0, 0, 0, 3, 0, 30, 40 },
X{ "vortex", 6, 4, 3, 0, 0, 0, 3, 0, 30, 55 },
X{ "ziller", 6, 15, 3, 0, 0, 0, 3, 0, 30, 35 },
X{ "violet fungi", 6, 12, 3, 0, 0, 0, 3, 0, 38, 100 },
X{ "wraith", 6, 3, 1, 6, 0, 0, 3, 0, 30, 325 },
X{ "forvalaka", 6, 2, 5, 0, 0, 0, 7, 0, 50, 280 },
X
X/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
X----------------------------------------------------------------- */
X
X{ "lama nobe", 7, 7, 3, 0, 0, 0, 6, 0, 35, 80 },
X{ "osequip", 7, 4, 3, 16, 0, 0, 4, 0, 35, 100 },
X{ "rothe", 7, 15, 5, 0, 0, 0, 3, 100, 50, 250 },
X{ "xorn", 7, 0, 6, 0, 0, 0, 13, 0, 60, 300 },
X{ "vampire", 7, 3, 4, 6, 0, 0, 17, 0, 50, 1000},
X{ "invisible stalker",7,3, 6, 0, 0, 0, 5, 0, 50, 350 },
X
X{ "poltergeist", 8, 1, 4, 0, 0, 0, 3, 0, 50, 450 },
X{ "disenchantress", 8, 3, 0, 9, 0, 0, 3, 0, 50, 500 },
X{ "shambling mound",8, 2, 5, 0, 0, 0, 6, 0, 45, 400 },
X{ "yellow mold", 8, 12, 4, 0, 0, 0, 3, 0, 35, 250 },
X{ "umber hulk", 8, 3, 7, 11, 0, 0, 14, 0, 65, 600 },
X
X/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
X----------------------------------------------------------------- */
X
X{ "gnome king", 9, -1, 10, 0, 0, 0, 18, 2000, 100,3000 },
X{ "mimic", 9, 5, 6, 0, 0, 0, 8, 0, 55, 99 },
X{ "water lord", 9, -10, 15, 7, 0, 0, 20, 0, 150,15000 },
X{ "bronze dragon", 9, 2, 9, 3, 0, 0, 16, 300, 80, 4000 },
X{ "green dragon", 9, 3, 8, 10, 0, 0, 15, 200, 70, 2500 },
X{ "purple worm", 9, -1, 11, 0, 0, 0, 3, 100, 120,15000 },
X{ "xvart", 9, -2, 12, 0, 0, 0, 13, 0, 90, 1000 },
X
X{ "spirit naga", 10, -20,12, 12, 0, 0, 23, 0, 95, 20000 },
X{ "silver dragon", 10, -1, 12, 3, 0, 0, 20, 700, 100,10000 },
X{ "platinum dragon",10, -5, 15, 13, 0, 0, 22, 1000, 130,24000 },
X{ "green urchin", 10, -3, 12, 0, 0, 0, 3, 0, 85, 5000 },
X{ "red dragon", 10, -2, 13, 3, 0, 0, 19, 800, 110,14000 },
X
X{ "type I demon lord", 12,-30, 18, 0, 0, 0, 20, 0, 140,50000 },
X{ "type II demon lord", 13,-30, 18, 0, 0, 0, 21, 0, 160,75000 },
X{ "type III demon lord",14,-30, 18, 0, 0, 0, 22, 0, 180,100000 },
X{ "type IV demon lord", 15,-35, 20, 0, 0, 0, 23, 0, 200,125000 },
X{ "type V demon lord", 16,-40, 22, 0, 0, 0, 24, 0, 220,150000 },
X{ "type VI demon lord", 17,-45, 24, 0, 0, 0, 25, 0, 240,175000 },
X{ "type VII demon lord",18,-70, 27, 6, 0, 0, 26, 0, 260,200000 },
X{ "demon prince", 25,-127,30, 6, 0, 0, 28, 0, 345,300000 }
X
X/* NAME LV AC DAM ATT DEF GEN INT GOLD HP EXP
X--------------------------------------------------------------------- */
X };
X
X/* name array for scrolls */
X
Xchar *scrollname[MAXSCROLL+1] = {
X"\0enchant armor",
X"\0enchant weapon",
X"\0enlightenment",
X"\0blank paper",
X"\0create monster",
X"\0create artifact",
X"\0aggravate monsters",
X"\0time warp",
X"\0teleportation",
X"\0expanded awareness",
X"\0haste monsters",
X"\0monster healing",
X"\0spirit protection",
X"\0undead protection",
X"\0stealth",
X"\0magic mapping",
X"\0hold monsters",
X"\0gem perfection",
X"\0spell extension",
X"\0identify",
X"\0remove curse",
X"\0annihilation",
X"\0pulverization",
X"\0life protection",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0zzzzzzzzzzzzzz" /* sentinel, for the sorted known objects inventory */
X };
X
X/* name array for magic potions */
Xchar *potionname[MAXPOTION+1] = {
X"\0sleep",
X"\0healing",
X"\0raise level",
X"\0increase ability",
X"\0wisdom",
X"\0strength",
X"\0raise charisma",
X"\0dizziness",
X"\0learning",
X"\0object detection",
X"\0monster detection",
X"\0forgetfulness",
X"\0water",
X"\0blindness",
X"\0confusion",
X"\0heroism",
X"\0sturdiness",
X"\0giant strength",
X"\0fire resistance",
X"\0treasure finding",
X"\0instant healing",
X" cure dianthroritis",
X"\0poison",
X"\0see invisible",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0 ",
X"\0zzzzzzzzzzzzzz" /* sentinel, for the sorted known objects inventory */
X };
X
X
X/*
X spell data
X */
Xchar spelknow[SPNUM];
Xchar splev[] = { 1, 4, 9, 14, 18, 22, 26, 29, 32, 35, 37, 37, 37, 37, 37 };
X
Xchar *spelcode[SPNUM+1]={
X "pro", "mle", "dex", "sle", "chm", "ssp",
X "web", "str", "enl", "hel", "cbl", "cre", "pha", "inv",
X "bal", "cld", "ply", "can", "has", "ckl", "vpr",
X "dry", "lit", "drl", "glo", "flo", "fgr",
X "sca", "hld", "stp", "tel", "mfi", /* 31 */
X "sph", "gen", "sum", "wtw", "alt", "per", "zzz"
X };
X
Xchar *spelname[]={
X "protection", "magic missile", "dexterity",
X "sleep", "charm monster", "sonic spear",
X
X "web", "strength", "enlightenment",
X "healing", "cure blindness", "create monster",
X "phantasmal forces", "invisibility",
X
X "fireball", "cold", "polymorph",
X "cancellation", "haste self", "cloud kill",
X "vaporize rock",
X
X "dehydration", "lightning", "drain life",
X "invulnerability", "flood", "finger of death",
X
X "scare monster", "hold monster", "time stop",
X "teleport away", "magic fire",
X
X "sphere of annihilation", "genocide", "summon demon",
X "walk through walls", "alter reality", "permanence",
X ""
X };
X
Xchar *speldescript[]={
X/* 1 */
X "generates a +2 protection field",
X "creates and hurls a magic missile equivalent to a + 1 magic arrow",
X "adds +2 to the casters dexterity",
X "causes some monsters to go to sleep",
X "some monsters may be awed at your magnificence",
X "causes your hands to emit a screeching sound toward what they point",
X/* 7 */
X "causes strands of sticky thread to entangle an enemy",
X "adds +2 to the casters strength for a short term",
X "the caster becomes aware of things around him",
X "restores some hp to the caster",
X "restores sight to one so unfortunate as to be blinded",
X "creates a monster near the caster appropriate for the location",
X "creates illusions, and if believed, monsters die",
X "the caster becomes invisible",
X/* 15 */
X "makes a ball of fire that burns on what it hits",
X "sends forth a cone of cold which freezes what it touches",
X "you can find out what this does for yourself",
X "negates the ability of a monster to use his special abilities",
X "speeds up the casters movements",
X "creates a fog of poisonous gas which kills all that is within it",
X "this changes rock to air",
X/* 22 */
X "dries up water in the immediate vicinity",
X "you finger will emit a lightning bolt when this spell is cast",
X "subtracts hit points from both you and a monster",
X "this globe helps to protect the player from physical attack",
X "this creates an avalanche of H2O to flood the immediate chamber",
X "this is a holy spell and calls upon your god to back you up",
X/* 28 */
X "terrifies the monster so that hopefully he wont hit the magic user",
X "the monster is frozen in his tracks if this is successful",
X "all movement in the caverns ceases for a limited duration",
X "moves a particular monster around in the dungeon (hopefully away from you)",
X "this causes a curtain of fire to appear all around you",
X/* 33 */
X "anything caught in this sphere is instantly killed. Warning -- dangerous",
X "eliminates a species of monster from the game -- use sparingly",
X "summons a demon who hopefully helps you out",
X "allows the player to walk through walls for a short period of time",
X "god only knows what this will do",
X "makes a character spell permanent, i. e. protection, strength, etc.",
X ""
X };
X
Xchar spelweird[MAXMONST+8][SPNUM] = {
X/* p m d s c s w s e h c c p i b c p c h c v d l d g f f s h s t m s g s w a p */
X/* r l e l h s e t n e b r h n a l l a a k p r i r l l g c l t e f p e u t l e */
X/* o e x e m p b r l l l e a v l d y n s l r y t l o o r a d p l i h n m w t r */
X
X
X/* bat */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* gnome */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* hobgoblin */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* jackal */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* kobold */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* orc */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* snake */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/*giant centipede */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* jaculi */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* troglodyte */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* giant ant */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* floating eye */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* leprechaun */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* nymph */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* quasit */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* rust monster */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* zombie */ { 0,0,0,8,0,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* assassin bug */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* bugbear */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* hell hound */ { 0,6,0,0,0,0, 12,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* ice lizard */ { 0,0,0,0,0,0, 11,0,0,0,0,0,0,0, 0,15,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* centaur */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* troll */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* yeti */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,15,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* white dragon */ { 0,0,0,0,0,0, 0,0,0,0,0,0,14,0, 0,15,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* elf */ { 0,0,0,0,0,0, 0,0,0,0,0,0,14,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/*gelatinous cube */ { 0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 0,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* metamorph */ { 0,13,0,0,0,0, 2,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* vortex */ { 0,13,0,0,0,10, 1,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* ziller */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* violet fungi */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* wraith */ { 0,0,0,8,0,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 4,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* forvalaka */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* lama nobe */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* osequip */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* rothe */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* xorn */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 4,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* vampire */ { 0,0,0,8,0,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,4,0, 0,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/*invisible staker*/ { 0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* poltergeist */ { 0,13,0,8,0,4, 1,0,0,0,0,0,0,0, 0,4,0,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* disenchantress */ { 0,0,0,8,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/*shambling mound */ { 0,0,0,0,0,10, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* yellow mold */ { 0,0,0,8,0,0, 1,0,0,0,0,0,4,0, 0,0,0,0,0,4,0, 0,0,0,0,0,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* umber hulk */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* gnome king */ { 0,7,0,0,3,0, 0,0,0,0,0,0,0,5, 0,0,9,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* mimic */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* water lord */ { 0,13,0,8,3,4, 1,0,0,0,0,0,0,0, 0,0,9,0,0,4,0, 0,0,0,0,16,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* bronze dragon */ { 0,7,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* green dragon */ { 0,7,0,0,0,0, 11,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* purple worm */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* xvart */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* spirit naga */ { 0,13,0,8,3,4, 1,0,0,0,0,0,0,5, 0,4,9,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* silver dragon */ { 0,6,0,9,0,0, 12,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/*platinum dragon */ { 0,7,0,9,0,0, 11,0,0,0,0,0,14,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* green urchin */ { 0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X/* red dragon */ { 0,6,0,0,0,0, 12,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 },
X
X/* p m d s c s w s e h c c p i b c p c h c v d l d g f f s h s t m s g s w a p */
X/* r l e l h s e t n e b r h n a l l a a k p r i r l l g c l t e f p e u t l e */
X/* o e x e m p b r l l l e a v l d y n s l r y t l o o r a d p l i h n m w t r */
X
X/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
X/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
X/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
X/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
X/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
X/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
X/* demon lord */ { 0,7,0,4,3,0, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 0,0,0,0,0, 9,0,0,0,0,0 },
X/* demon prince */ { 0,7,0,4,3,9, 1,0,0,0,0,0,14,5, 0,0,4,0,0,4,0, 4,0,0,0,4,4, 4,0,0,0,4, 9,0,0,0,0,0 }
X
X };
X
Xchar *spelmes[] = { "",
X/* 1 */ "the web had no effect on the %s",
X/* 2 */ "the %s changed shape to avoid the web",
X/* 3 */ "the %s isn't afraid of you",
X/* 4 */ "the %s isn't affected",
X/* 5 */ "the %s can see you with his infravision",
X/* 6 */ "the %s vaporizes your missile",
X/* 7 */ "your missile bounces off the %s",
X/* 8 */ "the %s doesn't sleep",
X/* 9 */ "the %s resists",
X/* 10 */ "the %s can't hear the noise",
X/* 11 */ "the %s's tail cuts it free of the web",
X/* 12 */ "the %s burns through the web",
X/* 13 */ "your missiles pass right through the %s",
X/* 14 */ "the %s sees through your illusions",
X/* 15 */ "the %s loves the cold!",
X/* 16 */ "the %s loves the water!"
X };
X
X/*
X * function to create scroll numbers with appropriate probability of
X * occurrence
X *
X * 0 - armor 1 - weapon 2 - enlightenment 3 - paper
X * 4 - create monster 5 - create item 6 - aggravate 7 - time warp
X * 8 - teleportation 9 - expanded awareness 10 - haste monst
X * 11 - heal monster 12 - spirit protection 13 - undead protection
X * 14 - stealth 15 - magic mapping 16 - hold monster
X * 17 - gem perfection 18 - spell extension 19 - identify
X * 20 - remove curse 21 - annihilation 22 - pulverization
X * 23 - life protection
X */
Xchar scprob[]= { 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3,
X 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9,
X 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14,
X 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 19, 20, 20, 20, 20, 21, 22,
X 22, 22, 23 };
X
X/*
X * function to return a potion number created with appropriate probability
X * of occurrence
X *
X * 0 - sleep 1 - healing 2 - raise level
X * 3 - increase ability 4 - gain wisdom 5 - gain strength
X * 6 - increase charisma 7 - dizziness 8 - learning
X * 9 - object detection 10 - monster detection 11 - forgetfulness
X * 12 - water 13 - blindness 14 - confusion
X * 15 - heroism 16 - sturdiness 17 - giant strength
X * 18 - fire resistance 19 - treasure finding 20 - instant healing
X * 21 - cure dianthroritis 22 - poison 23 - see invisible
X */
Xchar potprob[] = { 0, 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9,
X 10, 10, 10, 11, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19,
X 20, 20, 22, 22, 23, 23 };
X
Xchar nlpts[] = { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7 };
Xchar nch[] = { 0, 0, 0, 1, 1, 1, 2, 2, 3, 4 };
Xchar nplt[] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 4 };
Xchar ndgg[] = { 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5 };
Xchar nsw[] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3 };
END_OF_FILE
if test 31296 -ne `wc -c <'data.c'`; then
echo shar: \"'data.c'\" unpacked with wrong size!
fi
# end of 'data.c'
fi
echo shar: End of archive 14 \(of 17\).
cp /dev/null ark14isdone
#!/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 15 (of 17)."
# Contents: io.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:55 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'io.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'io.c'\"
else
echo shar: Extracting \"'io.c'\" \(33276 characters\)
sed "s/^X//" >'io.c' <<'END_OF_FILE'
X/* io.c
X *
X * setupvt100() Subroutine to set up terminal in correct mode for game
X * clearvt100() Subroutine to clean up terminal when the game is over
X * ttgetch() Routine to read in one character from the terminal
X * scbr() Function to set cbreak -echo for the terminal
X * sncbr() Function to set -cbreak echo for the terminal
X * newgame() Subroutine to save the initial time and seed rnd()
X *
X * FILE OUTPUT ROUTINES
X *
X * lprintf(format,args . . .) printf to the output buffer
X * lprint(integer) send binary integer to output buffer
X * lwrite(buf,len) write a buffer to the output buffer
X * lprcat(str) sent string to output buffer
X *
X * FILE OUTPUT MACROS (in header.h)
X *
X * lprc(character) put the character into the output buffer
X *
X * FILE INPUT ROUTINES
X *
X * long lgetc() read one character from input buffer
X * long lrint() read one integer from input buffer
X * lrfill(address,number) put input bytes into a buffer
X * char *lgetw() get a whitespace ended word from input
X * char *lgetl() get a \n or EOF ended line from input
X *
X * FILE OPEN / CLOSE ROUTINES
X *
X * lcreat(filename) create a new file for write
X * lopen(filename) open a file for read
X * lappend(filename) open for append to an existing file
X * lrclose() close the input file
X * lwclose() close output file
X * lflush() flush the output buffer
X *
X * Other Routines
X *
X * cursor(x,y) position cursor at [x,y]
X * cursors() position cursor at [1,24] (saves memory)
X * cl_line(x,y) Clear line at [1,y] and leave cursor at [x,y]
X * cl_up(x,y) Clear screen from [x,1] to current line.
X * cl_dn(x,y) Clear screen from [1,y] to end of display.
X * standout(str) Print the string in standout mode.
X * set_score_output() Called when output should be literally printed.
X ** ttputch(ch) Print one character in decoded output buffer.
X ** flush_buf() Flush buffer with decoded output.
X ** init_term() Terminal initialization -- setup termcap info
X ** char *tmcapcnv(sd,ss) Routine to convert VT100 \33's to termcap format
X * beep() Routine to emit a beep if enabled (see no-beep in .larnopts)
X *
X * Note: ** entries are available only in termcap mode.
X */
X
X#include "header.h"
X#include "larndefs.h"
X#include <ctype.h>
X#ifdef AMIGA
X#include <fcntl.h>
X#endif /* AMIGA */
X
X#ifdef SYSV /* system III or system V */
X# ifndef MSDOS
X# include <termio.h>
X# endif
X#define sgttyb termio
X#define stty(_a,_b) ioctl(_a,TCSETA,_b)
X#define gtty(_a,_b) ioctl(_a,TCGETA,_b)
X#ifndef MSDOS
Xstatic int rawflg = 0;
Xstatic char saveeof,saveeol;
X#define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\
X _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL)
X#define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL
X#endif
X#else not SYSV
X#ifdef VMS
X#include <descrip.h>
X#include <ssdef.h>
X#include <stsdef.h>
X#include <iodef.h>
X#include <ttdef.h>
X#include <tt2def.h>
X#else VMS
X#ifndef BSD
X#define CBREAK RAW /* V7 has no CBREAK */
X#endif
X#define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO)
X#define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO)
X#ifndef AMIGA
X#include <sgtty.h>
X#endif /* AMIGA */
X#endif not SYSV
X#endif VMS
X
X#ifndef NOVARARGS /* if we have varargs */
X#ifdef AMIGA
X#include <stdarg.h>
X#else
X#include <varargs.h>
X#endif AMIGA
X#else NOVARARGS /* if we don't have varargs */
Xtypedef char *va_list;
X#define va_dcl int va_alist;
X#define va_start(plist) plist = (char *) &va_alist
X#define va_end(plist)
X#define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1]
X#endif NOVARARGS
X
X#define LINBUFSIZE 128 /* size of the lgetw() and lgetl() buffer */
Xint lfd; /* output file numbers */
Xint fd; /* input file numbers */
X# ifndef AMIGA
X# ifndef MSDOS
X# ifndef VMS
Xstatic struct sgttyb ttx; /* storage for the tty modes */
X# else
Xint iochan; /* storage for the tty channel */
Xint ttx[3]; /* storage for the tty modes */
Xint cbflag; /* cbreak flag. Set when SCBRd */
X# endif VMS
X# endif MSDOS
X# endif AMIGA
Xstatic int ipoint=MAXIBUF,iepoint=MAXIBUF; /* input buffering pointers */
Xstatic char lgetwbuf[LINBUFSIZE]; /* get line (word) buffer */
X
X#ifdef MSDOS
X# include <setjmp.h>
X extern jmp_buf save_jbuf;
X extern int save_mode;
X#endif
X
X# ifdef MSDOS
X# include <fcntl.h> /* For O_BINARY */
Xstatic int (*getchfn)();
Xint getche(), kgetch();
X# endif
X
X/*
X * setupvt100() Subroutine to set up terminal in correct mode for game
X *
X * Attributes off, clear screen, set scrolling region, set tty mode
X */
Xsetupvt100()
X {
X#ifdef VMS
X struct dsc$descriptor idsc;
X register int status;
X
X idsc.dsc$a_pointer = "SYS$COMMAND";
X idsc.dsc$w_length = strlen(idsc.dsc$a_pointer);
X idsc.dsc$b_dtype = DSC$K_DTYPE_T;
X idsc.dsc$b_class = DSC$K_CLASS_S;
X status = SYS$ASSIGN(&idsc, &iochan, 0, 0);
X if (status&STS$M_SUCCESS == 0)
X exit(status);
X#endif
X lprc(T_INIT);
X clear(); setscroll(); scbr(); /* system("stty cbreak -echo"); */
X# ifdef MSDOS
X setraw();
X setcursor();
X
X /* Select normal ASCII and line drawing character sets.
X */
X if (DECRainbow)
X lprcat("\033(B\033)0");
X# endif
X }
X
X/*
X * clearvt100() Subroutine to clean up terminal when the game is over
X *
X * Attributes off, clear screen, unset scrolling region, restore tty mode
X */
Xclearvt100()
X {
X lprc(T_END);
X resetscroll(); clear(); sncbr(); /* system("stty -cbreak echo"); */
X# ifdef MSDOS
X unsetraw();
X resetcursor();
X# endif
X#ifdef VMS
X SYS$DASSGN(iochan);
X#endif
X }
X
X/*
X * ttgetch() Routine to read in one character from the terminal
X */
X
X#ifdef VMS
X
Xttgetch()
X{
X#define NIBUF 80 /* characters in the buffer. */
X static char ibuf[NIBUF];
X static int ibufi = 0;
X static int nibuf = 0;
X int status;
X int iosb[2];
X int term[2];
X
X lflush(); /* be sure output buffer is flushed */
X term[0] = 0;
X term[1] = 0;
X while (ibufi >= nibuf) {
X if (cbflag) {
X /* cbroken */
X ibufi = 0;
X/*
X status = SYS$QIOW(0, iochan, IO$_READLBLK|IO$M_TIMED,
X iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
X*/
X status = SYS$QIOW(0, iochan, IO$_READLBLK,
X iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
X if (status != SS$_NORMAL)
X continue;
X status = iosb[0] & 0xFFFF;
X if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
X continue;
X nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X if (nibuf == 0)
X {
X status = SYS$QIOW(0, iochan, IO$_READLBLK,
X iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
X if (status != SS$_NORMAL)
X continue;
X if ((iosb[0]&0xFFFF) != SS$_NORMAL)
X continue;
X nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X }
X } else {
X /* not cbroken */
X try_again:
X ibufi = 0;
X status = SYS$QIOW(0, iochan, IO$_READLBLK, iosb,
X 0, 0, ibuf, NIBUF, 0, 0, 0, 0);
X if (status != SS$_NORMAL)
X goto try_again;
X if ((iosb[0]&0xFFFF) != SS$_NORMAL)
X goto try_again;
X nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X }
X }
X if ((ibuf[ibufi]&0xFF) == '\r') /* carriage return */
X ibuf[ibufi] = '\n'; /* turns to newline */
X return (ibuf[ibufi++]&0xFF);
X}
X#else VMS
X
Xttgetch()
X {
X char byt;
X#ifdef EXTRA
X c[BYTESIN]++;
X#endif EXTRA
X lflush(); /* be sure output buffer is flushed */
X
X# ifdef AMIGA
X if((byt = AmGetch()) == '\r')
X byt = '\n';
X return byt;
X# endif AMIGA
X# ifdef MSDOS
X if ((byt = (*getchfn)()) == '\r')
X byt = '\n';
X return byt;
X# else MSDOS
X read(0,&byt,1); /* get byte from terminal */
X return(byt);
X# endif MSDOS
X }
X# endif VMS
X
X/*
X * scbr() Function to set cbreak -echo for the terminal
X *
X * like: system("stty cbreak -echo")
X */
Xscbr()
X {
X# ifdef AMIGA
X /* turn echo off */
X AmCBreak(TRUE);
X AmEcho(FALSE);
X# else
X# ifdef MSDOS
X /* Set up to use the direct console input call which may
X * read from the keypad;
X */
X getchfn = kgetch;
X# else
X# ifdef VMS
X int status;
X int iosb[2];
X
X cbflag = 1;
X status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
X ttx, sizeof(ttx), 0, 0, 0, 0);
X if (status&STS$M_SUCCESS == 0)
X exit(status);
X ttx[1] |= TT$M_NOECHO;
X ttx[2] |= TT2$M_PASTHRU;
X status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
X ttx, sizeof(ttx), 0, 0, 0, 0);
X if (status&STS$M_SUCCESS == 0)
X exit(status);
X# else
X gtty(0,&ttx); doraw(ttx); stty(0,&ttx);
X# endif VMS
X# endif MSDOS
X# endif AMIGA
X }
X
X/*
X * sncbr() Function to set -cbreak echo for the terminal
X *
X * like: system("stty -cbreak echo")
X */
Xsncbr()
X {
X# ifdef AMIGA
X AmCBreak(FALSE);
X AmEcho(TRUE);
X# else
X# ifdef MSDOS
X /* Set up to use the direct console input call with echo, getche()
X */
X getchfn = getche;
X# else
X# ifdef VMS
X int status;
X int iosb[2];
X cbflag = 0;
X status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
X ttx, sizeof(ttx), 0, 0, 0, 0);
X if (status&STS$M_SUCCESS == 0)
X exit(status);
X ttx[1] &= ~TT$M_NOECHO;
X ttx[2] &= ~TT2$M_PASTHRU;
X status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
X ttx, sizeof(ttx), 0, 0, 0, 0);
X if (status&STS$M_SUCCESS == 0)
X exit(status);
X# else
X gtty(0,&ttx); unraw(ttx); stty(0,&ttx);
X# endif VMS
X# endif MSDOS
X# endif AMIGA
X }
X
X/*
X * newgame() Subroutine to save the initial time and seed rnd()
X */
Xnewgame()
X{
X register long *p,*pe;
X for (p=c,pe=c+100; p<pe; *p++ =0);
X time(&initialtime);
X srand(initialtime);
X lcreat((char*)0); /* open buffering for output to terminal */
X}
X
X/*
X * lprintf(format,args . . .) printf to the output buffer
X * char *format;
X * ??? args . . .
X *
X * Enter with the format string in "format", as per printf() usage
X * and any needed arguments following it
X * Note: lprintf() only supports %s, %c and %d, with width modifier and left
X * or right justification.
X * No correct checking for output buffer overflow is done, but flushes
X * are done beforehand if needed.
X * Returns nothing of value.
X */
X#ifdef lint
X/*VARARGS*/
Xlprintf(str)
X char *str;
X {
X char *str2;
X str2 = str;
X str = str2; /* to make lint happy */
X }
X/*VARARGS*/
Xsprintf(str)
X char *str;
X {
X char *str2;
X str2 = str;
X str = str2; /* to make lint happy */
X }
X#else lint
X/*VARARGS*/
X#ifdef AMIGA
Xlprintf(char *fmt, ...)
X {
X#else
Xlprintf(va_alist)
Xva_dcl
X {
X register char *fmt;
X#endif AMIGA
X va_list ap; /* pointer for variable argument list */
X register char *outb,*tmpb;
X register long wide,left,cont,n; /* data for lprintf */
X char db[12]; /* %d buffer in lprintf */
X
X#ifdef AMIGA
X va_start(ap, fmt); /* initialize the var args pointer */
X#else
X va_start(ap); /* initialize the var args pointer */
X fmt = va_arg(ap, char *); /* pointer to format string */
X#endif /* AMIGA */
X if (lpnt >= lpend) lflush();
X outb = lpnt;
X for ( ; ; )
X {
X while (*fmt != '%')
X if (*fmt) *outb++ = *fmt++; else { lpnt=outb; return; }
X wide = 0; left = 1; cont=1;
X while (cont)
X switch(*(++fmt))
X {
X case 'd': n = va_arg(ap, long);
X if (n<0) { n = -n; *outb++ = '-'; if (wide) --wide; }
X tmpb = db+11; *tmpb = (char)(n % 10 + '0');
X while (n>9) *(--tmpb) = (char)((n /= 10) % 10 + '0');
X if (wide==0) while (tmpb < db+12) *outb++ = *tmpb++;
X else
X {
X wide -= db-tmpb+12;
X if (left) while (wide-- > 0) *outb++ = ' ';
X while (tmpb < db+12) *outb++ = *tmpb++;
X if (left==0) while (wide-- > 0) *outb++ = ' ';
X }
X cont=0; break;
X
X case 's': tmpb = va_arg(ap, char *);
X if (wide==0) { while (*outb++ = *tmpb++); --outb; }
X else
X {
X n = wide - strlen(tmpb);
X if (left) while (n-- > 0) *outb++ = ' ';
X while (*outb++ = *tmpb++); --outb;
X if (left==0) while (n-- > 0) *outb++ = ' ';
X }
X cont=0; break;
X
X case 'c': *outb++ = va_arg(ap, int); cont=0; break;
X
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9': wide = 10*wide + *fmt - '0'; break;
X
X case '-': left = 0; break;
X
X default: *outb++ = *fmt; cont=0; break;
X };
X fmt++;
X }
X va_end(ap);
X }
X#endif lint
X
X/*
X * lprint(long-integer) send binary integer to output buffer
X * long integer;
X *
X * +---------+---------+---------+---------+
X * | high | | | low |
X * | order | | | order |
X * | byte | | | byte |
X * +---------+---------+---------+---------+
X * 31 --- 24 23 --- 16 15 --- 8 7 --- 0
X *
X * The save order is low order first, to high order (4 bytes total)
X * and is written to be system independent.
X * No checking for output buffer overflow is done, but flushes if needed!
X * Returns nothing of value.
X */
Xlprint(x)
X register long x;
X {
X if (lpnt >= lpend) lflush();
X *lpnt++ = 255 & x; *lpnt++ = 255 & (x>>8);
X *lpnt++ = 255 & (x>>16); *lpnt++ = 255 & (x>>24);
X }
X
X/*
X * lwrite(buf,len) write a buffer to the output buffer
X * char *buf;
X * int len;
X *
X * Enter with the address and number of bytes to write out
X * Returns nothing of value
X */
Xlwrite(buf,len)
X register char *buf;
X int len;
X {
X register char *str;
X register int num2;
X if (len > 399) /* don't copy data if can just write it */
X {
X#ifdef EXTRA
X c[BYTESOUT] += len;
X#endif
X
X#ifndef VT100
X for (str=buf; len>0; --len)
X lprc(*str++);
X#else VT100
X lflush();
X write(lfd,buf,len);
X#endif VT100
X }
X else while (len)
X {
X if (lpnt >= lpend) lflush(); /* if buffer is full flush it */
X num2 = lpbuf+BUFBIG-lpnt; /* # bytes left in output buffer */
X if (num2 > len) num2=len;
X str = lpnt; len -= num2;
X while (num2--) *str++ = *buf++; /* copy in the bytes */
X lpnt = str;
X }
X }
X
X/*
X * long lgetc() Read one character from input buffer
X *
X * Returns 0 if EOF, otherwise the character
X */
Xlong lgetc()
X {
X register int i;
X
X if (ipoint != iepoint) return(inbuffer[ipoint++]);
X if (iepoint!=MAXIBUF) return(0);
X if ((i=vread(fd,inbuffer,MAXIBUF))<=0) {
X if (i!=0)
X write(1,"error reading from input file\n",30);
X iepoint = ipoint = 0;
X return(0);
X }
X ipoint=1; iepoint=i; return(*inbuffer);
X}
X
X/*
X * long lrint() Read one integer from input buffer
X *
X * +---------+---------+---------+---------+
X * | high | | | low |
X * | order | | | order |
X * | byte | | | byte |
X * +---------+---------+---------+---------+
X * 31 --- 24 23 --- 16 15 --- 8 7 --- 0
X *
X * The save order is low order first, to high order (4 bytes total)
X * Returns the int read
X */
Xlong lrint()
X {
X register unsigned long i;
X i = 255 & lgetc(); i |= (255 & lgetc()) << 8;
X i |= (255 & lgetc()) << 16; i |= (255 & lgetc()) << 24;
X return(i);
X }
X
X/*
X * lrfill(address,number) put input bytes into a buffer
X * char *address;
X * int number;
X *
X * Reads "number" bytes into the buffer pointed to by "address".
X * Returns nothing of value
X */
Xlrfill(adr,num)
X register char *adr;
X int num;
X {
X register char *pnt;
X register int num2;
X while (num)
X {
X if (iepoint == ipoint)
X {
X if (num>5) /* fast way */
X {
X if (vread(fd,adr,num) != num)
X write(2,"error reading from input file\n",30);
X num=0;
X }
X else { *adr++ = lgetc(); --num; }
X }
X else
X {
X num2 = iepoint-ipoint; /* # of bytes left in the buffer */
X if (num2 > num) num2=num;
X pnt = inbuffer+ipoint; num -= num2; ipoint += num2;
X while (num2--) *adr++ = *pnt++;
X }
X }
X }
X
X/*
X * char *lgetw() Get a whitespace ended word from input
X *
X * Returns pointer to a buffer that contains word. If EOF, returns a NULL
X */
Xchar *lgetw()
X {
X register char *lgp,cc;
X register int n=LINBUFSIZE,quote=0;
X lgp = lgetwbuf;
X do cc=lgetc(); while ((cc <= 32) && (cc > NULL)); /* eat whitespace */
X for ( ; ; --n,cc=lgetc())
X {
X if ((cc==NULL) && (lgp==lgetwbuf)) return(NULL); /* EOF */
X if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); }
X if (cc != '"') *lgp++ = cc; else quote ^= 1;
X }
X }
X
X/*
X * char *lgetl() Function to read in a line ended by newline or EOF
X *
X * Returns pointer to a buffer that contains the line. If EOF, returns NULL
X */
Xchar *lgetl()
X{
X register int i=LINBUFSIZE,ch;
X register char *str=lgetwbuf;
X for ( ; ; --i) {
X *str++ = ch = lgetc();
X if (ch == 0) {
X if (str == lgetwbuf+1)
X return(NULL); /* EOF */
X ot: *str = 0;
X return(lgetwbuf); /* line ended by EOF */
X }
X if ((ch=='\n') || (i<=1))
X goto ot; /* line ended by \n */
X }
X}
X
X/*
X * lcreat(filename) Create a new file for write
X * char *filename;
X *
X * lcreat((char*)0); means to the terminal
X * Returns -1 if error, otherwise the file descriptor opened.
X */
Xlcreat(str)
X char *str;
X {
X lpnt = lpbuf; lpend = lpbuf+BUFBIG;
X if (str==NULL) return(lfd=1);
X#ifdef AMIGA
X if ((lfd=creat(str,S_IWRITE|S_IREAD)) < 0)
X#else
X if ((lfd=creat(str,0644)) < 0)
X#endif /* AMIGA */
X {
X lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1);
X }
X# ifdef MSDOS
X setmode(lfd, O_BINARY);
X# endif
X return(lfd);
X }
X
X/*
X * lopen(filename) Open a file for read
X * char *filename;
X *
X * lopen(0) means from the terminal
X * Returns -1 if error, otherwise the file descriptor opened.
X */
Xlopen(str)
X char *str;
X {
X ipoint = iepoint = MAXIBUF;
X if (str==NULL) return(fd=0);
X if ((fd=open(str,0)) < 0)
X {
X lwclose(); lfd=1; lpnt=lpbuf; return(-1);
X }
X# ifdef MSDOS
X setmode(fd, O_BINARY);
X# endif
X return(fd);
X }
X
X/*
X * lappend(filename) Open for append to an existing file
X * char *filename;
X *
X * lappend(0) means to the terminal
X * Returns -1 if error, otherwise the file descriptor opened.
X */
Xlappend(str)
X char *str;
X {
X lpnt = lpbuf; lpend = lpbuf+BUFBIG;
X if (str==NULL) return(lfd=1);
X if ((lfd=open(str,2)) < 0)
X {
X lfd=1; return(-1);
X }
X# ifdef MSDOS
X setmode(lfd, O_BINARY);
X# endif
X lseek(lfd,0L,2); /* seek to end of file */
X return(lfd);
X }
X
X/*
X * lrclose() close the input file
X *
X * Returns nothing of value.
X */
Xlrclose()
X {
X if (fd > 0) close(fd);
X }
X
X/*
X * lwclose() close output file flushing if needed
X *
X * Returns nothing of value.
X */
Xlwclose()
X {
X lflush(); if (lfd > 2) close(lfd);
X }
X
X/*
X * lprcat(string) append a string to the output buffer
X * avoids calls to lprintf (time consuming)
X */
Xlprcat(str)
X register char *str;
X {
X register char *str2;
X if (lpnt >= lpend) lflush();
X str2 = lpnt;
X while (*str2++ = *str++);
X lpnt = str2 - 1;
X }
X
X#ifdef VT100
X/*
X * cursor(x,y) Subroutine to set the cursor position
X *
X * x and y are the cursor coordinates, and lpbuff is the output buffer where
X * escape sequence will be placed.
X */
Xstatic char *y_num[]= { "\33[","\33[","\33[2","\33[3","\33[4","\33[5","\33[6",
X "\33[7","\33[8","\33[9","\33[10","\33[11","\33[12","\33[13","\33[14",
X "\33[15","\33[16","\33[17","\33[18","\33[19","\33[20","\33[21","\33[22",
X "\33[23","\33[24" };
X
Xstatic char *x_num[]= { "H","H",";2H",";3H",";4H",";5H",";6H",";7H",";8H",";9H",
X ";10H",";11H",";12H",";13H",";14H",";15H",";16H",";17H",";18H",";19H",
X ";20H",";21H",";22H",";23H",";24H",";25H",";26H",";27H",";28H",";29H",
X ";30H",";31H",";32H",";33H",";34H",";35H",";36H",";37H",";38H",";39H",
X ";40H",";41H",";42H",";43H",";44H",";45H",";46H",";47H",";48H",";49H",
X ";50H",";51H",";52H",";53H",";54H",";55H",";56H",";57H",";58H",";59H",
X ";60H",";61H",";62H",";63H",";64H",";65H",";66H",";67H",";68H",";69H",
X ";70H",";71H",";72H",";73H",";74H",";75H",";76H",";77H",";78H",";79H",
X ";80H" };
X
Xcursor(x,y)
X int x,y;
X {
X register char *p;
X if (lpnt >= lpend) lflush();
X
X p = y_num[y]; /* get the string to print */
X while (*p) *lpnt++ = *p++; /* print the string */
X
X p = x_num[x]; /* get the string to print */
X while (*p) *lpnt++ = *p++; /* print the string */
X }
X#else VT100
X/*
X * cursor(x,y) Put cursor at specified coordinates staring at [1,1] (termcap)
X */
Xcursor (x,y)
X int x,y;
X {
X if (lpnt >= lpend) lflush ();
X
X *lpnt++ = CURSOR; *lpnt++ = x; *lpnt++ = y;
X }
X#endif VT100
X
X/*
X * Routine to position cursor at beginning of 24th line
X */
Xcursors()
X {
X cursor(1,24);
X }
X
X#ifndef VT100
X/*
X * Warning: ringing the bell is control code 7. Don't use in defines.
X * Don't change the order of these defines.
X * Also used in helpfiles. Codes used in helpfiles should be \E[1 to \E[7 with
X * obvious meanings.
X */
X
Xstatic char cap[256];
Xstatic char *CM, *CE, *CD, *CL, *SO, *SE, *AL, *DL, *TI, *TE;/* Termcap capabilities */
Xstatic char *outbuf=0; /* translated output buffer */
X
Xstatic int ttputch ();
X
X/*
X * init_term() Terminal initialization -- setup termcap info
X */
Xinit_term()
X {
X char termbuf[1024];
X char *capptr = cap+10;
X char *term;
X
X# ifdef MSDOS
X term = getenv("TERM");
X if (term == NULL)
X term = "ibmpc-mono";
X switch (tgetent(termbuf, term))
X# else
X# ifdef VMS
X term = getenv("TERM");
X if (term == NULL)
X term = getenv("TERMINAL");
X switch (tgetent(termbuf, term))
X# else
X switch (tgetent(termbuf, term = getenv("TERM")))
X# endif
X# endif
X {
X case -1:
X write(2, "Cannot open termcap file.\n", 26); exit();
X case 0:
X write(2, "Cannot find entry of ", 21);
X write(2, term, strlen (term));
X write(2, " in termcap\n", 12);
X exit();
X };
X
X CM = tgetstr("cm", &capptr); /* Cursor motion */
X CE = tgetstr("ce", &capptr); /* Clear to eoln */
X CL = tgetstr("cl", &capptr); /* Clear screen */
X
X/* OPTIONAL */
X AL = tgetstr("al", &capptr); /* Insert line */
X DL = tgetstr("dl", &capptr); /* Delete line */
X SO = tgetstr("so", &capptr); /* Begin standout mode */
X SE = tgetstr("se", &capptr); /* End standout mode */
X CD = tgetstr("cd", &capptr); /* Clear to end of display */
X TI = tgetstr("ti", &capptr); /* Terminal initialization */
X TE = tgetstr("te", &capptr); /* Terminal end */
X
X if (!CM) /* can't find cursor motion entry */
X {
X write(2, "Sorry, for a ",13); write(2, term, strlen(term));
X write(2, ", I can't find the cursor motion entry in termcap\n",50);
X exit();
X }
X if (!CE) /* can't find clear to end of line entry */
X {
X write(2, "Sorry, for a ",13); write(2, term, strlen(term));
X write(2,", I can't find the clear to end of line entry in termcap\n",57);
X exit();
X }
X if (!CL) /* can't find clear entire screen entry */
X {
X write(2, "Sorry, for a ",13); write(2, term, strlen(term));
X write(2, ", I can't find the clear entire screen entry in termcap\n",56);
X exit();
X }
X if ((outbuf=(char *)malloc(BUFBIG+16))==0) /* get memory for decoded output buffer*/
X {
X write(2,"Error malloc'ing memory for decoded output buffer\n",50);
X died(-285); /* malloc() failure */
X }
X }
X#endif VT100
X
X/*
X * cl_line(x,y) Clear the whole line indicated by 'y' and leave cursor at [x,y]
X */
Xcl_line(x,y)
X int x,y;
X {
X#ifdef VT100
X cursor(x,y); lprcat("\33[2K");
X#else VT100
X cursor(1,y); *lpnt++ = CL_LINE; cursor(x,y);
X#endif VT100
X }
X
X/*
X * cl_up(x,y) Clear screen from [x,1] to current position. Leave cursor at [x,y]
X */
Xcl_up(x,y)
X register int x,y;
X {
X#ifdef VT100
X cursor(x,y); lprcat("\33[1J\33[2K");
X#else VT100
X register int i;
X cursor(1,1);
X for (i=1; i<=y; i++) { *lpnt++ = CL_LINE; *lpnt++ = '\n'; }
X cursor(x,y);
X#endif VT100
X }
X
X/*
X * cl_dn(x,y) Clear screen from [1,y] to end of display. Leave cursor at [x,y]
X */
Xcl_dn(x,y)
X register int x,y;
X {
X#ifdef VT100
X cursor(x,y); lprcat("\33[J\33[2K");
X#else VT100
X register int i;
X cursor(1,y);
X if (!CD)
X {
X *lpnt++ = CL_LINE;
X for (i=y; i<=24; i++) { *lpnt++ = CL_LINE; if (i!=24) *lpnt++ = '\n'; }
X cursor(x,y);
X }
X else
X *lpnt++ = CL_DOWN;
X cursor(x,y);
X#endif VT100
X }
X
X/*
X * standout(str) Print the argument string in inverse video (standout mode).
X */
Xstandout(str)
X register char *str;
X {
X#ifdef VT100
X setbold();
X while (*str)
X *lpnt++ = *str++;
X resetbold();
X#else VT100
X *lpnt++ = ST_START;
X while (*str)
X *lpnt++ = *str++;
X *lpnt++ = ST_END;
X#endif VT100
X }
X
X/*
X * set_score_output() Called when output should be literally printed.
X */
Xset_score_output()
X {
X enable_scroll = -1;
X }
X
X/*
X * lflush() Flush the output buffer
X *
X * Returns nothing of value.
X * for termcap version: Flush output in output buffer according to output
X * status as indicated by `enable_scroll'
X */
X#ifndef VT100
Xstatic int scrline=18; /* line # for wraparound instead of scrolling if no DL */
Xlflush ()
X {
X register int lpoint;
X register char *str;
X static int curx = 0;
X static int cury = 0;
X
X if ((lpoint = lpnt - lpbuf) > 0)
X {
X#ifdef EXTRA
X c[BYTESOUT] += lpoint;
X#endif
X if (enable_scroll <= -1) {
X flush_buf();
X# ifdef MSDOS
X /* Catch write errors on save files
X */
X if (write(lfd,lpbuf,lpoint) != lpoint) {
X if (save_mode)
X longjmp(save_jbuf, -1);
X else
X warn("Error writing output file\n");
X }
X# else
X# ifdef AMIGA
X if(lfd == 1)
X WriteConsole(lpbuf, lpoint);
X else
X if(write(lfd,lpbuf,lpoint) != lpoint)
X write(2,"error writing to output file\n",29);
X# else
X if (write(lfd,lpbuf,lpoint) != lpoint)
X write(2,"error writing to output file\n",29);
X# endif /* AMIGA */
X# endif
X lpnt = lpbuf; /* point back to beginning of buffer */
X return;
X }
X for (str = lpbuf; str < lpnt; str++)
X {
X if (*str>=32) { ttputch (*str); curx++; }
X else switch (*str) {
X case CLEAR: tputs (CL, 1, ttputch); curx = cury = 0;
X break;
X
X case CL_LINE: tputs (CE, 1, ttputch);
X break;
X
X case CL_DOWN: tputs (CD, 1, ttputch);
X break;
X
X case ST_START: tputs (SO, 1, ttputch);
X break;
X
X case ST_END: tputs (SE, 1, ttputch);
X break;
X
X case CURSOR: curx = *++str - 1; cury = *++str - 1;
X tputs (tgoto (CM, curx, cury), 1, ttputch);
X break;
X
X case '\n': if ((cury == 23) && enable_scroll)
X {
X if (!DL || !AL) /* wraparound or scroll? */
X {
X if (++scrline > 23) scrline=19;
X
X if (++scrline > 23) scrline=19;
X tputs (tgoto (CM, 0, scrline), 1, ttputch);
X tputs (CE, 1, ttputch);
X
X if (--scrline < 19) scrline=23;
X tputs (tgoto (CM, 0, scrline), 1, ttputch);
X tputs (CE, 1, ttputch);
X }
X else
X {
X tputs (tgoto (CM, 0, 19), 1, ttputch);
X tputs (DL, 1, ttputch);
X tputs (tgoto (CM, 0, 23), 1, ttputch);
X /* tputs (AL, 1, ttputch); */
X }
X }
X else
X {
X ttputch ('\n'); cury++;
X }
X curx = 0;
X break;
X case T_INIT:
X if (TI)
X tputs(TI, 1, ttputch);
X break;
X case T_END:
X if (TE)
X tputs(TE, 1, ttputch);
X break;
X default:
X ttputch (*str);
X curx++;
X }
X }
X }
X lpnt = lpbuf;
X flush_buf(); /* flush real output buffer now */
X }
X#else VT100
X/*
X * lflush() flush the output buffer
X *
X * Returns nothing of value.
X */
Xlflush()
X {
X register int lpoint;
X if ((lpoint = lpnt - lpbuf) > 0)
X {
X#ifdef EXTRA
X c[BYTESOUT] += lpoint;
X#endif
X if (write(lfd,lpbuf,lpoint) != lpoint)
X write(2,"error writing to output file\n",29);
X }
X lpnt = lpbuf; /* point back to beginning of buffer */
X }
X#endif VT100
X
X#ifndef VT100
Xstatic int index=0;
X/*
X * ttputch(ch) Print one character in decoded output buffer.
X */
Xstatic int ttputch(c)
Xint c;
X {
X outbuf[index++] = c;
X if (index >= BUFBIG) flush_buf();
X }
X
X/*
X * flush_buf() Flush buffer with decoded output.
X */
Xstatic flush_buf()
X {
X#ifdef AMIGA
X if(lfd == 1)
X WriteConsole(outbuf, index);
X else
X if(write(lfd,outbuf,index) != index)
X write(2,"error writing to output file\n",29);
X#else
X if (index) write(lfd, outbuf, index);
X#endif /* AMIGA */
X index = 0;
X }
X
X/*
X * char *tmcapcnv(sd,ss) Routine to convert VT100 escapes to termcap format
X *
X * Processes only the \33[#m sequence (converts . files for termcap use
X */
Xchar *tmcapcnv(sd,ss)
X register char *sd,*ss;
X {
X register int tmstate=0; /* 0=normal, 1=\33 2=[ 3=# */
X char tmdigit=0; /* the # in \33[#m */
X while (*ss)
X {
X switch(tmstate)
X {
X case 0: if (*ss=='\33') { tmstate++; break; }
X ign: *sd++ = *ss;
X ign2: tmstate = 0;
X break;
X case 1: if (*ss!='[') goto ign;
X tmstate++;
X break;
X case 2: if (isdigit(*ss)) { tmdigit= *ss-'0'; tmstate++; break; }
X if (*ss == 'm') { *sd++ = ST_END; goto ign2; }
X goto ign;
X case 3: if (*ss == 'm')
X {
X if (tmdigit) *sd++ = ST_START;
X else *sd++ = ST_END;
X goto ign2;
X }
X default: goto ign;
X };
X ss++;
X }
X *sd=0; /* NULL terminator */
X return(sd);
X }
X#endif VT100
X
X/*
X * beep() Routine to emit a beep if enabled (see no-beep in .larnopts)
X */
Xbeep() {
X if (!nobeep) *lpnt++ = '\7';
X }
END_OF_FILE
if test 33276 -ne `wc -c <'io.c'`; then
echo shar: \"'io.c'\" unpacked with wrong size!
fi
# end of 'io.c'
fi
echo shar: End of archive 15 \(of 17\).
cp /dev/null ark15isdone
#!/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 16 (of 17)."
# Contents: object.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:55 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'object.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'object.c'\"
else
echo shar: Extracting \"'object.c'\" \(33382 characters\)
sed "s/^X//" >'object.c' <<'END_OF_FILE'
X/* object.c */
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
X/* LOOK_FOR_OBJECT
X subroutine to look for an object and give the player his options if an object
X was found.
X*/
Xlookforobject(do_ident, do_pickup, do_action)
X char do_ident; /* identify item: T/F */
X char do_pickup; /* pickup item: T/F */
X char do_action; /* prompt for actions on object: T/F */
X{
X register int i, j;
X
X /* can't find objects if time is stopped */
X if (c[TIMESTOP])
X return;
X i = item[playerx][playery];
X if (i == 0)
X return;
X j = iarg[playerx][playery];
X showcell(playerx, playery);
X cursors();
X yrepcount = 0;
X switch (i)
X {
X case OGOLDPILE:
X case OMAXGOLD:
X case OKGOLD:
X case ODGOLD:
X lprcat("\n\nYou have found some gold!");
X ogold(i);
X break;
X
X case OPOTION:
X if (do_ident)
X {
X lprcat("\n\nYou have found a magic potion");
X if (potionname[j][0])
X lprintf(" of %s", &potionname[j][1]);
X }
X if (do_pickup)
X if (take(OPOTION, j) == 0)
X forget();
X if (do_action)
X opotion(j);
X break;
X
X case OSCROLL:
X if (do_ident)
X {
X lprcat("\n\nYou have found a magic scroll");
X if (scrollname[j][0])
X lprintf(" of %s", &scrollname[j][1]);
X }
X if (do_pickup)
X if (take(OSCROLL, j) == 0)
X forget();
X if (do_action)
X oscroll(j);
X break;
X
X case OALTAR:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a Holy Altar here!");
X if (do_action)
X oaltar();
X break;
X
X case OBOOK:
X if (do_ident)
X lprcat("\n\nYou have found a book.");
X if (do_pickup)
X if (take(OBOOK, j) == 0)
X forget();
X if (do_action)
X obook();
X break;
X
X case OCOOKIE:
X if (do_ident)
X lprcat("\n\nYou have found a fortune cookie.");
X if (do_pickup)
X if (take(OCOOKIE, 0) == 0)
X forget();
X if (do_action)
X ocookie();
X break;
X
X case OTHRONE:
X if (nearbymonst())
X return;
X if (do_ident)
X lprintf("\n\nThere is %s here!", objectname[i]);
X if (do_action)
X othrone(0);
X break;
X
X case OTHRONE2:
X if (nearbymonst())
X return;
X if (do_ident)
X lprintf("\n\nThere is %s here!", objectname[i]);
X if (do_action)
X othrone(1);
X break;
X
X case ODEADTHRONE:
X if (do_ident)
X lprintf("\n\nThere is %s here!", objectname[i]);
X if (do_action)
X odeadthrone();
X break;
X
X case OPIT:
X /* always perform these actions. */
X lprcat("\n\nYou're standing at the top of a pit.");
X opit();
X break;
X
X case OSTAIRSUP: /* up */
X if (do_ident)
X lprcat("\n\nThere is a circular staircase here");
X if (do_action)
X ostairs(1);
X break;
X
X case OFOUNTAIN:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a fountain here");
X if (do_action)
X ofountain();
X break;
X
X case OSTATUE:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou are standing in front of a statue");
X if (do_action)
X ostatue();
X break;
X
X case OCHEST:
X if (do_ident)
X lprcat("\n\nThere is a chest here");
X if (do_pickup)
X if (take(OCHEST, j) == 0)
X forget();
X if (do_action)
X ochest();
X break;
X
X case OSCHOOL:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou have found the College of Larn.");
X if (do_action)
X prompt_enter();
X break;
X
X case OMIRROR:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a mirror here");
X if (do_action)
X omirror();
X break;
X
X case OBANK2:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou have found a branch office of the bank of Larn.");
X if (do_action)
X prompt_enter();
X break;
X
X case OBANK:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou have found the bank of Larn.");
X if (do_action)
X prompt_enter();
X break;
X
X case ODEADFOUNTAIN:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a dead fountain here");
X break;
X
X case ODNDSTORE:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a DND store here.");
X if (do_action)
X prompt_enter();
X break;
X
X case OSTAIRSDOWN: /* down */
X if (do_ident)
X lprcat("\n\nThere is a circular staircase here");
X if (do_action)
X ostairs(-1);
X break;
X
X case OOPENDOOR:
X if (do_ident)
X lprintf("\n\nYou have found %s", objectname[i]);
X if (do_action)
X o_open_door();
X break;
X
X case OCLOSEDDOOR:
X if (do_ident)
X lprintf("\n\nYou have found %s", objectname[i]);
X if (do_action)
X o_closed_door();
X break;
X
X case OENTRANCE:
X if (do_ident)
X lprcat("\nYou have found ");
X lprcat(objectname[i]);
X if (do_action)
X prompt_enter();
X break;
X
X case OVOLDOWN:
X if (do_ident)
X lprcat("\nYou have found ");
X lprcat(objectname[i]);
X if (do_action)
X prompt_volshaft(-1);
X break;
X
X case OVOLUP:
X if (do_ident)
X lprcat("\nYou have found ");
X lprcat(objectname[i]);
X if (do_action)
X prompt_volshaft(1);
X break;
X
X case OIVTELETRAP:
X if (rnd(11) < 6)
X return;
X item[playerx][playery] = OTELEPORTER;
X know[playerx][playery] = KNOWALL;
X /* fall through to OTELEPORTER case below!!! */
X
X case OTELEPORTER:
X lprcat("\nZaaaappp! You've been teleported!\n");
X beep();
X nap(3000);
X oteleport(0);
X break;
X
X case OTRAPARROWIV: /* for an arrow trap */
X if (rnd(17) < 13)
X return;
X item[playerx][playery] = OTRAPARROW;
X know[playerx][playery] = 0;
X /* fall through to OTRAPARROW case below!!! */
X
X case OTRAPARROW:
X lprcat("\nYou are hit by an arrow");
X beep();
X lastnum = 259;
X losehp(rnd(10) + level);
X bottomhp();
X return;
X
X case OIVDARTRAP: /* for a dart trap */
X if (rnd(17) < 13)
X return;
X item[playerx][playery] = ODARTRAP;
X know[playerx][playery] = 0;
X /* fall through to ODARTTRAP case below!!! */
X
X case ODARTRAP:
X lprcat("\nYou are hit by a dart");
X beep(); /* for a dart trap */
X lastnum = 260;
X losehp(rnd(5));
X if ((--c[STRENGTH]) < 3)
X c[STRENGTH] = 3;
X bottomline();
X return;
X
X case OIVTRAPDOOR: /* for a trap door */
X if (rnd(17) < 13)
X return;
X item[playerx][playery] = OTRAPDOOR;
X know[playerx][playery] = KNOWALL;
X /* fall through to OTRAPDOOR case below!!! */
X
X case OTRAPDOOR:
X lastnum = 272; /* a trap door */
X if ((level == MAXLEVEL - 1) || (level == MAXLEVEL + MAXVLEVEL - 1))
X {
X lprcat("\nYou fell through a bottomless trap door!");
X beep();
X nap(3000);
X died(271);
X }
X i = rnd(5 + level);
X lprintf("\nYou fall through a trap door! You lose %d hit points.", (long) i);
X beep();
X losehp(i);
X nap(2000);
X newcavelevel(level + 1);
X draws(0, MAXX, 0, MAXY);
X bot_linex();
X return;
X
X case OTRADEPOST:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\nYou have found the Larn trading Post.");
X if (do_action)
X prompt_enter();
X return;
X
X case OHOME:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\nYou have found your way home.");
X if (do_action)
X prompt_enter();
X return;
X
X case OWALL:
X break;
X
X case OANNIHILATION:
X died(283); /* annihilated by sphere of annihilation */
X return;
X
X case OLRS:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is an LRS office here.");
X if (do_action)
X prompt_enter();
X break;
X
X default:
X if (do_ident)
X {
X lprintf("\n\nYou have found %s ", objectname[i]);
X switch (i)
X {
X case ODIAMOND:
X case ORUBY:
X case OEMERALD:
X case OSAPPHIRE:
X case OSPIRITSCARAB:
X case OORBOFDRAGON:
X case OCUBEofUNDEAD:
X case ONOTHEFT:
X break;
X
X default:
X if (j > 0)
X lprintf("+ %d", (long) j);
X else
X if (j < 0)
X lprintf(" %d", (long) j);
X break;
X }
X }
X if (do_pickup)
X if (take(i, j) == 0)
X forget();
X if (do_action)
X {
X char tempc = 0;
X
X lprcat("\nDo you want to (t) take it");
X iopts();
X while (tempc != 't' && tempc != 'i' && tempc != '\33')
X tempc = ttgetch();
X if (tempc == 't')
X {
X lprcat("take");
X if (take(i, j) == 0)
X forget();
X return;
X }
X ignore();
X }
X break;
X };
X}
X
X
X/*
X * subroutine to process the stair cases if dir > 0 the up else down
X */
Xstatic ostairs(dir)
X int dir;
X{
X register int k;
X lprcat("\nDo you (s) stay here ");
X if (dir > 0)
X lprcat("or (u) go up? ");
X else
X lprcat("or (d) go down? ");
X
X while (1)
X switch (ttgetch())
X {
X case '\33':
X case 's':
X case 'i':
X lprcat("stay here");
X return;
X
X case 'u':
X lprcat("go up");
X act_up_stairs();
X return;
X
X case 'd':
X lprcat("go down");
X act_down_stairs();
X return;
X };
X}
X
X
X
X/*
X * subroutine to handle a teleport trap +/- 1 level maximum
X */
Xoteleport(err)
X int err;
X{
X register int tmp;
X if (err)
X if (rnd(151) < 3)
X died(264); /* stuck in a rock */
X c[TELEFLAG] = 1; /* show ?? on bottomline if been teleported */
X if (level == 0)
X tmp = 0;
X else
X if (level < MAXLEVEL)
X {
X tmp = rnd(5) + level - 3;
X if (tmp >= MAXLEVEL)
X tmp = MAXLEVEL - 1;
X if (tmp < 1)
X tmp = 1;
X } else
X {
X tmp = rnd(3) + level - 2;
X if (tmp >= MAXLEVEL + MAXVLEVEL)
X tmp = MAXLEVEL + MAXVLEVEL - 1;
X if (tmp < MAXLEVEL)
X tmp = MAXLEVEL;
X }
X playerx = rnd(MAXX - 2);
X playery = rnd(MAXY - 2);
X if (level != tmp)
X newcavelevel(tmp);
X positionplayer();
X draws(0, MAXX, 0, MAXY);
X bot_linex();
X}
X
X
X/*
X * function to process a potion
X */
Xstatic opotion(pot)
X int pot;
X{
X lprcat("\nDo you (d) drink it, (t) take it");
X iopts();
X while (1)
X switch (ttgetch())
X {
X case '\33':
X case 'i':
X ignore();
X return;
X
X case 'd':
X lprcat("drink\n");
X forget(); /* destroy potion */
X quaffpotion(pot, TRUE);
X return;
X
X case 't':
X lprcat("take\n");
X if (take(OPOTION, pot) == 0)
X forget();
X return;
X };
X}
X
X/*
X * function to drink a potion
X *
X * Also used to perform the action of a potion without quaffing a potion (see
X * invisible capability when drinking from a fountain).
X */
Xquaffpotion(pot, set_known)
X int pot;
X int set_known;
X{
X register int i, j, k;
X
X /* check for within bounds */
X if (pot < 0 || pot >= MAXPOTION)
X return;
X
X /*
X * if player is to know this potion (really quaffing one), make it
X * known
X */
X if (set_known)
X potionname[pot][0] = ' ';
X
X switch (pot)
X {
X case 0:
X lprcat("\nYou fall asleep. . .");
X i = rnd(11) - (c[CONSTITUTION] >> 2) + 2;
X while (--i > 0)
X {
X parse2();
X nap(1000);
X }
X cursors();
X lprcat("\nYou woke up!");
X return;
X
X case 1:
X lprcat("\nYou feel better");
X if (c[HP] == c[HPMAX])
X raisemhp(1);
X else
X if ((c[HP] += rnd(20) + 20 + c[LEVEL]) > c[HPMAX])
X c[HP] = c[HPMAX];
X break;
X
X case 2:
X lprcat("\nSuddenly, you feel much more skillful!");
X raiselevel();
X raisemhp(1);
X return;
X
X case 3:
X lprcat("\nYou feel strange for a moment");
X c[rund(6)]++;
X break;
X
X case 4:
X lprcat("\nYou feel more self confident!");
X c[WISDOM] += rnd(2);
X break;
X
X case 5:
X lprcat("\nWow! You feel great!");
X if (c[STRENGTH] < 12)
X c[STRENGTH] = 12;
X else
X c[STRENGTH]++;
X break;
X
X case 6:
X lprcat("\nYour charm went up by one!");
X c[CHARISMA]++;
X break;
X
X case 7:
X lprcat("\nYou become dizzy!");
X if (--c[STRENGTH] < 3)
X c[STRENGTH] = 3;
X break;
X
X case 8:
X lprcat("\nYour intelligence went up by one!");
X c[INTELLIGENCE]++;
X break;
X
X case 9:
X lprcat("\nYou sense the presence of objects!");
X nap(1000);
X if (c[BLINDCOUNT])
X return;
X for (i = 0; i < MAXY; i++)
X for (j = 0; j < MAXX; j++)
X switch (item[j][i])
X {
X case OPLATE:
X case OCHAIN:
X case OLEATHER:
X case ORING:
X case OSTUDLEATHER:
X case OSPLINT:
X case OPLATEARMOR:
X case OSSPLATE:
X case OSHIELD:
X case OSWORDofSLASHING:
X case OHAMMER:
X case OSWORD:
X case O2SWORD:
X case OSPEAR:
X case ODAGGER:
X case OBATTLEAXE:
X case OLONGSWORD:
X case OFLAIL:
X case OLANCE:
X case ORINGOFEXTRA:
X case OREGENRING:
X case OPROTRING:
X case OENERGYRING:
X case ODEXRING:
X case OSTRRING:
X case OCLEVERRING:
X case ODAMRING:
X case OBELT:
X case OSCROLL:
X case OPOTION:
X case OBOOK:
X case OCHEST:
X case OAMULET:
X case OORBOFDRAGON:
X case OSPIRITSCARAB:
X case OCUBEofUNDEAD:
X case ONOTHEFT:
X case OCOOKIE:
X know[j][i] = HAVESEEN;
X show1cell(j, i);
X break;
X }
X showplayer();
X return;
X
X case 10: /* monster detection */
X lprcat("\nYou detect the presence of monsters!");
X nap(1000);
X if (c[BLINDCOUNT])
X return;
X for (i = 0; i < MAXY; i++)
X for (j = 0; j < MAXX; j++)
X if (mitem[j][i] && (monstnamelist[mitem[j][i]] != floorc))
X {
X know[j][i] = HAVESEEN;
X show1cell(j, i);
X }
X return;
X
X case 11:
X lprcat("\nYou stagger for a moment . .");
X for (i = 0; i < MAXY; i++)
X for (j = 0; j < MAXX; j++)
X know[j][i] = 0;
X nap(1000);
X draws(0, MAXX, 0, MAXY); /* potion of forgetfulness */
X return;
X
X case 12:
X lprcat("\nThis potion has no taste to it");
X return;
X
X case 13:
X lprcat("\nYou can't see anything!"); /* blindness */
X c[BLINDCOUNT] += 500;
X return;
X
X case 14:
X lprcat("\nYou feel confused");
X c[CONFUSE] += 20 + rnd(9);
X return;
X
X case 15:
X lprcat("\nWOW!!! You feel Super-fantastic!!!");
X if (c[HERO] == 0)
X for (i = 0; i < 6; i++)
X c[i] += 11;
X c[HERO] += 250;
X break;
X
X case 16:
X lprcat("\nYou have a greater intestinal constitude!");
X c[CONSTITUTION]++;
X break;
X
X case 17:
X lprcat("\nYou now have incredibly bulging muscles!!!");
X if (c[GIANTSTR] == 0)
X c[STREXTRA] += 21;
X c[GIANTSTR] += 700;
X break;
X
X case 18:
X lprcat("\nYou feel a chill run up your spine!");
X c[FIRERESISTANCE] += 1000;
X break;
X
X case 19:
X lprcat("\nYou feel greedy . . .");
X nap(1000);
X if (c[BLINDCOUNT])
X return;
X for (i = 0; i < MAXY; i++)
X for (j = 0; j < MAXX; j++)
X {
X k = item[j][i];
X if ((k == ODIAMOND) ||
X (k == ORUBY) ||
X (k == OEMERALD) ||
X (k == OMAXGOLD) ||
X (k == OSAPPHIRE) ||
X (k == OLARNEYE) ||
X (k == OGOLDPILE))
X {
X know[j][i] = HAVESEEN;
X show1cell(j, i);
X }
X }
X showplayer();
X return;
X
X case 20:
X c[HP] = c[HPMAX];
X break; /* instant healing */
X
X case 21:
X lprcat("\nYou don't seem to be affected");
X return; /* cure dianthroritis */
X
X case 22:
X lprcat("\nYou feel a sickness engulf you"); /* poison */
X c[HALFDAM] += 200 + rnd(200);
X return;
X
X case 23:
X lprcat("\nYou feel your vision sharpen"); /* see invisible */
X c[SEEINVISIBLE] += rnd(1000) + 400;
X monstnamelist[INVISIBLESTALKER] = 'I';
X return;
X };
X bottomline(); /* show new stats */
X return;
X}
X
X
X/*
X * function to process a magic scroll
X */
Xstatic oscroll(typ)
X int typ;
X{
X lprcat("\nDo you ");
X if (c[BLINDCOUNT] == 0)
X lprcat("(r) read it, ");
X lprcat("(t) take it");
X iopts();
X while (1)
X switch (ttgetch())
X {
X case '\33':
X case 'i':
X ignore();
X return;
X
X case 'r':
X if (c[BLINDCOUNT])
X break;
X lprcat("read");
X forget();
X if (typ == 2 || typ == 15)
X {
X show1cell(playerx, playery);
X cursors();
X }
X /* destroy it */ read_scroll(typ);
X return;
X
X case 't':
X lprcat("take");
X if (take(OSCROLL, typ) == 0)
X forget(); /* destroy it */
X return;
X };
X}
X
X/*
X * data for the function to read a scroll
X */
Xstatic int xh, yh, yl, xl;
Xstatic char curse[] = {BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
X LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT,
X HALFDAM};
Xstatic char exten[] = {PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT,
X INVISIBILITY, CANCELLATION, HASTESELF, GLOBE,
X SCAREMONST, HOLDMONST, TIMESTOP};
Xstatic char time_change[] = {HASTESELF, HERO, ALTPRO, PROTECTIONTIME, DEXCOUNT,
X STRCOUNT, GIANTSTR, CHARMCOUNT, INVISIBILITY,
X CANCELLATION,HASTESELF, AGGRAVATE, SCAREMONST,
X STEALTH, AWARENESS, HOLDMONST, HASTEMONST,
X FIRERESISTANCE, GLOBE, SPIRITPRO, UNDEADPRO,
X HALFDAM, SEEINVISIBLE, ITCHING, CLUMSINESS, WTW};
X/*
X * function to adjust time when time warping and taking courses in school
X */
Xadjtime(tim)
X register long tim;
X{
X register int j;
X for (j = 0; j < 26; j++)/* adjust time related parameters */
X if (c[time_change[j]])
X if ((c[time_change[j]] -= tim) < 1)
X c[time_change[j]] = 1;
X regen();
X}
X
X/*
X * function to read a scroll
X */
Xread_scroll(typ)
X int typ;
X{
X register int i, j;
X if (typ < 0 || typ >= MAXSCROLL)
X return; /* be sure we are within bounds */
X scrollname[typ][0] = ' ';
X switch (typ)
X {
X case 0:
X lprcat("\nYour armor glows for a moment");
X enchantarmor();
X return;
X
X case 1:
X lprcat("\nYour weapon glows for a moment");
X enchweapon();
X return; /* enchant weapon */
X
X case 2:
X lprcat("\nYou have been granted enlightenment!");
X yh = min(playery + 7, MAXY);
X xh = min(playerx + 25, MAXX);
X yl = max(playery - 7, 0);
X xl = max(playerx - 25, 0);
X for (i = yl; i < yh; i++)
X for (j = xl; j < xh; j++)
X know[j][i] = KNOWALL;
X draws(xl, xh, yl, yh);
X return;
X
X case 3:
X lprcat("\nThis scroll seems to be blank");
X return;
X
X case 4:
X createmonster(makemonst(level + 1));
X return; /* this one creates a monster */
X
X case 5:
X something(level); /* create artifact */
X return;
X
X case 6:
X c[AGGRAVATE] += 800;
X return; /* aggravate monsters */
X
X case 7:
X gtime += (i = rnd(1000) - 850); /* time warp */
X if (i >= 0)
X lprintf("\nYou went forward in time by %d mobuls", (long) ((i + 99) / 100));
X else
X lprintf("\nYou went backward in time by %d mobuls", (long) (-(i + 99) / 100));
X adjtime((long) i); /* adjust time for time warping */
X return;
X
X case 8:
X oteleport(0);
X return; /* teleportation */
X
X case 9:
X c[AWARENESS] += 1800;
X return; /* expanded awareness */
X
X case 10:
X c[HASTEMONST] += rnd(55) + 12;
X return; /* haste monster */
X
X case 11:
X for (i = 0; i < MAXY; i++)
X for (j = 0; j < MAXX; j++)
X if (mitem[j][i])
X hitp[j][i] = monster[mitem[j][i]].hitpoints;
X return; /* monster healing */
X case 12:
X c[SPIRITPRO] += 300 + rnd(200);
X bottomline();
X return; /* spirit protection */
X
X case 13:
X c[UNDEADPRO] += 300 + rnd(200);
X bottomline();
X return; /* undead protection */
X
X case 14:
X c[STEALTH] += 250 + rnd(250);
X bottomline();
X return; /* stealth */
X
X case 15:
X lprcat("\nYou have been granted enlightenment!"); /* magic mapping */
X for (i = 0; i < MAXY; i++)
X for (j = 0; j < MAXX; j++)
X know[j][i] = KNOWALL;
X draws(0, MAXX, 0, MAXY);
X return;
X
X case 16:
X c[HOLDMONST] += 30;
X bottomline();
X return; /* hold monster */
X
X case 17:
X for (i = 0; i < 26; i++) /* gem perfection */
X switch (iven[i])
X {
X case ODIAMOND:
X case ORUBY:
X case OEMERALD:
X case OSAPPHIRE:
X j = ivenarg[i];
X j &= 255;
X j <<= 1;
X if (j > 255)
X j = 255; /* double value */
X ivenarg[i] = j;
X break;
X }
X break;
X
X case 18:
X for (i = 0; i < 11; i++)
X c[exten[i]] <<= 1; /* spell extension */
X break;
X
X case 19:
X for (i = 0; i < 26; i++) /* identify */
X {
X if (iven[i] == OPOTION)
X potionname[ivenarg[i]][0] = ' ';
X if (iven[i] == OSCROLL)
X scrollname[ivenarg[i]][0] = ' ';
X }
X break;
X
X case 20:
X for (i = 0; i < 10; i++) /* remove curse */
X if (c[curse[i]])
X c[curse[i]] = 1;
X break;
X
X case 21:
X annihilate();
X break; /* scroll of annihilation */
X
X case 22:
X godirect(22, 150, "The ray hits the %s", 0, ' '); /* pulverization */
X break;
X case 23:
X c[LIFEPROT]++;
X break; /* life protection */
X };
X}
X
Xstatic opit()
X{
X register int i;
X if (rnd(101) < 81)
X if (rnd(70) > 9 * c[DEXTERITY] - packweight() || rnd(101) < 5)
X if (level == MAXLEVEL - 1)
X obottomless();
X else
X if (level == MAXLEVEL + MAXVLEVEL - 1)
X obottomless();
X else
X {
X if (rnd(101) < 20)
X {
X i = 0;
X lprcat("\nYou fell into a pit! Your fall is cushioned by an unknown force\n");
X } else
X {
X i = rnd(level * 3 + 3);
X lprintf("\nYou fell into a pit! You suffer %d hit points damage", (long) i);
X lastnum = 261; /* if he dies scoreboard
X * will say so */
X }
X losehp(i);
X nap(2000);
X newcavelevel(level + 1);
X draws(0, MAXX, 0, MAXY);
X }
X}
X
Xstatic obottomless()
X{
X lprcat("\nYou fell into a bottomless pit!");
X beep();
X nap(3000);
X died(262);
X}
X
Xstatic ostatue()
X{
X}
X
Xstatic omirror()
X{
X}
X
Xstatic obook()
X{
X lprcat("\nDo you ");
X if (c[BLINDCOUNT] == 0)
X lprcat("(r) read it, ");
X lprcat("(t) take it");
X iopts();
X while (1)
X switch (ttgetch())
X {
X case '\33':
X case 'i':
X ignore();
X return;
X
X case 'r':
X if (c[BLINDCOUNT])
X break;
X lprcat("read");
X /* no more book */ readbook(iarg[playerx][playery]);
X forget();
X return;
X
X case 't':
X lprcat("take");
X if (take(OBOOK, iarg[playerx][playery]) == 0)
X forget(); /* no more book */
X return;
X };
X}
X
X/*
X * function to read a book
X */
Xreadbook(lev)
X register int lev;
X{
X register int i, tmp;
X if (lev <= 3)
X i = rund((tmp = splev[lev]) ? tmp : 1);
X else
X i = rnd((tmp = splev[lev] - 9) ? tmp : 1) + 9;
X spelknow[i] = 1;
X lprintf("\nSpell \"%s\": %s\n%s", spelcode[i], spelname[i], speldescript[i]);
X if (rnd(10) == 4)
X {
X lprcat("\nYour int went up by one!");
X c[INTELLIGENCE]++;
X bottomline();
X }
X}
X
Xstatic ocookie()
X{
X char *p;
X lprcat("\nDo you (e) eat it, (t) take it");
X iopts();
X while (1)
X switch (ttgetch())
X {
X case '\33':
X case 'i':
X ignore();
X return;
X
X case 'e':
X lprcat("eat");
X forget(); /* no more cookie */
X outfortune();
X return;
X
X case 't':
X lprcat("take");
X if (take(OCOOKIE, 0) == 0)
X forget(); /* no more book */
X return;
X };
X}
X
X/*
X * routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth
X * 100* the argument
X */
Xstatic ogold(arg)
X int arg;
X{
X register long i;
X i = iarg[playerx][playery];
X if (arg == OMAXGOLD)
X i *= 100;
X else
X if (arg == OKGOLD)
X i *= 1000;
X else
X if (arg == ODGOLD)
X i *= 10;
X lprintf("\nIt is worth %d!", (long) i);
X c[GOLD] += i;
X bottomgold();
X item[playerx][playery] = know[playerx][playery] = 0; /* destroy gold */
X}
X
Xohome()
X{
X register int i;
X nosignal = 1; /* disable signals */
X for (i = 0; i < 26; i++)
X if (iven[i] == OPOTION)
X if (ivenarg[i] == 21)
X {
X iven[i] = 0; /* remove the potion of cure
X * dianthroritis from
X * inventory */
X clear();
X lprcat("Congratulations. You found a potion of cure dianthroritis.\n");
X lprcat("\nFrankly, No one thought you could do it. Boy! Did you surprise them!\n");
X if (gtime > TIMELIMIT)
X {
X lprcat("\nThe doctor has the sad duty to inform you that your daughter died");
X lprcat("\nbefore your return. There was nothing he could do without the potion.\n");
X nap(5000);
X died(269);
X } else
X {
X lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
X lprcat("your daughter should be well on her way to recovery.\n");
X nap(6000);
X lprcat("\nThe potion is");
X nap(3000);
X lprcat(" working! The doctor thinks that\n");
X lprcat("your daughter will recover in a few days. Congratulations!\n");
X beep();
X nap(5000);
X died(263);
X }
X }
X while (1)
X {
X clear();
X lprintf("Welcome home %s. Latest word from the doctor is not good.\n", logname);
X
X if (gtime > TIMELIMIT)
X {
X lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
X lprcat("You didn't make it in time. There was nothing he could do without the potion.\n");
X nap(5000);
X died(269);
X }
X lprcat("\nThe diagnosis is confirmed as dianthroritis. He guesses that\n");
X lprintf("your daughter has only %d mobuls left in this world. It's up to you,\n", (long) ((TIMELIMIT - gtime + 99) / 100));
X lprintf("%s, to find the only hope for your daughter, the very rare\n", logname);
X lprcat("potion of cure dianthroritis. It is rumored that only deep in the\n");
X lprcat("depths of the caves can this potion be found.\n\n\n");
X lprcat("\n ----- press ");
X standout("return");
X lprcat(" to continue, ");
X standout("escape");
X lprcat(" to leave ----- ");
X i = ttgetch();
X while (i != '\33' && i != '\n')
X i = ttgetch();
X if (i == '\33')
X {
X drawscreen();
X nosignal = 0; /* enable signals */
X return;
X }
X }
X}
X
X/* routine to save program space */
Xiopts()
X{
X lprcat(", or (i) ignore it? ");
X}
Xignore()
X{
X lprcat("ignore\n");
X}
X
X/*
X * For prompt mode, prompt for entering a building.
X */
Xstatic prompt_enter()
X{
X char i;
X
X lprcat("\nDo you (g) go inside, or (i) stay here? ");
X i = 0;
X while ((i != 'g') && (i != 'i') && (i != '\33'))
X i = ttgetch();
X if (i == 'g')
X enter();
X else
X lprcat(" stay here");
X}
X
X/*
X * For prompt mode, prompt for climbing up/down the volcanic shaft.
X *
X * Takes one parameter: if it is negative, going down the shaft, otherwise,
X * going up the shaft.
X */
Xstatic prompt_volshaft(dir)
X int dir;
X{
X char i;
X
X lprcat("\nDo you (c) climb ");
X if (dir > 0)
X lprcat("up");
X else
X lprcat("down");
X iopts();
X
X i = 0;
X while ((i != 'c') && (i != 'i') && (i != '\33'))
X i = ttgetch();
X
X if ((i == '\33') || (i == 'i'))
X {
X ignore();
X return;
X }
X if (dir > 0)
X act_up_shaft();
X else
X act_down_shaft();
X}
X
Xstatic o_open_door()
X{
X char i;
X lprcat("\nDo you (c) close it");
X iopts();
X i = 0;
X while ((i != 'c') && (i != 'i') && (i != '\33'))
X i = ttgetch();
X if ((i == '\33') || (i == 'i'))
X {
X ignore();
X return;
X }
X lprcat("close");
X forget();
X item[playerx][playery] = OCLOSEDDOOR;
X iarg[playerx][playery] = 0;
X playerx = lastpx;
X playery = lastpy;
X}
X
Xstatic o_closed_door()
X{
X char i;
X lprcat("\nDo you (o) try to open it");
X iopts();
X i = 0;
X while ((i != 'o') && (i != 'i') && (i != '\33'))
X i = ttgetch();
X if ((i == '\33') || (i == 'i'))
X {
X ignore();
X playerx = lastpx;
X playery = lastpy;
X return;
X } else
X {
X lprcat("open");
X /*
X * if he failed to open the door ...
X */
X if (!act_open_door(playerx, playery))
X {
X playerx = lastpx;
X playery = lastpy;
X }
X }
X}
END_OF_FILE
if test 33382 -ne `wc -c <'object.c'`; then
echo shar: \"'object.c'\" unpacked with wrong size!
fi
# end of 'object.c'
fi
echo shar: End of archive 16 \(of 17\).
cp /dev/null ark16isdone
#!/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 17 (of 17)."
# Contents: main.c
# Wrapped by tadguy@ab20 on Mon Aug 26 21:51:55 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'main.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(41032 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#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X#include "patchlev.h"
X
X#ifndef AMIGA
X# ifndef MSDOS
X# ifndef VMS
X# include <pwd.h>
X# endif VMS
X# endif MSDOS
X#endif AMIGA
X
Xextern char move_no_pickup;
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#ifdef MSDOS
X
Xstatic char cmdhelp[] = "\
XCmd line format: larn [-slicnhp] [-o<optsfile>] [-##] [++]\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<optsfile>] [-##] [++]\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 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#ifdef VMS
X# define EXIT_FAILURE
X# define EXIT_SUCCESS 1
X#else
X# define EXIT_FAILURE 1
X# define EXIT_SUCCESS 0
X#endif
X
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;
X#ifdef VT100
X char *ttype;
X#endif
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 AMIGA
X AmInit(); /* Open console device */
X ptr = "AMIGAN";
X#else
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 /* VMS */
X#endif /* MSDOS */
X#endif /* AMIGA */
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))
X died(-285); /* malloc() failure */
X
X# ifdef 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 {
X argv[i][0] = 0; /* remove this argv */
X if (argv[i][2] != '\0')
X strncpy(optsfile, &argv[i][2], PATHLEN);
X else
X {
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 {
X strcpy(savefilename, larndir);
X strcat(savefilename, SAVEFILE);
X }
X if (!swapfile[0])
X {
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 /* MSDOS */
X
X if ((ptr = getenv("HOME")) == 0)
X 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#ifdef AMIGA
X sprintf(optsfile, "%s%s", LARNHOME, LARNOPTS); /* the options filename */
X#else
X sprintf(optsfile, "%s/%s",ptr, LARNOPTS); /* the options filename */
X#endif AMIGA
X#endif VMS
X
X# endif /* 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(EXIT_FAILURE);
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 exit(EXIT_SUCCESS);
X
X case 'l': /* show log file */
X diedlog();
X exit(EXIT_SUCCESS);
X
X case 'i': /* show all scoreboard */
X showallscores();
X exit(EXIT_SUCCESS);
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();
X lprc('\n');
X showscores();
X }
X exit(EXIT_SUCCESS);
X
X case 'n': /* no welcome msg */
X nowelcome=1;
X argv[i][0]=0;
X 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 case '?':
X write(1,cmdhelp,sizeof(cmdhelp));
X exit(EXIT_SUCCESS);
X
X case 'o': /* specify a .larnopts filename */
X if (argv[i]+2 != '\0')
X strncpy(optsfile,argv[i]+2,127);
X else
X {
X strncpy( optsfile, argv[i+1][0], 127 );
X argv[i+1][0] = '\0';
X }
X break;
X
X case 'p': /* set 'prompt_mode' flag */
X prompt_mode = 1 ;
X break ;
X
X default:
X printf("Unknown option <%s>\n",argv[i]);
X write(1,cmdhelp,sizeof(cmdhelp));
X exit(EXIT_SUCCESS);
X };
X
X if (strcmp(argv[i], "++") == 0)
X restorflag = 1;
X }
X
X#ifndef 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(EXIT_SUCCESS);
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)
X {
X write(2,"Can't obtain playerid\n",22);
X exit(EXIT_SUCCESS);
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);
X newgame(); /* set the initial clock */
X
X if (restorflag == 1) /* restore checkpoint file */
X {
X clear();
X hitflag = 1;
X restoregame(ckpfile);
X }
X else if (access(savefilename,0)==0) /* restore game if need to */
X {
X clear();
X restorflag = 1;
X hitflag=1;
X 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)
X welcome(); /* welcome the player to the game */
X# ifdef 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 /* nice(1); /* games should be run niced */
X yrepcount = hit2flag = 0;
X /* init previous player position to be current position, so we don't
X reveal any stuff on the screen prematurely.
X */
X oldx = playerx ;
X oldy = playery;
X gtime = -1;
X
X /* MAINLOOP
X find objects, move stuff, get commands, regenerate
X */
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 && !move_no_pickup ), FALSE );
X else
X dropflag=0; /* don't show it just dropped an item */
X
X /* handle global activity
X update game time, move spheres, move walls, move monsters
X all the stuff affected by TIMESTOP and HASTESELF
X */
X if (c[TIMESTOP] <= 0)
X if (c[HASTESELF] == 0 ||
X (c[HASTESELF] & 1) == 0)
X {
X gtime++;
X movsphere();
X
X if (hitflag==0)
X {
X if (c[HASTEMONST])
X movemonst();
X movemonst();
X }
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)
X lflushall();
X hitflag=hit3flag=0;
X bot_linex(); /* update bottom line */
X
X /* get commands and make moves
X */
X nomove=1;
X while (nomove)
X {
X if (hit3flag)
X lflushall();
X nomove=0;
X parse();
X }
X regen(); /* regenerate hp and spells */
X if (c[TIMESTOP]==0)
X if (--rmst <= 0)
X {
X rmst = 120-(level<<2);
X fillmonst(makemonst(level));
X }
X }
X }
X
X/*
X subroutine to randomly create monsters if needed
X */
Xstatic randmonst()
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 */
Xstatic parse()
X {
X register int i,j,k,flag;
X extern showeat(),showquaff(),showread();
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)
X 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 if (!floor_consume( OCOOKIE, "eat" ))
X consume( OCOOKIE, "eat", showeat );
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': /* inventory */
X yrepcount=0;
X nomove=1;
X showstr(FALSE);
X return;
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 if (!floor_consume( OPOTION, "quaff"))
X consume( OPOTION, "quaff", showquaff );
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 if (!floor_consume( OSCROLL, "read" ))
X if (!floor_consume( OBOOK, "read" ))
X consume( OSCROLL, "read", showread );
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 nomove = 1;
X cursors();
X lprintf("\nCaverns of Larn, Version %d.%d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)PATCHLEVEL,(long)c[HARDGAME]);
X if (wizard)
X lprcat(" Wizard");
X if (cheat)
X lprcat(" Cheater");
X lprcat("\nThis version of Larn by Kevin Routley");
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 '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 yrepcount = 0;
X nomove = 1;
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 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 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 MSDOS
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 object/monster */
X specify_object();
X nomove = 1 ;
X yrepcount = 0 ;
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
Xstatic run(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 */
Xstatic wield()
X {
X register int i;
X while (1)
X {
X if ((i = whatitem("wield (- for nothing)")) == '\33')
X return;
X if (i != '.')
X {
X if (i=='*')
X {
X i = showwield();
X cursors();
X }
X if ( i == '-' )
X {
X c[WIELD] = -1 ;
X bottomline();
X return;
X }
X if (i && i != '.')
X if (iven[i-'a']==0)
X { ydhi(i); return; }
X else if (iven[i-'a']==OPOTION)
X { ycwi(i); return; }
X else if (iven[i-'a']==OSCROLL)
X { ycwi(i); return; }
X else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD))
X { lprcat("\nBut one arm is busy with your shield!");
X return; }
X else
X {
X c[WIELD]=i-'a';
X if (iven[i-'a'] == OLANCE)
X c[LANCEDEATH]=1;
X else c[LANCEDEATH]=0;
X bottomline();
X return;
X }
X }
X }
X }
X
X/*
X common routine to say you don't have an item
X */
Xstatic ydhi(x)
X int x;
X { cursors(); lprintf("\nYou don't have item %c!",x); }
Xstatic ycwi(x)
X int x;
X { cursors(); lprintf("\nYou can't wield item %c!",x); }
X
X/*
X function to wear armor
X */
Xstatic wear()
X {
X register int i;
X while (1)
X {
X if ((i = whatitem("wear"))=='\33')
X return;
X if (i != '.' && i != '-')
X {
X if (i=='*')
X {
X i = showwear();
X cursors();
X }
X if (i && i != '.')
X switch(iven[i-'a'])
X {
X case 0:
X ydhi(i);
X return;
X case OLEATHER: case OCHAIN: case OPLATE:
X case ORING: case OSPLINT: case OPLATEARMOR:
X case OSTUDLEATHER: 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 */
Xstatic dropobj()
X {
X register int i;
X register char *p;
X long amt;
X
X p = &item[playerx][playery];
X while (1)
X {
X if ((i = whatitem("drop"))=='\33')
X return;
X if (i=='*')
X {
X i = showstr(TRUE);
X cursors();
X }
X 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#ifndef MSDOS
X lprcat("\n");
X#endif MSDOS
X lprcat("You don't have that much!");
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#ifndef MSDOS
X lprintf("You drop %d gold pieces",(long)amt);
X#else
X lprintf("\nYou drop %d gold pieces",(long)amt);
X#endif MSDOS
X iarg[playerx][playery]=i; bottomgold();
X know[playerx][playery]=0; dropflag=1; return;
X }
X if (i)
X {
X drop_object(i-'a');
X return;
X }
X }
X }
X }
X
Xstatic int floor_consume( search_item, cons_verb )
Xint search_item;
Xchar *cons_verb;
X {
X register int i;
X char tempc;
X
X cursors();
X i = item[playerx][playery];
X
X /* item not there, quit
X */
X if (i != search_item)
X return( 0 );
X
X /* item there. does the player want to consume it?
X */
X lprintf("\nThere is %s", objectname[i] );
X if (i==OSCROLL)
X if (scrollname[iarg[playerx][playery]][0])
X lprintf(" of%s", scrollname[iarg[playerx][playery]]);
X if (i==OPOTION)
X if (potionname[iarg[playerx][playery]][0])
X lprintf(" of%s", potionname[iarg[playerx][playery]]);
X lprintf(" here. Do you want to %s it?", cons_verb );
X
X if ((tempc = getyn()) == 'n' )
X return( 0 ); /* item there, not consumed */
X else if (tempc != 'y')
X {
X lprcat(" aborted");
X return( -1 ); /* abort */
X }
X
X /* consume the item.
X */
X switch( i )
X {
X case OCOOKIE:
X outfortune();
X forget();
X break;
X case OBOOK:
X readbook( iarg[playerx][playery] );
X forget();
X break;
X case OPOTION:
X quaffpotion( iarg[playerx][playery] );
X forget();
X break;
X case OSCROLL:
X /* scrolls are tricky because of teleport.
X */
X i = iarg[playerx][playery];
X know[playerx][playery] = 0;
X item[playerx][playery] = iarg[playerx][playery] = 0 ;
X read_scroll( i );
X break;
X }
X return( 1 );
X }
X
Xstatic int consume( search_item, prompt, showfunc )
Xint search_item ;
Xchar *prompt;
Xint (*showfunc)();
X {
X register int i;
X
X while (1)
X {
X if ((i = whatitem( prompt )) == '\33')
X return;
X if (i != '.' && i != '-')
X {
X if (i == '*')
X {
X i = showfunc();
X cursors();
X }
X if (i && i != '.')
X {
X switch (iven[i-'a'])
X {
X case OSCROLL:
X if ( search_item != OSCROLL )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X read_scroll( ivenarg[i-'a'] );
X break;
X case OBOOK:
X if ( search_item != OSCROLL )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X readbook( ivenarg[i-'a'] );
X break;
X case OCOOKIE:
X if ( search_item != OCOOKIE )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X outfortune();
X break;
X case OPOTION:
X if ( search_item != OPOTION )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X quaffpotion( ivenarg[i-'a'], TRUE );
X break;
X case 0:
X ydhi(i);
X return;
X default:
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X iven[i-'a'] = 0;
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=0;
X cursors(); lprintf("\nWhat do you want to %s [* for all] ? ",str);
X while (i>'z' || (i<'a' && i!='-' && i!='*' && i!='\33' && i!='.'))
X i=ttgetch();
X if (i=='\33')
X 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 41032 -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 17 \(of 17\).
cp /dev/null ark17isdone