From 9d9042e94b591a7de9f0333ceed8c710ea3fba43 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 1 Aug 2023 10:28:21 -0700 Subject: [PATCH] fix #K3968 - objfree: obj not worn New feature to sometimes hit twice for skilled martial-arts/bare-handed was unconditionally using uswapwep for the second hit. If it was a breakable object, hitting could break it and produce impossible "objfree: obj not free". Only use uswapwep for u.twoweap; use Null for second bare-handed hit. --- doc/fixes3-7-0.txt | 3 +++ src/uhitm.c | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 4c9f07223..fea3c9576 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1649,6 +1649,9 @@ hero might not be credited with "entered Mine Town" achievement for the town in the theme room "water-surrounded vault", guarantee an item which can be be used to escape from the room in one of the four chests pets capable of using items would pick up and wear cursed armor +if something breakable was set up as alternate weapon and the second of two + bare-handed hits succeeded, it would be broken and trigger impossible + "objfree: deleting worn obj" Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/uhitm.c b/src/uhitm.c index e8eab0630..1674ab9c5 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -743,7 +743,8 @@ static boolean hitum(struct monst *mon, struct attack *uattk) { boolean malive, wep_was_destroyed = FALSE; - struct obj *wepbefore = uwep; + struct obj *wepbefore = uwep, + *secondwep = u.twoweap ? uswapwep : (struct obj *) 0; int tmp, dieroll, mhit, armorpenalty, attknum = 0, x = u.ux + u.dx, y = u.uy + u.dy, oldumort = u.umortality; @@ -787,11 +788,12 @@ hitum(struct monst *mon, struct attack *uattk) mon_maybe_unparalyze(mon); dieroll = rnd(20); mhit = (tmp > dieroll || u.uswallow); - malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk, + malive = known_hitum(mon, secondwep, &mhit, tmp, armorpenalty, uattk, dieroll); /* second passive counter-attack only occurs if second attack hits */ if (mhit) - (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep); + (void) passive(mon, secondwep, mhit, malive, AT_WEAP, + secondwep && !uswapwep); } gt.twohits = 0; return malive;