[comp.sources.games] v10i088: nethack3p9 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/14/90)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 88
Archive-name: nethack3p9/Part43
Supersedes: NetHack3: Volume 7, Issue 56-93



#! /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 43 (of 56)."
# Contents:  amiga/amiwbench.c others/ovlmgr.doc others/suputils.ovl
#   src/shknam.c src/vault.c
# Wrapped by billr@saab on Wed Jul 11 17:11:57 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'amiga/amiwbench.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/amiwbench.c'\"
else
echo shar: Extracting \"'amiga/amiwbench.c'\" \(12444 characters\)
sed "s/^X//" >'amiga/amiwbench.c' <<'END_OF_FILE'
X/*    SCCS Id: @(#)amiwbench.c - Amiga Workbench interface  3.0   */
X/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1990	  */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X
X#undef TRUE
X#undef FALSE
X#undef COUNT
X#undef NULL
X
X#ifdef LATTICE
X#include <proto/exec.h>
X#include <proto/dos.h>
X#include <proto/icon.h>
X#endif
X
X#include <workbench/startup.h>
X#include <workbench/workbench.h>
X#include <exec/memory.h>
X#include <ctype.h>
X
X#ifdef LATTICE
X#include <string.h>
X#undef strlen			/* grrr */
X#endif
X
X#define ALLOC_SIZE		((long)sizeof(struct FileInfoBlock))
X
X#ifdef AZTEC_C
X/*
X * Change when manx becomes ANSI complient
X */
XBPTR FDECL(CurrentDir,(BPTR));
XBPTR FDECL(ParentDir, (BPTR));
XBPTR FDECL(Lock, (char *, long));
Xvoid *FDECL(AllocMem, (long, long));
Xvoid FDECL(FreeMem, (void *, long));
Xunsigned short FDECL(Examine, (BPTR, struct FileInfoBlock *));
Xstruct Library *FDECL(OpenLibrary,(char *, long));
Xstruct DiskObject *FDECL(GetDiskObject, (char *));
X
Xextern struct Library *IconBase;
X#endif
X
X#ifdef AMIGA_WBENCH
Xstatic void FDECL(ami_wb_findme,(char *,char *,struct WBArg *));
Xstatic int FDECL(buildPath,(LONG,struct FileInfoBlock *,char *));
Xstatic void FDECL(insert,(char *,char *));
X
XBOOL FromWBench=0;		/* if FALSE, this file is a big NOP */
Xstatic BOOL FromTool=0;		/* or from Project (ergo nothing to restore) */
Xstatic char argline[80];	/* fake command line from ToolTypes */
Xstatic BOOL TTparse=0;		/* parsing tooltypes? */
Xstatic BOOL KillIcon=FALSE;	/* delayed expunge of user's icon */
Xstatic char iconname[PATHLEN+5];
Xstatic char origicon[PATHLEN+5];
Xstatic char savefname[PL_NSIZ];		/* name from name of save file */
X
Xextern const char *classes;	/* liberated from pcmain */
Xextern char *PATH;
X
X/* Called after NetHack.cnf (and maybe NETHACKOPTIONS) are read.
X * If this is a request to show the score file, do it here and quit.
X */
Xvoid ami_wbench_init(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	struct WBStartup *wbs=(struct WBStartup *)argv;
X	struct WBArg *wa;
X	int	ia;			/* arg of active icon */
X	int	x,doscore=0;
X	char 	*p,*lp;
X	BPTR	olddir;			/* starting directory */
X	struct DiskObject *dobj;
X	char	*scorearg;
X	char	tmp_ramdisk[PATHLEN];
X	char	tmp_levels[PATHLEN];
X
X	FromWBench=(argc==0);
X	if(!FromWBench)return;			/* nothing if from CLI */
X
X	/*
X	 * "NULL" out arrays
X	 */
X	tmp_ramdisk[0] = '\0';
X	tmp_levels[0]  = '\0';
X
X	IconBase=OpenLibrary("icon.library",33L);
X	if(!IconBase)error("icon.library missing!");
X
X	wa=wbs->sm_ArgList;
X	if(wbs->sm_NumArgs>2)error("You can only play one game at a time!");
X	ia=wbs->sm_NumArgs-1;
X	strcpy(savefname,wa[ia].wa_Name);
X	if(!strncmp(index(savefname,'.'),".sav",4)){
X		*index(savefname,'.')='\0';
X	} else {
X		savefname[0]='\0';	/* don't override if not save file */
X	}
X
X	olddir=CurrentDir(wa[ia].wa_Lock);   /* where the icon is */
X
X	dobj=GetDiskObject(wa[ia].wa_Name);
X	(void)CurrentDir(olddir);		/* and back */
X	if(!dobj){
X		error("Sorry, I can't find your icon!");
X	}
X
X	FromTool=(dobj->do_Type==WBTOOL)?1:
X			(dobj->do_Type==WBPROJECT)?0:
X			(error("Sorry, I don't recognize this icon type!"),1);
X
X	ami_wb_findme(SAVEF,SAVEP,&wa[ia]);
X	strcpy(origicon,SAVEF);
X	strcat(origicon,".info");
X
X	argline[0]='\0';
X	if(dobj->do_ToolTypes)for(x=0;p=dobj->do_ToolTypes[x];x++){
X		lp=index(p,'=');
X		if(!lp++){
X			if((strncmp(p,"SCORES",6)==0) ||
X			   (strncmp(p,"SCORE",5)==0)){
X				doscore=1;
X				scorearg=malloc(strlen(p)+1);
X				strcpy(scorearg,p);
X			} else {
X				TTparse=TRUE;
X				parseoptions(p,(boolean)TRUE);
X				TTparse=FALSE;
X			}
X		} else {
X			while(*lp && isspace(*lp))lp++;
X				/* vars and lengths below match amidos.c,
X				 * but there is no SAVE - you put the
X				 * icon where you want it, and GRAPHICS
X				 * just doesn't belong		*/
X			if(!strncmp(p,"OPTIONS",4)){
X				TTparse=TRUE;
X				parseoptions(lp,(boolean)TRUE);
X				TTparse=FALSE;
X			} else
X			if(lp[0]=='#'){
X				/* for perversity's sake, a comment */
X			} else
X			if(!strncmp(p,"HACKDIR",4)){
X				strncpy(hackdir,lp,PATHLEN);
X			} else
X			if(!strncmp(p,"RAMDISK",3)){
X				strncpy(tmp_ramdisk,lp,PATHLEN);
X			} else
X			if(!strncmp(p,"LEVELS",4)){
X				strncpy(tmp_levels,lp,PATHLEN);
X			} else
X			if(!strncmp(p,"PATH",4)){
X				strncpy(PATH,lp,PATHLEN);
X			} else
X				/* new things */
X			if((strncmp(p,"CMDLINE",7)==0)||
X			   (strncmp(p,"COMMANDLINE",11)==0)){
X				strncpy(argline,lp,79);
X			} else
X			{
X				msmsg("Bad ToolTypes line: '%s'\n",p);
X				getreturn("to continue");
X			}
X		}
X	}
X		/* cleanup - from amidos.c, except we only change things
X		 * that are explicitly changed, since we already
X		 * did this once to get the defaults (in amidos.c)	*/
X	if(plname[0])plnamesuffix();	/* from amidos.c */
X	if(tmp_levels[0])strcpy(permbones,tmp_levels);
X	if(tmp_ramdisk[0]){
X		strcpy(levels,tmp_ramdisk);
X		strcpy(bones,levels);
X		if(strcmp(permbones,levels))
X			ramdisk=TRUE;
X	} else {
X		if(tmp_levels[0]){
X			strcpy(levels,tmp_levels);
X			strcpy(bones,levels);
X		}
X	}
X
X	FreeDiskObject(dobj);	/* we'll get it again later if we need it */
X
X	if(doscore){
X		long ac;
X		char *p;
X		char **av=calloc(1,50*sizeof(char *));
X#ifdef CHDIR
X		chdirx(hackdir,0);
X#endif
X		av[0]="NetHack";			/* why not? */
X		for(ac=1,p=scorearg;*p;ac++){
X			av[ac]=p;
X			while(*p && !isspace(*p))p++;
X			if(!*p)break;
X			*p++='\0';
X			while(*p && isspace(*p))p++;
X			if(ac==1)sprintf(av[ac],"-s");	/* overwrite SCORES */
X		}
X		prscore(ac+1,av);
X		exit(0);		/* overloaded */
X	}
X
X			/* if the user started us from the tool icon,
X			 * we can't save the game in the same place
X			 * we started from, so pick up the plname
X			 * and hope for the best.
X			 */
X	if(FromTool){
X		strcat(SAVEF,plname);
X		strcat(SAVEP,plname);
X	}
X}
X
X/* Simulate the command line (-s is already done, although this is
X * not exactly the way it should be). Note that we only handle flags
X * that are not otherwise available in NetHack.cnf		*/
Xvoid ami_wbench_args(){
X	char *p=argline;
X	if(!FromWBench)return;
X	if(!argline)return;
X
X	while(*p){
X		switch(*p++){
X		case '-':	break;
X#ifdef NEWS
X		case 'n':	flags.nonews = TRUE;
X#endif
X#if defined(WIZARD) || defined(EXPLORE_MODE)
X# ifndef EXPLORE_MODE
X		case 'X':
X# endif
X		case 'D':
X# ifdef WIZARD
X#  ifdef KR1ED
X			if(!strcmp(plname,WIZARD_NAME)){
X#  else
X			if(!strcmp(plname,WIZARD)){
X#  endif
X				wizard=TRUE;break;
X			}
X			/* else fall through */
X# endif
X# ifdef EXPLORE_MODE
X		case 'X':	discover=TRUE;
X# endif
X				break;
X#endif
X#ifdef DGK
X		case 'r':	/* no ram disk */
X			ramdisk=FALSE;
X			break;
X#endif
X		default:
X			p--;
X			if(index(classes,toupper(*p))){
X				char *t=pl_character;
X				int cnt=sizeof(pl_character)-1;
X				while(cnt && *p && !isspace(*p))*t++=*p++,cnt--;
X				*t=0;
X			} else {
X				Printf("Unknown switch: %s\n",p);
X				return;
X			}
X		}
X	}
X}
X
X
X/* IF (from workbench) && (currently parsing ToolTypes)
X * THEN print error message and return 0
X * ELSE return 1
X */
Xami_wbench_badopt(oopsline)
Xchar *oopsline;
X{
X	if(!FromWBench)return 1;
X	if(!TTparse)return 1;
X	Printf("Bad Syntax in OPTIONS in ToolTypes: %s.",oopsline);
X	return 0;
X}
X
X/* Construct (if necessary) and fill in icon for given save file */
Xvoid ami_wbench_iconwrite(base)
Xchar *base;
X{
X	BPTR lock;
X	char tmp[PATHLEN+5];
X
X	if(!FromWBench)return;
X
X	strcpy(tmp,base);
X	strcat(tmp,".info");
X	if(FromTool){				/* user clicked on main icon */
X		(void)CopyFile(DEFAULT_ICON,tmp);
X	} else {				/* from project */
X		lock=Lock(tmp,ACCESS_READ);
X		if(lock==0){	/* maybe our name changed - try to get
X				 * original icon */
X		    if(!Rename(origicon,tmp)){
X				/* nope, build a new icon */
X			lock=Lock(DEFAULT_ICON,ACCESS_READ);
X			if(lock==0)return;		/* no icon today */
X			UnLock(lock);
X			(void)CopyFile(DEFAULT_ICON,tmp);
X		    }
X		} else UnLock(lock);
X	}
X	KillIcon=FALSE;
X
X/*	dobj=GetDiskObject(base);
X	anything we need to change?  I don't think so.
X	PutDiskObject(base,dobj);
X	FreeDiskObject(dobj);
X*/
X}
X
X/* How much disk space will we need for the icon? */
Xint ami_wbench_iconsize(base)
Xchar *base;
X{
X	struct FileInfoBlock *fib;
X	BPTR lock;
X	int	rv;
X	char tmp[PATHLEN+5];
X
X	if(!FromWBench)return(0);
X	strcpy(tmp,base);
X	strcat(tmp,".info");
X	lock=Lock(tmp,ACCESS_READ);
X	if(lock==0){	/* check the default */
X		lock=Lock(DEFAULT_ICON,ACCESS_READ);
X		if(lock==0)return(0);
X	}
X	fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
X	if(!Examine(lock,fib)){
X		UnLock(lock);
X		FreeMem(fib, ALLOC_SIZE);
X		return(0);			/* if no icon, there
X						 * never will be one */
X	}
X	rv=fib->fib_Size+strlen(plname);	/* guessing */
X	UnLock(lock);
X	FreeMem(fib, ALLOC_SIZE);
X	return(rv);
X}
X
X/* Delete the icon associated with the given file (NOT the file itself! */
X/* (Don't worry if the icon doesn't exist */
Xvoid ami_wbench_unlink(base)
Xchar *base;
X{
X	if(!FromWBench)return;
X
X	strcpy(iconname,base);
X	strcat(iconname,".info");
X	KillIcon=TRUE;			/* don't do it now - this way the user
X					 * gets back whatever picture we had
X					 * when we started if the game is
X					 * saved again			 */
X/*	unlink(tmp); */
X}
X
X/* Check for a saved game.
XIF not a saved game -> -1
XIF can't open SAVEF -> -1
XELSE -> fd for reading SAVEF */
Xint ami_wbench_getsave(mode)
Xint mode;
X{
X	BPTR lock;
X	struct FileInfoBlock *fib;
X
X	if(!FromWBench)return(open(SAVEF,mode));
X			/* if the file will be created anyway, skip the
X			 * checks and just do it			*/
X	if(mode & O_CREAT)return(open(SAVEF,mode));
X	if(FromTool)return(-1);		/* otherwise, by definition, there
X					 * isn't a save file (even if a
X					 * file of the right name exists) */
X	if(savefname[0])
X		strncpy(plname,savefname,PL_NSIZ-1); /* restore poly'd name */
X	lock=Lock(SAVEF,ACCESS_READ);
X	fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
X	if(lock && Examine(lock,fib)){
X		if(fib->fib_Size>100){	/* random number << save file size */
X			UnLock(lock);
X                        FreeMem(fib,ALLOC_SIZE);
X			return(open(SAVEF,mode));
X		} else {
X				/* this is a dummy file we need because
X				 * workbench won't duplicate an icon with no
X				 * "real" data attached - try to get rid of it.
X				 */
X			UnLock(lock);
X			unlink(SAVEF);
X			FreeMem(fib,ALLOC_SIZE);
X			return(-1);
X		}
X	}
X	FreeMem(fib,ALLOC_SIZE);
X	return(-1);		/* give up */
X}
X
X#ifdef notdef
X/* cleanup */
Xvoid ami_wbench_cleanup(){
X	if(!FromWBench)return;
X	if(KillIcon){
X		unlink(iconname);
X	} else {
X		if(!FromTool){	/* game started and ended in one session */
X			char buf[PATHLEN+5];
X			strcpy(buf,SAVEF);
X			strcat(buf,".info");
X			unlink(buf);
X		}
X	}
X}
X#endif
X
X/* get printable version of where we came from */
Xstatic void ami_wb_findme(bufp,dirp,wa)
X	char *bufp,*dirp;
X	struct WBArg *wa;
X	{
X	BPTR dir;
X	struct FileInfoBlock *fib;
X	char *p;
X	int len;
X
X	dir=wa->wa_Lock;
X
X	fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE,MEMF_CLEAR);
X	buildPath(dir,fib,dirp);
X	strcat(dirp,"/");
X	strcpy(bufp,dirp);
X	if(FromTool){
X		/* do nothing - filename will be added later */
X	} else {
X		strcat(bufp,wa->wa_Name);
X	};
X	/* I know this looks redundent, but its not since we may add
X	 * a slash after returning from buildPath
X	 */
X	p=index(bufp,':');
X	if(!p){
X		p=index(bufp,'/');
X		if(p)*p=':';
X	}
X	p=index(dirp,':');
X	if(!p){
X		p=index(dirp,'/');
X		if(p)*p=':';
X	}
X	/* We found the icon - but we need the main file. */
X	len=strlen(bufp);
X	if(len<5)return;			/* who knows? */
X	if(strcmp(".info",&bufp[len-5]))return; /* who knows? */
X	bufp[len-5]='\0';
X        FreeMem(fib, ALLOC_SIZE);
X}
X
X/* Carolyn Scheppner - CATS, AmigaMail II-34 */
Xstatic int
XbuildPath(inlock,fib,buf)
XLONG inlock;
Xstruct FileInfoBlock *fib;       	/* ASSUMED LONGWORD BOUNDARY!! */
Xchar *buf;
X	{
X	int i;
X	LONG lock,oldlock;
X	BOOL MyOldLock = FALSE;
X
X	buf[0]='\0';
X	lock=inlock;
X
X	while(lock){
X		if(Examine(lock,fib)){
X			if(fib->fib_FileName[0]>' '){
X				if(buf[0])insert(buf,"/");
X				insert(buf,fib->fib_FileName);
X			}
X		}
X		oldlock=lock;
X		lock=ParentDir(lock);
X		if(MyOldLock) UnLock(oldlock);
X		else MyOldLock=TRUE;
X	}
X	if(fib->fib_FileName[0]>' '){
X		for(i=0;i<(strlen(buf));i++){
X			if(buf[i]=='/'){
X				buf[i]=':';
X				break;
X			}
X		}
X	}
X	else insert(buf,"RAM:");
X	return((int)strlen(buf));
X}
Xstatic void
Xinsert(buf,s)
Xchar *buf,*s;
X{
X	char tmp[256];
X	strcpy(tmp,buf);
X	strcpy(buf,s);
X	strcpy(&buf[strlen(s)],tmp);
X}
X
X#if 0 /* CopyFile should be OK */
Xstatic void copyicon(from,to)
Xchar *from,*to;
X{
X	int df,dt;
X	char buf[512];
X	int len=512;
X
X	df=open(from,O_RDONLY);
X	dt=open(to,O_WRONLY,0);
X	while(len=512){
X		len=read(df,buf,len);
X		write(dt,buf,len);
X	}
X	close(df);
X	close(dt);
X}
X#endif
X#endif /* AMIGA_WBENCH */
END_OF_FILE
if test 12444 -ne `wc -c <'amiga/amiwbench.c'`; then
    echo shar: \"'amiga/amiwbench.c'\" unpacked with wrong size!
fi
# end of 'amiga/amiwbench.c'
fi
if test -f 'others/ovlmgr.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'others/ovlmgr.doc'\"
else
echo shar: Extracting \"'others/ovlmgr.doc'\" \(13383 characters\)
sed "s/^X//" >'others/ovlmgr.doc' <<'END_OF_FILE'
X		     Brief notes about ovlmgr.asm
X		     ----------------------------
X			 (revised 1990may27)
X
XOVLMGR.ASM is a preliminary version of a multiple-residency overlay
Xmanager for use with the Microsoft Overlay Linker.  It is functionally
Xcompatible with the one in the MSC library _except_:
X
X- it usually accesses the disk less often and is a lot faster in some
X  applications.
X- it has different tuning characteristics.
X- you must (of course) link OVLMGR.OBJ into the root overlay (that is,
X  outside any parentheses in the link command).
X
X  See also the notes below.
X
X	As with other Microsoft-compatible overlay handlers you must be
X*very* careful never to call a function in an overlay through a pointer,
Xunless the initiator of the call resides in the *same* physical overlay
Xas the target (1).  Furthermore, setjmp() and longjmp() are not
Xsupported.
X
X	Unlike the Microsoft system, most of the available memory is
Xused to hold overlays.	Care must be taken to ensure that enough space
Xis reserved for the C heap.  This can be accomplished through
Xinformation stored in the .EXE file (currently the minalloc parameter,
Xas described below).
X
X       Furthermore, expanded memory support (EMS) is now an integral
Xpart of the overlay manager.  LIM EMS versions 3.2 and 4.0 are
Xsupported.  Note that the page frame must be 4 pages long (64K bytes) to
Xbe able to operate correctly (most drivers allocate a 64K frame by
Xdefault).  The overlay manager will use as much EMS as is necessary in
X64K chunks, up to a limit of 16 chunks (1 Meg).  Both hardware and
Xsoftware EMS drivers have been tested and found to be completely
Xcompatible.
X
X				~ * ~
X
X	OVLMGR.ASM currently has two assembly-time options, which are
Xspecified with the assembler's /D<symbol> option (or compatible).  They
Xare:
X
X	/DNOEMS Disable EMS support.
X		OVLMGR normally detects the presence of EMS memory and
X		makes use of it whenever it is present.  This flag
X		instructs ovlmgr to ignore EMS and operate only out of
X		conventional memory.  It should be used when overlaying
X		programmes which expect to use EMS themselves.
X
X	/Di386	Use 80386-specific instruction sequences.
X		Use of this flag will make ovlmgr perform better on
X		machines with 80386 processors.  However, the resulting
X		programme will not run at all on machines with less
X		capable CPUs.  Use this option with caution, especially
X		in the case of distribution code.
X
X				~ * ~
X
X	Although using the overlay manager is in essence much like using
XMicrosoft's, they operate on a slightly different principle, and tuning
Xfor them is rather different.  Technical part begins.
X
X	When overlay linking is requested (see your linker manual), the
XMS overlay linker changes all far calls into overlays from the (normal,
X8086) format:
X
X	offset	contents
X	------	--------
X	:0000	CALL
X	:0001	target-offset
X	:0003	target-segment
X
Xto this:
X	:0000	INT
X	:0001	int#	target-mod#
X	:0003	target-offset
X
X(note that here we are looking at the actual layout of the machine
Xcode, not at the assembly code as such) and relocates the code parts
Xof all the different overlays into the *same* physical area.  The
Xoverlaid code is all actually placed at the end of the .EXE file,
Xafter the 'normal' executable image, along with all its administrative
Xdata (fixups etc.).
X
X	When this altered 'call' is executed, of course, the interrupt
Xhandler int# is invoked.  Its job is to ensure that the target overlay
Xmodule is in memory (reading it from the tail of the .EXE file if it
Xisn't already loaded) and then transfer to the given offset within it,
X'faking up' the effect of the 'real' far call that would normally have
Xoccurred.  Something similar must be done when the call returns, to
Xensure that the thing being returned *into* is still (or is once more)
Xloaded.
X
X	The Microsoft linker, as we have said, relocates all the
Xoverlays to the same load address; and, in fact, it allocates am empty
Xblock of memory there that is at least as large as the largest
Xoverlay.  Into this area all the overlays are loaded without further
Xchange; thus, there can only ever be one overlay in memory at one
Xtime.  Transferring from one overlay to another causes one overlay to
Xreplace the other in the allocated overlay swap area.
X
X       Our overlay manager does not use the space allocated by the
Xlinker in the same way.  Rather, it allocates almost all of the memory
Xavailable from MS-DOS (including the original overlay area and any high
XDOS memory) as well as EMS memory if some is available and that option
Xis being used.	As overlays are needed, they are loaded wherever they
Xwill fit, and dynamically relocated to that address.  Thus, many more
Xthan one overlay may be loaded at any given time, greatly increasing
Xpotential performance.	Management of space is more or less according to
Xan LRU policy - once all of memory is full, the least recently used
Xoverlay is selected as the most likely candidate for replacement.
X
X	The implications of this difference are as follows:  while with
Xthe conventional (default) overlay manager, the best strategy is to
Xgroup object modules together in an overlay whenever they are known to
Xbe used in rapid succession, to make each overlay as big as possible
X(all things being equal) in order to take advantage of all available
Xmemory, and to make as few overlays as possible (to reduce the amount of
Xdisk access), the best strategy with our overlay manager is almost the
Xreverse.  Having a lot of small overlays will increase the amount of
Xuseful stuff that can be resident in memory at the same time; all of
Xmemory will automatically be employed; and there is no advantage at all
Xto uniformity of size (except perhaps in the unlikely case of *exact*
Xuniformity!).
X
X	Although ovlmgr allocates all available memory while it is
Xactive, you will find that the DOS exec() call works normally.	The
Xmemory that is allocated for administering the overlay system is freed
Xbefore the exec call is made and reallocated afterwards (we trap the DOS
Xfunction request vector to do this, which isn't very nice as a
Xprogramming practise but makes the existence of the overlay manager far
Xmore transparent).  There is, however, one circumstance under which this
Xcan be problematic:  if you use the exec() call to load a TSR
Xapplication, thereby causing memory that the overlay manager was using
Xto become unavailable, you may make it impossible for the overlaid
Xapplication to proceed.  This is because code that is nominally
X'running' (i.e. is currently on the stack) cannot be relocated and must
Xbe reloaded at the *same address* that previously held it.  If another
Xprocess now owns that area of memory, there is nothing we can do.  We
Xbelieve that this should not be a serious concern in normal use.
X
X				~ * ~
X
X	Since all available memory is potentially used by ovlmgr, there
Xis one additional concern in using it with C programmes:  the allocation
Xof sufficient space for the C heap (2).  While previous versions of
Xovlmgr.asm required the change of an internal constant and re-assembly
Xof ovlmgr to change the amount of space pre-allocated for this purpose,
Xthe current version uses the DOS minalloc parameter in the executable
Xfile to hold the size of the desired heap area.  This parameter can be
Xset at any time after the link process with either Microsoft's exemod
Xutility or with the supplied utility, exesmurf.
X
X				~ * ~
X
XNOTA BENE: This is a preliminary version of the overlay manager, but
Xby now it should be fairly well debugged. If you are considering
Xupgrading it please be aware that the following improvements are
Xplanned for the next version (though who knows when delivery will
Xoccur):
X
X      - compatible versions of setjmp() and longjmp()
X      - integral malloc() to eliminate the heap size guesswork
X      - support for swapped data areas (read-only and read/write)
X      - improved performance through dynamic link-loading (maybe)
X      - XMS support and improved EMS support
X      - support for divergent-functionality overlays (such as
X	  hardware-specific modules)
X      - enabling the overlay locking code
X      - Major code revamping
X
XSwap On!
X
X------------------------------------------------------------------------
XMESSAGES
X
XOVLMGR: Not enough free memory left to run this program.
X
X	Although DOS successfully loaded the programme, it proved
X	impossible to allocate enough additional contiguous memory to
X	load one or more of the overlays.  Either reduce the
X	RAM-loading of the application by reducing the size of either
X	the root or the largest overlays, or increase the amount of
X	memory available by unloading TSRs and/or simplifying your
X	CONFIG.SYS.
X
XOVLMGR: Internal memory allocation failure.
X
X	Either an internal error has occurred in ovlmgr or the
X	application programme, or some event has caused memory that
X	ovlmgr believed it could count on becoming unavailable.  A
X	typical example of the latter would be the result of
X	attempting to load a TSR while an overlaid application is
X	running.
X
XOVLMGR: Inaccessible EXE file. Can't load overlays.
X
X	For some reason ovlmgr could not locate or read the original
X	.EXE file in which the overlays reside.  This could be due to
X	your attempting to use a very old version of DOS,
X	an abject shortage of file handles, some strange event causing
X	the file to be deleted, a disk error, or the diskette that
X	contained the executable being removed.
X
XOVLMGR: Incorrect DOS version. Must be 3.00 or later.
X
X	The current version of ovlmgr does not support versions of DOS
X	prior to 3.0 because of the difficulty of locating the
X	executable file (and hence the overlays) at runtime.
X
XOVLMGR: EMS memory manager error.
X
X	An error occurred during an EMS access.  Either the hardware has
X	reported a bug, the software driver has detected an anomaly or
X	the page frame is not 64K bytes in length.
X
X(xxxx:xxxx:xxxx:xxxx)
X
X	This is a diagnostic code composed of the following fields:
X		- error code
X		- version number
X		- available conventional memory
X		- EMS memory usage
X	Please note it in any bug reports or correspondence with the
X	development team.
X
X------------------------------------------------------------------------
XKNOWN BUGS
X
XThe present version cannot always be used as a direct replacement for
XMicrosoft's overlay manager (even granted the documented differences)
Xbecause the minimum size required for an overlaid programme to run is at
Xleast the size of the root plus TWICE the size of the largest overlay.
XIf a programme has previously had its overlay structure tuned to take
Xbest advantage of Microsoft overlays, this may well cause a problem.
XThe overlays themselves will need to be split up.
X
XTransfers between overlays are very slow in machine terms, even if both
Xoverlays happen to reside in memory at the time (still significantly
Xfaster than Microsoft's, though).
X
XLocking overlays into memory is not really implemented even though
Xreading the source code might make you think it was.  Actually, reading
Xthe source code itself isn't very well implemented right now.  Comments
Xand stuff would help.  Yup, yup.
X
XDue to limitations in the LIM EMS standard (to 4.0), programmes that
Xthemselves use EMS memory cannot be overlaid with ovlmgr unless ovlmgr's
Xown EMS support is disabled.  This is accomplished by assembling with
Xthe /DNOEMS flag.
X
X------------------------------------------------------------------------
XBUG ALERT
X
XTo repeat a point made above, if you ever try to call a function in an
Xoverlay through a pointer, you *may* die with the Microsoft overlay
Xmanager.  If you ever try to call a function in an overlay through a
Xpointer, you *will* die with ours.  Nothing in an overlay ever ends up
Xin the same segment as the linker anticipated.	You have been warned!
X
X------------------------------------------------------------------------
XFOOTNOTES
X
X(1) This problem can be circumvented through the use of surrogate
X'trampoline' functions:  functions that reside in the root overlay and
Xsimply pass right through to the 'real', overlaid, implementations.
XThis can even be made transparent to the source code through the use
Xof the C macro preprocessor, with a locution of the form
X	#define foo(x) foo_(x)
Xvisible everywhere except at the actual definition point of the
Xtrampoline.  This has been implemented in NetHack 3.0.
X
X(2) If you should get a message to the effect that NetHack can't
Xallocate 28000 and some bytes when entering a maze level, that
Xisn't our problem!  In all probability you forgot to rebuild your
Xspecial level files when you changed the compiler flags.  We got
Xthat one, too, at one point.  The same applies to similar messages when
Xreading bones files or saved games:  it is more likely that you forgot
Xto discard them after recompiling your game than that the memory
Xallowance is so greatly incorrect.
X
X----------------------------------------------------------------------
XNOTICE
X
XOVLMGR.ASM is brought to you by Pierre Martineau and Stephen Spackman.
XIt, and this document, are copyright.  They are, however, provided as
Xpart of NetHack and may be freely distributed as described in the
XNetHack license.
X
X----------------------------------------------------------------------
XStephen P Spackman			     stephen@tira.uchicago.edu
XPierre G Martineau				  pierre@ozrout.uu.net
X----------------------------------------------------------------------
X    Copyright (c) 1989, 1990 Pierre G Martineau and Stephen P Spackman
X    All Rights Reserved.
END_OF_FILE
if test 13383 -ne `wc -c <'others/ovlmgr.doc'`; then
    echo shar: \"'others/ovlmgr.doc'\" unpacked with wrong size!
fi
# end of 'others/ovlmgr.doc'
fi
if test -f 'others/suputils.ovl' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'others/suputils.ovl'\"
else
echo shar: Extracting \"'others/suputils.ovl'\" \(3447 characters\)
sed "s/^X//" >'others/suputils.ovl' <<'END_OF_FILE'
X		     PC NetHack Support Utilities
X		     ============================
X		       Last revision: 1990June01
X
XThis file contains documentation for the NetHack MS-DOS support
Xutilities SPLITF.EXE and EXESMURF.EXE.  These utilities are provided for
Xyour use to:
X	SPLITF.EXE   - Split large files into smaller files.
X	EXESMURF.EXE - Modify the runtime parameters of an EXE file.
X		       (see below).
X
X
X1.  SPLITF
X----------
X
Xsplitf FILENAME.EXT [N]
Xsplitf FILENAME.EXT /r
X
XSplitf is a programme for splitting and recombining binary files so
Xthat they can be, if necessary, transferred between computers on
Xmultiple low-capacity floppies.
X
XThis utility is included because we have our doubts about the success all
Xversions of DOS have with the "copy /b file1 file2 > file3" command.
X
XIn order to split a file into several pieces, use the command
X	splitf FILENAME.EXT N
Xwhere
X	FILENAME.EXT - is the name of the file you wish to split.
Xand
X	N - is the size (in bytes) of the pieces you would like to result.
X            If you omit N the file will be split into roughly two equal parts.
X
XThe resulting files will be named in order, FILENAME.000,
XFILENAME.001, and so forth (depending on the original FILENAME).
XSince this convention loses the original extension, care must be
Xexercised when splitting multiple files with the same base name.
X
XTo reassemble a series of files into their original form, use the
Xcommand
X	splitf FILENAME.EXT /r
Xwhere
X	FILENAME.EXT is the name of the file to be reconstituted.
X
XSplitf will look for a series of files with names FILENAME.000,
XFILENAME.001 and so forth, and will continue combining them until the
Xnext sequential file is not found.
X
XBe aware that NO consistency checking is performed by splitf; if the files
Xthat are found by this process are NOT the files that were originally
Xproduced by splitf in the correct order, the result will be almost certain
Xgibberish.
X
X
X2. EXESMURF
X-----------
Xexesmurf FILENAME[.EXT] /v
Xexesmurf FILENAME[.EXT] /minN
Xexesmurf FILENAME[.EXT] /maxN
Xexesmurf FILENAME[.EXT] /stackN
X
XThe programme exesmurf is essentially a reimplementation of Microsoft's
XEXEMOD utility.  However, this incarnation is one that is "overlay-aware"
X(as they say).  It will provide the user with information about the executable
Xand its overlays, and allow you to modify the executable's parameters.
X
XThis program is made available for all users who were not graced with a
Xrelease of EXEMOD in their Microsoft product.
X
X/v.
XIf exesmurf is invoked with a filename as argument, optionally followed
Xby a /v, the filename's exeheader is listed for your viewing pleasure, along
Xwith the headers of any Microsoft-format overlays the file may contain.
X
X/minN, /maxN, /stackN.
XExesmurf may also be used to modify the "minalloc", "maxalloc" and "stack"
Xallocation parameters of the executable file.  This can be accomplished with
Xthe /min, /max, and /stack flags respectively.  Any aguments to these flags
Xshould be *immediately* followed by a decimal number N.  Note that this is
Xinconsistant with the agruments to EXEMOD which takes hex numbers, and *needs*
Xa space between the flag and the number.
X
XWhenever exesmurf is invoked, the extension .EXE is assumed for the file
Xif no extension is given.
X----------------------------------------------------------------------
XStephen P Spackman                           stephen@tira.uchicago.edu
X----------------------------------------------------------------------
END_OF_FILE
if test 3447 -ne `wc -c <'others/suputils.ovl'`; then
    echo shar: \"'others/suputils.ovl'\" unpacked with wrong size!
fi
# end of 'others/suputils.ovl'
fi
if test -f 'src/shknam.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/shknam.c'\"
else
echo shar: Extracting \"'src/shknam.c'\" \(13176 characters\)
sed "s/^X//" >'src/shknam.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)shknam.c	3.0	88/04/13
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/* shknam.c -- initialize a shop */
X
X#include "hack.h"
X#include "eshk.h"
X
X#ifdef OVLB
X
Xstatic void FDECL(mkshobj_at, (const struct shclass *,int,int));
Xstatic void FDECL(findname, (char *,const char **));
Xstatic int  FDECL(shkinit, (const struct shclass *,struct mkroom *));
X
Xstatic const char *shkliquors[] = {
X    /* Ukraine */
X    "Njezjin", "Tsjernigof", "Gomel", "Ossipewsk", "Gorlowka",
X    /* N. Russia */
X    "Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja",
X    "Narodnaja", "Kyzyl",
X    /* Silezie */
X    "Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice",
X    "Brzeg", "Krnov", "Hradec Kralove",
X    /* Schweiz */
X    "Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm",
X    "Flims", "Vals", "Schuls", "Zum Loch",
X    ""
X};
X
Xstatic const char *shkbooks[] = {
X    /* Eire */
X    "Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch",
X    "Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra",
X    "Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan",
X    "Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh",
X    "Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea",
X    "Culdaff", "Dunfanaghy", "Inishbofin", "Kesh",
X    ""
X};
X
Xstatic const char *shkarmors[] = {
X    /* Turquie */
X    "Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep",
X    "Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak",
X    "Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt",
X    "Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni",
X    "Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat",
X    "Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan",
X    ""
X};
X
Xstatic const char *shkwands[] = {
X    /* Wales */
X    "Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach",
X    "Rhaeader", "Llandrindod", "Llanfair-ym-muallt",
X    "Y-Fenni", "Measteg", "Rhydaman", "Beddgelert",
X    "Curig", "Llanrwst", "Llanerchymedd", "Caergybi",
X    /* Scotland */
X    "Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar",
X    "Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven",
X    "Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch",
X    "Kyleakin", "Dunvegan",
X    ""
X};
X
Xstatic const char *shkrings[] = {
X    /* Hollandse familienamen */
X    "Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken",
X    "Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy",
X    "Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix",
X    "Ypey",
X    /* Skandinaviske navne */
X    "Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko",
X    "Enontekis", "Rovaniemi", "Avasaksa", "Haparanda",
X    "Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske",
X    ""
X};
X
Xstatic const char *shkfoods[] = {
X    /* Indonesia */
X    "Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan",
X    "Bandjar", "Parbalingga", "Bojolali", "Sarangan",
X    "Ngebel", "Djombang", "Ardjawinangun", "Berbek",
X    "Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi",
X    "Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan",
X    "Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe",
X    "Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe",
X    ""
X};
X
Xstatic const char *shkweapons[] = {
X    /* Perigord */
X    "Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard",
X    "Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac",
X    "Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac",
X    "Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac",
X    "Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon",
X    "Eymoutiers", "Eygurande", "Eauze", "Labouheyre",
X    ""
X};
X
Xstatic const char *shktools[] = {
X    /* Spmi */
X    "Ymla", "Eed-morra", "Cubask", "Nieb", "Bnowr Falr", "Telloc Cyaj",
X    "Sperc", "Noskcirdneh", "Yawolloh", "Hyeghu", "Niskal", "Trahnil",
X    "Htargcm", "Enrobwem", "Kachzi Rellim", "Regien", "Donmyar",
X    "Yelpur", "Nosnehpets", "Stewe", "Renrut", "Zlaw", "Nosalnef",
X    "Rewuorb", "Rellenk", "Yad", "Cire Htims", "Y-crad", "Nenilukah", 
X#ifdef OVERLAY
X    "Erreip", "Nehpets", "Mron", "Snivek",
X#endif
X#ifdef MAC
X    "Nhoj-lee", "Evad\'kh", "Ettaw-noj", "Tsew-mot", "Ydna-s",
X#endif
X#ifdef AMIGA
X    "Falo", "Nosid-da\'r", "Ekim-p", "Rebrol-nek", "Noslo", "Yl-rednow",
X    "Mured-oog",
X#endif
X#ifdef VMS
X    "Lez-tneg", "Ytnu-haled", "Niknar",
X#endif
X    ""
X};
X
Xstatic const char *shkgeneral[] = {
X    /* Suriname */
X    "Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi",
X    "Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo",
X    "Akalapi", "Sipaliwini",
X    /* Greenland */
X    "Annootok", "Upernavik", "Angmagssalik",
X    /* N. Canada */
X    "Aklavik", "Inuvik", "Tuktoyaktuk",
X    "Chicoutimi", "Ouiatchouane", "Chibougamau",
X    "Matagami", "Kipawa", "Kinojevis",
X    "Abitibi", "Maganasipi",
X    /* Iceland */
X    "Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri",
X    "Holmavik",
X    ""
X};
X
X/*
X * To add new shop types, all that is necessary is to edit the shtypes[] array.
X * See mkroom.h for the structure definition. Typically, you'll have to lower
X * some or all of the probability fields in old entries to free up some
X * percentage for the new type.
X *
X * The placement type field is not yet used but will be in the near future.
X *
X * The iprobs array in each entry defines the probabilities for various kinds
X * of artifacts to be present in the given shop type. You can associate with
X * each percentage either a generic artifact type (represented by one of the
X * *_SYM macros) or a specific artifact (represented by an onames.h define).
X * In the latter case, prepend it with a unary minus so the code can know
X * (by testing the sign) whether to use mkobj() or mksobj().
X */
X
Xconst struct shclass shtypes[] = {
X	{"general store", RANDOM_SYM,
X#ifdef SPELLS
X	    44,
X#else
X	    47,
X#endif
X	    D_SHOP, {{100, RANDOM_SYM}, {0, 0}, {0, 0}}, (char **)shkgeneral},
X	{"used armor dealership", ARMOR_SYM, 14,
X	    D_SHOP, {{90, ARMOR_SYM}, {10, WEAPON_SYM}, {0, 0}}, (char **)shkarmors},
X	{"second hand bookstore", SCROLL_SYM, 10, D_SHOP,
X#ifdef SPELLS
X	    {{90, SCROLL_SYM}, {10, SPBOOK_SYM}, {0, 0}},
X#else
X	    {{100, SCROLL_SYM}, {0, 0}, {0, 0}},
X#endif
X	    (char **)shkbooks},
X	{"liquor emporium", POTION_SYM, 10, D_SHOP,
X	    {{100, POTION_SYM}, {0, 0}, {0, 0}}, (char **)shkliquors},
X	{"antique weapons outlet", WEAPON_SYM, 5, D_SHOP,
X	    {{90, WEAPON_SYM}, {10, ARMOR_SYM}, {0, 0}}, (char **)shkweapons},
X	{"delicatessen", FOOD_SYM, 5, D_SHOP,
X	    {{95, FOOD_SYM}, {5, POTION_SYM}, {0, 0}}, (char **)shkfoods},
X	{"jewelers", RING_SYM, 3, D_SHOP,
X	    {{85, RING_SYM}, {10, GEM_SYM}, {5, AMULET_SYM}, {0, 0}}, (char **)shkrings},
X	{"quality apparel and accessories", WAND_SYM, 3, D_SHOP,
X	    {{90, WAND_SYM}, {5, -LEATHER_GLOVES}, {5, -ELVEN_CLOAK}, {0, 0}},
X	     (char **)shkwands},
X	{"hardware store", TOOL_SYM, 3, D_SHOP,
X	    {{100, TOOL_SYM}, {0, 0}, {0, 0}}, (char **)shktools},
X	/* Actually shktools is ignored; the code specifically chooses a
X	 * random implementor name (the only shop type with random shopkeepers)
X	 */
X#ifdef SPELLS
X	{"rare books", SPBOOK_SYM, 3, D_SHOP,
X	    {{90, SPBOOK_SYM}, {10, SCROLL_SYM}, {0, 0}}, (char **)shkbooks},
X#endif
X	{NULL, 0, 0, 0, {{0, 0}, {0, 0}, {0, 0}}, (char **)0}
X};
X
Xstatic void
Xmkshobj_at(shp, sx, sy)
X/* make an object of the appropriate type for a shop square */
Xconst struct shclass *shp;
Xint sx, sy;
X{
X	register struct monst *mtmp;
X	int atype;
X	struct permonst *ptr;
X
X	if (rn2(100) < dlevel && !MON_AT(sx, sy) && (ptr = mkclass(S_MIMIC)) &&
X				(mtmp=makemon(ptr,sx,sy))) {
X		mtmp->mimic = 1;
X		/* note: makemon will set the mimic symbol to a shop item */
X		if (rn2(10) >= dlevel) {
X			mtmp->m_ap_type = M_AP_OBJECT;
X			mtmp->mappearance = STRANGE_OBJECT;
X		}
X	} else if ((atype = get_shop_item(shp - shtypes)) < 0)
X		(void) mksobj_at(-atype, sx, sy);
X	else (void) mkobj_at(atype, sx, sy, TRUE);
X}
X
Xstatic void
Xfindname(nampt, nlp)
X/* extract a shopkeeper name for the given shop type */
X	char *nampt;
X	const char *nlp[];
X{
X    register int i;
X
X    for(i = 0; i < dlevel; i++)
X	if (strlen(nlp[i]) == 0) {
X	    /* Not enough names, try general name */
X	    if (nlp != shkgeneral)
X		findname(nampt, shkgeneral);
X	    else
X		Strcpy(nampt, "Dirk");
X	    return;
X	}
X    (void) strncpy(nampt, nlp[i-1], PL_NSIZ);
X    nampt[PL_NSIZ-1] = 0;
X}
X
Xstatic int
Xshkinit(shp, sroom)	/* create a new shopkeeper in the given room */
Xconst struct shclass	*shp;
Xstruct mkroom	*sroom;
X{
X	register int sh, sx, sy;
X	struct monst *shk;
X
X	/* place the shopkeeper in the given room */
X	sh = sroom->fdoor;
X	sx = doors[sh].x;
X	sy = doors[sh].y;
X
X	/* check that the shopkeeper placement is sane */
X	if(sx == sroom->lx-1) sx++; else
X	    if(sx == sroom->hx+1) sx--; else
X		if(sy == sroom->ly-1) sy++; else
X		    if(sy == sroom->hy+1) sy--; else {
X#ifdef DEBUG
X# ifdef WIZARD
X		    /* Said to happen sometimes, but I have never seen it. */
X		    /* Supposedly fixed by fdoor change in mklev.c */
X			if(wizard) {
X			    register int j = sroom->doorct;
X
X			    pline("Where is shopdoor?");
X			    pline("Room at (%d,%d),(%d,%d).",
X				  sroom->lx, sroom->ly, sroom->hx, sroom->hy);
X			    pline("doormax=%d doorct=%d fdoor=%d",
X			    doorindex, sroom->doorct, sh);
X			    while(j--) {
X				pline("door [%d,%d]", doors[sh].x, doors[sh].y);
X				sh++;
X			    }
X			    more();
X			}
X# endif
X#endif
X			return(-1);
X		    }
X
X	if(MON_AT(sx, sy)) rloc(m_at(sx, sy)); /* insurance */
X
X	/* now initialize the shopkeeper monster structure */
X	if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy))) return(-1);
X	shk->isshk = shk->mpeaceful = 1;
X	shk->msleep = 0;
X	shk->mtrapseen = ~0;	/* we know all the traps already */
X	ESHK(shk)->shoproom = sroom - rooms;
X	ESHK(shk)->shoplevel = dlevel;
X	ESHK(shk)->shd = doors[sh];
X	ESHK(shk)->shk.x = sx;
X	ESHK(shk)->shk.y = sy;
X	ESHK(shk)->robbed = 0L;
X	ESHK(shk)->credit = 0L;
X	ESHK(shk)->debit = 0L;
X	ESHK(shk)->visitct = 0;
X	ESHK(shk)->following = 0;
X	ESHK(shk)->billct = 0;
X	shk->mgold = 1000L + 30L*(long)rnd(100);	/* initial capital */
X	if (shp->shknms == (char **)shktools) {
X		static int NEARDATA who;
X		who = rn2(sizeof(shktools)/sizeof(char *) - 1);
X		if (who==21) ESHK(shk)->ismale = FALSE;
X		else ESHK(shk)->ismale = TRUE;
X		(void) strncpy(ESHK(shk)->shknam, shp->shknms[who], PL_NSIZ);
X		ESHK(shk)->shknam[PL_NSIZ-1] = 0;
X	} else {
X		ESHK(shk)->ismale = dlevel%2;
X		findname(ESHK(shk)->shknam, (const char **)shp->shknms);
X	}
X
X	return(sh);
X}
X
Xvoid
Xstock_room(shp, sroom)
X/* stock a newly-created room with artifacts */
Xconst struct shclass	*shp;
Xregister struct mkroom *sroom;
X{
X    /*
X     * Someday soon we'll dispatch on the dist field of shclass to do
X     * different placements in this routine. Currently it only supports
X     * shop-style placement (all squares except a row nearest the first
X     * door get artifacts).
X     */
X    register int sx, sy, sh;
X    char buf[BUFSZ];
X
X    /* first, try to place a shopkeeper in the room */
X    if ((sh = shkinit(shp, sroom)) < 0)
X	return;
X
X    /* make sure no doorways without doors, and no */
X    /* trapped doors, in shops.			   */
X    sx = doors[sroom->fdoor].x;
X    sy = doors[sroom->fdoor].y;
X
X    if(levl[sx][sy].doormask == D_NODOOR) {
X	    levl[sx][sy].doormask = D_ISOPEN;
X	    mnewsym(sx,sy);
X    }
X    if(levl[sx][sy].typ == SDOOR) {
X	    levl[sx][sy].typ = DOOR;
X	    mnewsym(sx,sy);
X    }
X    if(levl[sx][sy].doormask & D_TRAPPED) {	
X	    levl[sx][sy].doormask &= ~D_TRAPPED;
X	    levl[sx][sy].doormask = D_LOCKED;
X    }
X
X    if(levl[sx][sy].doormask == D_LOCKED) {
X	    register int m = sx, n = sy;
X
X	    if(IS_ROOM(levl[sx+1][sy].typ)) m--;
X	    else if(IS_ROOM(levl[sx-1][sy].typ)) m++;
X	    if(IS_ROOM(levl[sx][sy+1].typ)) n--;
X	    else if(IS_ROOM(levl[sx][sy-1].typ)) n++;
X	    Sprintf(buf, "Closed for inventory"); 
X	    make_engr_at(m, n, buf); 
X    }
X
X    for(sx = sroom->lx; sx <= sroom->hx; sx++)
X	for(sy = sroom->ly; sy <= sroom->hy; sy++) {
X	    if((sx == sroom->lx && doors[sh].x == sx-1) ||
X	       (sx == sroom->hx && doors[sh].x == sx+1) ||
X	       (sy == sroom->ly && doors[sh].y == sy-1) ||
X	       (sy == sroom->hy && doors[sh].y == sy+1)) continue;
X	    mkshobj_at(shp, sx, sy);
X	}
X
X    /*
X     * Special monster placements (if any) should go here: that way,
X     * monsters will sit on top of artifacts and not the other way around.
X     */
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xint
Xsaleable(nshop, obj)			/* does "shop" stock this item type */
Xregister int nshop;
Xregister struct	obj *obj;
X{
X	int i;
X
X	if(shtypes[nshop].symb == RANDOM_SYM) return(1);
X	else {
X	    for(i = 0; shtypes[nshop].iprobs[i].iprob; i++)
X		if(shtypes[nshop].iprobs[i].itype < 0) {
X		   if(shtypes[nshop].iprobs[i].itype == - obj->otyp) return(1);
X		}
X		else if(shtypes[nshop].iprobs[i].itype == obj->olet) return(1);
X	}
X	return(0);
X}
X
X/* positive value: letter; negative value: specific item type */
Xint
Xget_shop_item(type)
Xint type;
X{
X	const struct shclass *shp = shtypes+type;
X	register int i,j;
X
X	/* select an appropriate artifact type at random */
X	for(j = rnd(100), i = 0; j -= shp->iprobs[i].iprob; i++)
X		if (j < 0) break;
X
X	return shp->iprobs[i].itype;
X}
X
X#endif /* OVL0 */
END_OF_FILE
if test 13176 -ne `wc -c <'src/shknam.c'`; then
    echo shar: \"'src/shknam.c'\" unpacked with wrong size!
fi
# end of 'src/shknam.c'
fi
if test -f 'src/vault.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/vault.c'\"
else
echo shar: Extracting \"'src/vault.c'\" \(12809 characters\)
sed "s/^X//" >'src/vault.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)vault.c	3.0	88/10/25
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X#include "vault.h"
X
XSTATIC_DCL boolean FDECL(in_vault,(int,int));
XSTATIC_DCL struct monst *NDECL(findgd);
X
X#ifdef OVLB
X
Xstatic boolean FDECL(clear_fcorr, (struct monst *,BOOLEAN_P));
Xstatic void FDECL(restfakecorr,(struct monst *));
Xstatic boolean FDECL(in_fcorridor, (struct monst *,int,int));
X
Xstatic boolean
Xclear_fcorr(grd, forceshow)
Xregister struct monst *grd;
Xregister boolean forceshow;
X{
X	register int fcx, fcy, fcbeg;
X	register struct rm *crm;
X	register struct monst *mtmp = (struct monst *)0;
X
X	while((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
X		fcx = EGD(grd)->fakecorr[fcbeg].fx;
X		fcy = EGD(grd)->fakecorr[fcbeg].fy;
X		if(!in_fcorridor(grd, u.ux, u.uy) && EGD(grd)->gddone)
X			forceshow = TRUE;
X		if((u.ux == fcx && u.uy == fcy) || 
X		   (!forceshow && cansee(fcx,fcy))) return(FALSE);
X		if(mtmp = m_at(fcx,fcy)) {
X			if(mtmp->isgd) return(FALSE);
X			else if(!in_fcorridor(grd, u.ux, u.uy)) {
X			    rloc(mtmp);
X			    if(mtmp->mpeaceful) You("hear a muffled yelp.");
X			}
X		}
X		crm = &levl[fcx][fcy];
X		crm->typ = EGD(grd)->fakecorr[fcbeg].ftyp;
X		if(!crm->typ) crm->seen = 0;
X		newsym(fcx,fcy);
X		if(cansee(fcx,fcy)) prl(fcx,fcy);
X		EGD(grd)->fcbeg++;
X	}
X	return(TRUE);
X}
X
Xstatic void
Xrestfakecorr(grd) 
Xregister struct monst *grd;
X{
X	/* it seems he left the corridor - let the guard disappear */
X	if(clear_fcorr(grd, FALSE)) mongone(grd);
X}
X
Xboolean
Xgrddead(grd)				/* called in mon.c */
Xregister struct monst *grd;
X{
X	register boolean dispose = clear_fcorr(grd, TRUE);
X
X	if(!dispose) {
X		remove_monster(grd->mx, grd->my);
X		place_monster(grd, 0, 0);
X		EGD(grd)->ogx = grd->mx;
X		EGD(grd)->ogy = grd->my;
X		dispose = clear_fcorr(grd, TRUE);
X	}
X	return(dispose);
X}
X
Xstatic boolean
Xin_fcorridor(grd, x, y)
Xregister struct monst *grd;
Xint x, y; 
X{
X	register int fci;
X
X	for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++)
X		if(x == EGD(grd)->fakecorr[fci].fx &&
X				y == EGD(grd)->fakecorr[fci].fy)
X			return(TRUE);
X	return(FALSE);
X}
X
XSTATIC_OVL
Xstruct monst *
Xfindgd() {
X
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X	    if(mtmp->isgd && EGD(mtmp)->gdlevel == dlevel)
X		return(mtmp);
X	return((struct monst *)0);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
XSTATIC_OVL
Xboolean
Xin_vault(x, y)
Xint x, y;
X{
X    register int roomno = inroom(x, y);
X
X    if(roomno < 0) return(FALSE);
X    return(rooms[roomno].rtype == VAULT);
X}
X
Xvoid
Xinvault() {
X
X#ifdef BSD_43_BUG
X    int dummy;		/* hack to avoid schain botch */
X#endif
X    struct monst *guard;
X
X    if(!in_vault(u.ux, u.uy)) {
X	u.uinvault = 0;
X	return;
X    }
X
X    guard = findgd();
X    if(++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
X	char buf[BUFSZ];
X	register int x, y, dd, gx, gy;
X
X	/* first find the goal for the guard */
X	for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
X	  for(y = u.uy-dd; y <= u.uy+dd; y++) {
X	    if(y < 0 || y > ROWNO-1) continue;
X	    for(x = u.ux-dd; x <= u.ux+dd; x++) {
X	      if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
X		x = u.ux+dd;
X	      if(x < 0 || x > COLNO-1) continue;
X	      if(levl[x][y].typ == CORR) goto fnd;
X	    }
X	  }
X	}
X	impossible("Not a single corridor on this level??");
X	tele();
X	return;
Xfnd:
X	gx = x; gy = y;
X
X	/* next find a good place for a door in the wall */
X	x = u.ux; y = u.uy;
X	while(levl[x][y].typ == ROOM) {
X		register int dx,dy;
X
X		dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X		dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X		if(abs(gx-x) >= abs(gy-y))
X			x += dx;
X		else
X			y += dy;
X	}
X
X	/* make something interesting happen */
X	if(!(guard = makemon(&mons[PM_GUARD], x, y))) return;
X	guard->isgd = 1;
X	guard->mpeaceful = 1;
X	EGD(guard)->gddone = 0;
X	EGD(guard)->ogx = x;
X	EGD(guard)->ogy = y;
X	EGD(guard)->gdlevel = dlevel;
X	EGD(guard)->vroom = inroom(x, y);
X	EGD(guard)->warncnt = 0;
X
X	if(!cansee(guard->mx, guard->my)) {
X		mongone(guard);
X		return;
X	}
X
X	reset_faint();			/* if fainted - wake up */
X	pline("Suddenly one of the Vault's guards enters!");
X	pmon(guard);
X	stop_occupation();		/* if occupied, stop it *now* */
X	do {
X		pline("\"Hello stranger, who are you?\" - ");
X		getlin(buf);
X	} while (!letter(buf[0]));
X
X	if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
X		verbalize("Oh, yes, of course.  Sorry to have disturbed you.");
X		mongone(guard);
X		return;
X	}
X	clrlin();
X	verbalize("I don't know you.");
X	if(!u.ugold)
X	    verbalize("Please follow me.");
X	else {
X	    verbalize("Most likely all that gold was stolen from this vault.");
X	    verbalize("Please drop that gold and follow me.");
X	}
X	EGD(guard)->gdx = gx;
X	EGD(guard)->gdy = gy;
X	EGD(guard)->fcbeg = 0;
X	EGD(guard)->fakecorr[0].fx = x;
X	EGD(guard)->fakecorr[0].fy = y;
X	EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
X	levl[x][y].typ = DOOR;
X	levl[x][y].doormask = D_NODOOR;
X	EGD(guard)->fcend = 1;
X	EGD(guard)->warncnt = 1;
X    }
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X/*
X * return  1: he moved,  0: he didn't,  -1: let m_move do it,  -2: died
X */
Xint
Xgd_move(grd)
Xregister struct monst *grd;
X{
X	int x, y, nx, ny, m, n;
X	int dx, dy, gx, gy, i, fci;
X	uchar typ;
X	struct fakecorridor *fcp;
X	register struct rm *crm;
X	register struct gold *gold;
X	register boolean goldincorridor = FALSE;
X
X#ifdef __GNULINT__
X	m = n = 0;
X#endif
X	if(EGD(grd)->gdlevel != dlevel) return(-1);
X	if(!grd->mpeaceful) {
X	    if((in_vault(grd->mx, grd->my) && !in_vault(u.ux, u.uy)) ||
X	       (in_fcorridor(grd, grd->mx, grd->my) && !in_vault(u.ux, u.uy) &&
X			!in_fcorridor(grd, u.ux, u.uy))) {
X		rloc(grd);
X		(void) clear_fcorr(grd, TRUE);
X		goto letknow;
X	    }
X	    if(!in_fcorridor(grd, grd->mx, grd->my))
X		(void) clear_fcorr(grd, TRUE);
X	    return(-1);
X	}
X	if(abs(EGD(grd)->ogx - grd->mx) > 1 || 
X			abs(EGD(grd)->ogy - grd->my) > 1)
X		return(-1);	/* teleported guard - treat as monster */
X	if(EGD(grd)->fcend == 1) {
X	    if(in_vault(u.ux, u.uy) && 
X			(u.ugold || um_dist(grd->mx, grd->my, 1))) {
X		if(EGD(grd)->warncnt == 3)
X			pline("\"Again, %sfollow me!\"", 
X				u.ugold ? "drop that gold and " : "");
X		if(EGD(grd)->warncnt == 7) {
X			m = grd->mx;
X			n = grd->my;
X			verbalize("You've been warned, knave!");
X			mnexto(grd);
X			levl[m][n].typ = EGD(grd)->fakecorr[0].ftyp;
X			newsym(m,n);
X			if(cansee(m,n)) prl(m,n);
X			grd->mpeaceful = 0;
X			return(-1);
X		}
X		/* not fair to get mad when (s)he's fainted */
X		if(!is_fainted()) EGD(grd)->warncnt++;
X		return(0);
X	    }
X	    if(!in_vault(u.ux,u.uy) && u.ugold) { /* player teleported */
X		m = grd->mx;
X		n = grd->my;
X		rloc(grd);
X		levl[m][n].typ = EGD(grd)->fakecorr[0].ftyp;
X		newsym(m,n);
X		if(!Blind) prl(m,n);
X		grd->mpeaceful = 0;
Xletknow:
X		if(!cansee(grd->mx, grd->my))
X		    You("hear the shrill sound of a guard's whistle.");
X		else
X		    You(um_dist(grd->mx, grd->my, 2) ?
X			"see an angry %s approaching." :
X			"are confronted by an angry %s.",
X			lmonnam(grd)+4);
X		return(-1);
X	    }
X	}
X	if(EGD(grd)->fcend > 1) {
X	    if(EGD(grd)->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
X		  !EGD(grd)->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
X		  levl[EGD(grd)->fakecorr[0].fx][EGD(grd)->fakecorr[0].fy].typ
X				 == EGD(grd)->fakecorr[0].ftyp) {
X		pline("The guard, confused, disappears.");
X		goto cleanup;
X	    }
X	    if(u.ugold && (in_fcorridor(grd, u.ux, u.uy) || /*cover 'blind' spot*/
X		    (EGD(grd)->fcend > 1 && in_vault(u.ux, u.uy)))) {
X		if(!grd->mx) {
X			restfakecorr(grd);
X			return(-2);
X		}
X		if(EGD(grd)->warncnt < 6) {
X			EGD(grd)->warncnt = 6;
X			verbalize("Drop all your gold, scoundrel!");
X			return(0);
X		} else {
X			verbalize("So be it, rogue!");
X			grd->mpeaceful = 0;
X			return(-1);
X		}	
X	    } 
X	}
X	for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++)
X	    if(g_at(EGD(grd)->fakecorr[fci].fx, EGD(grd)->fakecorr[fci].fy)){
X		m = EGD(grd)->fakecorr[fci].fx;
X		n = EGD(grd)->fakecorr[fci].fy;
X		goldincorridor = TRUE; 
X	    }
X	if(goldincorridor && !EGD(grd)->gddone) {
X		x = grd->mx;
X		y = grd->my;
X		if(m == x && n == y) mpickgold(grd);
X		else if(m == u.ux && n == u.uy) {
X		    gold = g_at(u.ux, u.uy);
X 		    grd->mgold += gold->amount;
X		    freegold(gold);
X		} else {
X		    /* just for insurance... */
X		    if(MON_AT(m, n) && m != grd->mx && n != grd->my) {
X			verbalize("Out of my way, scum!");
X			rloc(m_at(m, n));
X		    }
X		    remove_monster(grd->mx, grd->my);
X		    place_monster(grd, m, n);
X		    pmon(grd);
X		    mpickgold(grd);
X		}
X		pline("The %s%s picks up the gold.", lmonnam(grd)+4,
X				grd->mpeaceful ? " calms down and" : "");
X		if(x != grd->mx || y != grd->my) {
X		    remove_monster(grd->mx, grd->my);
X		    place_monster(grd, x, y);
X		    pmon(grd);
X		}
X		goldincorridor = FALSE;
X		if(!grd->mpeaceful) return(-1);
X		else {
X		    EGD(grd)->warncnt = 5;
X		    return(0);
X		}
X	}
X	if(um_dist(grd->mx, grd->my, 1) || EGD(grd)->gddone) {
X		restfakecorr(grd);
X		return(0);	/* didn't move */
X	}
X	x = grd->mx;
X	y = grd->my;
X	/* look around (hor & vert only) for accessible places */
X	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
X	  if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {
X
X	    typ = (crm = &levl[nx][ny])->typ;
X	    if(!IS_STWALL(typ) && !IS_POOL(typ)) {
X
X		for(i = EGD(grd)->fcbeg; i < EGD(grd)->fcend; i++)
X		    if(EGD(grd)->fakecorr[i].fx == nx && 
X				EGD(grd)->fakecorr[i].fy == ny)
X			goto nextnxy;
X
X		if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
X			continue;
X
X		/* seems we found a good place to leave him alone */
X		EGD(grd)->gddone = 1;
X		if(ACCESSIBLE(typ)) goto newpos;
X#ifdef STUPID
X		if (typ == SCORR)
X		    crm->typ = CORR;
X		else
X		    crm->typ = DOOR;
X#else
X		crm->typ = (typ == SCORR) ? CORR : DOOR;
X#endif
X		if(crm->typ == DOOR) crm->doormask = D_NODOOR;
X		goto proceed;
X	    }
X	  }
Xnextnxy:	;
X	}
X	nx = x;
X	ny = y;
X	gx = EGD(grd)->gdx;
X	gy = EGD(grd)->gdy;
X	dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X	dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X	if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
X
X	while((typ = (crm = &levl[nx][ny])->typ) != 0) {
X	/* in view of the above we must have IS_WALL(typ) or typ == POOL */
X	/* must be a wall here */
X		if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) &&
X		    SPACE_POS(levl[nx+nx-x][ny+ny-y].typ)){
X			crm->typ = DOOR;
X			crm->doormask = D_NODOOR;
X			goto proceed;
X		}
X		if(dy && nx != x) {
X			nx = x; ny = y+dy;
X			continue;
X		}
X		if(dx && ny != y) {
X			ny = y; nx = x+dx; dy = 0;
X			continue;
X		}
X		/* I don't like this, but ... */
X		crm->typ = DOOR;
X		crm->doormask = D_NODOOR;
X		goto proceed;
X	}
X	crm->typ = CORR;
Xproceed:
X	if(cansee(nx,ny)) {
X		mnewsym(nx,ny);
X		prl(nx,ny);
X	}
X	fcp = &(EGD(grd)->fakecorr[EGD(grd)->fcend]);
X	if(EGD(grd)->fcend++ == FCSIZ) panic("fakecorr overflow");
X	fcp->fx = nx;
X	fcp->fy = ny;
X	fcp->ftyp = typ;
Xnewpos:
X	if(EGD(grd)->gddone) {
X		/* The following is a kluge.  We need to keep     */
X		/* the guard around in order to be able to make   */
X		/* the fake corridor disappear as the player      */
X		/* moves out of it, but we also need the guard    */
X		/* out of the way.  We send the guard to never-   */
X		/* never land.  We set ogx ogy to mx my in order  */
X		/* to avoid a check at the top of this function.  */
X		/* At the end of the process, the guard is killed */
X		/* in restfakecorr().				  */
Xcleanup:
X		remove_monster(grd->mx, grd->my);
X		place_monster(grd, 0, 0);
X		EGD(grd)->ogx = grd->mx;
X		EGD(grd)->ogy = grd->my;
X		restfakecorr(grd);
X		if(in_fcorridor(grd, u.ux, u.uy) || cansee(grd->mx, grd->my)) {
X		    pline("Suddenly, the guard disappears.");
X		    return(1);
X		}
X		return(-2);
X	}
X	EGD(grd)->ogx = grd->mx;	/* update old positions */
X	EGD(grd)->ogy = grd->my;
X	remove_monster(grd->mx, grd->my);
X	place_monster(grd, nx, ny);
X	pmon(grd);
X	restfakecorr(grd);
X	return(1);
X}
X
X/* Routine when dying or quitting with a vault guard around */
Xvoid
Xpaygd() {
X
X	register struct monst *grd = findgd();
X	int gx,gy;
X	char buf[BUFSZ];
X
X	if (!u.ugold || !grd) return;
X
X	if (u.uinvault) {
X	    Your("%ld zorkmid%s goes into the Magic Memory Vault.",
X		u.ugold, plur(u.ugold));
X	    mkgold(u.ugold, u.ux, u.uy);
X	    u.ugold = 0L;
X	} else {
X	    if(grd->mpeaceful) { /* he has no "right" to your gold */
X		mongone(grd);
X		return;
X	    }
X	    mnexto(grd);
X	    pmon(grd);
X	    pline("%s remits your gold to the vault.", Monnam(grd));
X	    gx = rooms[EGD(grd)->vroom].lx + rn2(2);
X	    gy = rooms[EGD(grd)->vroom].ly + rn2(2);
X	    mkgold(u.ugold, gx, gy);
X	    u.ugold = 0L;
X	    Sprintf(buf,
X		"To Croesus: here's the gold recovered from the %s %s...",
X		player_mon()->mname, plname);
X	    make_engr_at(gx, gy, buf);
X	}
X	mongone(grd);
X}
X
X#ifdef SOUNDS
Xboolean
Xgd_sound() {  /* prevent "You hear footsteps.." when inappropriate */
X	register struct monst *grd = findgd();
X
X	return(grd == (struct monst *)0);
X}
X#endif
X
X#endif /* OVLB */
END_OF_FILE
if test 12809 -ne `wc -c <'src/vault.c'`; then
    echo shar: \"'src/vault.c'\" unpacked with wrong size!
fi
# end of 'src/vault.c'
fi
echo shar: End of archive 43 \(of 56\).
cp /dev/null ark43isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 56 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
    echo Building monst.c from monst.c1 and monst.c2
    cat src/monst.c1 src/monst.c2 > src/monst.c
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0