]> granicus.if.org Git - nethack/commitdiff
fix #6187 - attempting to eat inedible artifact
authorPatR <rankin@nethack.org>
Sat, 14 Oct 2017 09:09:43 +0000 (02:09 -0700)
committerPatR <rankin@nethack.org>
Sat, 14 Oct 2017 09:09:43 +0000 (02:09 -0700)
Rearrange the tests for edibility of non-food so that touching an
artifact won't happen unless the object could be eaten.

Add a bit of bulletproofing for rust monsters trying to eat a
rustproofed item and spitting it out.  Wishing for rustproof iron
ring, cursing it, wearing it, and attempting to eat it as a rust
monster would remove the rustproofing and spit it onto the floor,
ignoring the cursed state as far as taking it off goes.  That was
an issue in 3.4.3 and probably in 3.6.0, but in current code the
'rustproof' part of the wish would be ignored for an item which
isn't subject to erosion damage, so hero-as-rust monster will
successfully eat the ring instead of spitting it out.

src/eat.c

index 6bbc1836b8099d6100a55202b40e75357cc2bd04..a1b4bc33d3719287e11dc7065fb850bb3fdebcd0 100644 (file)
--- a/src/eat.c
+++ b/src/eat.c
@@ -2443,10 +2443,7 @@ doeat()
      * mails, players who polymorph back to human in the middle of their
      * metallic meal, etc....
      */
-    if (!(carried(otmp) ? retouch_object(&otmp, FALSE)
-                        : touch_artifact(otmp, &youmonst))) {
-        return 1;
-    } else if (!is_edible(otmp)) {
+    if (!is_edible(otmp)) {
         You("cannot eat that!");
         return 0;
     } else if ((otmp->owornmask & (W_ARMOR | W_TOOL | W_AMUL | W_SADDLE))
@@ -2454,6 +2451,9 @@ doeat()
         /* let them eat rings */
         You_cant("eat %s you're wearing.", something);
         return 0;
+    } else if (!(carried(otmp) ? retouch_object(&otmp, FALSE)
+                               : touch_artifact(otmp, &youmonst))) {
+        return 1; /* got blasted so use a turn */
     }
     if (is_metallic(otmp) && u.umonnum == PM_RUST_MONSTER
         && otmp->oerodeproof) {
@@ -2468,13 +2468,26 @@ doeat()
         /* The regurgitated object's rustproofing is gone now */
         otmp->oerodeproof = 0;
         make_stunned((HStun & TIMEOUT) + (long) rn2(10), TRUE);
-        You("spit %s out onto the %s.", the(xname(otmp)),
-            surface(u.ux, u.uy));
-        if (carried(otmp)) {
-            freeinv(otmp);
-            dropy(otmp);
+        /*
+         * We don't expect rust monsters to be wielding welded weapons
+         * or wearing cursed rings which were rustproofed, but guard
+         * against the possibility just in case.
+         */
+        if (welded(otmp) || (otmp->cursed && (otmp->owornmask & W_RING))) {
+            otmp->bknown = 1; /* for ring; welded() does this for weapon */
+            You("spit out %s.", the(xname(otmp)));
+        } else {
+            You("spit %s out onto the %s.", the(xname(otmp)),
+                surface(u.ux, u.uy));
+            if (carried(otmp)) {
+                /* no need to check for leash in use; it's not metallic */
+                if (otmp->owornmask)
+                    remove_worn_item(otmp, FALSE);
+                freeinv(otmp);
+                dropy(otmp);
+            }
+            stackobj(otmp);
         }
-        stackobj(otmp);
         return 1;
     }
     /* KMH -- Slow digestion is... indigestible */