]> granicus.if.org Git - nethack/commitdiff
non-rotting food (trunk only)
authornethack.rankin <nethack.rankin>
Sat, 7 Oct 2006 05:41:30 +0000 (05:41 +0000)
committernethack.rankin <nethack.rankin>
Sat, 7 Oct 2006 05:41:30 +0000 (05:41 +0000)
     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.

doc/fixes35.0
src/eat.c

index 24ef684341fc10b2804d416bef63651c329560f3..17edef8eea210f683cee89c5e6fa54c66b164ddb 100644 (file)
@@ -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
@@ -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
index dca4d9e5a340343807d75b9ab7f21d6aa0ad8eb6..e048486ad68ee23d7c3ebde9f4684759a1007a09 100644 (file)
--- a/src/eat.c
+++ b/src/eat.c
@@ -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. */
 
@@ -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(). */
@@ -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 */
@@ -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;
 }
@@ -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));
@@ -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);
@@ -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 */
@@ -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 */
@@ -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 */