home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume7
/
nethack3
/
part29
< prev
next >
Wrap
Internet Message Format
|
1989-07-31
|
56KB
Path: uunet!zephyr.ens.tek.com!tektronix!tekgen!tekred!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v07i084: NetHack3 - display oriented dungeons & dragons (Ver. 3.0), Part29/38
Message-ID: <4341@tekred.CNA.TEK.COM>
Date: 24 Jul 89 19:06:58 GMT
Sender: nobody@tekred.CNA.TEK.COM
Lines: 2060
Approved: billr@saab.CNA.TEK.COM
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 7, Issue 84
Archive-name: NetHack3/Part29
#! /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 29 (of 38)."
# Contents: amiga/Makefile.ami src/dog.c src/mkroom.c src/mthrowu.c
# src/spell.c
# Wrapped by billr@saab on Sun Jul 23 21:33:12 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'amiga/Makefile.ami' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'amiga/Makefile.ami'\"
else
echo shar: Extracting \"'amiga/Makefile.ami'\" \(10847 characters\)
sed "s/^X//" >'amiga/Makefile.ami' <<'END_OF_FILE'
X# Hack Makefile.
X# SCCS Id: @(#)Makefile.ami 3.0 89/04/23
X
X# This makefile is specifically for the Amiga.
X
XCFLAGS = +cd -e200
XCPPFLAGS = -I -Iamiga: -Iinclude:
XCC = cc
X
X# Use my special modified Cpp (-w flag writes all #defines)
X# since the one built in Manx CC is too stupid for now.
X
X.c.o:
X Cpp $(CPPFLAGS) $< ram:_$*.c
X cc $(CFLAGS) -o $*.o ram:_$*.c
X delete ram:_$*.c
X
X# Search path for default rules: (for my special modified Make)
X
X.PATH: src1: src2:
X
X.PRECIOUS: include:config.h include:decl.h include:_hack.h \
X include:permonst.h include:you.h
X
X
X# object files for makedefs
XMAKEOBJS = makedefs.o monst.o objects.o
X
X# object files for level compiler
XSPLEVOBJS = lev_comp.o lev_lex.o lev_main.o monst.o objects.o
X
X# make NetHack
XGAME = nethack
X
X# if you defined RANDOM in unixconf.h/pcconf.h since your system did not come
X# with a reasonable random number generator
XRANDOBJ = random.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, amiconf.h}, and possibly system.h
X
X# HACKCSRC = alloc.c apply.c artifact.c attrib.c bones.c cmd.c dbridge.c \
X# decl.c demon.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c \
X# dothrow.c eat.c end.c engrave.c exper.c extralev.c fountain.c \
X# getline.c hack.c invent.c lock.c mail.c makemon.c mcastu.c mhitm.c \
X# mhitu.c mklev.c mkmaze.c mkobj.c mkroom.c mon.c mondata.c \
X# monmove.c monst.c mthrowu.c music.c o_init.c objects.c objnam.c \
X# options.c pager.c pickup.c polyself.c potion.c pray.c pri.c \
X# priest.c prisym.c read.c restore.c rip.c rnd.c rumors.c save.c \
X# search.c shk.c shknam.c sit.c sounds.c sp_lev.c spell.c steal.c \
X# termcap.c timeout.c topl.c topten.c track.c trap.c u_init.c \
X# uhitm.c vault.c version.c weapon.c were.c wield.c wizard.c worm.c \
X# worn.c write.c zap.c
X
X# all .c files but msdos.c, tos.c, *main.c, *tty.c, *unix.c, (system specific)
X# and makedefs.c, lev_comp.c, panic.c (not part of any nethack)
X
X# CSOURCES = $(HACKCSRC) pcmain.c makedefs.c panic.c
X
X# HACKINCL = artifact.h attrib.h config.h coord.h decl.h edog.h epri.h eshk.h \
X# extern.h flag.h func_tab.h global.h gold.h hack.h lev.h mfndpos.h \
X# mkroom.h monattk.h mondata.h monflag.h monst.h monsym.h msdos.h \
X# obj.h objclass.h permonst.h prop.h rm.h sp_lev.h spell.h \
X# tradstdc.h trapname.h vault.h wseg.h you.h youprop.h
X
X# all .h files except date.h, onames.h, pm.h & trap.h which would cause
X# dependency loops if run through "make depend".
X
X# HSOURCES = $(HACKINCL) date.h onames.h pm.h trap.h
X
X# SOURCES = $(CSOURCES) $(HSOURCES)
X
XAOBJ = amidos.o amitcap.o amitty.o amiunix.o amiwind.o
XHOBJ1 = alloc.o apply.o artifact.o attrib.o bones.o cmd.o 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
XHOBJ2 = mail.o main.o makemon.o mcastu.o mhitm.o mhitu.o mklev.o mkmaze.o \
X mkobj.o mkroom.o mon.o mondata.o monmove.o monst.o mthrowu.o music.o \
X o_init.o objects.o objnam.o options.o pager.o pickup.o polyself.o \
X potion.o pray.o pri.o priest.o prisym.o read.o restore.o rip.o rnd.o \
X rumors.o save.o
XHOBJ3 = search.o shk.o shknam.o sit.o sounds.o sp_lev.o spell.o steal.o \
X timeout.o topl.o topten.o track.o trap.o u_init.o \
X uhitm.o vault.o version.o weapon.o were.o wield.o wizard.o \
X worm.o worn.o write.o zap.o $(RANDOBJ)
X
XHOBJ = $(AOBJ) $(HOBJ1) $(HOBJ2) $(HOBJ3)
X
X# the .o files from the HACKCSRC list, plus main.o tty.o unix.o
X
X$(GAME): $(HOBJ)
X ln -f ami.lnk
X
Xlink:
X ln -f ami.lnk
X
Xobj1: $(HOBJ1)
Xobj2: $(HOBJ2)
Xobj3: $(HOBJ3)
X
X#
X# Please note: The dependency lines for the modules here are
X# deliberately incorrect. Including "hack.h" in
X# the dependency list would cause a dependency
X# loop.
X#
Xmakedefs: $(MAKEOBJS)
X ln -o makedefs $(MAKEOBJS) -lcl
X
Xmakedefs.o: include:config.h include:permonst.h include:objclass.h
X
Xlev_comp: $(SPLEVOBJS)
X ln -o lev_comp $(SPLEVOBJS) -lcl
X
Xlev_comp.o: include:hack.h include:sp_lev.h
X Cpp $(CPPFLAGS) src1:lev_comp.c ram:_lev_comp.c
X cc +cd -e300 -o lev_comp.o ram:_lev_comp.c
X delete ram:_lev_comp.c
Xlev_lex.o: include:lev_comp.h include:hack.h include:sp_lev.h
X Cpp $(CPPFLAGS) src1:lev_lex.c ram:_lev_lex.c
X cc +cd -e300 -o lev_lex.o ram:_lev_lex.c
X delete ram:_lev_lex.c
Xlev_main.o: include:hack.h include:sp_lev.h
X Cpp $(CPPFLAGS) src1:lev_main.c ram:_lev_main.c
X cc +cd -e300 -o lev_main.o ram:_lev_main.c
X delete ram:_lev_main.c
X
X#
X# The following include files depend on makedefs to be created.
X# As a result, they are not defined in HACKINCL, instead, their
X# dependencies are explicitly outlined here.
X#
X
X#
X# date.h should be remade any time any of the source or include code
X# is modified. Unfortunately, this would make the contents of this
X# file far more complex. Since "hack.h" depends on most of the include
X# files, we kludge around this by making date.h dependent on hack.h,
X# even though it doesn't include this file.
X#
Xinclude:date.h: include:hack.h makedefs $(AOBJ)
X -makedefs -v
X
Xinclude:trap.h: include:config.h makedefs
X -makedefs -t
X copy makedefs.1 include:trap.h
X
Xinclude:onames.h: makedefs
X -makedefs -o
X
Xinclude:pm.h: makedefs
X -makedefs -p
X
X#
X# The following programs vary depending on what OS you are using.
X# As a result, they are not defined in HACKSRC, and their dependancies
X# are explicitly outlined here.
X#
X
Xamidos.o: include:hack.h amiga:amidos.c
X $(CC) $(CFLAGS) amiga:amidos.c -o amidos.o
X
Xamitcap.o: include:hack.h amiga:amitcap.c
X $(CC) $(CFLAGS) amiga:amitcap.c -o amitcap.o
X
Xamitty.o: include:hack.h amiga:amitty.c
X $(CC) $(CFLAGS) amiga:amitty.c -o amitty.o
X
Xamiunix.o: include:hack.h amiga:amiunix.c
X $(CC) $(CFLAGS) amiga:amiunix.c -o amiunix.o
X
Xamiwind.o: include:hack.h amiga:amiwind.c amiga:amimenu.c
X $(CC) $(CFLAGS) +IData:syms/amiga.syms amiga:amiwind.c -o amiwind.o
X
Xmain.o: include:hack.h src2:pcmain.c
X Cpp $(CPPFLAGS) src2:pcmain.c ram:_main.c
X cc $(CFLAGS) -o main.o ram:_main.c
X delete ram:_main.c
X
X# Pre-include hack.h to save disk I/O. Rename the original hack.h
X# to _hack.h though. The -w option makes Cpp write out all
X# necessary #defines at the end of the output.
X
Xinclude:hack.h: include:_hack.h makedefs
X -Cpp -Iinclude: -Iamiga: -w include:_hack.h hack.h
X -copy hack.h include:hack.h
X
Xclean:
X delete *.o ram:_*.c ram:ctmp*
X
Xspotless: clean
X delete $(GAME) lev_comp makedefs
X delete include:onames.h include:pm.h
X setdate include:onames.h include:pm.h
X setdate makedefs.c
X#(make sure files exist and have timestamps in the right order for next compile)
X
X
X# DO NOT DELETE THIS LINE
X
Xalloc.o: include:config.h
Xapply.o: include:hack.h include:edog.h
Xartifact.o: include:hack.h include:artifact.h
Xattrib.o: include:hack.h
Xbones.o: include:hack.h
Xcmd.o: include:hack.h include:func_tab.h
Xdbridge.o: include:hack.h
Xdecl.o: include:hack.h
Xdemon.o: include:hack.h
Xdo.o: include:hack.h
Xdo_name.o: include:hack.h
Xdo_wear.o: include:hack.h
Xdog.o: include:hack.h include:edog.h
Xdogmove.o: include:hack.h include:mfndpos.h include:edog.h
Xdokick.o: include:hack.h
Xdothrow.o: include:hack.h
Xeat.o: include:hack.h
Xend.o: include:hack.h include:eshk.h
Xengrave.o: include:hack.h
Xexper.o: include:hack.h
Xextralev.o: include:hack.h
Xfountain.o: include:hack.h
Xgetline.o: include:hack.h include:func_tab.h
Xhack.o: include:hack.h
Xinvent.o: include:hack.h include:lev.h include:wseg.h
Xlock.o: include:hack.h
Xmail.o: include:hack.h
Xmakemon.o: include:hack.h
Xmcastu.o: include:hack.h
Xmhitm.o: include:hack.h include:artifact.h
Xmhitu.o: include:hack.h include:artifact.h include:edog.h
Xmklev.o: include:hack.h
Xmkmaze.o: include:hack.h
Xmkobj.o: include:hack.h
Xmkroom.o: include:hack.h
Xmon.o: include:hack.h include:mfndpos.h include:artifact.h
Xmondata.o: include:hack.h include:eshk.h include:epri.h
Xmonmove.o: include:hack.h include:mfndpos.h include:artifact.h
Xmonst.o: include:config.h include:permonst.h include:monsym.h include:eshk.h include:vault.h include:epri.h
X Cpp $(CPPFLAGS) src2:monst.c ram:_monst.c
X cc $(CFLAGS) -z4000 -o monst.o ram:_monst.c
X delete ram:_monst.c
Xmthrowu.o: include:hack.h
Xmusic.o: include:hack.h
Xo_init.o: include:hack.h
Xobjects.o: include:config.h include:obj.h include:objclass.h include:prop.h
X Cpp $(CPPFLAGS) src2:objects.c ram:_objects.c
X cc $(CFLAGS) -z8000 +q -o objects.o ram:_objects.c
X delete ram:_objects.c
Xobjnam.o: include:hack.h
Xoptions.o: include:hack.h
Xpager.o: include:hack.h
Xpickup.o: include:hack.h
Xpolyself.o: include:hack.h
Xpotion.o: include:hack.h
Xpray.o: include:hack.h
Xpri.o: include:hack.h
Xpriest.o: include:hack.h include:mfndpos.h include:eshk.h include:epri.h
Xprisym.o: include:hack.h include:wseg.h include:lev.h
Xread.o: include:hack.h
Xrestore.o: include:hack.h include:lev.h include:wseg.h
Xrip.o: include:hack.h
X Cpp $(CPPFLAGS) src2:rip.c ram:_rip.c
X cc $(CFLAGS) +q -o rip.o ram:_rip.c
X delete ram:_rip.c
Xrnd.o: include:hack.h
Xrumors.o: include:hack.h
Xsave.o: include:hack.h include:lev.h include:wseg.h
Xsearch.o: include:hack.h include:artifact.h
Xshk.o: include:hack.h include:eshk.h
Xshknam.o: include:hack.h include:eshk.h
Xsit.o: include:hack.h
Xsounds.o: include:hack.h include:edog.h include:eshk.h
Xsp_lev.o: include:hack.h include:sp_lev.h
Xspell.o: include:hack.h
Xsteal.o: include:hack.h
Xtimeout.o: include:hack.h
Xtopl.o: include:hack.h
Xtopten.o: include:hack.h
Xtrack.o: include:hack.h
Xtrap.o: include:hack.h include:edog.h include:trapname.h
Xu_init.o: include:hack.h
Xuhitm.o: include:hack.h include:artifact.h
Xvault.o: include:hack.h include:vault.h
Xversion.o: include:hack.h include:date.h
Xweapon.o: include:hack.h
Xwere.o: include:hack.h
Xwield.o: include:hack.h
Xwizard.o: include:hack.h
Xworm.o: include:hack.h include:wseg.h
Xworn.o: include:hack.h
Xwrite.o: include:hack.h
Xzap.o: include:hack.h
Xinclude:config.h: include:tradstdc.h include:global.h
X -setdate include:config.h
Xinclude:decl.h: include:spell.h include:obj.h include:you.h include:onames.h include:pm.h
X -setdate include:decl.h
Xinclude:global.h: include:coord.h include:unixconf.h include:pcconf.h include:tosconf.h include:amiconf.h
X -setdate include:global.h
Xinclude:_hack.h: include:config.h include:decl.h include:monsym.h include:mkroom.h include:objclass.h include:gold.h include:trap.h include:flag.h include:rm.h
X -setdate include:_hack.h
Xinclude:permonst.h: include:monattk.h include:monflag.h
X -setdate include:permonst.h
Xinclude:you.h: include:attrib.h include:monst.h include:youprop.h
X -setdate include:you.h
Xinclude:youprop.h: include:prop.h include:permonst.h include:mondata.h include:pm.h
X -setdate include:youprop.h
X# DEPENDENCIES MUST END AT END OF FILE
X# IF YOU PUT STUFF HERE IT WILL GO AWAY
X# see make depend above
END_OF_FILE
if test 10847 -ne `wc -c <'amiga/Makefile.ami'`; then
echo shar: \"'amiga/Makefile.ami'\" unpacked with wrong size!
fi
# end of 'amiga/Makefile.ami'
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'\" \(7862 characters\)
sed "s/^X//" >'src/dog.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)dog.c 3.0 89/06/12
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
Xchar dogname[63] = DUMMY;
Xchar catname[63] = DUMMY;
X
X#define domestic(mtmp) (mtmp->data->msound == MS_BARK || mtmp->data->msound == MS_MEW)
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 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 register struct monst *mtmp2;
X
X mtmp->mnamelth = strlen(petname) + 1;
X mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
X *mtmp2 = *mtmp;
X
X replmon(mtmp, mtmp2);
X mtmp = mtmp2;
X Strcpy(NAME(mtmp), petname);
X petname[0] = '\0'; /* name first only; actually unnecessary */
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 trapdoor or stepped on a tele-trap. */
X/* 'down' is now true only of trapdooor 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#ifdef LINT
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->isshk)
X home_shk(mtmp);
X else
X rloc(mtmp);
X } else
X mtmp0 = mtmp;
X }
X}
X
Xvoid
Xkeepdogs(){
Xregister struct monst *mtmp;
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(((dist(mtmp->mx,mtmp->my) < 3 && 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->mfroz) {
X#ifdef WORM
X /* Bug "fix" for worm changing levels collapsing dungeon
X */
X if (mtmp->data == &mons[PM_LONG_WORM]) {
X if (canseemon(mtmp) || (Blind && Telepat))
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; /* to avoid mnexto()/mmask 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
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 mmask */
X}
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 carn = carnivorous(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 (!carn && !herbivorous(mon->data))
X return (obj->cursed ? UNDEF : APPORT);
X
X switch (obj->otyp) {
X case TRIPE_RATION:
X return (carn ? DOGFOOD : MANFOOD);
X case CORPSE:
X case EGG:
X if ((obj->age + 50 <= moves && mon->data->mlet != S_FUNGUS) ||
X (poisonous(&mons[obj->corpsenm]) && !resists_poison(mon->data)) ||
X (obj->corpsenm == PM_COCKATRICE && !resists_ston(mon->data)))
X return POISON;
X else return (carn ? CADAVER : MANFOOD);
X case DEAD_LIZARD:
X return (carn ? ACCFOOD : MANFOOD);
X default:
X return (obj->otyp < CARROT ? 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/* 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
Xint
Xtamedog(mtmp, obj)
Xregister struct monst *mtmp;
Xregister struct obj *obj;
X{
X register struct monst *mtmp2;
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(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->mfroz ||
X#ifdef WORM
X mtmp->wormno ||
X#endif
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(0);
X /* no tame long worms so they don't try to follow you down stairs
X or get in your way */
X if(obj) {
X if(dogfood(mtmp, obj) >= MANFOOD) return(0);
X if(cansee(mtmp->mx,mtmp->my)){
X pline("%s devours the %s.", Monnam(mtmp),
X objects[obj->otyp].oc_name);
X }
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(1);
X}
END_OF_FILE
if test 7862 -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/mkroom.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/mkroom.c'\"
else
echo shar: Extracting \"'src/mkroom.c'\" \(10546 characters\)
sed "s/^X//" >'src/mkroom.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)mkroom.c 3.0 88/11/24
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X/*
X * Entry points:
X * mkroom() -- make and stock a room of a given type
X * nexttodoor() -- return TRUE if adjacent to a door
X * has_dnstairs() -- return TRUE if given room has a down staircase
X * has_upstairs() -- return TRUE if given room has an up staircase
X * dist2() -- Euclidean square-of-distance function
X * courtmon() -- generate a court monster
X */
X#include "hack.h"
X
Xstatic void mkshop(), mkzoo(), mkswamp();
X#ifdef ORACLE
Xstatic void mkdelphi();
X#endif
X#if defined(ALTARS) && defined(THEOLOGY)
Xstatic void mktemple();
X#endif
X
Xstatic struct permonst *morguemon();
X#ifdef ARMY
Xstatic struct permonst *squadmon();
X#endif
X
X#define sq(x) ((x)*(x))
X
Xstatic boolean
Xisbig(sroom)
Xregister struct mkroom *sroom;
X{
X register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
X return( area > 20 );
X}
X
Xvoid
Xmkroom(roomtype)
X/* make and stock a room of a given type */
Xint roomtype;
X{
X
X if (roomtype >= SHOPBASE)
X mkshop(); /* someday, we should be able to specify shop type */
X else switch(roomtype) {
X#ifdef THRONES
X case COURT: mkzoo(COURT); break;
X#endif
X case ZOO: mkzoo(ZOO); break;
X case BEEHIVE: mkzoo(BEEHIVE); break;
X case MORGUE: mkzoo(MORGUE); break;
X case BARRACKS: mkzoo(BARRACKS); break;
X case SWAMP: mkswamp(); break;
X#ifdef ORACLE
X case DELPHI: mkdelphi(); break;
X#endif
X#if defined(ALTARS) && defined(THEOLOGY)
X case TEMPLE: mktemple(); break;
X#endif
X default: impossible("Tried to make a room of type %d.", roomtype);
X }
X}
X
Xstatic void
Xmkshop()
X{
X register struct mkroom *sroom;
X int i = -1;
X#ifdef WIZARD
X register char *ep;
X
X /* first determine shoptype */
X if(wizard){
X ep = getenv("SHOPTYPE");
X if(ep){
X if(*ep == 'z' || *ep == 'Z'){
X mkzoo(ZOO);
X return;
X }
X if(*ep == 'm' || *ep == 'M'){
X mkzoo(MORGUE);
X return;
X }
X if(*ep == 'b' || *ep == 'B'){
X mkzoo(BEEHIVE);
X return;
X }
X#ifdef THRONES
X if(*ep == 't' || *ep == 'T'){
X mkzoo(COURT);
X return;
X }
X#endif
X#ifdef ARMY
X if(*ep == 's' || *ep == 'S'){
X mkzoo(BARRACKS);
X return;
X }
X#endif /* ARMY */
X#if defined(ALTARS) && defined(THEOLOGY)
X if(*ep == '_'){
X mktemple();
X return;
X }
X#endif
X if(*ep == '}'){
X mkswamp();
X return;
X }
X for(i=0; shtypes[i].name; i++)
X if(*ep == shtypes[i].symb) goto gottype;
X i = -1;
X }
X }
Xgottype:
X#endif
X for(sroom = &rooms[0]; ; sroom++){
X if(sroom->hx < 0) return;
X if(sroom - rooms >= nroom) {
X pline("rooms not closed by -1?");
X return;
X }
X if(sroom->rtype != OROOM) continue;
X if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
X continue;
X if(
X#ifdef WIZARD
X (wizard && ep && sroom->doorct != 0) ||
X#endif
X sroom->doorct == 1) break;
X }
X
X if(i < 0) { /* shoptype not yet determined */
X register int j;
X
X /* pick a shop type at random */
X for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++)
X if (j < 0) break;
X
X /* big rooms cannot be wand or book shops,
X * - so make them general stores
X */
X if(isbig(sroom) && (shtypes[i].symb == WAND_SYM
X#ifdef SPELLS
X || shtypes[i].symb == SPBOOK_SYM
X#endif
X )) i = 0;
X }
X sroom->rtype = SHOPBASE + i;
X
X /* stock the room with a shopkeeper and artifacts */
X stock_room(&(shtypes[i]), sroom);
X}
X
Xstatic struct mkroom *
Xpick_room()
X/* pick an unused room, preferably with only one door */
X{
X register struct mkroom *sroom;
X register int i = nroom;
X
X for(sroom = &rooms[rn2(nroom)]; i--; sroom++) {
X if(sroom == &rooms[nroom])
X sroom = &rooms[0];
X if(sroom->hx < 0)
X return (struct mkroom *)0;
X if(sroom->rtype != OROOM) continue;
X if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
X continue;
X if(sroom->doorct == 1 || !rn2(5))
X return sroom;
X }
X return (struct mkroom *)0;
X}
X
Xstatic void
Xmkzoo(type)
Xint type;
X{
X register struct mkroom *sroom;
X struct monst *mon;
X register int sx,sy,i;
X int sh, tx, ty, goldlim = 500 * dlevel;
X
X if(!(sroom = pick_room())) return;
X
X sroom->rtype = type;
X sh = sroom->fdoor;
X switch(type) {
X case COURT:
X tx = somex(sroom); ty = somey(sroom); break;
X /* TODO: try to ensure the enthroned monster is an M2_PRINCE */
X case BEEHIVE:
X tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
X ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
X break;
X }
X for(sx = sroom->lx; sx <= sroom->hx; sx++)
X for(sy = sroom->ly; sy <= sroom->hy; sy++){
X if((sx == sroom->lx && doors[sh].x == sx-1) ||
X (sx == sroom->hx && doors[sh].x == sx+1) ||
X (sy == sroom->ly && doors[sh].y == sy-1) ||
X (sy == sroom->hy && doors[sh].y == sy+1)) continue;
X mon = makemon(
X#ifdef THRONES
X (type == COURT) ? courtmon() :
X#endif
X#ifdef ARMY
X (type == BARRACKS) ? squadmon() :
X#endif
X (type == MORGUE) ? morguemon() :
X (type == BEEHIVE) ?
X (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] :
X &mons[PM_KILLER_BEE]) :
X (struct permonst *) 0,
X sx, sy);
X if(mon) {
X mon->msleep = 1;
X#ifdef THRONES
X if (type==COURT && mon->mpeaceful) {
X mon->mpeaceful = 0;
X mon->malign = max(3,abs(mon->data->maligntyp));
X }
X#endif
X }
X switch(type) {
X case ZOO:
X i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
X if(i >= goldlim) i = 5*dlevel;
X goldlim -= i;
X mkgold((long)(10 + rn2(i)), sx, sy);
X break;
X case MORGUE:
X if(!rn2(5))
X (void) mk_tt_corpse(sx, sy);
X if(!rn2(10)) /* lots of treasure buried with dead */
X (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
X break;
X case BEEHIVE:
X if(!rn2(3))
X (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
X break;
X case BARRACKS:
X if(!rn2(20)) /* the payroll and some loot */
X (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
X break;
X }
X }
X#ifdef THRONES
X if(type == COURT) {
X levl[tx][ty].typ = THRONE;
X levl[tx][ty].scrsym = THRONE_SYM;
X
X tx = somex(sroom);
X ty = somey(sroom);
X mkgold((long) rn1(50 * dlevel,10), sx, sy);
X (void) mksobj_at(CHEST, sx, sy); /* the royal coffers */
X }
X#endif
X
X}
X
Xstatic struct permonst *
Xmorguemon()
X{
X register int i = rn2(100), hd = rn2(dlevel);
X
X if(hd > 10 && i < 10)
X return((Inhell) ? mkclass(S_DEMON) : &mons[ndemon()]);
X if(hd > 8 && i > 85)
X return(mkclass(S_VAMPIRE));
X
X return((i < 20) ? &mons[PM_GHOST]
X : (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE));
X}
X
Xstatic void
Xmkswamp() /* Michiel Huisjes & Fred de Wilde */
X{
X register struct mkroom *sroom;
X register int sx,sy,i,eelct = 0;
X
X for(i=0; i<5; i++) { /* 5 tries */
X sroom = &rooms[rn2(nroom)];
X if(sroom->hx < 0 || sroom->rtype != OROOM ||
X has_upstairs(sroom) || has_dnstairs(sroom))
X continue;
X
X /* satisfied; make a swamp */
X sroom->rtype = SWAMP;
X for(sx = sroom->lx; sx <= sroom->hx; sx++)
X for(sy = sroom->ly; sy <= sroom->hy; sy++)
X if(levl[sx][sy].omask == 0 && levl[sx][sy].gmask == 0 &&
X levl[sx][sy].mmask == 0 &&
X !t_at(sx,sy) && !nexttodoor(sx,sy)) {
X if((sx+sy)%2) {
X levl[sx][sy].typ = POOL;
X levl[sx][sy].scrsym = POOL_SYM;
X if(!eelct || !rn2(4)) {
X (void) makemon(mkclass(S_EEL), sx, sy);
X eelct++;
X }
X } else if(!rn2(4)) /* swamps tend to be moldy */
X (void) makemon(mkclass(S_FUNGUS), sx, sy);
X }
X }
X}
X
X#ifdef ORACLE
Xstatic void
Xmkdelphi()
X{
X register struct mkroom *sroom;
X register struct monst *oracl;
X int dy,xx,yy;
X
X if(doorindex >= DOORMAX) return;
X if(!(sroom = pick_room())) return;
X
X if(!place_oracle(sroom,&dy,&xx,&yy)) return;
X
X /* set up Oracle and environment */
X if(!(oracl = makemon(&mons[PM_ORACLE],xx,yy))) return;
X sroom->rtype = DELPHI;
X oracl->mpeaceful = 1;
X
X yy -= dy;
X if(ACCESSIBLE(levl[xx-1][yy].typ))
X (void) mkstatue(&mons[PM_FOREST_CENTAUR], xx-1, yy);
X if(ACCESSIBLE(levl[xx][yy].typ))
X (void) mkstatue(&mons[PM_MOUNTAIN_CENTAUR], xx, yy);
X if(ACCESSIBLE(levl[xx+1][yy].typ))
X (void) mkstatue(&mons[PM_PLAINS_CENTAUR], xx+1, yy);
X# ifdef FOUNTAINS
X mkfount(0,sroom);
X# endif
X}
X#endif
X
X#if defined(ALTARS) && defined(THEOLOGY)
Xvoid
Xshrine_pos(sx,sy,troom)
Xint *sx,*sy;
Xstruct mkroom *troom;
X{
X *sx = troom->lx + ((troom->hx - troom->lx) / 2);
X *sy = troom->ly + ((troom->hy - troom->ly) / 2);
X}
X
Xstatic void
Xmktemple()
X{
X register struct mkroom *sroom;
X int sx,sy;
X
X if(!(sroom = pick_room())) return;
X
X /* set up Priest and shrine */
X sroom->rtype = TEMPLE;
X shrine_pos(&sx,&sy,sroom);
X /*
X * In temples, shrines are blessed altars
X * located in the center of the room
X */
X levl[sx][sy].typ = ALTAR;
X levl[sx][sy].scrsym = ALTAR_SYM;
X levl[sx][sy].altarmask = rn2((int)A_LAW+1) | A_SHRINE;
X priestini(dlevel, sx, sy, (int) levl[sx][sy].altarmask);
X}
X#endif
X
Xboolean
Xnexttodoor(sx,sy)
Xregister int sx, sy;
X{
X register int dx, dy;
X register struct rm *lev;
X for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
X if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
X lev->typ == SDOOR)
X return(TRUE);
X return(FALSE);
X}
X
Xboolean
Xhas_dnstairs(sroom)
Xregister struct mkroom *sroom;
X{
X return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
X sroom->ly <= ydnstair && ydnstair <= sroom->hy);
X}
X
Xboolean
Xhas_upstairs(sroom)
Xregister struct mkroom *sroom;
X{
X return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
X sroom->ly <= yupstair && yupstair <= sroom->hy);
X}
X
Xint
Xdist2(x0,y0,x1,y1)
Xint x0, y0, x1, y1;
X{
X register int dx = x0 - x1, dy = y0 - y1;
X return sq(dx) + sq(dy);
X}
X
X#ifdef THRONES
Xstruct permonst *
Xcourtmon()
X{
X int i = rn2(60) + rn2(3*dlevel);
X if (i > 100) return(mkclass(S_DRAGON));
X else if (i > 95) return(mkclass(S_GIANT));
X else if (i > 85) return(mkclass(S_TROLL));
X else if (i > 75) return(mkclass(S_CENTAUR));
X else if (i > 60) return(mkclass(S_ORC));
X else if (i > 45) return(&mons[PM_BUGBEAR]);
X else if (i > 30) return(&mons[PM_HOBGOBLIN]);
X else if (i > 15) return(mkclass(S_GNOME));
X else return(mkclass(S_KOBOLD));
X}
X#endif /* THRONES /**/
X
X#ifdef ARMY
X#define NSTYPES (PM_CAPTAIN-PM_SOLDIER+1)
X
Xstruct {
X unsigned pm;
X unsigned prob;
X} squadprob[NSTYPES] = {
X PM_SOLDIER, 80, PM_SERGEANT, 15, PM_LIEUTENANT, 4, PM_CAPTAIN, 1
X};
X
Xstatic struct permonst *
Xsquadmon() { /* return soldier types. */
X
X register struct permonst *ptr;
X register int i, cpro, sel = rnd(80+dlevel);
X
X for(cpro = i = 0; i < NSTYPES; i++)
X if((cpro += squadprob[i].prob) > sel) {
X
X ptr = &mons[squadprob[i].pm];
X goto gotone;
X }
X ptr = &mons[squadprob[rn2(NSTYPES)].pm];
Xgotone:
X if(!(ptr->geno & G_GENOD)) return(ptr);
X else return((struct permonst *) 0);
X}
X#endif /* ARMY /* */
END_OF_FILE
if test 10546 -ne `wc -c <'src/mkroom.c'`; then
echo shar: \"'src/mkroom.c'\" unpacked with wrong size!
fi
# end of 'src/mkroom.c'
fi
if test -f 'src/mthrowu.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/mthrowu.c'\"
else
echo shar: Extracting \"'src/mthrowu.c'\" \(10474 characters\)
sed "s/^X//" >'src/mthrowu.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)mthrowu.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
Xstatic int movedist();
X
X#define URETREATING(x,y) (movedist(u.ux,u.uy,x,y) > movedist(u.ux0,u.uy0,x,y))
X
Xboolean lined_up();
X
Xschar tbx = 0, tby = 0; /* used for direction of throw, buzz, etc. */
X
Xconst char *breathwep[] = { "fragments",
X "fire",
X "sleep gas",
X "frost",
X "death",
X "lightning",
X "poison gas",
X "acid"
X};
X
Xint
Xthitu(tlev, dam, name) /* u is hit by sth, but not a monster */
X register int tlev, dam;
X register char *name;
X{
X char buf[BUFSZ];
X boolean acidic = (!strcmp(name, "splash of venom") && dam);
X /* A horrible kludge... the problem is that we want to do something
X * special--and we can't do it after returning since we might die and
X * not return, but the special stuff should be done anyway...
X */
X
X setan(name, buf);
X if(u.uac + tlev <= rnd(20)) {
X if(Blind || !flags.verbose) pline("It misses.");
X else You("are almost hit by %s!", buf);
X return(0);
X } else {
X if(Blind || !flags.verbose) You("are hit!");
X else You("are hit by %s!", buf);
X Strcpy(buf,name);
X /* If name came from xname() we must copy it, otherwise if
X * you die, the possession identify will call xname(),
X * overwriting xname's buffer, and your tombstone will say
X * you were killed by a green gem or some such.
X */
X#ifdef POLYSELF
X if (acidic && resists_acid(uasmon))
X pline("It doesn't seem to hurt you.");
X else {
X#endif
X if (acidic) pline("It burns!");
X losehp(dam, buf);
X#ifdef POLYSELF
X }
X#endif
X return(1);
X }
X}
X
X/* Be sure this corresponds with what happens to player-thrown objects in
X * dothrow.c (for consistency). --KAA
X */
Xstatic void
Xdrop_throw(obj, ohit, x, y)
Xregister struct obj *obj;
Xboolean ohit;
Xint x,y;
X{
X int create;
X
X if (obj->otyp == CREAM_PIE || obj->olet == VENOM_SYM)
X create = 0;
X else if (ohit &&
X ((obj->otyp >= ARROW && obj->otyp <= SHURIKEN) ||
X obj->otyp == ROCK))
X create = !rn2(3);
X else create = 1;
X if (create && !flooreffects(obj,x,y)) {
X obj->ox = x;
X obj->oy = y;
X obj->nobj = fobj;
X fobj = obj;
X stackobj(fobj);
X levl[x][y].omask = 1;
X } else free((genericptr_t)obj);
X}
X
Xstatic void
Xm_throw(x, y, dx, dy, range, obj)
X register int x,y,dx,dy,range; /* direction and range */
X register struct obj *obj;
X{
X register struct monst *mtmp;
X struct obj *singleobj;
X char sym = obj->olet;
X int damage;
X int hitu, blindinc=0;
X
X bhitpos.x = x;
X bhitpos.y = y;
X
X singleobj = splitobj(obj, (int)obj->quan-1);
X /* splitobj leaves the new object in the chain (i.e. the monster's
X * inventory). Remove it. We can do this in 1 line, but it's highly
X * dependent on the fact that we know splitobj() places it immediately
X * after obj.
X */
X obj->nobj = singleobj->nobj;
X
X if(sym) {
X tmp_at(-1, sym); /* open call */
X tmp_at(-3, (int)AT_OBJ);
X }
X while(range-- > 0) { /* Actually the loop is always exited by break */
X bhitpos.x += dx;
X bhitpos.y += dy;
X if(levl[bhitpos.x][bhitpos.y].mmask) {
X mtmp = m_at(bhitpos.x,bhitpos.y);
X
X if(mtmp->data->ac + 8 + obj->spe <= rnd(20)) {
X miss(distant_name(singleobj,xname), mtmp);
X if (!range) { /* Last position; object drops */
X drop_throw(singleobj, 0, mtmp->mx, mtmp->my);
X break;
X }
X } else {
X damage = dmgval(obj, mtmp->data);
X if (damage < 1) damage = 1;
X if (obj->otyp==ACID_VENOM && resists_acid(mtmp->data))
X damage = 0;
X hit(distant_name(singleobj,xname), mtmp,exclam(damage));
X if (obj->opoisoned) {
X if (resists_poison(mtmp->data))
X kludge("The poison doesn't seem to affect %s.",
X mon_nam(mtmp));
X else {
X if (rn2(10)) damage += rnd(6);
X else {
X pline("The poison was deadly...");
X damage = mtmp->mhp;
X }
X }
X }
X if (obj->otyp==ACID_VENOM && cansee(mtmp->mx,mtmp->my)){
X if (resists_acid(mtmp->data)) {
X pline("%s is unaffected.", Monnam(mtmp));
X damage = 0;
X } else pline("The acid burns %s!", mon_nam(mtmp));
X }
X mtmp->mhp -= damage;
X if(mtmp->mhp < 1) {
X if (cansee(mtmp->mx, mtmp->my))
X pline("%s is killed!", Monnam(mtmp));
X mondied(mtmp);
X }
X
X if((obj->otyp == CREAM_PIE) ||
X (obj->otyp == BLINDING_VENOM)) {
X if (cansee(mtmp->mx, mtmp->my))
X pline("%s is blinded by the %s.",
X Monnam(mtmp), xname(singleobj));
X if(mtmp->msleep) mtmp->msleep = 0;
X mtmp->mcansee = 0;
X {
X register unsigned rnd_tmp = rnd(25) + 20;
X if((mtmp->mblinded + rnd_tmp) > 127)
X mtmp->mblinded = 127;
X else mtmp->mblinded += rnd_tmp;
X }
X }
X drop_throw(singleobj, 1, bhitpos.x, bhitpos.y);
X break;
X }
X }
X if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
X if (multi) nomul(0);
X
X switch(obj->otyp) {
X int dam;
X case CREAM_PIE:
X case BLINDING_VENOM:
X hitu = thitu(8, 0, xname(singleobj));
X break;
X default:
X dam = dmgval(obj, uasmon);
X if (dam < 1) dam = 1;
X hitu = thitu(8+obj->spe, dam, xname(singleobj));
X }
X if (obj->opoisoned)
X /* it's safe to call xname twice because it's the
X same object both times... */
X poisoned(xname(singleobj), A_STR, xname(singleobj));
X if(hitu && (obj->otyp == CREAM_PIE ||
X obj->otyp == BLINDING_VENOM)) {
X blindinc = rnd(25);
X if(obj->otyp == CREAM_PIE) {
X if(!Blind) pline("Yecch! You've been creamed.");
X else pline("There's something sticky all over your %s.", body_part(FACE));
X } else { /* venom in the eyes */
X if(Blindfolded) /* nothing */ ;
X else if(!Blind) pline("The venom blinds you.");
X else Your("%s sting.",
X makeplural(body_part(EYE)));
X }
X }
X if (hitu || !range) {
X drop_throw(singleobj, hitu, u.ux, u.uy);
X break;
X }
X } else if (!range /* reached end of path */
X /* missile hits edge of screen */
X || !isok(bhitpos.x+dx,bhitpos.y+dy)
X /* missile hits the wall */
X || IS_WALL(levl[bhitpos.x+dx][bhitpos.y+dy].typ)
X || levl[bhitpos.x+dx][bhitpos.y+dy].typ == SDOOR
X || levl[bhitpos.x+dx][bhitpos.y+dy].typ == SCORR
X#ifdef SINKS
X /* Thrown objects "sink" */
X || IS_SINK(levl[bhitpos.x][bhitpos.y].typ)
X#endif
X ) {
X drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
X break;
X }
X tmp_at(bhitpos.x, bhitpos.y);
X }
X tmp_at(bhitpos.x, bhitpos.y);
X tmp_at(-1, -1);
X /* blindfold keeps substances out of your eyes */
X if (blindinc && !Blindfolded) {
X u.ucreamed += blindinc;
X make_blinded(Blinded + blindinc,FALSE);
X }
X}
X
X/* Remove an item from the monster's inventory.
X */
Xvoid
Xm_useup(mon, obj)
Xstruct monst *mon;
Xstruct obj *obj;
X{
X struct obj *otmp, *prev;
X
X prev = ((struct obj *) 0);
X for (otmp = mon->minvent; otmp; otmp = otmp->nobj) {
X if (otmp == obj) {
X if (prev)
X prev->nobj = obj->nobj;
X else
X mon->minvent = obj->nobj;
X free((genericptr_t) obj);
X break;
X }
X prev = otmp;
X }
X}
X
X/* Always returns 0??? -SAC */
Xint
Xthrwmu(mtmp) /* monster throws item at you */
Xregister struct monst *mtmp;
X{
X struct obj *otmp, *select_rwep();
X register xchar x, y;
X
X if(lined_up(mtmp)) {
X
X if((otmp = select_rwep(mtmp))) {
X
X /* If you are coming toward the monster, the monster
X * should try to soften you up with missiles. If you are
X * going away, you are probably hurt or running. Give
X * chase, but if you are getting too far away, throw.
X */
X x = mtmp->mx;
X y = mtmp->my;
X if(!URETREATING(x,y) ||
X !rn2(BOLT_LIM-movedist(x,mtmp->mux,y,mtmp->muy)))
X {
X m_throw(mtmp->mx, mtmp->my, sgn(tbx), sgn(tby),
X movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy), otmp);
X if (!otmp->quan) m_useup(mtmp, otmp);
X nomul(0);
X return 0;
X }
X }
X }
X return 0;
X}
X
Xint
Xspitmu(mtmp) /* monster spits substance at you */
Xregister struct monst *mtmp;
X{
X register struct obj *otmp;
X
X if(mtmp->mcan) {
X
X if(flags.soundok)
X pline("A dry rattle comes from %s's throat", mon_nam(mtmp));
X return 0;
X }
X if(lined_up(mtmp)) {
X otmp = mksobj(mtmp->data==&mons[PM_COBRA] ?
X BLINDING_VENOM : ACID_VENOM, FALSE);
X /* really incorrect; should check the attack type; this might
X * fail if someone introduces another monster with a venom
X * attack...
X */
X if(!rn2(BOLT_LIM-movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy))) {
X
X m_throw(mtmp->mx, mtmp->my, sgn(tbx), sgn(tby),
X movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy), otmp);
X nomul(0);
X return 0;
X }
X }
X return 0;
X}
X
Xint
Xbreamu(mtmp, mattk) /* monster breathes at you (ranged) */
X register struct monst *mtmp;
X register struct attack *mattk;
X{
X if(lined_up(mtmp)) {
X
X if(mtmp->mcan) {
X if(flags.soundok) {
X if(canseemon(mtmp))
X pline("%s coughs.", Monnam(mtmp));
X else
X You("hear a cough.");
X }
X return(0);
X }
X if(rn2(3)) {
X
X if((mattk->adtyp >= 1) && (mattk->adtyp < 11)) {
X
X if(canseemon(mtmp))
X pline("%s breathes %s!", Monnam(mtmp),
X breathwep[mattk->adtyp-1]);
X buzz((int) (-20 - (mattk->adtyp-1)), (int)mattk->damn,
X mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
X nomul(0);
X } else impossible("Breath weapon %d used", mattk->adtyp-1);
X }
X }
X return(1);
X}
X
Xboolean
Xlinedup(ax, ay, bx, by)
Xregister xchar ax, ay, bx, by;
X{
X register xchar x, y;
X
X tbx = ax - bx; /* These two values are set for use */
X tby = ay - by; /* after successful return. */
X
X if((!tbx || !tby || abs(tbx) == abs(tby)) /* straight line or diagonal */
X && movedist(tbx, 0, tby, 0) < BOLT_LIM) {
X
X /* Check if there are any dead squares between. If so,
X * it will not be possible to shoot.
X */
X x = bx; y = by;
X while(x != ax || y != ay) {
X
X if (!ACCESSIBLE(levl[x][y].typ) ||
X (IS_DOOR(levl[x][y].typ) &&
X (levl[x][y].doormask & (D_LOCKED | D_CLOSED))))
X return FALSE;
X x += sgn(tbx), y += sgn(tby);
X }
X return TRUE;
X }
X return FALSE;
X}
X
Xboolean
Xlined_up(mtmp) /* is mtmp in position to use ranged attack? */
X register struct monst *mtmp;
X{
X return(linedup(mtmp->mux,mtmp->muy,mtmp->mx,mtmp->my));
X}
X
X/* Check if a monster is carrying a particular item.
X */
Xstruct obj *
Xm_carrying(mtmp, type)
Xstruct monst *mtmp;
Xint type;
X{
X register struct obj *otmp;
X
X for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
X if(otmp->otyp == type)
X return(otmp);
X return((struct obj *) 0);
X}
X
Xstatic int
Xmovedist(x0, x1, y0, y1)
X{
X register int absdx, absdy;
X
X absdx = abs(x1 - x0);
X absdy = abs(y1 - y0);
X
X return (max(absdx,absdy));
X}
END_OF_FILE
if test 10474 -ne `wc -c <'src/mthrowu.c'`; then
echo shar: \"'src/mthrowu.c'\" unpacked with wrong size!
fi
# end of 'src/mthrowu.c'
fi
if test -f 'src/spell.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/spell.c'\"
else
echo shar: Extracting \"'src/spell.c'\" \(10739 characters\)
sed "s/^X//" >'src/spell.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)spell.c 3.0 88/09/18
X *
X * Copyright (c) M. Stepheneon 1988
X */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X#ifdef SPELLS
Xstatic schar delay; /* moves left for this spell */
Xstatic struct obj *book; /* last/current book being xscribed */
X
X#ifdef HARD
X#define spelluses(spell) spl_book[spell-1].sp_uses
X#define decrnuses(spell) spl_book[spell-1].sp_uses--
X#endif /* HARD */
X#define spellev(spell) spl_book[spell-1].sp_lev
X#define spellname(spell) objects[spl_book[spell-1].sp_id].oc_name
X#define spellid(spell) spl_book[spell-1].sp_id
X
Xstatic void
Xcursed_book(level)
X register int level;
X{
X switch(rn2(level)) {
X case 0:
X You("feel a wrenching sensation.");
X tele(); /* teleport him */
X break;
X case 1:
X You("feel threatened.");
X aggravate();
X break;
X case 2:
X make_blinded(Blinded + rn1(100,250),TRUE);
X break;
X case 3:
X take_gold();
X break;
X case 4:
X pline("These runes were just too much to comprehend.");
X make_confused(HConfusion + rn1(7,16),FALSE);
X break;
X case 5:
X pline("The book was coated with contact poison!");
X if (uarmg) {
X if (uarmg->rustfree)
X Your("gloves seem unaffected.");
X else if (uarmg->spe > -6) {
X Your("gloves corrode!");
X uarmg->spe--;
X } else
X Your("gloves look quite corroded.");
X break;
X }
X if(Poison_resistance) {
X losestr(rn1(1,2));
X losehp(rnd(6), "contact poison");
X } else {
X losestr(rn1(4,3));
X losehp(rnd(10), "contact poison");
X }
X break;
X case 6:
X if(Antimagic) {
X shieldeff(u.ux, u.uy);
X pline("The book explodes, but you are unharmed!");
X } else {
X pline("As you read the book, it explodes in your %s!",
X body_part(FACE));
X losehp (2*rnd(10)+5, "exploding rune");
X }
X break;
X default:
X rndcurse();
X break;
X }
X return;
X}
X
Xstatic int
Xlearn()
X{
X register int i;
X register unsigned booktype;
X
X if (delay) { /* not if (delay++), so at end delay == 0 */
X delay++;
X return(1); /* still busy */
X }
X
X booktype = book->otyp;
X for (i = 0; i < MAXSPELL; i++) {
X if (spl_book[i].sp_id == booktype) {
X#ifdef HARD
X Your("knowledge of that spell is keener.");
X spl_book[i].sp_uses += rn1(3,8-spl_book[i].sp_lev);
X#else
X pline("Oh, you already know that one!");
X#endif
X break;
X } else if (spl_book[i].sp_id == NO_SPELL) {
X spl_book[i].sp_id = booktype;
X spl_book[i].sp_lev = objects[booktype].spl_lev;
X spl_book[i].sp_flags = objects[booktype].bits;
X#ifdef HARD
X /* spells have 2 .. 10-level uses. */
X /* ie 2 or 3 uses w/ most potent */
X spl_book[i].sp_uses = rn1(3,8-spl_book[i].sp_lev);
X#endif
X You("add the spell to your repertoire.");
X makeknown(booktype);
X break;
X }
X }
X if (i == MAXSPELL) impossible("Too many spells memorized!");
X
X if (book->cursed) { /* maybe a demon cursed it */
X cursed_book(objects[booktype].spl_lev);
X }
X
X useup(book);
X book = 0;
X return(0);
X}
X
Xint
Xstudy_book(spellbook)
Xregister struct obj *spellbook;
X{
X register int booktype = spellbook->otyp;
X register boolean oops = !spellbook->blessed && (spellbook->cursed ||
Xrn2(20) > (ACURR(A_INT) + 4 + (int)(u.ulevel/2) - 2*objects[booktype].spl_lev));
X
X if (delay && spellbook == book)
X You("continue your efforts to memorize the spell.");
X else {
X switch(booktype) {
X
X/* level 1 spells */
X case SPE_HEALING:
X case SPE_DETECT_MONSTERS:
X case SPE_FORCE_BOLT:
X case SPE_LIGHT:
X case SPE_SLEEP:
X case SPE_KNOCK:
X/* level 2 spells */
X case SPE_MAGIC_MISSILE:
X case SPE_CONFUSE_MONSTER:
X case SPE_SLOW_MONSTER:
X case SPE_CURE_BLINDNESS:
X case SPE_CREATE_MONSTER:
X case SPE_DETECT_FOOD:
X case SPE_WIZARD_LOCK:
X delay = -objects[booktype].oc_delay;
X break;
X/* level 3 spells */
X case SPE_HASTE_SELF:
X case SPE_CAUSE_FEAR:
X case SPE_CURE_SICKNESS:
X case SPE_DETECT_UNSEEN:
X case SPE_EXTRA_HEALING:
X case SPE_CHARM_MONSTER:
X case SPE_CLAIRVOYANCE:
X/* level 4 spells */
X case SPE_LEVITATION:
X case SPE_RESTORE_ABILITY:
X case SPE_INVISIBILITY:
X case SPE_FIREBALL:
X case SPE_DETECT_TREASURE:
X delay = -(objects[booktype].spl_lev - 1) * objects[booktype].oc_delay;
X break;
X/* level 5 spells */
X case SPE_REMOVE_CURSE:
X case SPE_MAGIC_MAPPING:
X case SPE_CONE_OF_COLD:
X case SPE_IDENTIFY:
X case SPE_DIG:
X/* level 6 spells */
X case SPE_TURN_UNDEAD:
X case SPE_POLYMORPH:
X case SPE_CREATE_FAMILIAR:
X case SPE_TELEPORT_AWAY:
X delay = -objects[booktype].spl_lev * objects[booktype].oc_delay;
X break;
X/* level 7 spells */
X case SPE_CANCELLATION:
X case SPE_FINGER_OF_DEATH:
X case SPE_GENOCIDE:
X delay = -8 * objects[booktype].oc_delay;
X break;
X/* impossible */
X default:
X impossible("Unknown spellbook, %d;", booktype);
X return(0);
X }
X
X if (oops) {
X cursed_book(objects[booktype].spl_lev);
X nomul(delay); /* study time */
X delay = 0;
X useup(spellbook);
X return(1);
X }
X
X You("begin to memorize the runes.");
X }
X
X book = spellbook;
X set_occupation(learn, "studying", 0);
X return(1);
X}
X
Xstatic int
Xgetspell() {
X
X register int maxs, ilet, i;
X char lets[BUFSZ], buf[BUFSZ];
X
X if (spl_book[0].sp_id == NO_SPELL) {
X
X You("don't know any spells right now.");
X return(0);
X } else {
X
X for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
X if (maxs >= MAXSPELL) {
X
X impossible("Too many spells memorized.");
X return(0);
X }
X
X for(i = 0; (i < maxs) && (i < 26); buf[++i] = 0) buf[i] = 'a' + i;
X for(i = 26; (i < maxs) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26;
X
X if (maxs == 1) Strcpy(lets, "a");
X else if (maxs < 27) Sprintf(lets, "a-%c", 'a' + maxs - 1);
X else if (maxs == 27) Sprintf(lets, "a-z A");
X else Sprintf(lets, "a-z A-%c", 'A' + maxs - 27);
X for(;;) {
X
X pline("Cast which spell? [%s ?] ", lets);
X if ((ilet = readchar()) == '?') {
X (void) dovspell();
X continue;
X } else if ((ilet == '\033')||(ilet == '\n')||(ilet == ' '))
X return(0);
X else for(i = 0; buf[i] != 0; i++) if(ilet == buf[i]) return(++i);
X You("don't know that spell.");
X }
X }
X}
X
Xint
Xdocast()
X{
X register int spell;
X
X spell = getspell();
X if (!spell) return(0);
X
X return(spelleffects(spell,FALSE));
X}
X
Xint
Xspelleffects(spell,atme)
Xregister int spell;
Xboolean atme;
X{
X register int energy, damage;
X#ifdef HARD
X boolean confused = (Confusion != 0);
X#endif
X struct obj *pseudo;
X
X#ifdef HARD
X /* note that trying to cast it decrements the # of uses, */
X /* even if the mage does not have enough food/energy to use */
X /* the spell */
X switch (spelluses(spell)) {
X case 0:
X pline ("That spell is too hard to recall at the moment.");
X return(0);
X case 1:
X pline ("You can barely remember the runes of this spell.");
X break;
X case 2:
X pline ("This spell is starting to be over-used.");
X break;
X default:
X break;
X }
X decrnuses(spell);
X#endif
X energy = spellev(spell);
X if (u.uhave_amulet) {
X You("feel the amulet draining your energy away.");
X energy *= rnd(6);
X }
X if(energy > u.uen) {
X You("are too weak to cast that spell.");
X return(0);
X } else if ((u.uhunger <= 100 && spell != SPE_DETECT_FOOD) ||
X (ACURR(A_STR) < 6)) {
X You("lack the strength for that spell.");
X return(0);
X } else {
X if (spell != SPE_DETECT_FOOD)
X morehungry(energy * 10);
X u.uen -= energy;
X }
X flags.botl = 1;
X
X#ifdef HARD
X if (confused ||
X ((int)(ACURR(A_INT) + u.uluck) - 3 * spellev(spell)) < 0) {
X
X if (Hallucination)
X pline("Far out... a light show!");
X else pline("The air around you crackles as you goof up.");
X return(0);
X }
X#endif
X
X/* pseudo is a temporary "false" object containing the spell stats. */
X pseudo = mksobj(spellid(spell),FALSE);
X pseudo->blessed = pseudo->cursed = 0;
X pseudo->quan = 20; /* do not let useup get it */
X switch(pseudo->otyp) {
X
X/* These spells are all duplicates of wand effects */
X case SPE_FORCE_BOLT:
X case SPE_SLEEP:
X case SPE_MAGIC_MISSILE:
X case SPE_KNOCK:
X case SPE_SLOW_MONSTER:
X case SPE_WIZARD_LOCK:
X case SPE_FIREBALL:
X case SPE_CONE_OF_COLD:
X case SPE_DIG:
X case SPE_TURN_UNDEAD:
X case SPE_POLYMORPH:
X case SPE_TELEPORT_AWAY:
X case SPE_CANCELLATION:
X case SPE_FINGER_OF_DEATH:
X case SPE_LIGHT:
X case SPE_DETECT_UNSEEN:
X if (!(objects[pseudo->otyp].bits & NODIR)) {
X if (atme) u.dx = u.dy = u.dz = 0;
X else (void) getdir(1);
X if(!u.dx && !u.dy && !u.dz) {
X if((damage = zapyourself(pseudo)))
X losehp(damage, "self-inflicted injury");
X } else weffects(pseudo);
X } else weffects(pseudo);
X break;
X/* These are all duplicates of scroll effects */
X case SPE_CONFUSE_MONSTER:
X case SPE_DETECT_FOOD:
X case SPE_CAUSE_FEAR:
X case SPE_CHARM_MONSTER:
X case SPE_REMOVE_CURSE:
X case SPE_MAGIC_MAPPING:
X case SPE_CREATE_MONSTER:
X case SPE_IDENTIFY:
X case SPE_GENOCIDE:
X (void) seffects(pseudo);
X break;
X case SPE_HASTE_SELF:
X case SPE_DETECT_TREASURE:
X case SPE_DETECT_MONSTERS:
X case SPE_LEVITATION:
X case SPE_RESTORE_ABILITY:
X case SPE_INVISIBILITY:
X (void) peffects(pseudo);
X break;
X case SPE_HEALING:
X You("feel a bit better.");
X healup(rnd(8), 0, 0, 0);
X break;
X case SPE_CURE_BLINDNESS:
X healup(0, 0, 0, 1);
X break;
X case SPE_CURE_SICKNESS:
X You("are no longer ill.");
X healup(0, 0, 1, 0);
X break;
X case SPE_EXTRA_HEALING:
X You("feel a fair bit better.");
X healup(d(2,8), 1, 0, 0);
X break;
X case SPE_CREATE_FAMILIAR:
X make_familiar((struct obj *)0);
X break;
X case SPE_CLAIRVOYANCE:
X do_vicinity_map();
X break;
X default:
X impossible("Unknown spell %d attempted.", spell);
X obfree(pseudo, (struct obj *)0);
X return(0);
X }
X obfree(pseudo, (struct obj *)0); /* now, get rid of it */
X return(1);
X}
X
Xvoid
Xlosespells() {
X register boolean confused = (Confusion != 0);
X register int n, nzap, i;
X
X book = 0;
X for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++);
X if (!n) return;
X if (n < MAXSPELL) {
X nzap = rnd(n);
X if (nzap < n) nzap += confused;
X for (i = 0; i < nzap; i++) spl_book[n-i-1].sp_id = NO_SPELL;
X } else impossible("Too many spells memorized!");
X return;
X}
X
Xstatic char
Xspellet(spl)
X{
X return (spl < 27) ? ('a' + spl - 1) : ('A' + spl - 27);
X}
X
Xint
Xdovspell() {
X
X register int maxs, i;
X char buf[BUFSZ], any[BUFSZ];
X
X if (spl_book[0].sp_id == NO_SPELL) {
X
X You("don't know any spells right now.");
X return 0;
X }
X
X for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
X if (maxs >= MAXSPELL) {
X
X impossible("Too many spells memorized.");
X return 0;
X }
X morc = 0; /* just to be sure */
X cornline(0, "Currently known spells:");
X
X for(i = 1; i <= maxs; i++) {
X
X#ifdef HARD
X Sprintf(buf, "%c %c %s (%d)",
X spellet(i), (spelluses(i)) ? '-' : '*',
X spellname(i), spellev(i));
X#else
X Sprintf(buf, "%c %s (%d)",
X spellet(i),
X spellname(i), spellev(i));
X#endif
X cornline(1, buf);
X any[i-1] = spellet(i);
X }
X any[i-1] = 0;
X cornline(2, any);
X
X return 0;
X}
X
X
X#endif /* SPELLS /**/
END_OF_FILE
if test 10739 -ne `wc -c <'src/spell.c'`; then
echo shar: \"'src/spell.c'\" unpacked with wrong size!
fi
# end of 'src/spell.c'
fi
echo shar: End of archive 29 \(of 38\).
cp /dev/null ark29isdone
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 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 38 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0