From b805ba7bc39df5df1d41a1dce95d7e4fb0f2a459 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Fri, 11 May 2007 02:25:55 +0000 Subject: [PATCH] splattered oil fix splatter_burning_oil() is called when a lit potion of oil gets broken, and it can dish out fatal damage to the hero. An earlier fix to prevent a light-source panic (thrown item is not on any of the object lists) during bones creation didn't address leaving that lit potion intact if it was on the floor (which can happen if the breakage is caused by striking or force bolt rather than its being thrown or kicked). Use the existing obj->in_use mechanism as a more general fix, after teaching bones code that it applies to other things besides the hero's inventory. --- doc/fixes34.4 | 4 +++- src/bones.c | 10 ++++++++-- src/dothrow.c | 9 +-------- src/end.c | 7 +++++++ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 119ee0356..5d77d35a9 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -257,8 +257,10 @@ honor the never-in-hell flag when selecting random monster type for corpses, eggs, figurines, and statues created in Gehennom hero is not subject to light-based blindness while fainted from hunger engraving while underwater should use surface() which handles that case -prevent obj_is_local panic during bones creation when splatter_burning_oil() +prevent obj_is_local panic during bones creation when splattered burning oil from a thrown potion of oil kills the hero +don't leave lit potion intact when splattered burning oil from broken floor + potion kills the hero fix region timeout detection, caused strange display of stinking cloud while wearing the Eyes of the Overworld try to keep migrating monsters from escaping the wizard tower diff --git a/src/bones.c b/src/bones.c index c27346f04..6d36beec7 100644 --- a/src/bones.c +++ b/src/bones.c @@ -57,11 +57,17 @@ resetobjs(ochain,restore) struct obj *ochain; boolean restore; { - struct obj *otmp; + struct obj *otmp, *nobj; - for (otmp = ochain; otmp; otmp = otmp->nobj) { + for (otmp = ochain; otmp; otmp = nobj) { + nobj = otmp->nobj; if (otmp->cobj) resetobjs(otmp->cobj,restore); + if (otmp->in_use) { + obj_extract_self(otmp); + dealloc_obj(otmp); + continue; + } if (restore) { /* artifact bookeeping needs to be done during diff --git a/src/dothrow.c b/src/dothrow.c index 293ae0f3b..fd3748564 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1650,15 +1650,8 @@ boolean from_invent; change_luck(-2); break; case POT_WATER: /* really, all potions */ + obj->in_use = 1; /* in case it's fatal */ if (obj->otyp == POT_OIL && obj->lamplit) { - /* splatter_burning_oil() could kill hero, - and a timed obj with obj->where==0 - causes a problem during savebones() so - get rid of the timer/lightsources on it now */ - if (obj->timed) - obj_stop_timers(obj); - if (obj_sheds_light(obj)) - del_light_source(LS_OBJECT, obj_to_any(obj)); splatter_burning_oil(x,y); } else if (distu(x,y) <= 2) { if (!breathless(youmonst.data) || haseyes(youmonst.data)) { diff --git a/src/end.c b/src/end.c index 123a45338..1f7e0587b 100644 --- a/src/end.c +++ b/src/end.c @@ -20,6 +20,9 @@ #define FIRST_AMULET AMULET_OF_ESP #define LAST_AMULET AMULET_OF_YENDOR +extern struct obj *thrownobj; /* dothrow.c */ +extern struct obj *kickobj; /* dokick.c */ + struct valuable_data { long count; int typ; }; static struct valuable_data @@ -650,6 +653,10 @@ die: /* might have been killed while using a disposable item, so make sure it's gone prior to inventory disclosure and creation of bones data */ inven_inuse(TRUE); + /* not on object lists; if an active light source, would cause big + trouble (`obj_is_local' panic) for savebones() -> savelev() */ + if (thrownobj) dealloc_obj(thrownobj); + if (kickobj) dealloc_obj(kickobj); /* Sometimes you die on the first move. Life's not fair. * On those rare occasions you get hosed immediately, go out