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