[comp.sources.games] v10i060: 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 60
Archive-name: nethack3p9/Part15
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 15 (of 56)."
# Contents:  src/eat.c src/makedefs.c
# Wrapped by billr@saab on Wed Jul 11 17:11:11 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
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'\" \(37528 characters\)
sed "s/^X//" >'src/eat.c' <<'END_OF_FILE'
X/*      SCCS Id: @(#)eat.c      3.0     89/11/21
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include	"hack.h"
X/*#define DEBUG 	/* uncomment to enable new eat code debugging */
X
X#ifdef DEBUG
X# ifdef WIZARD
X#define debug	if (wizard) pline
X# else
X#define debug	pline
X# endif
X#endif
X
XSTATIC_PTR int NDECL(Meatdone);
XSTATIC_PTR int NDECL(eatfood);
XSTATIC_PTR int NDECL(opentin);
XSTATIC_PTR int NDECL(unfaint);
X
X#ifdef OVLB
Xstatic int FDECL(rounddiv, (long, int));
Xstatic void FDECL(choke, (struct obj *));
Xstatic void NDECL(recalc_wt);
Xstatic struct obj *FDECL(touchfood, (struct obj *));
Xstatic void NDECL(do_reset_eat);
Xstatic void FDECL(done_eating, (BOOLEAN_P));
Xstatic void FDECL(cprefx, (int));
Xstatic void FDECL(cpostfx, (int));
Xstatic void FDECL(start_tin, (struct obj *));
Xstatic int FDECL(eatcorpse, (struct obj *));
Xstatic void FDECL(start_eating, (struct obj *));
Xstatic void FDECL(fprefx, (struct obj *));
Xstatic void FDECL(fpostfx, (struct obj *));
Xstatic int NDECL(bite);
X
X#ifdef POLYSELF
Xstatic int FDECL(rottenfood, (struct obj *));
Xstatic void NDECL(eatspecial);
Xstatic const char * FDECL(foodword, (struct obj *));
X#else
Xstatic int NDECL(rottenfood);
X#endif /* POLYSELF */
X
Xchar corpsename[60];
Xchar msgbuf[BUFSZ];
X
X#endif /* OVLB */
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
X#ifdef OVLB
X
Xconst char *hu_stat[] = {
X	"Satiated",
X	"        ",
X	"Hungry  ",
X	"Weak    ",
X	"Fainting",
X	"Fainted ",
X	"Starved "
X};
X
X#endif /* OVLB */
X
X#ifndef OVLB
X
XSTATIC_DCL const char NEARDATA comestibles[];
X
X#else
X
XSTATIC_OVL const char NEARDATA comestibles[] = { FOOD_SYM, 0 };
X#ifdef POLYSELF
XSTATIC_OVL const char NEARDATA everything[] = { GOLD_SYM, /* must come first */
X	WEAPON_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM,
X# ifdef SPELLS
X	SPBOOK_SYM,
X# endif
X	RING_SYM, WAND_SYM, AMULET_SYM, FOOD_SYM, TOOL_SYM, GEM_SYM,
X	ROCK_SYM, BALL_SYM, CHAIN_SYM, 0 };
X
X#endif /* POLYSELF */
X#endif /* OVLB */
X#ifdef OVL1
X# ifdef POLYSELF
X
Xboolean
Xis_edible(obj)
Xregister struct obj *obj;
X{
X	if (metallivorous(uasmon) && (obj->olet == GOLD_SYM ||
X			(objects[obj->otyp].oc_material > WOOD &&
X			objects[obj->otyp].oc_material < MINERAL)))
X		return TRUE;
X	if (u.umonnum == PM_GELATINOUS_CUBE &&
X			objects[obj->otyp].oc_material <= WOOD)
X		return TRUE;
X	return !!index(comestibles, obj->olet);
X}
X# endif /* POLYSELF */
X#endif /* OVL1 */
X#ifdef OVLB
X
X/* calculate x/y, rounding as appropriate */
X
Xstatic int
Xrounddiv(x, y)
Xlong x;
Xint y;
X{
X	int divsgn = 1;
X	int r, m;
X
X	if (y == 0)
X		panic("division by zero in rounddiv");
X	if (x < 0) {
X		divsgn = -divsgn; x = -x;
X	}
X	if (y < 0) {
X		divsgn = -divsgn; y = -y;
X	}
X	r = x/y;
X	m = x%y;
X	if (2*m >= y)
X		r++;
X	return divsgn*r;
X}
X
Xvoid
Xinit_uhunger(){
X	u.uhunger = 900;
X	u.uhs = NOT_HUNGRY;
X}
X
Xconst struct { const 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} NEARDATA tin;
X
Xstatic struct {
X	struct	obj *piece;	/* the thing being eaten, or last thing that
X				 * was partially eaten, unless that thing was
X				 * a tin, which uses the tin structure above */
X	int	usedtime,	/* turns spent eating */
X		reqtime;	/* turns required to eat */
X	int	nmod;		/* coded nutrition per turn */
X	Bitfield(canchoke,1);	/* was satiated at beginning */
X	Bitfield(fullwarn,1);	/* have warned about being full */
X	Bitfield(eating,1);	/* victual currently being eaten */
X	Bitfield(doreset,1);	/* stop eating at end of turn */
X} NEARDATA victual;
X
XSTATIC_PTR
Xint
XMeatdone() {		/* called after mimicing is over */
X	u.usym =
X#ifdef POLYSELF
X		u.mtimedone ? uasmon->mlet :
X#endif
X		S_HUMAN;
X	prme();
X	return 0;
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 *		  11/10/89: if hard, rarely vomit anyway, for slim chance.
X */
X/*ARGSUSED*/
Xstatic void
Xchoke(food)	/* To a full belly all food is bad. (It.) */
X	register struct obj *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#ifdef HARD
X	if (!rn2(20)) {
X#else
X	if (rn2(20)) {
X#endif
X		You("stuff yourself and then vomit voluminously.");
X		morehungry(1000);	/* you just got *very* sick! */
X		vomit();
X	} else {
X		killer_format = KILLED_BY_AN;
X		if(food) {
X#ifdef POLYSELF
X			if (food->olet == GOLD_SYM) {
X				killer_format = KILLED_BY;
X				killer = "eating too rich a meal";
X			} else
X#endif
X				killer = singular(food, xname);
X		} else
X			killer = "exuberant appetite";
X		if (!food) You("choke over it.");
X#ifdef POLYSELF
X		else You("choke over your %s.", foodword(food));
X#else
X		else You("choke over your food.");
X#endif
X		You("die...");
X		done(CHOKING);
X	}
X}
X
Xstatic void
Xrecalc_wt() {	/* modify object wt. depending on time spent consuming it */
X	register struct obj *piece = victual.piece;
X
X#ifdef DEBUG
X	debug("Old weight = %d", piece->owt);
X	debug("Used time = %d, Req'd time = %d",
X		victual.usedtime, victual.reqtime);
X#endif
X	/* weight(piece) = weight of full item */
X  	if(victual.usedtime)
X	    piece->owt = eaten_stat(weight(piece), piece);
X#ifdef DEBUG
X	debug("New weight = %d", piece->owt);
X#endif
X}
X
Xvoid
Xreset_eat() {		/* called when eating interrupted by an event */
X
X    /* we only set a flag here - the actual reset process is done after
X     * the round is spent eating.
X     */
X	if(victual.eating && !victual.doreset) {
X#ifdef DEBUG
X	    debug("reset_eat...");
X#endif
X	    victual.doreset = TRUE;
X	}
X	return;
X}
X
Xstatic struct obj *
Xtouchfood(otmp)
Xregister struct obj *otmp;
X{
X	if (otmp->quan > 1) {
X	    otmp = splitobj(otmp, (int)otmp->quan-1);
X#ifdef DEBUG
X	    debug("split object,");
X#endif
X	}
X	if (!otmp->oeaten)
X	    otmp->oeaten = (otmp->otyp == CORPSE ?
X				(int)mons[otmp->corpsenm].cnutrit :
X				objects[otmp->otyp].nutrition);
X	if (carried(otmp)) {
X	    freeinv(otmp);
X	    if(inv_cnt() >= 52)
X		dropy(otmp);
X	    else
X		otmp = addinv(otmp); /* unlikely but a merge is possible */
X	}
X	return(otmp);
X}
X
X/* When food decays, in the middle of your meal, we don't want to dereference
X * any dangling pointers, so set it to null (which should still trigger
X * do_reset_eat() at the beginning of eatfood()) and check for null pointers
X * in do_reset_eat().
X */
Xvoid
Xfood_disappears(obj)
Xregister struct obj *obj;
X{
X	if (obj == victual.piece) victual.piece = (struct obj *)0;
X}
X
Xstatic void
Xdo_reset_eat() {
X
X#ifdef DEBUG
X	debug("do_reset_eat...");
X#endif
X	if (victual.piece) {
X		victual.piece = touchfood(victual.piece);
X		recalc_wt();
X	}
X	victual.fullwarn = victual.eating = victual.doreset = FALSE;
X	/* Do not set canchoke to FALSE; if we continue eating the same object
X	 * we need to know if canchoke was set when they started eating it the
X	 * previous time.  And if we don't continue eating the same object
X	 * canchoke always gets recalculated anyway.
X	 */
X	stop_occupation();
X}
X
XSTATIC_PTR
Xint
Xeatfood() {		/* called each move during eating process */
X	if(!carried(victual.piece) && !obj_here(victual.piece, u.ux, u.uy)) {
X		/* maybe it was stolen? */
X		do_reset_eat();
X		return(0);
X	}
X	if(!victual.eating) return(0);
X
X	if(++victual.usedtime < victual.reqtime) {
X	    if(bite()) return(0);
X	    return(1);	/* still busy */
X	} else {	/* done */
X	    done_eating(TRUE);
X	    return(0);
X	}
X}
X
Xstatic void
Xdone_eating(message)
Xboolean message;
X{
X#ifndef NO_SIGNAL
X	victual.piece->in_use = TRUE;
X#endif
X	if (nomovemsg) {
X		if (message) pline(nomovemsg);
X		nomovemsg = 0;
X	} else if (message)
X		You("finish eating the %s.", singular(victual.piece, xname));
X
X	if(victual.piece->otyp == CORPSE)
X		cpostfx(victual.piece->corpsenm);
X	else
X		fpostfx(victual.piece);
X
X	if (carried(victual.piece)) useup(victual.piece);
X	else useupf(victual.piece);
X	victual.piece = (struct obj *) 0;
X	victual.fullwarn = victual.eating = victual.doreset = FALSE;
X}
X
Xstatic void
Xcprefx(pm)		/* called at the "first bite" of a corpse */
Xregister int pm;
X{
X	if ((pl_character[0]=='E') ? is_elf(&mons[pm]) : is_human(&mons[pm])) {
X		You("cannibal!  You will regret this!");
X		Aggravate_monster |= INTRINSIC;
X	}
X
X	switch(pm) {
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_COCKATRICE:
X#ifdef MEDUSA
X	    case PM_MEDUSA:
X#endif
X#ifdef POLYSELF
X		if(!resists_ston(uasmon))
X#endif
X			{
X			char *cruft;	/* killer is const char * */
X			killer_format = KILLED_BY;
X			killer = cruft = (char *) alloc(40);
X			You("turn to stone.");
X			Sprintf(cruft, "%s meat", mons[pm].mname);
X			done(STONING);
X			}
X			break;
X#ifdef POLYSELF
X	    case PM_LIZARD:
X		/* Relief from cockatrices -dgk */
X		if (Stoned) {
X			Stoned = 0;
X			You("feel limber!");
X		}
X		break;
X	    default:
X		if(acidic(&mons[pm]) && Stoned) {
X		    pline("What a pity - you just destroyed a future piece of art!");
X		    Stoned = 0;
X		}
X#endif
X	}
X	return;
X}
X
Xstatic void
Xcpostfx(pm)		/* called after completely consuming a corpse */
Xregister int pm;
X{
X	register int tmp = 0;
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_STALKER:
X		if(!Invis) {
X			HInvis = 50+rn2(100);
X			if(!See_invisible)
X				newsym(u.ux, u.uy);
X		} else {
X			if (!(HInvis & INTRINSIC)) 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_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 pile of gold.");
X		    nomul(-tmp);
X		    afternmv = Meatdone;
X		    if (pl_character[0]=='E')
X			nomovemsg = "You now again prefer mimicking an elf.";
X		    else
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	    case PM_LIZARD:
X		if (HStun > 2)  make_stunned(2L,FALSE);
X		if (HConfusion > 2)  make_confused(2L,FALSE);
X		break;
X	    case PM_CHAMELEON:
X		You("feel a change coming over you.");
X#ifdef POLYSELF
X		polyself();
X#else
X		newman();
X#endif
X		break;
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		/* prevent polymorph abuse by killing/eating your offspring */
X		if(ptr >= &mons[PM_BABY_GRAY_DRAGON] &&
X		   ptr <= &mons[PM_BABY_YELLOW_DRAGON]) return;
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(15)) {
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(15)) {
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(15)) {
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(15))
X		   || ((pm == PM_KILLER_BEE || pm == PM_SCORPION) && !rn2(4))) {
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(15)) {
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(15)) {
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(15)) {
X		    if (!(HDisint_resistance & INTRINSIC)) {
X			You("feel very firm.");
X			HDisint_resistance |= INTRINSIC;
X		    }
X		}
X	    }
X	    break;
X	}
X	return;
X}
X
XSTATIC_PTR
Xint
Xopentin()		/* called during each move whilst opening a tin */
X{
X	register int r;
X
X	if(!carried(tin.tin) && !obj_here(tin.tin, u.ux, u.uy))
X					/* 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 && tin.tin->spe != -1 && !rn2(8)) {
X		b_trapped("tin");
X		goto use_me;
X	}
X	You("succeed in opening the tin.");
X	if(tin.tin->spe != 1) {
X	    if(tin.tin->corpsenm == -1) {
X		pline("It turns out to be empty.");
X		tin.tin->dknown = tin.tin->known = TRUE;
X		goto use_me;
X	    }
X	    r = tin.tin->cursed ? 4 : rn2(TTSZ-1); /* Always rotten if cursed */
X#ifdef MACOS
X	{
X		char tmp[128];
X		if(!flags.silent) SysBeep(20);
X		Sprintf(tmp, "It smells like %s. Eat it ?", makeplural(
X		  Hallucination ? rndmonnam() : mons[tin.tin->corpsenm].mname));
X		if(UseMacAlertText(128, tmp) == 2) {
X#else
X	    pline("It smells like %s.", makeplural(
X		  Hallucination ? rndmonnam() : mons[tin.tin->corpsenm].mname));
X	    pline("Eat it? ");
X	    if (yn() == 'n') {
X#endif
X		if (!Hallucination) tin.tin->dknown = tin.tin->known = TRUE;
X		if (flags.verbose) You("discard the open tin.");
X		goto use_me;
X	    }
X#ifdef MACOS
X	}
X#endif
X	    You("consume %s %s.", tintxts[r].txt,
X		  mons[tin.tin->corpsenm].mname);
X	    tin.tin->dknown = tin.tin->known = TRUE;
X	    cprefx(tin.tin->corpsenm); cpostfx(tin.tin->corpsenm);
X
X	    /* check for vomiting added by GAN 01/16/87 */
X	    if(tintxts[r].nut < 0) make_vomiting((long)rn1(15,10), FALSE);
X	    else lesshungry(tintxts[r].nut);
X
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#ifdef MACOS
X	{
X		char tmp[128];
X		if(!flags.silent) SysBeep(20);
X	    if (tin.tin->cursed)
X		Sprintf(tmp, "It contains some decaying %s substance. Eat it ?",
X			Hallucination ? hcolor() : green);
X	    else
X		Sprintf(tmp, "It contains spinach. Eat it ?");
X		if(UseMacAlertText(128, tmp) == 2) {
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.");
X
X	    pline("Eat it? ");
X	    if (yn() == 'n') {
X#endif
X		if (!Hallucination && !tin.tin->cursed)
X		    tin.tin->dknown = tin.tin->known = TRUE;
X		if (flags.verbose)
X		    You("discard the open tin.");
X		goto use_me;
X	    }
X#ifdef MACOS
X	}
X#endif
X	    if (!tin.tin->cursed)
X		pline("This makes you feel like %s!",
X		      Hallucination ? "Swee'pea" : "Popeye");
X	    lesshungry(600);
X	    gainstr(tin.tin, 0);
X	}
X	tin.tin->dknown = tin.tin->known = TRUE;
Xuse_me:
X	if (carried(tin.tin)) useup(tin.tin);
X	else useupf(tin.tin);
X	return(0);
X}
X
Xstatic void
Xstart_tin(otmp)		/* called when starting to open a tin */
X	register struct obj *otmp;
X{
X	register int tmp;
X
X#ifdef POLYSELF
X	if (metallivorous(uasmon)) {
X		You("bite right into the metal can....");
X		tmp = 1;
X	} else
X#endif
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 TOLKIEN
X		case ELVEN_DAGGER:
X		case ORCISH_DAGGER:
X#endif
X		case ATHAME:
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 {
Xno_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			if (carried(otmp)) dropx(otmp);
X			else stackobj(otmp);
X			return;
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;
X}
X
Xint
XHear_again() {		/* called when waking up after fainting */
X	flags.soundok = 1;
X	return 0;
X}
X
Xstatic int
X#ifdef POLYSELF
Xrottenfood(obj)
Xstruct obj *obj;
X#else
Xrottenfood()
X#endif
X{		/* called on the "first bite" of rotten food */
X#ifdef POLYSELF
X	pline("Blecch!  Rotten %s!", foodword(obj));
X#else
X	pline("Blecch!  Rotten food!");
X#endif
X	if(!rn2(4)) {
X		if (Hallucination) You("feel rather trippy.");
X		else You("feel rather %s.", 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		return(1);
X	}
X	return(0);
X}
X
Xstatic int
Xeatcorpse(otmp)		/* called when a corpse is selected as food */
X	register struct obj *otmp;
X{
X	register const char *cname = mons[otmp->corpsenm].mname;
X	register int tp, rotted = 0;
X
X	tp = 0;
X
X	if(otmp->corpsenm != PM_LIZARD) {
X#ifndef LINT	/* problem if more than 320K moves before try to eat */
X		rotted = (monstermoves - otmp->age)/((long)(10 + rn2(20)));
X#endif
X
X		if(otmp->cursed) rotted += 2;
X		else if (otmp->blessed) rotted -= 2;
X	}
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 = (const char *)corpsename;
X			flags.botl = 1;
X#ifdef POLYSELF
X		}
X#endif
X		if (carried(otmp)) useup(otmp);
X		else useupf(otmp);
X		return(1);
X	} else if(acidic(&mons[otmp->corpsenm])
X#ifdef POLYSELF
X		  && !resists_acid(uasmon)
X#endif
X		 ) {
X		tp++;
X		You("have a very bad case of stomach acid.");
X		losehp(rnd(15), "acidic corpse", KILLED_BY_AN);
X	} else if(poisonous(&mons[otmp->corpsenm]) && rn2(5)) {
X		tp++;
X		pline("Ecch - that must have been poisonous!");
X		if(!Poison_resistance) {
X			losestr(rnd(4));
X			losehp(rnd(15), "poisonous corpse", KILLED_BY_AN);
X		} else	You("seem unaffected by the poison.");
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", KILLED_BY_AN);
X	}
X	if(!tp && otmp->corpsenm != PM_LIZARD && (otmp->orotten || !rn2(7))) {
X#ifdef POLYSELF
X	    if(rottenfood(otmp)) {
X#else
X	    if(rottenfood()) {
X#endif
X		otmp->orotten = TRUE;
X		(void)touchfood(otmp);
X		return(1);
X	    }
X	    otmp->oeaten >>= 2;
X	} else {
X#ifdef POLYSELF
X	    pline("This %s corpse %s!", cname,
X		carnivorous(uasmon) ? "is delicious" : "tastes terrible");
X#else
X	    pline("This %s corpse tastes terrible!", cname);
X#endif
X	}
X
X	/* delay is weight dependent */
X	victual.reqtime = 3 + (mons[otmp->corpsenm].cwt >> 2);
X	return(0);
X}
X
Xstatic void
Xstart_eating(otmp)		/* called as you start to eat */
X	register struct obj *otmp;
X{
X#ifdef DEBUG
X	debug("start_eating: %lx (victual = %lx)", otmp, victual.piece);
X	debug("reqtime = %d", victual.reqtime);
X	debug("(original reqtime = %d)", objects[otmp->otyp].oc_delay);
X	debug("nmod = %d", victual.nmod);
X	debug("oeaten = %d", otmp->oeaten);
X#endif
X	victual.fullwarn = victual.doreset = FALSE;
X	victual.eating = TRUE;
X
X	if (otmp->otyp == CORPSE)
X	    cprefx(victual.piece->corpsenm);
X
X	if (bite()) return;
X
X	if(++victual.usedtime >= victual.reqtime) {
X	    done_eating(FALSE);
X	    return;
X	}
X
X	Sprintf(msgbuf, "eating the %s", singular(otmp, xname));
X	set_occupation(eatfood, msgbuf, 0);
X}
X
X
Xstatic void
Xfprefx(otmp)		/* called on "first bite" of (non-corpse) food */
X
X	register struct obj *otmp;
X{
X	switch(otmp->otyp) {
X
X	    case FOOD_RATION:
X		if(u.uhunger <= 200)
X		    if (Hallucination) pline("Oh wow, like, superior, man!");
X		    else	       pline("That food really hit the spot!");
X		else if(u.uhunger <= 700) pline("That satiated your stomach!");
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			&& !carnivorous(uasmon)
X#endif
X						) {
X			make_vomiting((long)rn1(victual.reqtime, 10), FALSE);
X		}
X		break;
X#ifdef POLYSELF
X	    case CLOVE_OF_GARLIC:
X		if (is_undead(uasmon)) {
X			make_vomiting((long)rn1(victual.reqtime, 5), FALSE);
X			break;
X		}
X		/* Fall through otherwise */
X#endif
X	    default:
X#ifdef TUTTI_FRUTTI
X		if (otmp->otyp==SLIME_MOLD && !otmp->cursed
X			&& otmp->spe == current_fruit)
X		    pline(!Hallucination ? "Mmm!  Your favorite!" :
X			    		   "Yum!  Your fave fruit!");
X		else
X#endif
X#ifdef UNIX
X		if (otmp->otyp == APPLE || otmp->otyp == PEAR) {
X		    if (!Hallucination) pline("Core dumped.");
X		    else {
X/* This is based on an old Usenet joke, a fake a.out manual page */
X			int x = rnd(100);
X			if (x <= 75)
X			    pline("Segmentation fault -- core dumped.");
X			else if (x <= 99)
X			    pline("Bus error -- core dumped.");
X			else pline("Yo' mama -- core dumped.");
X		    }
X		} else 
X#endif
X		{
X		    unsigned oldquan = otmp->quan;
X		    otmp->quan = 1;
X		    pline("This %s is %s!", xname(otmp),
X		      otmp->cursed ? (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		break;
X	}
X}
X
X#ifdef POLYSELF
Xstatic void
Xeatspecial() /* called after eating non-food */
X{
X	register struct obj *otmp = victual.piece;
X
X	lesshungry(victual.nmod);
X	victual.piece = (struct obj *)0;
X	victual.eating = 0;
X	if (otmp->olet == GOLD_SYM) { /* temporary gold object */
X		free ((genericptr_t)otmp);
X		return;
X	}
X	if (otmp->olet == POTION_SYM) {
X		otmp->quan++; /* dopotion() does a useup() */
X#ifdef MACOS
X		segments |= SEG_EAT;
X#endif
X		(void)dopotion(otmp);
X	}
X	if (otmp == uball) unpunish();
X	if (otmp == uchain) unpunish(); /* but no useup() */
X	else if (carried(otmp)) useup(otmp);
X	else useupf(otmp);
X}
X
Xstatic const char *
Xfoodword(otmp)
Xregister struct obj *otmp;
X{
X	if (otmp->olet == FOOD_SYM) return "food";
X	if (otmp->olet == GOLD_SYM) return "gold";
X	if (objects[otmp->otyp].oc_material == GLASS) {
X		if (otmp->olet == GEM_SYM && otmp->dknown)
X			makeknown(otmp->otyp);
X		return "glass";
X	}
X	if (objects[otmp->otyp].oc_material > WOOD &&
X			objects[otmp->otyp].oc_material < MINERAL)
X		return "metal";
X	if (objects[otmp->otyp].oc_material == MINERAL)
X		return (otmp->otyp <= LAST_GEM && otmp->olet == GEM_SYM)
X			? "rich food" : "stone";
X	if (objects[otmp->otyp].oc_material == WOOD) return "wood";
X	if (otmp->olet == ARMOR_SYM) return "armor";
X	return "stuff";
X}
X#endif
X
Xstatic void
Xfpostfx(otmp)		/* called after consuming (non-corpse) food */
X
X	register struct obj *otmp;
X{
X	switch(otmp->otyp) {
X#ifdef POLYSELF
X	    case CLOVE_OF_GARLIC:
X		if (u.ulycn != -1) {
X		    u.ulycn = -1;
X		    You("feel purified.");
X		    if(uasmon == &mons[u.ulycn] && !Polymorph_control)
X			rehumanize();
X		}
X		break;
X#endif
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_format = KILLED_BY_AN;
X			killer = "rotten lump of royal jelly";
X			done(POISONING);
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_format = KILLED_BY_AN;
X			killer = "cockatrice egg";
X#ifdef POLYSELF
X		    }
X#endif
X		}
X		break;
X	}
X	return;
X}
X
Xint
Xdoeat() {		/* generic "eat" command funtion (see cmd.c) */
X	register struct obj *otmp;
X	int basenutrit; 		/* nutrition of full item */
X
X	if (Strangled) {
X		pline("If you can't breathe air, how can you consume solids?");
X		return 0;
X	}
X	if (!(otmp = floorfood("eat", 0))) return 0;
X#ifdef POLYSELF
X	/* We have to make non-foods take no time to eat, unless we want to
X	 * do ridiculous amounts of coding to deal with partly eaten plate
X	 * mails, players who polymorph back to human in the middle of their
X	 * metallic meal, etc....
X	 */
X	if (!is_edible(otmp)) {
X	    You("cannot eat that!");
X	    if (otmp->olet == GOLD_SYM) { /* temp gold object */
X		if (otmp->ox) mkgold(OGOLD(otmp), u.ux, u.uy);
X		else u.ugold += OGOLD(otmp);
X		free((genericptr_t) otmp);
X	    }
X	    return 0;
X	}
X	if (otmp->olet != FOOD_SYM) {
X	    victual.reqtime = 1;
X	    victual.piece = otmp;
X		/* Don't split it, we don't need to if it's 1 move */
X	    victual.usedtime = 0;
X	    victual.canchoke = (u.uhs == SATIATED);
X	    if (otmp->olet == GOLD_SYM)
X		basenutrit = ((OGOLD(otmp) > 5000L) ? 5000 : (int)OGOLD(otmp));
X	    else basenutrit = otmp->owt * 10 / otmp->quan;
X	    victual.nmod = basenutrit;
X	    victual.eating = TRUE; /* needed for lesshungry() */
X		
X	    if (otmp->cursed) 
X		(void) rottenfood(otmp);
X
X	    if (otmp->olet == WEAPON_SYM && otmp->opoisoned) {
X		pline("Ecch - that must have been poisonous!");
X		if(!Poison_resistance) {
X		    losestr(rnd(4));
X		    losehp(rnd(15), xname(otmp), KILLED_BY_AN);
X		} else
X		    You("seem unaffected by the poison.");
X	    } else if (!otmp->cursed)
X		pline("This %s is delicious!",
X		    otmp->olet == GOLD_SYM ? "gold" : xname(otmp));
X	    eatspecial();
X	    return 1;
X	}
X#endif
X
X	if(otmp == victual.piece) {
X	/* If they weren't able to choke, they don't suddenly become able to
X	 * choke just because they were interrupted.  On the other hand, if
X	 * they were able to choke before, if they lost food it's possible
X	 * they shouldn't be able to choke now.
X	 */
X	    if (u.uhs != SATIATED) victual.canchoke = FALSE;
X	    if(!carried(victual.piece)) {
X		if(victual.piece->quan > 1)
X			(void) splitobj(victual.piece, 1);
X	    }
X	    You("resume your meal.");
X	    start_eating(victual.piece);
X	    return(1);
X	}
X
X	/* nothing in progress - so try to find something. */
X	/* tins are a special case */
X	if(otmp->otyp == TIN) {
X	    start_tin(otmp);
X	    return(1);
X	}
X
X	victual.piece = otmp = touchfood(otmp);
X	victual.usedtime = 0;
X
X	/* Now we need to calculate delay and nutritional info.
X	 * The base nutrition calculated here and in eatcorpse() accounts
X	 * for normal vs. rotten food.  The reqtime and nutrit values are
X	 * then adjusted in accordance with the amount of food left.
X	 */
X	if(otmp->otyp == CORPSE) {
X	    if(eatcorpse(otmp)) return(1);
X	    /* else eatcorpse sets up reqtime and oeaten */
X	} else {
X	    victual.reqtime = objects[otmp->otyp].oc_delay;
X	    if (otmp->otyp != FORTUNE_COOKIE &&
X		(otmp->cursed ||
X		 (((monstermoves - otmp->age) > otmp->blessed ? 50 : 30) &&
X		(otmp->orotten || !rn2(7))))) {
X
X#ifdef POLYSELF
X		if(rottenfood(otmp)) {
X#else
X  		if(rottenfood()) {
X#endif
X		    otmp->orotten = TRUE;
X		    return(1);
X		}
X		otmp->oeaten >>= 1;
X	    } else fprefx(otmp);
X	}
X
X	/* re-calc the nutrition */
X	if (otmp->otyp == CORPSE) basenutrit = mons[otmp->corpsenm].cnutrit;
X	else basenutrit = objects[otmp->otyp].nutrition;
X
X#ifdef DEBUG
X	debug("before rounddiv: victual.reqtime == %d", victual.reqtime);
X	debug("oeaten == %d, basenutrit == %d", otmp->oeaten, basenutrit);
X#endif
X	victual.reqtime = (basenutrit == 0 ? 0 :
X		rounddiv(victual.reqtime * (long)otmp->oeaten, basenutrit));
X#ifdef DEBUG
X	debug("after rounddiv: victual.reqtime == %d", victual.reqtime);
X#endif
X	/* calculate the modulo value (nutrit. units per round eating)
X	 * note: this isn't exact - you actually lose a little nutrition
X	 *	 due to this method.
X	 * TODO: add in a "remainder" value to be given at the end of the
X	 *	 meal.
X	 */
X	if(victual.reqtime == 0)
X	    /* possible if most has been eaten before */
X	    victual.nmod = 0;
X	else if (otmp->oeaten > victual.reqtime)
X	    victual.nmod = -(otmp->oeaten / victual.reqtime);
X	else
X	    victual.nmod = victual.reqtime % otmp->oeaten;
X	victual.canchoke = (u.uhs == SATIATED);
X
X	start_eating(otmp);
X	return(1);
X}
X
X/* Take a single bite from a piece of food, checking for choking and
X * modifying usedtime.  Returns 1 if they choked and survived, 0 otherwise.
X */
Xstatic int
Xbite()
X{
X	if(victual.canchoke && u.uhunger >= 2000) {
X		choke(victual.piece);
X		return 1;
X	}
X	if (victual.doreset) {
X		do_reset_eat();
X		return 0;
X	}
X	if(victual.nmod < 0) {
X		lesshungry(-victual.nmod);
X		victual.piece->oeaten -= -victual.nmod;
X	} else if(victual.nmod > 0 && (victual.usedtime % victual.nmod)) {
X		lesshungry(1);
X		victual.piece->oeaten--;
X	}
X	recalc_wt();
X	return 0;
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xvoid
Xgethungry() {		/* as time goes by - called in main.c */
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#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xmorehungry(num)	/* called after vomiting and after performing feats of magic */
Xregister int num;
X{
X	u.uhunger -= num;
X	newuhs(TRUE);
X}
X
X
Xvoid
Xlesshungry(num)	/* called after eating (and after drinking fruit juice) */
Xregister int num;
X{
X#ifdef DEBUG
X	debug("lesshungry(%d)", num);
X#endif
X	u.uhunger += num;
X	if(u.uhunger >= 2000) {
X	    if (!victual.eating || victual.canchoke)
X		if (victual.eating) {
X			choke(victual.piece);
X			reset_eat();
X		} else
X			choke((struct obj *) 0);
X			/* no reset_eat(); it was a non-food such as juice */
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	      if(!victual.eating || (victual.eating && !victual.fullwarn)) {
X		pline("You're having a hard time getting all of it down.");
X		nomovemsg = "You're finally finished.";
X		if(!victual.eating)
X		    multi = -2;
X		else {
X		    victual.fullwarn = TRUE;
X		    if (victual.canchoke) {
X#ifdef MACOS
X			if(!flags.silent) SysBeep(20);
X			if(UseMacAlertText(128, "Stop eating ?") == 1)
X#else
X			pline("Stop eating? ");
X			if(yn() == 'y')
X#endif
X				reset_eat();
X		    }
X		}
X	      }
X	    }
X	}
X	newuhs(FALSE);
X}
X
XSTATIC_PTR
Xint
Xunfaint() {
X	(void) Hear_again();
X	u.uhs = FAINTING;
X	flags.botl = 1;
X	return 0;
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xboolean
Xis_fainted() {
X	return(u.uhs == FAINTED);
X}
X
Xvoid
Xreset_faint() {	/* call when a faint must be prematurely terminated */
X	if(is_fainted()) nomul(0);
X}
X
Xvoid
Xsync_hunger() {
X
X	if(is_fainted()) {
X
X		flags.soundok = 0;
X		nomul(-10+(u.uhunger/10));
X		nomovemsg = "You regain consciousness.";
X		afternmv = unfaint;
X	}
X}
X
Xvoid
Xnewuhs(incr)		/* compute and comment on your (new?) hunger status */
X	boolean incr;
X{
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(is_fainted()) newhs = FAINTED;
X		if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
X			if(!is_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			killer_format = KILLED_BY;
X			killer = "starvation";
X			done(STARVING);
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_format = KILLED_BY;
X			killer = "exhaustion";
X			done(STARVING);
X		}
X	}
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X/* Returns an object representing food.  Object may be either on floor or
X * in inventory.
X */
Xstruct obj *
Xfloorfood(verb,corpseonly)	/* get food from floor or pack */
X	const char *verb;
X	boolean corpseonly;
X{
X	register struct obj *otmp;
X#ifdef POLYSELF
X	struct gold *gold = g_at(u.ux, u.uy);
X	boolean feeding = (!strcmp(verb, "eat"));
X#endif
X#ifdef POLYSELF
X	if (feeding && gold && metallivorous(uasmon)) {
X#ifdef MACOS
X		char tmp[128];
X	    if (gold->amount == 1)
X		Sprintf(tmp, "There is 1 gold piece here. Eat it ?");
X	    else Sprintf(tmp, "There are %ld gold pieces here. Eat them ?",
X								gold->amount);
X		if(UseMacAlertText(128, tmp) == 1) {
X#else
X	    if (gold->amount == 1)
X		pline("There is 1 gold piece here; eat it? ");
X	    else pline("There are %ld gold pieces here; eat them? ",
X								gold->amount);
X	    if (yn() == 'y') {
X#endif
X		otmp = newobj(0);
X		otmp->olet = GOLD_SYM;
X		otmp->ox = u.ux;
X		otmp->oy = u.uy;
X		OGOLD(otmp) = gold->amount;
X		freegold(gold);
X		return otmp;
X	    }
X	}
X#endif
X	/* Is there some food (probably a heavy corpse) here on the ground? */
X	if(!Levitation && !u.uswallow) {
X	    for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) {
X		if(corpseonly ? otmp->otyp==CORPSE : 
X#ifdef POLYSELF
X		    feeding ? is_edible(otmp) :
X#endif
X						otmp->olet==FOOD_SYM) {
X#ifdef MACOS
X			if(!flags.silent) SysBeep(20);
X		{
X			char tmp[128];
X			Sprintf(tmp, "There %s %s here. %s %s ?",
X				(otmp->quan == 1) ? "is" : "are",
X				doname(otmp), verb,
X				(otmp->quan == 1) ? "it" : "one");
X			if(UseMacAlertText(128, tmp) == 1)
X#else
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#endif
X				return(otmp);
X#ifdef MACOS
X		}
X#endif
X		}
X	    }
X	}
X#ifdef POLYSELF
X	/* We cannot use "#" since that causes getobj() to skip its
X	 * "ugly checks" and we need to check for inedible items.
X	 */
X	return getobj (feeding ? (const char *)everything :
X				 (const char *)comestibles, verb);
X#else
X	return getobj(comestibles, verb);
X#endif
X}
X
X/* Side effects of vomiting */
X/* added nomul (MRS) - it makes sense, you're too busy being sick! */
X/* TO DO: regurgitate swallowed monsters when poly'd */
Xvoid
Xvomit() {		/* A good idea from David Neves */
X	make_sick(0L,TRUE);
X	nomul(-2);
X}
X
Xint
Xeaten_stat(base, obj)
Xregister int base;
Xregister struct obj *obj;
X{
X	base *= obj->oeaten;
X
X	if (obj->otyp == CORPSE) 
X	    base = mons[obj->corpsenm].cnutrit ?
X				base / mons[obj->corpsenm].cnutrit : 0;
X	else base = objects[obj->otyp].nutrition ?
X				base / objects[obj->otyp].nutrition : 0;
X	return (base < 1) ? 1 : base;
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 37528 -ne `wc -c <'src/eat.c'`; then
    echo shar: \"'src/eat.c'\" unpacked with wrong size!
fi
# end of 'src/eat.c'
fi
if test -f 'src/makedefs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/makedefs.c'\"
else
echo shar: Extracting \"'src/makedefs.c'\" \(17802 characters\)
sed "s/^X//" >'src/makedefs.c' <<'END_OF_FILE'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X/* makedefs.c - NetHack version 3.0 */
X
X
X#include	"config.h"
X#include	"permonst.h"
X#include	"objclass.h"
X#ifdef MACOS
X#include "patchlevel.h"
X#endif
X#ifdef NULL
X#undef NULL
X#endif /* NULL */
X#define NULL	((genericptr_t)0)
X
X#if defined(VMS) && defined(__GNUC__)
X	char *FDECL(ctime, (time_t *));
X#endif
X
X#if !defined(LINT) && !defined(__GNULINT__)
Xstatic	const char	SCCS_Id[] = "@(#)makedefs.c\t3.0\t89/11/15";
X#endif
X
X#ifdef MSDOS
X# if !defined(AMIGA) && !defined(TOS)
X# define freopen _freopen
XFILE *FDECL(_freopen, (char *,char *,FILE *));
X# endif
X# undef	exit
Xextern void FDECL(exit, (int));
X# define RDMODE	"r"
X# define WRMODE	"w"
X#else
X# ifdef VMS
X#  define RDMODE  "r"
X#  define WRMODE  "w"
X# else
X#  define RDMODE  "r+"
X#  define WRMODE  "w+"
X# endif
X#endif
X
X#ifdef MACOS
XBoolean FDECL(TouchFile,(char *));
XStr255 VolName;
Xint vRef;
XStr255 File;
XFInfo info;
XOSErr macErr;
X#endif
X
X/* construct definitions of object constants */
X
X#ifdef AMIGA
X# define MONST_FILE	 "Incl:pm.h"
X# define ONAME_FILE	 "Incl:onames.h"
X# define TRAP_FILE	 "Incl:trap.h"
X# define DATE_FILE	 "Incl:date.h"
X# define DATA_FILE	 "Auxil:data"
X# define RUMOR_FILE	 "Auxil:rumors"
X#else
X# ifndef MACOS
X/* construct definitions of object constants */
X# define MONST_FILE	 "../include/pm.h"
X# define ONAME_FILE	 "../include/onames.h"
X# define TRAP_FILE	 "../include/trap.h"
X# define DATE_FILE	 "../include/date.h"
X# define DATA_FILE	 "../auxil/data"
X# define RUMOR_FILE	 "../auxil/rumors"
X# else
X/*****
X * MAC OS uses ':' to separate dir's and filenames.
X * The following (partial) pathnames assume the makedefs program
X * runs in the same directory as the include and auxil directories
X *****/
X# define MONST_FILE	":include:pm.h"
X# define ONAME_FILE	":include:onames.h"
X# define TRAP_FILE	":include:trap.h"
X# define DATE_FILE	":include:date.h"
X# define DATA_FILE	":auxil:data"
X# define RUMOR_FILE	":auxil:rumors"
X#  ifdef AZTEC
X#define	perror(x)	Printf(x)
X#include "Controls.h"
X#  else
X#include "ControlMgr.h"
X#  endif
X# endif
X#endif
X
X
Xchar	in_line[256];
Xextern char *FDECL(gets, (char *));
X
Xint FDECL(main, (int, char **));
Xvoid NDECL(do_objs);
Xvoid NDECL(do_traps);
Xvoid NDECL(do_data);
Xvoid NDECL(do_date);
Xvoid NDECL(do_permonst);
Xvoid NDECL(do_rumors);
X
Xchar * FDECL(tmpdup, (const char *));
X
X#if defined(SYSV) || defined(GENIX) || defined(UNIXDEBUG)
Xvoid FDECL(rename, (char *, char *));
X#endif
X
X#ifdef SMALLDATA
Xvoid NDECL(do_monst);
Xvoid NDECL(save_resource);
X#endif
X
Xchar *FDECL(limit, (char *,int));
X
X#if defined(SMALLDATA) && defined(MACOS)
XOSErr FDECL(write_resource, (Handle, ResType, short, Str255, short));
X# if defined(AZTEC) || defined(THINKC4)
Xint NDECL(getpid);
X# endif
X#endif
X
Xint
Xmain(argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	char	*option;
X#ifdef MACOS
X	DialogPtr	dialog;
X	char	params[3], *options;
X	short	itemHit, lastItem, type;
X	Rect	box;
X	ControlHandle	theControl;
X	GrafPtr	oldPort;
X
X#define	OK_BUTTON	1
X#define	CANCEL_BUTTON	2
X#define	FIRST_RADIO_BUTTON	3
X#define	ON	1
X#define	OFF	0
X
X	/* standard Mac initialization */
X	InitGraf(&MAINGRAFPORT);
X
X	InitFonts();
X	InitWindows();
X	InitMenus();
X	InitCursor();
X	FlushEvents(everyEvent,0);
X	InitDialogs(NULL);
X
X	params[0] = '-';
X	options = "DVPRTOM";
X	dialog = GetNewDialog(200, 0L, (WindowPtr) -1);
X	GetPort(&oldPort);
X	SetPort(dialog);
X	GetDItem(dialog, OK_BUTTON, &type, &theControl, &box);
X	LocalToGlobal(&box.top);
X	LocalToGlobal(&box.bottom);
X	SetPort(oldPort);
X	PenSize(3, 3);
X	InsetRect(&box, -4, -4);
X	FrameRoundRect(&box, 16, 16);
X	PenSize(1, 1);
X	itemHit = 0;
X	do {
X		lastItem = itemHit;
X		ModalDialog(NULL, &itemHit);
X		if (itemHit != lastItem && itemHit > CANCEL_BUTTON) {
X			if (lastItem) {
X				GetDItem(dialog, lastItem, &type,
X						&theControl, &box);
X				SetCtlValue(theControl, OFF);
X			}
X			params[1] = options[itemHit - FIRST_RADIO_BUTTON];
X			GetDItem(dialog, itemHit, &type, &theControl, &box);
X			SetCtlValue(theControl, ON);
X		}
X	} while (itemHit >= FIRST_RADIO_BUTTON);
X	DisposDialog(dialog);
X	argc = 1;
X	if (itemHit == OK_BUTTON && lastItem >= FIRST_RADIO_BUTTON) {
X		argc = 2;
X		option = params;
X
X#else
X	if(argc == 2) {
X	    option = argv[1];
X#endif
X	    switch (option[1]) {
X
X		case 'o':
X		case 'O':	do_objs();
X				break;
X		case 't':
X		case 'T':	do_traps();
X				break;
X
X		case 'd':
X		case 'D':	do_data();
X				break;
X
X		case 'v':
X		case 'V':	do_date();
X				break;
X
X		case 'p':
X		case 'P':	do_permonst();
X				break;
X
X		case 'r':
X		case 'R':	do_rumors();
X				break;
X#if defined(SMALLDATA)
X		case 'm':
X		case 'M':	do_monst();
X				break;
X
X#endif	/* SMALLDATA */
X
X		default:
X				(void) fprintf(stderr,
X					"Unknown option '%c'.\n", option[1]);
X				(void) fflush(stderr);
X				exit(1);
X	    }
X	    exit(0);
X	} else	(void) fprintf(stderr, "Bad arg count (%d).\n", argc-1);
X	(void) fflush(stderr);
X	exit(1);
X/*NOTREACHED*/
X#if defined(MSDOS) || defined(__GNULINT__)
X	return 0;
X#endif
X}
X
Xvoid
Xdo_traps() {
X	int	ntrap;
X	char	tempfile[30];
X
X#ifdef MACOS
X	Sprintf(tempfile, ":include:makedefs.%d", getpid());
X#else
X	Sprintf(tempfile, "makedefs.%d", getpid());
X#endif
X/* an ugly hack to limit pid-extension to 3 digits */
X#ifdef OS2
X	if (strlen(tempfile) > 12) tempfile[12] = '\0';
X#endif
X	if(freopen(tempfile, WRMODE, stdout) == (FILE *)0) {
X		perror(tempfile);
X		exit(1);
X	}
X
X	if(freopen(TRAP_FILE, RDMODE, stdin) == (FILE *)0) {
X		perror(TRAP_FILE);
X		exit(1);
X	}
X
X	while(gets(in_line) != NULL) {
X	    (void) puts(in_line);
X	    if(!strncmp(in_line, "/* DO NOT REMOVE THIS LINE */", 29)) break;
X	}
X	ntrap = 10;
X	Printf("\n");
X	Printf("#define\tMGTRP\t\t%d\n", ntrap++);
X	Printf("#define\tSQBRD\t\t%d\n", ntrap++);
X	Printf("#define\tWEB\t\t%d\n", ntrap++);
X	Printf("#define\tSPIKED_PIT\t%d\n", ntrap++);
X	Printf("#define\tLEVEL_TELEP\t%d\n", ntrap++);
X#ifdef SPELLS
X	Printf("#define\tANTI_MAGIC\t%d\n", ntrap++);
X#endif
X	Printf("#define\tRUST_TRAP\t%d\n", ntrap++);
X#ifdef POLYSELF
X	Printf("#define\tPOLY_TRAP\t%d\n", ntrap++);
X#endif
X	Printf("#define\tLANDMINE\t%d\n", ntrap++);
X	Printf("\n#define\tTRAPNUM\t%d\n", ntrap);
X	Printf("\n#endif /* TRAP_H /**/\n");
X	(void) fclose(stdin);
X	(void) fclose(stdout);
X#if defined(MSDOS) || defined(MACOS)
X	remove(TRAP_FILE);
X#endif
X	rename(tempfile, TRAP_FILE);
X	return;
X}
X
X
Xvoid
Xdo_rumors(){
X	char	infile[30];
X	long	true_rumor_size;
X
X	if(freopen(RUMOR_FILE, WRMODE, stdout) == (FILE *)0) {
X		perror(RUMOR_FILE);
X		exit(1);
X	}
X
X	Sprintf(infile, "%s.tru", RUMOR_FILE);
X	if(freopen(infile, RDMODE, stdin) == (FILE *)0) {
X		perror(infile);
X		exit(1);
X	}
X
X	/* get size of true rumors file */
X	(void) fseek(stdin, 0L, 2);
X	true_rumor_size = ftell(stdin);
X	(void) fwrite((genericptr_t)&true_rumor_size,sizeof(long),1,stdout);
X	(void) fseek(stdin, 0L, 0);
X
X	/* copy true rumors */
X	while(gets(in_line) != NULL)	 (void) puts(in_line);
X
X	Sprintf(infile, "%s.fal", RUMOR_FILE);
X	if(freopen(infile, RDMODE, stdin) == (FILE *)0) {
X		perror(infile);
X		exit(1);
X	}
X
X	/* copy false rumors */
X	while(gets(in_line) != NULL)	 (void) puts(in_line);
X
X	(void) fclose(stdin);
X	(void) fclose(stdout);
X#ifdef MACOS
X	Strcpy((char *)File, RUMOR_FILE);
X	CtoPstr((char *)File);
X	if(!GetVol(VolName, &vRef) && !GetFInfo(File, vRef, &info)){
X		info.fdCreator = CREATOR;
X		info.fdType = TEXT_TYPE;
X		(void) SetFInfo(File, vRef, &info);
X	}
X#endif
X	return;
X}
X
X#ifdef SYSV
Xextern long time();
X#endif
X
Xvoid
Xdo_date(){
X	long	clock;
X	char	cbuf[30], *c;
X
X	if(freopen(DATE_FILE, WRMODE, stdout) == (FILE *)0) {
X		perror(DATE_FILE);
X		exit(1);
X	}
X	Printf("/*\tSCCS Id: @(#)date.h\t3.0\t88/11/20 */\n\n");
X
X#ifdef KR1ED
X	(void) time(&clock);
X	Strcpy(cbuf, ctime(&clock));
X#else
X	(void) time((time_t *)&clock);
X	Strcpy(cbuf, ctime((time_t *)&clock));
X#endif
X	for(c = cbuf; *c != '\n'; c++);	*c = 0; /* strip off the '\n' */
X	Printf("const char datestring[] = \"%s\";\n", cbuf);
X#ifdef MSDOS
X      /* get the time we did a compile for checking save and level files */
X	Printf("const long compiletime = %ld;\n", clock);
X#endif
X
X	(void) fclose(stdout);
X	return;
X}
X
Xvoid
Xdo_data(){
X	char	tempfile[30];
X#ifndef INFERNO
X	boolean	skipping_demons = TRUE;
X#endif
X	Sprintf(tempfile,
X#ifdef OS2
X		"%s.bas",
X#else
X		"%s.base",
X#endif
X		DATA_FILE);
X	if(freopen(tempfile, RDMODE, stdin) == (FILE *)0) {
X		perror(tempfile);
X		exit(1);
X	}
X
X	if(freopen(DATA_FILE, WRMODE, stdout) == (FILE *)0) {
X		perror(DATA_FILE);
X		exit(1);
X	}
X
X	while(gets(in_line) != NULL) {
X#ifndef INFERNO
X	    if(skipping_demons)
X		while(gets(in_line) != NULL && strcmp(in_line, "*centaur"))
X		    ; /* do nothing */
X	    skipping_demons = FALSE;
X#endif
X#ifndef ARMY
X	    if(!strcmp(in_line, "*soldier")) {
X		while(gets(in_line) != NULL && in_line[0] != '\t') ;
X		while(gets(in_line) != NULL && in_line[0] == '\t')
X		    ; /* do nothing */
X	    }
X	    else
X#endif
X#ifndef WORM
X	    if(!strcmp(in_line, "*long worm")) {
X		while(gets(in_line) != NULL && in_line[0] != '\t') ;
X		while(gets(in_line) != NULL && in_line[0] == '\t')
X		    ; /* do nothing */
X	    }
X	    else
X#endif
X#ifndef GOLEMS
X	    if(!strcmp(in_line, "*golem"))
X		while(gets(in_line) != NULL && in_line[0] == '\t')
X		    ; /* do nothing */
X	    else
X#endif
X#ifndef MEDUSA
X	    if(!strcmp(in_line, "medusa"))
X		while(gets(in_line) != NULL && in_line[0] == '\t')
X		    ; /* do nothing */
X	    else
X#endif
X#ifndef NAMED_ITEMS
X	    if(!strcmp(in_line, "snickersnee")
X		|| !strcmp(in_line, "orcrist")
X	      )
X		while(gets(in_line) != NULL && in_line[0] == '\t')
X		    ; /* do nothing */
X	    else
X#endif
X#ifndef TOLKIEN
X	    if(!strcmp(in_line, "hobbit"))
X		while(gets(in_line) != NULL && in_line[0] == '\t')
X		    ; /* do nothing */
X	    else
X#endif
X		(void) puts(in_line);
X	}
X	(void) fclose(stdin);
X	(void) fclose(stdout);
X#ifdef MACOS
X	Strcpy((char *)File, DATA_FILE);
X	CtoPstr((char *)File);
X	if(!GetVol(VolName, &vRef) && !GetFInfo(File, vRef, &info)){
X		info.fdCreator = CREATOR;
X		info.fdType = TEXT_TYPE;
X		(void) SetFInfo(File, vRef, &info);
X	}
X#endif
X
X	return;
X}
X
Xvoid
Xdo_permonst()
X{
X	int	i;
X	char	*c, *nam;
X
X	if(freopen(MONST_FILE, WRMODE, stdout) == (FILE *)0) {
X		perror(MONST_FILE);
X		exit(1);
X	}
X	Printf("/*\tSCCS Id: @(#)pm.h\t3.0\t88/11/20 */\n\n");
X	Printf("#ifndef PM_H\n#define PM_H\n");
X
X	for(i = 0; mons[i].mlet; i++) {
X		Printf("\n#define\tPM_");
X		for(nam = c = tmpdup(mons[i].mname); *c; c++) {
X		    if((*c >= 'a') && (*c <= 'z')) *c -= (char)('a' - 'A');
X		    else if(*c == ' ' || *c == '-')	*c = '_';
X		}
X		Printf("%s\t%d", nam, i);
X	}
X	Printf("\n\n#define\tNUMMONS\t%d\n", i);
X	Printf("\n#endif /* PM_H /**/\n");
X	(void) fclose(stdout);
X	return;
X}
X
Xstatic	char	temp[32];
X
Xchar *
Xlimit(name,pref)	/* limit a name to 30 characters length */
Xchar	*name;
Xint	pref;
X{
X	(void) strncpy(temp, name, pref ? 26 : 30);
X	temp[pref ? 26 : 30] = 0;
X	return temp;
X}
X
Xvoid
Xdo_objs()
X{
X	int i = 0, sum = 0;
X	char *c, *objnam;
X#ifdef SPELLS
X	int nspell = 0;
X#endif
X	int prefix = 0;
X	char let = '\0';
X	boolean	sumerr = FALSE;
X
X	if(freopen(ONAME_FILE, WRMODE, stdout) == (FILE *)0) {
X		perror(ONAME_FILE);
X		exit(1);
X	}
X	Printf("/*\tSCCS Id: @(#)onames.h\t3.0\t89/01/10 */\n\n");
X	Printf("#ifndef ONAMES_H\n#define ONAMES_H\n\n");
X
X	for(i = 0; !i || objects[i].oc_olet != ILLOBJ_SYM; i++) {
X		if (!(objnam = tmpdup(objects[i].oc_name))) continue;
X
X		/* make sure probabilities add up to 1000 */
X		if(objects[i].oc_olet != let) {
X			if (sum && sum != 1000) {
X			    (void) fprintf(stderr,
X					"prob error for %c (%d%%)", let, sum);
X			    (void) fflush(stderr);
X			    sumerr = TRUE;
X			}
X			let = objects[i].oc_olet;
X			sum = 0;
X		}
X
X		for(c = objnam; *c; c++) {
X		    if((*c >= 'a') && (*c <= 'z')) *c -= (char)('a' - 'A');
X		    else if(*c == ' ' || *c == '-')	*c = '_';
X		}
X
X		switch (let) {
X		    case WAND_SYM:
X			Printf("#define\tWAN_"); prefix = 1; break;
X		    case RING_SYM:
X			Printf("#define\tRIN_"); prefix = 1; break;
X		    case POTION_SYM:
X			Printf("#define\tPOT_"); prefix = 1; break;
X#ifdef SPELLS
X		    case SPBOOK_SYM:
X			Printf("#define\tSPE_"); prefix = 1; nspell++; break;
X#endif
X		    case SCROLL_SYM:
X			Printf("#define\tSCR_"); prefix = 1; break;
X		    case GEM_SYM:
X			/* avoid trouble with stupid C preprocessors */
X			if(objects[i].oc_material == GLASS) {
X			    Printf("/* #define\t%s\t%d */\n",
X							objnam, i);
X			    prefix = -1;
X			    break;
X			}
X		    default:
X			Printf("#define\t");
X		}
X		if (prefix >= 0)
X			Printf("%s\t%d\n", limit(objnam, prefix), i);
X		prefix = 0;
X
X		sum += objects[i].oc_prob;
X	}
X
X	/* check last set of probabilities */
X	if (sum && sum != 1000) {
X	    (void) fprintf(stderr,
X			"prob error for %c (%d%%)", let, sum);
X	    (void) fflush(stderr);
X	    sumerr = TRUE;
X	}
X
X	Printf("#define\tLAST_GEM\t(JADE+1)\n");
X#ifdef SPELLS
X	Printf("#define\tMAXSPELL\t%d\n", nspell+1);
X#endif
X	Printf("#define\tNROFOBJECTS\t%d\n", i-1);
X	Printf("\n#endif /* ONAMES_H /**/\n");
X	(void) fclose(stdout);
X	if (sumerr) exit(1);
X	return;
X}
X
Xchar *
Xtmpdup(str)
Xconst char *str;
X{
X	static char buf[128];
X
X	if (!str) return (char *)0;
X	(void)strncpy(buf, str, 127);
X	return buf;
X}
X
X#if defined(SYSV) || defined(GENIX) || defined(UNIXDEBUG)
Xvoid
Xrename(oldname, newname)
Xchar	*oldname, *newname;
X{
X	if (strcmp(oldname, newname)) {
X		(void) unlink(newname);
X		(void) link(oldname, newname);
X		(void) unlink(oldname);
X	}
X	return;
X}
X#endif
X
X#ifdef MSDOS
X# if !defined(AMIGA) && !defined(TOS)
X/* Get around bug in freopen when opening for writing	*/
X/* Supplied by Nathan Glasser (nathan@mit-eddie)	*/
X#undef freopen
XFILE *
X_freopen(fname, fmode, fp)
Xchar *fname, *fmode;
XFILE *fp;
X{
X    if (!strncmp(fmode,"w",1))
X    {
X	FILE *tmpfp;
X
X	if ((tmpfp = fopen(fname,fmode)) == (FILE *)0)
X	    return (FILE *)0;
X	if (dup2(fileno(tmpfp),fileno(fp)) < 0)
X	    return (FILE *)0;
X	(void) fclose(tmpfp);
X	return fp;
X    }
X    else
X	return freopen(fname,fmode,fp);
X}
X# endif /* !AMIGA && !TOS */
X
X# if defined(__TURBOC__) || defined(AMIGA)
Xint
Xgetpid()
X{
X	return 1;
X}
X# endif
X#endif /* MSDOS */
X
X
X#if defined(SMALLDATA)
Xvoid
Xdo_monst()
X{
X	Handle	monstData, objData, versData;
X	char versStr[32], *vstr = VERSION;
X	short i, j, patlev = PATCHLEVEL;
X	pmstr	*pmMonst;
X	SFReply	reply;
X	short	refNum,error;
X	Str255	name;
X	short	findNamedFile();
X	OSErr	write_resource();
X
X	for(i = 0; mons[i].mlet; i++) {
X		;
X	}
X	i++;
X
X	/*
X	 * convert to struct where character arrays instead of pointers to
X	 * strings are used
X	 */
X	pmMonst = (pmstr *)NewPtr(i*sizeof(struct pmstr));
X	for (j = 0; j < i; j++) {
X		Strcpy(pmMonst[j].mname, mons[j].mname);
X		BlockMove(&(mons[j].mlet), &(pmMonst[j].pmp.mlet),
X				(long)sizeof(struct pmpart));
X	}
X
X	PtrToHand((Ptr)pmMonst, &monstData, (long)(i * sizeof(struct pmstr)));
X
X	/* store the object data, in Nethack the char * will be copied in */
X	for(i = 0; !i || objects[i].oc_olet != ILLOBJ_SYM; i++) {
X		;
X	}
X	PtrToHand((Ptr)objects, &objData, ((i+1)*sizeof(struct objclass)));
X
X	/* place a small string in the creator resource to identify version */
X	Sprintf(versStr, "n%s patchlevel%2d", vstr, patlev);
X	*versStr = (int)strlen(VERSION) + 13;  /* n = actual string length */
X	PtrToHand(versStr, &versData, sizeof(versStr));
X
X	Strcpy((char *)&name[0], "\021nethack.proj.rsrc");
X	if (findNamedFile(&name[1], 0, &reply)) {
X	    (void)strncpy((char *)&name[0],(char *)&reply.fName[0], reply.fName[0]+1);
X	    if ((refNum = OpenResFile(name)) != -1) {
X		if (ResError() == noErr) {
X		    Strcpy((char *)&name[0], "\012MONST_DATA");
X		    if (error = write_resource(monstData, HACK_DATA,
X						MONST_DATA, name, refNum)) {
X			SysBeep(1);
X			Printf("Couldn't add monster data resource.\n");
X		    }
X		    Strcpy((char *)&name[0], "\013OBJECT_DATA");
X		    if (error = write_resource(objData, HACK_DATA,
X						OBJECT_DATA, name, refNum)) {
X			SysBeep(1);
X			Printf("Couldn't add object data resource.\n");
X		    }
X		    Strcpy((char *)&name[0], "\000");
X		    if (error = write_resource(versData, CREATOR,
X						0, name, refNum)) {
X			SysBeep(1);
X			Printf("Couldn't add creator info resource.\n");
X		    }
X		    CloseResFile(refNum);
X		    if (ResError() != noErr) {
X			SysBeep(1);
X			Printf("Couldn't close resource file.");
X		    }
X		}
X	    }
X	}
X
X	DisposHandle(monstData);
X	DisposHandle(objData);
X
X	vRef = reply.vRefNum;
X	(void) TouchFile(SHELP);
X	(void) TouchFile(HELP);
X#ifdef NEWS
X	(void) TouchFile("news");
X#endif
X	if(!TouchFile(RECORD))
X		(void) Create(File, vRef, CREATOR, TEXT_TYPE);
X
X	(void) TouchFile(CMDHELPFILE);
X	(void) TouchFile(HISTORY);
X	(void) TouchFile(OPTIONFILE);
X#ifdef ORACLE
X	(void) TouchFile(ORACLEFILE);
X#endif
X	(void) TouchFile(LICENSE);
X#ifdef MACOS
X	(void) TouchFile(MACHELP);
X#endif
X}
X
XBoolean
XTouchFile(fname)
Xchar *fname;
X{
X	SFReply	reply;
X	short	findNamedFile();
X
X	Strcpy((char *)File, fname);
X	CtoPstr((char *)File);
X	File[File[0]+1] = 0;
X	reply.good = TRUE;
X	if(GetFInfo(File, vRef, &info)){
X		findNamedFile(&File[1], 2, &reply);
X		if(reply.good){
X			vRef = reply.vRefNum;
X			GetFInfo(File, vRef, &info);
X		}
X	}
X	if(reply.good){
X		info.fdCreator = CREATOR;
X		info.fdType = TEXT_TYPE;
X		(void) SetFInfo(File, vRef, &info);
X	}
X
X	return(reply.good);
X}
X
X
X
XOSErr
Xwrite_resource(data, theType, resID, resName, refNum)
XHandle	data;
XResType	theType;
Xshort	resID;
XStr255	resName;
Xshort	refNum;
X{
X	short	error;
X	Handle	theRes;
X
X    if (theRes = GetResource(theType, resID)) {
X		RmveResource(theRes);
X		error = ResError();
X		if (error == noErr) {
X			DisposHandle(theRes);
X			UpdateResFile(refNum);
X			error = ResError();
X		}
X		if (error != noErr) {
X			return error;
X		}
X	} else if (ResError() != resNotFound && ResError() != noErr) {
X			return (ResError());
X	}
X	AddResource(data, theType, resID, resName);
X	error = ResError();
X	if (error == noErr) {
X		WriteResource(data);
X		error = ResError();
X	}
X    return error;
X}
X# if defined(AZTEC) || defined(THINKC4)
Xint
Xgetpid()
X{
X	return 1;
X}
X# endif
X#endif	/* SMALLDATA */
END_OF_FILE
if test 17802 -ne `wc -c <'src/makedefs.c'`; then
    echo shar: \"'src/makedefs.c'\" unpacked with wrong size!
fi
# end of 'src/makedefs.c'
fi
echo shar: End of archive 15 \(of 56\).
cp /dev/null ark15isdone
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