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