mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
fix: improve pathfinding execution for climbing and block classification
- Fix MoveHelper.CanWalkThrough to treat climbable blocks (ladders, vines) as passable, not solid -- MCC's IsSolid() incorrectly classifies them - Fix MoveHelper.CanWalkOn to exclude climbable blocks from ground check - Add fence gate passability in MoveHelper - Fix start position calculation in MoveToAStar to handle solid-block floor rounding (player at y=79.9 → floor y=79 inside solid) - Fix ReachedWaypoint to require vertical proximity for climb waypoints, preventing premature waypoint consumption during ladder ascent - Fix SetInputToward to handle ladder climbing with Jump input and proper wall-facing when OnClimbable Made-with: Cursor
This commit is contained in:
parent
77c5f88168
commit
a6261e4019
2 changed files with 76 additions and 3 deletions
|
|
@ -1730,11 +1730,20 @@ namespace MinecraftClient
|
|||
int sx = (int)Math.Floor(location.X);
|
||||
int sy = (int)Math.Floor(location.Y);
|
||||
int sz = (int)Math.Floor(location.Z);
|
||||
|
||||
// If floored Y lands inside a solid block (e.g. player on top of it), step up
|
||||
if (!ctx.CanWalkThrough(sx, sy, sz) && ctx.CanWalkThrough(sx, sy + 1, sz))
|
||||
sy++;
|
||||
|
||||
int gx = (int)Math.Floor(goal.X);
|
||||
int gy = (int)Math.Floor(goal.Y);
|
||||
int gz = (int)Math.Floor(goal.Z);
|
||||
|
||||
Log.Info($"[Goto] A* search from ({sx},{sy},{sz}) to ({gx},{gy},{gz})...");
|
||||
if (!ctx.CanWalkThrough(gx, gy, gz) && ctx.CanWalkThrough(gx, gy + 1, gz))
|
||||
gy++;
|
||||
|
||||
Log.Info($"[Goto] A* search from ({sx},{sy},{sz}) to ({gx},{gy},{gz}) " +
|
||||
$"[raw pos=({location.X:F2},{location.Y:F2},{location.Z:F2})]");
|
||||
|
||||
using var cts = new CancellationTokenSource();
|
||||
var result = finder.Calculate(ctx, sx, sy, sz,
|
||||
|
|
@ -3293,12 +3302,20 @@ namespace MinecraftClient
|
|||
|
||||
/// <summary>
|
||||
/// Check if the player has approximately reached a waypoint.
|
||||
/// Uses both horizontal and vertical distance for climb/descend waypoints.
|
||||
/// </summary>
|
||||
private bool ReachedWaypoint(Location target)
|
||||
{
|
||||
double dx = target.X - location.X;
|
||||
double dz = target.Z - location.Z;
|
||||
return dx * dx + dz * dz < 0.25; // within ~0.5 blocks horizontally
|
||||
double dy = target.Y - location.Y;
|
||||
double horizDistSq = dx * dx + dz * dz;
|
||||
|
||||
// Vertical waypoint (climbing/falling): require reaching target Y level
|
||||
if (horizDistSq < 0.5 && Math.Abs(dy) > 0.8)
|
||||
return false;
|
||||
|
||||
return horizDistSq < 0.25 && Math.Abs(dy) < 0.8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -3312,7 +3329,41 @@ namespace MinecraftClient
|
|||
double dy = target.Y - location.Y;
|
||||
double distSqr = dx * dx + dz * dz;
|
||||
|
||||
if (distSqr < 0.01) return; // Close enough horizontally
|
||||
// Climbing: target is above/below with small horizontal offset
|
||||
if (playerPhysics.OnClimbable && Math.Abs(dy) > 0.5 && distSqr < 1.0)
|
||||
{
|
||||
if (dy > 0)
|
||||
{
|
||||
physicsInput.Jump = true;
|
||||
// Push against the wall for HorizontalCollision-triggered climbing
|
||||
if (distSqr > 0.01)
|
||||
{
|
||||
float yaw = (float)(-Math.Atan2(dx, dz) / Math.PI * 180.0);
|
||||
if (yaw < 0) yaw += 360;
|
||||
playerPhysics.Yaw = yaw;
|
||||
playerYaw = yaw;
|
||||
physicsInput.Forward = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
physicsInput.Forward = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
physicsInput.Sneak = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Non-climbing vertical jump
|
||||
if (distSqr < 0.1 && dy > 0.5 && playerPhysics.OnGround)
|
||||
{
|
||||
physicsInput.Jump = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distSqr < 0.01) return;
|
||||
|
||||
// Calculate yaw to face target
|
||||
float targetYaw = (float)(-Math.Atan2(dx, dz) / Math.PI * 180.0);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ namespace MinecraftClient.Pathing.Moves
|
|||
return true;
|
||||
if (mat.IsLiquid())
|
||||
return false;
|
||||
if (mat.CanBeClimbedOn())
|
||||
return true;
|
||||
if (IsOpenGate(mat))
|
||||
return true;
|
||||
if (mat.IsSolid())
|
||||
return false;
|
||||
if (mat.CanHarmPlayers())
|
||||
|
|
@ -38,6 +42,10 @@ namespace MinecraftClient.Pathing.Moves
|
|||
return false;
|
||||
if (mat.CanHarmPlayers())
|
||||
return false;
|
||||
if (mat.CanBeClimbedOn())
|
||||
return false;
|
||||
if (IsOpenGate(mat))
|
||||
return false;
|
||||
return mat.IsSolid();
|
||||
}
|
||||
|
||||
|
|
@ -65,5 +73,19 @@ namespace MinecraftClient.Pathing.Moves
|
|||
{
|
||||
return mat == Material.Water;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conservative check for gate-type blocks. Since we cannot read block state
|
||||
/// (open/closed) during planning, treat all fence gates as passable.
|
||||
/// </summary>
|
||||
private static bool IsOpenGate(Material mat)
|
||||
{
|
||||
return mat is Material.AcaciaFenceGate or Material.BirchFenceGate
|
||||
or Material.CrimsonFenceGate or Material.DarkOakFenceGate
|
||||
or Material.JungleFenceGate or Material.MangroveWood
|
||||
or Material.OakFenceGate or Material.SpruceFenceGate
|
||||
or Material.WarpedFenceGate or Material.CherryFenceGate
|
||||
or Material.BambooFenceGate or Material.PaleOakFenceGate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue