feat(headless): complete deterministic bot command parity
This commit is contained in:
parent
7e8acb74dd
commit
38e83640d9
37 changed files with 2805 additions and 295 deletions
|
|
@ -40,14 +40,87 @@ public sealed class RuntimeLocalPlayerMovementStateTests
|
|||
public void GraphicalAndDirectCommandsMutateOneAutorunLatch()
|
||||
{
|
||||
using var movement = new RuntimeLocalPlayerMovementState();
|
||||
var input = new MovementInput(
|
||||
Forward: true,
|
||||
Run: true);
|
||||
|
||||
Assert.True(movement.Execute(RuntimeMovementCommand.ToggleRunLock));
|
||||
movement.SetCommandInput(input);
|
||||
Assert.True(movement.AutoRunActive);
|
||||
Assert.True(movement.View.Snapshot.AutoRunActive);
|
||||
Assert.True(movement.HasCommandInput);
|
||||
Assert.Equal(input, movement.CommandInput);
|
||||
Assert.Equal(input, movement.View.Snapshot.CommandInput);
|
||||
|
||||
Assert.True(movement.Execute(RuntimeMovementCommand.Stop));
|
||||
Assert.False(movement.AutoRunActive);
|
||||
Assert.False(movement.View.Snapshot.AutoRunActive);
|
||||
Assert.False(movement.HasCommandInput);
|
||||
Assert.False(movement.View.Snapshot.HasCommandInput);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CommandInputIsDeduplicatedAndResetWithSessionIntent()
|
||||
{
|
||||
using var movement = new RuntimeLocalPlayerMovementState();
|
||||
var input = new MovementInput(
|
||||
StrafeLeft: true,
|
||||
Run: true);
|
||||
|
||||
movement.SetCommandInput(input);
|
||||
long revision = movement.Revision;
|
||||
movement.SetCommandInput(input);
|
||||
|
||||
Assert.Equal(revision, movement.Revision);
|
||||
Assert.True(movement.Snapshot.HasCommandInput);
|
||||
|
||||
movement.ResetInputIntent();
|
||||
|
||||
Assert.False(movement.HasCommandInput);
|
||||
Assert.Equal(default, movement.CommandInput);
|
||||
Assert.Equal(revision + 1, movement.Revision);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(RuntimeMovementCommand.Ready, MotionCommand.Ready)]
|
||||
[InlineData(RuntimeMovementCommand.Crouch, MotionCommand.Crouch)]
|
||||
[InlineData(RuntimeMovementCommand.Sit, MotionCommand.Sitting)]
|
||||
[InlineData(RuntimeMovementCommand.Sleep, MotionCommand.Sleeping)]
|
||||
public void StanceCommandsUseCanonicalControllerAndEmitOneMovementEdge(
|
||||
RuntimeMovementCommand command,
|
||||
uint expectedMotion)
|
||||
{
|
||||
var controller = new PlayerMovementController(new PhysicsEngine());
|
||||
using var movement = new RuntimeLocalPlayerMovementState
|
||||
{
|
||||
Controller = controller,
|
||||
};
|
||||
movement.SetCommandInput(
|
||||
new MovementInput(Forward: true, Run: true));
|
||||
|
||||
Assert.True(movement.Execute(command));
|
||||
Assert.False(movement.HasCommandInput);
|
||||
Assert.Equal(
|
||||
expectedMotion,
|
||||
controller.Motion.RawState.ForwardCommand);
|
||||
|
||||
MovementResult first = controller.Update(
|
||||
1f / 60f,
|
||||
default);
|
||||
MovementResult second = controller.Update(
|
||||
1f / 60f,
|
||||
default);
|
||||
|
||||
Assert.True(first.ShouldSendMovementEvent);
|
||||
Assert.False(second.ShouldSendMovementEvent);
|
||||
if (command == RuntimeMovementCommand.Ready)
|
||||
{
|
||||
Assert.Null(first.ForwardCommand);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(expectedMotion, first.ForwardCommand);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue