Don't attempt to cache encumber_msg result

There was only one point in the code at which this caching was
being done, and it was incorrect: it's possible for the result of
near_capacity to change during a monster turn because monster
actions can change either inventory weight or carry capacity.

The bug was particularly relevant in cases where a character
polymorphed into a slow weak monster gets attacked by a monster
that moves at normal speed: due to the polyform being slow, the
normal-speed monster gets in a lot of attacks and causes a
rehumanization, but due to the polyform being weak, it was
burdened at the start of the monster turn, and so when that
penalty is (due to the bug) applied to the next turn it can
mean that the character misses the next turn too, and may end up
dying as a result.
This commit is contained in:
Alex Smith
2025-11-24 02:07:23 +00:00
parent ae516ddc67
commit fce66245ca
20 changed files with 50 additions and 46 deletions

View File

@@ -90,7 +90,7 @@ moveloop_preamble(boolean resuming)
fix_shop_damage();
}
(void) encumber_msg(); /* in case they auto-picked up something */
encumber_msg(); /* in case they auto-picked up something */
if (gd.defer_see_monsters) {
gd.defer_see_monsters = FALSE;
see_monsters();
@@ -197,7 +197,7 @@ moveloop_core(void)
u.umovement -= NORMAL_SPEED;
do { /* hero can't move this turn loop */
mvl_wtcap = encumber_msg();
encumber_msg();
svc.context.mon_moving = TRUE;
do {
@@ -207,6 +207,10 @@ moveloop_core(void)
} while (monscanmove);
svc.context.mon_moving = FALSE;
/* this needs to be after the monster movement loop in
case monster actions affected burden, e.g. rehumanize */
mvl_wtcap = near_capacity();
if (!monscanmove && u.umovement < NORMAL_SPEED) {
/* both hero and monsters are out of steam this round */
struct monst *mtmp;
@@ -392,7 +396,7 @@ moveloop_core(void)
inventory may have changed in, e.g., nh_timeout(); we do
need two checks here so that the player gets feedback
immediately if their own action encumbered them */
(void) encumber_msg();
encumber_msg();
#ifdef STATUS_HILITES
if (iflags.hilite_delta)