fix #H2247 - lava inconsistencies (trunk only)
From a bug report, if you move into lava, die,
and are life-saved or leave bones, your potions will remain intact,
whereas if you have fire resistance and survive, they'll be subjected to
destroy_item() and usually be destroyed (not always, because stacks of
more than 1 don't always destroy the whole stack). Also, wooden ring
will be destroyed even if it happens to be ring of fire resistance.
This addresses both of those bugs.
He also thought that all vulnerable armor should be destroyed rather
than just boots in the case where you have fire resistance and survive,
but I didn't change that. It is a little odd, but presumeably only your
feet are in lava at first (although later sinking further into lava
doesn't actually burn up any other stuff).
This commit is contained in:
@@ -357,6 +357,11 @@ effectiveness of magic cancellation by worn armor has been reduced
|
||||
Protection improves the effectiveness of magic cancellation
|
||||
if an angry shopkeeper chased the hero to a different level and then got paid
|
||||
off, he'd dismiss kops on that other level but not on his shop level
|
||||
dying in lava and being life-saved or leaving bones would destroy ring of
|
||||
fire resistance if it happened to be made of wood, and also burn up
|
||||
scrolls of fire and spellbook of fireball
|
||||
surviving in lava boils away carried potions, but dying in lava and being
|
||||
life-saved or leaving bones would keep them intact
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
64
src/trap.c
64
src/trap.c
@@ -4652,16 +4652,29 @@ lava_effects()
|
||||
int dmg = d(6, 6); /* only applicable for water walking */
|
||||
boolean usurvive, boil_away;
|
||||
|
||||
usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
|
||||
/* a timely interrupt might manage to salvage your life
|
||||
but not your gear; do this before messages */
|
||||
if (!usurvive)
|
||||
for (obj = invent; obj; obj = obj->nobj)
|
||||
if (is_organic(obj) && !obj->oerodeproof) obj->in_use = TRUE;
|
||||
|
||||
burn_away_slime();
|
||||
if (likes_lava(youmonst.data)) return FALSE;
|
||||
|
||||
usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
|
||||
/*
|
||||
* A timely interrupt might manage to salvage your life
|
||||
* but not your gear. For scrolls and potions this
|
||||
* will destroy whole stacks, where fire resistant hero
|
||||
* survivor only loses partial stacks via destroy_item().
|
||||
*
|
||||
* Flag items to be destroyed before any messages so
|
||||
* that player causing hangup at --More-- won't get an
|
||||
* emergency save file created before item destruction.
|
||||
*/
|
||||
if (!usurvive)
|
||||
for (obj = invent; obj; obj = obj->nobj)
|
||||
if ((is_organic(obj) || obj->oclass == POTION_CLASS) &&
|
||||
!obj->oerodeproof &&
|
||||
objects[obj->otyp].oc_oprop != FIRE_RES &&
|
||||
obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL &&
|
||||
!obj_resists(obj, 0, 0)) /* for invocation items */
|
||||
obj->in_use = TRUE;
|
||||
|
||||
if (!Fire_resistance) {
|
||||
if(Wwalking) {
|
||||
pline_The("lava here burns you!");
|
||||
@@ -4677,35 +4690,21 @@ lava_effects()
|
||||
if (wizard) usurvive = TRUE;
|
||||
#endif
|
||||
|
||||
/* prevent Boots_off() -> spoteffects() -> lava_effects() recursion
|
||||
which would successfully delete (via useupall) the no-longer-worn
|
||||
boots; once recursive call returned, we would try to delete them
|
||||
again here in the outer call (access stale memory, probably panic) */
|
||||
/* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
|
||||
spoteffects() -> lava_effects() recursion which would
|
||||
successfully delete (via useupall) the no-longer-worn boots;
|
||||
once recursive call returned, we would try to delete them again
|
||||
here in the outer call (and access stale memory, probably panic) */
|
||||
iflags.in_lava_effects++;
|
||||
|
||||
for(obj = invent; obj; obj = obj2) {
|
||||
obj2 = obj->nobj;
|
||||
if(is_organic(obj) && !obj->oerodeproof) {
|
||||
if(obj->owornmask) {
|
||||
/* above, we set in_use for objects which are to be destroyed */
|
||||
if (obj->in_use) {
|
||||
if (obj->owornmask) {
|
||||
if (usurvive)
|
||||
pline("%s into flame!", Yobjnam2(obj, "burst"));
|
||||
|
||||
if(obj == uarm) (void) Armor_gone();
|
||||
else if(obj == uarmc) (void) Cloak_off();
|
||||
else if(obj == uarmh) (void) Helmet_off();
|
||||
else if(obj == uarms) (void) Shield_off();
|
||||
else if(obj == uarmg) (void) Gloves_off();
|
||||
else if(obj == uarmf) (void) Boots_off();
|
||||
#ifdef TOURIST
|
||||
else if(obj == uarmu) (void) Shirt_off();
|
||||
#endif
|
||||
else if(obj == uleft) Ring_gone(obj);
|
||||
else if(obj == uright) Ring_gone(obj);
|
||||
else if(obj == ublindf) Blindf_off(obj);
|
||||
else if(obj == uamul) Amulet_off();
|
||||
else if(obj == uwep) uwepgone();
|
||||
else if (obj == uquiver) uqwepgone();
|
||||
else if (obj == uswapwep) uswapwepgone();
|
||||
remove_worn_item(obj, TRUE);
|
||||
}
|
||||
useupall(obj);
|
||||
}
|
||||
@@ -4731,7 +4730,7 @@ lava_effects()
|
||||
}
|
||||
You("find yourself back on solid %s.", surface(u.ux, u.uy));
|
||||
return(TRUE);
|
||||
}
|
||||
} /* !Fire_resistance */
|
||||
|
||||
if (!Wwalking) {
|
||||
u.utrap = rn1(4, 4) + (rn1(4, 12) << 8);
|
||||
@@ -4743,7 +4742,8 @@ lava_effects()
|
||||
/* just want to burn boots, not all armor; destroy_item doesn't work on
|
||||
armor anyway */
|
||||
burn_stuff:
|
||||
if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) {
|
||||
if (uarmf && !uarmf->oerodeproof && is_organic(uarmf) &&
|
||||
objects[uarmf->otyp].oc_oprop != FIRE_RES) {
|
||||
/* save uarmf value because Boots_off() sets uarmf to null */
|
||||
obj = uarmf;
|
||||
pline("%s into flame!", Yobjnam2(obj, "burst"));
|
||||
|
||||
Reference in New Issue
Block a user