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