[comp.sources.games] v10i056: nethack3p9 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 56
Archive-name: nethack3p9/Part11
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 11 (of 56)."
# Contents:  src/pickup.c src/uhitm.c
# Wrapped by billr@saab on Wed Jul 11 17:11:05 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/pickup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/pickup.c'\"
else
echo shar: Extracting \"'src/pickup.c'\" \(16041 characters\)
sed "s/^X//" >'src/pickup.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)pickup.c	3.0	88/07/12
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X *	Contains code for picking objects up, and container use.
X */
X
X#include	"hack.h"
XSTATIC_PTR int FDECL(in_container,(struct obj *));
XSTATIC_PTR int FDECL(ck_container,(struct obj *));
XSTATIC_PTR int FDECL(ck_bag,(struct obj *));
XSTATIC_PTR int FDECL(out_container,(struct obj *));
Xvoid FDECL(explode_bag,(struct obj *));
X
X#define DELTA_CWT(cont) ((cont)->cursed?(obj->owt*2):(obj->owt/((cont)->blessed?4:2)) + 1)
X
X#ifdef OVL0
X
Xstatic const char nearloadmsg[] = "have a little trouble lifting";
X
Xvoid
Xpickup(all)
Xint all;
X{
X	register struct gold *gold = g_at(u.ux, u.uy);
X	register struct obj *obj, *obj2;
X	register int wt;
X	char buf[BUFSZ];
X	register char *ip;
X	register char sym;
X	register int oletct = 0, iletct = 0;
X	boolean all_of_a_type = FALSE, selective = FALSE;
X	char olets[20], ilets[20];
X	struct obj dummygold;
X
X	dummygold.ox = u.ux;
X	dummygold.oy = u.uy;
X	dummygold.olet = GOLD_SYM;
X	dummygold.nobj = fobj;
X	dummygold.nexthere = level.objects[u.ux][u.uy];
X	dummygold.cobj = 0;
X
X	if(Levitation) {
X		if ((multi && !flags.run) || (all && !flags.pickup))
X			read_engr_at(u.ux,u.uy);
X		return;
X	}
X	/* multi && !flags.run means they are in the middle of some other
X	 * action, or possibly paralyzed, sleeping, etc.... and they just
X	 * teleported onto the object.  They shouldn't pick it up.
X	 */
X	if ((multi && !flags.run) || (all && !flags.pickup)) {
X		int ct = 0;
X
X		for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
X			if(!obj->cobj && obj != uchain)
X				ct++;
X
X		/* Stop on a zorkmid */
X		if (gold) ct++;
X
X		/* If there are objects here, take a look.
X		 */
X		if (ct) {
X			if (flags.run)
X				nomul(0);
X			nscr();
X			if (ct < 5)
X				(void) dolook();
X			else {
X				read_engr_at(u.ux,u.uy);
X				pline("There are several objects here.");
X			}
X		} else read_engr_at(u.ux,u.uy);
X		return;
X	}
X
X	/* check for more than one object */
X	if(!all) {
X		register int ct = 0;
X
X		if (gold) ct++;
X		for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
X			if(!obj->cobj) ct++;
X		if(ct < 2)
X			all++;
X		else
X			pline("There are several objects here.");
X	}
X
X	/* added by GAN 10/24/86 to allow selective picking up */
X	if(!all)  {
X		register struct obj *otmp = level.objects[u.ux][u.uy];
X
X		ilets[iletct] = 0;
X		if(gold) {
X			ilets[iletct++] = GOLD_SYM;
X			ilets[iletct] = 0;
X		}
X		while(otmp) {
X			if(!index(ilets, otmp->olet) && !otmp->cobj) {
X				ilets[iletct++] = otmp->olet;
X				ilets[iletct] = 0;
X			}
X			otmp = otmp->nexthere;
X		}
X		if(iletct == 1)
X			Strcpy(buf,ilets);
X		else  {
X			ilets[iletct++] = ' ';
X			ilets[iletct++] = 'a';
X			ilets[iletct++] = 'A';
X			ilets[iletct] = 0;
X
X			pline("What kinds of thing do you want to pick up? [%s] ", ilets);
X			getlin(buf);
X			if(buf[0] == '\033') {
X				clrlin();
X				return;
X			}
X			else if(!buf[0]) selective = TRUE;
X		}
X		ip = buf;
X		olets[0] = 0;
X		while(sym = *ip++){
X			/* new A function (selective all) added by
X			 * GAN 01/09/87
X			 */
X			if(sym == ' ') continue;
X			if(sym == 'A') selective = TRUE;
X			else if(sym == 'a') all_of_a_type = TRUE;
X			else if(index(ilets, sym)){
X				if(!index(olets, sym)){
X					olets[oletct++] = sym;
X					olets[oletct] = 0;
X				}
X			}
X			else pline("There are no %c's here.", sym);
X		}
X	}
X	if(all_of_a_type && !olets[0]) all = TRUE;
X
X	for(obj = (gold ? &dummygold : level.objects[u.ux][u.uy]); obj;
X			obj = obj2) {
X	    obj2 = obj->nexthere;   /* perhaps obj will be picked up */
X	    if(!obj->cobj) {
X		if(flags.run) nomul(0);
X
X		if(!all)  {
X			char c;
X
X			if(!selective && !index(olets,obj->olet)) continue;
X
X			if (!all_of_a_type) {
X				if (obj == &dummygold)
X					pline("Pick up %ld gold piece%s? ",
X					    gold->amount, plur(gold->amount));
X				else pline("Pick up %s? ", doname(obj));
X				if((c = ynaq()) == 'q') return;
X				if(c == 'n') continue;
X				if(c == 'a') {
X					all_of_a_type = TRUE;
X					if (selective) {
X						selective = FALSE;
X						olets[0] = obj->olet;
X						olets[1] = 0;
X						/* oletct = 1; */
X					}
X				}
X			}
X		}
X
X		if(obj == &dummygold) {
X		    int iw = inv_weight();
X		    long gold_capacity;
X
X#ifndef lint /* long/int conversion */
X		    iw -= (int)((u.ugold + 500)/1000);
X#endif
X		    gold_capacity = ((-iw) * 1000L) - 500 + 999 - u.ugold;
X		    if (gold_capacity <= 0L) {
X	 pline("There %s %ld gold piece%s here, but you cannot carry any more.",
X				(gold->amount == 1) ? "is" : "are",
X				gold->amount, plur(gold->amount));
X			continue;
X		    }
X		    if (gold_capacity >= gold->amount) {
X			u.ugold += gold->amount;
X			if (inv_weight() > -5)
X				You(nearloadmsg);
X			pline("%ld gold piece%s.",
X				gold->amount, plur(gold->amount));
X			freegold(gold);
X			if(Invisible) newsym(u.ux,u.uy);
X		    } else {
X		You("can only carry %s of the %ld gold pieces lying here.",
X			    gold_capacity == 1L ? "one" : "some", gold->amount);
X			You(nearloadmsg);
X			pline("%ld gold piece%s.",
X				 gold_capacity, plur(gold_capacity));
X			u.ugold += gold_capacity;
X			gold->amount -= gold_capacity;
X		    }
X		    flags.botl = 1;
X		    if(flags.run) nomul(0);
X		    continue;
X		}
X
X		if((obj->otyp == CORPSE && obj->corpsenm == PM_COCKATRICE) &&
X		   !uarmg
X#ifdef POLYSELF
X			&& !resists_ston(uasmon)
X#endif
X						) {
X		    pline("Touching the dead cockatrice is a fatal mistake.");
X		    You("turn to stone.");
X		    You("die...");
X		    killer_format = KILLED_BY_AN;
X		    killer = "cockatrice corpse";
X		    done(STONING);
X		}
X
X		if(obj->otyp == SCR_SCARE_MONSTER){
X		  if(obj->blessed) obj->blessed = 0;
X		  else if(!obj->spe && !obj->cursed) obj->spe = 1;
X		  else {
X		    pline("The scroll%s turn%s to dust as you pick %s up.",
X				plur((long)obj->quan), (obj->quan==1) ? "s":"",
X				(obj->quan==1) ? "it" : "them");
X			if(!(objects[SCR_SCARE_MONSTER].oc_name_known) &&
X			   !(objects[SCR_SCARE_MONSTER].oc_uname))
X				docall(obj);
X		    useupf(obj);
X		    continue;
X		  }
X		}
X
X		/* do not pick up uchain */
X		if(obj == uchain)
X			continue;
X
X		wt = inv_weight() + (int)obj->owt;
X		if (obj->otyp == LOADSTONE)
X			goto lift_some; /* pick it up even if too heavy */
X#ifdef POLYSELF
X		if (obj->otyp == BOULDER && throws_rocks(uasmon)) {
X			wt = inv_weight();
X			goto lift_some;
X		}
X#endif
X		if(wt > 0) {
X			if(obj->quan > 1) {
X				/* see how many we can lift */
X				unsigned savequan = obj->quan;
X				int iw = inv_weight();
X				unsigned qq;
X				for(qq = 1; qq < savequan; qq++){
X					obj->quan = qq;
X					if(iw + weight(obj) > 0)
X						break;
X				}
X				obj->quan = savequan;
X				qq--;
X				/* we can carry qq of them */
X				if(qq) {
X				    register struct obj *obj3;
X
X				You("can only carry %s of the %s lying here.",
X					    (qq == 1) ? "one" : "some",
X					    doname(obj));
X				    obj3 = splitobj(obj, (int)qq);
X				    if(obj3->otyp == SCR_SCARE_MONSTER)
X					    if(obj3->spe) obj->spe = 0;
X				    goto lift_some;
X				}
X			}
X			pline("There %s %s here, but %s.",
X				(obj->quan == 1) ? "is" : "are",
X				doname(obj),
X				!invent ? "it is too heavy for you to lift"
X					: "you cannot carry any more");
X				if(obj->otyp == SCR_SCARE_MONSTER)
X					if(obj->spe) obj->spe = 0;
X			break;
X		}
X	lift_some:
X		if(inv_cnt() >= 52) {
X			Your("knapsack cannot accommodate any more items.");
X			if(obj->otyp == SCR_SCARE_MONSTER)
X				if(obj->spe) obj->spe = 0;
X			break;
X		}
X		{ unsigned pickquan = obj->quan;
X		  unsigned mergquan;
X
X		  obj = pick_obj(obj);
X		  if(wt > -5) You(nearloadmsg);
X		  if(!Blind) obj->dknown = 1;
X		  mergquan = obj->quan;
X		  obj->quan = pickquan; /* to fool prinv() */
X		  if(uwep && uwep == obj) mrg_to_wielded = TRUE;
X		  prinv(obj);
X		  mrg_to_wielded = FALSE;
X		  obj->quan = mergquan;
X		}
X	    }
X	}
X}
X
Xstruct obj *
Xpick_obj(otmp)
Xregister struct obj *otmp;
X{
X	if (otmp != uball)	     /* don't charge for this - kd, 1/17/90 */
X		addtobill(otmp, TRUE);       /* sets obj->unpaid if necessary */
X	freeobj(otmp);
X	if(Invisible) newsym(u.ux,u.uy);
X	return(addinv(otmp));    /* might merge it with other objects */
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xint
Xdoloot() {	/* loot a container on the floor. */
X
X	register struct obj *cobj, *nobj;
X	register int c;
X
X	if (Levitation) {
X		You("cannot reach the floor.");
X		return(0);
X	}
X	for(cobj = level.objects[u.ux][u.uy]; cobj; cobj = nobj) {
X	        nobj = cobj->nexthere;
X
X		if(Is_container(cobj)) {
X
X		    pline("There is %s here, loot it? ", doname(cobj));
X		    c = ynq();
X		    if(c == 'q') return 0;
X		    if(c == 'n') continue;
X
X		    if(cobj->olocked) {
X
X			pline("Hmmm, it seems to be locked.");
X			continue;
X		    }
X		    if(cobj->otyp == BAG_OF_TRICKS) {
X
X			You("carefully open the bag...");
X			pline("It develops a huge set of teeth and bites you!");
X			losehp(rnd(10), "carnivorous bag", KILLED_BY_AN);
X			makeknown(BAG_OF_TRICKS);
X			continue;
X		    }
X
X		    You("carefully open the %s...", xname(cobj));
X		    if(cobj->otrapped && chest_trap(cobj, FINGER)) /* don't use obj if obj dies */
X		      continue;
X		    if(multi < 0) return 0; /* a paralysis trap */
X
X		    use_container(cobj, 0);
X		}
X	}
X	return 0;
X}
X
Xstatic
Xstruct obj NEARDATA *current_container;	/* a local variable of use_container, to be
X				used by its local procedures in/ck_container */
X#define Icebox (current_container->otyp == ICE_BOX)
Xint baggone;	/* used in askchain so bag isn't used after explosion */
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xvoid
Xinc_cwt(cobj, obj)
Xregister struct obj *cobj, *obj;
X{
X	if (cobj->otyp == BAG_OF_HOLDING)
X		cobj->owt += DELTA_CWT(cobj);
X	else	cobj->owt += obj->owt;
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
XSTATIC_PTR int
Xin_container(obj)
Xregister struct obj *obj;
X{
X	char buf[BUFSZ];
X
X	if(obj == uball || obj == uchain) {
X		You("must be kidding.");
X		return(0);
X	}
X	if(obj == current_container) {
X		pline("That would be an interesting topological exercise.");
X		return(0);
X	}
X	if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) {
X		You("cannot %s something you are wearing.",
X			Icebox ? "refrigerate" : "stash");
X		return(0);
X	}
X	if((obj->otyp == LOADSTONE) && obj->cursed) {
X		obj->bknown = 1;
X		pline("The stone%s won't leave your person.",
X			plur((long)obj->quan));
X		return(0);
X	}
X	/* Prohibit Amulets in containers; if you allow it, monsters can't
X	 * steal them.  It also becomes a pain to check to see if someone
X	 * has the Amulet.
X	 */
X	if(obj->otyp == AMULET_OF_YENDOR && !obj->spe) {
X	    pline("The Amulet of Yendor cannot be confined in such trappings.");
X	    return(0);
X	}
X	/* no nested containers - they do not save/restore properly. */
X	/* magic bag -> magic bag will self destruct later on. */
X	if(Is_container(obj) && Is_container(current_container) &&
X	    (!Is_mbag(obj) || !Is_mbag(current_container))) {
X		pline("The %s won't go in.", xname(obj));
X		return(1);	/* be careful! */
X	}
X	if(obj == uwep) {
X		if(welded(obj)) {
X			weldmsg(obj, FALSE);
X			return(0);
X		}
X		setuwep((struct obj *) 0);
X		if (uwep) return(0); /* unwielded, died, rewielded */
X	}
X#ifdef WALKIES
X	if(obj->otyp == LEASH && obj->leashmon != 0) {
X		pline("The %s is attached to your pet.", xname(obj));
X		return(0);
X	}
X#endif
X	inc_cwt(current_container, obj);
X	freeinv(obj);
X
X	obj->cobj = current_container;
X	obj->nobj = fcobj;
X	fcobj = obj;
X	Strcpy(buf, xname(obj->cobj));
X	You("put %s into the %s.", doname(obj), buf);
X
X	if(Icebox) obj->age = monstermoves - obj->age; /* actual age */
X
X	else if(Is_mbag(obj->cobj) &&
X		(Is_mbag(obj) ||
X		 (obj->otyp == WAN_CANCELLATION && (obj->spe > 0)) )) {
X		explode_bag(obj);
X		You("are blasted by a magical explosion!");
X		losehp(d(6,6),"magical explosion", KILLED_BY_AN);
X		baggone = 1;
X	}
X	return(1);
X}
X
XSTATIC_PTR int
Xck_container(obj)
Xregister struct obj *obj;
X{
X	return(obj->cobj == current_container);
X}
X
X/* ck_bag() needs a formal argument to make the overlay/prototype mechanism
X * work right */
X/*ARGSUSED*/
XSTATIC_PTR int
Xck_bag(obj)
Xstruct obj *obj;
X{
X	return(!baggone);
X}
X
XSTATIC_PTR int
Xout_container(obj)
Xregister struct obj *obj;
X{
X	register struct obj *otmp, *ootmp;
X	register boolean near_capacity = (inv_weight() > -5);
X
X	if(inv_cnt() >= 52) {
X		pline("You have no room to hold anything else.");
X		return(0);
X	}
X	if(obj->otyp != LOADSTONE && inv_weight() + (int)obj->owt -
X	   (carried(current_container) ?
X		(current_container->otyp == BAG_OF_HOLDING ?
X		    (int)DELTA_CWT(current_container) : (int)obj->owt) : 0) > 0) {
X		char buf[BUFSZ];
X
X		Strcpy(buf, doname(obj));
X		pline("There %s %s in the %s, but %s.",
X			obj->quan==1 ? "is" : "are",
X			buf, xname(current_container),
X			invent ? "you cannot carry any more"
X			: "it is too heavy for you to carry");
X		/* "too heavy for you to lift" is not right if you're carrying
X		   the container... */
X		return(0);
X	}
X	if(obj == fcobj) fcobj = fcobj->nobj;
X	else {
X		for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj)
X			if(!otmp->nobj) panic("out_container");
X		otmp->nobj = obj->nobj;
X	}
X	dec_cwt(current_container, obj);
X	obj->cobj = (struct obj *) 0;
X
X	if (Icebox) obj->age = monstermoves - obj->age;
X	/* simulated point of time */
X
X	ootmp = addinv(obj);
X	if (near_capacity) You("have a little trouble removing");
X	prinv(ootmp);
X	return 0;
X}
X
X/* for getobj: 0: allow cnt; #: allow all types; %: expect food */
Xstatic const char NEARDATA frozen_food[] = { '0', '#', FOOD_SYM, 0 };
X
Xvoid
Xuse_container(obj, held)
Xregister struct obj *obj;
Xregister int held;
X{
X	register int cnt = 0;
X	register struct obj *otmp;
X	register struct obj *backobj;
X
X	current_container = obj;	/* for use by in/out_container */
X	if(current_container->olocked) {
X		pline("The %s seems to be locked.", xname(current_container));
X		return;
X	}
X	for(otmp = fcobj, backobj = (struct obj *) 0; otmp;
X	    backobj = otmp, otmp = otmp->nobj)
X		if(otmp->cobj == obj)
X		    if(Is_mbag(obj) && obj->cursed && !rn2(13)) {
X			if (otmp->known)
X				pline("The %s to have vanished!",
X							aobjnam(otmp,"seem"));
X			else You("%s %s disappear.",
X				Blind ? "notice" : "see",
X				doname(otmp));
X			if(!backobj) {
X			    fcobj = otmp->nobj;
X			    dec_cwt(current_container, otmp);
X			    obfree(otmp, (struct obj *) 0);
X			    otmp = fcobj;
X			} else {
X			    backobj->nobj = otmp->nobj;
X			    dec_cwt(current_container, otmp);
X			    obfree(otmp, (struct obj *) 0);
X			    otmp = backobj->nobj;
X			}
X			if (!otmp) break;
X			if(otmp->cobj == obj) cnt++;
X		    } else cnt++;
X	if(!cnt)
X	    pline("%s %s is empty.", (held) ? "Your" : "The", xname(obj));
X	else if (inv_cnt() < 52) {
X	    pline("Do you want to take something out of the %s? ",
X		  xname(obj));
X	    if(yn() != 'n')
X		if(askchain(fcobj, FALSE, NULL, 0, out_container, ck_container, 0, "nodot"))
X		    return;
X	}
X	if(!invent) return;
X	pline("Do you wish to put something in? ");
X	if(yn() != 'y') return;
X	if (Icebox && current_container->dknown) {
X		otmp = getobj(frozen_food, "put in");
X		if(!otmp || !in_container(otmp))
X			flags.move = multi = 0;
X	} else {
X		baggone = 0; /* might be set by in_container */
X		if(askchain(invent, TRUE, NULL, 0, in_container, ck_bag, 0, "nodot"))
X		  return;
X	}
X	return;
X}
X
Xvoid
Xdelete_contents(obj)
Xregister struct obj *obj;
X{
X	register struct obj *otmp, *notmp;
X
X	while (fcobj && fcobj->cobj == obj) {
X		otmp = fcobj;
X		fcobj = fcobj->nobj;
X		obfree(otmp,(struct obj *)0);
X	}
X	if (fcobj) {
X		otmp = fcobj;
X		while(otmp->nobj)
X			if (otmp->nobj->cobj == obj) {
X				notmp = otmp->nobj;
X				otmp->nobj = notmp->nobj;
X				obfree(notmp,(struct obj *)0);
X			} else
X				otmp = otmp->nobj;
X	}
X}
X
Xvoid
Xexplode_bag(obj)
Xstruct obj *obj;
X{
X	struct obj *otmp, *cobj;
X
X	cobj = obj->cobj;
X	delete_contents(cobj);
X
X	for (otmp = invent; otmp; otmp = otmp->nobj)
X		if (otmp == cobj) break;
X
X	if (otmp) {
X		You("see your %s blow apart!", xname(otmp));
X		useup(otmp);
X		/*return(0);*/
X	} else	panic("explode_bag: bag not in invent.");
X}
X
Xvoid
Xdec_cwt(cobj, obj)
Xregister struct obj *cobj, *obj;
X{
X	if (cobj->otyp == BAG_OF_HOLDING)
X		cobj->owt -= DELTA_CWT(cobj);
X	else	cobj->owt -= obj->owt;
X
X	if(cobj->owt < objects[cobj->otyp].oc_weight)
X		cobj->owt = objects[cobj->otyp].oc_weight;
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 16041 -ne `wc -c <'src/pickup.c'`; then
    echo shar: \"'src/pickup.c'\" unpacked with wrong size!
fi
# end of 'src/pickup.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'\" \(39521 characters\)
sed "s/^X//" >'src/uhitm.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)uhitm.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 boolean FDECL(known_hitum, (struct monst *,int));
Xstatic boolean FDECL(hitum, (struct monst *,int));
X#ifdef POLYSELF
Xstatic int FDECL(explum, (struct monst *,struct attack *));
Xstatic int FDECL(gulpum, (struct monst *,struct attack *));
Xstatic boolean FDECL(hmonas, (struct monst *,int));
X#endif
Xstatic void FDECL(nohandglow, (struct monst *));
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	if (!enexto(&mm, mm.x, mm.y, mon->data)) return (struct monst *)0;
X	if (MON_AT(mm.x, mm.y) || 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	place_monster(m2, m2->mx, m2->my);
X	if (mon->mtame) {
X	    struct monst *m3;
X
X	    if (m3 = tamedog(m2, (struct obj *)0))
X		m2 = m3;
X	}
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#ifdef MACOS
X			char mac_tbuf[80];
X			if(!flags.silent) SysBeep(1);
X			Sprintf(mac_tbuf, "Really attack %s?", mon_nam(mtmp));
X			if(UseMacAlertText(128, mac_tbuf) != 1) {
X#else
X			pline("Really attack %s? ", mon_nam(mtmp));
X			(void) fflush(stdout);
X			if (yn() != 'y') {
X#endif
X				flags.move = 0;
X				return(TRUE);
X			}
X		}
X	}
X
X	if(mtmp->mimic && !Protection_from_shape_changers) {
X		stumble_onto_mimic(mtmp);
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(Blind) pline("Wait!  There's a hidden monster there!");
X		    else if(OBJ_AT(mtmp->mx, mtmp->my)) {
X			if(obj = level.objects[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
Xschar
Xfind_roll_to_hit(mtmp)
Xregister struct monst *mtmp;
X{
X	schar tmp;
X	struct permonst *mdat = mtmp->data;
X
X#ifdef POLYSELF
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/*	it is unchivalrous to attack the defenseless or from behind */
X	if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL &&
X	    (!mtmp->mcanmove || 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->mcanmove) {
X		tmp += 4;
X		if(!rn2(10)) {
X			mtmp->mcanmove = 1;
X			mtmp->mfrozen = 0;
X		}
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#ifdef POLYSELF
X/*	Some monsters have a combination of weapon attacks and non-weapon
X *	attacks.  It is therefore wrong to add hitval to tmp; we must add it
X *	only for the specific attack (in hmonas()).
X */
X	if(uwep && u.umonnum == -1) tmp += hitval(uwep, mdat);
X#else
X	if(uwep) tmp += hitval(uwep, mdat);
X#endif
X	return tmp;
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->mfrozen && !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 (!Confusion && !Hallucination && flags.safe_dog &&
X	    (Blind ? Telepat : (!mtmp->minvis || See_invisible)) &&
X								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#endif
X
X	tmp = find_roll_to_hit(mtmp);
X#ifdef POLYSELF
X	if (u.umonnum >= 0) (void) hmonas(mtmp, tmp);
X	else
X#endif
X	    (void) hitum(mtmp, tmp);
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(!mon->msleep && mon->mcanmove)
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 NEARDATA malive;
X	boolean mhit = (tmp > rnd(20) || u.uswallow);
X
X	malive = known_hitum(mon, mhit);
X	(void) passive(mon, mhit, malive, FALSE);
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	struct permonst *mdat = mon->data;
X	/* Why all these booleans?  This stuff has to be done in the
X	 *      following order:
X	 * 1) Know what we're attacking with, and print special hittxt for
X	 *	unusual cases.
X	 * 2a) Know whether we did damage (depends on 1)
X	 * 2b) Know if it's poisoned (depends on 1)
X	 * 2c) Know whether we get a normal damage bonus or not (depends on 1)
X	 * 3a) Know what the value of the damage bonus is (depends on 2c)
X	 * 3b) Know how much poison damage was taken (depends on 2b) and if the
X	 *	poison instant-killed it
X	 * 4) Know if it was killed (requires knowing 3a, 3b) except by instant-
X	 *	kill poison
X	 * 5) Print hit message (depends on 1 and 4)
X	 * 6a) Print poison message (must be done after 5)
X#if 0
X	 * 6b) Rust weapon (must be done after 5)
X#endif
X	 * 7) Possibly kill monster (must be done after 6a, 6b)
X	 * 8) Instant-kill from poison (can happen anywhere between 5 and 9)
X	 * 9) Hands not glowing (must be done after 7 and 8)
X	 * The major problem is that since we don't want a "hit" message
X	 * when the monster dies, we have to know how much damage it did
X	 * _before_ outputting a hit message, but any messages associated with
X	 * the damage don't come out until _after_ outputting a hit message.
X	 */
X	boolean hittxt = FALSE, destroyed = FALSE;
X	boolean get_dmg_bonus = TRUE;
X	boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE;
X	boolean silvermsg = FALSE;
X
X	wakeup(mon);
X	if(!obj) {
X	    tmp = rnd(2);	/* attack with bare hands */
X#if 0
X	    if(mdat == &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		hittxt = TRUE; /* maybe lifesaved */
X	    }
X#endif
X	} else {
X	    if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
X	       obj->otyp == UNICORN_HORN || obj->olet == ROCK_SYM) {
X
X		if(obj == uwep && (obj->otyp >= BOW || obj->otyp < BOOMERANG)
X			&& obj->otyp != PICK_AXE && obj->otyp != UNICORN_HORN)
X		    tmp = rnd(2);
X		else {
X		    tmp = dmgval(obj, mdat);
X#ifdef NAMED_ITEMS
X		    if(spec_ability(obj, SPFX_DRLI) && !resists_drli(mdat)) {
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		    if(thrown && obj->otyp == SILVER_ARROW) {
X			if (is_were(mdat) || mdat->mlet==S_VAMPIRE
X			    || (mdat->mlet==S_IMP && mdat != &mons[PM_TENGU])
X			    || is_demon(mdat)) {
X				silvermsg = TRUE;
X				tmp += rnd(20);
X			}
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			hittxt = TRUE;
X			tmp = 1;
X			break;
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(mdat)) {
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			    nohandglow(mon);
X			    return(FALSE);
X			}
X			tmp = mons[obj->corpsenm].msize + 1;
X			break;
X		case EGG: /* only possible if hand-to-hand */
X			if(obj->corpsenm > -1
X					&& obj->corpsenm != PM_COCKATRICE
X					&& mdat == &mons[PM_COCKATRICE]) {
X				kludge("You hit %s with the %s egg%s.",
X					mon_nam(mon),
X					mons[obj->corpsenm].mname,
X					plur((long)obj->quan));
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(mdat)) 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(mdat) &&
X				    mdat != &mons[PM_FLOATING_EYE])
X				? "'s face" : "");
X			if(mon->msleep) mon->msleep = 0;
X			setmangry(mon);
X			mon->mcansee = 0;
X			tmp = rnd(25) + 20;
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(mdat)) {
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, mdat);
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(!thrown || !obj || !uwep ||
X			(obj->olet != GEM_SYM && obj->olet != WEAPON_SYM) ||
X			!objects[obj->otyp].w_propellor ||
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	    if(resists_poison(mdat))
X		needpoismsg = TRUE;
X	    else if (rn2(10))
X		tmp += rnd(6);
X	    else poiskilled = TRUE;
X	}
X	if(tmp < 1) tmp = 1;
X
X	mon->mhp -= tmp;
X	if(mon->mhp < 1)
X		destroyed = TRUE;
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((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
X		   && obj && obj == uwep
X		   && objects[obj->otyp].oc_material == METAL
X		   && mon->mhp > 1 && !thrown && !mon->mcan
X		   /* && !destroyed  -- guaranteed by mhp > 1 */ ) {
X
X		if (clone_mon(mon)) {
X			kludge("%s divides as you hit it!", Monnam(mon));
X			hittxt = TRUE;
X		}
X	}
X
X	if(!hittxt && !destroyed) {
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 (silvermsg) {
X		if (cansee(mon->mx, mon->my))
X			pline("The silver arrow sears %s's flesh!",
X				mon_nam(mon));
X		else
X			pline("Its flesh is seared!");
X	}
X
X	if (needpoismsg)
X		kludge("The poison doesn't seem to affect %s.", mon_nam(mon));
X	if (poiskilled) {
X		pline("The poison was deadly...");
X		xkilled(mon, 0);
X		nohandglow(mon);
X		return FALSE;
X	} else if (destroyed) {
X		killed(mon);	/* takes care of most messages */
X		nohandglow(mon);
X	} else if(u.umconf && !thrown) {
X		nohandglow(mon);
X		if(!resist(mon, '+', 0, NOTELL)) mon->mconf = 1;
X		if(!mon->mstun && mon->mcanmove && !mon->msleep &&
X		   !Blind && mon->mconf)
X			pline("%s appears confused.", Monnam(mon));
X	}
X
X#if 0
X	if(mdat == &mons[PM_RUST_MONSTER] && obj && obj == uwep &&
X		objects[obj->otyp].oc_material == METAL &&
X		obj->olet == WEAPON_SYM && 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(obj, "corrode"));
X		obj->spe--;
X	    }
X	}
X#endif
X
X	return(destroyed ? FALSE : TRUE);
X}
X
X#ifdef POLYSELF
X
Xint
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 INFERNO
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 = makemon(!rn2(6) ? &mons[ndemon()] : uasmon, 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_HEAL:
X	    case AD_LEGS:
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		if(!Blind) pline("%s is on fire!", Monnam(mdef));
X		tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE);
X# ifdef SPELLS
X		tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE);
X# endif
X		if(resists_fire(pd)) {
X		    if (!Blind)
X			pline("The fire doesn't heat %s!", mon_nam(mdef));
X# ifdef GOLEMS
X		    golemeffects(mdef, AD_FIRE, tmp);
X# endif /* GOLEMS */
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		}
X		/* only potions damage resistant players in destroy_item */
X		tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE);
X		break;
X	    case AD_COLD:
X		if(!Blind) pline("%s is covered in frost!", Monnam(mdef));
X		if(resists_cold(pd)) {
X		    shieldeff(mdef->mx, mdef->my);
X		    if (!Blind)
X			pline("The frost doesn't chill %s!", mon_nam(mdef));
X# ifdef GOLEMS
X		    golemeffects(mdef, AD_COLD, tmp);
X# endif /* GOLEMS */
X		    tmp = 0;
X		}
X		tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD);
X		break;
X	    case AD_ELEC:
X		if (!Blind) pline("%s is zapped!", Monnam(mdef));
X		tmp += destroy_mitem(mdef, WAND_SYM, AD_ELEC);
X		if(resists_elec(pd)) {
X		    if (!Blind)
X			pline("The zap doesn't shock %s!", mon_nam(mdef));
X# ifdef GOLEMS
X		    golemeffects(mdef, AD_ELEC, tmp);
X# endif /* GOLEMS */
X		    shieldeff(mdef->mx, mdef->my);
X		    tmp = 0;
X		}
X		/* only rings damage resistant players in destroy_item */
X		tmp += destroy_mitem(mdef, RING_SYM, AD_ELEC);
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
X		    stealoid = (struct obj *)0;
X		    if(is_mercenary(pd) && could_seduce(&youmonst,mdef,mattk)){
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				/* set dknown to insure proper merge */
X				if (!Blind) otmp->dknown = 1;
X				if (!stolen && otmp==stealoid) {
X					otmp = addinv(otmp);
X					if(inv_cnt() > 52)
X						dropx(otmp);
X					stealoid = otmp;
X					stolen = TRUE;
X				} else {
X					otmp = addinv(otmp);
X					if(inv_cnt() > 52) {
X						dropx(otmp);
X						You("steal %s.", doname(otmp));
X					} else {
X						You("steal: ");
X						prinv(otmp);
X					}
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 %s!", doname(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 (!Blind) otmp->dknown = 1;
X			otmp = addinv(otmp);
X			if(inv_cnt() > 52) {
X				dropx(otmp);
X				You("steal %s.", doname(otmp));
X			} else {
X				You("steal: ");
X				prinv(otmp);
X			}
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	    case AD_PLYS:
X		if (mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
X		    if (!Blind) pline("%s is frozen by you!", Monnam(mdef));
X		    mdef->mcanmove = 0;
X		    mdef->mfrozen = rnd(10);
X		}
X		break;
X	    case AD_SLEE:
X		if (!resists_sleep(mdef->data) && !mdef->msleep &&
X							mdef->mcanmove) {
X		    if (!Blind)
X			pline("%s suddenly falls asleep!", Monnam(mdef));
X		    mdef->mcanmove = 0;
X		    mdef->mfrozen = rnd(10);
X		}
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!", lmonnam(mdef) + 4);
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->mcansee) {
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	if(mdef->data->msize >= MZ_HUGE) return 0;
X
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 += mdef->data->cnutrit;
X			newuhs(FALSE);
X			xkilled(mdef,2);
X			Sprintf(msgbuf, "You totally digest %s.",
X					Blind ? "it" : mon_nam(mdef));
X			if (tmp = 3 + (mdef->data->cwt >> 2)) {
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 %s %s!", is_animal(uasmon) ? "regurgitate"
X			: "expel", mon_nam(mdef));
X		if (is_animal(uasmon)) {
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		}
X	    } else {
X		kludge("You bite into %s", mon_nam(mdef));
X		You("turn to stone...");
X		killer_format = KILLED_BY;
X		killer = "swallowing a cockatrice whole";
X		done(STONING);
X	    }
X	}
X	return(0);
X}
X
Xvoid
Xmissum(mdef,mattk)
Xregister struct monst *mdef;
Xregister struct attack *mattk;
X{
X	if (could_seduce(&youmonst, mdef, mattk))
X		kludge("You pretend to be friendly to %s.", mon_nam(mdef));
X	else if(!Blind && flags.verbose)
X		You("miss %s.", mon_nam(mdef));
X	else
X		You("miss it.");
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	    sum[i] = 0;
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			break;
X		case AT_CLAW:
X			if (i==0 && uwep && !cantwield(uasmon)) goto use_weapon;
X# ifdef SEDUCE
X			/* succubi/incubi are humanoid, but their _second_
X			 * attack is AT_CLAW, not their first...
X			 */
X			if (i==1 && uwep && (u.umonnum == PM_SUCCUBUS ||
X				u.umonnum == PM_INCUBUS)) goto use_weapon;
X# endif
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)) goto use_weapon;
X			if(dhit = (tmp > rnd(20) || u.uswallow)) {
X				int compat;
X
X				if (!u.uswallow &&
X				    (compat = could_seduce(&youmonst,
X							    mon, mattk)))
X				You("%s %s %s.",
X				    mon->mcansee ? "smile at" : "talk to",
X				    Blind ? "it" : mon_nam(mon),
X				    compat == 2 ? "engagingly" : "seductively");
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, mattk);
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))
X			    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			    }
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, mattk);
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			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			dhit = 0;
X			break;
X	    }
X	    if (dhit == -1)
X		rehumanize();
X	    if(sum[i] == 2) return(passive(mon, 1, 0, (mattk->aatyp==AT_KICK)));
X							/* defender dead */
X	    else {
X		(void) passive(mon, sum[i], 1, (mattk->aatyp==AT_KICK));
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 /* POLYSELF */
X
X/*	Special (passive) attacks on you by monsters done here.		*/
X
Xint
Xpassive(mon, mhit, malive, kicked)
Xregister struct monst *mon;
Xregister boolean mhit;
Xregister int malive;
Xboolean kicked;
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)) {
X		if (kicked) {
X		    if (uarmf)
X			(void) rust_dmg(uarmf, xname(uarmf), 3, TRUE);
X		} else corrode_weapon();
X	    }
X	    break;
X	  case AD_STON:
X	    if(mhit)
X	      if (!kicked)
X		if (!uwep && !uarmg
X#ifdef POLYSELF
X		    && !resists_ston(uasmon)
X#endif
X		   ) {
X		    You("turn to stone...");
X		    done_in_by(mon);
X		    return 2;
X		}
X	    break;
X	  case AD_RUST:
X	    if(mhit)
X	      if (kicked) {
X		if (uarmf)
X		    (void) rust_dmg(uarmf, xname(uarmf), 1, TRUE);
X	      } else
X		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:
X		tmp = -d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
X		if(ptr == &mons[PM_FLOATING_EYE]) {
X		    if (!canseemon(mon)) {
X			tmp = 0;
X			break;
X		    }
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		} else { /* gelatinous cube */
X		    You("are frozen by %s!", mon_nam(mon));
X		    nomul(tmp);
X		    tmp = 0;
X		}
X		break;
X	      case AD_COLD:		/* brown mold or blue jelly */
X		if(monnear(mon, u.ux, u.uy)) {
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(monnear(mon, u.ux, u.uy)) {
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#if defined(POLYSELF) && defined(GOLEMS)
X			ugolemeffects(AD_FIRE, tmp);
X#endif
X			tmp = 0;
X			break;
X		    }
X		    You("are suddenly very hot!");
X		    mdamageu(mon, tmp);
X		}
X		break;
X	      case AD_ELEC:
X		tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
X		if(Shock_resistance) {
X		    shieldeff(u.ux, u.uy);
X		    You("feel a mild tingle.");
X#if defined(POLYSELF) && defined(GOLEMS)
X		    ugolemeffects(AD_ELEC, tmp);
X#endif
X		    tmp = 0;
X		    break;
X		}
X		You("are jolted with electricity!");
X		mdamageu(mon, tmp);
X		break;
X	      default:
X		break;
X	    }
X	}
X	return(malive | mhit);
X}
X
X/* Note: caller must ascertain mtmp->mimic... */
Xvoid
Xstumble_onto_mimic(mtmp)
Xregister struct monst *mtmp;
X{
X	if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK))
X		u.ustuck = mtmp;
X	if (Blind) goto generic;
X	else if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == CLOSED_DOOR_SYM)
X#ifdef SPELLS
X	{
X		if (IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ) ||
X		    IS_DOOR(levl[u.ux+u.dx][u.uy+u.dy].typ))
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 {
Xgeneric:
X		pline("Wait!  That's %s!", defmonnam(mtmp));
X	}
X	wakeup(mtmp);	/* clears mtmp->mimic */
X}
X
Xstatic void
Xnohandglow(mon)
Xstruct monst *mon;
X{
X	if (!u.umconf || mon->mconf) return;
X	if (u.umconf == 1) {
X		if (Blind)
X			Your("%s stop tingling.", makeplural(body_part(HAND)));
X		else
X			Your("%s stop glowing %s.",
X				makeplural(body_part(HAND)),
X				Hallucination ? hcolor() : red);
X	} else {
X		if (Blind)
X			pline("The tingling in your %s lessens.",
X				makeplural(body_part(HAND)));
X		else
X			Your("%s no longer glow so brightly %s.",
X				makeplural(body_part(HAND)),
X				Hallucination ? hcolor() : red);
X	}
X	u.umconf--;
X}
END_OF_FILE
if test 39521 -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 11 \(of 56\).
cp /dev/null ark11isdone
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