feat(movement): wire server RunRate into player MotionInterpreter

Parse ForwardSpeed from UpdateMotion (0xF74C) InterpretedMotionState.
Feed server-echoed RunRate into the player's MotionInterpreter so
get_state_velocity produces the correct speed. Previously hardcoded
at 1.0 (4.0 m/s), now matches character's Run skill.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-13 23:11:49 +02:00
parent 4988ea02c0
commit c7fa1d36fb
5 changed files with 71 additions and 7 deletions

View file

@ -115,6 +115,18 @@ public sealed class PlayerMovementController
_motion = new MotionInterpreter(_body);
}
/// <summary>
/// Apply a server-echoed run rate (ForwardSpeed from UpdateMotion) to the
/// player's MotionInterpreter. The server broadcasts the real RunRate
/// derived from the character's Run skill; wiring it here ensures
/// get_state_velocity produces the correct speed instead of the default 1.0.
/// </summary>
public void ApplyServerRunRate(float forwardSpeed)
{
_motion.InterpretedState.ForwardSpeed = forwardSpeed;
_motion.apply_current_movement(cancelMoveTo: false, allowJump: false);
}
public void SetPosition(Vector3 pos, uint cellId)
{
_body.Position = pos;

View file

@ -952,6 +952,18 @@ public sealed class GameWindow : IDisposable
if (!newCycleIsGood)
return;
// Wire server-echoed RunRate into the player's MotionInterpreter.
// The server broadcasts the character's real Run-skill-derived ForwardSpeed
// in UpdateMotion; without this the player would always move at 4.0 m/s
// (ForwardSpeed = 1.0 hardcoded in MotionInterpreter defaults).
if (_playerController is not null
&& update.Guid == _playerServerGuid
&& update.MotionState.ForwardSpeed.HasValue
&& update.MotionState.ForwardSpeed.Value > 0f)
{
_playerController.ApplyServerRunRate(update.MotionState.ForwardSpeed.Value);
}
// Sequencer path
if (ae.Sequencer is not null)
{