mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
feat: add corner walk, sprint descend, and parkour descend moves
- MoveDiagonal: allow single-side-blocked diagonals (corner walk) so the bot can hug an open side to cut around a wall; both-sides-blocked remains impossible. Walk-speed cost when one side is blocked. - MoveSprintDescend: sprint off a ledge covering 2 horizontal blocks while dropping 1-3 blocks. Registered for cardinal and diagonal offsets. - MoveParkour: support negative yDelta (-1, -2) for descending parkour where the bot sprint-jumps across a gap and lands on a lower platform. Registered cardinal (dist 2-4, y-1/-2) and diagonal variants. - DescendTemplate: sprint when horizontal distance > 1.5 blocks. - SprintJumpTemplate: increase vertical landing tolerance for descend. Made-with: Cursor
This commit is contained in:
parent
285c3000c3
commit
9e6b689dd6
6 changed files with 183 additions and 11 deletions
|
|
@ -59,6 +59,16 @@ namespace MinecraftClient.Pathing.Core
|
|||
|
||||
moves.Add(new MoveFall());
|
||||
|
||||
// Sprint descend: sprint off ledge, 2 blocks horizontal + 1-3 drop
|
||||
foreach (int dx in offsets)
|
||||
{
|
||||
moves.Add(new MoveSprintDescend(dx * 2, 0));
|
||||
moves.Add(new MoveSprintDescend(dx, dx));
|
||||
moves.Add(new MoveSprintDescend(dx, -dx));
|
||||
}
|
||||
foreach (int dz in offsets)
|
||||
moves.Add(new MoveSprintDescend(0, dz * 2));
|
||||
|
||||
// Cardinal parkour: 2-4 block sprint jumps along +-X and +-Z
|
||||
foreach (int dx in offsets)
|
||||
{
|
||||
|
|
@ -67,6 +77,13 @@ namespace MinecraftClient.Pathing.Core
|
|||
// Ascending: +1Y, dist 2-3 (dist 4 ascend not physically reliable)
|
||||
for (int dist = 2; dist <= 3; dist++)
|
||||
moves.Add(new MoveParkour(dx * dist, 0, yDelta: 1));
|
||||
// Descending parkour: sprint-jump, land 1-2 blocks lower
|
||||
for (int dist = 2; dist <= 4; dist++)
|
||||
{
|
||||
moves.Add(new MoveParkour(dx * dist, 0, yDelta: -1));
|
||||
if (dist <= 3)
|
||||
moves.Add(new MoveParkour(dx * dist, 0, yDelta: -2));
|
||||
}
|
||||
}
|
||||
foreach (int dz in offsets)
|
||||
{
|
||||
|
|
@ -74,6 +91,12 @@ namespace MinecraftClient.Pathing.Core
|
|||
moves.Add(new MoveParkour(0, dz * dist));
|
||||
for (int dist = 2; dist <= 3; dist++)
|
||||
moves.Add(new MoveParkour(0, dz * dist, yDelta: 1));
|
||||
for (int dist = 2; dist <= 4; dist++)
|
||||
{
|
||||
moves.Add(new MoveParkour(0, dz * dist, yDelta: -1));
|
||||
if (dist <= 3)
|
||||
moves.Add(new MoveParkour(0, dz * dist, yDelta: -2));
|
||||
}
|
||||
}
|
||||
|
||||
// Diagonal parkour: sprint jumps at angles.
|
||||
|
|
@ -90,6 +113,11 @@ namespace MinecraftClient.Pathing.Core
|
|||
// (3,1)/(1,3): sqrt(10) ~ 3.16 blocks
|
||||
moves.Add(new MoveParkour(dx * 3, dz * 1));
|
||||
moves.Add(new MoveParkour(dx * 1, dz * 3));
|
||||
|
||||
// Diagonal descending parkour
|
||||
moves.Add(new MoveParkour(dx * 2, dz * 1, yDelta: -1));
|
||||
moves.Add(new MoveParkour(dx * 1, dz * 2, yDelta: -1));
|
||||
moves.Add(new MoveParkour(dx * 2, dz * 2, yDelta: -1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace MinecraftClient.Pathing.Execution.Templates
|
|||
/// <summary>
|
||||
/// Walk off a ledge and drop 1-N blocks to a landing spot.
|
||||
/// Walks toward the destination; gravity handles the fall.
|
||||
/// Sprints when the horizontal distance is large (> 1.5 blocks).
|
||||
/// Supports solid landings, water landings, and mid-fall vine/ladder grabs.
|
||||
/// </summary>
|
||||
public sealed class DescendTemplate : IActionTemplate
|
||||
|
|
@ -16,11 +17,15 @@ namespace MinecraftClient.Pathing.Execution.Templates
|
|||
|
||||
private int _tickCount;
|
||||
private bool _hasFallen;
|
||||
private readonly bool _needsSprint;
|
||||
|
||||
public DescendTemplate(Location start, Location end)
|
||||
{
|
||||
ExpectedStart = start;
|
||||
ExpectedEnd = end;
|
||||
double hdx = end.X - start.X;
|
||||
double hdz = end.Z - start.Z;
|
||||
_needsSprint = (hdx * hdx + hdz * hdz) > 2.25;
|
||||
}
|
||||
|
||||
public TemplateState Tick(Location pos, PlayerPhysics physics, MovementInput input)
|
||||
|
|
@ -70,6 +75,8 @@ namespace MinecraftClient.Pathing.Execution.Templates
|
|||
{
|
||||
physics.Yaw = TemplateHelper.SmoothYaw(physics.Yaw, targetYaw);
|
||||
input.Forward = true;
|
||||
if (_needsSprint)
|
||||
input.Sprint = true;
|
||||
}
|
||||
|
||||
return TemplateState.InProgress;
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ namespace MinecraftClient.Pathing.Execution.Templates
|
|||
goto case Phase.Landing;
|
||||
|
||||
case Phase.Landing:
|
||||
// Tolerance scales with jump distance
|
||||
double horizTolerance = _horizDist >= 3.5 ? 3.0 : 2.0;
|
||||
if (horizDistSq < horizTolerance && Math.Abs(dy) < 1.0)
|
||||
double vertTolerance = Math.Abs(ExpectedEnd.Y - ExpectedStart.Y) > 0.5 ? 1.5 : 1.0;
|
||||
if (horizDistSq < horizTolerance && Math.Abs(dy) < vertTolerance)
|
||||
return TemplateState.Complete;
|
||||
return TemplateState.Failed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ namespace MinecraftClient.Pathing.Moves.Impl
|
|||
{
|
||||
/// <summary>
|
||||
/// Diagonal walk (1 block in both X and Z, same Y).
|
||||
/// Checks both intermediate cardinal columns for clearance.
|
||||
/// Allows corner walks: if one intermediate cardinal is blocked by a wall
|
||||
/// but the other is clear, the player can hug the open side to cut the
|
||||
/// corner. Both sides blocked is impossible (player AABB too wide).
|
||||
/// </summary>
|
||||
public sealed class MoveDiagonal : IMove
|
||||
{
|
||||
|
|
@ -36,19 +38,22 @@ namespace MinecraftClient.Pathing.Moves.Impl
|
|||
return;
|
||||
}
|
||||
|
||||
if (!ctx.CanWalkThrough(x + XOffset, y, z) || !ctx.CanWalkThrough(x + XOffset, y + 1, z))
|
||||
bool sideX = ctx.CanWalkThrough(x + XOffset, y, z) &&
|
||||
ctx.CanWalkThrough(x + XOffset, y + 1, z);
|
||||
bool sideZ = ctx.CanWalkThrough(x, y, z + ZOffset) &&
|
||||
ctx.CanWalkThrough(x, y + 1, z + ZOffset);
|
||||
|
||||
if (!sideX && !sideZ)
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ctx.CanWalkThrough(x, y, z + ZOffset) || !ctx.CanWalkThrough(x, y + 1, z + ZOffset))
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
double cost = ctx.SprintCost * ActionCosts.DiagonalMultiplier;
|
||||
if (!sideX || !sideZ)
|
||||
cost = ctx.WalkCost * ActionCosts.DiagonalMultiplier;
|
||||
|
||||
result.Set(destX, y, destZ, ctx.SprintCost * ActionCosts.DiagonalMultiplier);
|
||||
result.Set(destX, y, destZ, cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ namespace MinecraftClient.Pathing.Moves.Impl
|
|||
{
|
||||
/// <summary>
|
||||
/// Sprint jump across a gap in cardinal or diagonal direction.
|
||||
/// Supports horizontal distances of 2-4 blocks and optional +1Y ascent.
|
||||
/// Supports horizontal distances of 2-4 blocks, optional +1Y ascent,
|
||||
/// and -1/-2Y descent (land on a lower platform after the jump).
|
||||
/// Based on Baritone's MovementParkour design with diagonal extensions.
|
||||
/// </summary>
|
||||
public sealed class MoveParkour : IMove
|
||||
|
|
@ -44,6 +45,12 @@ namespace MinecraftClient.Pathing.Moves.Impl
|
|||
return;
|
||||
}
|
||||
|
||||
if (_yDelta < 0 && -_yDelta > ctx.MaxFallHeight)
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ctx.CanSprint)
|
||||
{
|
||||
result.SetImpossible();
|
||||
|
|
@ -172,6 +179,9 @@ namespace MinecraftClient.Pathing.Moves.Impl
|
|||
double cost;
|
||||
if (_yDelta > 0)
|
||||
cost = horizDist * ctx.SprintCost + ctx.JumpPenalty * 2;
|
||||
else if (_yDelta < 0)
|
||||
cost = horizDist * ctx.SprintCost + ctx.JumpPenalty
|
||||
+ ActionCosts.FallCost(-_yDelta);
|
||||
else if (horizDist >= 3.5)
|
||||
cost = horizDist * ctx.SprintCost + ctx.JumpPenalty;
|
||||
else
|
||||
|
|
|
|||
122
MinecraftClient/Pathing/Moves/Impl/MoveSprintDescend.cs
Normal file
122
MinecraftClient/Pathing/Moves/Impl/MoveSprintDescend.cs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using MinecraftClient.Mapping;
|
||||
using MinecraftClient.Pathing.Core;
|
||||
|
||||
namespace MinecraftClient.Pathing.Moves.Impl
|
||||
{
|
||||
/// <summary>
|
||||
/// Sprint off a ledge and land 2 blocks away horizontally while dropping 1-3 blocks.
|
||||
/// At sprint speed (~5.6 blocks/s), falling 1-3 blocks gives enough airtime to
|
||||
/// cover 2 horizontal blocks without needing a jump.
|
||||
/// Supports cardinal (2,0)/(0,2) and diagonal (1,1) offsets.
|
||||
/// </summary>
|
||||
public sealed class MoveSprintDescend : IMove
|
||||
{
|
||||
public MoveType Type => MoveType.Descend;
|
||||
public int XOffset { get; }
|
||||
public int ZOffset { get; }
|
||||
public bool DynamicY => true;
|
||||
|
||||
public MoveSprintDescend(int xOffset, int zOffset)
|
||||
{
|
||||
XOffset = xOffset;
|
||||
ZOffset = zOffset;
|
||||
}
|
||||
|
||||
public void Calculate(CalculationContext ctx, int x, int y, int z, ref MoveResult result)
|
||||
{
|
||||
if (!ctx.CanSprint)
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
|
||||
int destX = x + XOffset;
|
||||
int destZ = z + ZOffset;
|
||||
|
||||
Material fromDown = ctx.GetMaterial(x, y - 1, z);
|
||||
if (fromDown.CanBeClimbedOn())
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
|
||||
int xSign = Math.Sign(XOffset);
|
||||
int zSign = Math.Sign(ZOffset);
|
||||
int xAbs = Math.Abs(XOffset);
|
||||
int zAbs = Math.Abs(ZOffset);
|
||||
|
||||
// The flight path sweeps through intermediate blocks at current Y.
|
||||
// Check body clearance for all intermediate and destination columns.
|
||||
for (int i = 0; i <= xAbs; i++)
|
||||
{
|
||||
for (int j = 0; j <= zAbs; j++)
|
||||
{
|
||||
if (i == 0 && j == 0) continue;
|
||||
int gx = x + xSign * i;
|
||||
int gz = z + zSign * j;
|
||||
if (!ctx.CanWalkThrough(gx, y, gz) || !ctx.CanWalkThrough(gx, y + 1, gz))
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The first step in the primary direction must lack ground (this IS a drop).
|
||||
if (xAbs > 0 && zAbs == 0)
|
||||
{
|
||||
if (ctx.CanWalkOn(x + xSign, y - 1, z))
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (xAbs == 0 && zAbs > 0)
|
||||
{
|
||||
if (ctx.CanWalkOn(x, y - 1, z + zSign))
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctx.CanWalkOn(x + xSign, y - 1, z + zSign))
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Scan downward from destination column for a landing spot.
|
||||
double horizDist = Math.Sqrt((double)(XOffset * XOffset + ZOffset * ZOffset));
|
||||
for (int drop = 1; drop <= ctx.MaxFallHeight; drop++)
|
||||
{
|
||||
int landY = y - drop - 1;
|
||||
if (landY < -64) break;
|
||||
|
||||
if (!ctx.CanWalkOn(destX, landY, destZ))
|
||||
continue;
|
||||
|
||||
Material landMat = ctx.GetMaterial(destX, landY, destZ);
|
||||
if (MoveHelper.IsHazardous(landMat))
|
||||
{
|
||||
result.SetImpossible();
|
||||
return;
|
||||
}
|
||||
|
||||
// Body space at landing
|
||||
if (!ctx.CanWalkThrough(destX, landY + 1, destZ) ||
|
||||
!ctx.CanWalkThrough(destX, landY + 2, destZ))
|
||||
continue;
|
||||
|
||||
double cost = horizDist * ctx.SprintCost + ActionCosts.FallCost(drop);
|
||||
result.Set(destX, landY + 1, destZ, cost);
|
||||
return;
|
||||
}
|
||||
|
||||
result.SetImpossible();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue