From aad6ad83d3b8bc0fefbb9fd2830b38df32d2646b Mon Sep 17 00:00:00 2001 From: BruceChen Date: Wed, 15 Apr 2026 16:43:39 +0000 Subject: [PATCH] pathing: snap yaw only for grounded jump-entry walk states --- .../GroundedTemplateConvergenceTests.cs | 55 +++++++++++++++++++ .../Execution/Templates/WalkTemplate.cs | 8 ++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/MinecraftClient.Tests/Pathing/Execution/GroundedTemplateConvergenceTests.cs b/MinecraftClient.Tests/Pathing/Execution/GroundedTemplateConvergenceTests.cs index a9b3fdb5..d3220942 100644 --- a/MinecraftClient.Tests/Pathing/Execution/GroundedTemplateConvergenceTests.cs +++ b/MinecraftClient.Tests/Pathing/Execution/GroundedTemplateConvergenceTests.cs @@ -147,6 +147,61 @@ public sealed class GroundedTemplateConvergenceTests $"state={state} finalPos={finalPos} vel={physics.DeltaMovement}"); } + [Fact] + public void WalkTemplate_PrepareJump_SnapsYawImmediatelyDuringRunUp() + { + World world = FlatWorldTestBuilder.CreateStoneFloor(); + var current = new PathSegment + { + Start = new Location(0.5, 80, 0.5), + End = new Location(1.5, 80, 0.5), + MoveType = MoveType.Traverse, + ExitTransition = PathTransitionType.PrepareJump, + ExitHints = new PathTransitionHints(1, 0, 0.10, double.PositiveInfinity, false, true, true, false, 10), + PreserveSprint = true + }; + var next = new PathSegment + { + Start = new Location(1.5, 80, 0.5), + End = new Location(3.5, 80, 0.5), + MoveType = MoveType.Parkour, + ExitTransition = PathTransitionType.FinalStop + }; + + var template = new WalkTemplate(current, next); + var physics = TemplateSimulationRunner.CreateGroundedPhysics(current.Start, yaw: 90f); + var input = new MovementInput(); + + TemplateState state = template.Tick(current.Start, physics, input, world); + + Assert.Equal(TemplateState.InProgress, state); + Assert.InRange(physics.Yaw, 269.9f, 270.1f); + Assert.True(input.Forward); + Assert.True(input.Sprint); + } + + [Fact] + public void WalkTemplate_FinalStop_RetainsSmoothYawOutsideJumpEntry() + { + World world = FlatWorldTestBuilder.CreateStoneFloor(); + var segment = new PathSegment + { + Start = new Location(0.5, 80, 0.5), + End = new Location(1.5, 80, 0.5), + MoveType = MoveType.Traverse, + ExitTransition = PathTransitionType.FinalStop + }; + + var template = new WalkTemplate(segment, null); + var physics = TemplateSimulationRunner.CreateGroundedPhysics(segment.Start, yaw: 90f); + var input = new MovementInput(); + + TemplateState state = template.Tick(segment.Start, physics, input, world); + + Assert.Equal(TemplateState.InProgress, state); + Assert.InRange(physics.Yaw, 124.9f, 125.1f); + } + [Fact] public void AscendTemplate_DiagonalPrepareJump_WithPlannerHints_CompletesOnRunUpBlock() { diff --git a/MinecraftClient/Pathing/Execution/Templates/WalkTemplate.cs b/MinecraftClient/Pathing/Execution/Templates/WalkTemplate.cs index 1483ca00..098e4f43 100644 --- a/MinecraftClient/Pathing/Execution/Templates/WalkTemplate.cs +++ b/MinecraftClient/Pathing/Execution/Templates/WalkTemplate.cs @@ -35,11 +35,17 @@ namespace MinecraftClient.Pathing.Execution.Templates double dx = ExpectedEnd.X - pos.X; double dz = ExpectedEnd.Z - pos.Z; double dy = ExpectedEnd.Y - pos.Y; + bool snapYawForJumpEntry = physics.OnGround + && _segment.ExitTransition == PathTransitionType.PrepareJump + && _segment.ExitHints.RequireJumpReady; float targetYaw = TemplateHelper.ShouldBiasTowardExitHeading(pos, _segment) ? TemplateHelper.GetExitHeadingYaw(_segment) : TemplateHelper.CalculateYaw(dx, dz); float targetPitch = TemplateHelper.CalculatePitch(dx, dy, dz); - physics.Yaw = TemplateHelper.SmoothYaw(physics.Yaw, targetYaw); + physics.Yaw = TemplateHelper.AlignYaw( + physics.Yaw, + targetYaw, + snapYawForJumpEntry ? YawAlignmentMode.Snap : YawAlignmentMode.Smooth); physics.Pitch = TemplateHelper.SmoothPitch(physics.Pitch, targetPitch); GroundedSegmentController.Apply(_segment, _nextSegment, pos, physics, input, world);