fix #K3915 - "deleting worn obj" warning

Knocking a monster into lava triggering impossible warnig "deleting
worn object" for a wooden shield.  The monster had to be wearning
flammable armor and be fire resistant to survive instead dying and
dropping inventory, and it couldn't be a creature that can survive at
lava locations like a salamander and the armor needed to already be
thoroughly burnt.

It wasn't hard to figure out what needed to be fixed, but it was very
hard to reproduce the situation in order to verify that fix.  The
report was for monster vs monster knockback but I jousted with a lance
instead.  I still don't understand why burning up a worn wooden shield
triggered the warning but burning up a worn orcish cloak did not.
This commit is contained in:
PatR
2023-05-06 00:08:35 -07:00
parent 41c8a18d3d
commit 6de996971b
2 changed files with 24 additions and 4 deletions

View File

@@ -1169,6 +1169,9 @@ engraving in an open doorway was allowed, engraving in closed one (presumably
change to allow engraving at closed door location
engraving in a breach in a shop's or vault's wall or vault guard's temporary
corridor would leave the engraving intact after repair/cleanup
if a fire resistant non-fire immune monster wearing a thoroughly burnt wooden
shield got knocked into lava, burning the shield completely yielded
impossible warning "obfree: deleting worn obj"
Fixes to 3.7.0-x General Problems Exposed Via git Repository

View File

@@ -190,9 +190,9 @@ erode_obj(
uvictim = (victim == &gy.youmonst);
vismon = victim && (victim != &gy.youmonst) && canseemon(victim);
/* Is gb.bhitpos correct here? Ugh. */
visobj = !victim && cansee(gb.bhitpos.x, gb.bhitpos.y)
&& (!is_pool(gb.bhitpos.x, gb.bhitpos.y)
|| (next2u(gb.bhitpos.x,gb.bhitpos.y) && Underwater));
visobj = (!victim && cansee(gb.bhitpos.x, gb.bhitpos.y)
&& (!is_pool(gb.bhitpos.x, gb.bhitpos.y)
|| (next2u(gb.bhitpos.x,gb.bhitpos.y) && Underwater)));
switch (type) {
case ERODE_BURN:
@@ -287,6 +287,7 @@ erode_obj(
return ER_DAMAGED;
} else if (ef_flags & EF_DESTROY) {
otmp->in_use = 1; /* in case of hangup during message w/ --More-- */
if (uvictim || vismon || visobj)
pline("%s %s %s away!",
uvictim ? "Your"
@@ -297,7 +298,23 @@ erode_obj(
if (ef_flags & EF_PAY)
costly_alteration(otmp, cost_type);
setnotworn(otmp);
if (otmp->owornmask) {
/* unwear otmp before deleting it */
if (carried(otmp)) {
/* otmp remains in hero's invent */
remove_worn_item(otmp, TRUE); /* calls Cloak_off(),&c */
} else if (mcarried(otmp)) {
/* results in otmp->where==OBJ_FREE; delobj() doesn't care */
extract_from_minvent(otmp->ocarry, otmp, TRUE, FALSE);
} else { /* worn but not in hero invent or monster minvent ? */
impossible(
"erode_obj(%d): destroying strangely worn item [%d, 0x%08lx: %s]",
type,
otmp->where, otmp->owornmask, simpleonames(otmp));
otmp->owornmask = 0L; /* otherwise a second complaint (about
* deleting a worn item) will ensue */
}
}
delobj(otmp);
return ER_DESTROYED;
} else {