fix(anim): call Sequencer.SetCycle on motion changes

The sequencer was initialized at spawn but never notified when the
player started walking/running/turning. UpdatePlayerAnimation and
OnLiveMotionUpdated both updated the legacy slerp fields but the
sequencer path in TickAnimations reads from Sequencer.Advance(dt),
which stayed at the initial idle cycle.

Fix: both methods now call ae.Sequencer.SetCycle(style, motion) when
the sequencer exists, alongside the legacy field updates (which serve
as fallback for entities without a sequencer).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-13 00:44:38 +02:00
parent ed37f0969b
commit e77dc1a0e8

View file

@ -951,6 +951,14 @@ public sealed class GameWindow : IDisposable
if (!newCycleIsGood)
return;
// If the entity has a sequencer, use SetCycle for transition links.
if (ae.Sequencer is not null)
{
uint fullStyle = stance != 0 ? (0x80000000u | (uint)stance) : ae.Sequencer.CurrentStyle;
uint fullMotion = command is > 0 ? (uint)command.Value : 0x41000003u;
ae.Sequencer.SetCycle(fullStyle, fullMotion);
}
ae.Animation = newCycle!.Animation;
ae.LowFrame = Math.Max(0, newCycle.LowFrame);
ae.HighFrame = Math.Min(newCycle.HighFrame, newCycle.Animation.PartFrames.Count - 1);
@ -2048,6 +2056,14 @@ public sealed class GameWindow : IDisposable
if (cycle is null || cycle.Framerate == 0f || cycle.HighFrame <= cycle.LowFrame) return;
// If the entity has a sequencer, use SetCycle for transition-link-aware
// motion switching. Otherwise update the legacy slerp path fields.
if (ae.Sequencer is not null)
{
uint fullStyle = 0x80000000u | (uint)NonCombatStance;
ae.Sequencer.SetCycle(fullStyle, animCommand);
}
ae.Animation = cycle.Animation;
ae.LowFrame = Math.Max(0, cycle.LowFrame);
ae.HighFrame = Math.Min(cycle.HighFrame, cycle.Animation.PartFrames.Count - 1);