From 6de996971b7aa5678dfb58b4c7744594e5b25ba5 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 6 May 2023 00:08:35 -0700 Subject: [PATCH] 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. --- doc/fixes3-7-0.txt | 3 +++ src/trap.c | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 6faeb10ee..c3d7151a5 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/src/trap.c b/src/trap.c index 7ba8b0cc3..46cf32718 100644 --- a/src/trap.c +++ b/src/trap.c @@ -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 {