[comp.sources.games] v07i065: NetHack3 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/24/89)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 7, Issue 65
Archive-name: NetHack3/Part10



#! /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 10 (of 38)."
# Contents:  auxil/nethack.sh src/mhitm.c src/uhitm.c
# Wrapped by billr@saab on Sun Jul 23 21:32:53 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'auxil/nethack.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'auxil/nethack.sh'\"
else
echo shar: Extracting \"'auxil/nethack.sh'\" \(219 characters\)
sed "s/^X//" >'auxil/nethack.sh' <<'END_OF_FILE'
X#!/bin/sh
X#	SCCS Id: @(#)nethack.sh	1.4	87/08/08
XHACKDIR=/usr/games/lib/nethackdir
XHACK=$HACKDIR/nethack
XMAXNROFPLAYERS=4
X
Xcd $HACKDIR
Xcase $1 in
X	-s*)
X		exec $HACK $@
X		;;
X	*)
X		exec $HACK $@ $MAXNROFPLAYERS
X		;;
Xesac
END_OF_FILE
if test 219 -ne `wc -c <'auxil/nethack.sh'`; then
    echo shar: \"'auxil/nethack.sh'\" unpacked with wrong size!
fi
# end of 'auxil/nethack.sh'
fi
if test -f 'src/mhitm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/mhitm.c'\"
else
echo shar: Extracting \"'src/mhitm.c'\" \(17168 characters\)
sed "s/^X//" >'src/mhitm.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)mhitm.c	3.0	88/11/10
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 boolean vis, far_noise;
Xstatic long noisetime;
Xstatic struct obj *otmp;
X
Xstatic void mrustm P((struct monst *, struct monst *, struct obj *));
Xstatic int hitmm P((struct monst *,struct monst *,struct attack *));
Xstatic int gazemm P((struct monst *,struct monst *,struct attack *));
Xstatic int gulpmm P((struct monst *,struct monst *,struct attack *));
Xstatic int explmm P((struct monst *,struct attack *));
Xstatic int mdamagem P((struct monst *,struct monst *,struct attack *));
Xstatic void mswingsm P((struct monst *, struct monst *, struct obj *));
X
Xstatic boolean
Xm_incompat(magr, mdef)
X/* This must work like in mhitu.c.  Specifically, if it's a shopkeeper
X * polymorphed into a monster of a specific gender, the specific gender
X * overrides.  Thus, do not use is_female(), since then a female shopkeeper
X * polymorphed into an incubus, or any shopkeeper turned into something
X * genderless, would be treated improperly.
X * This nonsense could be avoided if every monster had a gender field...
X */
Xregister struct monst *magr, *mdef;
X{
X	return(gender(magr) != 1-gender(mdef));
X}
X
Xstatic void
Xnoises(magr, mattk)
X	register struct monst *magr;
X	register struct	attack *mattk;
X{
X	boolean farq = (dist(magr->mx, magr->my) > 15);
X
X	if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) {
X		far_noise = farq;
X		noisetime = moves;
X		You("hear %s%s.",
X			(mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",
X			farq ? " in the distance" : "");
X	}
X}
X
Xstatic
Xvoid
Xmissmm(magr, mdef, mattk)
X	register struct monst *magr, *mdef;
X	struct attack *mattk;
X{
X	char buf[BUFSZ];
X
X	if(vis) {
X		if(mdef->mimic) seemimic(mdef);
X		if(magr->mimic) seemimic(magr);
X		if (sp_melee(magr) && !magr->mcan &&
X			    (is_nymph(magr) || !m_incompat(magr,mdef))) {
X			Sprintf(buf, "%s pretends to be friendly to",
X								Monnam(magr));
X		} else
X			Sprintf(buf,"%s misses", Monnam(magr));
X		pline("%s %s.", buf, mon_nam(mdef));
X	} else  noises(magr, mattk);
X}
X
Xint
Xfightm(mtmp)		/* have monsters fight each other */
X	register struct monst *mtmp;
X{
Xregister struct monst *mon;
X/*	TODO:	this loop needs to be restructured, as we don't know if
X *		either "mon" or "mon->nmon" will exist after the attack.
X */
X	for(mon = fmon; mon; mon = mon->nmon)
X	    if(mon != mtmp) {
X		if(dist2(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3)
X		    return(mattackm(mtmp,mon));
X	    }
X	return(-1);
X}
X
X/*
X * mattackm returns -1 (magr died), 0 (miss), 1 (mdef hit), or 2 (mdef killed)
X *
X * Each successive attack has a lower probability of hitting.  Some
X * rely on the success of previous attacks.
X *
X * In the case of exploding monsters, the monster dies as well.
X */
Xint
Xmattackm(magr, mdef)
X	register struct monst *magr,*mdef;
X{
X	int	i, tmp, nsum, sum[NATTK];
X	struct	attack	*mattk;
X	struct	permonst *pa, *pd;
X	schar	strike;
X
X	if(!magr || !mdef) return(0);		/* mike@genat */
X	pa = magr->data; pd = mdef->data;
X	if(magr->mfroz) return(0);		/* riv05!a3 */
X
X/*	Calculate the armour class differential.	*/
X
X	tmp = pd->ac + magr->m_lev;
X	if(mdef->mconf || mdef->mfroz || mdef->msleep){
X		tmp += 4;
X		if(mdef->msleep) mdef->msleep = 0;
X	}
X
X	if (is_elf(magr->data) && is_orc(mdef->data)) tmp++;
X
X/*	Set up visibility of action			*/
X	vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
X
X/*	Set flag indicating monster has moved this turn.  Necessary since a
X *	monster might get an attack out of sequence (i.e. before its move) in
X *	some cases, in which case this still counts as its move for the round
X *	and it shouldn't move again.
X */
X	magr->mlstmv = moves;
X
X/*	Now perform all attacks for the monster.	*/
X
X	for(i=0; i<NATTK; i++) sum[i] = 0;
X	for(i = nsum = 0; i < NATTK; nsum |= sum[i++]) {
X	    mattk = &(pa->mattk[i]);
X	    otmp = (struct obj *)0;
X	    switch(mattk->aatyp) {
X
X		case AT_WEAP:		/* "hand to hand" attacks */
X			otmp = select_hwep(magr);
X			if(otmp) {
X				if (vis) mswingsm(magr, mdef, otmp);
X				tmp += hitval(otmp, pd);
X			}
X		case AT_CLAW:
X		case AT_KICK:
X		case AT_BITE:
X		case AT_STNG:
X		case AT_TUCH:
X		case AT_BUTT:
X			if((strike = (tmp > rnd(20+i)))) {
X				sum[i] = hitmm(magr, mdef, mattk);
X				if(sum[i] == -1) return(-1);
X			} else	missmm(magr, mdef, mattk);
X			break;
X
X		case AT_HUGS:	/* automatic if prev two attacks succeed */
X			strike = 1;
X			if(sum[i-1] && sum[i-2]) {
X			    sum[i] = hitmm(magr, mdef, mattk);
X			    if(sum[i] == -1) return(-1);
X			}
X			break;
X
X		case AT_GAZE:	/* will not wake up a sleeper */
X			strike = 0;
X			sum[i] = gazemm(magr, mdef, mattk);
X			break;
X
X		case AT_EXPL:	/* automatic hit if next to */
X			strike = -1;
X			sum[i] = explmm(magr, mattk);
X			break;
X
X		case AT_ENGL:
X			if((strike = (tmp > rnd(20+i))))
X				sum[i]= gulpmm(magr, mdef, mattk);
X			else	missmm(magr, mdef, mattk);
X			break;
X
X		default:		/* no attack */
X			strike = 0;
X			break;
X	    }
X	    if(sum[i] == 2) return(2);  	/* defender dead */
X	    if(strike)	    mdef->msleep = 0;
X	    if(strike == -1)   return(-1);		/* attacker dead */
X	    nsum |= sum[i];
X	}
X	return(nsum);
X}
X
X/* hitmm returns 0 (miss), 1 (hit), 2 (kill), or -1 (magr died) */
Xstatic int
Xhitmm(magr, mdef, mattk)
X	register struct monst *magr,*mdef;
X	struct	attack *mattk;
X{
X
X	if(vis){
X		char buf[BUFSZ];
X		if(mdef->mimic) seemimic(mdef);
X		if(magr->mimic) seemimic(magr);
X		if(sp_melee(magr) && !magr->mcan) {
X			if(!is_nymph(magr) && m_incompat(magr,mdef))
X				goto strike;
X			Sprintf(buf, "%s %s", Monnam(magr),
X				mdef->mblinded ? "talks to" : "smiles at");
X			pline("%s %s %s.", buf, mon_nam(mdef),
X				m_incompat(magr,mdef) ?
X					"engagingly" : "seductively");
X		} else {
X	strike:
X		    switch (mattk->aatyp) {
X			case AT_BITE:
X				Sprintf(buf,"%s bites", Monnam(magr));
X				break;
X			case AT_STNG:
X				Sprintf(buf,"%s stings", Monnam(magr));
X				break;
X			case AT_BUTT:
X				Sprintf(buf,"%s butts", Monnam(magr));
X				break;
X			case AT_TUCH:
X				Sprintf(buf,"%s touches", Monnam(magr));
X				break;
X			case AT_HUGS:
X				if (magr != u.ustuck) {
X				    Sprintf(buf,"%s squeezes", Monnam(magr));
X				    break;
X				}
X			default:
X				Sprintf(buf,"%s hits", Monnam(magr));
X		    }
X		}
X		pline("%s %s.", buf, mon_nam(mdef));
X	} else  noises(magr, mattk);
X	return(mdamagem(magr, mdef, mattk));
X}
X
Xstatic int
Xgazemm(magr, mdef, mattk)
X	register struct monst *magr, *mdef;
X	struct attack *mattk;
X{
X	char buf[BUFSZ];
X
X	if(vis) {
X		Sprintf(buf,"%s gazes at", Monnam(magr));
X		pline("%s %s.", buf, mon_nam(mdef));
X	}
X
X	if (mdef->mblinded || mdef->msleep) {
X
X	    if(vis) pline("but nothing happens.");
X	    return(0);
X	}
X
X	return(mdamagem(magr, mdef, mattk));
X}
X
Xstatic int
Xgulpmm(magr, mdef, mattk)
X	register struct monst *magr, *mdef;
X	register struct	attack *mattk;
X{
X	int	mx, my, tmp;
X	char buf[BUFSZ];
X
X	if(vis) {
X		Sprintf(buf,"%s swallows", Monnam(magr));
X		pline("%s %s.", buf, mon_nam(mdef));
X	}
X
X	mx = magr->mx;
X	my = magr->my;
X	 /* move over top of the defender */
X	if(cansee(mdef->mx, mdef->my))	unpmon(mdef);
X	if(cansee(magr->mx, magr->my))	unpmon(magr);
X	magr->mx = mdef->mx;
X	magr->my = mdef->my;
X	if(cansee(magr->mx, magr->my))	pmon(magr);
X	if((tmp = mdamagem(magr, mdef, mattk)) == 2) {
X		levl[mx][my].mmask = 0;
X		return(2);	/* defender died */
X	} else {		/* defender survived */
X		if(cansee(magr->mx, magr->my))	unpmon(magr);
X		magr->mx = mx;
X		magr->my = my;
X		/* move off of defender */
X		if(cansee(magr->mx, magr->my))	pmon(magr);
X		if(cansee(mdef->mx, mdef->my))	pmon(mdef);
X		return(tmp);
X	}
X}
X
Xstatic int
Xexplmm(magr, mattk)
X	register struct monst *magr;
X	register struct	attack *mattk;
X{
X	register struct monst *mon;
X
X	if(cansee(magr->mx, magr->my))
X		pline("%s explodes!", Monnam(magr));
X	else	noises(magr, mattk);
X
X	for(mon = fmon; mon; mon = mon->nmon)
X	    if(mon != magr) {
X		if(dist2(mon->mx, mon->my, magr->mx, magr->my) < 3)
X		    (void) mdamagem(magr, mon, mattk);
X	    }
X
X	if(dist2(magr->mx, magr->my, u.ux, u.uy) < 3)
X		(void) mdamageu(magr, d((int)mattk->damn, (int)mattk->damd));
X
X	mondied(magr);
X	return(2);
X}
X
Xstatic int
Xmdamagem(magr, mdef, mattk)
X	register struct monst	*magr, *mdef;
X	register struct attack	*mattk;
X{
X	struct	permonst *ptr, *pd = mdef->data;
X	int	tmp = d((int)mattk->damn,(int)mattk->damd);
X	char buf[BUFSZ];
X
X	switch(mattk->adtyp) {
X	    case AD_DGST:
X		if(flags.verbose && flags.soundok) pline("\"Burrrrp!\"");
X		tmp = mdef->mhp;
X		break;
X	    case AD_STUN:
X		if (magr->mcan) break;
X		if(vis) pline("%s staggers for a moment.", Monnam(mdef));
X		mdef->mstun = 1;
X	    case AD_PHYS:
X		if (mattk->aatyp == AT_KICK && thick_skinned(mdef->data))
X			tmp = 0;
X		else if(mattk->aatyp == AT_WEAP) {
X		    if(otmp) {
X			tmp += dmgval(otmp, pd);
X#ifdef NAMED_ITEMS
X			if(spec_ability(otmp, SPFX_DRLI) &&
X			    !resists_drli(mdef->data)) {
X			    int dam = rnd(8);
X
X			    tmp += dam;
X			    if(vis)
X				pline("The %s blade drains the life from %s!",
X					Hallucination ? hcolor() : black,
X					mon_nam(mdef));
X			    mdef->mhpmax -= dam;
X			    if (mdef->m_lev == 0)
X				tmp = mdef->mhp;
X			    else mdef->m_lev--;
X			}
X#endif
X			mrustm(magr, mdef, otmp);
X		    }
X		}
X		break;
X	    case AD_FIRE:
X		if (magr->mcan) {
X		    tmp = 0;
X		    break;
X		}
X#ifdef GOLEMS
X		golemeffects(mdef, AD_FIRE, tmp);
X#endif /* GOLEMS */
X		if(resists_fire(pd)) {
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		} else {
X		    tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE);
X		    tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE);
X#ifdef SPELLS
X		    tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE);
X#endif
X		}
X		break;
X	    case AD_COLD:
X		if (magr->mcan) {
X		    tmp = 0;
X		    break;
X		}
X#ifdef GOLEMS
X		golemeffects(mdef, AD_COLD, tmp);
X#endif /* GOLEMS */
X		if(resists_cold(pd)) {
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		} else tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD);
X		break;
X	    case AD_ELEC:
X		if (magr->mcan) {
X		    tmp = 0;
X		    break;
X		}
X#ifdef GOLEMS
X		golemeffects(mdef, AD_ELEC, tmp);
X#endif /* GOLEMS */
X		if(resists_elec(pd)) {
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		}
X		break;
X	    case AD_ACID:
X		if (magr->mcan) {
X		    tmp = 0;
X		    break;
X		}
X		if(resists_acid(pd)) tmp = 0;
X		break;
X	    case AD_RUST:
X#ifdef GOLEMS
X		if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) {
X			if (vis) pline("%s falls to pieces!", Monnam(mdef));
X			else if(mdef->mtame)
X			     pline("May %s rust in peace.", mon_nam(mdef));
X			mondied(mdef);
X			magr->mhpmax += 1 + rn2((int)mdef->m_lev+1);
X			ptr = grow_up(magr);
X			if(!ptr) return(-1);
X			return(2);
X		}
X#endif /* GOLEMS */
X		tmp = 0;
X		break;
X	    case AD_DCAY:
X#ifdef GOLEMS
X		if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] ||
X		    pd == &mons[PM_LEATHER_GOLEM])) {
X			if (vis) pline("%s falls to pieces!", Monnam(mdef));
X			else if(mdef->mtame)
X			     pline("May %s rot in peace.", mon_nam(mdef));
X			mondied(mdef);
X			magr->mhpmax += 1 + rn2((int)mdef->m_lev+1);
X			ptr = grow_up(magr);
X			if(!ptr) return(-1);
X			return(2);
X		}
X#endif /* GOLEMS */
X		tmp = 0;
X		break;
X	    case AD_STON:
X		if(!resists_ston(pd)) {
X			magr->mhpmax += 1 + rn2((int)mdef->m_lev+1);
X			if(vis) pline("%s turns to stone!", Monnam(mdef));
X			else if(mdef->mtame)
X     You("have a peculiarly sad feeling for a moment, then it passes.");
X			monstone(mdef);
X			ptr = grow_up(magr);
X			if(!ptr) return(-1);
X			return(2);
X		}
X		tmp = 0;	/* no damage if this fails */
X		break;
X	    case AD_TLPT:
X		if(!magr->mcan && tmp >= mdef->mhp) {
X		    rloc(mdef);
X		    if(vis && !cansee(mdef->mx, mdef->my))
X			pline("%s suddenly disappears!", Monnam(mdef));
X		}
X		break;
X	    case AD_SLEE:
X		if(!resists_sleep(pd) && !magr->mcan && vis && !mdef->msleep) {
X		    pline("%s falls asleep.", Monnam(mdef));
X		    mdef->msleep = 1;
X		}
X		break;
X	    case AD_PLYS:
X		if(!magr->mcan && vis && !mdef->mfroz) {
X		    pline("%s stops moving.", Monnam(mdef));
X		    mdef->mfroz = 1;
X		}
X		break;
X	    case AD_SLOW:
X		if(!magr->mcan && vis && mdef->mspeed != MSLOW) {
X		    pline("%s slows down.", Monnam(mdef));
X		    if (mdef->mspeed == MFAST) mdef->mspeed = 0;
X		    else mdef->mspeed = MSLOW;
X		}
X		break;
X	    case AD_CONF:
X		/* Since confusing another monster doesn't have a real time
X		 * limit, setting spec_used would not really be right (though
X		 * we still should check for it).
X		 */
X		if(!magr->mcan && vis && !mdef->mconf && !magr->mspec_used) {
X		    pline("%s looks confused.", Monnam(mdef));
X		    mdef->mconf = 1;
X		}
X		break;
X	    case AD_BLND:
X		if(!magr->mcan && haseyes(pd)) {
X
X		    if(vis && !mdef->mblinded)
X			pline("%s is blinded.", Monnam(mdef));
X		    {
X			register unsigned rnd_tmp;
X			rnd_tmp = d((int)mattk->damn, (int)mattk->damd);
X			mdef->mcansee = 0;
X			if((mdef->mblinded + rnd_tmp) > 127)
X				mdef->mblinded = 127;
X			else mdef->mblinded += rnd_tmp;
X		    }
X		}
X		tmp = 0;
X		break;
X	    case AD_CURS:
X		if(!night() && (magr->data == &mons[PM_GREMLIN])) break;
X		if(!magr->mcan && !rn2(10)) {
X		    if (is_were(mdef->data) && mdef->data->mlet != S_HUMAN)
X			were_change(mdef);
X#ifdef GOLEMS
X		    if (mdef->data == &mons[PM_CLAY_GOLEM]) {
X			    if (vis) {
X				pline("Some writing vanishes from %s's head!",
X				    mon_nam(mdef));
X				pline("%s dies!", Monnam(mdef));
X			    }
X			    else if (mdef->mtame)
X	You("have a strangely sad feeling for a moment, then it passes.");
X			    mondied(mdef);
X			    magr->mhpmax += 1 + rn2((int)mdef->m_lev+1);
X			    ptr = grow_up(magr);
X			    if(!ptr) return(-1);
X			    return(2);
X		      }
X#endif /* GOLEMS */
X		    mdef->mcan = 1;
X		    if (flags.soundok) {
X			    if (!vis) You("hear laughter.");
X			    else pline("%s chuckles.", Monnam(magr));
X		    }
X		}
X		break;
X	    case AD_SGLD:
X		tmp = 0;
X		if (magr->mcan || !mdef->mgold) break;
X		/* technically incorrect; no check for stealing gold from
X		 * between mdef's feet...
X		 */
X		magr->mgold += mdef->mgold;
X		mdef->mgold = 0;
X		if (vis) {
X			Strcpy(buf, Monnam(magr));
X			pline("%s steals some gold from %s.", buf,
X								mon_nam(mdef));
X		}
X		break;
X	    case AD_DRLI:
X		if(rn2(2) && !resists_drli(mdef->data)) {
X			tmp = d(2,6);
X			if (vis)
X			    kludge("%s suddenly seems weaker!", Monnam(mdef));
X			mdef->mhpmax -= tmp;
X			if (mdef->m_lev == 0)
X				tmp = mdef->mhp;
X			else mdef->m_lev--;
X			/* Automatic kill if drained past level 0 */
X		}
X		break;
X#ifdef SEDUCE
X	    case AD_SSEX:
X#endif
X	    case AD_SITM:	/* for now these are the same */
X	    case AD_SEDU:
X		if (!magr->mcan && mdef->minvent) {
X		   	otmp = mdef->minvent;
X			mdef->minvent = otmp->nobj;
X			otmp->nobj = magr->minvent;
X			magr->minvent = otmp;
X			if (vis) {
X				Strcpy(buf, Monnam(magr));
X				pline("%s steals %s from %s!", buf,
X						doname(otmp), mon_nam(mdef));
X			}
X		}
X		tmp = 0;
X		break;
X	    case AD_DRST:
X	    case AD_DRDX:
X	    case AD_DRCO:
X		if (!magr->mcan && !rn2(8)) {
X		    if (vis)
X			pline("%s's %s was poisoned!", Monnam(magr),
X				mattk->aatyp==AT_BITE ? "bite" : "sting");
X		    if (resists_poison(mdef->data)) {
X			if (vis)
X			    pline("The poison doesn't seem to affect %s.",
X				mon_nam(mdef));
X		    } else {
X			if (rn2(10)) tmp += rn1(10,6);
X			else {
X			    if (vis) pline("The poison was deadly...");
X			    tmp = mdef->mhp;
X			}
X		    }
X		}
X		break;
X	    case AD_STCK:
X	    case AD_WRAP: /* monsters cannot grab one another, it's too hard */
X		break;
X	    default:	tmp = 0;
X			break;
X	}
X	if(!tmp) return(1);
X
X	if((mdef->mhp -= tmp) < 1) {
X	    magr->mhpmax += 1 + rn2((int)mdef->m_lev+1);
X	    if(vis) pline("%s is killed!", Monnam(mdef));
X	    else if(mdef->mtame)
X		You("have a sad feeling for a moment, then it passes.");
X	    mondied(mdef);
X	    ptr = grow_up(magr);
X	    if(!ptr) return(-1);
X	    return(2);
X	}
X	/* fixes a bug where max monster hp could overflow. */
X	if(magr->mhpmax <= 0 || magr->mhpmax > MHPMAX) magr->mhpmax = MHPMAX;
X
X	return(1);
X}
X
Xint
Xnoattacks(ptr)			/* returns 1 if monster doesn't attack */
X	struct	permonst *ptr;
X{
X	int i;
X
X	for(i = 0; i < NATTK; i++)
X		if(ptr->mattk[i].aatyp) return(0);
X
X	return(1);
X}
X
Xstatic void
Xmrustm(magr, mdef, obj)
Xregister struct monst *magr, *mdef;
Xregister struct obj *obj;
X{
X	if (!magr || !mdef || !obj) return; /* just in case */
X	if (mdef->data == &mons[PM_RUST_MONSTER] &&
X				objects[obj->otyp].oc_material == METAL &&
X				!obj->rustfree && obj->spe > -2) {
X		if(obj->blessed && rn2(3)) {
X		    if (cansee(mdef->mx, mdef->my))
X			pline("%s's weapon is not affected.", Monnam(magr));
X		} else {
X		    if (cansee(mdef->mx, mdef->my))
X			pline("%s's %s!", Monnam(magr),
X						aobjnam(obj, "corrode"));
X		    obj->spe--;
X		}
X	}
X}
X
Xstatic void
Xmswingsm(magr, mdef, otemp)
Xregister struct monst *magr, *mdef;
Xregister struct obj *otemp;
X{
X	char buf[BUFSZ];
X	Strcpy(buf, mon_nam(mdef));
X	if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return;
X	pline("%s %s %s %s at %s.", Monnam(magr),
X	      (otemp->otyp == SPEAR ||
X	       otemp->otyp == LANCE ||
X	       otemp->otyp == GLAIVE ||
X	       otemp->otyp == TRIDENT) ? "thrusts" : "swings",
X	      is_female(magr) ? "her" :
X	      is_human(magr->data) ? "his" : "its",
X	      xname(otemp), buf);
X}
END_OF_FILE
if test 17168 -ne `wc -c <'src/mhitm.c'`; then
    echo shar: \"'src/mhitm.c'\" unpacked with wrong size!
fi
# end of 'src/mhitm.c'
fi
if test -f 'src/uhitm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/uhitm.c'\"
else
echo shar: Extracting \"'src/uhitm.c'\" \(33761 characters\)
sed "s/^X//" >'src/uhitm.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)uhitm.c	3.0	88/04/11
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 boolean hitum();
X#ifdef POLYSELF
Xstatic boolean hmonas();
X#endif
Xstatic int passive();
X
X#ifdef WORM
Xextern boolean notonhead;
X#endif
X
Xstruct monst *
Xclone_mon(mon)
Xstruct monst *mon;
X{
X	coord mm;
X	struct monst *m2;
X
X	mm.x = mon->mx;
X	mm.y = mon->my;
X	enexto(&mm, mm.x, mm.y);
X	if (levl[mm.x][mm.y].mmask || mon->mhp <= 1) return (struct monst *)0;
X	m2 = newmonst(0);
X	*m2 = *mon;			/* copy condition of old monster */
X	m2->nmon = fmon;
X	fmon = m2;
X	m2->m_id = flags.ident++;
X	m2->mx = mm.x;
X	m2->my = mm.y;
X
X	m2->minvent = (struct obj *) 0; /* objects don't clone */
X	m2->mleashed = FALSE;
X	m2->mgold = 0L;
X	/* Max HP the same, but current HP halved for both.  The caller
X	 * might want to override this by halving the max HP also.
X	 */
X	m2->mhpmax = mon->mhpmax;
X	m2->mhp = mon->mhp /= 2;
X
X	/* since shopkeepers and guards will only be cloned if they've been
X	 * polymorphed away from their original forms, the clone doesn't have
X	 * room for the extra information.  we also don't want two shopkeepers
X	 * around for the same shop.
X	 * similarly, clones of named monsters don't have room for the name,
X	 * so we just make the clone unnamed instead of bothering to create
X	 * a clone with room and copying over the name from the right place
X	 * (which changes if the original was a shopkeeper or guard).
X	 */
X	if (mon->isshk) m2->isshk = FALSE;
X	if (mon->isgd) m2->isgd = FALSE;
X#if defined(ALTARS) && defined(THEOLOGY)
X	if (mon->ispriest) m2->ispriest = FALSE;
X#endif
X	m2->mxlth = 0;
X	m2->mnamelth = 0;
X	m2->mdispl = 0;
X	pmon(m2);	/* display the new monster */
X	levl[m2->mx][m2->my].mmask = 1;
X	if (mon->mtame) (void) tamedog(m2, (struct obj *)0);
X	return m2;
X}
X
Xboolean
Xspecial_case(mtmp)
X/* Moved this code from attack() in order to 	*/
X/* avoid having to duplicate it in dokick.	*/
Xregister struct monst *mtmp;
X{
X	if (flags.confirm && (mtmp->mpeaceful || mtmp->mtame) && !Confusion
X	    && !Hallucination && (!mtmp->mhide || !mtmp->mundetected)
X	    && (!mtmp->mimic || Protection_from_shape_changers)) {
X		if (Blind ? Telepat : (!mtmp->minvis || See_invisible)) {
X			pline("Really attack %s? ", mon_nam(mtmp));
X			(void) fflush(stdout);
X			if (yn() != 'y') {
X				flags.move = 0;
X				return(TRUE);
X			}
X		}
X	}
X
X	if(mtmp->mimic && !Protection_from_shape_changers) {
X		if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK))
X			u.ustuck = mtmp;
X		if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == DOOR_SYM)
X#ifdef SPELLS
X		{
X		    if (okdoor(u.ux+u.dx, u.uy+u.dy))
X#endif
X			pline("The door actually was %s.", defmonnam(mtmp));
X#ifdef SPELLS
X		    else
X			pline("That spellbook was %s.", defmonnam(mtmp));
X		}
X#endif
X		else if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == GOLD_SYM)
X			pline("That gold was %s!", defmonnam(mtmp));
X		else
X			pline("Wait!  That's %s!", defmonnam(mtmp));
X		wakeup(mtmp);	/* clears mtmp->mimic */
X		return(TRUE);
X	}
X
X	if(mtmp->mhide && mtmp->mundetected && !canseemon(mtmp)) {
X		mtmp->mundetected = 0;
X		if (!(Blind ? Telepat : (HTelepat & WORN_HELMET))) {
X		    register struct obj *obj;
X
X		    if(levl[mtmp->mx][mtmp->my].omask == 1) {
X			if(obj = o_at(mtmp->mx,mtmp->my))
X				pline("Wait!  There's %s hiding under %s!",
X					defmonnam(mtmp), doname(obj));
X		    } else if (levl[mtmp->mx][mtmp->my].gmask == 1)
X				pline("Wait!  There's %s hiding under some gold!",
X					defmonnam(mtmp));
X		    wakeup(mtmp);
X		    return(TRUE);
X		}
X	}
X	return(FALSE);
X}
X
X
X/* try to attack; return FALSE if monster evaded */
X/* u.dx and u.dy must be set */
Xboolean
Xattack(mtmp)
Xregister struct monst *mtmp;
X{
X	schar tmp = 0;
X	register struct permonst *mdat = mtmp->data;
X
X	if(unweapon) {
X	    unweapon=FALSE;
X	    if(flags.verbose)
X		if(uwep)
X		    You("begin bashing monsters with your %s.",
X			aobjnam(uwep, NULL));
X		else
X#ifdef POLYSELF
X		    if (!cantwield(uasmon))
X#endif
X		    You("begin bashing monsters with your %s hands.",
X			uarmg ? "gloved" : "bare");		/* Del Lamb */
X	}
X	/* andrew@orca: prevent unlimited pick-axe attacks */
X	u_wipe_engr(3);
X
X	if(mdat->mlet == S_LEPRECHAUN && !mtmp->mfroz && !mtmp->msleep &&
X	   !mtmp->mconf && mtmp->mcansee && !rn2(7) &&
X	   (m_move(mtmp, 0) == 2 ||			    /* he died */
X	   mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* he moved */
X		return(FALSE);
X
X	/* This section of code provides protection against accidentally
X	 * hitting peaceful (like '@') and tame (like 'd') monsters.
X	 * There is protection only if you're not blind, confused, or hallu-
X	 * cinating.
X	 */
X	/*  changes by wwp 5/16/85 */
X	if (!Blind && !Confusion && !Hallucination && flags.safe_dog &&
X	    (mdat->mlet == S_DOG || mdat->mlet == S_FELINE) && mtmp->mtame) {
X		mtmp->mflee = 1;
X		mtmp->mfleetim = rnd(6);
X		if (mtmp->mnamelth)
X		    You("stop to avoid hitting %s.", NAME(mtmp));
X		else
X		    You("stop to avoid hitting your %s.",
X			  mdat->mname);
X		return(TRUE);
X	}
X
X	/* moved code to a separate function to share with dokick */
X	if(special_case(mtmp)) return(TRUE);
X
X#ifdef POLYSELF
X	if(u.umonnum >= 0) {	/* certain "pacifist" monsters don't attack */
X		set_uasmon();
X		if(noattacks(uasmon)) {
X			You("have no way to attack monsters physically.");
X			return(TRUE);
X		}
X	}
X	tmp = Luck + mdat->ac + abon() +
X		     ((u.umonnum >= 0) ? uasmon->mlevel : u.ulevel);
X#else
X	tmp = Luck + u.ulevel + mdat->ac + abon();
X#endif
X
X/*	it is unchivalrous to attack the defenseless or from behind */
X	if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL &&
X	    (mtmp->mfroz || mtmp->msleep || mtmp->mflee) &&
X	    u.ualign > -10) adjalign(-1);
X
X/*	Adjust vs. (and possibly modify) monster state.		*/
X
X	if(mtmp->mstun) tmp += 2;
X	if(mtmp->mflee) tmp += 2;
X
X	if(mtmp->msleep) {
X		mtmp->msleep = 0;
X		tmp += 2;
X	}
X	if(mtmp->mfroz) {
X		tmp += 4;
X		if(!rn2(10)) mtmp->mfroz = 0;
X	}
X	if (is_orc(mtmp->data) && pl_character[0]=='E') tmp++;
X
X/*	with a lot of luggage, your agility diminishes */
X	tmp -= (inv_weight() + 40)/20;
X	if(u.utrap) tmp -= 3;
X
X#ifdef POLYSELF
X	if(u.umonnum >= 0) (void) hmonas(mtmp, tmp);
X	else {
X#endif
X		if(uwep) tmp += hitval(uwep, mdat);
X		(void) hitum(mtmp, tmp);
X#ifdef POLYSELF
X	}
X#endif
X
X	return(TRUE);
X}
X
Xstatic boolean
Xknown_hitum(mon, mhit)	/* returns TRUE if monster still lives */
X/* Made into a separate function because in some cases we want to know
X * in the calling function whether we hit.
X */
Xregister struct monst *mon;
Xregister int mhit;
X{
X	register boolean malive = TRUE;
X
X	stoned = FALSE;		/* this refers to the thing hit, not you */
X
X	if(!mhit) {
X	    if(!Blind && flags.verbose) You("miss %s.", mon_nam(mon));
X	    else			You("miss it.");
X	    if(is_human(mon->data) && !(mon->msleep || mon->mfroz))
X		wakeup(mon);
X	} else {
X	    /* we hit the monster; be careful: it might die! */
X
X#ifdef WORM
X	    if (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy)
X		notonhead = TRUE;
X#endif
X	    if((malive = hmon(mon, uwep, 0)) == TRUE) {
X		/* monster still alive */
X		if(!rn2(25) && mon->mhp < mon->mhpmax/2) {
X			mon->mflee = 1;
X			if(!rn2(3)) mon->mfleetim = rnd(100);
X			if(u.ustuck == mon && !u.uswallow
X#ifdef POLYSELF
X						&& !sticks(uasmon)
X#endif
X								)
X				u.ustuck = 0;
X		}
X#ifdef WORM
X		if(mon->wormno)
X		    cutworm(mon, u.ux+u.dx, u.uy+u.dy,
X			    uwep ? uwep->otyp : 0);
X#endif
X	    }
X#if defined(ALTARS) && defined(THEOLOGY)
X	    if(mon->ispriest && !rn2(2)) ghod_hitsu();
X#endif
X	}
X	return(malive);
X}
X
Xstatic boolean
Xhitum(mon, tmp)		/* returns TRUE if monster still lives */
Xstruct monst *mon;
Xint tmp;
X{
X	static int malive;
X	boolean mhit = !((tmp <= rnd(20)) && !u.uswallow);
X
X	malive = known_hitum(mon, mhit);
X	(void) passive(mon, mhit, malive);
X	return(malive);
X}
X
Xboolean			/* general "damage monster" routine */
Xhmon(mon, obj, thrown)		/* return TRUE if mon still alive */
Xregister struct monst *mon;
Xregister struct obj *obj;
Xregister int thrown;
X{
X	register int tmp;
X	boolean hittxt = FALSE;
X	boolean get_dmg_bonus = TRUE;
X	boolean ispoisoned = FALSE;
X
X	wakeup(mon);
X	if(!obj) {
X	    tmp = rnd(2);	/* attack with bare hands */
X	    if(mon->data == &mons[PM_COCKATRICE] && !uarmg
X#ifdef POLYSELF
X		&& !resists_ston(uasmon)
X#endif
X		) {
X
X		kludge("You hit %s with your bare %s.",
X			mon_nam(mon), makeplural(body_part(HAND)));
X		You("turn to stone...");
X		done_in_by(mon);
X	    }
X	} else {
X	    if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
X	       obj->olet == ROCK_SYM) {
X
X		if(mon->data == &mons[PM_RUST_MONSTER] && obj == uwep &&
X			objects[obj->otyp].oc_material == METAL &&
X			obj->spe > -2) {
X		    if(obj->rustfree) {
X			pline("The rust on your %s vanishes instantly!",
X			      is_sword(obj) ? "sword" : "weapon");
X		    } else if(obj->blessed && rnl(4))
X			pline("Somehow your %s is not affected!",
X			      is_sword(obj) ? "sword" : "weapon");
X		    else {
X		    	Your("%s!", aobjnam(uwep, "corrode"));
X		    	uwep->spe--;
X		    }
X		}
X
X		if(obj == uwep && (obj->otyp > VOULGE || obj->otyp < BOOMERANG)
X				&& obj->otyp != PICK_AXE)
X		    tmp = rnd(2);
X		else {
X		    tmp = dmgval(obj, mon->data);
X#ifdef NAMED_ITEMS
X		    if(spec_ability(obj, SPFX_DRLI) &&
X						!resists_drli(mon->data)) {
X			if (!Blind) {
X			    pline("The %s blade draws the life from %s!",
X				Hallucination ? hcolor() : black,
X				mon_nam(mon));
X			    hittxt = TRUE;
X			}
X			if (mon->m_lev == 0) tmp = mon->mhp;
X			else {
X			    int drain = rnd(8);
X			    tmp += drain;
X			    mon->mhpmax -= drain;
X			    mon->m_lev--;
X			}
X		    }
X#endif
X		    if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&
X		       !rnl(3)) {
X			kludge("As you hit %s, the boomerang breaks into splinters.",
X			      mon_nam(mon));
X			useup(obj);
X			hittxt = TRUE;
X			tmp++;
X		    }
X		    if(thrown && (obj->otyp >= ARROW && obj->otyp <= SHURIKEN)){
X			if(((uwep && objects[obj->otyp].w_propellor ==
X				-objects[uwep->otyp].w_propellor)
X				|| obj->otyp==DART || obj->otyp==SHURIKEN) &&
X				obj->opoisoned)
X			    ispoisoned = TRUE;
X		    }
X		}
X	    } else if(obj->olet == POTION_SYM) {
X			if (obj->quan > 1) setuwep(splitobj(obj, 1));
X			else setuwep((struct obj *)0);
X			freeinv(obj);
X			potionhit(mon,obj);
X			hittxt = TRUE;
X			tmp = 1;
X	    } else	switch(obj->otyp) {
X		case HEAVY_IRON_BALL:
X			tmp = rnd(25); break;
X		case BOULDER:
X			tmp = rnd(20); break;
X#ifdef MEDUSA
X		case MIRROR:
X			You("break your mirror.  That's bad luck!");
X			change_luck(-2);
X			useup(obj);
X			return(TRUE);
X#endif
X		case EXPENSIVE_CAMERA:
X	You("succeed in destroying your camera.  Congratulations!");
X			useup(obj);
X			return(TRUE);
X		case CORPSE:		/* fixed by polder@cs.vu.nl */
X			if(obj->corpsenm == PM_COCKATRICE) {
X			    kludge("You hit %s with the cockatrice corpse.",
X				  mon_nam(mon));
X			    if(resists_ston(mon->data)) {
X				tmp = 1;
X				hittxt = TRUE;
X				break;
X			    }
X			    kludge("%s turns to stone.", Monnam(mon));
X			    stoned = TRUE;
X			    xkilled(mon,0);
X			    return(FALSE);
X			}
X			tmp = bigmonst(&mons[obj->corpsenm]) ? 5 : 2 ;
X			break;
X		case EGG: /* only possible if hand-to-hand */
X			if(obj->corpsenm > -1
X					&& obj->corpsenm != PM_COCKATRICE
X					&& mon->data==&mons[PM_COCKATRICE]) {
X				kludge("You hit %s with the %s egg%s.",
X					mon_nam(mon),
X					mons[obj->corpsenm].mname,
X					(obj->quan==1) ? "" : "s");
X				hittxt = TRUE;
X				pline("The egg%sn't live any more...",
X					(obj->quan==1) ? " is" : "s are");
X				obj->otyp = ROCK;
X				obj->olet = GEM_SYM;
X				obj->known = obj->dknown = 0;
X				obj->owt = weight(obj);
X			}
X			tmp = 1;
X			break;
X		case CLOVE_OF_GARLIC:		/* no effect against demons */
X			if(is_undead(mon->data)) mon->mflee = 1;
X			tmp = 1;
X			break;
X		case CREAM_PIE:
X#ifdef POLYSELF
X		case BLINDING_VENOM:
X			if(Blind)
X			    pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!");
X			else if (obj->otyp == BLINDING_VENOM)
X			    pline("The venom blinds %s%s!", mon_nam(mon),
X					mon->mcansee ? "" : " further");
X#else
X			if(Blind) pline("Splat!");
X#endif
X			else
X			    pline("The cream pie splashes over %s%s!",
X				mon_nam(mon),
X				(haseyes(mon->data) &&
X					mon->data != &mons[PM_FLOATING_EYE])
X				? "'s face" : "");
X			if(mon->msleep) mon->msleep = 0;
X			setmangry(mon);
X			mon->mcansee = 0;
X			if((mon->mblinded + tmp) > 127) mon->mblinded = 127;
X			else mon->mblinded += tmp;
X			hittxt = TRUE;
X			get_dmg_bonus = FALSE;
X			tmp = 0;
X			break;
X#ifdef POLYSELF
X		case ACID_VENOM: /* only possible if thrown */
X			if(resists_acid(mon->data)) {
X				kludge("Your venom hits %s harmlessly.",
X					mon_nam(mon));
X				tmp = 0;
X			} else {
X				kludge("Your venom burns %s!", mon_nam(mon));
X				tmp = dmgval(obj, mon->data);
X			}
X			hittxt = TRUE;
X			get_dmg_bonus = FALSE;
X			break;
X#endif
X		default:
X			/* non-weapons can damage because of their weight */
X			/* (but not too much) */
X			tmp = obj->owt/10;
X			if(tmp < 1) tmp = 1;
X			else tmp = rnd(tmp);
X			if(tmp > 6) tmp = 6;
X	    }
X	}
X
X	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
X	 *      *OR* if attacking bare-handed!! */
X
X	if (get_dmg_bonus) {
X		tmp += u.udaminc;
X		/* If you throw using a propellor, you don't get a strength
X		 * bonus but you do get an increase-damage bonus.
X		 */
X		if(!obj || !uwep ||
X			(obj->olet != GEM_SYM && obj->olet != WEAPON_SYM) ||
X			objects[obj->otyp].w_propellor !=
X				-objects[uwep->otyp].w_propellor)
X		    tmp += dbon();
X	}
X
X/* TODO:	Fix this up.  multiple engulf attacks now exist.
X	if(u.uswallow) {
X	    if((tmp -= u.uswldtim) <= 0) {
X		Your("%s are no longer able to hit.",
X			makeplural(body_part(ARM)));
X		return(TRUE);
X	    }
X	}
X */
X	if (ispoisoned) {
X	    /* OK to reference obj because ispoisoned can only be set
X	     * when obj is a throwing weapon */
X	    hit(xname(obj), mon, exclam(tmp));
X	    hittxt = TRUE;
X	    if(resists_poison(mon->data))
X		kludge("The poison doesn't seem to affect %s.", mon_nam(mon));
X	    else if (rn2(10))
X		tmp += rnd(6);
X	    else {
X		pline("The poison was deadly...");
X		xkilled(mon,0);
X		return FALSE;
X	    }
X	}
X	if(tmp < 1) tmp = 1;
X
X	mon->mhp -= tmp;
X	if(mon->mhp < 1) {
X		killed(mon);
X		return(FALSE);
X	}
X	if(mon->mtame && (!mon->mflee || mon->mfleetim)) {
X#ifdef SOUNDS
X		if (rn2(8)) yelp(mon);
X		else growl(mon); /* give them a moment's worry */
X#endif
X		mon->mtame--;
X		mon->mflee = 1;			/* Rick Richardson */
X		mon->mfleetim += 10*rnd(tmp);
X	}
X	if((mon->data == &mons[PM_BLACK_PUDDING] ||
X		   mon->data == &mons[PM_BROWN_PUDDING]) && uwep &&
X		   uwep == obj && objects[obj->otyp].oc_material == METAL
X		   && mon->mhp > 1 && !thrown && !mon->mcan) {
X
X		if (clone_mon(mon)) {
X			pline("%s divides as you hit it!", Monnam(mon));
X			hittxt = TRUE;
X		}
X	}
X
X	if(!hittxt) {
X		if(thrown)
X		    /* thrown => obj exists */
X		    hit(xname(obj), mon, exclam(tmp) );
X		else if(Blind || !flags.verbose) You("hit it.");
X		else	You("hit %s%s", mon_nam(mon), exclam(tmp));
X	}
X
X	if(u.umconf && !thrown) {
X		if(!Blind) {
X			Your("%s stop glowing %s.",
X			makeplural(body_part(HAND)),
X			Hallucination ? hcolor() : red);
X		}
X		if(!resist(mon, '+', 0, NOTELL)) mon->mconf = 1;
X		if(!mon->mstun && !mon->mfroz && !mon->msleep &&
X		   !Blind && mon->mconf)
X			pline("%s appears confused.", Monnam(mon));
X		u.umconf = 0;
X	}
X	return(TRUE);	/* mon still alive */
X}
X
X#ifdef POLYSELF
Xstatic int
Xdamageum(mdef, mattk)
Xregister struct monst *mdef;
Xregister struct attack *mattk;
X{
X	register struct permonst *pd = mdef->data;
X	register int	tmp = d((int)mattk->damn, (int)mattk->damd);
X
X	stoned = FALSE;
X	if (is_demon(uasmon) && !rn2(13) && !uwep
X#ifdef HARD
X		&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
X		&& u.umonnum != PM_BALROG
X#endif
X	    ) {
X	    struct monst *dtmp;
X	    pline("Some hell-p has arrived!");
X/*	    if((dtmp = mkmon_at(uasmon, u.ux, u.uy)))*/
X/*	    if((dtmp = makemon(uasmon, u.ux, u.uy)))*/
X	    if((dtmp = makemon(&mons[ndemon()], u.ux, u.uy)))
X		(void)tamedog(dtmp, (struct obj *)0);
X	    return(0);
X	}
X
X	switch(mattk->adtyp) {
X	    case AD_STUN:
X		if(!Blind)
X		    pline("%s staggers for a moment.", Monnam(mdef));
X		mdef->mstun = 1;
X		/* fall through to next case */
X	    case AD_WERE:	    /* no effect on monsters */
X	    case AD_PHYS:
X		if(mattk->aatyp == AT_WEAP) {
X			if(uwep) tmp = 0;
X		} else if(mattk->aatyp == AT_KICK)
X			if(thick_skinned(mdef->data)) tmp = 0;
X		break;
X	    case AD_FIRE:
X#ifdef GOLEMS
X		golemeffects(mdef, AD_FIRE, tmp);
X#endif /* GOLEMS */
X		if(resists_fire(pd)) {
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		} else {
X		    if(!Blind) pline("%s is on fire!", Monnam(mdef));
X		    tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE);
X		    tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE);
X#ifdef SPELLS
X		    tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE);
X#endif
X		}
X		break;
X	    case AD_COLD:
X#ifdef GOLEMS
X		golemeffects(mdef, AD_COLD, tmp);
X#endif /* GOLEMS */
X		if(resists_cold(pd)) {
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		} else {
X		    if(!Blind) pline("%s is covered in frost.", Monnam(mdef));
X		    tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD);
X		}
X		break;
X	    case AD_ELEC:
X#ifdef GOLEMS
X		golemeffects(mdef, AD_ELEC, tmp);
X#endif /* GOLEMS */
X		if(resists_elec(pd)) {
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		}
X		break;
X	    case AD_ACID:
X		if(resists_acid(pd)) tmp = 0;
X		break;
X	    case AD_STON:
X		if(!resists_ston(pd)) {
X		    stoned = TRUE;
X		    if(!Blind) pline("%s turns to stone.", Monnam(mdef));
X		    xkilled(mdef, 0);
X		    return(2);
X		}
X		tmp = 0;	/* no damage if this fails */
X		break;
X#ifdef SEDUCE
X	    case AD_SSEX:
X#endif
X	    case AD_SEDU:
X	    case AD_SITM:
X		if(mdef->minvent) {
X		    struct obj *otmp, *addinv(), *stealoid;
X		    int isize = inv_cnt();
X
X		    stealoid = (struct obj *)0;
X		    if (is_mercenary(pd)) {
X			for(otmp = mdef->minvent; otmp; otmp=otmp->nobj)
X			    if (otmp->otyp >= PLATE_MAIL && otmp->otyp
X				<= ELVEN_CLOAK) stealoid = otmp;
X		    }
X		    if (stealoid) {
X			boolean stolen = FALSE;
X			/* Is "he"/"his" always correct? */
X	 kludge("You seduce %s and he starts to take off his clothes.",
X				mon_nam(mdef));
X			while(mdef->minvent) {
X				otmp = mdef->minvent;
X				mdef->minvent = otmp->nobj;
X				if (!stolen && otmp==stealoid) {
X					if(isize < 52) {
X						otmp = addinv(otmp);
X						isize++;
X					} else dropy(otmp);
X					stealoid = otmp;
X					stolen = TRUE;
X				} else {
X					if(isize < 52) {
X						otmp = addinv(otmp);
X						isize++;
X					} else dropy(otmp);
X					You("steal: ");
X					prinv(otmp);
X				}
X			}
X			if (!stolen)
X				impossible("Player steal fails!");
X			else {
X				kludge("%s finishes taking off his suit.",
X							Monnam(mdef));
X				You("steal a %s.", xname(stealoid));
X#ifdef ARMY
X				mdef->data = &mons[PM_UNARMORED_SOLDIER];
X#endif
X			}
X		   } else {
X		   	   otmp = mdef->minvent;
X			   mdef->minvent = otmp->nobj;
X			   if(isize < 52) otmp = addinv(otmp);
X			   else dropy(otmp);
X			   You("steal: ");
X			   prinv(otmp);
X		   }
X		}
X		tmp = 0;
X		break;
X	    case AD_SGLD:
X		if (mdef->mgold) {
X		    u.ugold += mdef->mgold;
X		    mdef->mgold = 0;
X		    Your("purse feels heavier.");
X		}
X		tmp = 0;
X		break;
X	    case AD_TLPT:
X		if(tmp <= 0) tmp = 1;
X		if(tmp < mdef->mhp) {
X		    rloc(mdef);
X		    if(!Blind) pline("%s suddenly disappears!", Monnam(mdef));
X		}
X		break;
X	    case AD_BLND:
X		if(haseyes(pd)) {
X
X		    if(!Blind) pline("%s is blinded.", Monnam(mdef));
X		    mdef->mcansee = 0;
X		    mdef->mblinded += tmp;
X		}
X		tmp = 0;
X		break;
X	    case AD_CURS:
X		if (night() && !rn2(10) && !mdef->mcan) {
X#ifdef GOLEMS
X		    if (mdef->data == &mons[PM_CLAY_GOLEM]) {
X			if (!Blind)
X			    pline("Some writing vanishes from %s's head!",
X				mon_nam(mdef));
X			xkilled(mdef, 0);
X			return 2;
X		      }
X#endif /* GOLEMS */
X		    mdef->mcan = 1;
X		    You("chuckle.");
X		}
X		tmp = 0;
X		break;
X	    case AD_DRLI:
X		if(rn2(2) && !resists_drli(pd)) {
X			int xtmp = d(2,6);
X			kludge("%s suddenly seems weaker!", Monnam(mdef));
X			mdef->mhpmax -= xtmp;
X			if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev--) {
X				kludge("%s dies.", Monnam(mdef));
X				xkilled(mdef,0);
X				return(2);
X			}
X		}
X		tmp = 0;
X		break;
X	    case AD_RUST:
X#ifdef GOLEMS
X		if (pd == &mons[PM_IRON_GOLEM]) {
X			kludge("%s falls to pieces!", Monnam(mdef));
X			xkilled(mdef,0);
X			return(2);
X		}
X#endif /* GOLEMS */
X		tmp = 0;
X		break;
X	    case AD_DCAY:
X#ifdef GOLEMS
X		if (pd == &mons[PM_WOOD_GOLEM] ||
X		    pd == &mons[PM_LEATHER_GOLEM]) {
X			kludge("%s falls to pieces!", Monnam(mdef));
X			xkilled(mdef,0);
X			return(2);
X		}
X#endif /* GOLEMS */
X	    case AD_DRST:
X	    case AD_DRDX:
X	    case AD_DRCO:
X		if (!rn2(8)) {
X		    Your("%s was poisoned!", mattk->aatyp==AT_BITE ?
X			"bite" : "sting");
X		    if (resists_poison(mdef->data))
X			kludge("The poison doesn't seem to affect %s.",
X				mon_nam(mdef));
X		    else {
X			if (!rn2(10)) {
X			    Your("poison was deadly...");
X			    tmp = mdef->mhp;
X			} else tmp += rn1(10,6);
X		    }
X		}
X		break;
X	    case AD_WRAP:
X	    case AD_STCK:
X		if (!sticks(mdef->data))
X		    u.ustuck = mdef; /* it's now stuck to you */
X		break;
X	    default:	tmp = 0;
X			break;
X	}
X	if(!tmp) return(1);
X
X	if((mdef->mhp -= tmp) < 1) {
X
X	    if(mdef->mtame) {
X		if(!Blind) You("killed your %s!", mon_nam(mdef));
X		else	You("feel embarrassed for a moment.");
X	    } else {
X		if(!Blind && flags.verbose)  pline("%s is killed!", Monnam(mdef));
X		else	    You("kill it!");
X	    }
X	    xkilled(mdef, 0);
X	    return(2);
X	}
X	return(1);
X}
X
Xstatic int
Xexplum(mdef, mattk)
Xregister struct monst *mdef;
Xregister struct attack *mattk;
X{
X	switch(mattk->adtyp) {
X	    case AD_BLND:
X		if(mdef->data->mlet != S_YLIGHT) {
X		    kludge("%s is blinded by your flash of light!", Monnam(mdef));
X		    if (!mdef->mblinded) {
X			mdef->mblinded += rn2(25);
X			mdef->mcansee = 0;
X		    }
X		}
X		break;
X	    case AD_COLD:
X		You("explode!");
X		if (!resists_cold(mdef->data)) {
X		    kludge("%s gets blasted!", Monnam(mdef));
X		    mdef->mhp -= d(6,6);
X		    if (mdef->mhp <= 0) {
X			 killed(mdef);
X			 return(2);
X		    }
X#ifdef GOLEMS
X		} else if (is_golem(mdef->data)) {
X		    golemeffects(mdef, AD_COLD, d(6,6));
X		    shieldeff(mdef->mx, mdef->my);
X#endif /* GOLEMS */
X		} else {
X		    shieldeff(mdef->mx, mdef->my);
X		    kludge("The blast doesn't seem to affect %s.",
X			   mon_nam(mdef));
X		}
X		break;
X	    default:	break;
X	}
X	return(1);
X}
X
Xstatic int
Xgulpum(mdef,mattk)
Xregister struct monst *mdef;
Xregister struct attack *mattk;
X{
X	register int tmp;
X	register int dam = d((int)mattk->damn, (int)mattk->damd);
X	/* Not totally the same as for real monsters.  Specifically, these
X	 * don't take multiple moves.  (It's just too hard, for too little
X	 * result, to program monsters which attack from inside you, which
X	 * would be necessary if done accurately.)  Instead, we arbitrarily
X	 * kill the monster immediately for AD_DGST and we regurgitate them
X	 * after exactly 1 round of attack otherwise.  -KAA
X	 */
X
X#ifdef WORM
X	if(mdef->wormno) return 0;
X#endif
X	if(u.uhunger < 1500 && !u.uswallow) {
X
X	    if(mdef->data->mlet != S_COCKATRICE) {
X#ifdef LINT	/* static char msgbuf[BUFSZ]; */
X		char msgbuf[BUFSZ];
X#else
X		static char msgbuf[BUFSZ];
X#endif
X/* TODO: get the symbol display also to work (monster symbol is removed from
X * the screen and you moved onto it, then you get moved back and it gets
X * moved back if the monster survives--just like when monsters swallow you.
X */
X		kludge("You engulf %s!", mon_nam(mdef));
X		switch(mattk->adtyp) {
X		    case AD_DGST:
X			u.uhunger += 20*mdef->mhpmax;
X			newuhs(FALSE);
X			xkilled(mdef,2);
X			Sprintf(msgbuf, "You totally digest %s.",
X					Blind ? "it" : mon_nam(mdef));
X			if ((tmp = mdef->mhpmax/5)) {
X			    kludge("You digest %s.", mon_nam(mdef));
X			    nomul(-tmp);
X			    nomovemsg = msgbuf;
X			} else pline(msgbuf);
X			return(2);
X		    case AD_PHYS:
X			kludge("%s is pummeled with your debris!",Monnam(mdef));
X			break;
X		    case AD_ACID:
X			kludge("%s is covered with your goo!", Monnam(mdef));
X			if (resists_acid(mdef->data)) {
X			    kludge("It seems harmless to %s.", mon_nam(mdef));
X			    dam = 0;
X			}
X			break;
X		    case AD_BLND:
X			if (mdef->mcansee)
X			    kludge("%s can't see in there!", Monnam(mdef));
X			mdef->mcansee = 0;
X			dam += mdef->mblinded;
X			if (dam > 127) dam = 127;
X			mdef->mblinded = dam;
X			dam = 0;
X			break;
X		    case AD_ELEC:
X			if (rn2(2)) {
X			    kludge("The air around %s crackles with electricity.", mon_nam(mdef));
X			    if (resists_elec(mdef->data)) {
X				kludge("%s seems unhurt.", Monnam(mdef));
X				dam = 0;
X			    }
X#ifdef GOLEMS
X			    golemeffects(mdef,(int)mattk->adtyp,dam);
X#endif
X			} else dam = 0;
X			break;
X		    case AD_COLD:
X			if (rn2(2)) {
X			    if (resists_cold(mdef->data)) {
X				kludge("%s seems mildly chilly.", Monnam(mdef));
X				dam = 0;
X			    } else
X				kludge("%s is freezing to death!",Monnam(mdef));
X#ifdef GOLEMS
X			    golemeffects(mdef,(int)mattk->adtyp,dam);
X#endif
X			} else dam = 0;
X			break;
X		    case AD_FIRE:
X			if (rn2(2)) {
X			    if (resists_fire(mdef->data)) {
X				kludge("%s seems mildly hot.", Monnam(mdef));
X				dam = 0;
X			    } else
X				kludge("%s is burning to a crisp!",Monnam(mdef));
X#ifdef GOLEMS
X			    golemeffects(mdef,(int)mattk->adtyp,dam);
X#endif
X			} else dam = 0;
X			break;
X		}
X		if ((mdef->mhp -= dam) <= 0) {
X		    kludge("%s is killed!", Monnam(mdef));
X		    xkilled(mdef,0);
X		    return(2);
X		}
X		kludge("You regurgitate %s!", mon_nam(mdef));
X		if (Blind)
X		    pline("Obviously, you didn't like its taste.");
X		else
X		    pline("Obviously, you didn't like %s's taste.",
X								mon_nam(mdef));
X	    } else {
X		kludge("You bite into %s", mon_nam(mdef));
X		You("turn to stone...");
X		killer = "poor choice of food";
X		done("stoned");
X	    }
X	}
X	return(0);
X}
X
Xstatic void
Xmissum(mdef)
Xregister struct monst *mdef;
X{
X#ifdef POLYSELF
X	if (u.usym==S_NYMPH
X#  ifdef SEDUCE
X|| ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mdef))
X#  endif
X									)
X		kludge("You pretend to be friendly to %s.", mon_nam(mdef));
X	else
X#endif
X	if(!Blind && flags.verbose)  You("miss %s.", mon_nam(mdef));
X	else	    You("miss it.");
X	if(is_human(mdef->data) && !(mdef->msleep || mdef->mfroz))
X		wakeup(mdef);
X}
X
Xstatic boolean
Xhmonas(mon, tmp)		/* attack monster as a monster. */
Xregister struct monst *mon;
Xregister int tmp;
X{
X	register struct attack *mattk;
X	int	i, sum[NATTK];
X	int	nsum = 0;
X	schar	dhit;
X
X	for(i = 0; i < NATTK; i++) {
X
X	    mattk = &(uasmon->mattk[i]);
X	    switch(mattk->aatyp) {
X		case AT_WEAP:
Xuse_weapon:
X	/* Certain monsters don't use weapons when encountered as enemies,
X	 * but players who polymorph into them have hands or claws and thus
X	 * should be able to use weapons.  This shouldn't prohibit the use
X	 * of most special abilities, either.
X	 */
X	/* Potential problem: if the monster gets multiple weapon attacks,
X	 * we currently allow the player to get each of these as a weapon
X	 * attack.  Is this really desirable?
X	 */
X			if(uwep) tmp += hitval(uwep, mon->data);
X			dhit = !((tmp <= rnd(20)) && !u.uswallow);
X			/* Enemy dead, before any special abilities used */
X			if (!known_hitum(mon,dhit)) return 0;
X			/* Do not print "You hit" message, since known_hitum
X			 * already did it.
X			 */
X			if (dhit && mattk->adtyp != AD_SPEL
X				&& mattk->adtyp != AD_PHYS)
X				sum[i] = damageum(mon,mattk);
X			else sum[i] = 0;
X			break;
X		case AT_CLAW:
X			if (i==0 && uwep && humanoid(uasmon)) goto use_weapon;
X		case AT_KICK:
X		case AT_BITE:
X		case AT_STNG:
X		case AT_TUCH:
X		case AT_BUTT:
X			if (i==0 && uwep && (u.usym==S_LICH
X				)) goto use_weapon;
X			if(dhit = (tmp > rnd(20) || u.uswallow)) {
X/* <----- <----- <----- <----- <----- <----- <----- <----- <----- */
Xif (!u.uswallow && (u.usym==S_NYMPH
X#ifdef SEDUCE
X  || ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mon))
X#endif
X									)) {
X		kludge("You %s %s %s.", mon->mblinded ? "talk to" : "smile at",
X			mon_nam(mon),
X			incompatible(mon) ? "engagingly" : "seductively");
X}
X/* <----- <----- <----- <----- <----- <----- <----- <----- <----- */
X				else if (mattk->aatyp == AT_KICK)
X					kludge("You kick %s.", mon_nam(mon));
X				else if (mattk->aatyp == AT_BITE)
X					kludge("You bite %s.", mon_nam(mon));
X				else if (mattk->aatyp == AT_STNG)
X					kludge("You sting %s.", mon_nam(mon));
X				else if (mattk->aatyp == AT_BUTT)
X					kludge("You butt %s.", mon_nam(mon));
X				else if (mattk->aatyp == AT_TUCH)
X					kludge("You touch %s.", mon_nam(mon));
X				else kludge("You hit %s.", mon_nam(mon));
X				sum[i] = damageum(mon, mattk);
X			} else {
X				missum(mon);
X				sum[i] = 0;
X			}
X			break;
X
X		case AT_HUGS:
X			/* automatic if prev two attacks succeed, or if
X			 * already grabbed in a previous attack
X			 */
X			dhit = 1;
X			if (sticks(mon->data)) sum[i] = 0;
X			else if (mon==u.ustuck) {
X			    kludge("%s is being %s.", Monnam(mon),
X#ifdef GOLEMS
X				u.umonnum==PM_ROPE_GOLEM ? "choked":
X#endif
X				"crushed");
X			    sum[i] = damageum(mon, mattk);
X			} else if(sum[i-1] && sum[i-2]) {
X			    kludge("You grab %s!", mon_nam(mon));
X			    u.ustuck = mon;
X			    sum[i] = damageum(mon, mattk);
X			} else sum[i] = 0;
X			break;
X
X		case AT_EXPL:	/* automatic hit if next to */
X			dhit = -1;
X			sum[i] = explum(mon, mattk);
X			break;
X
X		case AT_ENGL:
X			if((dhit = (tmp > rnd(20+i))))
X				sum[i]= gulpum(mon,mattk);
X			else {
X				missum(mon);
X				sum[i] = 0;
X			}
X			break;
X
X		case AT_MAGC:
X			/* No check for uwep; if wielding nothing we want to
X			 * do the normal 1-2 points bare hand damage...
X			 */
X			if (i==0 && (u.usym==S_KOBOLD
X				|| u.usym==S_ORC
X				|| u.usym==S_GNOME
X				)) goto use_weapon;
X
X		case AT_NONE:
X			sum[i] = 0;
X			continue;
X			/* Not break--avoid passive attacks from enemy */
X
X		default: /* Strange... */
X			impossible("strange attack of yours (%d)",
X				 mattk->aatyp);
X		case AT_BREA:
X		case AT_SPIT:
X		case AT_GAZE:	/* all done using #monster command */
X			sum[i] = dhit = 0;
X			break;
X	    }
X	    if (dhit == -1)
X		rehumanize();
X	    if(sum[i] == 2) return(passive(mon, 1, 0)); /* defender dead */
X	    else {
X		(void) passive(mon, sum[i], 1);
X		nsum |= sum[i];
X	    }
X	    if (uasmon == &playermon)
X		break; /* No extra attacks if no longer a monster */
X	    if (multi < 0)
X		break; /* If paralyzed while attacking, i.e. floating eye */
X	}
X	return(nsum);
X}
X
X#endif
X
X/*	Special (passive) attacks on you by monsters done here.		*/
X
Xstatic int
Xpassive(mon, mhit, malive)
Xregister struct monst *mon;
Xregister boolean mhit;
Xregister int malive;
X{
X	register struct permonst *ptr = mon->data;
X	register int i, tmp;
X
X	for(i = 0; ; i++) {
X	    if(i >= NATTK) return(malive | mhit);	/* no passive attacks */
X	    if(ptr->mattk[i].aatyp == AT_NONE) break;	/* try this one */
X	}
X
X/*	These affect you even if they just died */
X
X	switch(ptr->mattk[i].adtyp) {
X
X	  case AD_ACID:
X	    if(mhit && rn2(2)) {
X		if (Blind || !flags.verbose) You("are splashed!");
X		else	You("are splashed by %s's acid!", mon_nam(mon));
X
X		tmp = d((int)mon->m_lev, (int)ptr->mattk[i].damd);
X#ifdef POLYSELF
X		if(!resists_acid(uasmon))
X#endif
X			mdamageu(mon, tmp);
X		if(!rn2(30)) corrode_armor();
X	    }
X	    if(mhit && !rn2(6)) corrode_weapon();
X	    break;
X	  case AD_MAGM:
X	    /* wrath of gods for attacking Oracle */
X	    if(Antimagic) {
X		shieldeff(u.ux, u.uy);
X		pline("A hail of magic missiles narrowly misses you!");
X	    } else {
X		tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
X		You("are hit by magic missiles appearing from thin air!");
X		mdamageu(mon, tmp);
X	    }
X	    break;
X	  default:
X	    break;
X	}
X
X/*	These only affect you if they still live */
X
X	if(malive && !mon->mcan && rn2(3)) {
X
X	    switch(ptr->mattk[i].adtyp) {
X
X	      case AD_PLYS:		/* specifically floating eye */
X		if(canseemon(mon)) {
X
X		    tmp = -d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
X		    if(mon->mcansee) {
X			if(Reflecting & W_AMUL) {
X			    makeknown(AMULET_OF_REFLECTION);
X			    pline("%s's gaze is reflected by your medallion.",
X				  Monnam(mon));
X			} else if(Reflecting & W_ARMS) {
X			    makeknown(SHIELD_OF_REFLECTION);
X			    pline("%s's gaze is reflected by your shield.",
X				  Monnam(mon));
X			} else {
X			    You("are frozen by %s's gaze!", mon_nam(mon));
X			    nomul((ACURR(A_WIS) > 12 || rn2(4)) ? tmp : -120);
X			}
X		    } else {
X			pline("%s cannot defend itself.", Amonnam(mon,"blind"));
X			if(!rn2(500)) change_luck(-1);
X		    }
X		}
X		break;
X	      case AD_COLD:		/* brown mold or blue jelly */
X		if(dist(mon->mx, mon->my) <= 3) {
X		    tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
X		    if(Cold_resistance) {
X  			shieldeff(u.ux, u.uy);
X			You("feel a mild chill.");
X#ifdef POLYSELF
X#ifdef GOLEMS
X			ugolemeffects(AD_COLD, tmp);
X#endif /* GOLEMS */
X#endif
X			tmp = 0;
X			break;
X		    }
X		    You("are suddenly very cold!");
X		    mdamageu(mon, tmp);
X		/* monster gets stronger with your heat! */
X		    mon->mhp += tmp / 2;
X		    if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp;
X		/* at a certain point, the monster will reproduce! */
X		    if(mon->mhpmax > ((mon->m_lev+1) * 8)) {
X			register struct monst *mtmp;
X
X			if(mtmp = clone_mon(mon)) {
X			    mtmp->mhpmax = mon->mhpmax /= 2;
X			    if(!Blind)
X				pline("%s multiplies from your heat!",
X								Monnam(mon));
X			}
X		    }
X		}
X		break;
X	      case AD_STUN:		/* specifically yellow mold */
X		if(!Stunned)
X		    make_stunned((long)d((int)mon->m_lev+1, (int)ptr->mattk[i].damd), TRUE);
X		break;
X	      case AD_FIRE:
X		if(dist(mon->mx, mon->my) <= 3) {
X		    tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
X		    if(Fire_resistance) {
X  			shieldeff(u.ux, u.uy);
X			You("feel mildly warm.");
X#ifdef POLYSELF
X#ifdef GOLEMS
X			ugolemeffects(AD_FIRE, tmp);
X#endif /* GOLEMS */
X#endif
X			tmp = 0;
X			break;
X		    }
X		    You("are suddenly very hot!");
X		    mdamageu(mon, tmp);
X		}
X		break;
X	      default:
X		break;
X	    }
X	}
X	return(malive | mhit);
X}
END_OF_FILE
if test 33761 -ne `wc -c <'src/uhitm.c'`; then
    echo shar: \"'src/uhitm.c'\" unpacked with wrong size!
fi
# end of 'src/uhitm.c'
fi
echo shar: End of archive 10 \(of 38\).
cp /dev/null ark10isdone
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