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;