From: PatR Date: Fri, 22 Sep 2017 22:08:42 +0000 (-0700) Subject: vulnerable items thrown into lava X-Git-Tag: NetHack-3.6.1_RC01~344 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e589d87d186cb3aa4bfdd95c1a11911855503fb1;p=nethack vulnerable items thrown into lava 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). --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 46bb2ad03..27c12ef6f 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -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 diff --git a/include/extern.h b/include/extern.h index f5e6ec9de..f4581f2e2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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)); diff --git a/src/do.c b/src/do.c index fe27e7973..56a056fc0 100644 --- 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 diff --git a/src/trap.c b/src/trap.c index 33aedca38..d6b3f8de9 100644 --- a/src/trap.c +++ b/src/trap.c @@ -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;