Skip to content

Commit

Permalink
non-rotting food (trunk only)
Browse files Browse the repository at this point in the history
     From a bug report:  if you
attempted to eat a Rider corpse and got the 1/7 chance that non-yet-rotten
food will be treated as rotten, then also got "the world spins and goes
dark" result for rotten food, you would both survive the eating attempt
and also end up with a partly eaten Rider corpse.  This patch treats Rider
corpses like lizard and lichen corpses; they'll never yield rotten food
effects.  That way, they'll always be fatal to eat.  They'll still end up
being partly eaten if you are life-saved, but since they'll immediately
revive, the only way you'll know that is to use probing or stethoscope to
discover that they've revived at less than full health.

     Nearly two years ago, <email deleted>
suggested that lembas wafers and cram rations be treated like fortune
cookies and never yield the rotten food result.  I'm guessing that cookies
are handled that way so that rotten food feedback doesn't override false
rumor delivery when they're cursed, rather than because they're considered
to be rot-proof.  This implements <Someone>'s suggestion, except that cursed
lembas and cram will still behave like rotten food.
  • Loading branch information
nethack.rankin committed Oct 7, 2006
1 parent 3654408 commit f49361a
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 14 deletions.
3 changes: 3 additions & 0 deletions doc/fixes35.0
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ add Unaware pseudo-property to suppress various messages while unconscious
missile which kills engulfer will now be placed prior to hero's return to map
bugles affect all monsters to some extent
nurses are affected if player is polymorphed as a cockatrice
getting a particular rotten food result can't make attempting to eat a
corpse of one of the Riders be survivable


Platform- and/or Interface-Specific Fixes
Expand Down Expand Up @@ -242,6 +244,7 @@ opening magic frees from bear traps and webs, activates trap doors
closing magic activates bear traps and webs
locking converts a hole into a trap door; striking does the opposite
add Malcolm Ryan's Statue Glyphs patch
lembas and cram never rot unless cursed


Platform- and/or Interface-Specific New Features
Expand Down
38 changes: 24 additions & 14 deletions src/eat.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* SCCS Id: @(#)eat.c 3.5 2006/08/18 */
/* SCCS Id: @(#)eat.c 3.5 2006/10/06 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */

Expand Down Expand Up @@ -63,6 +63,16 @@ char msgbuf[BUFSZ];
/* monster types that cause hero to be turned into stone if eaten */
#define flesh_petrifies(pm) (touch_petrifies(pm) || (pm) == &mons[PM_MEDUSA])

/* Rider corpses are treated as non-rotting so that attempting to eat one
will be sure to reach the stage of eating where that meal is fatal */
#define nonrotting_corpse(mnum) ((mnum) == PM_LIZARD || \
(mnum) == PM_LICHEN || \
is_rider(&mons[mnum]))

/* non-rotting non-corpses; unlike lizard corpses, these items will behave
as if rotten if they are cursed (fortune cookies handled elsewhere) */
#define nonrotting_food(otyp) ((otyp) == LEMBAS_WAFER || (otyp) == CRAM_RATION)

STATIC_OVL NEARDATA const char comestibles[] = { FOOD_CLASS, 0 };

/* Gold must come first for getobj(). */
Expand Down Expand Up @@ -1257,8 +1267,7 @@ int forcetype;
r = forcetype;
} else { /* RANDOM_TIN */
r = rn2(TTSZ-1); /* take your pick */
if (r == ROTTEN_TIN && (obj->corpsenm == PM_LIZARD ||
obj->corpsenm == PM_LICHEN))
if (r == ROTTEN_TIN && nonrotting_corpse(obj->corpsenm))
r = HOMEMADE_TIN; /* lizards don't rot */
}
obj->spe = -(r+1); /* offset by 1 to allow index 0 */
Expand All @@ -1285,8 +1294,7 @@ boolean disp; /* we're just displaying so leave things alone */
!obj->blessed && !rn2(7))
r = ROTTEN_TIN; /* some homemade tins go bad */

if (r == ROTTEN_TIN && (obj->corpsenm == PM_LIZARD ||
obj->corpsenm == PM_LICHEN))
if (r == ROTTEN_TIN && nonrotting_corpse(obj->corpsenm))
r = HOMEMADE_TIN; /* lizards don't rot */
return r;
}
Expand Down Expand Up @@ -1537,7 +1545,7 @@ eatcorpse(otmp) /* called when a corpse is selected as food */
if (!vegan(&mons[mnum])) u.uconduct.unvegan++;
if (!vegetarian(&mons[mnum])) violated_vegetarian();

if (mnum != PM_LIZARD && mnum != PM_LICHEN) {
if (!nonrotting_corpse(mnum)) {
long age = peek_at_iced_corpse_age(otmp);

rotted = (monstermoves - age)/(10L + rn2(20));
Expand Down Expand Up @@ -1589,8 +1597,7 @@ eatcorpse(otmp) /* called when a corpse is selected as food */
/* delay is weight dependent */
context.victual.reqtime = 3 + (mons[mnum].cwt >> 6);

if (!tp && mnum != PM_LIZARD && mnum != PM_LICHEN &&
(otmp->orotten || !rn2(7))) {
if (!tp && !nonrotting_corpse(mnum) && (otmp->orotten || !rn2(7))) {
if (rottenfood(otmp)) {
otmp->orotten = TRUE;
(void)touchfood(otmp);
Expand Down Expand Up @@ -2123,7 +2130,7 @@ struct obj *otmp;
stoneorslime = (!Unchanging && !flaming(youmonst.data) &&
youmonst.data != &mons[PM_GREEN_SLIME]);

if (cadaver && mnum != PM_LIZARD && mnum != PM_LICHEN) {
if (cadaver && !nonrotting_corpse(mnum)) {
long age = peek_at_iced_corpse_age(otmp);
/* worst case rather than random
in this calculation to force prompt */
Expand Down Expand Up @@ -2419,16 +2426,17 @@ doeat() /* generic "eat" command funtion (see cmd.c) */

context.victual.reqtime = objects[otmp->otyp].oc_delay;
if (otmp->otyp != FORTUNE_COOKIE &&
(otmp->cursed ||
(((monstermoves - otmp->age) > (int) otmp->blessed ? 50:30) &&
(otmp->orotten || !rn2(7))))) {
(otmp->cursed || (!nonrotting_food(otmp->otyp) &&
(monstermoves - otmp->age) > (otmp->blessed ? 50L : 30L) &&
(otmp->orotten || !rn2(7))))) {

if (rottenfood(otmp)) {
otmp->orotten = TRUE;
dont_start = TRUE;
}
consume_oeaten(otmp, 1); /* oeaten >>= 1 */
} else fprefx(otmp);
} else
fprefx(otmp);
}

/* re-calc the nutrition */
Expand Down Expand Up @@ -2943,7 +2951,9 @@ int threat;
if (occupation != opentin) return FALSE;
otin = context.tin.tin;
/* make sure hero still has access to tin */
if (!carried(otin) && !obj_here(otin, u.ux, u.uy)) return FALSE;
if (!carried(otin) &&
(!obj_here(otin, u.ux, u.uy) || !can_reach_floor(TRUE)))
return FALSE;
/* unknown tin is assumed to be helpful */
if (!otin->known) return TRUE;
/* known tin is helpful if it will stop life-threatening problem */
Expand Down

0 comments on commit f49361a

Please sign in to comment.