billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 10, Issue 50 Archive-name: nethack3p9/Part05 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 5 (of 56)." # Contents: others/Makefile.pc src/mhitu.c # Wrapped by billr@saab on Wed Jul 11 17:10:55 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'others/Makefile.pc' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'others/Makefile.pc'\" else echo shar: Extracting \"'others/Makefile.pc'\" \(8066 characters\) sed "s/^X//" >'others/Makefile.pc' <<'END_OF_FILE' X# SCCS Id: @(#)Makefile.pc 3.0 89/07/07 X# PC NetHack 3.0 Makefile for Microsoft(tm) "C" 4.0 or better. X# X# Large memory model, register bug, remove stack probes: XCC = msc XLINK = link XMODEL = L X X# Directories (makedefs hardcodes these, don't change them) XINCL = ..\include XAUX = ..\auxil XSRC = ..\src X XCFLAGS = -A$(MODEL) -DLINT_ARGS -Ot -Oa -Gs -Gt28 -I$(INCL) XLFLAGS = -exe -noig -stack:0x0aff -seg:512 XTARG = pc X X.c.o: X $(CC) $(CFLAGS) $*.c, o\$*.o; X X# Optional high-quality BSD random number generation routines (see pcconf.h). X# Set to nothing if not used. XRANDOM = o\random.obj X X# For NDMAKE, to handle the .o suffix. X.SUFFIXES: .exe .o .c .y .l X X# The game name XGAME= nethack X X# The game directory XGAMEDIR = \games\$(GAME) X X# The game filename XGAMEFILE = $(GAMEDIR)\$(GAME).exe X X# object files for makedefs XMAKEOBJS = o\makedefs.o o\monst.o o\objects.o X X# object files for special levels compiler XSPLEVOBJS = o\lev_comp.o o\lev_lex.o o\lev_main.o o\alloc.o o\monst.o o\objects.o 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 = o\allmain.o o\alloc.o o\apply.o o\artifact.o o\attrib.o o\bones.o \ X o\cmd.o o\dbridge.o o\decl.o o\demon.o o\do.o o\do_name.o o\do_wear.o \ X o\dog.o o\dogmove.o o\dokick.o o\dothrow.o o\eat.o o\end.o o\engrave.o \ X o\exper.o o\extralev.o o\fountain.o o\getline.o o\hack.o o\invent.o \ X o\lock.o o\mail.o o\main.o o\makemon.o o\mcastu.o o\mhitm.o o\mhitu.o \ X o\mklev.o o\mkmaze.o o\mkobj.o o\mkroom.o o\mon.o o\mondata.o \ X o\msdos.o o\monmove.o o\monst.o o\mthrowu.o o\music.o o\o_init.o \ X o\objects.o o\objnam.o o\options.o o\pager.o o\pickup.o o\polyself.o \ X o\potion.o o\pray.o o\pri.o o\priest.o o\prisym.o $(RANDOM) o\read.o \ X o\restore.o o\rip.o o\rnd.o o\rumors.o o\save.o o\search.o o\shk.o \ X o\shknam.o o\sit.o o\sounds.o o\sp_lev.o o\spell.o o\steal.o \ X o\termcap.o o\timeout.o o\topl.o o\topten.o o\track.o o\trap.o \ X o\tty.o o\u_init.o o\uhitm.o o\unix.o o\vault.o o\weapon.o o\were.o \ X o\wield.o o\wizard.o o\worm.o o\worn.o o\write.o o\zap.o XHOBJ = $(VOBJ) o\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)\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$(GAMEDIR)\$(GAME).exe: o $(HOBJ) X .\linkit X# $(LINK) $(HOBJ),nethack,nethack,ltermcap llibux $(LFLAGS) ; X X# NDMAKE automatically generates LINK response files, so you can X# uncomment the second line if you are using NDMAKE. X X$(GAME): $(GAMEDIR)\$(GAME).exe X$(GAME).exe: $(GAMEDIR)\$(GAME).exe X X.c.o: X $(CC) $(CFLAGS) $*.c, o\$*.o ; X Xall: o $(GAME) auxil X @echo Done. X Xo: X mkdir o X Xmakedefs.exe: $(MAKEOBJS) X $(LINK) $(LFLAGS) $(MAKEOBJS); X Xo\makedefs.o: $(INCL)\config.h $(INCL)\permonst.h $(INCL)\objclass.h X Xlev_comp.exe: $(SPLEVOBJS) X $(LINK) $(LFLAGS) -o lev_comp $(SPLEVOBJS) X Xo\lev_comp.o: $(HACK_H) $(INCL)\sp_lev.h Xo\lev_lex.o: $(INCL)\lev_comp.h $(HACK_H) $(INCL)\sp_lev.h Xo\lev_main.o: $(HACK_H) X X# If you have yacc or lex programs, and make any changes, X# add some .y.c and .l.c rules to your Make.ini. X Xlev_comp.c: lev_comp.y Xlev_lex.c: lev_comp.l X 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.exe X .\makedefs -v X X$(INCL)\trap.h: makedefs.exe X .\makedefs -t X X$(INCL)\onames.h: makedefs.exe X .\makedefs -o X X$(INCL)\pm.h: makedefs.exe X .\makedefs -p X Xdata: $(AUX)\data.base makedefs.exe X .\makedefs -d X Xrumors: $(AUX)\rumors.tru $(AUX)\rumors.fal makedefs.exe X .\makedefs -r X X# X# The following programs vary depending on what OS you are using. X# Xo\main.o: $(HACK_H) $(TARG)main.c X $(CC) $(CFLAGS) $(TARG)main.c, o\main.o ; X Xo\tty.o: $(HACK_H) $(INCL)\func_tab.h $(TARG)tty.c X $(CC) $(CFLAGS) $(TARG)tty.c, o\tty.o ; X Xo\unix.o: $(HACK_H) $(TARG)unix.c X $(CC) $(CFLAGS) $(TARG)unix.c, o\unix.o ; X X# X# Secondary targets X# X Xauxil: spec_levs X cd $(AUX) X xcopy *. $(GAMEDIR) X Xspec_levs: $(AUX)\castle.des $(AUX)\endgame.des $(AUX)\tower.des X lev_comp $(AUX)\castle.des X lev_comp $(AUX)\endgame.des X lev_comp $(AUX)\tower.des X cd $(AUX) X xcopy castle $(GAMEDIR) X del castle X xcopy endgame $(GAMEDIR) X del endgame X xcopy tower? $(GAMEDIR) X del tower? X Xclean: X del o\*.obj X rmdir o X Xspotless: clean X cd $(INCL) X del date.h X del onames.h X del pm.h X touch date.h onames.h pm.h X cd $(SRC) X del makedefs.exe X if exist lev_comp.exe del lev_comp.exe X X# X# Other dependencies X# X X# GO AHEAD, DELETE THIS LINE X Xo\allmain.o: $(HACK_H) Xo\alloc.o: $(CONFIG_H) Xo\apply.o: $(HACK_H) $(INCL)\edog.h Xo\artifact.o: $(HACK_H) $(INCL)\artifact.h Xo\attrib.o: $(HACK_H) Xo\bones.o: $(HACK_H) Xo\cmd.o: $(HACK_H) $(INCL)\func_tab.h Xo\dbridge.o: $(HACK_H) Xo\decl.o: $(HACK_H) Xo\demon.o: $(HACK_H) Xo\do.o: $(HACK_H) Xo\do_name.o: $(HACK_H) Xo\do_wear.o: $(HACK_H) Xo\dog.o: $(HACK_H) $(INCL)\edog.h Xo\dogmove.o: $(HACK_H) $(INCL)\mfndpos.h $(INCL)\edog.h Xo\dokick.o: $(HACK_H) $(INCL)\eshk.h Xo\dothrow.o: $(HACK_H) Xo\eat.o: $(HACK_H) Xo\end.o: $(HACK_H) $(INCL)\eshk.h Xo\engrave.o: $(HACK_H) Xo\exper.o: $(HACK_H) Xo\extralev.o: $(HACK_H) Xo\fountain.o: $(HACK_H) Xo\getline.o: $(HACK_H) $(INCL)\func_tab.h Xo\hack.o: $(HACK_H) Xo\invent.o: $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h Xo\ioctl.o: $(HACK_H) Xo\lock.o: $(HACK_H) Xo\makemon.o: $(HACK_H) Xo\mail.o: $(HACK_H) Xo\mcastu.o: $(HACK_H) Xo\mhitm.o: $(HACK_H) $(INCL)\artifact.h Xo\mhitu.o: $(HACK_H) $(INCL)\artifact.h $(INCL)\edog.h Xo\mklev.o: $(HACK_H) Xo\mkmaze.o: $(HACK_H) Xo\mkobj.o: $(HACK_H) Xo\mkroom.o: $(HACK_H) Xo\mon.o: $(HACK_H) $(INCL)\mfndpos.h $(INCL)\wseg.h Xo\mondata.o: $(HACK_H) $(INCL)\eshk.h $(INCL)\epri.h Xo\monmove.o: $(HACK_H) $(INCL)\mfndpos.h $(INCL)\artifact.h Xo\monst.o: $(CONFIG_H) $(PERMONST_H) $(INCL)\monsym.h $(INCL)\eshk.h $(INCL)\vault.h $(INCL)\epri.h $(INCL)\color.h Xo\msdos.o: $(HACK_H) Xo\mthrowu.o: $(HACK_H) Xo\music.o: $(HACK_H) Xo\o_init.o: $(HACK_H) Xo\objects.o: $(CONFIG_H) $(INCL)\obj.h $(INCL)\objclass.h $(INCL)\prop.h $(INCL)\color.h Xo\objnam.o: $(HACK_H) Xo\options.o: $(HACK_H) Xo\pager.o: $(HACK_H) Xo\panic.o: $(CONFIG_H) Xo\pickup.o: $(HACK_H) Xo\polyself.o: $(HACK_H) Xo\potion.o: $(HACK_H) Xo\pray.o: $(HACK_H) Xo\pri.o: $(HACK_H) $(INCL)\epri.h $(INCL)\termcap.h Xo\priest.o: $(HACK_H) $(INCL)\mfndpos.h $(INCL)\eshk.h $(INCL)\epri.h Xo\prisym.o: $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h Xo\random.o: Xo\read.o: $(HACK_H) Xo\restore.o: $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h Xo\rip.o: $(HACK_H) Xo\rnd.o: $(HACK_H) Xo\rumors.o: $(HACK_H) Xo\save.o: $(HACK_H) $(INCL)\lev.h $(INCL)\wseg.h Xo\search.o: $(HACK_H) $(INCL)\artifact.h Xo\shk.o: $(HACK_H) $(INCL)\eshk.h Xo\shknam.o: $(HACK_H) $(INCL)\eshk.h Xo\sit.o: $(HACK_H) Xo\sounds.o: $(HACK_H) $(INCL)\edog.h $(INCL)\eshk.h Xo\sp_lev.o: $(HACK_H) $(INCL)\sp_lev.h Xo\spell.o: $(HACK_H) Xo\steal.o: $(HACK_H) Xo\termcap.o: $(HACK_H) $(INCL)\termcap.h Xo\timeout.o: $(HACK_H) Xo\topl.o: $(HACK_H) Xo\topten.o: $(HACK_H) Xo\track.o: $(HACK_H) Xo\trap.o: $(HACK_H) $(INCL)\edog.h Xo\u_init.o: $(HACK_H) Xo\uhitm.o: $(HACK_H) $(INCL)\artifact.h Xo\vault.o: $(HACK_H) $(INCL)\vault.h Xo\version.o: $(HACK_H) $(INCL)\date.h $(INCL)\patchlev.h Xo\weapon.o: $(HACK_H) Xo\were.o: $(HACK_H) Xo\wield.o: $(HACK_H) Xo\wizard.o: $(HACK_H) Xo\worm.o: $(HACK_H) $(INCL)\wseg.h Xo\worn.o: $(HACK_H) Xo\write.o: $(HACK_H) Xo\zap.o: $(HACK_H) END_OF_FILE if test 8066 -ne `wc -c <'others/Makefile.pc'`; then echo shar: \"'others/Makefile.pc'\" unpacked with wrong size! fi # end of 'others/Makefile.pc' fi if test -f 'src/mhitu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/mhitu.c'\" else echo shar: Extracting \"'src/mhitu.c'\" \(47502 characters\) sed "s/^X//" >'src/mhitu.c' <<'END_OF_FILE' X/* SCCS Id: @(#)mhitu.c 3.0 89/11/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#ifdef NAMED_ITEMS X# include "artifact.h" X#endif X XSTATIC_VAR struct obj NEARDATA *otmp; X X#ifdef POLYSELF XSTATIC_DCL void FDECL(urustm, (struct monst *, struct obj *)); X# ifdef OVL1 Xstatic int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *)); X# endif /* OVL1 */ X#endif /* POLYSELF */ X X#ifdef OVLB X# ifdef SEDUCE Xstatic void FDECL(mayberem, (struct obj *, const char *)); X# endif X#endif /* OVLB */ X XSTATIC_DCL int FDECL(hitmu, (struct monst *,struct attack *)); XSTATIC_DCL int FDECL(gulpmu, (struct monst *,struct attack *)); XSTATIC_DCL int FDECL(explmu, (struct monst *,struct attack *)); XSTATIC_DCL int FDECL(gazemu, (struct monst *,struct attack *)); XSTATIC_DCL void FDECL(missmu,(struct monst *,BOOLEAN_P,struct attack *)); XSTATIC_DCL void FDECL(mswings,(struct monst *,struct obj *)); XSTATIC_DCL void FDECL(wildmiss,(struct monst *)); X XSTATIC_DCL void FDECL(hurtarmor,(struct permonst *,int)); X X#ifdef OVL1 X Xstatic void FDECL(hitmsg,(struct monst *,struct attack *)); X Xstatic void Xhitmsg(mtmp, mattk) Xregister struct monst *mtmp; Xregister struct attack *mattk; X{ X int compat; X X /* Note: if opposite gender, "seductively" */ X /* If same gender, "engagingly" for nymph, normal msg for others */ X if((compat = could_seduce(mtmp, &youmonst, mattk)) X && !mtmp->mcan && !mtmp->mspec_used) { X kludge("%s %s you %s.", Monnam(mtmp), X Blind ? "talks to" : "smiles at", X compat == 2 ? "engagingly" : "seductively"); X } else X switch (mattk->aatyp) { X case AT_BITE: X kludge("%s bites!", Monnam(mtmp)); X break; X case AT_KICK: X#ifdef POLYSELF X kludge("%s kicks%c", Monnam(mtmp), thick_skinned(uasmon) ? '.' : '!'); X#else X kludge("%s kicks!", Monnam(mtmp)); X#endif X break; X case AT_STNG: X kludge("%s stings!", Monnam(mtmp)); X break; X case AT_BUTT: X kludge("%s butts!", Monnam(mtmp)); X break; X case AT_TUCH: X kludge("%s touches you!", Monnam(mtmp)); X break; X default: X kludge("%s hits!", Monnam(mtmp)); X } X} X XSTATIC_OVL void Xmissmu(mtmp, nearmiss, mattk) /* monster missed you */ Xregister struct monst *mtmp; Xregister boolean nearmiss; Xregister struct attack *mattk; X{ X if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan) X kludge("%s pretends to be friendly.", Monnam(mtmp)); X else { X if (!flags.verbose || !nearmiss) X kludge("%s misses.", Monnam(mtmp)); X else X kludge("%s just misses!", Monnam(mtmp)); X } X} X XSTATIC_OVL void Xmswings(mtmp, otemp) /* monster swings obj */ Xregister struct monst *mtmp; Xregister struct obj *otemp; X{ X if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return; X pline("%s %s %s %s.", Monnam(mtmp), X ((otemp->otyp >= SPEAR && X otemp->otyp <= LANCE) || X (otemp->otyp >= PARTISAN && X otemp->otyp <= SPETUM) || X otemp->otyp == TRIDENT) ? "thrusts" : "swings", X is_female(mtmp) ? "her" : X is_human(mtmp->data) ? "his" : "its", X xname(otemp)); X} X X#endif /* OVL1 */ X#ifdef OVLB X XSTATIC_OVL void Xwildmiss(mtmp) /* monster attacked your displaced image */ X register struct monst *mtmp; X{ X int compat; X X if (!flags.verbose) return; X if (!cansee(mtmp->mx, mtmp->my)) return; X /* maybe it's attacking an image around the corner? */ X X compat = could_seduce(mtmp, &youmonst, (struct attack *)0); X /* we really want to have the attack here to pass -- X * the previous code checked whether mtmp was a nymph, X * which was not correct either since the attack type of X * succubi/incubi varies with SEDUCE X */ X X if(Invis && !perceives(mtmp->data)) { X if(compat) X kludge("%s tries to touch you and misses!", Monnam(mtmp)); X else X switch(rn2(3)) { X case 0: kludge("%s swings wildly and misses!", Monnam(mtmp)); X break; X case 1: kludge("%s attacks a spot beside you.", Monnam(mtmp)); X break; X case 2: kludge("%s strikes at thin air!", Monnam(mtmp)); X break; X default:kludge("%s swings wildly!", Monnam(mtmp)); X break; X } X } X else if(Displaced) { X if(compat) X kludge("%s smiles %s at your %sdisplaced image...", X Monnam(mtmp), X compat == 2 ? "engagingly" : "seductively", X Invis ? "invisible " : ""); X else X kludge("%s strikes at your %sdisplaced image and misses you!", X /* Note: if you're both invisible and displaced, X * only monsters which see invisible will attack your X * displaced image, since the displaced image is also X * invisible. X */ X Monnam(mtmp), X Invis ? "invisible " : ""); X } X else impossible("%s attacks you without knowing your location?", X Monnam(mtmp)); X} X Xvoid Xexpels(mtmp, mdat, message) Xregister struct monst *mtmp; Xregister struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */ Xboolean message; X{ X if (message) X if (is_animal(mdat)) X You("get regurgitated!"); X else { X char blast[40]; X register int i; X X blast[0] = '\0'; X for(i = 0; i < NATTK; i++) X if(mdat->mattk[i].aatyp == AT_ENGL) X break; X if (mdat->mattk[i].aatyp != AT_ENGL) X impossible("Swallower has no engulfing attack?"); X else { X if (is_whirly(mdat)) { X switch (mdat->mattk[i].adtyp) { X case AD_ELEC: X Strcpy(blast, X " in a shower of sparks"); X break; X case AD_COLD: X Strcpy(blast, X " in a blast of frost"); X break; X } X } else X Strcpy(blast, " with a squelch"); X You("get expelled from %s%s!", X mon_nam(mtmp), blast); X } X } X unstuck(mtmp); X mnexto(mtmp); X prme(); X spoteffects(); X /* to cover for a case where mtmp is not in a next square */ X if(um_dist(mtmp->mx,mtmp->my,1)) X pline("Brrooaa... You land hard at some distance."); X} X X#endif /* OVLB */ X#ifdef OVL0 X X/* X * mattacku: monster attacks you X * returns 1 if monster dies (e.g. "yellow light"), 0 otherwise X * Note: if you're displaced or invisible the monster might attack the X * wrong position... X * Assumption: it's attacking you or an empty square; if there's another X * monster which it attacks by mistake, the caller had better X * take care of it... X */ Xint Xmattacku(mtmp) X register struct monst *mtmp; X{ X struct attack *mattk; X int i, j, tmp, sum[NATTK]; X struct permonst *mdat = mtmp->data; X boolean ranged = (dist(mtmp->mx, mtmp->my) > 3); X /* Is it near you? Affects your actions */ X boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy); X /* Does it think it's near you? Affects its actions */ X boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy); X /* Is it attacking you or your image? */ X boolean youseeit = (cansee(mtmp->mx, mtmp->my)); X /* Necessary since if it's attacking your image around a X * corner, you might not see it X */ X X if(!ranged) nomul(0); X if(mtmp->mhp <= 0) return(0); X X /* If swallowed, can only be affected by u.ustuck */ X if(u.uswallow) { X if(mtmp != u.ustuck) X return(0); X u.ustuck->mux = u.ux; X u.ustuck->muy = u.uy; X range2 = 0; X foundyou = 1; X /* This is not impossible! */ X /* If the swallowing monster changes into a monster X * that is not capable of swallowing you, you get X * regurgitated - dgk X * X * This code is obsolete: newcham() will handle this contingency X * as soon as it occurs in the course of a round. - kcd X * X * for(i = 0; i < NATTK; i++) X * if(mdat->mattk[i].aatyp == AT_ENGL) goto doattack; X * X * You("get regurgitated!"); X * regurgitates(mtmp); X * return(0); X */ X } X/* doattack: use commented out above */ X#ifdef POLYSELF X if (u.uundetected && !range2 && foundyou && !u.uswallow) { X u.uundetected = 0; X if (u.usym == S_PIERCER) { X coord cc; /* maybe we need a unexto() function? */ X X unpmon(mtmp); X remove_monster(mtmp->mx, mtmp->my); X place_monster(mtmp, u.ux, u.uy); X pmon(mtmp); X (void) enexto(&cc, u.ux, u.uy, &playermon); X teleds(cc.x, cc.y); X You("fall from the ceiling!"); X if (is_mercenary(mtmp->data) && m_carrying(mtmp,HELMET)) { X kludge("Your blow glances off %s's helmet.", X mon_nam(mtmp)); X } else { X if (3 + mtmp->data->ac <= rnd(20)) { X kludge("%s is hit by a falling piercer (you)!", X Monnam(mtmp)); X if ((mtmp->mhp -= d(3,6)) < 1) X killed(mtmp); X } else X kludge("%s is almost hit by a falling piercer (you)!", X Monnam(mtmp)); X } X } else { X if (Blind) pline("It tries to move where you are hiding."); X else X pline("Wait, %s! There's a %s named %s hiding under %s!", X mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname, X uasmon->mname, plname, X OBJ_AT(u.ux,u.uy) X ? doname(level.objects[u.ux][u.uy]) : X "some gold"); X prme(); X } X return(0); X } X if (u.usym == S_MIMIC_DEF && !range2 && foundyou && !u.uswallow) { X if (Blind) pline("It gets stuck on you."); X else pline("Wait, %s! That's a %s named %s!", X mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname, X uasmon->mname, plname); X u.ustuck = mtmp; X u.usym = S_MIMIC; X prme(); X return(0); X } X#endif X/* Work out the armor class differential */ X tmp = u.uac + 10; /* tmp ~= 0 - 20 */ X/* give people with Ac < -9 at least some vulnerability */ X/* negative AC gives an actual AC of somewhere from -1 to the AC */ X if (tmp < 10) tmp = 10 - rnd(10-tmp); X tmp += mtmp->m_lev; X if(multi < 0) tmp += 4; X if((Invis && !perceives(mdat)) || !mtmp->mcansee) X tmp -= 2; X if(mtmp->mtrapped) tmp -= 2; X if(tmp <= 0) tmp = 1; X X /* make eels visible the moment they hit/miss us */ X if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) { X mtmp->minvis = 0; X pmon(mtmp); X } X X/* Special demon handling code */ X if(!mtmp->cham && is_demon(mdat) && !range2 X#ifdef INFERNO X && mtmp->data != &mons[PM_BALROG] X && mtmp->data != &mons[PM_SUCCUBUS] X && mtmp->data != &mons[PM_INCUBUS] X#endif X ) X if(!mtmp->mcan && !rn2(13)) dsummon(mdat); X X/* Special lycanthrope handling code */ X if(!mtmp->cham && is_were(mdat) && !range2) { X X if(is_human(mdat)) { X if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp); X } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp); X X if(!rn2(10) && !mtmp->mcan) { X if(!Blind) { X pline("%s summons help!",youseeit ? X Monnam(mtmp) : "It"); X } else X You("feel hemmed in."); X /* Technically wrong; we really should check if you can see the X * help, but close enough... X */ X if (!were_summon(mdat,FALSE) && !Blind) X pline("But none comes."); X } X } X X for(i = 0; i < NATTK; i++) { X X sum[i] = 0; X mattk = &(mdat->mattk[i]); X if (u.uswallow && (mattk->aatyp != AT_ENGL)) X continue; X switch(mattk->aatyp) { X case AT_CLAW: /* "hand to hand" attacks */ X case AT_KICK: X case AT_BITE: X case AT_STNG: X case AT_TUCH: X case AT_BUTT: X if(!range2) { X if (foundyou) { X if(tmp > (j = rnd(20+i))) { X#ifdef POLYSELF X if (mattk->aatyp != AT_KICK || X !thick_skinned(uasmon)) X#endif X sum[i] = hitmu(mtmp, mattk); X } else X missmu(mtmp, (tmp == j), mattk); X } else X wildmiss(mtmp); X } X break; X X case AT_HUGS: /* automatic if prev two attacks succeed */ X /* Note: if displaced, prev attacks never succeeded */ X if((!range2 && i>=2 && sum[i-1] && sum[i-2]) X || mtmp == u.ustuck) X sum[i]= hitmu(mtmp, mattk); X break; X X case AT_GAZE: /* can affect you either ranged or not */ X if (youseeit) X /* not displaced around a corner so not visible */ X sum[i] = gazemu(mtmp, mattk); X break; X X case AT_EXPL: /* automatic hit if next to, and aimed at you */ X if(!range2) { X if (foundyou) X sum[i] = explmu(mtmp, mattk); X else { X if (!mtmp->mcan) { X pline("%s explodes at a spot in thin air!", X youseeit ? Monnam(mtmp) : "It"); X mondead(mtmp); X sum[i] = 2; X } X } X } X break; X X case AT_ENGL: X if (!range2) { X if(foundyou) { X if(u.uswallow || tmp > (j = rnd(20+i))) { X /* Force swallowing monster to be X * displayed even when player is X * moving away */ X nscr(); X sum[i] = gulpmu(mtmp, mattk); X } else { X missmu(mtmp, (tmp == j), mattk); X } X } else if (is_animal(mtmp->data)) X pline("%s gulps some air!", youseeit ? X Monnam(mtmp) : "It"); X else X if (youseeit) X pline("%s lunges forward and recoils!", X Monnam(mtmp)); X else X You("hear a %s nearby.", X is_whirly(mtmp->data)? X "rushing noise" : X "\"splat!\""); X } X break; X case AT_BREA: X if(range2) sum[i] = breamu(mtmp, mattk); X /* Note: breamu takes care of displacement */ X break; X case AT_SPIT: X if(range2) sum[i] = spitmu(mtmp, mattk); X /* Note: spitmu takes care of displacement */ X break; X case AT_WEAP: X if(range2) { X#ifdef REINCARNATION X if (dlevel != rogue_level) X#endif X sum[i] = thrwmu(mtmp); X } else X if (foundyou) { X set_uasmon(); X otmp = select_hwep(mtmp); X if(otmp) { X tmp += hitval(otmp, uasmon); X mswings(mtmp, otmp); X } X if(tmp > (j = rnd(20+i))) X sum[i] = hitmu(mtmp, mattk); X else X missmu(mtmp, (tmp == j), mattk); X } else X wildmiss(mtmp); X break; X case AT_MAGC: X if (range2) X sum[i] = buzzmu(mtmp, mattk); X else X if (foundyou) X sum[i] = castmu(mtmp, mattk); X else X pline("%s casts a spell at thin air!", X youseeit ? Monnam(mtmp) : "It"); X /* Not totally right since castmu allows other X * spells, such as the monster healing itself, X * that should work even when not next to you-- X * but the previous code was just as wrong. X * --KAA X */ X break; X X default: /* no attack */ X break; X } X if(flags.botl) bot(); X if(sum[i] == 2) return(1); /* attacker dead */ X if(sum[i] == 3) break; /* attacker teleported, no more attacks */ X /* sum[i] == 1: successful attack */ X /* sum[i] == 0: unsuccessful attack */ X } X return(0); X} X X#endif /* OVL0 */ X#ifdef OVLB X X/* X * helper function for some compilers that have trouble with hitmu X */ X XSTATIC_OVL Xvoid Xhurtarmor(mdat, attk) Xstruct permonst *mdat; Xint attk; X{ X boolean getbronze, rusting; X int hurt; X X rusting = (attk == AD_RUST); X if (rusting) { X hurt = 1; X getbronze = (mdat == &mons[PM_BLACK_PUDDING] && X uarm && is_corrodeable(uarm)); X } X else { X hurt=2; X getbronze = FALSE; X } X /* What the following code does: it keeps looping until it X * finds a target for the rust monster. X * Head, feet, etc... not covered by metal, or covered by X * rusty metal, are not targets. However, your body always X * is, no matter what covers it. X */ X while (1) { X switch(rn2(5)) { X case 0: X if (!rust_dmg(uarmh, rusting ? "helmet" : "leather helmet", X hurt, FALSE)) X continue; X break; X case 1: X if (uarmc) break; X /* Note the difference between break and continue; X * break means it was hit and didn't rust; continue X * means it wasn't a target and though it didn't rust X * something else did. X */ X if (getbronze) X (void)rust_dmg(uarm, "bronze armor", 3, TRUE); X else if (uarm) X (void)rust_dmg(uarm, xname(uarm), hurt, TRUE); X break; X case 2: X if (!rust_dmg(uarms, rusting ? "shield" : "wooden shield", X hurt, FALSE)) X continue; X break; X case 3: X if (!rust_dmg(uarmg, rusting ? "metal gauntlets" : "gloves", X hurt, FALSE)) X continue; X break; X case 4: X if (!rust_dmg(uarmf, rusting ? "metal boots" : "boots", X hurt, FALSE)) X continue; X break; X } X break; /* Out of while loop */ X } X} X X#endif /* OVLB */ X#ifdef OVL1 X X/* X * hitmu: monster hits you X * returns 2 if monster dies (e.g. "yellow light"), 1 otherwise X * 3 if the monster lives but teleported/paralyzed, so it can't keep X * attacking you X */ XSTATIC_OVL Xint Xhitmu(mtmp, mattk) X register struct monst *mtmp; X register struct attack *mattk; X{ X register struct permonst *mdat = mtmp->data; X register int dmg, ctmp, ptmp; X int armpro; X char buf[BUFSZ]; X#ifdef POLYSELF X struct permonst *olduasmon = uasmon; X int res; X#endif X X/* If the monster is undetected & hits you. You should know where X * the attack came from. X */ X if(mtmp->mhide && mtmp->mundetected) { X mtmp->mundetected = 0; X if(!(Blind ? Telepat : (HTelepat & WORN_HELMET))) { X register struct obj *obj; X X if(OBJ_AT(mtmp->mx, mtmp->my)) { X if(obj = level.objects[mtmp->mx][mtmp->my]) X pline("%s was hidden under %s!", X Xmonnam(mtmp), doname(obj)); X } else if (levl[mtmp->mx][mtmp->my].gmask == 1) X pline("%s was hidden under some gold!", X Xmonnam(mtmp)); X } X } X X/* First determine the base damage done */ X dmg = d((int)mattk->damn, (int)mattk->damd); X if(is_undead(mdat) && midnight()) X dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */ X X/* Next a cancellation factor */ X/* Use ctmp when the cancellation factor takes into account certain X * armor's special magic protection. Otherwise just use !mtmp->mcan. X */ X armpro = 0; X if (uarm && armpro < objects[uarm->otyp].a_can) X armpro = objects[uarm->otyp].a_can; X if (uarmc && armpro < objects[uarmc->otyp].a_can) X armpro = objects[uarmc->otyp].a_can; X ctmp = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50)); X X/* Now, adjust damages via resistances or specific attacks */ X switch(mattk->adtyp) { X case AD_PHYS: X if(mattk->aatyp == AT_HUGS X#ifdef POLYSELF X && !sticks(uasmon) X#endif X ) { X if(!u.ustuck && rn2(2)) { X u.ustuck = mtmp; X kludge("%s grabs you!", Monnam(mtmp)); X } else if(u.ustuck == mtmp) X You("are being %s.", X#ifdef GOLEMS X (mtmp->data == &mons[PM_ROPE_GOLEM]) X ? "choked" : X#endif /* GOLEMS */ X "crushed"); X X } else { /* hand to hand weapon */ X hitmsg(mtmp, mattk); X if(mattk->aatyp == AT_WEAP && otmp) { X dmg += dmgval(otmp, uasmon); X if (dmg <= 0) dmg = 1; X#ifdef NAMED_ITEMS X if (spec_ability(otmp, SPFX_DRLI) X# ifdef POLYSELF X && !resists_drli(uasmon) X# endif X ) { X if (Blind) X You("feel an unholy blade drain your life!"); X else X pline("The %s blade drains your life!", X Hallucination ? hcolor() : black); X losexp(); X } X#endif X#ifdef POLYSELF X if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) && X (u.umonnum==PM_BLACK_PUDDING X || u.umonnum==PM_BROWN_PUDDING)) { X /* This redundancy necessary because you have to X * take the damage _before_ being cloned. X */ X if (u.uac < 0) dmg += u.uac; X if (dmg < 1) dmg = 1; X u.mh -= dmg; X flags.botl = 1; X dmg = 0; X if(cloneu()) X kludge("You divide as %s hits you!",mon_nam(mtmp)); X } X urustm(mtmp, otmp); X#endif X } X } X break; X case AD_DISE: X hitmsg(mtmp, mattk); X#ifdef POLYSELF X if (u.usym == S_FUNGUS) X You("feel a slight illness."); X else X#endif X You("feel very sick."); X make_sick((long)rn1(25-ACURR(A_CON),15),FALSE); X u.usick_cause = mdat->mname; X break; X case AD_FIRE: X hitmsg(mtmp, mattk); X if(ctmp) { X pline("You're on fire!"); X if (Fire_resistance) { X pline("The fire doesn't feel hot!"); X dmg = 0; X } X if(mtmp->m_lev > rn2(20)) X destroy_item(SCROLL_SYM, AD_FIRE); X if(mtmp->m_lev > rn2(20)) X destroy_item(POTION_SYM, AD_FIRE); X#ifdef SPELLS X if(mtmp->m_lev > rn2(25)) X destroy_item(SPBOOK_SYM, AD_FIRE); X#endif X } else dmg = 0; X break; X case AD_COLD: X hitmsg(mtmp, mattk); X if(ctmp) { X pline("You're covered in frost!"); X if (Cold_resistance) { X pline("The frost doesn't seem cold!"); X dmg = 0; X } X if(mtmp->m_lev > rn2(20)) X destroy_item(POTION_SYM, AD_COLD); X } else dmg = 0; X break; X case AD_ELEC: X hitmsg(mtmp, mattk); X if(ctmp) { X You("get zapped!"); X if (Shock_resistance) { X pline("The zap doesn't shock you!"); X dmg = 0; X } X if(mtmp->m_lev > rn2(20)) X destroy_item(WAND_SYM, AD_ELEC); X if(mtmp->m_lev > rn2(20)) X destroy_item(RING_SYM, AD_ELEC); X } else dmg = 0; X break; X case AD_SLEE: X hitmsg(mtmp, mattk); X if(ctmp && multi >= 0 && !rn2(5)) { X if (Sleep_resistance) break; X nomul(-rnd(10)); X if (Blind) You("are put to sleep!"); X else You("are put to sleep by %s!",mon_nam(mtmp)); X } X break; X case AD_DRST: X ptmp = A_STR; X goto dopois; X case AD_DRDX: X ptmp = A_DEX; X goto dopois; X case AD_DRCO: X ptmp = A_CON; Xdopois: X hitmsg(mtmp, mattk); X if(ctmp && !rn2(8)) { X Sprintf(buf, "%s's %s", X Hallucination ? rndmonnam() : mdat->mname, X (mattk->aatyp == AT_BITE) ? "bite" : "sting"); X poisoned(buf, ptmp, mdat->mname, 30); X } X break; X case AD_PLYS: X hitmsg(mtmp, mattk); X if(ctmp && multi >= 0 && !rn2(3)) { X if (Blind) You("are frozen!"); X else You("are frozen by %s!", mon_nam(mtmp)); X nomul(-rnd(10)); X } X break; X case AD_DRLI: X hitmsg(mtmp, mattk); X if (ctmp && !rn2(3) X#ifdef POLYSELF X && !resists_drli(uasmon) X#endif X#ifdef NAMED_ITEMS X && !defends(AD_DRLI, uwep) X#endif X ) losexp(); X break; X case AD_LEGS: X { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; X if (mtmp->mcan) { X kludge("%s nuzzles against your %s %s!", Monnam(mtmp), X (side == RIGHT_SIDE) ? "right" : "left", X body_part(LEG)); X } else { X if (uarmf) { X kludge("%s scratches your %s boot!", Monnam(mtmp), X (side == RIGHT_SIDE) ? "right" : "left"); X break; X } X kludge("%s pricks your %s %s!", Monnam(mtmp), X (side == RIGHT_SIDE) ? "right" : "left", X body_part(LEG)); X set_wounded_legs(side, rnd(60-ACURR(A_DEX))); X } X break; X } X case AD_STON: /* at present only a cockatrice */ X hitmsg(mtmp, mattk); X if(!rn2(3) && !Stoned) { X if (mtmp->mcan) { X if (flags.soundok) X You("hear a cough from %s!", Blind ? "it" X : mon_nam(mtmp)); X } else { X if (flags.soundok) X if (Blind) You("hear its hissing!"); X else You("hear %s's hissing!", mon_nam(mtmp)); X if((!rn2(10) || X (flags.moonphase == NEW_MOON && !have_lizard())) X#ifdef POLYSELF X && !resists_ston(uasmon) X#endif X ) { X Stoned = 5; X return(1); X /* You("turn to stone..."); */ X /* done_in_by(mtmp); */ X } X } X } X break; X case AD_STCK: X hitmsg(mtmp, mattk); X if(ctmp && !u.ustuck X#ifdef POLYSELF X && !sticks(uasmon) X#endif X ) u.ustuck = mtmp; X break; X case AD_WRAP: X if(ctmp X#ifdef POLYSELF X && !sticks(uasmon) X#endif X ) { X if(!u.ustuck && !rn2(10)) { X kludge("%s swings itself around you!", Monnam(mtmp)); X u.ustuck = mtmp; X } else if(u.ustuck == mtmp) { X if (is_pool(mtmp->mx,mtmp->my) X#ifdef POLYSELF X && !is_swimmer(uasmon) X#endif X ) { X kludge("%s drowns you...", Monnam(mtmp)); X done(DROWNING); X } else if(mattk->aatyp == AT_HUGS) X You("are being crushed."); X } else dmg = 0; X } else dmg = 0; X break; X case AD_WERE: X hitmsg(mtmp, mattk); X#ifdef POLYSELF X if (ctmp && !rn2(4) && u.ulycn == -1 X && !Protection_from_shape_changers X# ifdef NAMED_ITEMS X && !defends(AD_WERE,uwep) X# endif X ) { X You("feel feverish."); X u.ulycn = monsndx(mdat); X } X#endif X break; X case AD_SGLD: X hitmsg(mtmp, mattk); X#ifdef POLYSELF X if (u.usym == mdat->mlet) break; X#endif X if(!mtmp->mcan) stealgold(mtmp); X break; X X case AD_SITM: /* for now these are the same */ X case AD_SEDU: X#ifdef POLYSELF X if (dmgtype(uasmon, AD_SEDU) X# ifdef SEDUCE X || dmgtype(uasmon, AD_SSEX) X# endif X ) { X if (mtmp->minvent) X kludge("%s brags about the goods some dungeon explorer provided.", X Monnam(mtmp)); X else X kludge("%s makes some remarks about how difficult theft is lately.", X Monnam(mtmp)); X rloc(mtmp); X return 3; X } else X#endif X if(mtmp->mcan) { X if (!Blind) { X pline("%s tries to %s you, but you seem %s.", X Amonnam(mtmp, "plain"), X flags.female ? "charm" : "seduce", X flags.female ? "unaffected" : "uninterested"); X } X if(rn2(3)) { X rloc(mtmp); X return 3; X } X } else { X switch (steal(mtmp)) { X case -1: X return 2; X case 0: X break; X default: X rloc(mtmp); X mtmp->mflee = 1; X return 3; X } X } X break; X#ifdef SEDUCE X case AD_SSEX: X if(could_seduce(mtmp, &youmonst, mattk) == 1 X && !mtmp->mcan) X if (doseduce(mtmp)) X return 3; X break; X#endif X case AD_SAMU: X hitmsg(mtmp, mattk); X /* when the Wiz hits, 1/20 steals the amulet */ X if (!carrying(AMULET_OF_YENDOR)) break; X if (!rn2(20)) stealamulet(mtmp); X break; X X case AD_TLPT: X hitmsg(mtmp, mattk); X if(ctmp) { X if(flags.verbose) X Your("position suddenly seems very uncertain!"); X tele(); X } X break; X case AD_RUST: X hitmsg(mtmp, mattk); X if (mtmp->mcan) break; X#if defined(POLYSELF) && defined(GOLEMS) X if (u.umonnum == PM_IRON_GOLEM) { X You("rust!"); X rehumanize(); X break; X } X#endif X hurtarmor(mdat, AD_RUST); X break; X case AD_DCAY: X hitmsg(mtmp, mattk); X if (mtmp->mcan) break; X#if defined(POLYSELF) && defined(GOLEMS) X if (u.umonnum == PM_WOOD_GOLEM || X u.umonnum == PM_LEATHER_GOLEM) { X You("rot!"); X rehumanize(); X break; X } X#endif X hurtarmor(mdat, AD_DCAY); X break; X case AD_HEAL: X if(!uwep X#ifdef SHIRT X && !uarmu X#endif X && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) { X kludge("%s hits! (I hope you don't mind.)", Monnam(mtmp)); X#ifdef POLYSELF X if (u.mtimedone) { X u.mh += rnd(7); X if(!rn2(7)) u.mhmax++; X if(u.mh > u.mhmax) u.mh = u.mhmax; X if(u.mh == u.mhmax && !rn2(50)) mongone(mtmp); X } else { X#endif X u.uhp += rnd(7); X if(!rn2(7)) u.uhpmax++; X if(u.uhp > u.uhpmax) u.uhp = u.uhpmax; X if(u.uhp == u.uhpmax && !rn2(50)) mongone(mtmp); X#ifdef POLYSELF X } X#endif X flags.botl = 1; X if(!rn2(50)) rloc(mtmp); X dmg = 0; X } else X if(pl_character[0] == 'H') { X if (flags.soundok && !(moves % 5)) X verbalize("Doc, I can't help you unless you cooperate."); X dmg = 0; X } else hitmsg(mtmp, mattk); X break; X case AD_CURS: X hitmsg(mtmp, mattk); X if(!night() && mdat == &mons[PM_GREMLIN]) break; X if(!mtmp->mcan && !rn2(10)) { X if (flags.soundok) X if (Blind) You("hear laughter."); X else pline("%s chuckles.", Monnam(mtmp)); X#ifdef POLYSELF X#ifdef GOLEMS X if (u.umonnum == PM_CLAY_GOLEM) { X pline("Some writing vanishes from your head!"); X rehumanize(); X break; X } X#endif /* GOLEMS */ X#endif X attrcurse(); X } X break; X case AD_STUN: X hitmsg(mtmp, mattk); X if(!mtmp->mcan && !rn2(4)) { X make_stunned(HStun + dmg, TRUE); X dmg /= 2; X } X break; X case AD_ACID: X hitmsg(mtmp, mattk); X if(!mtmp->mcan && !rn2(3)) X#ifdef POLYSELF X if (resists_acid(uasmon)) { X pline("You're covered in acid, but it seems harmless."); X dmg = 0; X } else X#endif X pline("You're covered in acid! It burns!"); X else dmg = 0; X break; X case AD_SLOW: X hitmsg(mtmp, mattk); X if(!ctmp && (Fast & (INTRINSIC|TIMEOUT)) && !rn2(4)) { X Fast &= ~(INTRINSIC|TIMEOUT); X You("feel yourself slowing down."); X } X break; X case AD_DREN: X hitmsg(mtmp, mattk); X#ifdef SPELLS X if(!ctmp && !rn2(4)) drain_en(dmg); X#endif X dmg = 0; X break; X#ifdef INFERNO /* a non-gaze AD_CONF exists only for one of the demons */ X case AD_CONF: X hitmsg(mtmp, mattk); X if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { X mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6)); X if(Confusion) X You("are getting even more confused."); X else You("are getting confused."); X make_confused(HConfusion + dmg, FALSE); X } X#endif X /* fall through to next case */ X default: dmg = 0; X break; X } X if(u.uhp < 1) done_in_by(mtmp); X X/* Negative armor class reduces damage done instead of fully protecting X * against hits. X */ X if (dmg && u.uac < 0) { X dmg -= rnd(-u.uac); X if (dmg < 1) dmg = 1; X } X X if(dmg) mdamageu(mtmp, dmg); X X#ifdef POLYSELF X res = passiveum(olduasmon, mtmp, mattk); X stop_occupation(); X return res; X#else X stop_occupation(); X return 1; X#endif X} X X#endif /* OVL1 */ X#ifdef OVLB X XSTATIC_OVL Xint Xgulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */ X register struct monst *mtmp; X register struct attack *mattk; X{ X int tmp = d((int)mattk->damn, (int)mattk->damd); X int tim_tmp; X#ifdef WALKIES X int i; X#endif X X if(!u.uswallow) { /* swallows you */ X#ifdef POLYSELF X if (uasmon->msize >= MZ_HUGE) return(0); X#endif X remove_monster(mtmp->mx, mtmp->my); X place_monster(mtmp, u.ux, u.uy); X u.ustuck = mtmp; X pmon(mtmp); X kludge("%s engulfs you!", Monnam(mtmp)); X stop_occupation(); X if (u.utrap) { X You("are released from the %s!", X u.utraptype==TT_WEB ? "web" : "trap"); X u.utrap = 0; X } X#ifdef WALKIES X if((i = number_leashed()) > 0) { X pline("The leash%s snap%s loose...", X (i > 1) ? "es" : "", X (i > 1) ? "" : "s"); X unleash_all(); X } X#endif X#ifdef POLYSELF X if (u.umonnum==PM_COCKATRICE && !resists_ston(mtmp->data)) { X kludge("%s turns to stone!", Monnam(mtmp)); X stoned = 1; X xkilled(mtmp, 0); X return 2; X } X#endif X more(); X seeoff(1); X u.uswallow = 1; X /*assume that u.uswldtim always set >=0*/ X u.uswldtim = (tim_tmp = X (-u.uac + 10 + rnd(25 - (int)mtmp->m_lev)) >> 1) > 0 ? X tim_tmp : 0; X swallowed(1); X } else { X X if(mtmp != u.ustuck) return(0); X switch(mattk->adtyp) { X X case AD_DGST: X if(!u.uswldtim) { /* a3 *//*no cf unsigned <=0*/ X kludge("%s totally digests you!", Monnam(mtmp)); X tmp = u.uhp; X } else { X kludge("%s digests you!", Monnam(mtmp)); X } X break; X case AD_PHYS: X You("are pummeled with debris!"); X break; X case AD_ACID: X#ifdef POLYSELF X if (resists_acid(uasmon)) { X You("are covered with a seemingly harmless goo."); X tmp = 0; X } else X#endif X if (Hallucination) pline("Ouch! You've been slimed!"); X else You("are covered in slime! It burns!"); X break; X case AD_BLND: X if(!Blind) { X You("can't see in here!"); X make_blinded((long)tmp,FALSE); X } else make_blinded(Blinded+1,FALSE); /* keep him blind until disgorged */ X tmp = 0; X break; X case AD_ELEC: X if(!mtmp->mcan && rn2(2)) { X pline("The air around you crackles with electricity."); X if (Shock_resistance) { X shieldeff(u.ux, u.uy); X You("seem unhurt."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_ELEC,tmp); X#endif X tmp = 0; X } X } else tmp = 0; X break; X case AD_COLD: X if(!mtmp->mcan && rn2(2)) { X if (Cold_resistance) { X shieldeff(u.ux, u.uy); X You("feel mildly chilly."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_COLD,tmp); X#endif X tmp = 0; X } else You("are freezing to death!"); X } else tmp = 0; X break; X case AD_FIRE: X if(!mtmp->mcan && rn2(2)) { X if (Fire_resistance) { X shieldeff(u.ux, u.uy); X You("feel mildly hot."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_FIRE,tmp); X#endif X tmp = 0; X } else You("are burning to a crisp!"); X } else tmp = 0; X break; X#ifdef INFERNO X case AD_DISE: X if (!Sick) You("feel very sick."); X make_sick(Sick + (long)rn1(25-ACURR(A_CON),15),FALSE); X u.usick_cause = mtmp->data->mname; X break; X#endif X default: tmp = 0; X break; X } X } X X mdamageu(mtmp, tmp); X if(tmp) stop_occupation(); X if(u.uswldtim) --u.uswldtim; X if(!u.uswldtim X#ifdef POLYSELF X || u.umonnum==PM_COCKATRICE X || uasmon->msize >= MZ_HUGE X#endif X ) { X#ifdef POLYSELF X if (u.umonnum == PM_COCKATRICE) { X kludge("%s very hurriedly %s you!", Monnam(mtmp), X is_animal(mtmp->data)? "regurgitates" : "expels"); X u.uswldtim = 0; X } else { X#endif X You("get %s!", X is_animal(mtmp->data)? "regurgitated" : "expelled"); X if(flags.verbose && is_animal(mtmp->data)) X kludge("Obviously %s doesn't like your taste.", X mon_nam(mtmp)); X#ifdef POLYSELF X } X#endif X expels(mtmp, mtmp->data, FALSE); X } X return(1); X} X XSTATIC_OVL Xint Xexplmu(mtmp, mattk) /* monster explodes in your face */ X register struct monst *mtmp; X register struct attack *mattk; X{ X register int tmp = d((int)mattk->damn, (int)mattk->damd); X X if(mtmp->mcan) return(0); X if(!Blind) kludge("%s explodes!", Monnam(mtmp)); X else pline("It explodes!"); X X switch(mattk->adtyp) { X case AD_COLD: X if(Cold_resistance) { X You("seem unaffected by it."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_COLD,tmp); X#endif X tmp = 0; X } else { X if(ACURR(A_DEX) > rnd(20)) { X if (flags.verbose) X You("get blasted!"); X } else { X You("duck the blast..."); X tmp /= 2; X } X } X break; X case AD_BLND: X if(!Blind X#ifdef POLYSELF X && u.usym != S_YLIGHT X#endif X ) { X You("are blinded by a blast of light!"); X make_blinded((long)tmp,FALSE); X } X tmp = 0; X break; X default: break; X } X mdamageu(mtmp, tmp); X mondead(mtmp); X return(2); /* it dies */ X} X XSTATIC_OVL Xint Xgazemu(mtmp, mattk) /* monster gazes at you */ X register struct monst *mtmp; X register struct attack *mattk; X{ X switch(mattk->adtyp) { X#ifdef MEDUSA X case AD_STON: X if (mtmp->mcan) { X You("notice that %s isn't all that ugly.",mon_nam(mtmp)); X break; X } X if (canseemon(mtmp)) { X You("look upon %s.", mon_nam(mtmp)); X# ifdef POLYSELF X if (resists_ston(uasmon)) { X pline("So what?"); X break; X } X# endif X You("turn to stone..."); X killer_format = KILLED_BY_AN; X killer = mons[PM_MEDUSA].mname; X done(STONING); X } X break; X#endif X case AD_CONF: X if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && X !mtmp->mspec_used && rn2(5)) { X int conf = d(3,4); X X mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6)); X if(!Confusion) X pline("%s's gaze confuses you!", Monnam(mtmp)); X else X You("are getting more and more confused."); X make_confused(HConfusion + conf, FALSE); X } X break; X#ifdef INFERNO X case AD_STUN: X if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && X !mtmp->mspec_used && rn2(5)) { X int stun = d(2,6); X X pline("%s stares piercingly at you!", Monnam(mtmp)); X mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6)); X make_stunned(HStun + stun, TRUE); X } X break; X#endif X default: impossible("Gaze attack %d?", mattk->adtyp); X break; X } X return(1); X} X X#endif /* OVLB */ X#ifdef OVL1 X Xvoid Xmdamageu(mtmp, n) /* mtmp hits you for n points damage */ X register struct monst *mtmp; X register int n; X{ X#ifdef POLYSELF X if (u.mtimedone) { X u.mh -= n; X flags.botl = 1; X if (u.mh < 1) rehumanize(); X return; X } X#endif X u.uhp -= n; X flags.botl = 1; X if(u.uhp < 1) X done_in_by(mtmp); X} X X#endif /* OVL1 */ X#ifdef OVLB X X#ifdef POLYSELF XSTATIC_OVL void Xurustm(mon, obj) Xregister struct monst *mon; Xregister struct obj *obj; X{ X boolean vis = cansee(mon->mx, mon->my); X X if (!mon || !obj) return; /* just in case */ X if (u.umonnum == PM_RUST_MONSTER && X objects[obj->otyp].oc_material == METAL && X obj->spe > -2) { X if(obj->rustfree) { X if (vis) X pline("The rust vanishes from %s's weapon!", X mon_nam(mon)); X } else if(obj->blessed && rn2(3)) { X if (vis) X pline("Somehow, %s's weapon is not affected!", X mon_nam(mon)); X } else { X if (vis) X pline("%s's %s!", Monnam(mon), aobjnam(obj,"corrode")); X obj->spe--; X } X } X} X#endif X X#endif /* OVLB */ X#ifdef OVL1 X Xint Xcould_seduce(magr,mdef,mattk) Xstruct monst *magr, *mdef; Xstruct attack *mattk; X/* returns 0 if seduction impossible, X * 1 if fine, X * 2 if wrong gender for nymph */ X{ X register struct permonst *pagr, *pdef; X boolean agrinvis, defperc; X xchar genagr, gendef; X X if(magr == &youmonst) { X pagr = uasmon; X agrinvis = (Invis != 0); X genagr = poly_gender(); X } else { X pagr = magr->data; X agrinvis = magr->minvis; X genagr = gender(magr); X } X if(mdef == &youmonst) { X pdef = uasmon; X defperc = (See_invisible != 0); X gendef = poly_gender(); X } else { X pdef = mdef->data; X defperc = perceives(pdef); X gendef = gender(mdef); X } X X if(agrinvis && !defperc X#ifdef SEDUCE X && mattk && mattk->adtyp != AD_SSEX X#endif X ) X return 0; X X if(pagr->mlet != S_NYMPH X#ifdef INFERNO X && ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) X# ifdef SEDUCE X || (mattk && mattk->adtyp != AD_SSEX) X# endif X ) X#endif X ) X return 0; X X if(genagr == 1 - gendef) X return 1; X else X return (pagr->mlet == S_NYMPH) ? 2 : 0; X} X X#endif /* OVL1 */ X#ifdef OVLB X X#ifdef SEDUCE X/* Returns 1 if monster teleported */ Xint Xdoseduce(mon) Xregister struct monst *mon; X{ X register struct obj *ring; X boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ X X if (mon->mcan || mon->mspec_used) { X pline("%s acts as though %s has got a %sheadache.", X Blind ? "It" : Monnam(mon), Blind ? "it" : X fem ? "she" : "he", X mon->mcan ? "severe " : ""); X return 0; X } X X if (unconscious()) { X kludge("%s seems dismayed at your lack of response.", X Monnam(mon)); X return 0; X } X X if (Blind) pline("It caresses you..."); X else You("feel very attracted to %s.", mon_nam(mon)); X X for(ring = invent; ring; ring = ring->nobj) { X if (ring->otyp != RIN_ADORNMENT) continue; X if (fem) { X if (rn2(20) < ACURR(A_CHA)) { X pline("\"That %s looks pretty. May I have it?\" ", X xname(ring)); X makeknown(RIN_ADORNMENT); X if (yn() == 'n') continue; X } else pline("%s decides she'd like your %s, and takes it.", X Blind ? "She" : Monnam(mon), xname(ring)); X makeknown(RIN_ADORNMENT); X if (ring==uleft || ring==uright) Ring_gone(ring); X if (ring==uwep) setuwep((struct obj *)0); X freeinv(ring); X mpickobj(mon,ring); X } else { X char buf[BUFSZ]; X X if (uleft && uright && uleft->otyp == RIN_ADORNMENT X && uright->otyp==RIN_ADORNMENT) X break; X if (ring==uleft || ring==uright) continue; X if (rn2(20) < ACURR(A_CHA)) { X pline("\"That %s looks pretty. Would you wear it for me?\" ", X xname(ring)); X makeknown(RIN_ADORNMENT); X if (yn() == 'n') continue; X } else { X pline("%s decides you'd look prettier wearing your %s,", X Blind ? "He" : Monnam(mon), xname(ring)); X pline("and puts it on your finger."); X } X makeknown(RIN_ADORNMENT); X if (!uright) { X pline("%s puts the %s on your right hand.", X Blind ? "He" : Monnam(mon), xname(ring)); X setworn(ring, RIGHT_RING); X } else if (!uleft) { X pline("%s puts the %s on your left hand.", X Blind ? "He" : Monnam(mon), xname(ring)); X setworn(ring, LEFT_RING); X } else if (uright && uright->otyp != RIN_ADORNMENT) { X Strcpy(buf, xname(uright)); X pline("%s replaces your %s with your %s.", X Blind ? "He" : Monnam(mon), buf, xname(ring)); X Ring_gone(uright); X setworn(ring, RIGHT_RING); X } else if (uleft && uleft->otyp != RIN_ADORNMENT) { X Strcpy(buf, xname(uleft)); X pline("%s replaces your %s with your %s.", X Blind ? "He" : Monnam(mon), buf, xname(ring)); X Ring_gone(uleft); X setworn(ring, LEFT_RING); X } else impossible("ring replacement"); X Ring_on(ring); X prinv(ring); X } X } X X if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh X#ifdef SHIRT X && !uarmu X#endif X ) X pline("%s murmurs sweet nothings into your ear.", X Blind ? (fem ? "She" : "He") : Monnam(mon)); X else X pline("%s murmurs in your ear, while helping you undress.", X Blind ? (fem ? "She" : "He") : Monnam(mon)); X mayberem(uarmc, "cloak"); X if(!uarmc) X mayberem(uarm, "suit"); X mayberem(uarmf, "boots"); X mayberem(uarmg, "gloves"); X mayberem(uarms, "shield"); X mayberem(uarmh, "helmet"); X#ifdef SHIRT X if(!uarmc && !uarm) X mayberem(uarmu, "shirt"); X#endif X X if (uarm || uarmc) { X pline("\"You're such a %s; I wish...\"", X flags.female ? "sweet lady" : "nice guy"); X rloc(mon); X return 1; X } X#define ALIGNLIM (5L + (moves/200L)) /* from pray.c */ X if (u.ualigntyp == U_CHAOTIC && u.ualign < ALIGNLIM) u.ualign++; X X /* by this point you have discovered mon's identity, blind or not... */ X pline("Time stands still while you and %s lie in each other's arms...", X mon_nam(mon)); X if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { X /* Don't bother with mspec_used here... it didn't get tired! */ X pline("%s seems to have enjoyed it more than you...", X Monnam(mon)); X#ifdef SPELLS X switch (rn2(5)) { X case 0: You("feel drained of energy."); X u.uen = 0; X u.uenmax -= rnd(10); X if (u.uenmax < 0) u.uenmax = 0; X break; X#else X switch (rnd(4)) { X#endif X case 1: You("are down in the dumps."); X adjattrib(A_CON, -1, TRUE); X flags.botl = 1; X break; X case 2: Your("senses are dulled."); X adjattrib(A_WIS, -1, TRUE); X flags.botl = 1; X break; X case 3: X#ifdef POLYSELF X if (resists_drli(uasmon)) X You("have a curious feeling..."); X else { X#endif X You("feel out of shape."); X losexp(); X if(u.uhp <= 0) { X killer_format = KILLED_BY; X killer = "overexertion"; X done(DIED); X } X#ifdef POLYSELF X } X#endif X break; X case 4: You("feel exhausted."); X losehp(5+rnd(10), "exhaustion", KILLED_BY); X break; X } X } else { X mon->mspec_used = rnd(100); /* monster is worn out */ X You("seem to have enjoyed it more than %s...", mon_nam(mon)); X#ifdef SPELLS X switch (rn2(5)) { X case 0: You("feel raised to your full potential."); X u.uen = (u.uenmax += rnd(5)); X break; X#else X switch (rnd(4)) { X#endif X case 1: You("feel good enough to do it again."); X adjattrib(A_CON, 1, TRUE); X flags.botl = 1; X break; X case 2: You("will always remember %s...", mon_nam(mon)); X adjattrib(A_WIS, 1, TRUE); X flags.botl = 1; X break; X case 3: pline("That was a very educational experience."); X pluslvl(); X break; X case 4: You("feel restored to health!"); X u.uhp = u.uhpmax; X#ifdef POLYSELF X if (u.mtimedone) u.mh = u.mhmax; X#endif X flags.botl = 1; X break; X } X } X X if (mon->mtame) /* don't charge */ ; X else if (rn2(20) < ACURR(A_CHA)) { X pline("%s demands that you pay %s, but you refuse...", X Monnam(mon), (fem ? "her" : "him")); X } X#ifdef POLYSELF X else if (u.umonnum == PM_LEPRECHAUN) X pline("%s tries to take your money, but fails...", X Monnam(mon)); X#endif X else { X long cost = (long)rnd( X (int)(u.ugold > 32757L ? 32757 : u.ugold) +10) + 500; X X if (mon->mpeaceful) { X cost /= 5; X if (!cost) cost=1; X } X if (cost > u.ugold) cost = u.ugold; X if (!cost) verbalize("It's on the house!"); X else { X pline("%s takes %ld zorkmid%s for services rendered!", X Monnam(mon), cost, plur(cost)); X u.ugold -= cost; X mon->mgold += cost; X flags.botl = 1; X } X } X if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ X rloc(mon); X return 1; X} X Xstatic void Xmayberem(obj, str) Xregister struct obj *obj; Xconst char *str; X{ X if (!obj || !obj->owornmask) return; X X if (rn2(20) < ACURR(A_CHA)) { X pline("\"Shall I remove your %s, %s?\" ", X str, X (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); X if (yn() == 'n') return; X } else pline("\"Take off your %s; %s.\"", str, X (obj == uarm) ? "let's get a little closer" : X (obj == uarmc || obj == uarms) ? "it's in the way" : X (obj == uarmf) ? "let me rub your feet" : X (obj == uarmg) ? "they're too clumsy" : X#ifdef SHIRT X (obj == uarmu) ? "let me massage you" : X#endif X /* obj == uarmh */ X "let me run my fingers through your hair"); X X if (donning(obj)) cancel_don(); X if (obj == uarm) (void) Armor_off(); X else if (obj == uarmc) (void) Cloak_off(); X else if (obj == uarmf) (void) Boots_off(); X else if (obj == uarmg) (void) Gloves_off(); X else if (obj == uarmh) (void) Helmet_off(); X else setworn((struct obj *)0, obj->owornmask & W_ARMOR); X} X#endif /* SEDUCE */ X X#endif /* OVLB */ X X#ifdef POLYSELF X X#ifdef OVL1 X Xstatic int Xpassiveum(olduasmon,mtmp,mattk) Xstruct permonst *olduasmon; Xregister struct monst *mtmp; Xregister struct attack *mattk; X{ X register struct permonst *mdat = mtmp->data; X int i; X int dam = 0; X X for(i = 0; ; i++) { X if(i >= NATTK) return 1; X if(olduasmon->mattk[i].aatyp == AT_NONE) break; X } X X /* These affect the enemy even if you were "killed" (rehumanized) */ X switch(olduasmon->mattk[i].adtyp) { X case AD_ACID: X if (!rn2(2)) { X kludge("%s is splashed by your acid!", Monnam(mtmp)); X if(!resists_acid(mdat)) X dam = d((int)olduasmon->mlevel+1, X (int)olduasmon->mattk[i].damd); X else pline("%s is not affected.", Monnam(mtmp)); X } X break; X case AD_STON: /* cockatrice */ X if (!resists_ston(mdat) && X (mattk->aatyp != AT_WEAP || !select_hwep(mtmp)) && X mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL && X mattk->aatyp != AT_MAGC && X (!is_mercenary(mdat) || X !m_carrying(mtmp, LEATHER_GLOVES))) { X kludge("%s turns to stone!", Monnam(mtmp)); X stoned = 1; X xkilled(mtmp, 0); X return 2; X } X default: X break; X } X if (!u.mtimedone) return 1; X X /* These affect the enemy only if you are still a monster */ X if (rn2(3)) switch(uasmon->mattk[i].adtyp) { X case AD_PLYS: /* Floating eye */ X {int tmp = d((int)uasmon->mlevel+1, (int)uasmon->mattk[i].damd); X if (u.umonnum == PM_FLOATING_EYE) { X if (!rn2(4)) tmp = 120; X if (mtmp->mcansee && rn2(3) && X (perceives(mdat) || !Invis)) { X if (Blind) X pline("As a blind %s, you cannot defend yourself.", X uasmon->mname); X else { X pline("%s is frozen by your gaze!", Monnam(mtmp)); X mtmp->mcanmove = 0; X mtmp->mfrozen = tmp; X return 3; X } X } X } else { /* gelatinous cube */ X kludge("%s is frozen by you.", Monnam(mtmp)); X mtmp->mcanmove = 0; X mtmp->mfrozen = tmp; X return 3; X } X break; X } X case AD_COLD: /* Brown mold or blue jelly */ X dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[i].damd); X if(resists_cold(mdat)) { X shieldeff(mtmp->mx, mtmp->my); X kludge("%s is mildly chilly.", Monnam(mtmp)); X#ifdef GOLEMS X golemeffects(mtmp, AD_COLD, dam); X#endif /* GOLEMS */ X dam = 0; X break; X } X kludge("%s is suddenly very cold!", Monnam(mtmp)); X u.mh += dam / 2; X if (u.mhmax < u.mh) u.mhmax = u.mh; X if (u.mhmax > ((uasmon->mlevel+1) * 8)) { X register struct monst *mon; X X if (mon = cloneu()) { X mon->mhpmax = u.mhmax /= 2; X if (Blind) X You("multiply from its heat!"); X else X You("multiply from %s's heat!", mon_nam(mtmp)); X } X } X break; X case AD_STUN: /* Yellow mold */ X if (!mtmp->mstun) { X mtmp->mstun = 1; X kludge("%s staggers.", Monnam(mtmp)); X } X break; X case AD_FIRE: /* Red mold */ X dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[i].damd); X if(resists_fire(mdat)) { X shieldeff(mtmp->mx, mtmp->my); X kludge("%s is mildly warm.", Monnam(mtmp)); X#ifdef GOLEMS X golemeffects(mtmp, AD_FIRE, dam); X#endif /* GOLEMS */ X dam = 0; X break; X } X kludge("%s is suddenly very hot!", Monnam(mtmp)); X default: break; X } X X if((mtmp->mhp -= dam) <= 0) { X kludge("%s dies!", Monnam(mtmp)); X xkilled(mtmp,0); X return 2; X } X return 1; X} X X#endif /* OVL1 */ X#ifdef OVLB X X#include "edog.h" Xstruct monst * Xcloneu() X{ X register struct monst *mon; X X if (u.mh <= 1) return(struct monst *)0; X uasmon->pxlth += sizeof(struct edog); X mon = makemon(uasmon, u.ux, u.uy); X uasmon->pxlth -= sizeof(struct edog); X mon = christen_monst(mon, plname); X initedog(mon); X mon->m_lev = uasmon->mlevel; X mon->mhp = u.mh /= 2; X mon->mhpmax = u.mhmax; X return(mon); X} X X#endif /* OVLB */ X X#endif /* POLYSELF */ X END_OF_FILE if test 47502 -ne `wc -c <'src/mhitu.c'`; then echo shar: \"'src/mhitu.c'\" unpacked with wrong size! fi # end of 'src/mhitu.c' fi echo shar: End of archive 5 \(of 56\). cp /dev/null ark5isdone 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 else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0