[comp.sources.games] v10i093: 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 93
Archive-name: nethack3p9/Part48
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 48 (of 56)."
# Contents:  UPDATE6 others/Makefile.st src/artifact.c src/dog.c
#   src/mail.c src/mcastu.c src/wizard.c
# Wrapped by billr@saab on Wed Jul 11 17:12:07 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'UPDATE6' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'UPDATE6'\"
else
echo shar: Extracting \"'UPDATE6'\" \(1295 characters\)
sed "s/^X//" >'UPDATE6' <<'END_OF_FILE'
X--------
XUPDATE 6
X--------
X
XThis patch contains two major improvements:
X
XFirst, thanks to Ari Huttunen, different door states show up as different
X(configurable) characters on the screen.
X
XSecond, doors can now be entered/exited diagonally both for player and
Xmonster.
X
XThird, a gaggle of people credited in the appropriate files developed an
Xoverlay manager for MS-DOS and MSC such that all the options of NetHack can
Xbe supported.  See Install.dos and ovlmgr.* for further details.
X
XIn more minor news:
X
XYou no longer have to pick up food to eat it, and you no longer necessarily
Xresume eating your interrupted meal.
X
XYou can no longer get properties from wielding a non-weapon.
X
XThere is a new option, CLIPPING, which allows playing on small screens or
Xwindows.
X
XThe multiple demon types portion of HARD has been split off into the new
XINFERNO option.
X
XThe Macintosh port has been further refined.
X
XThe / command now takes configurable characters into account when identifying
Xitems.
X
XLeprechauns and lichs and nymphs and nagas had their letters switched so that
Xthe more formidable monsters get capital letters.  Several new low-level
Xmonsters were added.
X
XDrawbridge interactions are much smarter, thanks to Kevin Darcy.
X
XAnd a large number of minor bug fixes and efficiency enhancements.
X
END_OF_FILE
if test 1295 -ne `wc -c <'UPDATE6'`; then
    echo shar: \"'UPDATE6'\" unpacked with wrong size!
fi
# end of 'UPDATE6'
fi
if test -f 'others/Makefile.st' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'others/Makefile.st'\"
else
echo shar: Extracting \"'others/Makefile.st'\" \(9665 characters\)
sed "s/^X//" >'others/Makefile.st' <<'END_OF_FILE'
X#	SCCS Id: @(#)Makefile.st	3.0	90/01/14
X#	ST NetHack 3.0 Makefile for GCC 1.34 or higher
X#
X#    NOTE: There's a bug in the GCC 1.35 (and maybe 1.34) that
X#    requires the omission of the -O flag on a couple of files;
X#    see the comments further down.
X#
X#    Also: There's one really awful kludge here: I had to break
X#    monst.o up into two pieces to get it to compile on my machine
X#    (a Mega 2). You'll need "sed" to get this to work.
X#    If you have 2.5 megs or more, you can probably delete the
X#    strange dependency lines for monst.o and just compile
X#    it directly.
X#
XCC	= d:\gnu\bin\gcc.ttp
XLD	= d:\gnu\bin\gcc-ld.ttp
XYACC	= d:\gnu\bin\bison.ttp -y
XLEX	= d:\gnu\bin\flex.ttp
X#
X# for 32 bit integers (slow, but type mismatches are no problem)
X# MODEL	=
X# TERMCAP = -lcurses
X#
X# for 16 bit integers (faster, but more finicky)
XMODEL	= -mshort
XTERMCAP = -lcurses16
X
X# Directories (makedefs hardcodes these, don't change them)
XINCL	= ..\include
XAUX	= ..\auxil
XSRC	= ..\src
X
X#
X# Use the following line for maximum warnings
XWARN=-D__GNULINT__ -W -Wimplicit -Wreturn-type -Wunused -Wpointer-arith \
X -Wcast-qual -Wwrite-strings
X#
X# WARN =
X#
XCFLAGS = $(MODEL) -O -fomit-frame-pointer $(WARN) -I..\include
XLFLAGS	= $(MODEL) -s
XTARG	= tos
XPC	= pc
X
X# Optional high-quality BSD random number generation routines (see tosconf.h).
X# Set to nothing if not used.
XRANDOM = random.o
X
X# The game name
XGAME= nethack
X
X# The game directory
XGAMEDIR = \games\$(GAME)
X
X# The game filename
XGAMEFILE = $(GAMEDIR)\$(GAME).ttp
X
X# object files for makedefs
XMAKEOBJS = makedefs.o monst.o objects.o
X
X# object files for special levels compiler
XSPLEVOBJS = lev_comp.o lev_lex.o lev_main.o alloc.o monst.o objects.o panic.o
X
X# nothing below this line should have to be changed
X#
X# other things that have to be reconfigured are in config.h,
X# {unixconf.h, pcconf.h, tosconf.h}, and possibly system.h
X
XVOBJ = allmain.o alloc.o apply.o artifact.o attrib.o bones.o cmd.o \
X	dbridge.o decl.o \
X	demon.o do.o do_name.o do_wear.o dog.o dogmove.o dokick.o dothrow.o \
X 	eat.o end.o engrave.o exper.o extralev.o fountain.o getline.o hack.o \
X	invent.o lock.o main.o makemon.o mcastu.o mhitm.o \
X	mhitu.o mklev.o mkmaze.o mkobj.o mkroom.o mon.o mondata.o monmove.o \
X	monst.o  mthrowu.o msdos.o music.o o_init.o objects.o \
X	objnam.o options.o pager.o \
X	pickup.o polyself.o potion.o pray.o pri.o priest.o prisym.o read.o \
X	restore.o rip.o rnd.o rumors.o save.o search.o shk.o shknam.o sit.o \
X	sounds.o sp_lev.o spell.o steal.o termcap.o timeout.o topl.o topten.o \
X	track.o trap.o tty.o u_init.o uhitm.o unix.o vault.o \
X	weapon.o were.o wield.o wizard.o worm.o worn.o write.o zap.o $(RANDOM)
X
XHOBJ =	$(VOBJ) version.o
X
XPCCONF_H   = $(INCL)\$(TARG)conf.h $(INCL)\msdos.h $(INCL)\system.h \
X	     $(INCL)\extern.h 
XGLOBAL_H   = $(INCL)\global.h $(INCL)\coord.h $(PCCONF_H)
XCONFIG_H   = $(INCL)\config.h $(INCL)\tradstdc.h $(GLOBAL_H)
XTRAP_H	   = $(INCL)\trap.h
XPERMONST_H = $(INCL)\permonst.h $(INCL)\monattk.h $(INCL)\monflag.h
XYOU_H	   = $(INCL)\you.h $(INCL)\attrib.h $(PERMONST_H) $(INCL)\mondata.h \
X	     $(INCL)\monst.h $(INCL)\youprop.h $(INCL)\prop.h $(INCL)\pm.h
XDECL_H	   = $(INCL)\decl.h $(INCL)\spell.h $(INCL)\obj.h $(YOU_H) \
X	     $(INCL)\onames.h $(INCL)\pm.h $(INCL)\color.h
XHACK_H	   = $(CONFIG_H) $(DECL_H) $(INCL)\monsym.h $(INCL)\mkroom.h \
X	     $(INCL)\objclass.h $(INCL)\gold.h $(INCL)\trap.h $(INCL)\flag.h \
X	     $(INCL)\rm.h $(INCL)\hack.h
X
X# The main target
X$(GAME).ttp: $(HOBJ)
X	$(CC) -o $(GAME).ttp $(LFLAGS) $(HOBJ) $(TERMCAP)
X
X$(GAME): $(GAME).ttp
X
Xall:	$(GAME) lev_comp.ttp auxil
X	@echo Done.
X
Xmakedefs.ttp:	$(MAKEOBJS)
X	$(CC) $(LFLAGS) -o makedefs.ttp $(MAKEOBJS)
X
Xmakedefs.o:  $(INCL)\config.h $(INCL)\permonst.h $(INCL)\objclass.h
X
Xlev_comp.ttp:  $(SPLEVOBJS)
X	$(CC) $(LFLAGS) -o lev_comp.ttp $(SPLEVOBJS)
X
Xlev_comp.o:  $(HACK_H) $(INCL)\sp_lev.h
Xlev_lex.o:  $(INCL)\lev_comp.h $(HACK_H) $(INCL)\sp_lev.h
Xlev_main.o:  $(HACK_H)
X
X# If you have yacc or lex programs, and make any changes,
X# you'll need rules like these. The names of the output
X# files (e.g. lex,yy.c) vary widely among different ST implementations
X# of YACC and LEX.
X#
X# Also: for some reason the supplied lev_lex.c causes the GCC to abort
X# on my machine (maybe not enough memory?) when compiled with -mshort.
X# With MODEL=-mshort, I had to use the lev_lex.c from others.
X#
Xlev_comp.c:  lev_comp.y
X	$(YACC) -d lev_comp.y
X	cp y,tab.c lev_comp.c
X	cp y,tab.h ..\include\lev_comp.h
X	rm y,tab.c y,tab.h
X
Xlev_lex.c:  lev_comp.l
X	$(LEX) lev_comp.l
X	cp lex,yy.c lev_lex.c
X	rm lex,yy.c
X#
X#	The following include files depend on makedefs to be created.
X#
X#	date.h should be remade any time any of the source or include code
X#	is modified.
X#
X$(INCL)\date.h:	 $(VOBJ) makedefs.ttp
X	.\makedefs -v
X
X$(INCL)\trap.h:	 makedefs.ttp
X	.\makedefs -t
X
X$(INCL)\onames.h:  makedefs.ttp
X	.\makedefs -o
X
X$(INCL)\pm.h:  makedefs.ttp
X	.\makedefs -p
X
Xdata:	$(AUX)\data.base makedefs.ttp
X	.\makedefs -d
X
Xrumors: $(AUX)\rumors.tru $(AUX)\rumors.fal makedefs.ttp
X	.\makedefs -r
X
X#
X#	The following programs vary depending on what OS you are using.
X#
Xmain.o:   $(HACK_H) $(PC)main.c
X	$(CC) -c $(CFLAGS) $(PC)main.c -o main.o
X
Xtty.o:   $(HACK_H) $(INCL)\func_tab.h $(PC)tty.c
X	$(CC) -c $(CFLAGS) $(PC)tty.c -o tty.o
X
Xunix.o:   $(HACK_H) $(PC)unix.c
X	$(CC) -c $(CFLAGS) $(PC)unix.c -o unix.o
X
X#
X# GCC 1.35 has trouble with the construct
X#	for (x = ...) for(y = ...) levl[x][y].foo = stuff;
X# this happens in (at least) bones.c and shknam.c. So if you're using
X# 1.35, uncomment the following lines. The problem is fixed in 1.36.
X#
X#bones.o: $(HACK_H)
X#	$(CC) $(MODEL) $(WARN) -I$(INCL) -c bones.c
X#shknam.o: $(HACK_H) $(INCL)\eshk.h
X#	$(CC) $(MODEL) $(WARN) -I$(INCL) -c shknam.c
X#
X# Secondary targets
X#
X
XAUXMISC = cmdhelp help hh history license opthelp oracles
X
Xauxil:	data rumors spec_levs
X	cd $(AUX)
X	cp data rumors $(GAMEDIR)
X	rm data rumors
X	cp $(AUXMISC) $(GAMEDIR)
X
Xspec_levs: $(AUX)\castle.des $(AUX)\endgame.des $(AUX)\tower.des
X	cd $(AUX)
X	..\src\lev_comp castle.des
X	..\src\lev_comp endgame.des
X	..\src\lev_comp tower.des
X	cp castle endgame $(GAMEDIR)
X	rm castle endgame
X	cp tower1 tower2 tower3 $(GAMEDIR)
X	rm tower1 tower2 tower3
X
Xclean:
X	rm *.o
X
Xspotless: clean
X	cd $(INCL)
X	rm date.h
X	rm onames.h
X	rm pm.h
X	touch date.h onames.h pm.h
X	cd $(SRC)
X	rm makedefs.ttp
X	rm lev_comp.ttp
X
X#
X# Other dependencies
X#
X
X# GO AHEAD, DELETE THIS LINE
X
Xallmain.o: $(HACK_H)
Xalloc.o:  $(CONFIG_H)
Xapply.o:  $(HACK_H) $(INCL)\edog.h
Xartifact.o:  $(HACK_H) $(INCL)\artifact.h
Xattrib.o:  $(HACK_H)
Xbones.o:  $(HACK_H)
Xcmd.o:  $(HACK_H) $(INCL)\func_tab.h
Xdbridge.o: $(HACK_H)
Xdecl.o:  $(HACK_H)
Xdemon.o:  $(HACK_H)
Xdo.o:  $(HACK_H)
Xdo_name.o:  $(HACK_H)
Xdo_wear.o:  $(HACK_H)
Xdog.o:  $(HACK_H) $(INCL)\edog.h
Xdogmove.o:  $(HACK_H) $(INCL)\mfndpos.h $(INCL)\edog.h
Xdokick.o:  $(HACK_H) $(INCL)\eshk.h
Xdothrow.o:  $(HACK_H)
Xeat.o:  $(HACK_H)
Xend.o:  $(HACK_H) $(INCL)\eshk.h
Xengrave.o:  $(HACK_H)
Xexper.o:  $(HACK_H)
Xextralev.o:  $(HACK_H)
Xfountain.o:  $(HACK_H)
Xgetline.o:  $(HACK_H) $(INCL)\func_tab.h
Xhack.o:  $(HACK_H)
Xinvent.o:  $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h
Xioctl.o:  $(HACK_H)
Xlock.o:  $(HACK_H)
Xmakemon.o:  $(HACK_H)
Xmail.o:  $(HACK_H)
Xmcastu.o:  $(HACK_H)
Xmhitm.o:  $(HACK_H) $(INCL)\artifact.h
Xmhitu.o:  $(HACK_H) $(INCL)\artifact.h $(INCL)\edog.h
Xmklev.o:  $(HACK_H)
Xmkmaze.o:  $(HACK_H)
Xmkobj.o:  $(HACK_H)
Xmkroom.o:  $(HACK_H)
Xmon.o:  $(HACK_H) $(INCL)\mfndpos.h $(INCL)\wseg.h
Xmondata.o:  $(HACK_H) $(INCL)\eshk.h $(INCL)\epri.h
Xmonmove.o:  $(HACK_H) $(INCL)\mfndpos.h $(INCL)\artifact.h
X
X# kludge for "monst.c: Virtual memory exhausted" errors
X# we build monst.s in two pieces, then glue them together with
X# "sed". if you don't have memory problems, uncomment out
X# all but the line starting "monst.o:". if you don't have sed, get it from
X# a comp.binaries.atari.st site, or get gnu sed (the port to
X# the atari GCC is easy).
X
Xmonst.o:  $(CONFIG_H) $(PERMONST_H) $(INCL)\eshk.h $(INCL)\vault.h $(INCL)\epri.h $(INCL)\color.h
X	$(CC) $(CFLAGS) -S -o monst1.s -DSPLITMON_1 monst.c
X	$(CC) $(CFLAGS) -S -o monst2.s -DSPLITMON_2 monst.c
X	sed -e s/LC/LD/ -e s/gcc_compiled.:// monst2.s >>monst1.s
X	$(CC) $(CFLAGS) -c monst1.s -o monst.o
X	rm monst1.s monst2.s
X
Xmsdos.o:  $(HACK_H)
Xmthrowu.o:  $(HACK_H)
Xmusic.o:  $(HACK_H)
Xo_init.o:  $(HACK_H) $(INCL)\onames.h
Xobjects.o:  $(CONFIG_H) $(INCL)\obj.h $(INCL)\objclass.h $(INCL)\prop.h $(INCL)\color.h
Xobjnam.o:  $(HACK_H)
Xoptions.o:  $(HACK_H)
Xpager.o:  $(HACK_H)
Xpanic.o:  $(CONFIG_H)
Xpickup.o:  $(HACK_H)
Xpolyself.o:  $(HACK_H)
Xpotion.o:  $(HACK_H)
Xpray.o:  $(HACK_H)
Xpri.o:  $(HACK_H) $(INCL)\epri.h $(INCL)\termcap.h
Xpriest.o:  $(HACK_H) $(INCL)\mfndpos.h $(INCL)\eshk.h $(INCL)\epri.h
Xprisym.o:  $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h
Xrandom.o:
Xread.o:  $(HACK_H)
Xrestore.o:  $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h
Xrip.o:  $(HACK_H)
Xrnd.o:  $(HACK_H)
Xrumors.o:  $(HACK_H)
Xsave.o:  $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h
Xsearch.o:  $(HACK_H) $(INCL)\artifact.h
Xshk.o:  $(HACK_H) $(INCL)\eshk.h
Xshknam.o:  $(HACK_H) $(INCL)\eshk.h
Xsit.o:  $(HACK_H)
Xsounds.o:  $(HACK_H) $(INCL)\edog.h $(INCL)\eshk.h
Xsp_lev.o:  $(HACK_H) $(INCL)\sp_lev.h
Xspell.o:  $(HACK_H)
Xsteal.o:  $(HACK_H)
Xtermcap.o:  $(HACK_H) $(INCL)\termcap.h
Xtimeout.o:  $(HACK_H)
Xtopl.o:  $(HACK_H)
Xtopten.o:  $(HACK_H)
Xtrack.o:  $(HACK_H)
Xtrap.o:  $(HACK_H) $(INCL)\edog.h
Xu_init.o:  $(HACK_H)
Xuhitm.o:  $(HACK_H) $(INCL)\artifact.h
Xvault.o:  $(HACK_H) $(INCL)\vault.h
Xversion.o:  $(HACK_H) $(INCL)\date.h $(INCL)\patchlevel.h
Xweapon.o:  $(HACK_H)
Xwere.o:  $(HACK_H)
Xwield.o:  $(HACK_H)
Xwizard.o:  $(HACK_H)
Xworm.o:  $(HACK_H) $(INCL)\wseg.h
Xworn.o:  $(HACK_H)
Xwrite.o:  $(HACK_H)
Xzap.o:  $(HACK_H)
END_OF_FILE
if test 9665 -ne `wc -c <'others/Makefile.st'`; then
    echo shar: \"'others/Makefile.st'\" unpacked with wrong size!
fi
# end of 'others/Makefile.st'
fi
if test -f 'src/artifact.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/artifact.c'\"
else
echo shar: Extracting \"'src/artifact.c'\" \(8821 characters\)
sed "s/^X//" >'src/artifact.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)artifact.c	3.0	88/07/27
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X
X#ifdef NAMED_ITEMS
X
X#include "artifact.h"
X
X#ifndef OVLB
X
XSTATIC_DCL const struct artifact artilist[];
X
X#else /* OVLB */
X
X/* the artifacts (currently weapons only) */
XSTATIC_OVL const struct artifact NEARDATA artilist[] = {
X
X#define	    NO_ATTK	{ 0, 0, 0, 0 }
X
X{ LONG_SWORD,	 "Excalibur",	(SPFX_NOGEN | SPFX_SEEK | SPFX_DEFN |
X								SPFX_SEARCH), 0,
X  { 0, AD_PHYS, 5, 10 }, { 0, AD_DRLI, 0, 0}, A_LAW, 'K' },
X
X{ KATANA,	 "Snickersnee",	SPFX_RESTR, 0,
X  { 0, AD_PHYS, 0, 8 }, NO_ATTK, A_LAW, 'S' },
X
X/*	Ah, never shall I forget the cry, 
X *		or the shriek that shrieked he,
X *	As I gnashed my teeth, and from my sheath
X *		I drew my Snickersnee!
X *
X *		--Koko, Lord high executioner of Titipu
X *		  (From Sir W.S. Gilbert's "The Mikado")
X */
X
X{ AXE,		 "Cleaver",	SPFX_RESTR, 0,
X  { 0, AD_PHYS, 3, 12 }, NO_ATTK, A_CHAOS, 0 },
X
X#ifdef TOLKIEN
X{ ORCISH_DAGGER, "Grimtooth",	SPFX_RESTR, 0,
X  { 0, AD_PHYS, 2, 6 }, NO_ATTK, A_CHAOS, 0 },
X#else
X{ DAGGER,	 "Grimtooth",	SPFX_RESTR, 0,
X  { 0, AD_PHYS, 2, 6 }, NO_ATTK, A_CHAOS, 0 },
X#endif
X
X/*  Special purpose swords - various types */
X
X{ TWO_HANDED_SWORD, "Orcrist",	SPFX_DFLAG2, M2_ORC,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 'E' },
X
X#ifdef TOLKIEN
X{ ELVEN_DAGGER,	 "Sting",	(SPFX_WARN | SPFX_DFLAG2), M2_ORC,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
X#else
X{ DAGGER,	 "Sting",	(SPFX_WARN | SPFX_DFLAG2), M2_ORC,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
X#endif
X
X{ LONG_SWORD,	 "Frost Brand", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0,
X  { 0, AD_COLD, 5, 0 }, { 0, AD_COLD, 0, 0 }, A_NEUTRAL, 0 },
X
X{ LONG_SWORD,	 "Fire Brand",	(SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0,
X  { 0, AD_FIRE, 5, 0 }, { 0, AD_FIRE, 0, 0 }, A_NEUTRAL, 0 },
X
X/* Stormbringer only has a 2 because it can drain a level, providing 8 more */
X{ BROADSWORD,	 "Stormbringer", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN |
X								SPFX_DRLI), 0,
X  { 0, AD_DRLI, 5, 2 }, { 0, AD_DRLI, 0, 0 }, A_CHAOS, 0 },
X
X{ LONG_SWORD,	 "Sunsword",	(SPFX_RESTR | SPFX_DFLAG2), M2_UNDEAD,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
X
X{ BROADSWORD,	 "Dragonbane",	(SPFX_RESTR | SPFX_DCLAS), S_DRAGON,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_NEUTRAL, 0 },
X
X{ LONG_SWORD,	 "Demonbane",	(SPFX_RESTR | SPFX_DFLAG2), M2_DEMON,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
X
X/* A silver weapon would be appropriate, if we had one. */
X{ LONG_SWORD,	 "Werebane",	(SPFX_RESTR | SPFX_DFLAG2), M2_WERE,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
X
X{ LONG_SWORD,	 "Giantslayer", (SPFX_RESTR | SPFX_DFLAG2), M2_GIANT,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_NEUTRAL, 0 },
X
X/* Another interesting weapon would be the dwarven hammer or axe with the
X * boomerang-like power of returning to the wielder's hand, if the code
X * were written to add such an ability.
X */
X{ WAR_HAMMER, "Ogresmasher",	(SPFX_RESTR | SPFX_DCLAS), S_OGRE,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
X
X{ WAR_HAMMER, "Mjollnir",	(SPFX_RESTR | SPFX_ATTK),  0,
X  { 0, AD_ELEC, 5, 24 }, NO_ATTK, A_LAW, 'V' }, /* Mjo:llnir */
X
X{ MORNING_STAR,	 "Trollsbane", (SPFX_RESTR | SPFX_DCLAS), S_TROLL,
X  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
X
X/*	ARRAY TERMINATOR	*/
X{ 0,  "", 0, 0, NO_ATTK, NO_ATTK, 0, 0 }
X};
X
Xconst int artifact_num = SIZE(artilist);
X
X/* this array gets saved / restored - thus not static */
Xboolean artiexist[SIZE(artilist)];
X
X#endif /* OVLB */
X
XSTATIC_DCL const struct artifact *FDECL(get_artifact, (struct obj *));
XSTATIC_DCL int FDECL(spec_applies, (const struct artifact *, struct permonst *));
X
X#ifdef OVLB
X
X/* zero out the artifact exist list */
Xvoid
Xinit_exists()
X{
X	int i;
X
X	for(i = 0; i < SIZE(artilist); i++)
X		artiexist[i] = 0;
X}
X
Xvoid
Xmkartifact(otmp1)
Xstruct obj **otmp1;
X{
X	register const struct artifact *artif;
X	register struct obj *otmp = *otmp1;
X	register int n = 0, m;
X
X	for(artif = artilist,m = 0; artif->otyp; artif++,m++)
X	    if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN) &&
X	       !artiexist[m]) n++;
X
X	if (n) {
X		n = rnd(n);
X		for(artif = artilist,m = 0; artif->otyp && n > 0; ) {
X		    if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN) &&
X		       !artiexist[m]) n--;
X		    if (n > 0) {
X			artif++;
X			m++;
X		    }
X		}
X
X		if(artif->otyp) {
X		    *otmp1 = oname(otmp, artif->name, 0);
X		    artiexist[m] = TRUE;
X		}
X	}
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
XSTATIC_OVL const struct artifact *
Xget_artifact(otmp)
Xstruct obj *otmp;
X{
X	register const struct artifact *artif;
X
X	if(otmp)
X	    if(strlen(ONAME(otmp)))
X		for(artif = artilist; artif->otyp; artif++)
X		    if(artif->otyp == otmp->otyp &&
X		       !strcmp(ONAME(otmp), artif->name))
X			    return artif;
X	return((struct artifact *)0);
X}
X
X#endif /* OVL0 */
X#ifdef OVL2
X
Xboolean
Xis_artifact(otmp)
Xstruct obj *otmp;
X{
X	return(get_artifact(otmp) != (struct artifact *)0);
X}
X
X#endif /* OVL2 */
X#ifdef OVLB
Xboolean
Xexist_artifact(otmp, name)
Xregister struct obj *otmp;
Xregister const char *name;
X{
X	register const struct artifact *artif;
X	register boolean *arex;
X
X	if(otmp && strlen(name))
X	    for(artif = artilist,arex = artiexist; artif->otyp; artif++,arex++)
X		if(artif->otyp == otmp->otyp &&
X		   !strcmp(name, artif->name) &&
X		   *arex)
X		    return TRUE;
X	return FALSE;
X}
X
Xvoid
Xartifact_exists(otmp, name, mod)
Xregister struct obj *otmp;
Xregister const char *name;
Xregister boolean mod;
X{
X	register const struct artifact *artif;
X	register boolean *arex;
X
X	if(otmp && strlen(name))
X	    for(artif = artilist,arex = artiexist; artif->otyp; artif++,arex++)
X		if(artif->otyp == otmp->otyp &&
X		   !strcmp(name, artif->name))
X		    *arex = mod;
X	return;
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xboolean
Xspec_ability(otmp, abil)
Xstruct obj *otmp;
Xunsigned abil;
X{
X	const struct artifact *arti = get_artifact(otmp);
X	
X	return(arti && (arti->spfx & abil));
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xint
Xrestr_name(otmp, name)	/* returns 1 if name is restricted for otmp->otyp */
Xregister struct obj *otmp;
Xregister char	*name;
X{
X	register const struct artifact *artif;
X
X	if(!strlen(name)) return(0);
X
X	for(artif = artilist; artif->otyp; artif++)
X	    if(artif->otyp == otmp->otyp)
X		if(artif->spfx & (SPFX_NOGEN | SPFX_RESTR))
X		    if(!strcmp(artif->name, name)) return(1);
X
X	return(0);
X}
X
X# if defined(THEOLOGY) && defined(ALTARS)
Xstruct obj *
Xmk_aligned_artifact(align)
Xunsigned align;
X{
X	register const struct artifact *artif;
X	register struct obj *otmp;
X	register int n = 0, m;
X
X	for(artif = artilist,m = 0; artif->otyp; artif++,m++)
X	    if(align == artif->align && !(artif->spfx & SPFX_NOGEN) && !artiexist[m])
X		if (pl_character[0] == artif->class) {
X		    n = 0;
X		    break;
X		} else n++;
X	if (n) {
X		n = rnd(n);
X		for(artif = artilist,m = 0; artif->otyp && n > 0; ) {
X		    if(align == artif->align && !(artif->spfx & SPFX_NOGEN) && !artiexist[m])
X			n--;
X		    if (n > 0) {
X			artif++;
X			m++;
X		    }
X		}
X	}
X	if(artif->otyp) {
X		otmp = mksobj((int)artif->otyp, FALSE);
X		otmp = oname(otmp, artif->name, 0);
X		artiexist[m] = TRUE;
X		return (otmp);
X	}
X	return ((struct obj *) 0);
X}
X# endif
X
Xint
Xdefends(adtyp, otmp)
Xregister int adtyp;
Xregister struct obj *otmp;
X{
X	register const struct artifact *weap;
X
X	if(weap = get_artifact(otmp))
X		return(weap->defn.adtyp == adtyp);
X	return(0);
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
XSTATIC_OVL int
Xspec_applies(weap, ptr)
Xregister const struct artifact *weap;
Xstruct permonst *ptr;
X{
X	if(!(weap->spfx & (SPFX_DBONUS | SPFX_ATTK)))
X	    return(0);
X
X	if(weap->spfx & SPFX_DMONS)
X	    return((ptr == &mons[(int)weap->mtype]));
X	else if(weap->spfx & SPFX_DCLAS)
X	    return((weap->mtype == ptr->mlet));
X	else if(weap->spfx & SPFX_DFLAG1)
X	    return((ptr->mflags1 & weap->mtype) != 0L);
X	else if(weap->spfx & SPFX_DFLAG2)
X	    return((ptr->mflags2 & weap->mtype) != 0L);
X	else if(weap->spfx & SPFX_ATTK) {
X	    switch(weap->attk.adtyp) {
X		case AD_FIRE:	return(!resists_fire(ptr));
X		case AD_COLD:	return(!resists_cold(ptr));
X		case AD_ELEC:	return(!resists_elec(ptr));
X		case AD_DRLI:	return(!resists_drli(ptr));
X		case AD_STON:	return(!resists_ston(ptr));
X		default:	impossible("Weird special attack for '%s'",
X					   weap->name);
X	    }
X	}
X	return(0);
X}
X
Xint
Xspec_abon(otmp, ptr)
Xstruct obj *otmp;
Xstruct permonst *ptr;
X{
X	register const struct artifact *weap;
X
X	if((weap = get_artifact(otmp)))
X		if(spec_applies(weap, ptr))
X		    return((weap->attk.damn) ? rnd((int)weap->attk.damn) : 0);
X	return(0);
X}
X
Xint
Xspec_dbon(otmp, ptr, tmp)
Xregister struct obj *otmp;
Xregister struct permonst *ptr;
Xregister int	tmp;
X{
X	register const struct artifact *weap;
X
X	if((weap = get_artifact(otmp)))
X		if(spec_applies(weap, ptr))
X		    return((weap->attk.damd) ? rnd((int)weap->attk.damd) : tmp);
X	return(0);
X}
X
X#endif /* OVL1 */
X
X#endif /* NAMED_ITEMS */
END_OF_FILE
if test 8821 -ne `wc -c <'src/artifact.c'`; then
    echo shar: \"'src/artifact.c'\" unpacked with wrong size!
fi
# end of 'src/artifact.c'
fi
if test -f 'src/dog.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dog.c'\"
else
echo shar: Extracting \"'src/dog.c'\" \(8861 characters\)
sed "s/^X//" >'src/dog.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)dog.c	3.0	89/11/20
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 "edog.h"
X
X#ifdef OVLB
X
Xchar NEARDATA dogname[63] = DUMMY;
Xchar NEARDATA catname[63] = DUMMY;
X
X#endif /* OVLB */
X
X#define domestic(mtmp)	(mtmp->data->msound == MS_BARK || mtmp->data->msound == MS_MEW)
X
X#ifdef OVLB
X
Xvoid
Xinitedog(mtmp)
Xregister struct monst *mtmp;
X{
X	mtmp->mtame = domestic(mtmp) ? 10 : 5;
X	mtmp->mpeaceful = 1;
X	mtmp->mleashed = 0;
X	mtmp->meating = 0;
X	EDOG(mtmp)->droptime = 0;
X	EDOG(mtmp)->dropdist = 10000;
X	EDOG(mtmp)->apport = 10;
X	EDOG(mtmp)->whistletime = 0;
X	EDOG(mtmp)->hungrytime = 1000 + moves;
X}
X
Xvoid
Xmake_familiar(otmp)
Xregister struct obj *otmp;
X{
X	register struct monst *mtmp;
X	register struct permonst *pm;
X
Xtop:
X	if (otmp) pm = &mons[otmp->corpsenm]; /* Figurine; otherwise spell */
X	else if (rn2(3)) {
X	    if (!(pm = rndmonst())) {
X		pline("There seems to be nothing available for a familiar.");
X		return;
X	    }
X	}
X	else if ((pl_character[0]=='W' || rn2(2)) && pl_character[0]!='C')
X		pm = &mons[PM_KITTEN];
X	else pm = &mons[PM_LITTLE_DOG];
X
X	pm->pxlth += sizeof(struct edog);
X	mtmp = makemon(pm, u.ux, u.uy);
X	pm->pxlth -= sizeof(struct edog);
X	if (!mtmp) { /* monster was genocided */
X	    if (otmp)
X		pline("The figurine writhes and then shatters into pieces!");
X	    else goto top;
X		/* rndmonst() returns something not genocided always, so this
X		 * means it was a cat or dog; loop back to try again until
X		 * either rndmonst() is called, or if only one of cat/dog
X		 * was genocided, they get the other.
X		 */
X	    return;
X	}
X	initedog(mtmp);
X	mtmp->msleep = 0;
X	if (otmp && otmp->cursed) { /* cursed figurine */
X		You("get a bad feeling about this.");
X		mtmp->mtame = mtmp->mpeaceful = 0;
X	}
X}
X
Xstruct monst *
Xmakedog() {
X	register struct monst *mtmp;
X	register char *petname;
X
X	if (pl_character[0]=='C' || (pl_character[0] != 'W' && rn2(2))) {
X		mons[PM_LITTLE_DOG].pxlth = sizeof(struct edog);
X		mtmp = makemon(&mons[PM_LITTLE_DOG], u.ux, u.uy);
X		mons[PM_LITTLE_DOG].pxlth = 0;
X		petname = dogname;
X	} else {
X		mons[PM_KITTEN].pxlth = sizeof(struct edog);
X		mtmp = makemon(&mons[PM_KITTEN], u.ux, u.uy);
X		mons[PM_KITTEN].pxlth = 0;
X		petname = catname;
X	}
X
X	if(!mtmp) return((struct monst *) 0); /* dogs were genocided */
X
X	if (petname[0]) {
X		mtmp = christen_monst(mtmp, petname);
X#ifndef MACOS
X		petname[0] = '\0'; /* name first only; actually unnecessary */
X#endif
X	}
X	initedog(mtmp);
X	return(mtmp);
X}
X
X/* attach the monsters that went down (or up) together with @ */
Xstruct monst *mydogs = 0;
X/* monsters that fell through a trap door or stepped on a tele-trap. */
X/* 'down' is now true only of trap door falling, not for tele-trap. */
Xstruct monst *fallen_down = 0;
X				
Xvoid
Xlosedogs(){
X	register struct monst *mtmp,*mtmp0,*mtmp2;
X
X	while(mtmp = mydogs){
X		mydogs = mtmp->nmon;
X		mtmp->nmon = fmon;
X		fmon = mtmp;
X		mnexto(mtmp);
X	}
X#if defined(LINT) || defined(__GNULINT__)
X	mtmp0 = (struct monst *)0;
X#endif
X	for(mtmp = fallen_down; mtmp; mtmp = mtmp2) {
X		mtmp2 = mtmp->nmon;
X		if(mtmp->mx == dlevel) {
X		    mtmp->mx = 0;
X		    if(mtmp == fallen_down)
X			fallen_down = mtmp->nmon;
X		    else
X			mtmp0->nmon = mtmp->nmon;
X		    mtmp->nmon = fmon;
X		    fmon = mtmp;
X		    if ((mtmp->data->geno&G_GENOD) && !(mtmp->data->geno&G_UNIQ)) {
X#ifdef KOPS
X			allow_kops = FALSE;
X#endif
X			mondead(mtmp);	/* must put in fmon list first */
X#ifdef KOPS
X			allow_kops = TRUE;
X#endif
X		    } else if (mtmp->isshk)
X			home_shk(mtmp);
X		    else
X			rloc(mtmp);
X		} else
X		    mtmp0 = mtmp;
X	}
X}
X
X#endif /* OVLB */
X#ifdef OVL2
X
Xvoid
Xkeepdogs(){
Xregister struct monst *mtmp;
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X	    if(((monnear(mtmp, u.ux, u.uy) && levl_follower(mtmp)) ||
X		/* the wiz will level t-port from anywhere to chase
X		   the amulet; if you don't have it, will chase you
X		   only if in range. -3. */
X			(u.uhave_amulet && mtmp->iswiz))
X			&& !mtmp->msleep && mtmp->mcanmove) {
X#ifdef WORM
X		/* Bug "fix" for worm changing levels collapsing dungeon
X		 */
X		if (mtmp->data == &mons[PM_LONG_WORM]) {
X			if (showmon(mtmp))
X				pline("The worm can't fit down the stairwell.");
X# ifdef WALKIES
X			if (mtmp->mleashed) {
X				pline("The leash slides off the slimy worm.");
X				m_unleash(mtmp);
X			}
X# endif
X			continue;
X		}
X#endif
X		if (mon_has_amulet(mtmp)) {
X			pline("%s seems very disoriented for a moment.",
X				Monnam(mtmp));
X#ifdef WALKIES
X			if (mtmp->mleashed) {
X				pline("%s leash suddenly comes loose.",
X					is_female(mtmp) ? "Her" :
X					humanoid(mtmp->data) ? "His" : "Its");
X				m_unleash(mtmp);
X			}
X#endif
X			continue;
X		}
X		relmon(mtmp);
X		mtmp->mx = mtmp->my = 0; /* avoid mnexto()/MON_AT() problem */
X		mtmp->nmon = mydogs;
X		mydogs = mtmp;
X		unpmon(mtmp);
X		keepdogs();	/* we destroyed the link, so use recursion */
X		return;		/* (admittedly somewhat primitive) */
X	}
X}
X
X#endif /* OVL2 */
X#ifdef OVLB
X
Xvoid
Xfall_down(mtmp, tolev) 
Xregister struct monst *mtmp; 
Xregister int tolev;
X{
X	relmon(mtmp);
X	mtmp->nmon = fallen_down;
X	fallen_down = mtmp;
X#ifdef WALKIES
X	if (mtmp->mleashed)  {
X		pline("The leash comes off!");
X		m_unleash(mtmp);
X	}
X#endif
X	unpmon(mtmp);
X	mtmp->mtame = 0;
X	mtmp->mx = tolev; 
X	mtmp->my = 0;
X		/* make sure to reset mtmp->mx to 0 when releasing, */
X		/* so rloc() on next level doesn't affect MON_AT() state */
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
X/* return quality of food; the lower the better */
X/* fungi will eat even tainted food */
Xint
Xdogfood(mon,obj)
Xstruct monst *mon;
Xregister struct obj *obj;
X{
X	boolean carni = carnivorous(mon->data);
X	boolean herbi = herbivorous(mon->data);
X
X	switch(obj->olet) {
X	case FOOD_SYM:
X	    if (obj->otyp == CORPSE && obj->corpsenm == PM_COCKATRICE &&
X		!resists_ston(mon->data))
X		    return TABU;
X
X	    if (!carni && !herbi)
X		    return (obj->cursed ? UNDEF : APPORT);
X
X	    switch (obj->otyp) {
X		case TRIPE_RATION:
X		    return (carni ? DOGFOOD : MANFOOD);
X		case EGG:
X		    if (obj->corpsenm == PM_COCKATRICE &&
X						!resists_ston(mon->data))
X			return POISON;
X		    return (carni ? CADAVER : MANFOOD);
X		case CORPSE:
X		    if ((obj->age+50 <= monstermoves
X					    && obj->corpsenm != PM_LIZARD
X					    && mon->data->mlet != S_FUNGUS) ||
X			(acidic(&mons[obj->corpsenm]) &&
X						!resists_acid(mon->data)) ||
X			(poisonous(&mons[obj->corpsenm]) &&
X						!resists_poison(mon->data)))
X			return POISON;
X		    else if (mon->data->mlet == S_FUNGUS)
X			return (herbi ? CADAVER : MANFOOD);
X		    else return (carni ? CADAVER : MANFOOD);
X		case CLOVE_OF_GARLIC:
X		    return (is_undead(mon->data) ? TABU :
X			    (herbi ? ACCFOOD : MANFOOD));
X		case TIN:
X		    return MANFOOD;
X		case APPLE:
X		case CARROT:
X		    return (herbi ? DOGFOOD : MANFOOD);
X		default:
X#ifdef TUTTI_FRUTTI
X		    return (obj->otyp > SLIME_MOLD ?
X#else
X		    return (obj->otyp > CLOVE_OF_GARLIC ?
X#endif
X			    (carni ? ACCFOOD : MANFOOD) :
X			    (herbi ? ACCFOOD : MANFOOD));
X	    }
X	default:
X	    if(!obj->cursed) return(APPORT);
X	    /* fall into next case */
X	case BALL_SYM:
X	case CHAIN_SYM:
X	case ROCK_SYM:
X	    return(UNDEF);
X	}
X}
X
X#endif /* OVL1 */
X#ifdef OVL0
X
X/* return roomnumber or -1 */
Xint
Xinroom(x,y) xchar x,y; {
X	register struct mkroom *croom = &rooms[0];
X	while(croom->hx >= 0){
X		if(croom->hx >= x-1 && croom->lx <= x+1 &&
X		   croom->hy >= y-1 && croom->ly <= y+1)
X			return(croom - rooms);
X		croom++;
X	}
X	return(-1);	/* not in room or on door */
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xstruct monst *
Xtamedog(mtmp, obj)
Xregister struct monst *mtmp;
Xregister struct obj *obj;
X{
X	register struct monst *mtmp2;
X
X	/* The wiz and medusa aren't even made peaceful. */
X	if (mtmp->iswiz
X#ifdef MEDUSA
X			   || mtmp->data == &mons[PM_MEDUSA]
X#endif
X								)
X		return((struct monst *)0);
X
X	/* worst case, at least he'll be peaceful. */
X	mtmp->mpeaceful = 1;
X	if(flags.moonphase == FULL_MOON && night() && rn2(6) && obj
X						&& mtmp->data->mlet == S_DOG)
X		return((struct monst *)0);
X
X	/* If we cannot tame him, at least he's no longer afraid. */
X	mtmp->mflee = 0;
X	mtmp->mfleetim = 0;
X	if(mtmp->mtame || !mtmp->mcanmove ||
X	   mtmp->isshk || mtmp->isgd ||
X#if defined(ALTARS) && defined(THEOLOGY)
X	   mtmp->ispriest ||
X#endif
X#ifdef POLYSELF
X	   is_human(mtmp->data) || (is_demon(mtmp->data) && !is_demon(uasmon)))
X#else
X	   is_human(mtmp->data) || is_demon(mtmp->data))
X#endif
X		return((struct monst *)0);
X	if(obj) {
X		if(dogfood(mtmp, obj) >= MANFOOD) return((struct monst *)0);
X		if(cansee(mtmp->mx,mtmp->my))
X			pline("%s devours the %s.", Monnam(mtmp), xname(obj));
X		obfree(obj, (struct obj *)0);
X	}
X	mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
X	*mtmp2 = *mtmp;
X	mtmp2->mxlth = sizeof(struct edog);
X	if(mtmp->mnamelth) Strcpy(NAME(mtmp2), NAME(mtmp));
X	initedog(mtmp2);
X	replmon(mtmp,mtmp2);
X	return(mtmp2);
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 8861 -ne `wc -c <'src/dog.c'`; then
    echo shar: \"'src/dog.c'\" unpacked with wrong size!
fi
# end of 'src/dog.c'
fi
if test -f 'src/mail.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/mail.c'\"
else
echo shar: Extracting \"'src/mail.c'\" \(8762 characters\)
sed "s/^X//" >'src/mail.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)mail.c	3.0	89/07/07
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/* block some unused #defines to avoid overloading some cpp's */
X#define MONATTK_H
X#include "hack.h"	/* mainly for index() which depends on BSD */
X
X#ifdef MAIL
Xstatic void FDECL(mdrush,(struct monst *,int,int));
Xstatic void FDECL(mdappear,(struct monst *,BOOLEAN_P));
Xstatic void NDECL(newmail);
X
X# ifdef UNIX
X#  include <sys/stat.h>
X#  include <pwd.h>
X# endif
X# ifdef VMS
X#  include <descrip.h>
X#  include <ssdef.h>
X# endif
X
X/*
X * Notify user when new mail has arrived. [Idea from Merlyn Leroy, but
X * I don't know the details of his implementation.]
X * { Later note: he disliked my calling a general mailreader and felt that
X *   hack should do the paging itself. But when I get mail, I want to put it
X *   in some folder, reply, etc. - it would be unreasonable to put all these
X *   functions in hack. }
X *
X * The mail daemon can move with less than usual restraint.  It can:
X *	- move diagonally from a door
X *	- use secret doors
X *	- run thru a monster
X *
X * Its path should be longer when you are Telepat-hic and Blind.
X *
X * Possible extensions:
X *	- Open the file MAIL and do fstat instead of stat for efficiency.
X *	  (But sh uses stat, so this cannot be too bad.)
X *	- Examine the mail and produce a scroll of mail named "From somebody".
X *	- Invoke MAILREADER in such a way that only this single letter is read.
X *	- Do something to the text when the scroll is enchanted or cancelled.
X */
X
X/*
X * { Note by Olaf Seibert: On the Amiga, we usually don't get mail.
X *   So we go through most of the effects at 'random' moments. }
X */
X
X/*
X * I found many bugs in this code, some dating back to Hack.
X * Here are some minor problems i didn't fix:  -3.
X *
X *	- The code sometimes pops up the mail daemon next to you on
X *	  the corridor side of doorways when there are open spaces
X *	  within the room.
X *	- It may also do this with adjoining castle rooms.
X */
X
X#ifdef OVL0
X
X# if !defined(UNIX) && !defined(VMS)
Xint mustgetmail = -1;
X# endif
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X# ifdef UNIX
Xextern struct passwd *getpwuid();
Xstatic struct stat omstat,nmstat;
Xstatic char *mailbox = NULL;
Xstatic long laststattime;
X
X# ifdef AMS				/* Just a placeholder for AMS */
X#   define MAILPATH "/dev/null"
X# else
X#  ifdef BSD
X#   define MAILPATH "/usr/spool/mail/"
X#  endif
X#  ifdef SYSV
X#   define MAILPATH "/usr/mail/"
X#  endif
X# endif /* AMS */
X
Xvoid
Xgetmailstatus() {
X	if(!mailbox && !(mailbox = getenv("MAIL"))) {
X#  ifdef MAILPATH
X#   ifdef AMS
X	        struct passwd ppasswd;
X
X		bcopy(getpwuid(getuid()), &ppasswd, sizeof(struct passwd));
X		if (ppasswd.pw_dir) {
X		     mailbox = (char *) alloc((unsigned) strlen(ppasswd.pw_dir)+sizeof(AMS_MAILBOX));
X		     Strcpy(mailbox, ppasswd.pw_dir);
X		     Strcat(mailbox, AMS_MAILBOX);
X		} else
X		  return;
X#   else
X		mailbox = (char *) alloc(sizeof(MAILPATH)+8);
X		Strcpy(mailbox, MAILPATH);
X		Strcat(mailbox, getpwuid(getuid())->pw_name);
X#  endif /* AMS */
X#  else
X		return;
X#  endif
X	}
X	if(stat(mailbox, &omstat)){
X#  ifdef PERMANENT_MAILBOX
X		pline("Cannot get status of MAIL=\"%s\".", mailbox);
X		mailbox = 0;
X#  else
X		omstat.st_mtime = 0;
X#  endif
X	}
X}
X# endif /* UNIX */
X
X# ifdef VMS
Xextern unsigned long pasteboard_id;
Xvolatile int broadcasts = 0;
X#  define getmailstatus()
X# endif /* VMS */
X
X
X/* make mail daemon run through the dungeon */
Xstatic void
Xmdrush(md,fx,fy)
Xstruct monst *md;
Xregister int fx, fy;	/* origin, where the '&' is displayed */
X{
X	register int tx = md->mx, ty = md->my;
X			/* real location, where the '&' is going */
X
X	tmp_at(-1, md->data->mlet);	/* open call */
X#ifdef TEXTCOLOR
X	tmp_at(-3, (int)md->data->mcolor);
X#endif
X
X	while(fx != tx || fy != ty) {
X		register int dx, dy,		/* direction counters */
X			     nfx = fx, nfy = fy,/* next location */ 
X			     d1, d2;		/* shortest dist, eval */
X
X		/* display the '&' at (fx,fy) */
X		tmp_at(fx,fy);
X
X		/* find location next to (fx,fy) closest to (tx,ty) */
X		d1 = dist2(fx,fy,tx,ty);
X		for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
X		    if((dx || dy) && isok(fx+dx,fy+dy) && 
X		       !IS_STWALL(levl[fx+dx][fy+dy].typ)) {
X			d2 = dist2(fx+dx,fy+dy,tx,ty);
X			if(d2 < d1) {
X			    d1 = d2;
X			    nfx = fx+dx;
X			    nfy = fy+dy;
X			}
X		    }
X
X		/* set (fx,fy) to next location, unless it stopped */
X		if(nfx != fx || nfy != fy) {
X		    fx = nfx;
X		    fy = nfy;
X		} else break;
X	}
X
X	tmp_at(-1,-1);			/* close call */
X}
X
Xstatic void
Xmdappear(md,away)
Xstruct monst *md;
Xboolean away;
X{
X	static int fx, fy;			/* origin */
X	int tx = md->mx, ty = md->my;		/* destination */
X	register int uroom = inroom(u.ux, u.uy);/* room you're in */
X
X	/* if mail daemon is in same room as you */
X	if(uroom >= 0 && inroom(md->mx,md->my) == uroom && (!Blind || Telepat))
X		if(away) {
X			unpmon(md);
X			remove_monster(tx, ty);
X
X			/* fake "real" location to origin */
X			md->mx = fx; md->my = fy;
X
X			/* rush from destination */
X			mdrush(md,tx,ty);
X			return;
X		} else {
X			/* choose origin */
X			register int cnt = rooms[uroom].doorct;
X			register int tmp = rooms[uroom].fdoor;
X			register int dd = 0;
X
X			/* which door (or staircase) is farthest? */
X			while (cnt--) {
X				if(dd < dist(doors[tmp].x, doors[tmp].y)) {
X					fx = doors[tmp].x;
X					fy = doors[tmp].y;
X					dd = dist(tx,ty);
X				}
X				tmp++;
X			}
X			if (has_dnstairs(&rooms[uroom]))
X				if(dd < dist(xdnstair, ydnstair)) {
X					fx = xdnstair;
X					fy = ydnstair;
X					dd = dist(xdnstair, ydnstair);
X				}
X			if (has_upstairs(&rooms[uroom]))
X				if(dd < dist(xupstair, yupstair)) {
X					fx = xupstair;
X					fy = yupstair;
X				}
X
X			/* rush from origin */
X			mdrush(md,fx,fy);
X		}
X
X	pmon(md);
X}
X
Xstatic void
Xnewmail() {
X	struct obj *obj;
X	/* deliver a scroll of mail */
X	register boolean invload =
X		((inv_weight() + (int)objects[SCR_MAIL].oc_weight) > 0 ||
X			 Fumbling);
X	register struct monst *md = makemon(&mons[PM_MAIL_DAEMON], u.ux, u.uy);
X
X	if(!md)	return;
X
X	mdappear(md,FALSE);
X
X# ifdef VMS
X	pline("\"Hello, %s!  I have a message for you.\"", plname);
X# else
X#  ifdef NO_MAILREADER
X	pline("\"Hello, %s!  You have some mail in the outside world.\"", plname);
X#  else
X	pline("\"Hello, %s!  I have some mail for you.\"", plname);
X# endif
X# endif
X
X# ifndef NO_MAILREADER
X	if(dist(md->mx,md->my) > 2)
X		verbalize("Catch!");
X	more();
X	obj = mksobj(SCR_MAIL, FALSE);
X	obj->known = obj->dknown = TRUE;
X	makeknown(SCR_MAIL);
X	if (!invload) obj = addinv(obj);
X	if(invload || inv_cnt() > 52) {
X		if (invload) dropy(obj);
X		else dropx(obj);
X		stackobj(fobj);		
X		verbalize("Oops!");
X	} else {
X		int savequan = obj->quan;
X		obj->quan = 1;
X		prinv(obj);
X		obj->quan = savequan;
X	}
X# endif /* NO_MAILREADER */
X
X	/* disappear again */
X	mdappear(md,TRUE);
X	mongone(md);
X
X	/* force the graphics character set off */
X	nscr();
X# ifdef VMS
X	broadcasts--;
X# endif
X}
X
X#endif /* OVLB */
X
X# if !defined(UNIX) && !defined(VMS)
X
X#ifdef OVL0
X
Xvoid
Xckmailstatus() {
X	if (mustgetmail < 0)
X	    return;
X	if (--mustgetmail <= 0) {
X		newmail();
X		mustgetmail = -1;
X	}
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xreadmail()
X{
X	pline("It says:  \"Please disregard previous letter.\"");
X}
X
X#endif /* OVLB */
X
X# endif /* !UNIX && !VMS */
X
X# ifdef UNIX
X
X#ifdef OVL0
X
Xvoid
Xckmailstatus() {
X	if(!mailbox
X#  ifdef MAILCKFREQ
X		    || moves < laststattime + MAILCKFREQ
X#  endif
X							)
X		return;
X
X	laststattime = moves;
X	if(stat(mailbox, &nmstat)){
X#  ifdef PERMANENT_MAILBOX
X		pline("Cannot get status of MAIL=\"%s\" anymore.", mailbox);
X		mailbox = 0;
X#  else
X		nmstat.st_mtime = 0;
X#  endif
X	} else if(nmstat.st_mtime > omstat.st_mtime) {
X		if(nmstat.st_size)
X			newmail();
X		getmailstatus();	/* might be too late ... */
X	}
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xreadmail() {
X#  ifdef DEF_MAILREADER			/* This implies that UNIX is defined */
X	register char *mr = 0;
X	more();
X	if(!(mr = getenv("MAILREADER")))
X		mr = DEF_MAILREADER;
X	if(child(1)){
X		(void) execl(mr, mr, NULL);
X		exit(1);
X	}
X#  else
X#   ifndef AMS  			/* AMS mailboxes are directories */
X	(void) page_file(mailbox, FALSE);
X#   endif /* AMS */
X#  endif /* DEF_MAILREADER */
X
X	/* get new stat; not entirely correct: there is a small time
X	   window where we do not see new mail */
X	getmailstatus();
X}
X
X#endif /* OVLB */
X
X# endif /* UNIX */
X
X# ifdef VMS
X
X#ifdef OVL0
X
Xvoid
Xckmailstatus()
X{
X	if (broadcasts)
X		newmail();
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xreadmail()
X{
X	char buf[16384];	/* $BRKTHRU limits messages to 16350 bytes */
X	$DESCRIPTOR(message, buf);
X	short length;
X
X	if (SMG$GET_BROADCAST_MESSAGE(&pasteboard_id, &message, &length)
X	    == SS$_NORMAL && length != 0) {
X		buf[length] = '\0';
X		pline("%s", buf);
X	}
X}
X# endif /* VMS */
X
X#endif /* OVLB */
X
X#endif /* MAIL */
END_OF_FILE
if test 8762 -ne `wc -c <'src/mail.c'`; then
    echo shar: \"'src/mail.c'\" unpacked with wrong size!
fi
# end of 'src/mail.c'
fi
if test -f 'src/mcastu.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/mcastu.c'\"
else
echo shar: Extracting \"'src/mcastu.c'\" \(8350 characters\)
sed "s/^X//" >'src/mcastu.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)mcastu.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#include	"hack.h"
X
X#ifdef OVL0
X
Xstatic void FDECL(cursetxt,(struct monst *));
Xconst char *spelltyp[] = {
X	"shower of missiles",
X	"fireball",
X	"sleep ray",
X	"cone of cold",
X	"finger of death",
X	"bolt of lightning",
X	"",
X	"",
X	"",
X	""
X};
X
Xstatic
Xvoid
Xcursetxt(mtmp)
X	register struct monst *mtmp;
X{
X	if(canseemon(mtmp)) {
X	    if ((Invis && !perceives(mtmp->data) &&
X				(mtmp->mux != u.ux || mtmp->muy != u.uy))
X#ifdef POLYSELF
X			|| u.usym == S_MIMIC_DEF || u.uundetected
X#endif
X									)
X		pline("%s points and curses in your general direction.",
X				Monnam(mtmp));
X	    else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
X		pline("%s points and curses at your displaced image.",
X				Monnam(mtmp));
X	    else
X		pline("%s points at you, then curses.", Monnam(mtmp));
X	} else if((!(moves%4) || !rn2(4)) && flags.soundok) 
X		You("hear a mumbled curse.");
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xint
Xcastmu(mtmp, mattk)	/* monster casts spell at you */
X	register struct monst *mtmp;
X	register struct attack *mattk;
X{
X	int	dmg = 0, ml = mtmp->m_lev;
X
X	if(mtmp->mcan || mtmp->mspec_used || !ml) {  /* could not attack */
X	    cursetxt(mtmp);
X	    return(0);
X	} else {
X	    nomul(0);
X	    if(rn2(ml*10) < (mtmp->mconf ? 100 : 20)) {	/* fumbled attack */
X		if(canseemon(mtmp)
X#ifdef SOUNDS
X				&& flags.soundok
X#endif
X							)
X		    pline("The air crackles around %s.", mon_nam(mtmp));
X		return(0);
X	    }
X	}
X/*
X *	As these are spells, the damage is related to the level
X *	of the monster casting the spell.
X */
X	if (mattk->damd)
X		dmg = d((int)((ml/3) + mattk->damn), (int)mattk->damd);
X	else dmg = d((int)((ml/3) + 1), 6);
X
X	switch(mattk->adtyp)   {
X
X	    case AD_FIRE:
X		pline("You're enveloped in flames.");
X		if(Fire_resistance) {
X			shieldeff(u.ux, u.uy);
X			pline("But you resist the effects.");
X			dmg = 0;
X		}
X		break;
X	    case AD_COLD:
X		pline("You're covered in frost.");
X		if(Cold_resistance) {
X			shieldeff(u.ux, u.uy);
X			pline("But you resist the effects.");
X			dmg = 0;
X		}
X		break;
X#ifdef INFERNO
X	    case AD_MAGM:
X		You("are hit by a shower of missiles!");
X		if(Antimagic) {
X			shieldeff(u.ux, u.uy);
X			pline("The missiles bounce off!");
X			dmg = 0;
X		} else dmg = d((int)mtmp->m_lev/2 + 1,6);
X		break;
X#endif
X	    case AD_SPEL:	/* random spell */
X
X		mtmp->mspec_used = 10 - mtmp->m_lev;
X		if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
X		switch(rn2((int)mtmp->m_lev)) {
X		    case 22:
X		    case 21:
X		    case 20:
X			pline("Oh no, %s's using the touch of death!",
X			      is_female(mtmp) ? "she" :
X			      is_human(mtmp->data) ? "he" : "it"
X			     );
X#ifdef POLYSELF
X			if (is_undead(uasmon))
X			    You("seem no deader than before.");
X			else
X#endif
X			if(!Antimagic && rn2(ml) > 12)  {
X
X			    if(Hallucination)
X				You("have an out of body experience.");
X			    else  {
X				killer_format = KILLED_BY_AN;
X				killer = "touch of death";
X				done(DIED);
X			    }
X			} else {
X				if(Antimagic) shieldeff(u.ux, u.uy);
X				pline("Lucky for you, it didn't work!");
X			}
X			dmg = 0;
X			break;
X		    case 19:
X		    case 18:
X			if(mtmp->iswiz && flags.no_of_wizards == 1) {
X				pline("Double Trouble...");
X				clonewiz();
X				dmg = 0;
X				break;
X			} /* else fall into the next case */
X		    case 17:
X		    case 16:
X		    case 15:
X			if(mtmp->iswiz && flags.soundok)
X			    pline("\"Destroy the thief, my pets!\"");
X#ifdef HARD
X			nasty();	/* summon something nasty */
X#endif
X			/* fall into the next case */
X		    case 14:		/* aggravate all monsters */
X		    case 13:
X			aggravate();
X			dmg = 0;
X			break;
X		    case 12:		/* curse random items */
X		    case 11:
X		    case 10:
X			rndcurse();
X			dmg = 0;
X			break;
X		    case 9:
X		    case 8:		/* destroy armor */
X			if(Antimagic) {
X				shieldeff(u.ux, u.uy);
X				pline("A field of force surrounds you!");
X			} else if(!destroy_arm(some_armor()))
X				Your("skin itches.");
X			dmg = 0;
X			break;
X		    case 7:
X		    case 6:		/* drain strength */
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    You("feel momentarily weakened.");
X			} else {
X			    You("suddenly feel weaker!");
X			    losestr(rnd(ml - 6));
X			    if(u.uhp < 1)
X				done_in_by(mtmp);
X			}
X			dmg = 0;
X			break;
X		    case 5:		/* make invisible if not */
X		    case 4:
X			if(!mtmp->minvis) {
X			    if(canseemon(mtmp) && !See_invisible)
X				pline("%s suddenly disappears!",
X				      Monnam(mtmp));
X			    mtmp->minvis = 1;
X			    unpmon(mtmp);
X			    dmg = 0;
X			    break;
X			} /* else fall into the next case */
X		    case 3:		/* stun */
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    if(!Stunned)
X				You("feel momentarily disoriented.");
X			    make_stunned(1L, FALSE);
X			} else {
X			    if (Stunned)	You("struggle to keep your balance.");
X			    else		You("reel...");
X			    make_stunned(HStun + d(ACURR(A_DEX) < 12 ? 6 : 4, 4), FALSE);
X			}
X			dmg = 0;
X			break;
X		    case 2:		/* haste self */
X			if(mtmp->mspeed == MSLOW)	mtmp->mspeed = 0;
X			else				mtmp->mspeed = MFAST;
X			dmg = 0;
X			break;
X		    case 1:		/* cure self */
X			if(mtmp->mhp < mtmp->mhpmax) {
X			    if((mtmp->mhp += rnd(8)) > mtmp->mhpmax)
X				mtmp->mhp = mtmp->mhpmax;
X			    dmg = 0;
X			    break;
X			} /* else fall through to default case */
X		    default:		/* psi bolt */
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    You("get a slight %sache.",body_part(HEAD));
X			    dmg = 1;
X			} else {
X			    if (dmg <= 10)
X				Your("brain is on fire!");
X			    else Your("%s suddenly aches!", body_part(HEAD));
X			}
X			break;
X		}
X		break;
X		
X	    case AD_CLRC:	/* clerical spell */
X
X		mtmp->mspec_used = 10 - mtmp->m_lev;
X		if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
X		switch(rn2((int)mtmp->m_lev)) {
X		    /* Other ideas: lightning bolts, towers of flame,
X				    gush of water  -3. */
X
X		    default:		/* confuse */
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    You("feel momentarily dizzy.");
X			} else {
X			    make_confused(HConfusion + (long)mtmp->m_lev, TRUE);
X			}
X			dmg = 0;
X			break;
X		    case 12:		/* curse random items */
X		    case 11:
X		    case 10:
X			rndcurse();
X			dmg = 0;
X			break;
X		    case 9:
X		    case 8:		/* insects */
X			/* Try for insects, and if there are none
X			   left, go for (sticks to) snakes.  -3. */
X			{
X			int i;
X			struct permonst *pm = mkclass(S_ANT);
X			struct monst *mtmp2;
X			char let = (pm ? S_ANT : S_SNAKE);
X  
X			for (i = 0; i <= mtmp->m_lev; i++)
X			   if ((pm = mkclass(let)) &&
X					(mtmp2 = makemon(pm, u.ux, u.uy)))
X				mtmp2->msleep = mtmp2->mpeaceful =
X					mtmp2->mtame = 0;
X			}			
X			dmg = 0;
X			break;
X		    case 6:
X		    case 7:		/* blindness */
X			if (!Blinded) {
X			    pline("Scales cover your eyes!");
X			    make_blinded(200L, FALSE);
X			    dmg = 0;
X			    break;
X			}
X		    case 4:
X		    case 5:		/* wound */
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    Your("skin itches badly for a moment.");
X			    dmg = 0;
X			} else {
X			    pline("Wounds appear on your body!");
X			    dmg = d(2,8) + 1;
X			}
X			break;
X		    case 3:		/* hold */
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    if(multi >= 0)
X				You("stiffen briefly.");
X			    nomul(-1);
X		 	} else {
X			    if (multi >= 0)	
X			        You("are frozen in place!");
X			    nomul(-4 - (int)mtmp->m_lev);
X			}
X			dmg = 0;
X			break;
X		    case 2:
X		    case 1:		/* cure self */
X			if(mtmp->mhp < mtmp->mhpmax) {
X			    if((mtmp->mhp += rnd(8)) > mtmp->mhpmax)
X				mtmp->mhp = mtmp->mhpmax;
X			    dmg = 0;
X			    break;
X			} /* else fall through to default case */
X		}
X	}
X	if(dmg) mdamageu(mtmp, dmg);
X	return(1);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xint
Xbuzzmu(mtmp, mattk)		/* monster uses spell (ranged) */
X	register struct monst *mtmp;
X	register struct attack  *mattk;
X{
X	if(mtmp->mcan || mattk->adtyp > AD_SPC2) {
X	    cursetxt(mtmp);
X	    return(0);
X	}
X	if(lined_up(mtmp) && rn2(3)) {
X	    nomul(0);
X	    if(mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
X		if(canseemon(mtmp))
X		    pline("%s zaps you with a %s!", Monnam(mtmp),
X			  spelltyp[mattk->adtyp-1]);
X		buzz((int) (-10 - (mattk->adtyp-1)), (int)mattk->damn,
X		     mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
X	    } else impossible("Monster spell %d cast", mattk->adtyp-1);
X	}
X	return(1);
X}
X
X#endif /* OVL0 */
X
END_OF_FILE
if test 8350 -ne `wc -c <'src/mcastu.c'`; then
    echo shar: \"'src/mcastu.c'\" unpacked with wrong size!
fi
# end of 'src/mcastu.c'
fi
if test -f 'src/wizard.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/wizard.c'\"
else
echo shar: Extracting \"'src/wizard.c'\" \(8915 characters\)
sed "s/^X//" >'src/wizard.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)wizard.c	3.0	90/01/09
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */
X/*	       - heavily modified to give the wiz balls.  (genat!mike)   */
X/*	       - dewimped and given some maledictions. -3. */
X
X#include "hack.h"
X
X#ifdef OVLB
X
X#ifdef HARD
X/*	TODO:	Expand this list.	*/
Xstatic const int NEARDATA nasties[] = {
X	PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, PM_RED_DRAGON,
X	PM_GREEN_DRAGON, PM_OWLBEAR, PM_PURPLE_WORM, PM_ROCK_TROLL, PM_XAN,
X	PM_GREMLIN, PM_UMBER_HULK, PM_VAMPIRE_LORD, PM_XORN, PM_ZRUTY,
X#ifdef ARMY
X	PM_CAPTAIN,
X#endif
X	};
X#endif /* HARD */
X
Xstatic const unsigned NEARDATA wizapp[] = {
X	PM_HUMAN, PM_WATER_DEMON, PM_VAMPIRE,
X	PM_RED_DRAGON, PM_TROLL, PM_UMBER_HULK,
X	PM_XORN, PM_XAN, PM_COCKATRICE,
X	PM_FLOATING_EYE,
X	PM_GUARDIAN_NAGA,
X	PM_TRAPPER
X};
X
X#endif /* OVLB */
X#ifdef OVL0
X
X/* If he has found the Amulet, make the wizard appear after some time */
Xvoid
Xamulet(){
X	register struct monst *mtmp;
X
X	if(!flags.made_amulet || !flags.no_of_wizards)
X		return;
X	/* find wizard, and wake him if necessary */
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X	    if(mtmp->iswiz && mtmp->msleep && !rn2(40))
X		    if(u.uhave_amulet) {
X			mtmp->msleep = 0;
X			if(dist(mtmp->mx,mtmp->my) > 2)
X			    You(
X    "get the creepy feeling that somebody noticed your taking the Amulet."
X			    );
X			return;
X		    }
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xint
Xmon_has_amulet(mtmp)
Xregister struct monst *mtmp;
X{
X	register struct obj *otmp;
X
X	for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj){
X		if(otmp->otyp == AMULET_OF_YENDOR && otmp->spe >= 0) return(1);
X	}
X	return(0);
X}
X
X/* the wiz's prime directive */
Xint
Xwiz_get_amulet(mtmp)
Xregister struct monst *mtmp;
X{
X	/* if he doesn't have the amulet */
X	if(!mon_has_amulet(mtmp))
X	    if(u.uhave_amulet) {
X
X		/* player has it, dog them til he gets it or dies */
X		mnexto(mtmp);
X	    } else {
X		register struct obj *otmp;
X
X		/* if it is lying around someplace, he teleports to it */
X		for(otmp = fobj; otmp; otmp = otmp->nobj)
X		    if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) {
X			if(u.ux == otmp->ox && u.uy == otmp->oy) {
X			    /* player is standing on it */
X			    mnexto(mtmp);
X			    return(0);
X			}
X			if(!MON_AT(otmp->ox, otmp->oy) ||
X			    (mtmp->mx == otmp->ox && mtmp->my == otmp->oy)) {
X
X			    /* teleport to it and pick it up */
X			    remove_monster(mtmp->mx, mtmp->my);
X			    place_monster(mtmp, otmp->ox, otmp->oy);
X			    if (cansee(mtmp->mx, mtmp->my))
X				pline("%s picks up %s.", Monnam(mtmp),
X								xname(otmp));
X			    freeobj(otmp);
X			    mpickobj(mtmp, otmp);
X			    pmon(mtmp);
X			    return(1);
X			}
X			break;
X		    }
X		/* we don't know where it is */
X	    }
X
X	/* he has it or can't find it */
X	/* secondary goal - stayin' alive */
X
X	/* if wounded, hole up on or near the stairs (to block them) */
X	/* unless, of course, there are no stairs (e.g. endlevel */
X	if(mtmp->mhp < 20 + rnd(10) && (xupstair || yupstair))
X	    if (mtmp->mx != xupstair && mtmp->my != yupstair)
X		mnearto(mtmp,xupstair,yupstair,TRUE);
X
X	/* if you're not around, cast healing spells */
X	if(dist(mtmp->mx,mtmp->my) > (BOLT_LIM * BOLT_LIM))
X	    if(mtmp->mhp <= mtmp->mhpmax - 8) {
X		mtmp->mhp += rnd(8);
X		return(1);
X	    }
X	    /* healthy wiz with nothing to do */
X	    else if(!rn2(5))
X		mnexto(mtmp);
X
X	/* the effect is that below 30 hp, wily wiz teleports
X	   again and again, unless/until he blocks the stairs.
X
X	   if you keep away from the wounded wiz, he sits
X	   there healing himself, until he gets healthy
X	   and decides to punish you some more.  -3. */
X
X	return(0);
X}
X
Xvoid
Xaggravate()
X{
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X		mtmp->msleep = 0;
X		if(!mtmp->mcanmove && !rn2(5)) {
X			mtmp->mfrozen = 0;
X			mtmp->mcanmove = 1;
X		}
X	}
X}
X
Xvoid
Xclonewiz()
X{
X	register struct monst *mtmp2;
X
X	if(mtmp2 = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy)) {
X		mtmp2->msleep = mtmp2->mtame = mtmp2->mpeaceful = 0;
X		if (!u.uhave_amulet && rn2(2)) {  /* give clone a fake */
X			mtmp2->minvent = mksobj(AMULET_OF_YENDOR,FALSE);
X			mtmp2->minvent->spe = -1;
X		}
X		unpmon(mtmp2);
X		mtmp2->m_ap_type = M_AP_MONSTER;
X		mtmp2->mappearance = wizapp[rn2(SIZE(wizapp))];
X		pmon(mtmp2);
X	}
X}
X
X#ifdef HARD
Xvoid
Xnasty() {
X	register struct monst	*mtmp;
X	register int	i, tmp;
X
X	if(!rn2(10) && Inhell) dsummon(&mons[PM_WIZARD_OF_YENDOR]);
X	else {
X	    tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */
X
X	    for(i = rnd(tmp); i > 0; --i)
X		if((mtmp = makemon(&mons[nasties[rn2(SIZE(nasties))]], u.ux, u.uy))) {
X
X		    mtmp->msleep = mtmp->mpeaceful = mtmp->mtame = 0;
X		} else
X		  (void)makemon((struct permonst *)0, u.ux, u.uy); /* GENOD? */
X	}
X	return;
X}
X
X/*	Let's resurrect the wizard, for some unexpected fun.	*/
Xvoid
Xresurrect()
X{
X	register struct monst	*mtmp;
X
X	if(mtmp = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy)) {
X		mtmp->msleep = mtmp->mtame = mtmp->mpeaceful = 0;
X		pline("A voice booms out...");
X		pline("\"So thou thought thou couldst kill me, fool.\"");
X	}
X
X}
X
X/*	Here, we make trouble for the poor shmuck who actually	*/
X/*	managed to do in the Wizard.				*/
Xvoid
Xintervene() {
X
X	switch(rn2(6)) {
X
X	    case 0:
X	    case 1:	You("feel vaguely nervous.");
X			break;
X	    case 2:	if (!Blind)
X			    You("notice a %s glow surrounding you.",
X				  Hallucination ? hcolor() : black);
X			rndcurse();
X			break;
X	    case 3:	aggravate();
X			break;
X	    case 4:	nasty();
X			break;
X	    case 5:	if (!flags.no_of_wizards) resurrect();
X			break;
X	}
X}
X
Xvoid
Xwizdead(mtmp)
Xregister struct monst	*mtmp;
X{
X	flags.no_of_wizards--;
X	if(! u.udemigod)  {
X
X		u.udemigod = TRUE;
X		u.udg_cnt = rn1(250, 50);
X
X	/*  Make the wizard meaner the next time he appears  */
X		mtmp->data->mlevel++;
X		mtmp->data->ac--;
X	} else  
X		mtmp->data->mlevel++;
X}
X#endif /* HARD /**/
X
Xconst char *random_insult[] = {
X	"antic",
X	"blackguard",
X	"caitiff",
X	"chucklehead",
X	"coistrel",
X	"craven",
X	"cretin",
X	"cur",
X	"dastard",
X	"demon fodder",
X	"dimwit",
X	"dolt",
X	"fool",
X	"footpad",
X	"imbecile",
X	"knave",
X	"maledict",
X	"miscreant",
X	"niddering",
X	"poltroon",
X	"rattlepate",
X	"reprobate",
X	"scapegrace",
X	"varlet",
X	"villein",	/* (sic.) */
X	"wittol",
X	"worm",
X	"wretch",
X};
X
Xconst char *random_malediction[] = {
X	"Hell shall soon claim thy remains,",
X	"I chortle at thee, thou pathetic",
X	"Prepare to die, thou ",
X	"Resistance is useless,",
X	"Surrender or die, thou",
X	"There shall be no mercy, thou",
X	"Thou shalt repent of thy cunning,",
X	"Thou art as a flea to me,",
X	"Thou art doomed,",
X	"Thy fate is sealed,",
X	"Verily, thou shalt be one dead"
X};
X
X#ifdef SOUNDS
Xconst char *demonic_malediction[] = {
X	"I first mistook thee for a statue, when I regarded thy head of stone.",
X	"Come here often?",
X	"Dost pain excite thee?  Wouldst thou prefer the whip?",
X	"Thinkest thou it shall tickle as I rip out thy lungs?",
X	"Eat slime and die!",
X	"Go ahead, fetch thy mama!  I shall wait.",
X	"Go play leapfrog with a herd of unicorns!",
X	"Hast thou been drinking, or art thou always so clumsy?",
X	"This time I shall let thee off with a spanking, but let it not happen again.",
X	"I've met smarter (and prettier) acid blobs.",
X	"Look!  Thy bootlace is undone!",
X	"Mercy!  Dost thou wish me to die of laughter?",
X	"Run away!  Live to flee another day!",	
X	"Thou hadst best fight better than thou canst dress!",
X	"Twixt thy cousin and thee, Medusa is the prettier.",
X	"Methinks thou wert unnaturally interested in yon corpse back there, eh, varlet?",
X	"Up thy nose with a rubber hose!",
X	"Verily, thy corpse could not smell worse!",
X	"Wait!  I shall polymorph into a grid bug to give thee a fighting chance!",
X	"Why search for the Amulet?  Thou wouldst but lose it, cretin.",
X};
X#endif
X
X/* Insult or intimidate the player */
Xvoid
Xcuss(mtmp)
Xregister struct monst	*mtmp;
X{
X#ifdef SOUNDS
X	if (mtmp->iswiz) {
X#endif
X	    if (!rn2(5))  /* typical bad guy action */
X		pline("%s laughs fiendishly.", Monnam(mtmp));
X	    else 
X		if (u.uhave_amulet && !rn2(SIZE(random_insult)))
X		    pline("\"Relinquish the amulet, %s!\"",
X			  random_insult[rn2(SIZE(random_insult))]);
X		else if (u.uhp < 5 && !rn2(2))	/* Panic */
X		    pline(rn2(2) ?
X			  "\"Even now thy life force ebbs, %s!\"" :
X			  "\"Savor thy breath, %s, it be thine last!\"",
X			  random_insult[rn2(SIZE(random_insult))]);
X		else if (mtmp->mhp < 5 && !rn2(2))	/* Parthian shot */
X		    verbalize(rn2(2) ?
X			      "I shall return." :
X			      "I'll be back.");
X		else
X		    pline("\"%s %s!\"",
X			  random_malediction[rn2(SIZE(random_malediction))],
X			  random_insult[rn2(SIZE(random_insult))]);
X#ifdef SOUNDS
X	} else {
X	    if (!rn2(5))
X		kludge("%s casts aspersions on your ancestry.", Monnam(mtmp));
X	    else
X		verbalize(demonic_malediction[rn2(SIZE(demonic_malediction))]);
X	}
X#endif
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 8915 -ne `wc -c <'src/wizard.c'`; then
    echo shar: \"'src/wizard.c'\" unpacked with wrong size!
fi
# end of 'src/wizard.c'
fi
echo shar: End of archive 48 \(of 56\).
cp /dev/null ark48isdone
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