[comp.sources.games] v03i016: NetHack2.2 - display oriented dungeons and dragons, Part16/20

games-request@tekred.TEK.COM (12/03/87)

Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 3, Issue 16
Archive-name: nethack2.2/Part16



#! /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 20)."
# Contents:  README.OLD config.h dogmove.c fountain.c prisym.c
#   termcap.c write.c
# Wrapped by billr@tekred on Tue Dec  1 16:25:11 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README.OLD -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README.OLD\"
else
echo shar: Extracting \"README.OLD\" \(7714 characters\)
sed "s/^X//" >README.OLD <<'END_OF_README.OLD'
X			      NetHack V1.0 README
X
X	This file contains information on NetHack, it's history, features,
Xand installation proceedures.
X
X	For a detailed history of the game, see the README.ORIG file, which
Xcontains three separate readme files, dating back to the original release of
Xthe game (then named hack) by Jay Fenlason.
X
X	 History:
X	==========
X
X	NetHack is the product of literally dozens of people's work.  I have
Xa list of *some* of those who made major additions to the game which appears
Xbelow:
X
XJay Fenlason	wrote the original release of "Hack", with help	from
X		Kenny Woodland, Mike Thome and Jon Payne.
X
XAndries Brouwer	did a major re-write on the program and	publshed (at least)
X		two versions to the Usenet.
X
XDon Kneller	ported the 1.0.3 version of Hack to the PC, creating PC-Hack.
X
X	The following folks didn't actually re-write the game, or port it to
Xa new machine, but have made significant contributions to the playability of
Xthe game:
X
Xins_akaa@jhunix.UUCP (Ken Arromdee)
X
X	New character classes.
X	New weapons code.
X	Armor weights implemented.
X	New tools code.
X	Polymorph self code.
X	additional bug fixes.
X
Xsrt@ucla-cs (Scott R. Turner)
X
X	Rockmole & Keystone Kops code.
X	Squeeky Board & Magic traps.
X	Fountain code.
X	more bug fixes.
X
Xgil@cornell.UUCP (Gil Neiger)
X
X	Magic Marker code.
X	Fountain code enhancements.
X	Enhancements to dozens of routines.
X	more bug fixes (esp. in hack.zap.c)
X
Xericb@hplsla.UUCP (Eric Backus)
X
X	#dip mods to fountain code.
X	yet more bug fixes.
X
X	As for myself, I have added new character classes and traps, the
XThrone Room, spellbooks and spellcasting, implemented code for praying and
Xmade some enhancements to the endgame.
X
X	NetHack is an integrated version of two major "flavors" of Hack,
XUnix and PC Hack.  It is designed so that you should be able to compile it
Xin either one of the target enviornments.  The filenames of all modules have
Xbeen modified to correspond with the PC-Hack standards implemented by Don
XKneller.
X
X	 config.h
X	==========
X
X	As distributed, it is set up to compile on my machine (a Pyramid 98xe
Xin the Berkeley universe).  Due to the large number of "features" in NetHack,
Xthe config file (config.h) is used to select the target options.
X
X	Here is a list of the currently supported options:
X
XSPELLS		Spell casting code
XPRAYERS		Prayer code
XKAA		Various changes made by Ken Arromdee
XMARKER		Magic marker modification
XNEWCLASS	New classes, traps, and Throne Rooms.
XSAFE_ATTACK 	Safe attack code
XPROBING		Wand of probing code
XDIAGS		Diagnostics after death/quit
XSORTING		Sorted inventory
XDGK		Additional features by Don Kneller (PC specific)
XDGKMOD		Additional features by Don Kneller (Non-PC specific)
XREDO 		support for redoing last command
XHARD		Enhanced wizard code among other things.
XNEWTRAPS	Magic and Squeeky board traps
XFREEHAND	Cannot use Pick-axe without wielding it.
XSPIDERS		Spiders and webs
XFOUNTAINS	Fountain code
XKOPS		Keystone Kops
XROCKMOLE	Rockmoles
X
XStatus Line options:
X
XGOLD_ON_BOTL
XEXP_ON_BOTL
X
X	In a number of cases, code written for one specific version of Hack
Xor another was separated out and given it's own designation (eg. REDO has
Xbeen moved out of DGKMOD which was moved out of DGK from PC-HACK).
X
X	 Some New Features:
X	====================
X
X	Some of the old code (eg. KOPS) has been enhanced to allow for more
Xfunctionality.  Here's a couple of examples - you can find out the rest for
Xyourself in the traditional Hack style :-)
X
X	Kops now throw cream pies (thank/blame KAA for the suggestion).
X
X	The wizard may not stay dead!!!
X
X	There are a couple of new types of demons.
X
X	Demons may not be aggressive.
X
X	There are lots more of these little gems, with sufficient hints in
Xvarious fortune cookies to give away enough clues.
X
X	 Makefiles:
X	============
X
X	The Unix "Makefile" has been enhanced to make installation cleaner
Xand also to allow "initialization" of the play directories (WARNING: this
Xwill destroy old score files!!!).  The PC Makefile hasn't been upgraded in
Xthis respect.
X
X	The program "makedefs" has been modified in order to allow limited
Xuse of "#ifdef/#else/#endif" sets in objects.h.  Makedefs will only generate
Xone #define for any number of ocurrences of a given object name string.  In
Xaddition, "makedefs" also generates alternate defines for "DEAD_xxxxx" in
Xthose cases where a monster has been given an alternate identity.
X
X	Makedefs has also been modified in order that it may be used to
Xinitialize the following variable def files:
X
X	objects.h	-o option,  see above.
X	trap.h		-t option,  trap type defines.
X	date.h		-d option,  date string.
X	data		-D option,  optional monster names.
X	rumors		-r option,  optional rumor addition.
X
X	To compile the program on any 4.n or Sys V system, you should only
Xneed to copy "Makefile.unix" to "Makefile", set up "Makefile" and "config.h",
Xthen type "make".  On a Xenix system, use "Makefile.xenix" and similarly set
Xup "Makefile" and "config.h", with "STUPID" defined.  At this point in time,
XI can get the Xenix version to build, but it will immediately dump core on
Xinvocation.
X
X	 Known Problems:
X	=================
X
X	There are several known problem areas and deficiencies in the code
Xwhich I haven't yet addressed, prefering to get the really fatal bugs out of
Xthe way.  Here's a short list of things someone out there might want to work
Xon (and it is by no means complete):
X
X	- The WALKIES code is really crude.  Fido get's mnexto()'d you when
X	  he gets out of the effective leash range.  I haven't yet been able
X	  to integrate leashed movement into dogmove().  You might just want
X	  to comment out the #define in config.h.
X
X	- ROCKMOLES have some problems with screen updating.  I didn't make
X	  any changes to the code I received, and have noticed some distinct
X	  problems with walls not being set to "door" until the rockmole
X	  moves off the cell.
X
X	- There are some problems in the item selection code, the usual effect
X	  of which is to leave the cursor sitting at some arbitrary point on
X	  the screen instead of returning it to the upper left hand corner or
X	  onto the "@".  This doesn't affect the screen updating, so I have
X	  ignored it up to now.
X
X	- REDO may not be completely implemented.  I am still working on it
X	  here but would appreciate any help anyone out there might want to
X	  give.
X
X	I fully expect that about one week's worth of play on the net will
Xresult in a couple dozen bugs being discovered.  I would like to keep a lid
Xon the potential explosion of different sub-versions of the game, so if you
Xpossibly can, please send me the bug reports, instead of releasing them to
Xthe general public.  I will apply them to my code here, and will generate an
Xupdate to the release when the mass of fixes (or mass * severity factor) gets
Xlarge enough.  This way, we should be able to keep most of the net up to a
Xcertain level  -  this may turn out to be the first truely net maintained
Xgame.  Unless circumstances change, I will continue to consolidate fixes and
Xmodifications to the game, and will continue to post to the net through
Xcomp.sources.games, with notices of new patches/fixes/mods going out through
Xrec.games.hack.
X
X	 Making Bug Reports:
X	=====================
X
X	To send bug reports, just E-Mail me at any one of the following net
Xaddresses (in order of connectivity):
X
X	seismo!mnetor!genat!mike
X	utzoo!mnetor!genat!mike
X	pyramid!pyrnj!genat!mike
X	utzoo!utgpu!genat!mike
X
X	When you send in a bug report, please keep your code fragments as
Xsmall as possible.  Remember that each site along the way is paying for the
Xtransmission of the code.
X
X						Mike Stephenson
X
XMail:	Genamation Inc.		Phone:	(416) 475-9434
X	351 Steelcase Rd. W
X	Markham, Ontario.	UUCP:	{seismo, utzoo}!mnetor!genat!mike
X	Canada   L3R 3W1
END_OF_README.OLD
if test 7714 -ne `wc -c <README.OLD`; then
    echo shar: \"README.OLD\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f config.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"config.h\"
else
echo shar: Extracting \"config.h\" \(8162 characters\)
sed "s/^X//" >config.h <<'END_OF_config.h'
X/*	SCCS Id: @(#)config.h	2.2	87/11/11
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#ifndef CONFIG	/* make sure the compiler does not see the typedefs twice */
X#define	CONFIG
X
X#define	CHDIR		/* delete if no chdir() available */
X
X/*
X * Some include files are in a different place under SYSV
X * 	BSD		   SYSV
X * <strings.h>		<string.h>
X * <sys/time.h>		<time.h>
X * <sgtty.h>		<termio.h>
X * Some routines are called differently
X * index		strchr
X * rindex		strrchr
X * Also, the code for suspend and various ioctls is only given for BSD4.2
X */
X/* #define MSDOS 	/* define for MS-DOS (actually defined by compiler) */
X#define	UNIX		/* delete if no fork(), exec() available */
X/* #define	GENIX		/* Yet Another Unix Clone */
X#define BSD		/* defind for 4.n BSD  */
X/* #define SYSV		/* define for System V */
X
X/* #define BETA		/* if a beta-test copy  [MRS] */
X#define VERSION	"2.2a"	/* version number. */
X
X#define PYRAMID_BUG 	/* avoid a bug on the Pyramid */
X/* #define APOLLO		/* same for the Apollo */
X/* #define STUPID		/* avoid some complicated expressions if
X			   your C compiler chokes on them */
X/* #define TERMINFO		/* uses "curses" rather than termcap */
X
X#ifdef __TURBOC__
X#define	alloc	malloc
X#define	signal	ssignal
X#endif
X
X#define WIZARD  "mike"	/* the person allowed to use the -D option */
X#define RECORD	"record"/* the file containing the list of topscorers */
X#define	NEWS	"news"	/* the file containing the latest hack news */
X#define	HELP	"help"	/* the file containing a description of the commands */
X#define	SHELP	"hh"	/* abbreviated form of the same */
X#define	RUMORFILE	"rumors"	/* a file with fortune cookies */
X#define	DATAFILE	"data"	/* a file giving the meaning of symbols used */
X#define	FMASK	0660	/* file creation mask */
X
X#ifdef UNIX
X#define	HLOCK	"perm"	/* an empty file used for locking purposes */
X#define LLOCK	"safelock"	/* link to previous */
X
X/*
X * Define DEF_PAGER as your default pager, e.g. "/bin/cat" or "/usr/ucb/more"
X * If defined, it can be overridden by the environment variable PAGER.
X * Hack will use its internal pager if DEF_PAGER is not defined.
X * (This might be preferable for security reasons.)
X * #define DEF_PAGER	".../mydir/mypager"
X */
X
X/*
X * If you define MAIL, then the player will be notified of new mail
X * when it arrives. If you also define DEF_MAILREADER then this will
X * be the default mail reader, and can be overridden by the environment
X * variable MAILREADER; otherwise an internal pager will be used.
X * A stat system call is done on the mailbox every MAILCKFREQ moves.
X */
X#define	MAIL
X#define	DEF_MAILREADER	"/usr/bin/mail"		/* or e.g. /bin/mail */
X#define	MAILCKFREQ	1
X
X
X#define SHELL		/* do not delete the '!' command */
X
X#ifdef BSD
X#define	SUSPEND		/* let ^Z suspend the game */
X#endif
X
X#ifdef BSD
X/* Use the high quality random number routines. */
Xextern long random();
X#define rand()	random()
X#define srand(seed) srandom(seed)
X#else
Xextern long lrand48();
X#define rand()	lrand48()
X#define srand(seed) srand48(seed)
X#endif
X#endif /* UNIX /**/
X
X#ifdef CHDIR
X/*
X * If you define HACKDIR, then this will be the default playground;
X * otherwise it will be the current directory.
X */
X#define HACKDIR	"/usr/games/lib/nethackdir"
X
X/*
X * Some system administrators are stupid enough to make Hack suid root
X * or suid daemon, where daemon has other powers besides that of reading or
X * writing Hack files. In such cases one should be careful with chdir's
X * since the user might create files in a directory of his choice.
X * Of course SECURE is meaningful only if HACKDIR is defined.
X */
X#define SECURE			/* do setuid(getuid()) after chdir() */
X
X/*
X * If it is desirable to limit the number of people that can play Hack
X * simultaneously, define HACKDIR, SECURE and MAX_NR_OF_PLAYERS.
X * #define MAX_NR_OF_PLAYERS	6
X */
X#endif /* CHDIR /**/
X
X/* size of terminal screen is (at least) (ROWNO+2) by COLNO */
X#define	COLNO	80
X#define	ROWNO	22
X
X#ifdef BSD
X#include <strings.h>		/* declarations for strcat etc. */
X#define memcpy(d, s, n)		bcopy(s, d, n)
X#define memcmp(s1, s2, n)	bcmp(s2, s1, n)
X#else
X#include <string.h>		/* idem on System V */
X#define	index	strchr
X#define	rindex	strrchr
X#endif
X
X/*
X * small signed integers (8 bits suffice)
X *	typedef	char	schar;
X * will do when you have signed characters; otherwise use
X *	typedef	short int schar;
X */
Xtypedef	char	schar;
X
X/*
X * small unsigned integers (8 bits suffice - but 7 bits do not)
X * - these are usually object types; be careful with inequalities! -
X *	typedef	unsigned char	uchar;
X * will be satisfactory if you have an "unsigned char" type; otherwise use
X *	typedef unsigned short int uchar;
X */
Xtypedef	unsigned char	uchar;
X
X/*
X * small integers in the range 0 - 127, usually coordinates
X * although they are nonnegative they must not be declared unsigned
X * since otherwise comparisons with signed quantities are done incorrectly
X */
Xtypedef schar	xchar;
Xtypedef	xchar	boolean;		/* 0 or 1 */
X#define	TRUE	1
X#define	FALSE	0
X
X/*
X * Declaration of bitfields in various structs; if your C compiler
X * doesnt handle bitfields well, e.g., if it is unable to initialize
X * structs containing bitfields, then you might use
X *	#define Bitfield(x,n)	uchar x
X * since the bitfields used never have more than 7 bits. (Most have 1 bit.)
X * otherwise:
X *	#define	Bitfield(x,n)	unsigned x:n
X */
X#define	Bitfield(x,n)	uchar x
X
X#define	SIZE(x)	(int)(sizeof(x) / sizeof(x[0]))
X
X#ifdef MSDOS
X#include <fcntl.h>
X#define	exit	msexit		/* do chdir first */
X#ifdef getchar
X#	undef getchar
X#endif /* getchar /**/
X#define getchar tgetch
X#define DGK			/* MS DOS specific enhancements by dgk */
X
X#ifdef DGK
X#  include "msdos.h"	/* contains necessary externs for msdos.c */
X#  define SHELL		/* via exec of COMMAND.COM */
X#  define PATHLEN	64	/* maximum pathlength */
X#  define FILENAME 80	/* maximum filename length (conservative) */
X#  define FROMPERM	1	/* for ramdisk use */
X#  define TOPERM	2	/* for ramdisk use */
X#  define glo(x)	name_file(lock, x)	/* name_file used for bones */
X	extern char *configfile;
X#endif /* DGK /**/
X#endif /* MSDOS /**/
X
X/*
X *	Conditional compilation of special options are controlled here.
X *	If you define the following flags, you will add not only to the
X *	complexity of the game but also to the size of the load module.
X */ 
X
X#define	DOGNAME		/* Name of your first dog as an option */ 
X#define	SPELLS		/* Spell casting by M. Stephenson */
X#define	PRAYERS		/* Prayer code by M. Stephenson */
X#define KAA		/* Various changes made by Ken Arromdee */
X#define MARKER		/* Magic marker modification from Gil Neiger */
X#define	NEWCLASS	/* Samurai/Ninja etc. by M. Stephenson */ 
X#define	SAFE_ATTACK 	/* Safe attack code by Don Kneller */
X#define	PROBING		/* Wand of probing code by Gil Neiger */
X#define	DIAGS		/* Diagnostics after death/quit by Gil Neiger */
X#define	SORTING		/* Sorted inventory by Don Kneller */
X#define	DGKMOD		/* Additional features by Don Kneller */
X#define REDO 		/* support for redoing last command - DGK */
X#define	HARD		/* Enhanced wizard code by M. Stephenson */
X#define	WALKIES		/* Leash code by M. Stephenson */
X#define NEWTRAPS	/* Magic and Squeeky board traps by Scott R. Turner*/
X#define FREEHAND	/* Cannot use Pick-axe without wielding it. */
X#define SPIDERS		/* Spiders and webs by Scott R. Turner */
X#define FOUNTAINS	/* Fountain code by SRT (+ GAN + EB) */
X#define KOPS		/* Keystone Kops by Scott R. Turner */
X#define ROCKMOLE	/* Rockmoles by Scott R. Turner */
X#define COM_COMPL	/* Command line completion by John S. Bien */
X#define GRAPHICS	/* Funky screen character support (Eric S. Raymond) */
X#define HACKOPTIONS	/* Support DGK-style HACKOPTIONS processing (ESR) */
X#define RPH		/* Various hacks by Richard P. Hughey */
X#define KJSMODS		/* Various changes made by Kevin Sweet */
X#define	BVH		/* Additions by Bruce Holloway */
X#define SAC		/* Soldiers, barracks by Steve Creps */
X
X#if defined(MSDOS) && defined(GRAPHICS)
X#define MSDOSCOLOR
X#endif
X
X/*
X *	Status Line options.
X */
X
X#define	GOLD_ON_BOTL
X#define	EXP_ON_BOTL
X	 
X#ifdef REDO
X#define DOAGAIN	'\001'		/* Used in tty.c and cmd.c */
X#endif
X
X#ifdef DGKMOD
X#define LARGEST_INT	((1 << 15) - 1)
X#endif
X
X#endif /* CONFIG /**/
END_OF_config.h
if test 8162 -ne `wc -c <config.h`; then
    echo shar: \"config.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dogmove.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dogmove.c\"
else
echo shar: Extracting \"dogmove.c\" \(7691 characters\)
sed "s/^X//" >dogmove.c <<'END_OF_dogmove.c'
X/*	SCCS Id: @(#)dogmove.c	1.4	87/08/08
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* dogmove.c - version 1.0 */
X
X#include	"hack.h"
X#include "mfndpos.h"
X#include "mkroom.h"
X#include "edog.h"
X
X/* return 0 (no move), 1 (move) or 2 (dead) */
Xdog_move(mtmp, after) register struct monst *mtmp; {
X#ifndef REGBUG
Xregister
X#endif
X	 int nx,ny,omx,omy,appr,nearer,j;
Xint udist,chi,i,whappr;
Xregister struct monst *mtmp2;
Xregister struct permonst *mdat = mtmp->data;
Xregister struct edog *edog = EDOG(mtmp);
Xstruct obj *obj;
Xstruct trap *trap;
Xxchar cnt,chcnt,nix,niy;
Xschar dogroom,uroom;
Xxchar gx,gy,gtyp,otyp;	/* current goal */
Xcoord poss[9];
Xlong info[9];
X#define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy))
X#define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy))
X
X	if(moves <= edog->eattime) return(0);	/* dog is still eating */
X	omx = mtmp->mx;
X	omy = mtmp->my;
X	whappr = (moves - EDOG(mtmp)->whistletime < 5);
X	if(moves > edog->hungrytime + 500 && !mtmp->mconf){
X		mtmp->mconf = 1;
X		mtmp->mhpmax /= 3;
X		if(mtmp->mhp > mtmp->mhpmax)
X			mtmp->mhp = mtmp->mhpmax;
X		if(cansee(omx,omy))
X			pline("%s is confused from hunger.", Monnam(mtmp));
X		else	pline("You feel worried about %s.", monnam(mtmp));
X	} else
X	if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){
X#ifdef WALKIES
X		if(mtmp->mleashed) {
X			mtmp->mleashed = 0;
X			pline("Your leash goes slack...");
X		}
X#endif
X		if(cansee(omx,omy))
X			pline("%s dies%s.", Monnam(mtmp),
X			      (mtmp->mhp >= 1) ? "" : " from hunger");
X		else
X			pline("You have a sad feeling for a moment, then it passes.");
X		mondied(mtmp);
X		return(2);
X	}
X	dogroom = inroom(omx,omy);
X	uroom = inroom(u.ux,u.uy);
X	udist = dist(omx,omy);
X
X	/* maybe we tamed him while being swallowed --jgm */
X	if(!udist) return(0);
X
X	/* if we are carrying sth then we drop it (perhaps near @) */
X	/* Note: if apport == 1 then our behaviour is independent of udist */
X	if(mtmp->minvent){
X		if(!rn2(udist) || !rn2((int) edog->apport))
X		if(rn2(10) < edog->apport){
X			relobj(mtmp, (int) mtmp->minvis);
X			if(edog->apport > 1) edog->apport--;
X			edog->dropdist = udist;		/* hpscdi!jon */
X			edog->droptime = moves;
X		}
X	} else {
X		if(obj = o_at(omx,omy)) if(!index("0_", obj->olet)){
X		    if((otyp = dogfood(obj)) <= CADAVER){
X			nix = omx;
X			niy = omy;
X			goto eatobj;
X		    }
X		    if(obj->owt < 10*mtmp->data->mlevel)
X		    if(rn2(20) < edog->apport+3)
X		    if(rn2(udist) || !rn2((int) edog->apport)){
X			freeobj(obj);
X			unpobj(obj);
X			/* if(levl[omx][omy].scrsym == obj->olet)
X				newsym(omx,omy); */
X			mpickobj(mtmp,obj);
X		    }
X		}
X	}
X
X	gtyp = UNDEF;	/* no goal as yet */
X	gx = gy = 0;	/* suppress 'used before set' message */
X#ifdef WALKIES
X	/* If he's on a leash, he's not going anywhere. */
X	if(mtmp->mleashed) {
X
X		gtyp = APPORT;
X		gx = u.ux;
X		gy = u.uy;
X	} else
X#endif
X	/* first we look for food */
X	    for(obj = fobj; obj; obj = obj->nobj) {
X		otyp = dogfood(obj);
X		if(otyp > gtyp || otyp == UNDEF) continue;
X		if(inroom(obj->ox,obj->oy) != dogroom) continue;
X		if(otyp < MANFOOD &&
X		 (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) {
X			if(otyp < gtyp || (otyp == gtyp &&
X				DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){
X				gx = obj->ox;
X				gy = obj->oy;
X				gtyp = otyp;
X			}
X		} else
X		if(gtyp == UNDEF && dogroom >= 0 &&
X		   uroom == dogroom &&
X		   !mtmp->minvent && edog->apport > rn2(8)){
X			gx = obj->ox;
X			gy = obj->oy;
X			gtyp = APPORT;
X		}
X	    }
X
X	if(gtyp == UNDEF ||
X	  (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){
X		if(dogroom < 0 || dogroom == uroom){
X			gx = u.ux;
X			gy = u.uy;
X#ifndef QUEST
X		} else {
X			int tmp = rooms[dogroom].fdoor;
X			    cnt = rooms[dogroom].doorct;
X
X			gx = gy = FAR;	/* random, far away */
X			while(cnt--){
X			    if(dist(gx,gy) >
X				dist(doors[tmp].x, doors[tmp].y)){
X					gx = doors[tmp].x;
X					gy = doors[tmp].y;
X				}
X				tmp++;
X			}
X			/* here gx == FAR e.g. when dog is in a vault */
X			if(gx == FAR || (gx == omx && gy == omy)){
X				gx = u.ux;
X				gy = u.uy;
X			}
X#endif
X		}
X		appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0;
X		if(after && udist <= 4 && gx == u.ux && gy == u.uy)
X			return(0);
X		if(udist > 1){
X			if(!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||
X			   whappr ||
X			   (mtmp->minvent && rn2((int) edog->apport)))
X				appr = 1;
X		}
X		/* if you have dog food he'll follow you more closely */
X		if(appr == 0){
X			obj = invent;
X			while(obj){
X				if(obj->otyp == TRIPE_RATION){
X					appr = 1;
X					break;
X				}
X				obj = obj->nobj;
X			}
X		}
X	} else	appr = 1;	/* gtyp != UNDEF */
X	if(mtmp->mconf) appr = 0;
X
X	if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)) {
X	extern coord *gettrack();
X	register coord *cp;
X		cp = gettrack(omx,omy);
X		if(cp){
X			gx = cp->x;
X			gy = cp->y;
X		}
X	}
X
X	nix = omx;
X	niy = omy;
X	cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS);
X	chcnt = 0;
X	chi = -1;
X	for(i=0; i<cnt; i++){
X		nx = poss[i].x;
X		ny = poss[i].y;
X#ifdef WALKIES
X		/* if leashed, we drag him along. */
X		if(dist(nx, ny) > 4 && mtmp->mleashed) continue;
X#endif
X		if(info[i] & ALLOW_M) {
X			mtmp2 = m_at(nx,ny);
X			if(mtmp2)
X			    if(mtmp2->data->mlevel >= mdat->mlevel+2 ||
X			       mtmp2->data->mlet == 'c')
X				continue;
X			if(after) return(0); /* hit only once each move */
X
X			if(hitmm(mtmp, mtmp2) == 1 && rn2(4) &&
X			  mtmp2->mlstmv != moves &&
X			  hitmm(mtmp2,mtmp) == 2) return(2);
X			return(0);
X		}
X
X		/* dog avoids traps */
X		/* but perhaps we have to pass a trap in order to follow @ */
X		if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){
X			if(!trap->tseen && rn2(40)) continue;
X			if(rn2(10)) continue;
X		}
X
X		/* dog eschewes cursed objects */
X		/* but likes dog food */
X		obj = fobj;
X		while(obj){
X		    if(obj->ox != nx || obj->oy != ny)
X			goto nextobj;
X		    if(obj->cursed) goto nxti;
X		    if(obj->olet == FOOD_SYM &&
X			(otyp = dogfood(obj)) < MANFOOD &&
X			(otyp < ACCFOOD || edog->hungrytime <= moves)){
X			/* Note: our dog likes the food so much that he
X			might eat it even when it conceals a cursed object */
X			nix = nx;
X			niy = ny;
X			chi = i;
X		     eatobj:
X			edog->eattime =
X			    moves + obj->quan * objects[obj->otyp].oc_delay;
X			if(edog->hungrytime < moves)
X			    edog->hungrytime = moves;
X			edog->hungrytime +=
X			    5*obj->quan * objects[obj->otyp].nutrition;
X			mtmp->mconf = 0;
X			if(cansee(nix,niy))
X			    pline("%s ate %s.", Monnam(mtmp), doname(obj));
X			/* perhaps this was a reward */
X			if(otyp != CADAVER)
X			edog->apport += 200/(edog->dropdist+moves-edog->droptime);
X			delobj(obj);
X			goto newdogpos;
X		    }
X		nextobj:
X		    obj = obj->nobj;
X		}
X
X		for(j=0; j<MTSZ && j<cnt-1; j++)
X			if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
X				if(rn2(4*(cnt-j))) goto nxti;
X
X/* Some stupid C compilers cannot compute the whole expression at once. */
X		nearer = GDIST(nx,ny);
X		nearer -= GDIST(nix,niy);
X		nearer *= appr;
X		if((nearer == 0 && !rn2(++chcnt)) || nearer<0 ||
X			(nearer > 0 && !whappr &&
X				((omx == nix && omy == niy && !rn2(3))
X				|| !rn2(12))
X			)){
X			nix = nx;
X			niy = ny;
X			if(nearer < 0) chcnt = 0;
X			chi = i;
X		}
X	nxti:	;
X	}
Xnewdogpos:
X	if(nix != omx || niy != omy){
X		if(info[chi] & ALLOW_U){
X			(void) hitu(mtmp, d(mdat->damn, mdat->damd)+1);
X			return(0);
X		}
X		mtmp->mx = nix;
X		mtmp->my = niy;
X		for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
X		mtmp->mtrack[0].x = omx;
X		mtmp->mtrack[0].y = omy;
X	}
X#ifdef WALKIES
X	  /* an incredible kluge, but the only way to keep pooch near
X	   * after he spends time eating or in a trap, etc...
X	   */
X	  else  if(mtmp->mleashed && dist(omx, omy) > 4) mnexto(mtmp);
X#endif
X
X	if(mintrap(mtmp) == 2)	{		/* he died */
X#ifdef WALKIES
X		mtmp->mleashed = 0;
X#endif
X		return(2);
X	}
X	pmon(mtmp);
X	return(1);
X}
END_OF_dogmove.c
if test 7691 -ne `wc -c <dogmove.c`; then
    echo shar: \"dogmove.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fountain.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"fountain.c\"
else
echo shar: Extracting \"fountain.c\" \(7618 characters\)
sed "s/^X//" >fountain.c <<'END_OF_fountain.c'
X/*	SCCS Id: @(#)fountain.c	2.1	87/10/19
X/* fountain.c  v 1.4.3 */
X
X/*
X * Revision 1.4.3  87/11/25  19:16:00  M. Stephenson
X * Implemented levitation bug fixes.
X *
X * Revision 1.4.2  87/10/19  11:48:00  M. Stephenson
X * Implementation of KJS bug fixes.
X *
X * Revision 1.4.1  87/05/20  11:53:00  M. Stephenson
X * Implementation of KAA bug fixes.
X *
X * Revision 1.4    87/05/04  17:39:00  M. Stephenson
X * Integration of independent modifications
X *
X * Revision 1.3    87/03/02            Eric Backus
X * Rearranged, and dipfountain added
X * 
X * Revision 1.2    87/03/01  13:59:59  gil
X * patches
X * 
X * Revision 1.1    87/02/11  15:14:10  gil
X * Initial revision
X *
X */
X
X/* Code for drinking from fountains.   */
X/* Scott R. Turner, srt@ucla, 10/27/86 */
X
X#include "hack.h"
X
Xextern struct monst *mkmon_at();
Xextern struct obj *mkobj_at();
Xextern char genocided[];
X
X#ifdef FOUNTAINS
X#define somex() ((rand()%(croom->hx-croom->lx+1))+croom->lx)
X#define somey() ((rand()%(croom->hy-croom->ly+1))+croom->ly)
X
Xdowatersnakes() /* Fountain of snakes! */ {
X	register int num = rnd(6);
X	if (!index(genocided, 'S')) {
X
X		pline("Good Lord!  An endless stream of snakes pours forth!");
X		while(num-- > 0) (void) mkmon_at('S',u.ux,u.uy);
X	} else
X		pline("The fountain bubbles furiously for a moment, then calms.");
X}
X
Xdowaterdemon() /* Water demon */ {
Xregister struct monst *mtmp;
X
X	if((mtmp = mkmon_at('&',u.ux,u.uy))) {
X	    pline("You have unleashed a water demon!");
X
X	/* Give those on low levels a (slightly) better chance of survival */
X	    if ( rnd(100) > (80 + dlevel)) {
X		pline("Grateful for his release, he grants you a wish!");
X		makewish();
X		mondied(mtmp);
X	    }
X	}
X}
X
Xdowaternymph() /* Water Nymph */ {
X	register struct monst *mtmp;
X	if((mtmp = mkmon_at('N',u.ux,u.uy))) {
X
X		pline("You have attracted a water nymph!");
X		mtmp->msleep = 0;
X	} else
X		pline("A large bubble rises to the surface and pops.");
X}
X
X#include	"mkroom.h"
X
Xdogushforth() /* Gushing forth in this room */ {
Xregister int num = rnd(10);
Xregister xchar mx,my;
Xregister int tryct = 0;
Xregister int uroom = inroom(u.ux, u.uy);
Xregister struct mkroom *croom = &rooms[uroom];
Xregister int madepool = 0;
X
X	if(croom->hx < 0 || has_upstairs(croom) ||
X	   has_dnstairs(croom))  {
X		pline("Your thirst is quenched.");
X		return;
X	}
X	while(num--) {
X	    do {
X		if(++tryct > 200)  {
X		    if(madepool)
X			pline("Water gushes forth from the overflowing fountain!");
X		    else
X			pline("Your thirst is quenched.");
X		    return;
X		}
X		mx = somex();
X		my = somey();
X	    } while(nexttodoor(mx,my) || !((mx+my)%2) ||
X		    (mx == u.ux && my == u.uy) ||
X		    (IS_POOL(levl[mx][my].typ)));
X		       
X	    /* Put a pool at mx, my */
X		     
X	    levl[mx][my].typ = POOL;
X	    atl(mx,my,POOL_SYM);
X	    madepool = 1;
X	}
X
X	pline("Water gushes forth from the overflowing fountain!");
X}
X
Xdofindgem() /* Find a gem in the sparkling waters. */ {
X
X	if (!Blind) pline("You spot a gem in the sparkling waters!");
X	mkobj_at('*',u.ux,u.uy);
X}
X
Xdryup(){
X	if (!rn2(3) && (levl[u.ux][u.uy].typ == FOUNTAIN)) {
X		pline("The fountain dries up!");
X		levl[u.ux][u.uy].typ = ROOM;
X		if(Invis) newsym(u.ux, u.uy);
X	}
X}
X
Xdrinkfountain() {
X
X	/* What happens when you drink from a fountain? */
X	register int fate = rnd(30);
X
X	if(Levitation) 	pline("You are floating high above the fountain.");
X	else if (fate < 10) {
X		pline("The cool draught refreshes you.");
X		lesshungry(rnd(10));
X	} else {
X	    switch (fate) {
X
X		case 20: /* Foul water */
X
X			pline("The water is foul!  You gag and vomit.");
X			morehungry(rnd(20)+10);
X			if(Sick)  {
X				Sick = 0;
X				pline("What a relief!");
X			}
X			break;
X
X		case 21: /* Poisonous */
X
X			pline("The water is contaminated!");
X			if (Poison_resistance) {
X			   pline("Perhaps it is run off from the nearby orange farm.");
X			   losehp(rnd(4),"unrefrigerated orange juice");
X			   break;
X			}
X			losestr(rn1(4,3));
X			losehp(rnd(10),"contaminated water");
X			break;
X	
X		case 22: /* Fountain of snakes! */
X			dowatersnakes();
X			break;
X
X		case 23: /* Water demon */
X			dowaterdemon();
X			break;
X
X		case 24: /* Curse an item... */ {
X			register struct obj *obj;
X
X			pline("This water's no good!");
X			morehungry(rnd(20)+10);
X			for(obj = invent; obj ; obj = obj->nobj)
X				if (!rn2(5))	obj->cursed++;
X			break;
X			}
X			 
X		case 25: /* See invisible */
X
X			pline("You see an image of someone stalking you.");
X			pline("But it disappears.");
X			HSee_invisible |= INTRINSIC;
X			break;
X
X		case 26: /* See Monsters */ {
X			register struct monst *mtmp;
X
X			  if(!fmon) pline("You feel oddly disturbed.");
X			  else {
X			    cls();
X			    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X				if(mtmp->mx > 0)
X				    at(mtmp->mx,mtmp->my,mtmp->data->mlet);
X			    prme();
X			    pline("You sense the presence of monsters.");
X			    more();
X			    docrt();
X			  }
X			}
X			break;
X
X		case 27: /* Find a gem in the sparkling waters. */
X			dofindgem();
X			break;
X
X		case 28: /* Water Nymph */
X			dowaternymph();
X			break;
X
X		case 29: /* Scare */ {
X			register struct monst *mtmp;
X
X			pline("This water gives you bad breath!");
X			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 
X				mtmp->mflee = 1;
X			}
X			break;
X
X		case 30: /* Gushing forth in this room */
X			dogushforth();
X			break;
X		default:
X			break;
X	    }
X	}
X	dryup();
X}
X
Xdipfountain(obj)
Xregister struct obj *obj;
X{
X	register int fate = rnd(30);
X
X	if(Levitation) 	pline("You are floating high above the fountain.");
X	else if(fate<10)
X		if(!obj->rustfree &&
X			/* Only swords affected here */
X			(obj->otyp == LONG_SWORD ||
X			obj->otyp == KATANA ||
X			obj->otyp == BROAD_SWORD ||
X			obj->otyp == SHORT_SWORD ||
X			obj->otyp == TWO_HANDED_SWORD)) {
X			if(obj->spe > -6) {
X				pline("Your weapon rusts somewhat.");
X				obj->spe--;
X			} else pline("Your weapon looks quite rusted.");
X		} else pline("Well, it looks wet now.");
X	else if(fate<14)
X		if(obj->otyp == LONG_SWORD
X#ifndef RPH
X		   && !strcmp(ONAME(obj), "Excalibur")
X#endif
X		) {
X			/* The lady of the lake acts! - Eric Backus */
X			/* Be *REAL* nice to him */
X	pline("A murky hand from the depths reaches up to bless the sword.");
X	pline("As the hand retreats, the fountain disappears!");
X#ifndef RPH
X			if(obj->spe < 5) obj->spe = 5;
X#else
X			/* otherwise +rnd(10) / +5 "Super"sword */
X			oname(obj, "Excalibur");
X#endif
X#ifdef KAA
X			obj->dknown = 1;	/* blessed */
X#endif
X			obj->cursed = 0;
X			obj->rustfree = 1;
X			levl[u.ux][u.uy].typ = ROOM;
X			if(Invis) newsym(u.ux, u.uy);
X			return(0);
X		} else pline ("Well, it looks wet now.");
X	else {
X	    switch (fate) {
X		case 16: /* Curse the item */
X			pline("Well, it looks wet now.");
X			obj->cursed = 1;
X			break;
X		case 17:
X		case 18:
X		case 19:
X		case 20: /* Uncurse the item */
X			if(obj->cursed) {
X			    pline("The water glows for a moment.");
X			    obj->cursed = 0;
X			} else {
X			    pline("A feeling of loss comes over you.");
X			}
X			break;
X		case 21: /* Water Demon */
X			dowaterdemon();
X			break;
X		case 22: /* Water Nymph */
X			dowaternymph();
X			break;
X		case 23: /* An Endless Stream Of Snakes */
X			dowatersnakes();
X			break;
X		case 24: /* Find a gem */
X			dofindgem();
X			break;
X		case 25: /* Water gushes forth */
X			dogushforth();
X			break;
X		case 26: /* Strange feeling */
X			pline("A strange tingling runs up your arm.");
X			break;
X		case 27: /* Strange feeling */
X			pline("You feel a sudden chill.");
X			break;
X		case 28: /* Strange feeling */
X		pline("An urge to take a bath nearly overwhelms you.");
X			break;
X		case 29: /* You see coins */
X		pline("Far below you, you see coins glistening in the water.");
X			break;
X		default:
X			break;
X	    }
X	}
X	dryup();
X	return(0);
X}
X#endif
END_OF_fountain.c
if test 7618 -ne `wc -c <fountain.c`; then
    echo shar: \"fountain.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f prisym.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"prisym.c\"
else
echo shar: Extracting \"prisym.c\" \(7263 characters\)
sed "s/^X//" >prisym.c <<'END_OF_prisym.c'
X/*	SCCS Id: @(#)prisym.c	2.0	87/09/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include <stdio.h>
X#include "hack.h"
X
Xextern xchar scrlx, scrhx, scrly, scrhy; /* corners from pri.c */
X
Xatl(x,y,ch)
Xregister x,y;
X{
X	register struct rm *crm = &levl[x][y];
X
X	if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){
X		impossible("atl(%d,%d,%c)",x,y,ch);
X		return;
X	}
X	if(crm->seen && crm->scrsym == ch) return;
X	crm->scrsym = ch;
X	crm->new = 1;
X	on_scr(x,y);
X}
X
Xon_scr(x,y)
Xregister x,y;
X{
X	if(x < scrlx) scrlx = x;
X	if(x > scrhx) scrhx = x;
X	if(y < scrly) scrly = y;
X	if(y > scrhy) scrhy = y;
X}
X
X/* call: (x,y) - display
X	(-1,0) - close (leave last symbol)
X	(-1,-1)- close (undo last symbol)
X	(-1,let)-open: initialize symbol
X	(-2,let)-change let
X*/
X
Xtmp_at(x,y) int x,y; {
Xstatic schar prevx, prevy;
Xstatic char let;
X	if((int)x == -2){	/* change let call */
X		let = y;
X		return;
X	}
X	if((int)x == -1 && (int)y >= 0){	/* open or close call */
X		let = y;
X		prevx = -1;
X		return;
X	}
X	if(prevx >= 0 && cansee(prevx,prevy)) {
X		delay_output();
X		prl(prevx, prevy);	/* in case there was a monster */
X		at(prevx, prevy, levl[prevx][prevy].scrsym);
X	}
X	if(x >= 0){	/* normal call */
X		if(cansee(x,y)) at(x,y,let);
X		prevx = x;
X		prevy = y;
X	} else {	/* close call */
X		let = 0;
X		prevx = -1;
X	}
X}
X
X/* like the previous, but the symbols are first erased on completion */
XTmp_at(x,y) int x,y; {
Xstatic char let;
Xstatic xchar cnt;
Xstatic coord tc[COLNO];		/* but watch reflecting beams! */
Xregister xx,yy;
X	if((int)x == -1) {
X		if(y > 0) {	/* open call */
X			let = y;
X			cnt = 0;
X			return;
X		}
X		/* close call (do not distinguish y==0 and y==-1) */
X		while(cnt--) {
X			xx = tc[cnt].x;
X			yy = tc[cnt].y;
X			prl(xx, yy);
X			at(xx, yy, levl[xx][yy].scrsym);
X		}
X		cnt = let = 0;	/* superfluous */
X		return;
X	}
X	if((int)x == -2) {	/* change let call */
X		let = y;
X		return;
X	}
X	/* normal call */
X	if(cansee(x,y)) {
X		if(cnt) delay_output();
X		at(x,y,let);
X		tc[cnt].x = x;
X		tc[cnt].y = y;
X		if(++cnt >= COLNO) panic("Tmp_at overflow?");
X		levl[x][y].new = 0;	/* prevent pline-nscr erasing --- */
X	}
X}
X
Xcurs_on_u(){
X	curs(u.ux, u.uy+2);
X}
X
Xpru()
X{
X	if(u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
X		/* if(! levl[u.udisx][u.udisy].new) */
X			if(!vism_at(u.udisx, u.udisy))
X				newsym(u.udisx, u.udisy);
X	if(Invisible) {
X		u.udispl = 0;
X		prl(u.ux,u.uy);
X	} else
X	if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
X		atl(u.ux, u.uy, u.usym);
X		u.udispl = 1;
X		u.udisx = u.ux;
X		u.udisy = u.uy;
X	}
X	levl[u.ux][u.uy].seen = 1;
X}
X
X#ifndef NOWORM
X#include	"wseg.h"
Xextern struct wseg *m_atseg;
X#endif
X
X/* print a position that is visible for @ */
Xprl(x,y)
X{
X	register struct rm *room;
X	register struct monst *mtmp;
X	register struct obj *otmp;
X	register struct trap *ttmp;
X
X	if(x == u.ux && y == u.uy && (!Invisible)) {
X		pru();
X		return;
X	}
X	if(!isok(x,y)) return;
X	room = &levl[x][y];
X	if((!room->typ) ||
X	   (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
X		return;
X	if((mtmp = m_at(x,y)) && !mtmp->mhide &&
X		(!mtmp->minvis || See_invisible)) {
X#ifndef NOWORM
X		if(m_atseg)
X			pwseg(m_atseg);
X		else
X#endif
X		pmon(mtmp);
X	}
X	else if((otmp = o_at(x,y)) && room->typ != POOL)
X		atl(x,y,Hallucination ? rndobjsym() : otmp->olet);
X#ifdef SPIDERS
X	else if((!mtmp || mtmp->data == PM_SPIDER) &&
X		  (ttmp = t_at(x,y)) && ttmp->ttyp == WEB)
X		atl(x,y,WEB_SYM);
X#endif
X	else if(mtmp && (!mtmp->minvis || See_invisible)) {
X		/* must be a hiding monster, but not hiding right now */
X		/* assume for the moment that long worms do not hide */
X		pmon(mtmp);
X	}
X	else if(g_at(x,y) && room->typ != POOL)
X		atl(x,y,Hallucination ? rndobjsym() : GOLD_SYM);
X	else if(!room->seen || room->scrsym == STONE_SYM) {
X		room->new = room->seen = 1;
X		newsym(x,y);
X		on_scr(x,y);
X	}
X	room->seen = 1;
X}
X
Xchar
Xnews0(x,y)
Xregister xchar x,y;
X{
X	register struct obj *otmp;
X	register struct trap *ttmp;
X	struct rm *room;
X	register char tmp;
X
X	room = &levl[x][y];
X	if(!room->seen) tmp = STONE_SYM;
X	else if(room->typ == POOL) tmp = POOL_SYM;
X	else if(!Blind && (otmp = o_at(x,y)))
X		tmp = Hallucination ? rndobjsym() : otmp->olet;
X	else if(!Blind && g_at(x,y))
X		tmp = Hallucination ? rndobjsym() : GOLD_SYM;
X	else if(x == xupstair && y == yupstair) tmp = UP_SYM;
X	else if(x == xdnstair && y == ydnstair) tmp = DN_SYM;
X#ifdef SPIDERS
X	else if((ttmp = t_at(x,y)) && ttmp->ttyp == WEB) tmp = WEB_SYM;
X	else if(ttmp && ttmp->tseen) tmp = TRAP_SYM;
X#else
X	else if((ttmp = t_at(x,y)) && ttmp->tseen) tmp = TRAP_SYM;
X#endif
X	else switch(room->typ) {
X	case SCORR:
X	case SDOOR:
X		tmp = room->scrsym;	/* %% wrong after killing mimic ! */
X		break;
X	case HWALL:
X		tmp = room->scrsym;	/* OK for corners only */
X		if (!IS_CORNER(tmp))
X			tmp = HWALL_SYM;
X		break;
X	case VWALL:
X		tmp = VWALL_SYM;
X		break;
X	case LDOOR:
X	case DOOR:
X		tmp = DOOR_SYM;
X		break;
X	case CORR:
X		tmp = CORR_SYM;
X		break;
X	case ROOM:
X		if(room->lit || cansee(x,y) || Blind) tmp = ROOM_SYM;
X		else tmp = STONE_SYM;
X		break;
X#ifdef FOUNTAINS
X	case FOUNTAIN:
X		tmp = FOUNTAIN_SYM;
X		break;
X#endif
X#ifdef NEWCLASS
X	case THRONE:
X		tmp = THRONE_SYM;
X		break;
X#endif
X/*
X	case POOL:
X		tmp = POOL_SYM;
X		break;
X*/
X	default:
X		tmp = ERRCHAR;
X	}
X	return(tmp);
X}
X
Xnewsym(x,y)
Xregister x,y;
X{
X	atl(x,y,news0(x,y));
X}
X
X/* used with wand of digging (or pick-axe): fill scrsym and force display */
X/* also when a POOL evaporates */
Xmnewsym(x,y)
Xregister x,y;
X{
X	register struct rm *room;
X	char newscrsym;
X
X	if(!vism_at(x,y)) {
X		room = &levl[x][y];
X		newscrsym = news0(x,y);
X		if(room->scrsym != newscrsym) {
X			room->scrsym = newscrsym;
X			room->seen = 0;
X		}
X	}
X}
X
Xnosee(x,y)
Xregister x,y;
X{
X	register struct rm *room;
X
X	if(!isok(x,y)) return;
X	room = &levl[x][y];
X	if(room->scrsym == ROOM_SYM && !room->lit && !Blind) {
X		room->scrsym = ' ';
X		room->new = 1;
X		on_scr(x,y);
X	}
X}
X
X#ifndef QUEST
Xprl1(x,y)
Xregister x,y;
X{
X	if(u.dx) {
X		if(u.dy) {
X			prl(x-(2*u.dx),y);
X			prl(x-u.dx,y);
X			prl(x,y);
X			prl(x,y-u.dy);
X			prl(x,y-(2*u.dy));
X		} else {
X			prl(x,y-1);
X			prl(x,y);
X			prl(x,y+1);
X		}
X	} else {
X		prl(x-1,y);
X		prl(x,y);
X		prl(x+1,y);
X	}
X}
X
Xnose1(x,y)
Xregister x,y;
X{
X	if(u.dx) {
X		if(u.dy) {
X			nosee(x,u.uy);
X			nosee(x,u.uy-u.dy);
X			nosee(x,y);
X			nosee(u.ux-u.dx,y);
X			nosee(u.ux,y);
X		} else {
X			nosee(x,y-1);
X			nosee(x,y);
X			nosee(x,y+1);
X		}
X	} else {
X		nosee(x-1,y);
X		nosee(x,y);
X		nosee(x+1,y);
X	}
X}
X#endif /* QUEST /**/
X
Xvism_at(x,y)
Xregister x,y;
X{
X	register struct monst *mtmp;
X
X	if(x == u.ux && y == u.uy && !Invisible) return(1);
X
X	if(mtmp = m_at(x,y)) return((Blind && Telepat) || canseemon(mtmp));
X
X	return(0);
X}
X
X#ifdef NEWSCR
Xpobj(obj) register struct obj *obj; {
Xregister int show = (!obj->oinvis || See_invisible) &&
X		cansee(obj->ox,obj->oy);
X	if(obj->odispl){
X		if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
X		if(!vism_at(obj->odx,obj->ody)){
X			newsym(obj->odx, obj->ody);
X			obj->odispl = 0;
X		}
X	}
X	if(show && !vism_at(obj->ox,obj->oy)){
X		atl(obj->ox,obj->oy,obj->olet);
X		obj->odispl = 1;
X		obj->odx = obj->ox;
X		obj->ody = obj->oy;
X	}
X}
X#endif /* NEWSCR /**/
X
Xunpobj(obj) register struct obj *obj; {
X/* 	if(obj->odispl){
X		if(!vism_at(obj->odx, obj->ody))
X			newsym(obj->odx, obj->ody);
X		obj->odispl = 0;
X	}
X*/
X	if(!vism_at(obj->ox,obj->oy))
X		newsym(obj->ox,obj->oy);
X}
END_OF_prisym.c
if test 7263 -ne `wc -c <prisym.c`; then
    echo shar: \"prisym.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f termcap.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"termcap.c\"
else
echo shar: Extracting \"termcap.c\" \(8400 characters\)
sed "s/^X//" >termcap.c <<'END_OF_termcap.c'
X/*	SCCS Id: @(#)termcap.c	2.1	87/10/19
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include <stdio.h>
X#include <ctype.h>	/* for isdigit() */
X#include "hack.h"	/* for ROWNO, COLNO, *HI, *HE */
X#ifdef GENIX
X#define	void	int	/* jhn - mod to prevent compiler from bombing */
X#endif
X
Xextern char *tgetstr(), *tgoto(), *getenv();
Xextern long *alloc();
X
X#ifndef TERMINFO
X# ifndef LINT
Xextern			/* it is defined in libtermlib (libtermcap) */
X# endif
X	short ospeed;		/* terminal baudrate; used by tputs */
X#endif
Xstatic char tbuf[512];
Xstatic char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
Xstatic char *VS, *VE, *US, *UE;
Xstatic int SG;
Xstatic char PC = '\0';
Xchar *CD;		/* tested in pri.c: docorner() */
Xint CO, LI;		/* used in pri.c and whatis.c */
X
X#ifdef MSDOS
Xstatic char tgotobuf[20];
X#define tgoto(fmt, x, y)	(sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
X#endif /* MSDOS /**/
X
Xstartup()
X{
X#ifdef MSDOS
X	HO = "\033[H";
X	CL = "\033[2J";
X	CE = "\033[K";
X	UP = "\033[1A";
X	CM = "\033[%d;%dH";	/* used with function tgoto() */
X	ND = "\033[1C";
X	XD = "\033[1B";
X	BC = "\033[1D";
X# ifdef MSDOSCOLOR	/* creps@silver.bacs.indiana.edu */
X	TI = "\033[44;37m";
X	TE = "\033[0m";
X	VS = VE = "";
X	SO = "\033[31m";
X	SE = "\033[44;37m";
X# else
X	TI = TE = VS = VE = "";
X  	SO = "\033[7m";
X  	SE = "\033[0m";
X# endif
X	CD = "\033";
X	CO = COLNO;
X	LI = ROWNO;
X# if defined(DGK) || defined(SORTING)
X#  ifdef MSDOSCOLOR
X	HI = "\033[32m";
X	HE = "\033[44;37m";
X#  else
X	HI = "\033[4m";
X	HE = "\033[0m";
X#  endif
X# endif
X#else /* MSDOS /**/
X	register char *term;
X	register char *tptr;
X	char *tbufptr, *pc;
X	register int i;
X
X	tptr = (char *) alloc(1024);
X
X	tbufptr = tbuf;
X	if(!(term = getenv("TERM")))
X		error("Can't get TERM.");
X	if(!strncmp(term, "5620", 4))
X		flags.nonull = 1;	/* this should be a termcap flag */
X	if(tgetent(tptr, term) < 1)
X		error("Unknown terminal type: %s.", term);
X	if(pc = tgetstr("pc", &tbufptr))
X		PC = *pc;
X	if(!(BC = tgetstr("bc", &tbufptr))) {	
X		if(!tgetflag("bs"))
X			error("Terminal must backspace.");
X		BC = tbufptr;
X		tbufptr += 2;
X		*BC = '\b';
X	}
X	HO = tgetstr("ho", &tbufptr);
X	CO = tgetnum("co");
X	LI = tgetnum("li");
X	if(CO < COLNO || LI < ROWNO+2)
X		setclipped();
X	if(!(CL = tgetstr("cl", &tbufptr)))
X		error("Hack needs CL.");
X	ND = tgetstr("nd", &tbufptr);
X	if(tgetflag("os"))
X		error("Hack can't have OS.");
X	CE = tgetstr("ce", &tbufptr);
X	UP = tgetstr("up", &tbufptr);
X	/* It seems that xd is no longer supported, and we should use
X	   a linefeed instead; unfortunately this requires resetting
X	   CRMOD, and many output routines will have to be modified
X	   slightly. Let's leave that till the next release. */
X	XD = tgetstr("xd", &tbufptr);
X/* not: 		XD = tgetstr("do", &tbufptr); */
X	if(!(CM = tgetstr("cm", &tbufptr))) {
X		if(!UP && !HO)
X			error("Hack needs CM or UP or HO.");
X		printf("Playing hack on terminals without cm is suspect...\n");
X		getret();
X	}
X	SO = tgetstr("so", &tbufptr);
X	SE = tgetstr("se", &tbufptr);
X	US = tgetstr("us", &tbufptr);
X	UE = tgetstr("ue", &tbufptr);
X	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */
X	if(!SO || !SE || (SG > 0)) SO = SE = US = UE = 0;
X	TI = tgetstr("ti", &tbufptr);
X	TE = tgetstr("te", &tbufptr);
X	VS = VE = "";
X# ifdef SORTING
X	/* Get rid of padding numbers for HI and HE.  Hope they
X	 * aren't really needed!!!  HI and HE are ouputted to the
X	 * pager as a string - so how can you send it NULLS???
X	 *  -jsb
X	 */
X	    HI = (char *) alloc(strlen(SO) + 1);
X	    HE = (char *) alloc(strlen(SE) + 1);
X	    i = 0;
X	    while(isdigit(SO[i])) i++;
X	    strcpy(HI, &SO[i]);
X	    i = 0;
X	    while(isdigit(SE[i])) i++;
X	    strcpy(HE, &SE[i]);
X# endif
X	CD = tgetstr("cd", &tbufptr);
X	set_whole_screen();		/* uses LI and CD */
X	if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
X	free(tptr);
X#endif /* MSDOS /**/
X#ifdef MSDOSCOLOR
X	init_hilite();
X#endif
X}
X
Xstart_screen()
X{
X	xputs(TI);
X	xputs(VS);
X#ifdef DGK
X	/* Select normal ASCII and line drawing character sets.
X	 */
X	if (flags.DECRainbow)
X		xputs("\033(B\033)0");
X#endif
X}
X
Xend_screen()
X{
X	clear_screen();
X	xputs(VE);
X	xputs(TE);
X}
X
X/* Cursor movements */
Xextern xchar curx, cury;
X
Xcurs(x, y)
Xregister int x, y;	/* not xchar: perhaps xchar is unsigned and
X			   curx-x would be unsigned as well */
X{
X
X	if (y == cury && x == curx)
X		return;
X	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */
X		cmov(x, y);			/* bunker!wtm */
X		return;
X	}
X	if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
X		nocmov(x, y);
X	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
X		(void) putchar('\r');
X		curx = 1;
X		nocmov(x, y);
X	} else if(!CM) {
X		nocmov(x, y);
X	} else
X		cmov(x, y);
X}
X
Xnocmov(x, y)
X{
X	if (cury > y) {
X		if(UP) {
X			while (cury > y) {	/* Go up. */
X				xputs(UP);
X				cury--;
X			}
X		} else if(CM) {
X			cmov(x, y);
X		} else if(HO) {
X			home();
X			curs(x, y);
X		} /* else impossible("..."); */
X	} else if (cury < y) {
X		if(XD) {
X			while(cury < y) {
X				xputs(XD);
X				cury++;
X			}
X		} else if(CM) {
X			cmov(x, y);
X		} else {
X			while(cury < y) {
X				xputc('\n');
X				curx = 1;
X				cury++;
X			}
X		}
X	}
X	if (curx < x) {		/* Go to the right. */
X		if(!ND) cmov(x, y); else	/* bah */
X			/* should instead print what is there already */
X		while (curx < x) {
X			xputs(ND);
X			curx++;
X		}
X	} else if (curx > x) {
X		while (curx > x) {	/* Go to the left. */
X			xputs(BC);
X			curx--;
X		}
X	}
X}
X
Xcmov(x, y)
Xregister x, y;
X{
X	xputs(tgoto(CM, x-1, y-1));
X	cury = y;
X	curx = x;
X}
X
Xxputc(c) char c; {
X	(void) fputc(c, stdout);
X}
X
Xxputs(s) char *s; {
X#ifdef MSDOS
X	fputs(s, stdout);
X#else
X	tputs(s, 1, xputc);
X#endif
X}
X
Xcl_end() {
X	if(CE)
X		xputs(CE);
X/*#ifdef MSDOSCOLOR
X/*		xputs(TI);
X/*#endif
X*/
X	else {	/* no-CE fix - free after Harold Rynes */
X		/* this looks terrible, especially on a slow terminal
X		   but is better than nothing */
X		register cx = curx, cy = cury;
X
X		while(curx < COLNO) {
X			xputc(' ');
X			curx++;
X		}
X		curs(cx, cy);
X	}
X}
X
Xclear_screen() {
X	xputs(CL);
X#ifdef MSDOSCOLOR
X	xputs(TI);
X#endif
X	home();
X}
X
Xhome()
X{
X	if(HO)
X		xputs(HO);
X	else if(CM)
X		xputs(tgoto(CM, 0, 0));
X	else
X		curs(1, 1);	/* using UP ... */
X	curx = cury = 1;
X}
X
Xstandoutbeg()
X{
X	if(SO) xputs(SO);
X}
X
Xstandoutend()
X{
X	if(SE) xputs(SE);
X}
X
Xbacksp()
X{
X	xputs(BC);
X	curx--;
X}
X
Xbell()
X{
X#ifdef DGKMOD
X	if (flags.silent) return;
X#endif /* DGKMOD /**/
X	(void) putchar('\007');		/* curx does not change */
X	(void) fflush(stdout);
X}
X
Xstatic short tmspc10[] = {		/* from termcap */
X	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
X};
X
Xdelay_output() {
X	/* delay 50 ms - could also use a 'nap'-system call */
X	/* BUG: if the padding character is visible, as it is on the 5620
X	   then this looks terrible. */
X#ifdef MSDOS
X	/* simulate the delay with "cursor here" */
X	register i;
X	for (i = 0; i < 3; i++) {
X		cmov(curx, cury);
X		(void) fflush(stdout);
X	}
X#else
X	if(!flags.nonull)
X#ifdef TERMINFO
X		tputs("$<50>", 1, xputs);
X#else
X		tputs("50", 1, xputs);
X#endif
X		/* cbosgd!cbcephus!pds for SYS V R2 */
X		/* is this terminfo, or what? */
X		/* tputs("$<50>", 1, xputc); */
X
X	else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
X		/* delay by sending cm(here) an appropriate number of times */
X		register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
X		register int i = 500 + tmspc10[ospeed]/2;
X
X		while(i > 0) {
X			cmov(curx, cury);
X			i -= cmlen*tmspc10[ospeed];
X		}
X	}
X#endif /* MSDOS /**/
X}
X
Xcl_eos()			/* free after Robert Viduya */
X{				/* must only be called with curx = 1 */
X
X	if(CD)
X		xputs(CD);
X	else {
X		register int cx = curx, cy = cury;
X		while(cury <= LI-2) {
X			cl_end();
X			xputc('\n');
X			curx = 1;
X			cury++;
X		}
X		cl_end();
X		curs(cx, cy);
X	}
X}
X
X#ifdef MSDOSCOLOR
X
X#define ESCCHR		'\033'
X#define HILITE_ATTRIB	1	/* highlight */
X
X#define HILITE_MONSTER	1	/* red */
X#define HILITE_OBJECT	2	/* green */
X
Xinit_hilite()
X{
X	register int hilen, def_background;
X
X	/* find default background color */
X	hilen = strlen(HI) - 1;
X	if (hilen < 5) def_background = 0;	/* black */
X	else {
X		if (!isdigit(HI[hilen-1])) def_background = 0;
X		else def_background = HI[hilen-1];
X	}
X
X	HI_MON = (char *) alloc(sizeof("E[0;33;44m"));
X	sprintf(HI_MON, "%c[%d;3%d;4%dm", ESCCHR, HILITE_ATTRIB, 
X	        HILITE_MONSTER, def_background);
X	HI_OBJ = (char *) alloc(sizeof("E[0;33;44m"));
X	sprintf(HI_OBJ, "%c[%d;3%d;4%dm", ESCCHR, HILITE_ATTRIB, 
X	        HILITE_OBJECT, def_background);
X}
X
X#endif /* MSDOSCOLOR */
END_OF_termcap.c
if test 8400 -ne `wc -c <termcap.c`; then
    echo shar: \"termcap.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f write.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"write.c\"
else
echo shar: Extracting \"write.c\" \(3837 characters\)
sed "s/^X//" >write.c <<'END_OF_write.c'
X/*	SCCS Id: @(#)write.c	2.0	87/09/16
X */
X
X#include "hack.h"
X
Xextern char pl_character[];
X
X#ifdef MARKER
X
X/*
X * returns basecost of a scroll
X */
Xint
Xcost(scroll)
Xregister struct obj *scroll;
X{
X	switch(scroll->otyp)  {
X# ifdef MAIL
X	case SCR_MAIL:
X		return(0);
X		break;
X# endif
X	case SCR_LIGHT:
X	case SCR_GOLD_DETECTION:
X	case SCR_FOOD_DETECTION:
X	case SCR_MAGIC_MAPPING:
X	case SCR_AMNESIA:
X	case SCR_FIRE:
X		return(8);
X		break;
X	case SCR_DESTROY_ARMOR:
X	case SCR_DAMAGE_WEAPON:
X	case SCR_CREATE_MONSTER:
X	case SCR_PUNISHMENT:
X		return(10);
X		break;
X	case SCR_CONFUSE_MONSTER:
X		return(12);
X		break;
X	case SCR_IDENTIFY:
X		return(14);
X		break;
X	case SCR_ENCHANT_ARMOR:
X	case SCR_REMOVE_CURSE:
X	case SCR_ENCHANT_WEAPON:
X		return(16);
X		break;
X	case SCR_SCARE_MONSTER:
X	case SCR_TAMING:
X	case SCR_TELEPORTATION:
X		return(20);
X		break;
X	case SCR_GENOCIDE:
X		return(30);
X		break;
X	case SCR_BLANK_PAPER:
X	default:
X		impossible("You can't write such a weird scroll!");
X	}
X	return(1000);
X}
X
X
Xdowrite(pen)
X	register struct obj *pen;
X{
X	register struct obj *paper;
X	char namebuf[BUFSZ], scrbuf[BUFSZ];
X	register struct obj *newscroll;
X	extern struct obj *readobjnam(), *addinv();
X	int basecost, actualcost;
X	int newquan;
X	
X	if(!pen)
X		return(0);
X	if(pen->otyp != MAGIC_MARKER)  {
X		pline("You can't write with that!");
X		return(0);
X	}
X	
X	/* get paper to write on */
X	paper = getobj("?","write on");
X	if(!paper)
X		return(0);
X	if(!(objects[paper->otyp].oc_name_known))  {
X		pline("In your haste, you rip the scroll to pieces.");
X		useup(paper);
X		return(1);
X	}
X# ifndef KAA
X/* If this is included, the strategy would be to name all scrolls so that
X * you can test them for blankness with a magic marker.  This is tedious,
X * thus, let's make it easier. */
X	if(!(objects[paper->otyp].oc_name_known))  {
X		pline("In your haste, you rip the scroll to pieces.");
X		useup(paper);
X		return(0);
X	}
X# endif
X	if(paper->otyp != SCR_BLANK_PAPER)  {
X		pline("You fool, that scroll's not blank!");
X		return(0);
X	}
X	
X	/* what to write */
X	pline("What do you want to write? ");
X	getlin(namebuf);
X	if(namebuf[0] == '\033' || !namebuf[0])
X		return(0);
X	strcpy(scrbuf,"scroll of ");
X	strcat(scrbuf,namebuf);
X	newscroll = readobjnam(scrbuf);
X	if(newscroll->olet != SCROLL_SYM ||
X	   newscroll->otyp == SCR_BLANK_PAPER)  {
X		pline("You can't write that!");
X		pline("It's obscene!");
X		return(0);
X	}
X	
X	/* see if there's enough ink */
X	basecost = cost(newscroll);
X	if(pen->spe < basecost/2)  {
X		pline("You marker is too dried out to write that!");
X		obfree(newscroll, (struct obj *) 0);
X		return(0);
X	}
X	
X	/* we're really going to write now, so calculate
X	 * cost and useup old scroll
X	 */
X	actualcost = rn1(basecost/2,basecost/2);
X	useup(paper);
X	
X	/* dry out marker */
X	if(pen->spe < actualcost)  {
X		pline("Your marker dries out!");
X		pline("The scroll is now useless and disappears!");
X		pen->spe = 0;
X		obfree(newscroll, (struct obj *) 0);
X		return(1);
X	}
X	pen->spe -= actualcost;
X# ifdef KAA /* Since the KAA modification allows writing on unknown blank
X		paper, identify blank paper. */
X	objects[SCR_BLANK_PAPER].oc_name_known=1;
X# endif
X	
X	/* can't write if we don't know it - unless we're lucky */
X	if(!(objects[newscroll->otyp].oc_name_known) && 
X# ifdef KAA
X	   !(objects[newscroll->otyp].oc_uname) && 
X# endif
X	   ((pl_character[0] == 'W' && rn2(3)) ||
X	    (pl_character[0] != 'W' && rn2(10))))  {
X		pline("You don't know how to write that!");
X		pline("You write \"Shah was here!\" and the scroll disappears.");
X		obfree(newscroll, (struct obj *) 0);
X		return(1);
X	}
X	
X	/* and now you know it! */
X	objects[newscroll->otyp].oc_name_known = 1;
X	
X	/* success - don't forget to fool prinv() */
X	newscroll = addinv(newscroll);
X	newquan = newscroll->quan;
X	newscroll->quan = 1;
X	prinv(newscroll);
X	newscroll->quan = newquan;
X	
X	return(1);
X}
X# endif /* MARKER /**/
END_OF_write.c
if test 3837 -ne `wc -c <write.c`; then
    echo shar: \"write.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 16 \(of 20\).
cp /dev/null ark16isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 20 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