[comp.sources.games] v10i065: 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 65
Archive-name: nethack3p9/Part20
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 20 (of 56)."
# Contents:  src/apply.c src/polyself.c
# Wrapped by billr@saab on Wed Jul 11 17:11:20 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/apply.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/apply.c'\"
else
echo shar: Extracting \"'src/apply.c'\" \(34008 characters\)
sed "s/^X//" >'src/apply.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)apply.c	3.0	88/10/24
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#define MONATTK_H	/* comment line for pre-compiled headers */
X/* block some unused #defines to avoid overloading some cpp's */
X#include	"hack.h"
X#include	"edog.h"
X
X#ifdef MUSIC
X#define IS_INSTRUMENT(typ)	((typ) >= FLUTE && (typ) <= DRUM_OF_EARTHQUAKE)
X#endif /* MUSIC /**/
X
X#ifdef OVLB
X
Xstatic const char NEARDATA tools[] = { TOOL_SYM, 0 };
X
Xstatic boolean NEARDATA did_dig_msg;
X
Xstatic struct monst *FDECL(bchit, (int, int, int, CHAR_P));
Xstatic void FDECL(use_camera, (struct obj *));
Xstatic void FDECL(use_stethoscope, (struct obj *));
Xstatic void FDECL(use_whistle, (struct obj *));
Xstatic void FDECL(use_magic_whistle, (struct obj *));
X#ifdef WALKIES
Xstatic void FDECL(use_leash, (struct obj *));
X#endif
XSTATIC_DCL int NDECL(dig);
Xstatic boolean FDECL(wield_tool, (struct obj *));
Xstatic int FDECL(use_pick_axe, (struct obj *));
X#ifdef MEDUSA
Xstatic void FDECL(use_mirror, (struct obj *));
X#endif
Xstatic void FDECL(use_lamp, (struct obj *));
Xstatic void FDECL(use_crystal_ball, (struct obj *));
Xstatic void FDECL(use_tinning_kit, (struct obj *));
X
X/* version of bhit for cameras and mirrors */
Xstatic
Xstruct monst *
Xbchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; {
X	register struct monst *mtmp = (struct monst *) 0;
X	register int bchx = u.ux, bchy = u.uy;
X
X	if(sym) {
X		Tmp_at2(-1, sym);	/* open call */
X#ifdef TEXTCOLOR
X		Tmp_at2(-3, WHITE);
X#endif
X	}
X	while(range--) {
X		bchx += ddx;
X		bchy += ddy;
X		if(MON_AT(bchx, bchy)) {
X			mtmp = m_at(bchx,bchy);
X			break;
X		}
X		if(!ZAP_POS(levl[bchx][bchy].typ) || closed_door(bchx, bchy)) {
X			bchx -= ddx;
X			bchy -= ddy;
X			break;
X		}
X		if(sym) Tmp_at2(bchx, bchy);
X	}
X	if(sym) Tmp_at2(-1, -1);
X	return(mtmp);
X}
X
Xstatic void
Xuse_camera(obj) /* register */ struct obj *obj; {
Xregister struct monst *mtmp;
X	if(!getdir(1)){		/* ask: in what direction? */
X		flags.move = multi = 0;
X		return;
X	}
X	if(u.uswallow) {
X		You("take a picture of %s's %s.", mon_nam(u.ustuck),
X		    is_animal(u.ustuck->data)? "stomach" : "interior");
X		return;
X	}
X	if(obj->cursed && !rn2(2)) goto blindu;
X	if(u.dz) {
X		You("take a picture of the %s.",
X			(u.dz > 0) ? "floor" : "ceiling");
X		return;
X	}
X	if(!u.dx && !u.dy && !u.dz) {
Xblindu:
X		if(!Blind) {
X			You("are blinded by the flash!");
X			make_blinded((long)rnd(25),FALSE);
X		}
X		return;
X	}
X	if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) {
X		if(mtmp->msleep){
X			mtmp->msleep = 0;
X			pline("The flash awakens %s.", mon_nam(mtmp)); /* a3 */
X		} else
X		if(mtmp->data->mlet != S_YLIGHT)
X		if(mtmp->mcansee || mtmp->mblinded){
X			register int tmp = dist(mtmp->mx,mtmp->my);
X			register int tmp2;
X			if(cansee(mtmp->mx,mtmp->my))
X			  pline("%s is blinded by the flash!", Monnam(mtmp));
X			if(mtmp->data == &mons[PM_GREMLIN]) {
X			  /* Rule #1: Keep them out of the light. */
X			  kludge("%s cries out in pain!", Monnam(mtmp));
X			  if (mtmp->mhp > 1) mtmp->mhp--;
X			}
X			setmangry(mtmp);
X			if(tmp < 9 && !mtmp->isshk && rn2(4)) {
X				mtmp->mflee = 1;
X				if(rn2(4)) mtmp->mfleetim = rnd(100);
X			}
X			if(tmp < 3) {
X				mtmp->mcansee  = 0;
X				mtmp->mblinded = 0;
X			} else {
X				tmp2 = mtmp->mblinded;
X				tmp2 += rnd(1 + 50/tmp);
X				if(tmp2 > 127) tmp2 = 127;
X				mtmp->mblinded = tmp2;
X				mtmp->mcansee = 0;
X			}
X		}
X	}
X}
X
X/* Strictly speaking it makes no sense for usage of a stethoscope to
X   not take any time; however, unless it did, the stethoscope would be
X   almost useless. */
Xstatic void
Xuse_stethoscope(obj) register struct obj *obj; {
Xregister struct monst *mtmp;
Xregister struct rm *lev;
Xregister int rx, ry;
X	if(!freehand()) {
X		You("have no free %s!", body_part(HAND));
X		return;
X	}
X	if (!getdir(1)) {
X		flags.move=multi=0;
X		return;
X	}
X	if(u.dz < 0 || (u.dz && Levitation)) {
X		You("can't reach the %s!", u.dz<0 ? "ceiling" : "floor");
X		return;
X	}
X	if(obj->cursed && !rn2(2)) {
X		You("hear your heart beat.");
X		return;
X	}
X	if(u.dz) {
X#ifdef STRONGHOLD
X		if (dlevel == stronghold_level)
X			You("hear the crackling of hellfire.");
X		else
X#endif
X			pline("The floor seems healthy enough.");
X		return;
X	}
X	if (Stunned || (Confusion && !rn2(5))) confdir();
X	if (!u.dx && !u.dy && !u.dz) {
X		ustatusline();
X		return;
X	}
X	rx = u.ux + u.dx; ry = u.uy + u.dy;
X	if(u.uswallow) {
X		mstatusline(u.ustuck);
X		return;
X	}
X	if (!isok(rx,ry)) {
X		You("hear a faint typing noise.");
X		return;
X	}
X	lev = &levl[rx][ry];
X	if(MON_AT(rx, ry)) {
X		mtmp = m_at(rx,ry);
X		mstatusline(mtmp);
X		if (mtmp->mundetected) {
X			mtmp->mundetected = 0;
X			if (cansee(rx,ry)) pmon(mtmp);
X		}
X		return;
X	}
X	if(lev->typ == SDOOR) {
X		You("hear a hollow sound!  This must be a secret door!");
X		lev->typ = DOOR;
X		lev->seen = 0;		/* force prl */
X		prl(rx,ry);
X		return;
X	}
X	if(lev->typ == SCORR) {
X		You("hear a hollow sound!  This must be a secret passage!");
X		lev->typ = CORR;
X		lev->seen = 0;		/* force prl */
X		prl(rx,ry);
X		return;
X	}
X	You("hear nothing special.");
X}
X
X/* ARGSUSED */
Xstatic void
Xuse_whistle(obj)
Xstruct obj *obj; {
X	You("produce a high whistling sound.");
X	wake_nearby();
X}
X
Xstatic void
Xuse_magic_whistle(obj)
Xstruct obj *obj; {
X	register struct monst *mtmp = fmon;
X
X	if(obj->cursed && !rn2(2)) {
X		You("produce a high-pitched humming noise.");
X		wake_nearby();
X	} else {
X		You("produce a %s whistling sound.", Hallucination
X			? "normal" : "strange");
X		while(mtmp) {
X			if(mtmp->mtame) mnexto(mtmp);
X			mtmp = mtmp->nmon;
X		}
X	}
X}
X
Xboolean
Xum_dist(x,y,n)
Xregister xchar x, y, n;
X{
X	return(abs(u.ux - x) > n  || abs(u.uy - y) > n);
X}
X
X#endif /* OVLB */
X
X#ifdef WALKIES
X#define MAXLEASHED	2
X
X#ifdef OVLB
X
Xint
Xnumber_leashed()
X{
X	register int i = 0;
X	register struct obj *obj;
X
X	for(obj = invent; obj; obj = obj->nobj)
X		if(obj->otyp == LEASH && obj->leashmon != 0) i++;
X	return(i);
X}
X
Xvoid
Xo_unleash(otmp) 	/* otmp is about to be destroyed or stolen */
Xregister struct obj *otmp;
X{
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X		if(mtmp->m_id == (unsigned)otmp->leashmon)
X			mtmp->mleashed = 0;
X	otmp->leashmon = 0;
X}
X
Xvoid
Xm_unleash(mtmp) 	/* mtmp is about to die, or become untame */
Xregister struct monst *mtmp;
X{
X	register struct obj *otmp;
X
X	for(otmp = invent; otmp; otmp = otmp->nobj)
X		if(otmp->otyp == LEASH &&
X				otmp->leashmon == (int)mtmp->m_id)
X			otmp->leashmon = 0;
X	mtmp->mleashed = 0;
X}
X
Xvoid
Xunleash_all()		/* player is about to die (for bones) */
X{
X	register struct obj *otmp;
X	register struct monst *mtmp;
X
X	for(otmp = invent; otmp; otmp = otmp->nobj)
X		if(otmp->otyp == LEASH) otmp->leashmon = 0;
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X		if(mtmp->mtame) mtmp->mleashed = 0;
X}
X
X/* ARGSUSED */
Xstatic void
Xuse_leash(obj)
Xstruct obj *obj;
X{
X	register int x, y;
X	register struct monst *mtmp;
X
X	if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
X		You("can't leash additional pets.");
X		return;
X	}
X
X	if(!getdir(1)) return;
X
X	x = u.ux + u.dx;
X	y = u.uy + u.dy;
X
X	if((x == u.ux) && (y == u.uy)) {
X		pline("Leash yourself?  Very funny...");
X		return;
X	}
X
X	if(!MON_AT(x, y)) {
X		pline("There is no creature here.");
X		return;
X	}
X
X	mtmp = m_at(x, y);
X
X	if(!mtmp->mtame) {
X		pline("%s is not %s!", Monnam(mtmp), (!obj->leashmon) ?
X				"leashable" : "leashed");
X		return;
X	}
X	if(!obj->leashmon) {
X		if(mtmp->mleashed) {
X			pline("This %s is already leashed!", lmonnam(mtmp)+4);
X			return;
X		}
X		You("slip the leash around your %s.", lmonnam(mtmp)+4);
X		mtmp->mleashed = 1;
X		obj->leashmon = (int)mtmp->m_id;
X		if(mtmp->msleep)  mtmp->msleep = 0;
X		return;
X	}
X	if(obj->leashmon != (int)mtmp->m_id) {
X		pline("This leash is not attached to that creature!");
X		return;
X	} else {
X		if(obj->cursed) {
X			pline("The leash wouldn't come off!");
X			return;
X		}
X		mtmp->mleashed = 0;
X		obj->leashmon = 0;
X		You("remove the leash from your %s.",
X		/* a hack to include the dogs full name.  +4 eliminates */
X		/* the 'the' at the start of the name */
X				 lmonnam(mtmp)+4);
X	}
X	return;
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xboolean
Xnext_to_u()
X{
X	register struct monst *mtmp;
X	register struct obj *otmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X		if(mtmp->mleashed) {
X			if(dist(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
X			if(dist(mtmp->mx,mtmp->my) > 2) {
X			    for(otmp = invent; otmp; otmp = otmp->nobj)
X				if(otmp->otyp == LEASH &&
X					otmp->leashmon == (int)mtmp->m_id) {
X				    if(otmp->cursed) return(FALSE);
X				    You("feel %s leash go slack.",
X					(number_leashed() > 1) ? "a" : "the");
X				    mtmp->mleashed = 0;
X				    otmp->leashmon = 0;
X				}
X			}
X		}
X	return(TRUE);
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
Xstruct obj *
Xget_mleash(mtmp) 	/* assuming mtmp->mleashed has been checked */
Xregister struct monst *mtmp;
X{
X	register struct obj *otmp;
X
X	otmp = invent;
X	while(otmp) {
X		if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
X			return(otmp);
X		otmp = otmp->nobj;
X	}
X	return((struct obj *)0);
X}
X#endif /* OVLB */
X
X#endif /* WALKIES */
X#ifdef OVL0
X
X#ifdef WALKIES
Xvoid
Xcheck_leash(x, y)
Xregister xchar x, y;
X{
X	register struct obj *otmp;
X	register struct monst *mtmp = fmon;
X
X	for(otmp = invent; otmp; otmp = otmp->nobj)
X	    if(otmp->otyp == LEASH && otmp->leashmon != 0) {
X		while(mtmp) {
X		    if((int)mtmp->m_id == otmp->leashmon &&
X			    (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
X				dist2(x,y,mtmp->mx,mtmp->my))
X			) {
X			if(otmp->cursed) {
X			    if(um_dist(mtmp->mx, mtmp->my, 5)) {
X				pline("%s chokes to death!",Monnam(mtmp));
X				mondied(mtmp);
X			    } else
X				if(um_dist(mtmp->mx, mtmp->my, 3))
X					pline("%s chokes on the leash!",
X						Monnam(mtmp));
X			} else {
X			    if(um_dist(mtmp->mx, mtmp->my, 5)) {
X				pline("%s's leash snaps loose!",Monnam(mtmp));
X				m_unleash(mtmp);
X			    } else {
X				if(um_dist(mtmp->mx, mtmp->my, 3)) {
X				    You("pull on the leash.");
X# ifdef SOUNDS
X				    if (mtmp->data->msound != MS_SILENT)
X				    switch(rn2(3)) {
X					case 0:  growl(mtmp);	break;
X					case 1:  yelp(mtmp);	break;
X					default: whimper(mtmp); break;
X				    }
X# endif
X				}
X			    }
X			}
X		    }
X		    mtmp = mtmp->nmon;
X		}
X	    }
X}
X
X#endif /* WALKIES */
X
X#endif /* OVL0 */
X#ifdef OVLB
X
XSTATIC_OVL int
Xdig() {
X	register struct rm *lev;
X	register int dpx = dig_pos.x, dpy = dig_pos.y;
X
X	lev = &levl[dpx][dpy];
X	/* perhaps a nymph stole his pick-axe while he was busy digging */
X	/* or perhaps he teleported away */
X	if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
X	    dig_level != dlevel ||
X	    ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
X	     (!dig_down && dist(dpx,dpy) > 2)))
X		return(0);
X
X	if(dig_down && is_maze_lev) {
X		pline("The floor here is too hard to dig in.");
X		return(0);
X	}
X	if(!dig_down && IS_ROCK(lev->typ) && !may_dig(dpx,dpy)) {
X		pline("This wall is too hard to dig into.");
X		return(0);
X	}
X	if(Fumbling && !rn2(3)) {
X		switch(rn2(3)) {
X		case 0:  if(!welded(uwep)) {
X			     You("fumble and drop your %s.", xname(uwep));
X			     dropx(uwep);
X			     setuwep((struct obj *)0);
X			 } else {
X			     pline("Ouch!  Your %s bounces and hits you!",
X				xname(uwep));
X			     set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
X			 }
X			 break;
X		case 1:  pline("Bang!  You hit with the broad side of the %s!",
X			 xname(uwep)); break;
X		default: Your("swing misses its mark."); 
X			 break;
X		}
X		return(0);
X	}
X	dig_effort += 10 + abon() + uwep->spe + rn2(5);
X	if(dig_down) {
X		if(dig_effort > 250) {
X			dighole();
X			dig_level = -1;
X			return(0);	/* done with digging */
X		}
X		if(dig_effort > 50) {
X			register struct trap *ttmp = t_at(dpx,dpy);
X
X			if(!ttmp) {
X				ttmp = maketrap(dpx,dpy,PIT);
X				ttmp->tseen = 1;
X				if(Invisible) newsym(ttmp->tx,ttmp->ty);
X				You("have dug a pit.");
X				u.utrap = rn1(4,2);
X				u.utraptype = TT_PIT;
X				dig_level = -1;
X				return(0);
X			}
X		}
X	} else
X	if(dig_effort > 100) {
X		register const char *digtxt;
X		register struct obj *obj;
X
X		if(obj = sobj_at(STATUE, dpx, dpy)) {
X			if (break_statue(obj))
X				digtxt = "The statue shatters.";
X			else
X				/* it was a statue trap; break_statue()
X				 * printed a message and updated the screen
X				 */
X				digtxt = NULL;
X		} else if(obj = sobj_at(BOULDER, dpx, dpy)) {
X			fracture_rock(obj);
X			digtxt = "The boulder falls apart.";
X		} else if(!lev->typ || lev->typ == SCORR) {
X			lev->typ = CORR;
X			digtxt = "You succeeded in cutting away some rock.";
X		} else if(IS_WALL(lev->typ)) {
X#ifdef STUPID
X		        if (is_maze_lev)
X			    lev->typ = ROOM;
X			else
X			    lev->typ = DOOR;
X#else
X			lev->typ = is_maze_lev ? ROOM : DOOR;
X#endif
X			digtxt = "You just made an opening in the wall.";
X		} else if(lev->typ == SDOOR) {
X			lev->typ = DOOR;
X			digtxt = "You just broke through a secret door.";
X			if(!(lev->doormask & D_TRAPPED))
X				lev->doormask = D_BROKEN;
X		} else if(closed_door(dpx, dpy)) {
X			digtxt = "You just broke a hole through the door.";
X			if(!(lev->doormask & D_TRAPPED))
X				lev->doormask = D_BROKEN;
X		} else return(0); /* statue or boulder got taken */
X		mnewsym(dpx, dpy);
X		prl(dpx, dpy);
X		if (digtxt) pline(digtxt);	/* after mnewsym & prl */
X		if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
X			b_trapped("door");
X			lev->doormask = D_NODOOR;
X			mnewsym(dpx, dpy);
X			prl(dpx, dpy);
X		}
X		dig_level = -1;
X		return(0);
X	} else {
X		if(IS_WALL(lev->typ) || closed_door(dpx, dpy)) {
X		    register int rno = inroom(dpx,dpy);
X
X		    if(rno >= 0 && rooms[rno].rtype >= SHOPBASE) {
X			pline("This %s seems too hard to dig into.",
X			IS_DOOR(lev->typ) ? "door" : "wall");
X			return(0);
X		    }
X		} else if (!IS_ROCK(lev->typ) && !sobj_at(STATUE, dpx, dpy)
X				&& !sobj_at(BOULDER, dpx, dpy))
X			return(0); /* statue or boulder got taken */
X		if(!did_dig_msg) {
X		    You("hit the %s with all your might.",
X			sobj_at(STATUE, dpx, dpy) ? "statue" :
X			sobj_at(BOULDER, dpx, dpy) ? "boulder" :
X			IS_DOOR(lev->typ) ? "door" : "rock");
X		    did_dig_msg = TRUE;
X		}
X	}
X	return(1);
X}
X
X/* When will hole be finished? Very rough indication used by shopkeeper. */
Xint
Xholetime() {
X	if(occupation != dig || !in_shop(u.ux, u.uy)) return(-1);
X	return((250 - dig_effort)/20);
X}
X
Xvoid
Xdighole()
X{
X	register struct trap *ttmp = t_at(u.ux, u.uy);
X
X	if(is_maze_lev
X#ifdef ENDGAME
X			|| dlevel == ENDLEVEL
X#endif
X						) {
X		pline("The floor here seems too hard to dig in.");
X	} else {
X		if(IS_FURNITURE(levl[u.ux][u.uy].typ)) {
X#if defined(ALTARS) && defined(THEOLOGY)
X	            if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
X		    	altar_wrath(u.ux, u.uy);
X			if(in_temple(u.ux, u.uy)) angry_priest();
X		    }
X#endif
X		    levl[u.ux][u.uy].typ = ROOM;
X		    levl[u.ux][u.uy].altarmask = 0;
X		}
X		if(ttmp)
X			ttmp->ttyp = TRAPDOOR;
X		else
X			ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
X		ttmp->tseen = 1;
X		if(Invisible) newsym(ttmp->tx,ttmp->ty);
X		pline("You've made a hole in the floor.");
X		if(!u.ustuck && !Levitation) {			/* KAA */
X			if(in_shop(u.ux, u.uy))
X				shopdig(1);
X#ifdef WALKIES
X			if(!next_to_u())
X			    You("are jerked back by your pet!");
X			else {
X#endif
X			    You("fall through...");
X			    if(u.utraptype == TT_PIT) {
X				u.utrap = 0;
X				u.utraptype = 0;
X			    }
X			    unsee();
X#ifdef MACOS
X			    segments |= SEG_APPLY;
X#endif
X			    goto_level(dlevel+1, FALSE, TRUE);
X#ifdef WALKIES
X			}
X#endif
X		}
X	}
X}
X
Xstatic boolean
Xwield_tool(obj)
Xstruct obj *obj;
X{
X	if(uwep && uwep->cursed) {
X		/* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
X		if(flags.verbose) {
X			pline("Since your weapon is welded to your %s,",
X				bimanual(uwep) ?
X				makeplural(body_part(HAND))
X				: body_part(HAND));
X			pline("you cannot wield that %s.", xname(obj));
X		}
X		return(FALSE);
X	}
X# ifdef POLYSELF
X	if(cantwield(uasmon)) {
X		You("can't hold it strongly enough.");
X		return(FALSE);
X	}
X# endif
X	unweapon = TRUE;
X	You("now wield %s.", doname(obj));
X	setuwep(obj);
X	if (uwep != obj) return(FALSE); /* rewielded old object after dying */
X	return(TRUE);
X}
X
Xstatic int
Xuse_pick_axe(obj)
Xstruct obj *obj;
X{
X	char dirsyms[12];
X	register char *dsp = dirsyms;
X	register const char *sdp = flags.num_pad ? ndir : sdir;
X	register struct rm *lev;
X	register int rx, ry, res = 0;
X	register boolean isclosedoor = FALSE;
X
X	if(obj != uwep)
X	    if (!wield_tool(obj)) return(0);
X	    else res = 1;
X
X	while(*sdp) {
X		(void) movecmd(*sdp);	/* sets u.dx and u.dy and u.dz */
X		rx = u.ux + u.dx;
X		ry = u.uy + u.dy;
X		if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
X		    (IS_ROCK(levl[rx][ry].typ)
X		    || sobj_at(STATUE, rx, ry)
X		    || sobj_at(BOULDER, rx, ry))))
X			*dsp++ = *sdp;
X		sdp++;
X	}
X	*dsp = 0;
X	pline("In what direction do you want to dig? [%s] ", dirsyms);
X	if(!getdir(0))		/* no txt */
X		return(res);
X	if(u.uswallow && attack(u.ustuck)) /* return(1) */;
X	else if(u.dz < 0) You("cannot reach the ceiling.");
X	else if(!u.dx && !u.dy && !u.dz) {
X		char buf[BUFSZ];
X		int dam;
X
X		dam = rnd(2) + dbon() + obj->spe;
X		if (dam <= 0) dam = 1;
X		You("hit yourself with your own pick-axe.");
X		/* self_pronoun() won't work twice in a sentence */
X		Strcpy(buf, self_pronoun("killed %sself with %%s own pick-axe",
X			"him"));
X		losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX);
X		flags.botl=1;
X		return(1);
X	} else if(u.dz == 0) {
X		if(Stunned || (Confusion && !rn2(5))) confdir();
X		rx = u.ux + u.dx;
X		ry = u.uy + u.dy;
X		lev = &levl[rx][ry];
X		if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
X			return(1);
X		if(!isok(rx, ry)) {
X			pline("Clash!");
X			return(1);
X		}
X		isclosedoor = closed_door(rx, ry);
X		if(!IS_ROCK(lev->typ)
X		     && !isclosedoor
X		     && !sobj_at(STATUE, rx, ry)
X		     && !sobj_at(BOULDER, rx, ry)) {
X			/* ACCESSIBLE or POOL */
X			You("swing your %s through thin air.",
X				aobjnam(obj, NULL));
X		} else {
X			if(dig_pos.x != rx || dig_pos.y != ry
X			    || dig_level != dlevel || dig_down) {
X				dig_down = FALSE;
X				dig_pos.x = rx;
X				dig_pos.y = ry;
X				dig_level = dlevel;
X				dig_effort = 0;
X			    	You("start %s.",
X				   sobj_at(STATUE, rx, ry) ?
X						"chipping the statue" :
X				   sobj_at(BOULDER, rx, ry) ?
X						"hitting the boulder" :
X				   isclosedoor ? "chopping at the door" :
X						"digging");
X			} else
X				You("continue %s.",
X				   sobj_at(STATUE, rx, ry) ?
X						"chipping the statue" :
X				   sobj_at(BOULDER, rx, ry) ?
X						"hitting the boulder" :
X				   isclosedoor ? "chopping at the door" :
X						"digging");
X			did_dig_msg = FALSE;
X			set_occupation(dig, "digging", 0);
X		}
X	} else if(Levitation) {
X		You("cannot reach the floor.");
X	} else {
X		if(dig_pos.x != u.ux || dig_pos.y != u.uy
X		    || dig_level != dlevel || !dig_down) {
X			dig_down = TRUE;
X			dig_pos.x = u.ux;
X			dig_pos.y = u.uy;
X			dig_level = dlevel;
X			dig_effort = 0;
X			You("start digging in the floor.");
X			if(in_shop(u.ux, u.uy))
X				shopdig(0);
X		} else
X			You("continue digging in the floor.");
X		did_dig_msg = FALSE;
X		set_occupation(dig, "digging", 0);
X	}
X	return(1);
X}
X
X#define WEAK	3	/* from eat.c */
X
X#ifdef MEDUSA
Xstatic void
Xuse_mirror(obj)
Xstruct obj *obj;
X{
X	register struct monst *mtmp;
X	register char mlet;
X
X	if(!getdir(1)){		/* ask: in what direction? */
X		flags.move = multi = 0;
X		return;
X	}
X	if(obj->cursed && !rn2(2)) {
X		if (!Blind)
X			pline("The mirror gets foggy and doesn't reflect!");
X		return;
X	}
X	if(!u.dx && !u.dy && !u.dz) {
X		if(!Blind && !Invisible) {
X#ifdef POLYSELF
X		    if(u.umonnum == PM_FLOATING_EYE) {
X			pline("Yikes!  You've frozen yourself!");
X			nomul(-rnd((MAXULEV+6) - (int)u.ulevel));
X		    } else if (u.usym == S_VAMPIRE || u.usym == S_DEMON)
X			You("don't seem to reflect anything.");
X		    else if(u.umonnum == PM_UMBER_HULK) {
X			pline("Huh?  That doesn't look like you!");
X			make_confused(HConfusion + d(3,4),FALSE);
X		    } else
X#endif
X			   if (Hallucination) You("look %s.", hcolor());
X		    else if (Sick)
X			You("look peaked.");
X		    else if (u.uhs >= WEAK)
X			You("look undernourished.");
X#ifdef POLYSELF
X		    else if (u.usym == S_NYMPH
X#ifdef INFERNO
X			     || u.umonnum==PM_SUCCUBUS
X#endif
X			     )
X			You("look beautiful in the mirror.");
X#ifdef INFERNO
X		    else if (u.umonnum == PM_INCUBUS)
X			You("look handsome in the mirror.");
X#endif
X#endif
X		    else You("look as %s as ever.",
X				ACURR(A_CHA) > 14 ?
X				(poly_gender()==1 ? "beautiful" : "handsome") :
X				"ugly");
X		} else {
X		if (Luck <= 10 && rn2(4-Luck/3) || !HTelepat ||
X		    (u.ukilled_medusa
X#ifdef HARD
X			&& u.udemigod
X#endif
X		    )) {
X			You("can't see your %s %s.",
X				ACURR(A_CHA) > 14 ?
X				(poly_gender()==1 ? "beautiful" : "handsome") :
X				"ugly",
X				body_part(FACE));
X		} else {
X			static char buf[35];
X			const char *tm, *tl; int ll;
X			if (!u.ukilled_medusa && rn2(4)) {
X			    tm = "n ugly snake-headed monster";
X			    ll = dlevel - medusa_level;
X			}
X			else {
X			    tm = " powerful wizard";
X			    ll = dlevel - wiz_level;
X			}
X			if (ll < -10) tl = "far below you";
X			else if (ll < -1) tl = "below you";
X			else if (ll == -1) {
X			    Sprintf(buf, "under your %s", makeplural(
X				body_part(FOOT)));
X			    tl = buf;
X			} else if (ll == 0)  tl = "very close to you";
X			else if (ll == 1) {
X			    Sprintf(buf, "above your %s", body_part(HEAD));
X			    tl = buf;
X			} else if (ll > 10) tl = "far above you";
X			else tl = "above you";
X			You("get an impression that a%s lives %s.",
X				tm, tl);
X		    }
X		}
X		return;
X	}
X	if(u.uswallow) {
X		You("reflect %s's %s.", mon_nam(u.ustuck), 
X		    is_animal(u.ustuck->data)? "stomach" : "interior");
X		return;
X	}
X	if(u.dz) {
X		You("reflect the %s.",
X			(u.dz > 0) ? "floor" : "ceiling");
X		return;
X	}
X	if(!(mtmp = bchit(u.dx, u.dy, COLNO, 0)) || !haseyes(mtmp->data))
X		return;
X
X	mlet = mtmp->data->mlet;
X	if(mtmp->msleep) {
X		if(!Blind)
X		    pline ("%s is tired and doesn't look at your mirror.",
X			    Monnam(mtmp));
X		mtmp->msleep = 0;
X	} else if (!mtmp->mcansee) {
X		if (!Blind)
X		    pline("%s can't see anything at the moment.", Monnam(mtmp));
X	/* some monsters do special things */
X	} else if (mlet == S_VAMPIRE || mlet == S_DEMON || mlet == S_GHOST ||
X		  (mtmp->minvis && !perceives(mtmp->data) && !See_invisible)) {
X		if (!Blind)
X		   pline ("%s doesn't seem to reflect anything.", Monnam(mtmp));
X	} else if(!mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) {
X		if (!Blind)
X			pline("%s is turned to stone!", Monnam(mtmp));
X		stoned = TRUE;
X		killed(mtmp);
X	} else if(!mtmp->mcan && !mtmp->minvis &&
X					mtmp->data == &mons[PM_FLOATING_EYE]) {
X		int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd);
X		if (!rn2(4)) tmp = 120;
X	/* Note: floating eyes cannot use their abilities while invisible,
X	 * but medusas and umber hulks can.
X	 */
X		if (!Blind)
X			pline("%s is frozen by its reflection.",Monnam(mtmp));
X		mtmp->mcanmove = 0;
X		if (mtmp->mfrozen + tmp > 127)
X			mtmp->mfrozen = 127;
X		else mtmp->mfrozen += tmp;
X	} else if(!mtmp->mcan && mtmp->data == &mons[PM_UMBER_HULK]) {
X		if (!Blind)
X			pline ("%s has confused itself!", Monnam(mtmp));
X	    	mtmp->mconf = 1;
X	} else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH
X#ifdef INFERNO
X			  || mtmp->data==&mons[PM_SUCCUBUS]
X#endif
X			  )) {
X		if (!Blind) {
X	    	    pline ("%s looks beautiful in your mirror.",Monnam(mtmp));
X	    	    pline ("She decides to take it!");
X		} else pline ("It steals your mirror!");
X		setnotworn(obj); /* in case mirror was wielded */
X	    	freeinv(obj);
X	    	mpickobj(mtmp,obj);
X	    	rloc(mtmp);
X	} else if (mlet != S_UNICORN && !humanoid(mtmp->data) && 
X			(!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
X		if (!Blind)
X			pline ("%s is frightened by its reflection%s.",
X				Monnam(mtmp), (mtmp->minvis && !See_invisible
X					&& !Telepat) ?
X				", though you see nothing" : "");
X		mtmp->mflee = 1;
X		mtmp->mfleetim += d(2,4);
X	} else if (!Blind) {
X		if (mtmp->minvis && !See_invisible)
X		    pline("%s doesn't seem to reflect anything.",
X			Monnam(mtmp));
X		else if (mtmp->minvis && !perceives(mtmp->data))
X		    pline("%s doesn't seem to be aware of its reflection.",
X			Monnam(mtmp));
X		else
X		    pline("%s doesn't seem to mind %s reflection.",
X			Monnam(mtmp), (is_female(mtmp) ? "her" :
X		        is_human(mtmp->data) ? "his" : "its"));
X	}
X}/* use_mirror */
X
X#endif
X
Xstatic void
Xuse_lamp(obj)
Xstruct obj *obj;
X{
X	if(obj->spe <= 0 || obj->otyp == MAGIC_LAMP ) {
X		pline("This lamp has no oil.");
X		return;
X	}
X	if(obj->cursed && !rn2(2))
X		pline("The lamp flickers on for a moment and dies.");
X	else litroom(TRUE);
X	obj->spe -= 1;
X}
X
Xstatic void
Xuse_crystal_ball(obj)
X	struct obj *obj;
X{
X	char buf[BUFSZ];
X	int oops, ret;
X
X	if (Blind) {
X		pline("Too bad you can't see the crystal ball.");
X		return;
X	}
X	oops = (rnd(20) > ACURR(A_INT) || obj->cursed);
X	if (oops && (obj->spe > 0)) {
X		switch(rnd(5)) {
X		case 1 : pline("The crystal ball is too much to comprehend!");
X			break;
X		case 2 : pline("The crystal ball confuses you!");
X			make_confused(HConfusion + rnd(100),FALSE);
X			break;
X		case 3 : pline("The crystal ball damages your vision!");
X			make_blinded(Blinded + rnd(100),FALSE);
X			break;
X		case 4 : pline("The crystal ball zaps your mind!");
X			make_hallucinated(Hallucination + rnd(100),FALSE);
X			break;
X		case 5 : pline("The crystal ball explodes!");
X			useup(obj);
X			losehp(rnd(30), "exploding crystal ball",
X				KILLED_BY_AN);
X			break;
X		}
X		obj->spe -= 1;
X		return;
X	}
X
X	pline("What do you want to look for? ");
X	getlin(buf);
X	clrlin();
X	if (!buf[0] || buf[0] == '\033') {
X		if(flags.verbose) pline("Never mind.");
X		return;
X		}
X	You("peer into the crystal ball.");
X	nomul(-rnd(10));
X	nomovemsg = "";
X	if(obj->spe <= 0)
X		pline("The vision is unclear.");
X	else {
X	  	obj->spe -= 1;
X		switch(buf[0]) {
X		case GOLD_SYM :	ret = gold_detect((struct obj *)0);
X			break;
X		case '^' :	ret = trap_detect((struct obj *)0);
X			break;
X		case FOOD_SYM :	ret = food_detect((struct obj *)0);
X			break;
X		case POTION_SYM :
X		case GEM_SYM :
X		case TOOL_SYM :
X		case WEAPON_SYM :
X		case WAND_SYM :
X		case SCROLL_SYM :
X#ifdef SPELLS
X		case SPBOOK_SYM :
X#endif
X		case ARMOR_SYM :	ret = object_detect((struct obj *)0);
X			break;
X		default  : lcase(buf);
X			if (!strncmp(buf,"gold",4) || !strncmp(buf,"money",5))
X				ret = gold_detect((struct obj *)0);
X			else if (!strncmp(buf,"trap",4))
X				ret = trap_detect((struct obj *)0);
X			else if (!strncmp(buf,"food",4) ||
X				 !strncmp(buf,"dead",4) ||
X				 !strncmp(buf,"corpse",6))
X				ret = food_detect((struct obj *)0);
X			else if (!strncmp(buf,"obj",3) ||
X				 !strncmp(buf,"the",3) ||
X				 !strncmp(buf,"a ",2) ||
X				 !strncmp(buf,"an ",3))
X				 /* || strstr(buf, " of") */
X				ret = object_detect((struct obj *)0);
X			else ret = monster_detect((struct obj *)0);
X			break;
X		}
X		if (ret)
X		    if (!rn2(100))  /* make them nervous */
X			You("see the Wizard of Yendor gazing out at you.");
X		    else pline("The vision is unclear.");
X	}
X	return;
X}
X
Xstatic const char NEARDATA cuddly[] = { TOOL_SYM, 0 };
X
Xint
Xdorub()
X{
X	struct obj *obj = getobj(cuddly, "rub");
X
X	if(!obj || (obj != uwep && !wield_tool(obj))) return 0;
X
X	/* now uwep is obj */
X	if (uwep->otyp == MAGIC_LAMP) {
X	    if (uwep->spe > 0 && !rn2(3)) {
X		uwep->spe = 0;
X		djinni_from_bottle(uwep);
X		makeknown(MAGIC_LAMP);
X	    } else if (rn2(2) && !Blind)
X		You("see a puff of smoke.");
X	    else pline(nothing_happens);
X	} else pline(nothing_happens);
X	return 1;
X}
X
Xint
Xdojump()
X{
X	coord cc;
X	register struct monst *mtmp;
X	if (!Jumping) {
X		You("can't jump very far.");
X		return 0;
X	} else if (u.uswallow) {
X		pline("You've got to be kidding!");
X		return 0;
X	} else if (u.ustuck) {
X		kludge("You cannot escape from %s!",
X			mon_nam(u.ustuck));
X		return 0;
X	} else if (inv_weight() > -5) {
X		You("are carrying too much to jump!");
X		return 0;
X	} else if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
X		You("lack the strength to jump!");
X		return 0;
X	}
X	pline("Where do you want to jump?");
X	cc.x = u.ux;
X	cc.y = u.uy;
X	getpos(&cc, 1, "the desired position");
X	if (dist(cc.x, cc.y) > 9) {
X		pline("Too far!");
X		return 0;
X	} else if (!cansee(cc.x, cc.y)) {
X		You("cannot see where to land!");
X		return 0;
X	} else if (MON_AT(cc.x, cc.y)) {
X		mtmp = m_at(cc.x, cc.y);
X		You("cannot trample %s!", mon_nam(mtmp));
X		return 0;
X	} else if (!isok(cc.x, cc.y) ||
X#ifdef POLYSELF
X		(IS_ROCK(levl[cc.x][cc.y].typ) && !passes_walls(uasmon)) ||
X#else
X		IS_ROCK(levl[cc.x][cc.y].typ) ||
X#endif
X		sobj_at(BOULDER, cc.x, cc.x) ) {
X			You("cannot jump there!");
X			return 0;
X	} else {
X			teleds(cc.x, cc.y);
X			nomul(-1);
X			nomovemsg = "";
X			morehungry(rnd(25));
X			return 1;
X	}
X}
X
Xstatic void
Xuse_tinning_kit(obj)
Xregister struct obj *obj;
X{
X	register struct obj *corpse, *can = (struct obj *)0;
X
X	/* This takes only 1 move.  If this is to be changed to take many
X	 * moves, we've got to deal with decaying corpses...
X	 */
X	if (!(corpse = floorfood("can", 1))) return;
X	if (corpse->oeaten) {
X		You("cannot tin something which is partly eaten.");
X		return;
X	}
X	if ((corpse->corpsenm == PM_COCKATRICE)
X#ifdef POLYSELF
X		&& !resists_ston(uasmon)
X#endif
X		&& !uarmg) {
Xpline("Tinning a cockatrice corpse without gloves was not a very wise move...");
X		You("turn to stone...");
X		killer_format = KILLED_BY;
X		killer = "trying to tin a cockatrice without gloves";
X		done(STONING);
X	}
X	if (mons[corpse->corpsenm].cnutrit == 0) {
X		You("can't tin something that insubstantial!");
X		return;
X	}
X	if(can = mksobj(TIN,FALSE)) {
X	    int savequan;
X
X	    can->corpsenm = corpse->corpsenm;
X	    can->quan = 1; /*Defeat the occasional creation of pairs of tins */
X	    can->owt = weight(can);
X	    can->known = 1;
X	    can->spe = -1; /* Mark tinned tins. No spinach allowed... */
X	    can->cursed = obj->cursed;
X	    can->blessed = obj->blessed;
X	    can = addinv(can);
X	    savequan = can->quan;
X	    can->quan = 1;
X	    if (inv_cnt() <= 52) {
X		prinv(can);
X		can->quan = savequan;
X	    } else {
X		pline("You make, but cannot pick up, %s.", doname(can));
X		/* can->quan = savequan; */
X		/* unnecessary since savequan = quan = 1 here */
X		dropx(can);
X	    }
X	    if (carried(corpse)) useup(corpse);
X	    else useupf(corpse);
X	} else impossible("Tinning failed.");
X}
X
Xint
Xuse_unicorn_horn(obj)
Xstruct obj *obj;
X{
X	boolean blessed = (obj && obj->blessed);
X	boolean did_something = FALSE;
X
X	if (obj && obj->cursed) {
X		switch (rn2(6)) {
X		    static char buf[BUFSZ];
X		    case 0: make_sick(Sick ? 1L : (long)(20 + rn2(20)), TRUE);
X			    Strcpy(buf, xname(obj));
X			    u.usick_cause = (const char *)buf;
X			    break;
X		    case 1: make_blinded(Blinded + (long) rnd(100), TRUE);
X			    break;
X		    case 2: if (!Confusion)
X				You("suddenly feel %s.",
X					Hallucination ? "trippy" : "confused");
X			    make_confused(HConfusion + (long) rnd(100), TRUE);
X			    break;
X		    case 3: make_stunned(HStun + (long) rnd(100), TRUE);
X			    break;
X		    case 4: adjattrib(rn2(6), -1, FALSE);
X			    break;
X		    case 5: make_hallucinated(Hallucination + (long) rnd(100),
X				TRUE);
X			    break;
X		}
X		return 1;
X	}
X		
X	if (Sick) {
X		make_sick(0L, TRUE);
X		did_something++;
X	}
X	if (Blinded > (long)(u.ucreamed+1) && (!did_something || blessed)) {
X		make_blinded(u.ucreamed ? (long)(u.ucreamed+1) : 0L, TRUE);
X		did_something++;
X	}
X	if (Hallucination && (!did_something || blessed)) {
X		make_hallucinated(0L, TRUE);
X		did_something++;
X	}
X	if (Vomiting && (!did_something || blessed)) {
X		make_vomiting(0L, TRUE);
X		did_something++;
X	}
X	if (HConfusion && (!did_something || blessed)) {
X		make_confused(0L, TRUE);
X		did_something++;
X	}
X	if (HStun && (!did_something || blessed)) {
X		make_stunned(0L, TRUE);
X		did_something++;
X	}
X	if (!did_something || blessed) {
X		register int j;
X		int did_stat = 0;
X		int i = rn2(A_MAX);
X		for(j=0; j<A_MAX; j++) {
X			if ((blessed || j==i) && ABASE(i) < AMAX(i)) {
X				did_something++;
X				/* They may have to use it several times... */
X				if (!did_stat) {
X					did_stat++;
X					pline("This makes you feel good!");
X				}
X				ABASE(i)++;
X				flags.botl = 1;
X			}
X		}
X	}
X	if (!did_something) pline(nothing_happens);
X	return !!did_something;
X}
X
Xint
Xdoapply() {
X	register struct obj *obj;
X	register int res = 1;
X
X	obj = getobj(tools, "use or apply");
X	if(!obj) return 0;
X
X	check_unpaid(obj);
X
X#ifdef MUSIC
X	if (IS_INSTRUMENT(obj->otyp)) {
X		res = do_play_instrument(obj);
X		return (res);
X	}
X#endif /* MUSIC /**/
X
X	switch(obj->otyp){
X	case EXPENSIVE_CAMERA:
X		use_camera(obj); break;
X	case CREDIT_CARD:
X	case LOCK_PICK:
X	case SKELETON_KEY:
X	case KEY:
X		(void) pick_lock(obj);
X		break;
X	case BAG_OF_TRICKS:
X		if(obj->spe > 0) {
X			register int cnt = 1;
X
X			obj->spe -= 1;
X			if(!rn2(23)) cnt += rn2(7) + 1;
X			while(cnt--)
X			    (void) makemon((struct permonst *) 0, u.ux, u.uy);
X			makeknown(BAG_OF_TRICKS);
X		}
X		break;
X	case LARGE_BOX:
X	case CHEST:
X	case ICE_BOX:
X	case SACK:
X	case BAG_OF_HOLDING:
X		use_container(obj, 1); break;
X	case PICK_AXE:
X		res = use_pick_axe(obj);
X		break;
X	case TINNING_KIT:
X		use_tinning_kit(obj);
X		break;
X	case MAGIC_WHISTLE:
X		if(pl_character[0] == 'W' || u.ulevel > (MAXULEV/3)) {
X			use_magic_whistle(obj);
X			break;
X		}
X		/* fall into next case */
X	case WHISTLE:
X		use_whistle(obj);
X		break;
X#ifdef MEDUSA
X	case MIRROR:
X		use_mirror(obj);
X		break;
X#endif
X	case LAMP:
X	case MAGIC_LAMP:
X		use_lamp(obj);
X		break;
X	case CRYSTAL_BALL:
X		use_crystal_ball(obj);
X		break;
X#ifdef WALKIES
X	case LEASH:
X		use_leash(obj);
X		break;
X#endif
X	case MAGIC_MARKER:
X		dowrite(obj);
X		break;
X	case TIN_OPENER:
X		if(!carrying(TIN)) {
X			You("have no tin to open.");
X			goto xit;
X		}
X		You("cannot open a tin without eating or discarding its contents.");
X		if(flags.verbose)
X			pline("In order to eat, use the 'e' command.");
X		if(obj != uwep)
X    pline("Opening the tin will be much easier if you wield the tin opener.");
X		goto xit;
X
X	case STETHOSCOPE:
X		res = 0;
X		use_stethoscope(obj);
X		break;
X	case FIGURINE:
X		You("set the figurine on the ground and it transforms.");
X		make_familiar(obj);
X		useup(obj);
X		break;
X	case BLINDFOLD:
X		if (obj == ublindf) {
X		    if(cursed(obj)) break;
X		    else Blindf_off(obj);
X		} 
X		else if (!ublindf) Blindf_on(obj);
X		else You("are already wearing a blindfold!");
X		break;
X	case UNICORN_HORN:
X		res = use_unicorn_horn(obj);
X		break;
X	default:
X		pline("Sorry, I don't know how to use that.");
X	xit:
X		nomul(0);
X		return 0;
X	}
X	nomul(0);
X	return res;
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 34008 -ne `wc -c <'src/apply.c'`; then
    echo shar: \"'src/apply.c'\" unpacked with wrong size!
fi
# end of 'src/apply.c'
fi
if test -f 'src/polyself.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/polyself.c'\"
else
echo shar: Extracting \"'src/polyself.c'\" \(21103 characters\)
sed "s/^X//" >'src/polyself.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)polyself.c 3.0	89/11/21
X/* Polymorph self routine.  Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X
X#ifdef POLYSELF
X#ifdef OVLB
Xstatic void NDECL(break_armor);
Xstatic void FDECL(drop_weapon,(int));
Xstatic void NDECL(skinback);
Xstatic void NDECL(uunstick);
Xstatic boolean sticky;
X#endif /* OVLB */
X#endif
X
X#ifdef OVLB
X
Xvoid
Xnewman()
X{
X	int tmp, tmp2;
X	char buf[BUFSZ];
X
X	if (!rn2(10)) {
X		flags.female = !flags.female;
X		max_rank_sz();
X		if (pl_character[0] == 'P')
X			Strcpy(pl_character+6, flags.female ? "ess" : "");
X		if (pl_character[0] == 'C')
X			Strcpy(pl_character+5, flags.female ? "woman" : "man");
X	}
X#ifdef POLYSELF
X	if (u.umonnum != -1) {
X		u.acurr = u.macurr;	/* restore old attribs */
X		u.amax = u.mamax;
X	}
X	u.usym = S_HUMAN;
X	u.umonnum = -1;
X	if (u.uundetected) u.uundetected = 0;
X	prme();
X	u.mtimedone = u.mh = u.mhmax = 0;
X#endif
X	tmp = u.uhpmax;
X	tmp2 = u.ulevel;
X	u.ulevel = u.ulevel-2+rn2(5);
X	if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1;
X	if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
X
X	adjabil(tmp2, (int)u.ulevel);
X	tmp = u.uhpmax;
X
X	/* random experience points for the new experience level */
X	u.uexp = rndexp();
X#ifndef LINT
X	u.uhpmax = (u.uhpmax-10)*(long)u.ulevel/tmp2 + 19 - rn2(19);
X#endif
X/* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character
X   with 16 hp who polymorphed into a 3rd level one would have an average
X   of 48 hp.  */
X#ifdef LINT
X	u.uhp = u.uhp + tmp;
X#else
X	u.uhp = u.uhp * (long)u.uhpmax/tmp;
X#endif
X#ifdef SPELLS
X	tmp = u.uenmax;
X#  ifndef LINT
X	u.uenmax = u.uenmax * (long)u.ulevel/tmp2 + 9 - rn2(19);
X#  endif
X	if (u.uenmax < 0) u.uenmax = 0;
X#  ifndef LINT
X	u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);
X#  endif
X#endif
X	redist_attr();
X	u.uhunger = rn1(500,500);
X	Sick = 0;
X	Stoned = 0;
X	if (u.uhp <= 0 || u.uhpmax <= 0) {
X#ifdef POLYSELF
X		if(Polymorph_control) {
X		    if (u.uhp <= 0) u.uhp = 1;
X		    if (u.uhpmax <= 0) u.uhpmax = 1;
X		} else {
X#endif
X		    Your("new form doesn't seem healthy enough to survive.");
X		    killer_format = KILLED_BY_AN;
X		    killer="unsuccessful polymorph";
X		    done(DIED);
X#ifdef POLYSELF
X		}
X#endif
X	}
X#ifdef POLYSELF
X	set_uasmon();
X#endif
X	You("feel like a new %sman!", flags.female ? "wo" : "");
X#ifdef WIZARD
X	if(!wizard) {
X#endif
Xnewname:	more();
X		do {
X		    pline("What is your new name? ");
X		    getlin(buf);
X		} while (buf[0]=='\033' || buf[0]==0);
X		if (!strcmp(plname,buf)) {
X		    pline("That is the same as your old name!");
X		    goto newname;
X		}
X		(void)strncpy(plname, buf, sizeof(plname)-1);
X#ifdef VMS
X		Sprintf(SAVEF, "[.save]%d%s", getuid(), plname);
X		regularize(SAVEF+7);
X		Strcat(SAVEF, ";1");
X#else
X# ifdef MSDOS
X		(void)strcpy(SAVEF, SAVEP);
X		{
X			int i = strlen(SAVEF);
X			(void)strncat(SAVEF, plname, 8);
X			regularize(SAVEF+i);
X		}
X		(void)strcat(SAVEF, ".sav");
X# else
X		Sprintf(SAVEF, "save/%d%s", getuid(), plname);
X		regularize(SAVEF+5);		/* avoid . or / in name */
X# endif
X#endif
X#ifdef WIZARD
X	}
X#endif
X	flags.botl = 1;
X#ifdef POLYSELF
X	skinback();
X	find_ac();
X	if (sticky) uunstick();
X#endif
X}
X
X#ifdef POLYSELF
Xvoid
Xpolyself()
X{
X	char buf[BUFSZ];
X	int mntmp = -1;
X	int tries=0;
X	boolean draconian = (uarm && uarm->otyp==DRAGON_SCALE_MAIL &&
X		uarm->corpsenm >= PM_GRAY_DRAGON &&
X		uarm->corpsenm <= PM_YELLOW_DRAGON);
X	boolean iswere = (u.ulycn > -1 || is_were(uasmon));
X	boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
X	/* We have to calculate sticky in multiple places since we might go
X	 * through any one of them without going through the others.
X	 */
X	sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X
X	if(!Polymorph_control && !draconian && !iswere && !isvamp) {
X	    if (rn2(20) > ACURR(A_CON)) {
X		You("shudder for a moment.");
X		losehp(rn2(30),"system shock", KILLED_BY_AN);
X		return;
X	    }
X	}
X
X	if (Polymorph_control) {
X		do {
X			pline("Become what kind of monster? [type the name] ");
X			getlin(buf);
X			mntmp = name_to_mon(buf);
X			if (mntmp < 0)
X				pline("I've never heard of such monsters.");
X			else if (!polyok(&mons[mntmp]))
X				You("cannot polymorph into that.");
X			else break;
X		} while(++tries < 5);
X		if (tries==5) pline(thats_enough_tries);
X	} else if (draconian || iswere || isvamp) {
X		/* special changes that don't require polyok() */
X		if (draconian) {
X			mntmp = uarm->corpsenm;
X			if (!(mons[mntmp].geno & G_GENOD)) {
X				You("merge with your scaly armor.");
X				uskin = uarm;
X				uarm = (struct obj *)0;
X			}
X		} else if (iswere) {
X			if (is_were(uasmon))
X				mntmp = PM_HUMAN; /* Illegal; force newman() */
X			else
X				mntmp = u.ulycn;
X		} else {
X			if (u.usym == S_VAMPIRE)
X				mntmp = PM_VAMPIRE_BAT;
X			else
X				mntmp = PM_VAMPIRE;
X		}
X		if (polymon(mntmp))
X			return;
X	}
X
X	if (mntmp < 0) {
X		tries = 0;
X		do {
X			mntmp = rn2(PM_ARCHEOLOGIST);
X			/* All valid monsters are from 0 to PM_ARCHEOLOGIST-1 */
X		} while(!polyok(&mons[mntmp]) && tries++ < 200);
X	}
X
X	/* The below polyok() fails either if everything is genocided, or if
X	 * we deliberately chose something illegal to force newman().
X	 */
X	if (!polyok(&mons[mntmp]) || !rn2(5))
X		newman();
X	else if(!polymon(mntmp)) return;
X
X	if (!uarmg) selftouch("No longer petrify-resistant, you");
X	if (Inhell && !Fire_resistance) {
X	    You("burn to a crisp.");
X	    killer_format = KILLED_BY;
X	    killer = "losing fire resistance after polymorphing";
X	    while(1) {
X		done(BURNING);
X		You("continue burning.");
X	    }
X	}
X}
X
Xint
Xpolymon(mntmp)	/* returns 1 if polymorph successful */
X	int	mntmp;
X{
X	int	tmp;
X	sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X
X	if (mons[mntmp].geno & G_GENOD) {
X		You("feel rather %s-ish.",mons[mntmp].mname);
X		return(0);
X	}
X
X	if (u.umonnum == -1) {
X		/* Human to monster; save human stats */
X		u.macurr = u.acurr;
X		u.mamax = u.amax;
X	} else {
X		/* Monster to monster; restore human stats, to be
X		 * immediately changed to provide stats for the new monster
X		 */
X		u.acurr = u.macurr;
X		u.amax = u.mamax;
X	}
X	tmp = u.umonnum;
X	u.umonnum = mntmp;
X	set_uasmon();
X	u.usym = mons[mntmp].mlet;
X
X	if (tmp != mntmp)
X		You("turn into %s!", an(mons[mntmp].mname));
X	else
X		You("feel like a new %s!", mons[mntmp].mname);
X
X	/* New stats for monster, to last only as long as polymorphed.
X	 * Currently only strength gets changed.
X	 */
X	if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118;
X
X	if (resists_ston(uasmon) && Stoned) { /* parnes@eniac.seas.upenn.edu */
X		Stoned = 0;
X		You("no longer seem to be petrifying.");
X	}
X	if (u.usym == S_FUNGUS && Sick) {
X		Sick = 0;
X		You("no longer feel sick.");
X	}
X	if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON) u.mhmax = 80;
X#ifdef GOLEMS
X	else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp);
X#endif /* GOLEMS */
X	else {
X
X		/*
X		tmp = adj_lev(&mons[mntmp]);
X		 * We can't do this, since there's no such thing as an
X		 * "experience level of you as a monster" for a polymorphed
X		 * character.
X		 */
X		tmp = mons[mntmp].mlevel;
X		if (!tmp) u.mhmax = rnd(4);
X		else u.mhmax = d(tmp, 8);
X	}
X	u.mh = u.mhmax;
X	if (uskin && mntmp != uskin->corpsenm)
X		skinback();
X	break_armor();
X	drop_weapon(1);
X	if (u.uundetected && !hides_under(uasmon)) u.uundetected = 0;
X	else if (hides_under(uasmon) && (OBJ_AT(u.ux, u.uy) ||
X			levl[u.ux][u.uy].gmask))
X		u.uundetected = 1;
X	prme();
X	if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0;
X	else if (sticky && !sticks(uasmon)) uunstick();
X	u.mtimedone = 500 + rn2(500);
X	if (u.ulevel < mons[mntmp].mlevel)
X	/* Low level characters can't become high level monsters for long */
X		u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel;
X	flags.botl = 1;
X	if (flags.verbose) {
X	    if (can_breathe(uasmon))
X		pline("Use the command #monster to use your breath weapon.");
X	    if (attacktype(uasmon, AT_SPIT))
X		pline("Use the command #monster to spit venom.");
X	    if (u.usym == S_NYMPH)
X		pline("Use the command #monster to remove an iron ball.");
X	    if (u.usym == S_UMBER)
X		pline("Use the command #monster to confuse monsters.");
X	    if (is_hider(uasmon))
X		pline("Use the command #monster to hide.");
X	    if (is_were(uasmon))
X		pline("Use the command #monster to summon help.");
X	    if (webmaker(uasmon))
X		pline("Use the command #monster to spin a web.");
X	    if (u.usym == S_UNICORN)
X		pline("Use the command #monster to use your horn.");
X	    if (lays_eggs(uasmon) || u.umonnum == PM_QUEEN_BEE)
X		pline("Use the command #sit to lay an egg.");
X	}
X	find_ac();
X	return(1);
X}
X
Xstatic void
Xbreak_armor() {
X     struct obj *otmp;
X
X     if (breakarm(uasmon)) {
X	if (otmp = uarm) {
X		if (donning(otmp)) cancel_don();
X		You("break out of your armor!");
X		(void) Armor_gone();
X		useup(otmp);
X	}
X	if (otmp = uarmc) {
X		Your("cloak tears apart!");
X		(void) Cloak_off();
X		useup(otmp);
X	}
X#ifdef SHIRT
X	if (uarmu) {
X		Your("shirt rips to shreds!");
X		useup(uarmu);
X	}
X#endif
X     } else if (sliparm(uasmon)) {
X	if (otmp = uarm) {
X		if (donning(otmp)) cancel_don();
X		Your("armor falls around you!");
X		(void) Armor_gone();
X		dropx(otmp);
X	}
X	if (otmp = uarmc) {
X		You("shrink out of your cloak!");
X		(void) Cloak_off();
X		dropx(otmp);
X	}
X#ifdef SHIRT
X	if (otmp = uarmu) {
X		You("become much too small for your shirt!");
X		setworn((struct obj *)0, otmp->owornmask & W_ARMU);
X		dropx(otmp);
X	}
X#endif
X     }
X     if (nohands(uasmon) || verysmall(uasmon)) {
X	  if (otmp = uarmg) {
X	       if (donning(otmp)) cancel_don();
X	       /* Drop weapon along with gloves */
X	       You("drop your gloves%s!", uwep ? " and weapon" : "");
X	       drop_weapon(0);
X	       (void) Gloves_off();
X	       dropx(otmp);
X	  }
X	  if (otmp = uarms) {
X	       You("can no longer hold your shield!");
X	       (void) Shield_off();
X	       dropx(otmp);
X	  }
X	  if (otmp = uarmh) {
X	       if (donning(otmp)) cancel_don();
X	       Your("helmet falls to the floor!");
X	       (void) Helmet_off();
X	       dropx(otmp);
X	  }
X	  if (otmp = uarmf) {
X	       if (donning(otmp)) cancel_don();
X	       Your("boots %s off your feet!",
X			verysmall(uasmon) ? "slide" : "are pushed");
X	       (void) Boots_off();
X	       dropx(otmp);
X	  }
X     }
X}
X
Xstatic void
Xdrop_weapon(alone)
Xint alone;
X{
X     struct obj *otmp;
X     if (otmp = uwep) {
X	  /* !alone check below is currently superfluous but in the
X	   * future it might not be so if there are monsters which cannot
X	   * wear gloves but can wield weapons
X	   */
X	  if (!alone || cantwield(uasmon)) {
X	       if (alone) You("find you must drop your weapon!");
X	       uwepgone();
X	       dropx(otmp);
X	  }
X     }
X}
X
Xvoid
Xrehumanize()
X{
X	sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X
X	u.mh = u.mhmax = u.mtimedone = 0;
X 	u.acurr = u.macurr;		/* restore old strength */
X 	u.amax = u.mamax;
X	u.usym = S_HUMAN;
X	u.umonnum = -1;
X	skinback();
X	set_uasmon();
X	You("return to %sn form!", (pl_character[0] == 'E')? "elve" : "huma");
X
X	if (u.uhp < 1)	done(DIED);
X	if (!Fire_resistance && Inhell) {
X	    You("burn to a crisp.");
X	    killer_format = KILLED_BY;
X	    killer = "losing fire resistance after rehumanization";
X	    while(1) {
X		done(BURNING);
X		You("continue burning.");
X	    }
X	}
X	if (!uarmg) selftouch("No longer petrify-resistant, you");
X	if (sticky) uunstick();
X	nomul(0);
X	if (u.uundetected) u.uundetected = 0;
X	prme();
X	flags.botl = 1;
X	find_ac();
X}
X
Xint
Xdobreathe() {
X	if(!getdir(1)) return(0);
X	if (rn2(4))
X	    You("produce a loud and noxious belch.");
X	else {
X	    register struct attack *mattk;
X	    register int i;
X
X	    for(i = 0; i < NATTK; i++) {
X		mattk = &(uasmon->mattk[i]);
X		if(mattk->aatyp == AT_BREA) break;
X	    }
X	    buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,
X		u.ux, u.uy, u.dx, u.dy);
X	}
X	return(1);
X}
X
Xint
Xdospit() {
X	struct obj *otmp;
X
X	if (!getdir(1)) return(0);
X	otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, FALSE);
X	otmp->spe = 1; /* to indicate it's yours */
X	(void) throwit(otmp);
X	return(1);
X}
X
Xint
Xdoremove() {
X     if (!Punished) {
X	  You("are not chained to anything!");
X	  return(0);
X     }
X     unpunish();
X     return(1);
X}
X
Xint
Xdospinweb() {
X	register struct trap *ttmp = t_at(u.ux,u.uy);
X
X	if (Levitation) {
X		You("must be on the ground to spin a web.");
X		return(0);
X	}
X	if (u.uswallow) {
X		You("release web fluid inside %s.", mon_nam(u.ustuck));
X		if (is_animal(u.ustuck->data)) {
X			expels(u.ustuck, u.ustuck->data, TRUE);
X			return(0);
X		}
X		if (is_whirly(u.ustuck->data)) {
X			int i;
X
X			for (i = 0; i < NATTK; i++)
X				if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
X					break;
X			if (i == NATTK)
X			       impossible("Swallower has no engulfing attack?");
X			else {
X				char sweep[30];
X
X				sweep[0] = '\0';
X				switch(u.ustuck->data->mattk[i].adtyp) {
X					case AD_FIRE:
X						Strcpy(sweep, "ignites and ");
X						break;
X					case AD_ELEC:
X						Strcpy(sweep, "fries and ");
X						break;
X					case AD_COLD:
X						Strcpy(sweep,
X						      "freezes, shatters and ");
X						break;
X				}
X				pline("The web %sis swept away!", sweep);
X			}
X			return(0);
X		}		     /* default: a nasty jelly-like creature */ 
X		pline("The web dissolves into %s.", mon_nam(u.ustuck));
X		return(0);
X	}
X	if (u.utrap) {
X		You("cannot spin webs while stuck in a trap.");
X		return(0);
X	}
X	if (ttmp) switch (ttmp->ttyp) {
X		case SPIKED_PIT:
X		case PIT: You("spin a web, covering up the pit.");
X			deltrap(ttmp);
X			if (Invisible) newsym(u.ux, u.uy);
X			return(1);
X		case WEB: You("make the web thicker.");
X			return(1);
X		case SQBRD: pline("The squeaky board is muffled.");
X			deltrap(ttmp);
X			if (Invisible) newsym(u.ux, u.uy);
X			return(1);
X		case TELEP_TRAP:
X		case LEVEL_TELEP:
X			Your("webbing vanishes!");
X			return(0);
X		case TRAPDOOR: if (!is_maze_lev) {
X				You("web over the trap door.");
X				deltrap(ttmp);
X				if (Invisible) newsym(u.ux, u.uy);
X				return 1;
X			}
X			/* Fall through */
X		case MGTRP:
X		case POLY_TRAP:
X		case DART_TRAP:
X		case ARROW_TRAP:
X#ifdef SPELLS
X		case ANTI_MAGIC:
X#endif
X		case LANDMINE:
X		case SLP_GAS_TRAP:
X		case BEAR_TRAP:
X		case RUST_TRAP:
X			You("have triggered a trap!");
X			dotrap(ttmp);
X			return(1);
X		default:
X			impossible("Webbing over trap type %d?", ttmp->ttyp);
X			return(0);
X	}
X	ttmp = maketrap(u.ux, u.uy, WEB);
X	ttmp->tseen = 1;
X	if (Invisible) newsym(u.ux, u.uy);
X	return(1);
X}
X
Xint
Xdosummon()
X{
X	You("call upon your brethren for help!");
X	if (!were_summon(uasmon,TRUE))
X		pline("But none arrive.");
X	return(1);
X}
X
Xint
Xdoconfuse()
X{
X	register struct monst *mtmp;
X	int looked = 0;
X
X	if (Blind) {
X		You("can't see anything to gaze at.");
X		return 0;
X	}
X	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X	    if (canseemon(mtmp)) {
X		looked = 1;
X		if (Invis && !perceives(mtmp->data))
X		    pline("%s seems not to notice your gaze.", Monnam(mtmp));
X		else if (mtmp->minvis && !See_invisible)
X		    You("can't see where to gaze at %s.", Monnam(mtmp));
X		else if (mtmp->mimic)
X		    continue;
X		else if (flags.safe_dog && !Confusion && !Hallucination
X		  && mtmp->mtame) {
X		    if (mtmp->mnamelth)
X			You("avoid gazing at %s.", NAME(mtmp));
X		    else
X			You("avoid gazing at your %s.",
X						mtmp->data->mname);
X		} else {
X		    if (flags.confirm && mtmp->mpeaceful && !Confusion
X							&& !Hallucination) {
X#ifdef MACOS
X			char mac_tbuf[80];
X			if(!flags.silent) SysBeep(1);
X			Sprintf(mac_tbuf, "Really confuse %s?", mon_nam(mtmp));
X			if(UseMacAlertText(128, mac_tbuf) != 1) continue;
X#else
X			pline("Really confuse %s? ", mon_nam(mtmp));
X			(void) fflush(stdout);
X			if (yn() != 'y') continue;
X#endif
X			setmangry(mtmp);
X		    }
X		    if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||
X							!mtmp->mcansee)
X			continue;
X		    if (!mtmp->mconf)
X			Your("gaze confuses %s!", mon_nam(mtmp));
X		    else
X			pline("%s is getting more and more confused.",
X							Monnam(mtmp));
X		    mtmp->mconf = 1;
X		    if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
X			You("are frozen by %s's gaze!", mon_nam(mtmp));
X			nomul((u.ulevel > 6 || rn2(4)) ? 
X				-d((int)mtmp->m_lev+1,
X					(int)mtmp->data->mattk[0].damd)
X				: -200);
X			return 1;
X		    }
X#ifdef MEDUSA
X		    if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) {
X			pline("Gazing at the awake Medusa is not a very good idea.");
X			/* as if gazing at a sleeping anything is fruitful... */
X			You("turn to stone...");
X			done(STONING);
X		    }
X#endif
X		}
X	    }
X	}
X	if (!looked) You("gaze at no place in particular.");
X	return 1;
X}
X
Xint
Xdohide()
X{
X	if (u.uundetected || u.usym == S_MIMIC_DEF) {
X		You("are already hiding.");
X		return(0);
X	}
X	if (u.usym == S_MIMIC) {
X		u.usym = S_MIMIC_DEF;
X		prme();
X	} else {
X		newsym(u.ux,u.uy);
X		u.uundetected = 1;
X	}
X	return(1);
X}
X
Xstatic void
Xuunstick()
X{
X	kludge("%s is no longer in your clutches.", Monnam(u.ustuck));
X	u.ustuck = 0;
X}
X
Xstatic void
Xskinback()
X{
X	if (uskin) {
X		Your("skin returns to its original form.");
X		uarm = uskin;
X		uskin = (struct obj *)0;
X	}	
X}
X#endif
X
X#endif /* OVLB */
X#ifdef OVL1
Xconst char *
Xbody_part(part)
Xint part;
X{
X	/* Note: it is assumed these will never be >22 characters long,
X	 * plus the trailing null, after pluralizing (since sometimes a
X	 * buffer is made a fixed size and must be able to hold it)
X	 */
X	static const char NEARDATA *humanoid_parts[] = { "arm", "eye", "face", "finger",
X		"fingertip", "foot", "hand", "handed", "head", "leg",
X                "light headed", "neck", "spine", "toe" };
X#ifdef POLYSELF
X	static const char NEARDATA *jelly_parts[] = { "pseudopod", "dark spot", "front",
X		"pseudopod extension", "pseudopod extremity",
X		"pseudopod root", "grasp", "grasped", "cerebral area",
X		"lower pseudopod", "viscous", "middle", "surface",
X		"pseudopod extremity" },
X	NEARDATA *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip",
X		"rear claw", "foreclaw", "clawed", "head", "rear limb",
X		"light headed", "neck", "spine", "rear claw tip" },
X	NEARDATA *horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip",
X		"rear hoof", "foreclaw", "hooved", "head", "rear limb",
X		"light headed", "neck", "backbone", "rear hoof tip" },
X	NEARDATA *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle",
X		"tentacle tip", "lower appendage", "tentacle", "tentacled",
X		"body", "lower tentacle", "rotational", "equator", "body",
X		"lower tentacle tip" },
X	NEARDATA *fungus_parts[] = { "mycelium", "visual area", "front", "hypha",
X		"hypha", "root", "strand", "stranded", "cap area",
X		"rhizome", "sporulated", "stalk", "root", "rhizome tip" },
X	NEARDATA *vortex_parts[] = { "region", "eye", "front", "minor current",
X		"minor current", "lower current", "swirl", "swirled",
X		"central core", "lower current", "addled", "center",
X		"currents", "edge" },
X	NEARDATA *snake_parts[] = { "vestigial limb", "eye", "face", "large scale",
X		"large scale tip", "rear region", "scale gap", "scale gapped",
X		"head", "rear region", "light headed", "neck", "length",
X		"rear scale" };
X	
X	if (humanoid(uasmon) || (u.usym==S_CENTAUR && 
X		(part==ARM || part==FINGER || part==FINGERTIP
X		|| part==HAND || part==HANDED))) return humanoid_parts[part];
X	if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part];
X	if (u.usym==S_SNAKE || u.usym==S_NAGA || u.usym==S_WORM)
X		return snake_parts[part];
X	if (u.usym==S_EYE) return sphere_parts[part];
X	if (u.usym==S_JELLY || u.usym==S_PUDDING || u.usym==S_BLOB)
X		return jelly_parts[part];
X	if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part];
X	if (u.usym==S_FUNGUS) return fungus_parts[part];
X	return animal_parts[part];
X#else
X	return humanoid_parts[part];
X#endif
X}
X
X#endif /* OVL1 */
X#ifdef OVL0
X
Xint
Xpoly_gender()
X{
X/* Returns gender of polymorphed player; 0/1=same meaning as flags.female,
X * 2=none.
X * Used in:
X *	- Seduction by succubus/incubus
X *	- Talking to nymphs (sounds.c)
X * Not used in:
X *	- Messages given by nymphs stealing armor (they can't steal from
X *	  incubi/succubi/nymphs, and nonhumanoids can't wear armor).
X *	- Amulet of change (must refer to real gender no matter what
X *	  polymorphed into).
X *	- Priest/Priestess, Caveman/Cavewoman (ditto)
X *	- Polymorph self (only happens when human)
X *	- Shopkeeper messages (since referred to as "creature" and not "sir"
X *	  or "lady" when polymorphed)
X */
X#ifdef POLYSELF
X	if (uasmon->mflags2 & M2_FEM) return 1;
X# ifdef INFERNO
X	if (u.umonnum == PM_INCUBUS) return 0;
X# endif
X	if (!humanoid(uasmon)) return 2;
X#endif
X	return flags.female;
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X#if defined(POLYSELF) && defined(GOLEMS)
Xvoid
Xugolemeffects(damtype, dam)
Xint damtype, dam;
X{
X	int heal = 0;
X	/* We won't bother with "slow"/"haste" since players do not
X	 * have a monster-specific slow/haste so there is no way to
X	 * restore the old velocity once they are back to human.
X	 */
X	if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM)
X		return;
X	switch (damtype) {
X		case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM)
X				heal = dam / 6; /* Approx 1 per die */
X			break;
X		case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM)
X				heal = dam;
X			break;
X	}
X	if (heal && (u.mh < u.mhmax)) {
X		u.mh += heal;
X		if (u.mh > u.mhmax) u.mh = u.mhmax;
X		flags.botl = 1;
X		pline("Strangely, you feel better than before.");
X	}
X}
X#endif /* POLYSELF && GOLEMS */
X
X#endif /* OVLB */
END_OF_FILE
if test 21103 -ne `wc -c <'src/polyself.c'`; then
    echo shar: \"'src/polyself.c'\" unpacked with wrong size!
fi
# end of 'src/polyself.c'
fi
echo shar: End of archive 20 \(of 56\).
cp /dev/null ark20isdone
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