mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Theory simulator: - Add 2D side-wall jump physics with yaw sweep for worst-case margin - Generate sidewall theory cases (flat/ascend/descend, wall_offset 0/1) - Add momentum-capabilities.json with band compression and max_reach - Extend models, capabilities, canonical, and renderers for sidewall Full-coverage parkour test suite (tools/test-parkour.py): - Derive test matrix from momentum-capabilities.json - Build linear/neo/ceiling courses via RCON with 7-block clear margin - Use /goto for pathfinding, parse A* and PathMgr log output - Stop-at-first-failure per (family, subfamily, dy, ceil, wo) group - Hierarchical --filter (e.g. linear/flat, ceiling/headhitter/ceil2.5) - Exclude sidewall from default matrix (identical max_reach to linear) Pathing execution fixes: - Align parkour contracts and timing budgets with live test results - Fix jump-entry yaw snapping for grounded handoffs - Template helper and sprint jump template refinements Made-with: Cursor
93 lines
3 KiB
C#
93 lines
3 KiB
C#
using MinecraftClient.Mapping;
|
|
using MinecraftClient.Pathing.Core;
|
|
using MinecraftClient.Pathing.Moves.Impl;
|
|
using MinecraftClient.Tests.Pathing.Execution;
|
|
using Xunit;
|
|
|
|
namespace MinecraftClient.Tests.Pathing.Moves;
|
|
|
|
public sealed class MoveParkourTests
|
|
{
|
|
private const int FloorY = 79;
|
|
|
|
private static CalculationContext BuildContext(World world)
|
|
=> new(world, allowParkour: true, allowParkourAscend: true);
|
|
|
|
[Fact]
|
|
public void Rejects3x1JumpWhenRunUpMissing()
|
|
{
|
|
var world = FlatWorldTestBuilder.CreateStoneFloor(FloorY);
|
|
world.SetBlock(new Location(-1, FloorY, 0), Block.Air);
|
|
var ctx = BuildContext(world);
|
|
var move = new MoveParkour(3, 0);
|
|
var result = default(MoveResult);
|
|
|
|
move.Calculate(ctx, 0, FloorY + 1, 0, ref result);
|
|
|
|
Assert.True(result.IsImpossible);
|
|
}
|
|
|
|
[Fact]
|
|
public void Accepts2x1GapWithClearTakeoff()
|
|
{
|
|
var world = FlatWorldTestBuilder.CreateStoneFloor(FloorY);
|
|
world.SetBlock(new Location(1, FloorY, 0), Block.Air);
|
|
var ctx = BuildContext(world);
|
|
var move = new MoveParkour(2, 0);
|
|
var result = default(MoveResult);
|
|
|
|
move.Calculate(ctx, 0, FloorY + 1, 0, ref result);
|
|
|
|
Assert.False(result.IsImpossible);
|
|
Assert.Equal(2, result.DestX);
|
|
}
|
|
|
|
[Fact]
|
|
public void Rejects2x1WhenAdjacentBlockIsStillWalkable()
|
|
{
|
|
var world = FlatWorldTestBuilder.CreateStoneFloor(FloorY);
|
|
var ctx = BuildContext(world);
|
|
var move = new MoveParkour(2, 0);
|
|
var result = default(MoveResult);
|
|
|
|
move.Calculate(ctx, 0, FloorY + 1, 0, ref result);
|
|
|
|
Assert.True(result.IsImpossible);
|
|
}
|
|
|
|
[Fact]
|
|
public void Rejects2x1GapWhenSideWallNarrowsLanding()
|
|
{
|
|
var world = FlatWorldTestBuilder.CreateStoneFloor(FloorY);
|
|
FlatWorldTestBuilder.ClearBox(world, -1, FloorY, -2, 4, FloorY + 4, 2);
|
|
FlatWorldTestBuilder.SetSolid(world, 0, FloorY, 0);
|
|
FlatWorldTestBuilder.SetSolid(world, 2, FloorY, 0);
|
|
FlatWorldTestBuilder.SetSolid(world, 1, FloorY + 1, -1);
|
|
FlatWorldTestBuilder.SetSolid(world, 1, FloorY + 2, -1);
|
|
FlatWorldTestBuilder.SetSolid(world, 2, FloorY + 1, -1);
|
|
FlatWorldTestBuilder.SetSolid(world, 2, FloorY + 2, -1);
|
|
|
|
var ctx = BuildContext(world);
|
|
var move = new MoveParkour(2, 0);
|
|
var result = default(MoveResult);
|
|
|
|
move.Calculate(ctx, 0, FloorY + 1, 0, ref result);
|
|
|
|
Assert.True(result.IsImpossible);
|
|
}
|
|
|
|
[Fact]
|
|
public void RejectsDiagonalWhenShoulderBlocked()
|
|
{
|
|
var world = FlatWorldTestBuilder.CreateStoneFloor(FloorY);
|
|
world.SetBlock(new Location(1, FloorY + 1, 0), new Block(1));
|
|
world.SetBlock(new Location(1, FloorY + 2, 0), new Block(1));
|
|
var ctx = BuildContext(world);
|
|
var move = new MoveParkour(1, 1);
|
|
var result = default(MoveResult);
|
|
|
|
move.Calculate(ctx, 0, FloorY + 1, 0, ref result);
|
|
|
|
Assert.True(result.IsImpossible);
|
|
}
|
|
}
|