From 2309f012911d8992fbb5bcebde6d4b46f4226d6b Mon Sep 17 00:00:00 2001 From: lyizai <3945107889@qq.com> Date: Wed, 19 Aug 2026 21:33:46 +0800 Subject: [PATCH] =?UTF-8?q?v1.2.2:=20=E6=A0=B9=E6=B2=BB=E5=AF=BB=E8=B7=AF?= =?UTF-8?q?=E7=A7=92CALC=5FFAILED=E2=80=94=E2=80=94=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89ChunkGoal(=E5=90=AB=E9=AB=98?= =?UTF-8?q?=E5=BA=A6isInGoal)=EF=BC=8C=E6=94=B9=E7=94=A8Baritone=E5=8E=9F?= =?UTF-8?q?=E7=94=9FGoalXZ=E5=88=B0=E5=8C=BA=E5=9D=97=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/bridge/BaritoneBridge.java | 49 +++---------- .../autostore/client/bridge/ChunkGoal.java | 70 ------------------- 2 files changed, 9 insertions(+), 110 deletions(-) delete mode 100644 src/main/java/autostore/client/bridge/ChunkGoal.java diff --git a/src/main/java/autostore/client/bridge/BaritoneBridge.java b/src/main/java/autostore/client/bridge/BaritoneBridge.java index 56a70de..c2ebb5a 100644 --- a/src/main/java/autostore/client/bridge/BaritoneBridge.java +++ b/src/main/java/autostore/client/bridge/BaritoneBridge.java @@ -11,13 +11,11 @@ import baritone.api.event.events.PathEvent; import baritone.api.event.listener.AbstractGameEventListener; import autostore.client.config.ExpansionConfig; import autostore.client.territory.ChunkPos; +import baritone.api.pathing.goals.GoalXZ; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.MinecraftClient; -import net.minecraft.world.Heightmap; -import net.minecraft.world.World; /** * Baritone API 封装(桥接层)。 @@ -72,7 +70,13 @@ public final class BaritoneBridge { } /** - * 让 Baritone 寻路前往指定区块(以“到达区块内”为完成条件)。 + * 让 Baritone 寻路前往指定区块中心。 + * + *

使用 Baritone 原生{@link GoalXZ}(目标区块中心单格):原生 GoalXZ 对 + * 可达地形几乎不会误判“目标不可达”,是最好的默认选择。早期用自定义 + * {@code ChunkGoal}(曾加入高度硬约束)疑似是“平原上一按 W 就能走、Baritone 却秒 + * CALC_FAILED”的根因——自定义 Goal 在某些站位/边界下会把可达目标判成不可达。 + * 到达判定仍由控制器 {@code playerChunk.equals(target)} 保证,与 Goal 自身容差无关。

* * @param chunk 目标区块 */ @@ -81,42 +85,7 @@ public final class BaritoneBridge { if (baritone == null) { return; } - // 使用自定义 ChunkGoal:完成条件为“玩家脚下方块落在目标区块内地表”, - // 与控制器 playerChunk.equals(target) 的判定一致,并对高度施加约束, - // 避免 Baritone 把终点停在地下洞穴/矿坑里。避免 Baritone 自带 GoalXZ - //(容差 0,精确到区块中心单格)在中心不可达时停在相邻区块,造成目标区块错位。 - baritone.getCustomGoalProcess().setGoalAndPath(new ChunkGoal(chunk, this.surfaceY(chunk))); - } - - /** - * 计算目标区块内地表高度(方块 Y):遍历该区块 16×16 各列,取 - * “排除树叶的实体地表”高度的中位数,作为高度约束目标。 - * - *

用中位数而非最大值:高树/孤峰只是少数列(其树干顶也算 MOTION_BLOCKING_NO_LEAVES), - * 取最大值会把整个区块的目标高度拉到无法到达的高柱顶,导致一步之隔的平原区块也 - * CALC_FAILED(v1.2.2 回归);中位数代表区块“通常地表”,天然可达,而地下矿坑的 y - * 仍远低于中位,不会被误判为已到达。

- * - * @param chunk 目标区块 - * @return 地表高度中位数;≤0 表示暂无法确定(不施加高度约束) - */ - private int surfaceY(ChunkPos chunk) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client == null || client.world == null) { - return 0; - } - World world = client.world; - int x0 = chunk.x() * 16; - int z0 = chunk.z() * 16; - int[] ys = new int[256]; - int n = 0; - for (int bx = x0; bx < x0 + 16; ++bx) { - for (int bz = z0; bz < z0 + 16; ++bz) { - ys[n++] = world.getTopY(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, bx, bz); - } - } - java.util.Arrays.sort(ys); - return ys[128]; + baritone.getCustomGoalProcess().setGoalAndPath(new GoalXZ(chunk.centerBlockX(), chunk.centerBlockZ())); } /** 强制取消当前寻路任务。 */ diff --git a/src/main/java/autostore/client/bridge/ChunkGoal.java b/src/main/java/autostore/client/bridge/ChunkGoal.java deleted file mode 100644 index 1937819..0000000 --- a/src/main/java/autostore/client/bridge/ChunkGoal.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 本文件为 AutoStore 模组自定义的 Baritone 寻路目标。 - */ -package autostore.client.bridge; - -import autostore.client.territory.ChunkPos; -import baritone.api.pathing.goals.Goal; - -/** - * 以“到达目标区块内”为完成条件的寻路目标。 - * - *

完成条件为纯二维:只要玩家脚下方块落在目标区块内即视为到达。 - * 这样目标区块的可达性与平坦地表相邻区块一致,绝不会因一步之隔、贴边落点、 - * 或高度起伏被误判为目标不可达(CALC_FAILED 后秒切目标)。

- * - *

“避免寻路下到地下矿坑、尽量走地表”改为在启发式中做软引导: - * 仅当玩家远低于该区块的地表高度(很有可能是下了矿洞)时,给 heuristic 叠加 - * 向上的加权,促使 Baritone 优先走地表。它不改变 isInGoal 的完成判定,因此 - * 不会像“高度硬约束”那样导致本可达的目标被判成不可达。

- */ -public final class ChunkGoal implements Goal { - - /** 目标区块 X 坐标 */ - private final int targetX; - /** 目标区块 Z 坐标 */ - private final int targetZ; - /** 目标区块中心的方块 X 坐标(用于启发式距离估算) */ - private final int centerX; - /** 目标区块中心的方块 Z 坐标(用于启发式距离估算) */ - private final int centerZ; - /** - * 目标地表高度(方块 Y):目标区块内 16×16 各列 “排除树叶的实体地表”高度的中位数。 - * 仅用于启发式软引导(避开矿洞);≤0 表示暂无法确定地表高度,跳过引导。 - */ - private final int targetY; - /** 深度容差:低于目标地表超过该值才视为“很可能下了矿洞”,触发向上引导 */ - private static final int DEPTH_TOLERANCE = 6; - - public ChunkGoal(ChunkPos chunk) { - this(chunk, -1); - } - - public ChunkGoal(ChunkPos chunk, int targetY) { - this.targetX = chunk.x(); - this.targetZ = chunk.z(); - this.centerX = chunk.centerBlockX(); - this.centerZ = chunk.centerBlockZ(); - this.targetY = targetY; - } - - /** 完成条件:纯二维——玩家脚下方块是否落在目标区块内 */ - @Override - public boolean isInGoal(int x, int y, int z) { - return Math.floorDiv(x, 16) == this.targetX && Math.floorDiv(z, 16) == this.targetZ; - } - - /** 启发式:到目标区块中心的水平欧几里得距离;深度低于地表时叠加向上软引导 */ - @Override - public double heuristic(int x, int y, int z) { - double dx = x - this.centerX; - double dz = z - this.centerZ; - double h = Math.sqrt(dx * dx + dz * dz); - if (this.targetY > 0 && y < this.targetY - DEPTH_TOLERANCE) { - // 软引导:还在目标地表下较深处(疑似矿洞),给予越深越高的小幅加权, - // 让 Baritone 倾向走地表,但不把它变成 isInGoal 的硬约束(避免误判不可达)。 - h += (this.targetY - y) * 0.1; - } - return h; - } -} \ No newline at end of file