acdream/tests/AcDream.Core.Tests/Physics/ServerControlledLocomotionTests.cs
Erik 9812965183 fix(anim): Phase L.1c match MoveTo run speed
Retail MovementManager::PerformMovement (0x00524440) reads MoveTo speed and runRate from the packet, MovementParameters::UnPackNet (0x0052AC50) defines the layout, and CMotionInterp::apply_run_to_command (0x00527BE0) multiplies RunForward by runRate. Parse those fields for UpdateMotion/CreateObject, seed server-controlled MoveTo locomotion with the retail speed multiplier, and avoid overriding active monster MoveTo with sparse UpdatePosition-derived velocity.
2026-04-28 20:58:22 +02:00

88 lines
2.6 KiB
C#

using System.Numerics;
using AcDream.Core.Physics;
using Xunit;
namespace AcDream.Core.Tests.Physics;
public sealed class ServerControlledLocomotionTests
{
[Fact]
public void PlanMoveToStart_SeedsImmediateRunCycle()
{
var plan = ServerControlledLocomotion.PlanMoveToStart();
Assert.True(plan.IsMoving);
Assert.Equal(MotionCommand.RunForward, plan.Motion);
Assert.Equal(1.0f, plan.SpeedMod);
}
[Fact]
public void PlanMoveToStart_AppliesRetailRunRate()
{
var plan = ServerControlledLocomotion.PlanMoveToStart(
moveToSpeed: 1.25f,
runRate: 1.5f,
canRun: true);
Assert.True(plan.IsMoving);
Assert.Equal(MotionCommand.RunForward, plan.Motion);
Assert.Equal(1.875f, plan.SpeedMod);
}
[Fact]
public void PlanMoveToStart_UsesWalkWhenRunDisallowed()
{
var plan = ServerControlledLocomotion.PlanMoveToStart(
moveToSpeed: 0.75f,
runRate: 2.0f,
canRun: false);
Assert.True(plan.IsMoving);
Assert.Equal(MotionCommand.WalkForward, plan.Motion);
Assert.Equal(0.75f, plan.SpeedMod);
}
[Fact]
public void PlanFromVelocity_StopsBelowRetailNoiseThreshold()
{
var plan = ServerControlledLocomotion.PlanFromVelocity(
new Vector3(0.10f, 0.12f, 3.0f));
Assert.False(plan.IsMoving);
Assert.Equal(MotionCommand.Ready, plan.Motion);
Assert.Equal(1.0f, plan.SpeedMod);
}
[Fact]
public void PlanFromVelocity_WalksForSlowServerControlledMotion()
{
var plan = ServerControlledLocomotion.PlanFromVelocity(
new Vector3(0.0f, 0.80f, 0.0f));
Assert.True(plan.IsMoving);
Assert.Equal(MotionCommand.WalkForward, plan.Motion);
Assert.InRange(plan.SpeedMod, 0.25f, 0.27f);
}
[Fact]
public void PlanFromVelocity_RunsAtRetailRunScale()
{
var plan = ServerControlledLocomotion.PlanFromVelocity(
new Vector3(0.0f, MotionInterpreter.RunAnimSpeed, 0.0f));
Assert.True(plan.IsMoving);
Assert.Equal(MotionCommand.RunForward, plan.Motion);
Assert.Equal(1.0f, plan.SpeedMod, precision: 4);
}
[Fact]
public void PlanFromVelocity_ClampsVeryFastSnapshots()
{
var plan = ServerControlledLocomotion.PlanFromVelocity(
new Vector3(0.0f, 30.0f, 0.0f));
Assert.True(plan.IsMoving);
Assert.Equal(MotionCommand.RunForward, plan.Motion);
Assert.Equal(ServerControlledLocomotion.MaxSpeedMod, plan.SpeedMod);
}
}