diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 9ce420c..542359a 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -2465,6 +2465,32 @@ public sealed class GameWindow : IDisposable { remoteMot.ServerMoveToActive = update.MotionState.IsServerControlledMoveTo; + // Bulk-copy the wire's resolved ForwardCommand + speed + // into InterpretedState UNCONDITIONALLY (overlay, + // substate, AND MoveTo packets). Matches retail's + // copy_movement_from semantics + // (acclient_2013_pseudo_c.txt:293301-293311) which does + // not filter by MovementType. + // + // For MoveTo packets, fullMotion is the RunForward seed + // from PlanMoveToStart, so this populates + // ForwardCommand=RunForward + ForwardSpeed=speed*runRate + // — what the OLD substate-only DoInterpretedMotion call + // (commit f794832 removed) used to set. Without it, + // apply_current_movement reads the default + // ForwardCommand=Ready and produces zero velocity, so + // chasing creatures only translate via UpdatePosition + // hard-snaps and at spawn appear posed at default + // (visible as "torso on the ground" until the first UP + // snap hits). + // + // For overlay (Action) packets this sets ForwardCommand + // to the Attack/Twitch/etc command, and + // get_state_velocity returns 0 because the gate is + // RunForward||WalkForward — body stops moving forward. + remoteMot.Motion.InterpretedState.ForwardCommand = fullMotion; + remoteMot.Motion.InterpretedState.ForwardSpeed = speedMod <= 0f ? 1f : speedMod; + if (update.MotionState.IsServerControlledMoveTo && update.MotionState.MoveToPath is { } path) { @@ -2488,15 +2514,6 @@ public sealed class GameWindow : IDisposable // Off MoveTo — clear stale destination so the per-tick // driver doesn't keep steering. remoteMot.HasMoveToDestination = false; - - // Bulk-copy the wire's resolved ForwardCommand + speed - // into InterpretedState. For Action commands this - // makes apply_current_movement return zero velocity - // on the next tick (gate fails). For substate - // commands (Run/Walk/Ready), this is identical to - // what DoInterpretedMotion would have written. - remoteMot.Motion.InterpretedState.ForwardCommand = fullMotion; - remoteMot.Motion.InterpretedState.ForwardSpeed = speedMod <= 0f ? 1f : speedMod; } }