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

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

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



#! /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 16 (of 38)."
# Contents:  auxil/hh src/apply.c src/eat.c
# Wrapped by billr@saab on Sun Jul 23 21:32:59 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'auxil/hh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'auxil/hh'\"
else
echo shar: Extracting \"'auxil/hh'\" \(2718 characters\)
sed "s/^X//" >'auxil/hh' <<'END_OF_FILE'
Xy k u	7 8 9	Move commands:
X \|/	 \|/		yuhjklbn: go one step in specified direction
Xh-.-l	4-.-6		YUHJKLBN: go in specified direction until you
X /|\	 /|\			    hit a wall or run into something
Xb j n	1 2 3		g<dir>:   run in direction <dir> until something
X      numberpad 		    interesting is seen
X			G<dir>,   same, except a branching corridor isn't
X			^<dir>:     considered interesting
X			m<dir>:   move without picking up objects
X		If the numberpad option is set, the number keys move instead.
X
XMeta commands:
X?	help	print one of several informative texts
XQ	quit	end the game
XS	save	save the game (to be continued later)
X!	sh	escape to some SHELL (if allowed)
X^Z	suspend suspend the game (independent of your current suspend char)
XO	options set options
X/	whatis	give name (and sometimes more info) of specified monster
X\	known	print list of what's been discovered
Xv	version	print version number
XV	history	print game history
X^A	again	redo the previous command
X^R	redraw	redraw the screen (^R denotes the symbol CTRL/R)
X^P	print	repeat last message  (subsequent ^P's repeat earlier messages)
X#		introduces a long command (# ? for list of long commands)
X
XGame commands:
X^T	'port	teleport (if you can)
X^D	kick	kick a door
Xa	apply	apply or use a tool (pick-axe, key, camera, etc.)
XA	remove	take off all armor
Xc	close	close a door
XC	name	name an individual monster (e.g., baptize your dog)
Xd	drop	drop an object.  d7a:  drop seven items of object 'a'
XD	drop	drop several things
Xe	eat	eat something
XE	engrave write a message in the dust on the floor  (E-  use fingers)
Xi	invent	list the inventory (all objects you are carrying)
XI	invent	list selected parts of the inventory
X		Iu: list unpaid objects
X		Ix: list unpaid but used up items
X		I$: count your money
Xo	open	open a door
Xp	pay	pay your bill
XP	wear	put on a ring
Xq	quaff	drink a potion
Xr	read	read a scroll or spell book
XR	remove	remove a ring
Xs	search	search for secret doors, hidden traps and monsters
Xt	throw	throw or shoot a weapon
XT	remove	take off some armor
Xw	wield	wield a weapon	(w-  wield nothing)
XW	wear	put on some armor
Xz	zap	zap a wand
XZ	cast	cast a spell
X<	up	go up the stairs
X>	down	go down the stairs
X^	trap_id identify a previously found trap
X),[,=,",(		ask for current items of specified symbol in use
X$	gold	count your gold
X+	spells	list the spells you know
X.	rest	wait a moment
X,	pickup	pick up all you can carry
X@		turn "autopickup" on and off
X:	look	look at what is here
X
XAnd if the "number_pad" option is on, these additional commands:
X
Xn		followed by number of times to repeat the next command
Xj	jump	jump to a location
Xk	kick	kick a door
Xl	loot	loot a box on the floor
XN	name	name an object or type of object
Xu	untrap	untrap a trapped object
END_OF_FILE
if test 2718 -ne `wc -c <'auxil/hh'`; then
    echo shar: \"'auxil/hh'\" unpacked with wrong size!
fi
# end of 'auxil/hh'
fi
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'\" \(28934 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/* block some unused #defines to avoid overloading some cpp's */
X#define MONATTK_H
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
Xstatic const char tools[] = { TOOL_SYM, 0 };
X
Xstatic boolean did_dig_msg;
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 MSDOSCOLOR
X		Tmp_at2(-3, (int)AT_WHITE);
X#endif
X	}
X	while(range--) {
X		bchx += ddx;
X		bchy += ddy;
X		if(levl[bchx][bchy].mmask) {
X			mtmp = m_at(bchx,bchy);
X			break;
X		}
X		if(!ZAP_POS(levl[bchx][bchy].typ) ||
X		    (IS_DOOR(levl[bchx][bchy].typ) &&
X			    (levl[bchx][bchy].doormask & (D_CLOSED | D_LOCKED)))
X		  ) {
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 stomach.", mon_nam(u.ustuck));
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) mtmp->mcansee  = 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(lev->mmask) {
X		mtmp = m_at(rx,ry);
X		mstatusline(mtmp);
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#ifdef WALKIES
X#define MAXLEASHED	2
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(levl[x][y].mmask == 0) {
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.",
X				mtmp->data->mname);
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
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
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
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#endif /* WALKIES */
X
X
Xstatic 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			 } 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 char *digtxt;
X		register struct obj *obj;
X
X		if(obj = sobj_at(BOULDER, dpx, dpy)) {
X			fracture_rock(obj);
X			digtxt = "The boulder falls apart.";
X		} else if(obj = sobj_at(STATUE, dpx, dpy)) {
X			if (break_statue(obj))
X				digtxt = "The statue shatters.";
X			else
X	digtxt = "Instead of shattering, the statue suddenly comes alive!";
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			lev->typ = is_maze_lev ? ROOM : DOOR;
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 (IS_DOOR(lev->typ) &&
X			   (lev->doormask & (D_CLOSED | D_LOCKED))) {
X			digtxt = "You just broke a hole through the door.";
X			if(!(lev->doormask & D_TRAPPED))
X				lev->doormask = D_BROKEN;
X		} else
X		  digtxt = "Now what exactly was it that you were digging in?";
X		mnewsym(dpx, dpy);
X		prl(dpx, dpy);
X		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		}
X		dig_level = -1;
X		return(0);
X	} else {
X		if(IS_WALL(lev->typ) ||
X		 (IS_DOOR(lev->typ) && lev->doormask & (D_CLOSED | D_LOCKED))) {
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		}
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	return( (occupation == dig) ? (250 - dig_effort)/20 : -1);
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(inshop())
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			    goto_level(dlevel+1, FALSE);
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, *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		int dam;
X
X		dam = rnd(2) + dbon();
X		if (dam <= 0) dam = 1;
X		You("hit yourself with your own pick-axe.");
X		losehp(dam, "self-inflicted wound");
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(lev->mmask && attack(m_at(rx, ry)))
X			return(1);
X		if(!isok(rx, ry)) {
X			pline("Clash!");
X			return(1);
X		}
X		isclosedoor = (IS_DOOR(lev->typ) &&
X			       (lev->doormask & (D_CLOSED | D_LOCKED)));
X		if(!IS_ROCK(lev->typ)
X		     && (!IS_DOOR(lev->typ) || (lev->doormask==D_NODOOR
X			|| lev->doormask & (D_ISOPEN | D_BROKEN)))
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				   isclosedoor ? "chopping at the door" :
X				   sobj_at(STATUE, rx, ry) ?
X						"chipping the statue" :
X				   sobj_at(BOULDER, rx, ry) ?
X						"hitting the boulder" :
X						"digging");
X			} else
X				You("continue %s.",
X				   isclosedoor ? "chopping at the door" :
X				   sobj_at(STATUE, rx, ry) ?
X						"chipping the statue" :
X				   sobj_at(BOULDER, rx, ry) ?
X						"hitting the boulder" :
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(inshop())
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(!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 peakish.");
X		    else if (u.uhs >= WEAK)
X			You("look undernourished.");
X#ifdef POLYSELF
X		    else if (u.usym == S_NYMPH
X#ifdef HARD
X			     || u.umonnum==PM_SUCCUBUS
X#endif
X			     )
X			You("look beautiful in the mirror.");
X#ifdef HARD
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 (rn2(4-u.uluck/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			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 stomach.", mon_nam(u.ustuck));
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	    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	    } else if (mtmp->minvis || mlet == S_VAMPIRE ||
X					mlet == S_DEMON || mlet == S_GHOST) {
X		if (!Blind)
X		   pline ("%s doesn't seem to reflect anything.", Monnam(mtmp));
X	    } else if (!mtmp->mcan) {
X	    /* some monsters do special things */
X		if(obj->cursed && !rn2(2)) {
X		    if (!Blind)
X			pline("The mirror gets foggy and doesn't reflect!");
X		    return;
X		} else if(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->data == &mons[PM_FLOATING_EYE]) {
X		    if (!Blind)
X			pline("%s is frozen by its reflection.",Monnam(mtmp));
X		    mtmp->mfroz = 1;
X		} else if(mtmp->data == &mons[PM_UMBER_HULK]) {
X		    if (!Blind)
X			pline ("%s has confused itself!", Monnam(mtmp));
X	    	    mtmp->mconf = 1;
X		} else if(mlet == S_NYMPH
X#ifdef HARD
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	    	    freeinv(obj);
X	    	    mpickobj(mtmp,obj);
X	    	    rloc(mtmp);
X		}
X	    } else if (mlet != S_UNICORN && !humanoid(mtmp->data) && rn2(5)) {
X		if (!Blind)
X		pline ("%s is frightened by its reflection.", Monnam(mtmp));
X		mtmp->mflee = 1;
X		mtmp->mfleetim += d(2,4);
X	    } else if (!Blind)
X		pline("%s doesn't seem to mind %s reflection.", Monnam(mtmp),
X		      (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			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 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	if (uwep->otyp == MAGIC_LAMP) {
X	    if (uwep->spe > 0 && !rn2(3)) {
X		uwep->spe = 0;
X		djinni_from_bottle(uwep);
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	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 (levl[cc.x][cc.y].mmask) {
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;
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->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 = "unwise tinning decision";
X		done("stoned");
X	}
X	can = mksobj(TIN,FALSE);
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 = 0; /* No spinach allowed... */
X	can->cursed = obj->cursed;
X	can->blessed = obj->blessed;
X	can = addinv(can);
X	You("now have %s.", doname(can));
X	useup(corpse);
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 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	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}
END_OF_FILE
if test 28934 -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/eat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/eat.c'\"
else
echo shar: Extracting \"'src/eat.c'\" \(19624 characters\)
sed "s/^X//" >'src/eat.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)eat.c	3.0	88/10/22
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include	"hack.h"
X
Xchar corpsename[60];
X
X/* hunger texts used on bottom line (each 8 chars long) */
X#define	SATIATED	0
X#define NOT_HUNGRY	1
X#define	HUNGRY		2
X#define	WEAK		3
X#define	FAINTING	4
X#define FAINTED		5
X#define STARVED		6
X
Xconst char *hu_stat[] = {
X	"Satiated",
X	"        ",
X	"Hungry  ",
X	"Weak    ",
X	"Fainting",
X	"Fainted ",
X	"Starved "
X};
X
Xstatic const char comestibles[] = { FOOD_SYM, 0 };
X
Xvoid
Xinit_uhunger(){
X	u.uhunger = 900;
X	u.uhs = NOT_HUNGRY;
X}
X
Xconst struct { char *txt; int nut; } tintxts[] = {
X	"deep fried",	60,
X	"pickled",	40,
X	"soup made from", 20,
X	"pureed", 500,
X	"rotten", -50,
X	"",	0
X};
X#define	TTSZ	SIZE(tintxts)
X
Xstatic struct {
X	struct obj *tin;
X	int usedtime, reqtime;
X} tin;
X
Xstatic int
XMeatdone() {
X	u.usym =
X#ifdef POLYSELF
X		u.mtimedone ? uasmon->mlet :
X#endif
X		S_HUMAN;
X	prme();
X	return 0;
X}
X
Xstatic int
Xcorpsefx(pm)
Xregister int pm;
X{
X	register int tmp = 0, tp = 0;
X
X	if ((pl_character[0]=='E') ? is_elf(&mons[pm]) : is_human(&mons[pm])) {
X		You("cannibal!  You will be sorry for this!");
X		Aggravate_monster |= INTRINSIC;
X	}
X
X	switch(pm) {
X	    case PM_WRAITH:
X		pluslvl();
X		break;
X#ifdef POLYSELF
X	    case PM_WERERAT:
X		u.ulycn = PM_RATWERE;
X		break;
X	    case PM_WEREJACKAL:
X		u.ulycn = PM_JACKALWERE;
X		break;
X	    case PM_WEREWOLF:
X		u.ulycn = PM_WOLFWERE;
X		break;
X#endif
X	    case PM_NURSE:
X		u.uhp = u.uhpmax;
X		flags.botl = 1;
X		break;
X	    case PM_LITTLE_DOG:
X	    case PM_DOG:
X	    case PM_LARGE_DOG:
X	    case PM_KITTEN:
X	    case PM_HOUSECAT:
X	    case PM_LARGE_CAT:
X		Aggravate_monster |= INTRINSIC;
X		break;
X	    case PM_STALKER:
X		if(!Invis) {
X			HInvis = 50+rn2(100);
X			if(!See_invisible)
X				newsym(u.ux, u.uy);
X		} else {
X			if (!HInvis) You("feel hidden!");
X			HInvis |= INTRINSIC;
X			HSee_invisible |= INTRINSIC;
X		}
X		/* fall into next case */
X	    case PM_YELLOW_LIGHT:
X		/* fall into next case */
X	    case PM_GIANT_BAT:
X		make_stunned(HStun + 30,FALSE);
X		/* fall into next case */
X	    case PM_BAT:
X		make_stunned(HStun + 30,FALSE);
X		break;
X	    case PM_COCKATRICE:
X#ifdef MEDUSA
X	    case PM_MEDUSA:
X#endif
X#ifdef POLYSELF
X		if(!resists_ston(uasmon)) {
X#endif
X			killer = (char *) alloc(40);
X			You("turn to stone.");
X			Sprintf(killer, "%s meat",
X				      mons[pm].mname);
X			done("stoned");
X#ifdef POLYSELF
X		}
X#endif
X		break;
X	    case PM_GIANT_MIMIC:
X		tmp += 10;
X		/* fall into next case */
X	    case PM_LARGE_MIMIC:
X		tmp += 20;
X		/* fall into next case */
X	    case PM_SMALL_MIMIC:
X		tmp += 20;
X		if(u.usym == S_HUMAN) {
X		    You("cannot resist the temptation to mimic a treasure chest.");
X		    tp++;
X		    nomul(tmp);
X		    afternmv = Meatdone;
X		    nomovemsg = "You now again prefer mimicking a human.";
X		    u.usym = GOLD_SYM;
X		    prme();
X		}
X		break;
X	    case PM_FLOATING_EYE:
X		if (!(HTelepat & INTRINSIC)) {
X			HTelepat |= INTRINSIC;
X			You("feel a %s mental acuity.",
X			Hallucination ? "normal" : "strange");
X		}
X		break;
X	    case PM_QUANTUM_MECHANIC:
X		Your("velocity suddenly seems very uncertain!");
X		if (Fast & INTRINSIC) {
X			Fast &= ~INTRINSIC;
X			You("seem slower.");
X		} else {
X			Fast |= INTRINSIC;
X			You("seem faster.");
X		}
X		break;
X#ifdef POLYSELF
X	    case PM_CHAMELEON:
X		You("feel a change coming over you.");
X		polyself();
X		break;
X#endif
X	    default: {
X		register struct permonst *ptr = &mons[pm];
X		if(dmgtype(ptr, AD_STUN) || ptr==&mons[PM_VIOLET_FUNGUS]) {
X		    pline ("Oh wow!  Great stuff!");
X		    make_hallucinated(Hallucination + 200,FALSE);
X		}
X		if(dmgtype(ptr, AD_ACID)) {
X		  if(Stoned) {
X			pline("What a pity - you just destroyed a future piece of art!");
X			tp++;
X			Stoned = 0;
X		  }
X		}
X		if(is_giant(ptr)) gainstr((struct obj *)0, 0);
X
X		if(can_teleport(ptr) && ptr->mlevel > rn2(10)) {
X		    if (!(HTeleportation & INTRINSIC)) {
X			You("feel very jumpy.");
X			HTeleportation |= INTRINSIC;
X		    }
X		} else if(control_teleport(ptr) && ptr->mlevel > rn2(20)) {
X		    if (!(HTeleport_control & INTRINSIC)) {
X			You("feel in control of yourself.");
X			HTeleport_control |= INTRINSIC;
X		    }
X		} else if(resists_fire(ptr) && ptr->mlevel > rn2(20)) {
X		    if (!(HFire_resistance & INTRINSIC)) {
X			You("feel a momentary chill.");
X			HFire_resistance |= INTRINSIC;
X		    }
X		} else if(resists_cold(ptr) && ptr->mlevel > rn2(20)) {
X		    if (!(HCold_resistance & INTRINSIC)) {
X			You("feel full of hot air.");
X			HCold_resistance |= INTRINSIC;
X		    }
X		} else if((ptr->mflags1 & M1_POIS_RES) && ptr->mlevel>rn2(20)) {
X		/* Monsters with only M1_POIS are poison resistant themselves,
X		 * but do not confer resistance when eaten
X		 */
X		    if (!(HPoison_resistance & INTRINSIC)) {
X			You("feel healthy.");
X			HPoison_resistance |= INTRINSIC;
X		    }
X		} else if(resists_elec(ptr) && ptr->mlevel > rn2(20)) {
X		    if (!(HShock_resistance & INTRINSIC)) {
X			Your("health currently feels amplified!");
X			HShock_resistance |= INTRINSIC;
X		    }
X		} else if((ptr->mflags1 & M1_SLEE_RES) && ptr->mlevel > rn2(20)) {
X		/* Undead monsters never sleep,
X		 * but also do not confer resistance when eaten
X		 */
X		    if (!(HSleep_resistance & INTRINSIC)) {
X			You("feel wide awake.");
X			HSleep_resistance |= INTRINSIC;
X		    }
X		} else if(resists_disint(ptr) && ptr->mlevel > rn2(20)) {
X		    if (!(HDisint_resistance & INTRINSIC)) {
X			You("feel very firm.");
X			HDisint_resistance |= INTRINSIC;
X		    }
X		}
X	    }
X	    break;
X	}
X	return(tp);
X}
X
Xstatic int
Xopentin(){
X	register int r;
X
X	if(!carried(tin.tin))		/* perhaps it was stolen? */
X		return(0);		/* %% probably we should use tinoid */
X	if(tin.usedtime++ >= 50) {
X		You("give up your attempt to open the tin.");
X		return(0);
X	}
X	if(tin.usedtime < tin.reqtime)
X		return(1);		/* still busy */
X	if(tin.tin->cursed && !rn2(8)) {
X		b_trapped("tin");
X		useup(tin.tin);
X		return(0);
X	}
X	You("succeed in opening the tin.");
X	if(!tin.tin->spe) {
X	    if(tin.tin->corpsenm == -1) {
X		pline("It turns out to be empty.");
X		tin.tin->dknown = tin.tin->known = TRUE;
X		useup(tin.tin);
X		return(0);
X	    }
X	    r = tin.tin->cursed ? 4 : rn2(TTSZ-1); /* Always rotten if cursed */
X	    pline("It smells like %s.", makeplural(
X		  Hallucination ? rndmonnam() : mons[tin.tin->corpsenm].mname));
X	    pline("Eat it? ");
X	    if (yn() == 'n') {
X		if (!Hallucination) tin.tin->dknown = tin.tin->known = TRUE;
X		useup(tin.tin);
X		return 0;
X	    }
X	    You("consume %s %s.", tintxts[r].txt,
X		  mons[tin.tin->corpsenm].mname);
X	    tin.tin->dknown = tin.tin->known = TRUE;
X	    (void) corpsefx(tin.tin->corpsenm);
X	    /* check for vomiting added by GAN 01/16/87 */
X	    if(tintxts[r].nut < 0) {
X		You("vomit.");
X		vomit();
X		morehungry(-tintxts[r].nut);
X	    } else lesshungry(tintxts[r].nut);
X	    if(r == 0) {			/* Deep Fried */
X		Glib = rnd(15);
X		pline("Eating deep fried food made your %s very slippery.",
X			makeplural(body_part(FINGER)));
X	    }
X	} else {
X	    if (tin.tin->cursed)
X		pline("It contains some decaying %s substance.",
X			Hallucination ? hcolor() : green);
X	    else
X		pline("It contains spinach - this makes you feel like %s!",
X			Hallucination ? "Swee'pea" : "Popeye");
X
X	    lesshungry(600);
X	    gainstr(tin.tin, 0);
X	}
X	tin.tin->dknown = tin.tin->known = TRUE;
X	useup(tin.tin);
X	return(0);
X}
X
Xint
XHear_again()
X{
X	flags.soundok = 1;
X	return 0;
X}
X
Xstatic void
Xrottenfood() {
X
X	pline("Blecch!  Rotten food!");
X	if(!rn2(4)) {
X		if (Hallucination) You("feel rather trippy.");
X		else
X			You("feel rather %s.",
X				body_part(LIGHT_HEADED));
X		make_confused(HConfusion + d(2,4),FALSE);
X	} else if(!rn2(4) && !Blind) {
X		pline("Everything suddenly goes dark.");
X		make_blinded((long)d(2,10),FALSE);
X	} else if(!rn2(3)) {
X		if(Blind)
X		  pline("The world spins and you slap against the floor.");
X		else
X		  pline("The world spins and goes dark.");
X		flags.soundok = 0;
X		nomul(-rnd(10));
X		nomovemsg = "You are conscious again.";
X		afternmv = Hear_again;
X	}
X}
X
Xstatic void
Xeatcorpse(otmp) register struct obj *otmp; {
X	register char *cname = mons[otmp->corpsenm].mname;
X	register int tp, rotted;
X
X	tp = 0;
X#ifdef LINT	/* problem if more than 320K moves before try to eat */
X	rotted = 0;
X#else
X	rotted = (moves - otmp->age)/((long)(10 + rn2(20)));	/* how decomposed? */
X#endif
X
X	if(otmp->cursed) rotted += 2;
X	else if (otmp->blessed) rotted -= 2;
X
X	if(otmp->corpsenm != PM_ACID_BLOB && (rotted > 5)) {
X		tp++;
X		pline("Ulch - that %s was tainted!",
X		      mons[otmp->corpsenm].mlet != S_FUNGUS ?
X				"meat" : "fungoid vegetation");
X#ifdef POLYSELF
X		if (u.usym == S_FUNGUS)
X			pline("It doesn't seem at all sickening, though...");
X		else {
X#endif
X			make_sick(10L + rn2(10),FALSE);
X			Sprintf(corpsename, "rotted %s corpse", cname);
X			u.usick_cause = corpsename;
X			flags.botl = 1;
X#ifdef POLYSELF
X		}
X#endif
X	} else if(poisonous(&mons[otmp->corpsenm]) && rn2(5)){
X		pline("Ecch - that must have been poisonous!");
X		if(!Poison_resistance) {
X			losestr(rnd(4));
X			losehp(rnd(15), "poisonous corpse");
X		} else	You("seem unaffected by the poison.");
X		(void) corpsefx(otmp->corpsenm);
X		tp++;
X	/* now any corpse left too long will make you mildly ill */
X	} else if(((rotted > 5) || ((rotted > 3) && rn2(5)))
X#ifdef POLYSELF
X		&& u.usym != S_FUNGUS
X#endif
X							){
X		tp++;
X		You("feel%s sick.", (Sick) ? " very" : "");
X		losehp(rnd(8), "cadaver");
X	} else	tp = corpsefx(otmp->corpsenm);
X	if(!tp && !rn2(7)) {
X
X	    rottenfood();
X	    lesshungry((int)mons[otmp->corpsenm].cnutrit >> 2);
X	} else {
X#ifdef POLYSELF
X	    pline("That %s corpse %s!", cname,
X		carnivorous(uasmon) ? "was delicious" : "tasted terrible");
X#else
X	    pline("That %s corpse tasted terrible!", cname);
X#endif
X	    lesshungry((int)mons[otmp->corpsenm].cnutrit);
X	}
X
X	/* delay is weight dependant */
X	multi = -(3 + (mons[otmp->corpsenm].cwt >> 2));
X}
X
X/* Created by GAN 01/28/87
X * Amended by AKP 09/22/87: if not hard, don't choke, just vomit.
X * Amended by 3.  06/12/89: if not hard, sometimes choke anyway, to keep risk.
X *
X * Note that if you have enough food, you can always stop being Sick!
X * choke() returns if you don't choke, kills you if you do.
X */
X/*ARGSUSED*/
Xstatic void
Xchoke(food)
Xregister struct objclass *food;
X{
X	/* only happens if you were satiated */
X	if(u.uhs != SATIATED) return;
X
X	if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL)
X		u.ualign--;	/* gluttony is unchivalrous */
X
X#ifndef HARD
X	if (rn2(20)) {
X		You("stuff yourself and then vomit voluminously.");
X		morehungry(1000);	/* you just got *very* sick! */
X		vomit();
X	} else {
X#endif
X		if(food)	killer = food->oc_name;
X		else		killer = "exuberant appetite";
X		You("choke over your food.");
X		You("die...");
X		done("choked");
X#ifndef HARD
X	}
X#endif
X}
X
Xint
Xdoeat() {
X	register struct obj *otmp;
X	register struct objclass *ftmp;
X	register int tmp;
X
X	if (!(otmp = floorfood("eat", 0))) return 0;
X
X	if(otmp->otyp == TIN) {
X		if (otmp->blessed) {
X			pline("The tin opens like magic!");
X			tmp = 1;
X		} else if(uwep) {
X			switch(uwep->otyp) {
X			case TIN_OPENER:
X				tmp = 1;
X				break;
X			case DAGGER:
X#ifdef WORM
X			case CRYSKNIFE:
X#endif
X				tmp = 3;
X				break;
X			case PICK_AXE:
X			case AXE:
X				tmp = 6;
X				break;
X			default:
X				goto no_opener;
X			}
X			pline("Using your %s you try to open the tin.",
X				aobjnam(uwep, NULL));
X		} else {
X		no_opener:
X			pline("It is not so easy to open this tin.");
X			if(Glib) {
X				pline("The tin slips out of your hands.");
X				if(otmp->quan > 1) {
X					register struct obj *obj;
X					obj = splitobj(otmp, 1);
X					if(otmp == uwep) setuwep(obj);
X				}
X				dropx(otmp);
X				return(1);
X			}
X			tmp = 10 + rn2(1 + 500/((int)(ACURR(A_DEX) + ACURR(A_STR))));
X		}
X		tin.reqtime = tmp;
X		tin.usedtime = 0;
X		tin.tin = otmp;
X		set_occupation(opentin, "opening the tin", 0);
X		return(1);
X	}
X
X	ftmp = &objects[otmp->otyp];
X	multi = -ftmp->oc_delay;
X	if(otmp->otyp == CORPSE) eatcorpse(otmp);
X	else {
X	    if (otmp->otyp != FORTUNE_COOKIE &&
X		otmp->otyp != DEAD_LIZARD &&
X		(otmp->cursed ||
X		 ((moves - otmp->age) > otmp->blessed ? 50 : 30)) &&
X		  !rn2(7)) {
X
X		rottenfood();
X		lesshungry(ftmp->nutrition >> 2);
X	    } else {
X		if(u.uhunger >= 1500) choke(ftmp);
X
X		switch(otmp->otyp){
X		case FOOD_RATION:
X			if(u.uhunger <= 200)
X			    if (Hallucination)
X				pline("Oh wow, like, superior, man!");
X			    else
X				pline("That food really hit the spot!");
X			else if(u.uhunger <= 700)
X				pline("That satiated your stomach!");
X	/* Have lesshungry() report when you are nearly full so all eating
X	 * warns when you are about to choke.
X	 */
X			lesshungry(ftmp->nutrition);
X			if(multi < 0) nomovemsg = "You finished your meal.";
X			break;
X		case TRIPE_RATION:
X#ifdef POLYSELF
X			if (carnivorous(uasmon))
X			    pline("That tripe ration was surprisingly good!");
X			else {
X#endif
X			    pline("Yak - dog food!");
X			    more_experienced(1,0);
X			    flags.botl = 1;
X#ifdef POLYSELF
X			}
X#endif
X			if(rn2(2)
X#ifdef POLYSELF
X				&& u.usym == S_HUMAN
X#endif
X							){
X				You("vomit.");
X				morehungry(20);
X				vomit();
X			} else	lesshungry(ftmp->nutrition);
X			break;
X#ifdef POLYSELF
X		case CLOVE_OF_GARLIC:
X			if (is_undead(uasmon)) {
X				You("cannot stand eating it.  You vomit.");
X				vomit();
X				break;
X			}
X			/* Fall through otherwise */
X#endif
X		default:
X			if (otmp->otyp==SLIME_MOLD && !otmp->cursed &&
X				otmp->spe == current_fruit)
X			    pline(!Hallucination ?
X				    "Mmm!  Your favorite!" :
X				    "Yum!  Your fave fruit!");
X			else {
X			    int oldquan = otmp->quan;
X			    otmp->quan = 1;
X			    pline("That %s was %s!", xname(otmp),
X			      otmp->cursed ?
X				(Hallucination ? "grody" : "terrible"):
X			      Hallucination ? "gnarly" : (
X#ifdef TOLKIEN
X			       otmp->otyp==CRAM_RATION ? "bland":
X#endif
X			       "delicious"));
X			    otmp->quan = oldquan;
X			}
X			lesshungry(ftmp->nutrition);
X
X			switch(otmp->otyp) {
X#ifdef POLYSELF
X			    case CLOVE_OF_GARLIC:
X				if (u.ulycn != -1) {
X					You("feel purified.");
X					if(uasmon == &mons[u.ulycn] &&
X					  !Polymorph_control)
X						rehumanize();
X					u.ulycn = -1;
X				}
X				break;
X#endif
X			    case DEAD_LIZARD:
X				/* Relief from cockatrices -dgk */
X				if (Stoned) {
X					Stoned = 0;
X					You("feel limber!");
X				}
X				if (HStun > 2)  make_stunned(2L,FALSE);
X				if (HConfusion > 2)  make_confused(2L,FALSE);
X				break;
X			    case CARROT:
X				make_blinded(0L,TRUE);
X				break;
X			    case FORTUNE_COOKIE:
X				outrumor(bcsign(otmp), TRUE);
X				break;
X			    case LUMP_OF_ROYAL_JELLY:
X				/* This stuff seems to be VERY healthy! */
X				gainstr(otmp, 1);
X				u.uhp += (otmp->cursed) ? -rnd(20) : rnd(20);
X				if(u.uhp > u.uhpmax) {
X					if(!rn2(17)) u.uhpmax++;
X					u.uhp = u.uhpmax;
X				} else if(u.uhp <= 0) {
X					killer = "rotten jelly lump";
X					done("died");
X				}
X				if(!otmp->cursed) heal_legs();
X				break;
X			    case EGG:
X				if(otmp->corpsenm == PM_COCKATRICE) {
X#ifdef POLYSELF
X				    if(!resists_ston(uasmon)) {
X#endif
X					if (!Stoned) Stoned = 5;
X					killer = "cockatrice egg";
X#ifdef POLYSELF
X				    }
X#endif
X				}
X				break;
X			    default:	break;
X			}
X			break;
X		}
X	    }
X	}
X	
X
X	if(multi < 0 && !nomovemsg){
X#ifdef LINT	/* JAR		static char msgbuf[BUFSZ]; */
X		char msgbuf[BUFSZ];
X#else
X		static char msgbuf[BUFSZ];
X#endif
X		/* note: ftmp->oc_name usually works, the exception being
X		 * for fruits.  If fruits are changed to take more time to
X		 * eat, this has to be modified.
X		 */
X		if (otmp->otyp != CORPSE)
X			Sprintf(msgbuf, "You finish eating the %s.",
X						ftmp->oc_name);
X		else
X			Sprintf(msgbuf, "You finish eating the %s corpse.",
X						mons[otmp->corpsenm].mname);
X		nomovemsg = msgbuf;
X	}
X	useup(otmp);
X	return(1);
X}
X
X/* called in main.c */
Xvoid
Xgethungry(){
X	--u.uhunger;
X	if(moves % 2) {
X		if(HRegeneration) u.uhunger--;
X		if(Hunger) u.uhunger--;
X		/* a3:  if(Hunger & LEFT_RING) u.uhunger--;
X			if(Hunger & RIGHT_RING) u.uhunger--;
X		   etc. */
X	}
X	if(moves % 20 == 0) {			/* jimt@asgb */
X		/* +0 rings don't do anything, so don't affect hunger */
X		if(uleft && uleft->otyp && (!objects[uleft->otyp].oc_charged
X			|| uleft->spe)) u.uhunger--;
X		if(uright && uright->otyp && (!objects[uright->otyp].oc_charged
X			|| uright->spe)) u.uhunger--;
X		if(uamul) u.uhunger--;
X		if(u.uhave_amulet) u.uhunger--;
X	}
X	newuhs(TRUE);
X}
X
X/* called after vomiting and after performing feats of magic */
Xvoid
Xmorehungry(num)
Xregister int num;
X{
X	u.uhunger -= num;
X	newuhs(TRUE);
X}
X
X/* called after eating something (and after drinking fruit juice) */
Xvoid
Xlesshungry(num)
Xregister int num;
X{
X	u.uhunger += num;
X	if(u.uhunger >= 2000) choke((struct objclass *) 0);
X	else {
X	    /* Have lesshungry() report when you're nearly full so all eating
X	     * warns when you're about to choke.
X	     */
X	    if (u.uhunger >= 1500) {
X		pline("You're having a hard time getting all of it down.");
X		multi -= 2;
X		nomovemsg = "You're finally finished.";
X	    }
X	}
X	newuhs(FALSE);
X}
X
Xstatic int
Xunfaint() {
X	(void) Hear_again();
X	u.uhs = FAINTING;
X	flags.botl = 1;
X	return 0;
X}
X
Xvoid
Xnewuhs(incr) boolean incr; {
X	register int newhs, h = u.uhunger;
X
X	newhs = (h > 1000) ? SATIATED :
X		(h > 150) ? NOT_HUNGRY :
X		(h > 50) ? HUNGRY :
X		(h > 0) ? WEAK : FAINTING;
X
X	if(newhs == FAINTING) {
X		if(u.uhs == FAINTED) newhs = FAINTED;
X		if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
X			if(u.uhs != FAINTED && multi >= 0 /* %% */) {
X				You("faint from lack of food.");
X				flags.soundok = 0;
X				nomul(-10+(u.uhunger/10));
X				nomovemsg = "You regain consciousness.";
X				afternmv = unfaint;
X				newhs = FAINTED;
X			}
X		} else
X		if(u.uhunger < -(int)(200 + 20*ACURR(A_CON))) {
X			u.uhs = STARVED;
X			flags.botl = 1;
X			bot();
X			You("die from starvation.");
X			done("starved");
X		}
X	}
X
X	if(newhs != u.uhs) {
X		if(newhs >= WEAK && u.uhs < WEAK)
X			losestr(1);	/* this may kill you -- see below */
X		else if(newhs < WEAK && u.uhs >= WEAK)
X			losestr(-1);
X		switch(newhs){
X		case HUNGRY:
X			if (Hallucination) {
X			    pline((!incr) ?
X				"You now have a lesser case of the munchies." :
X				"You are getting the munchies.");
X			} else
X			    You((!incr) ? "only feel hungry now." :
X				  (u.uhunger < 145) ? "feel hungry." :
X				   "are beginning to feel hungry.");
X			break;
X		case WEAK:
X			if (Hallucination)
X			    pline((!incr) ?
X				  "You still have the munchies." :
X				  "The munchies are starting to interfere with your motor capabilities.");
X			else
X			    You((!incr) ? "feel weak now." :
X				  (u.uhunger < 45) ? "feel weak." :
X				   "are beginning to feel weak.");
X			break;
X		}
X		u.uhs = newhs;
X		flags.botl = 1;
X		if(u.uhp < 1) {
X			You("die from hunger and exhaustion.");
X			killer = "exhaustion";
X			done("starved");
X		}
X	}
X}
X
Xstruct obj *
Xfloorfood(verb,corpseonly)
Xchar *verb;
Xint corpseonly;
X{
X	register struct obj *otmp;
X
X	/* Is there some food (probably a heavy corpse) here on the ground? */
X	if(!Levitation && !u.uswallow) {
X	if(levl[u.ux][u.uy].omask)
X	    for(otmp = fobj; otmp; otmp = otmp->nobj) {
X		if(otmp->ox == u.ux && otmp->oy == u.uy &&
X		   (otmp->otyp==CORPSE ||
X		   (!corpseonly && otmp->olet == FOOD_SYM))) {
X			pline("There %s %s here; %s %s? ",
X				(otmp->quan == 1) ? "is" : "are",
X				doname(otmp), verb,
X				(otmp->quan == 1) ? "it" : "one");
X			if(yn() == 'y') {
X				if(otmp->quan != 1)
X					(void) splitobj(otmp, 1);
X				freeobj(otmp);
X				otmp = addinv(otmp);
X				addtobill(otmp, TRUE);
X				if(Invisible) newsym(u.ux, u.uy);
X				return otmp;
X			}
X		}
X	    }
X	}
X	return getobj(comestibles, verb);
X}
X
X/* Side effects of vomiting */
X/* TO DO: regurgitate swallowed monsters when poly'd */
Xvoid
Xvomit() { /* A good idea from David Neves */
X	make_sick(0L,TRUE);
X}
END_OF_FILE
if test 19624 -ne `wc -c <'src/eat.c'`; then
    echo shar: \"'src/eat.c'\" unpacked with wrong size!
fi
# end of 'src/eat.c'
fi
echo shar: End of archive 16 \(of 38\).
cp /dev/null ark16isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 38 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0