]> granicus.if.org Git - nethack/commitdiff
vulnerable items thrown into lava
authorPatR <rankin@nethack.org>
Fri, 22 Sep 2017 22:08:42 +0000 (15:08 -0700)
committerPatR <rankin@nethack.org>
Fri, 22 Sep 2017 22:08:42 +0000 (15:08 -0700)
Reported directly to devteam, player threw a troll corpse into lava and
then later got messages about it reviving and burning to death.  Items
thrown, kicked, or dropped into lava were being subjected to fire damage
(so scrolls burned up, potions boiled, non-fireproofed flammable weapons
and armor eroded), but corpses and a lot of other stuff not subject to
erosion remained unaffected.  This makes things that are made out of
wood, cloth, flesh and other flammable stuff burn up (when in lava, not
when hit by fire).

doc/fixes36.1
include/extern.h
src/do.c
src/trap.c

index 46bb2ad03816976034ffd5c63dfc2df54b02279d..27c12ef6f20df9573ba6d963bb270ae244e9aff0 100644 (file)
@@ -444,6 +444,8 @@ fix buffer overflow in wizard mode for '#' command when 'extmenu' option is on
        could get that message, move a bit, then get "you can move again"
        after the 2 turn freeze applied along with the actual vomit
 fix mention_walls reporting secret doors as solid walls
+corpses and other flammable items not subject to direct burning or fire-based
+       erosion which were thrown or dropped into lava remained intact
 
 
 Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
index f5e6ec9de952c66238e79cf656c50b3addb67c2d..f4581f2e25d8e30b86e980857def1d01629e38a1 100644 (file)
@@ -2416,6 +2416,7 @@ E void NDECL(climb_pit);
 E boolean FDECL(fire_damage, (struct obj *, BOOLEAN_P, XCHAR_P, XCHAR_P));
 E int FDECL(fire_damage_chain,
             (struct obj *, BOOLEAN_P, BOOLEAN_P, XCHAR_P, XCHAR_P));
+E boolean FDECL(lava_damage, (struct obj *, XCHAR_P, XCHAR_P));
 E void acid_damage(struct obj *);
 E int FDECL(water_damage, (struct obj *, const char *, BOOLEAN_P));
 E void FDECL(water_damage_chain, (struct obj *, BOOLEAN_P));
index fe27e7973bca0035eda62d4aebe75355ccf7a780..56a056fc05474a20224f554c3d07df1292ce0f5f 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -190,7 +190,7 @@ const char *verb;
         newsym(x, y);
         return TRUE;
     } else if (is_lava(x, y)) {
-        return fire_damage(obj, FALSE, x, y);
+        return lava_damage(obj, x, y);
     } else if (is_pool(x, y)) {
         /* Reasonably bulky objects (arbitrary) splash when dropped.
          * If you're floating above the water even small things make
index 33aedca38ccd2af6f9f340dc3ebe1655f2298b72..d6b3f8de9ed49afdf84fc4eaf4f69a698f4814c6 100644 (file)
@@ -3287,6 +3287,7 @@ xchar x, y;
 {
     struct obj *obj, *nobj;
     int num = 0;
+
     for (obj = chain; obj; obj = nobj) {
         nobj = here ? obj->nexthere : obj->nobj;
         if (fire_damage(obj, force, x, y))
@@ -3298,6 +3299,51 @@ xchar x, y;
     return num;
 }
 
+/* obj has been thrown or dropped into lava; damage is worse than mere fire */
+boolean
+lava_damage(obj, x, y)
+struct obj *obj;
+xchar x, y;
+{
+    int otyp = obj->otyp, ocls = obj->oclass;
+
+    /* the Amulet, invocation items, and Rider corpses are never destroyed
+       (let Book of the Dead fall through to fire_damage() to get feedback) */
+    if (obj_resists(obj, 0, 0) && otyp != SPE_BOOK_OF_THE_DEAD)
+        return FALSE;
+    /* destroy liquid (venom), wax, veggy, flesh, paper (except for scrolls
+       and books--let fire damage deal with them), cloth, leather, wood, bone
+       unless it's inherently or explicitly fireproof or contains something;
+       note: potions are glass so fall through to fire_damage() and boil */
+    if (objects[otyp].oc_material < DRAGON_HIDE
+        && ocls != SCROLL_CLASS && ocls != SPBOOK_CLASS
+        && objects[otyp].oc_oprop != FIRE_RES
+        && otyp != WAN_FIRE && otyp != FIRE_HORN
+        /* assumes oerodeproof isn't overloaded for some other purpose on
+           non-eroding items */
+        && !obj->oerodeproof
+        /* fire_damage() knows how to deal with containers and contents */
+        && !Has_contents(obj)) {
+        if (cansee(x, y)) {
+            /* this feedback is pretty clunky and can become very verbose
+               when former contents of a burned container get here via
+               flooreffects() */
+            if (obj == thrownobj || obj == kickedobj)
+                pline("%s %s up!", is_plural(obj) ? "They" : "It",
+                      otense(obj, "burn"));
+            else
+                You_see("%s hit lava and burn up!", doname(obj));
+        }
+        if (carried(obj)) { /* shouldn't happen */
+            remove_worn_item(obj, TRUE);
+            useupall(obj);
+        } else
+            delobj(obj);
+        return TRUE;
+    }
+    return fire_damage(obj, TRUE, x, y);
+}
+
 void
 acid_damage(obj)
 struct obj *obj;