v1.2.2: 根治寻路秒CALC_FAILED——删除自定义ChunkGoal(含高度isInGoal),改用Baritone原生GoalXZ到区块中心

这个提交包含在:
lyizai
2026-08-19 21:33:46 +08:00
父节点 3cddee2abb
当前提交 2309f01291
共修改 2 个文件,包含 9 行新增和 110 行删除
@@ -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 寻路前往指定区块中心。
*
* <p>使用 Baritone <b>原生</b>{@link GoalXZ}(目标区块中心单格):原生 GoalXZ 对
* 可达地形几乎不会误判“目标不可达”,是最好的默认选择。早期用自定义
* {@code ChunkGoal}(曾加入高度硬约束)疑似是“平原上一按 W 就能走、Baritone 却秒
* CALC_FAILED”的根因——自定义 Goal 在某些站位/边界下会把可达目标判成不可达。
* 到达判定仍由控制器 {@code playerChunk.equals(target)} 保证,与 Goal 自身容差无关。</p>
*
* @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 各列,取
* “排除树叶的实体地表”高度的<b>中位数</b>,作为高度约束目标。
*
* <p>用中位数而非最大值:高树/孤峰只是少数列(其树干顶也算 MOTION_BLOCKING_NO_LEAVES),
* 取最大值会把整个区块的目标高度拉到无法到达的高柱顶,导致一步之隔的平原区块也
* CALC_FAILED(v1.2.2 回归);中位数代表区块“通常地表”,天然可达,而地下矿坑的 y
* 仍远低于中位,不会被误判为已到达。</p>
*
* @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()));
}
/** 强制取消当前寻路任务。 */