fix(anim): Phase L.1b route motion commands
This commit is contained in:
parent
1c69670392
commit
460f95cb42
6 changed files with 218 additions and 53 deletions
|
|
@ -0,0 +1,66 @@
|
|||
using AcDream.Core.Physics;
|
||||
using DatReaderWriter.DBObjs;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.Core.Tests.Physics;
|
||||
|
||||
public sealed class AnimationCommandRouterTests
|
||||
{
|
||||
private const uint NonCombat = 0x8000003Du;
|
||||
|
||||
[Theory]
|
||||
[InlineData(0x00000000u, AnimationCommandRouteKind.None)]
|
||||
[InlineData(0x10000057u, AnimationCommandRouteKind.Action)] // Sanctuary
|
||||
[InlineData(0x2500003Bu, AnimationCommandRouteKind.Modifier)] // Jump
|
||||
[InlineData(0x13000087u, AnimationCommandRouteKind.ChatEmote)] // Wave
|
||||
[InlineData(0x41000003u, AnimationCommandRouteKind.SubState)] // Ready
|
||||
[InlineData(0x40000011u, AnimationCommandRouteKind.SubState)] // Dead
|
||||
[InlineData(0x8000003Du, AnimationCommandRouteKind.Ignored)] // NonCombat style
|
||||
public void Classify_ReturnsRetailRouteKind(uint command, AnimationCommandRouteKind expected)
|
||||
{
|
||||
Assert.Equal(expected, AnimationCommandRouter.Classify(command));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RouteWireCommand_SubState_UsesSetCycle()
|
||||
{
|
||||
var seq = MakeEmptySequencer();
|
||||
|
||||
var route = AnimationCommandRouter.RouteWireCommand(seq, NonCombat, 0x0011);
|
||||
|
||||
Assert.Equal(AnimationCommandRouteKind.SubState, route);
|
||||
Assert.Equal(NonCombat, seq.CurrentStyle);
|
||||
Assert.Equal(MotionCommand.Dead, seq.CurrentMotion);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RouteWireCommand_Sanctuary_IsActionNotDeadCycle()
|
||||
{
|
||||
var seq = MakeEmptySequencer();
|
||||
|
||||
var route = AnimationCommandRouter.RouteWireCommand(seq, NonCombat, 0x0057);
|
||||
|
||||
Assert.Equal(AnimationCommandRouteKind.Action, route);
|
||||
Assert.Equal(0u, seq.CurrentMotion);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RouteWireCommand_Wave_IsChatEmote()
|
||||
{
|
||||
var seq = MakeEmptySequencer();
|
||||
|
||||
var route = AnimationCommandRouter.RouteWireCommand(seq, NonCombat, 0x0087);
|
||||
|
||||
Assert.Equal(AnimationCommandRouteKind.ChatEmote, route);
|
||||
}
|
||||
|
||||
private static AnimationSequencer MakeEmptySequencer()
|
||||
{
|
||||
return new AnimationSequencer(new Setup(), new MotionTable(), new NullAnimationLoader());
|
||||
}
|
||||
|
||||
private sealed class NullAnimationLoader : IAnimationLoader
|
||||
{
|
||||
public Animation? LoadAnimation(uint id) => null;
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,10 @@ public class MotionCommandResolverTests
|
|||
[InlineData(0x000E, 0x6500000Eu)] // TurnLeft
|
||||
[InlineData(0x000F, 0x6500000Fu)] // SideStepRight
|
||||
[InlineData(0x0015, 0x40000015u)] // Falling
|
||||
[InlineData(0x0011, 0x40000011u)] // Dead
|
||||
[InlineData(0x0012, 0x41000012u)] // Crouch
|
||||
[InlineData(0x0013, 0x41000013u)] // Sitting
|
||||
[InlineData(0x0014, 0x41000014u)] // Sleeping
|
||||
// Action-class one-shots: melee attacks, death, portals
|
||||
[InlineData(0x0057, 0x10000057u)] // Sanctuary (death)
|
||||
[InlineData(0x0058, 0x10000058u)] // ThrustMed
|
||||
|
|
|
|||
|
|
@ -685,6 +685,33 @@ public sealed class MotionInterpreterTests
|
|||
Assert.False(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ContactAllowsMove_DeadState_RejectsMove()
|
||||
{
|
||||
var body = MakeGrounded();
|
||||
var interp = MakeInterp(body);
|
||||
interp.InterpretedState.ForwardCommand = MotionCommand.Dead;
|
||||
|
||||
bool allowed = interp.contact_allows_move(MotionCommand.WalkForward);
|
||||
|
||||
Assert.False(allowed);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(MotionCommand.Crouch)]
|
||||
[InlineData(MotionCommand.Sitting)]
|
||||
[InlineData(MotionCommand.Sleeping)]
|
||||
public void ContactAllowsMove_PostureState_RejectsMove(uint postureCommand)
|
||||
{
|
||||
var body = MakeGrounded();
|
||||
var interp = MakeInterp(body);
|
||||
interp.InterpretedState.ForwardCommand = postureCommand;
|
||||
|
||||
bool allowed = interp.contact_allows_move(MotionCommand.WalkForward);
|
||||
|
||||
Assert.False(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ContactAllowsMove_CrouchRange_RejectsMove()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue