fix #270: fire ReportExhaustion on the stamina-exhaustion edge only, not every stats tick

Retail calls CPhysicsObj::report_exhaustion from exactly one site -
CommandInterpreter::HandleExhaustion (0x006b3c70), a notification handler
for the stamina-exhaustion EVENT. Campaign P P1 wired it to every
movement-stats application instead (every stamina regen/drain tick), and
each call re-dispatches the current movement state through the animation
sink - truncating any in-flight action animation. The diagnostic session
log shows 490 spurious casting-stance re-queues in one short session:
'sometimes stuck in spell animations' was every stamina tick that
collided with a cast gesture's play window.

The re-apply now fires only when the exhausted state (stamina == 0)
transitions, matching retail's event semantics. Stats still reach
PlayerWeenie immediately via RuntimeMovementSkillProjection.ApplyTo.

Also adds the [remote-edge] probe (rides ACDREAM_DUMP_MOTION=1): one
line per remote HitGround/LeaveGround - each such edge drains the
mover's pending action animations (retail HandleEnterWorld), the
working theory for intermittently missing monster attack swings.

Complete Release suite: 10,026 passed / 5 skips / 0 failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-30 22:11:20 +02:00
parent 5788fdaa02
commit a46c8e65b2
4 changed files with 101 additions and 10 deletions

View file

@ -98,6 +98,38 @@ Copy this block when adding a new issue:
---
## #270 — Stuck spell animations + intermittently missing monster attack animations
**Status:** LOCAL CAUSE FIXED 2026-07-30 (pending user re-test); remote
attack-animation misses under investigation with the [remote-edge] probe
**Severity:** HIGH (combat/casting presentation)
**Component:** motion re-dispatch cadence / remote action animations
**Local stuck casts — root cause CONFIRMED and fixed:** Campaign P P1 wired
`ApplyMovementStats` to call `MotionInterpreter.ReportExhaustion()` on EVERY
movement-stats application — i.e. every stamina regen/drain tick. Each call
re-dispatches the current movement state through the animation sink,
truncating any in-flight action animation; the diagnostic session log shows
490 spurious casting-stance re-queues while the user was in magic mode.
Retail fires `CPhysicsObj::report_exhaustion` from exactly ONE site —
`CommandInterpreter::HandleExhaustion` (0x006b3c70), a notification handler
invoked on the stamina-EXHAUSTION EVENT. Fix: the re-apply now fires only
when the exhausted state (stamina == 0) transitions; skills/burden/stamina
still reach `PlayerWeenie` immediately (the next natural dispatch picks up
rate changes, exactly retail).
**Monster attack misses — theory + probe:** every logged attack UM
(cmd=0x00D3, spd=2.0) DID dispatch (`SetCycle 0x400000D3`), so the wire →
animation path works. Working theory: remote ground-contact edges (bounce
hops / contact flickers on dead-reckoned bodies) each drain the mover's
pending action animations (retail `HandleEnterWorld` semantics — faithful
per edge, wrong if we generate edges retail doesn't). A `[remote-edge]`
probe (rides `ACDREAM_DUMP_MOTION=1`) now logs every remote
HitGround/LeaveGround with the guid — one repro session with a missed swing
will convict or acquit.
---
## #269 — Slope-stop slide runs too far (post-bounce-rework residual)
**Status:** OPEN (user live gate 2026-07-30 — "almost pass with merits")