fix(anim): pass resolved command (not original) to sequencer SetCycle

The left→right fallback resolved the cycle correctly but still passed
the original TurnLeft/SideStepLeft command to the sequencer. The
sequencer did its own internal cycle lookup with the left-side command
and found nothing → no animation played.

Fix: track which command actually resolved (after fallback) and pass
that to SetCycle so the sequencer's internal lookup matches.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-13 00:51:39 +02:00
parent 0868849b3d
commit 1b4fdac13c

View file

@ -2057,6 +2057,7 @@ public sealed class GameWindow : IDisposable
// AC reuses right-side animations for left-side motions (played in // AC reuses right-side animations for left-side motions (played in
// reverse). If the left-side command has no cycle, fall back to the // reverse). If the left-side command has no cycle, fall back to the
// right-side equivalent so the player isn't stuck in idle. // right-side equivalent so the player isn't stuck in idle.
uint resolvedCommand = animCommand; // track which command actually resolved
if (cycle is null || cycle.Framerate == 0f || cycle.HighFrame <= cycle.LowFrame) if (cycle is null || cycle.Framerate == 0f || cycle.HighFrame <= cycle.LowFrame)
{ {
ushort fallback = cmdOverride switch ushort fallback = cmdOverride switch
@ -2073,17 +2074,20 @@ public sealed class GameWindow : IDisposable
motionTableIdOverride: _playerMotionTableId, motionTableIdOverride: _playerMotionTableId,
stanceOverride: NonCombatStance, stanceOverride: NonCombatStance,
commandOverride: fallback); commandOverride: fallback);
// Update resolvedCommand so the sequencer looks up the right cycle
resolvedCommand = (animCommand & 0xFF000000u) | fallback;
} }
} }
if (cycle is null || cycle.Framerate == 0f || cycle.HighFrame <= cycle.LowFrame) return; if (cycle is null || cycle.Framerate == 0f || cycle.HighFrame <= cycle.LowFrame) return;
// If the entity has a sequencer, use SetCycle for transition-link-aware // If the entity has a sequencer, use SetCycle for transition-link-aware
// motion switching. Otherwise update the legacy slerp path fields. // motion switching. Pass the RESOLVED command (after left→right fallback)
// so the sequencer's internal cycle lookup finds the same animation.
if (ae.Sequencer is not null) if (ae.Sequencer is not null)
{ {
uint fullStyle = 0x80000000u | (uint)NonCombatStance; uint fullStyle = 0x80000000u | (uint)NonCombatStance;
ae.Sequencer.SetCycle(fullStyle, animCommand); ae.Sequencer.SetCycle(fullStyle, resolvedCommand);
} }
ae.Animation = cycle.Animation; ae.Animation = cycle.Animation;