142 行
6.0 KiB
Java
142 行
6.0 KiB
Java
/*
|
|
* 本文件由 autostore-1.0-SNAPSHOT.jar 反编译并整理而来(CFR 0.152),
|
|
* 混淆名已替换为 Minecraft 1.21.4 Yarn 可读映射,并补充中文注释。
|
|
*/
|
|
package autostore.client.bridge;
|
|
|
|
import baritone.api.BaritoneAPI;
|
|
import baritone.api.IBaritone;
|
|
import baritone.api.Settings;
|
|
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;
|
|
|
|
/**
|
|
* Baritone API 封装(桥接层)。
|
|
*
|
|
* <p>将模组对 Baritone 寻路机器人的调用集中在此类中,包括:应用寻路行为配置、
|
|
* 前往目标区块、取消寻路、查询寻路状态等。所有调用都做了空安全保护,
|
|
* 当 Baritone 未加载时相关操作会安全地静默失败。</p>
|
|
*/
|
|
@Environment(EnvType.CLIENT)
|
|
public final class BaritoneBridge {
|
|
|
|
/**
|
|
* 寻路事件回调:用于把 Baritone 的路径事件(如计算失败、到达目标)转发给控制器,
|
|
* 使控制器能及时识别“目标不可达”并跳过,而不是傻等到超时。
|
|
*/
|
|
public interface PathListener {
|
|
void onPathEvent(PathEvent event);
|
|
}
|
|
|
|
/** 已注册的路径事件监听器集合(线程安全) */
|
|
private final Set<PathListener> pathListeners = ConcurrentHashMap.newKeySet();
|
|
/** 是否已向 Baritone 注册事件监听器(只注册一次) */
|
|
private volatile boolean eventListenerRegistered;
|
|
|
|
/** 注册一个路径事件监听器;同时确保已向 Baritone 事件总线挂载转发器 */
|
|
public void addPathListener(PathListener listener) {
|
|
this.pathListeners.add(listener);
|
|
this.primary();
|
|
}
|
|
|
|
/**
|
|
* 将模组配置同步到 Baritone 的全局设置。
|
|
*
|
|
* @param config 扩地配置
|
|
*/
|
|
public void applyConfig(ExpansionConfig config) {
|
|
Settings settings = BaritoneAPI.getSettings();
|
|
settings.allowSprint.value = config.allowSprint;
|
|
settings.allowBreak.value = config.allowBreak;
|
|
settings.allowPlace.value = config.allowPlace;
|
|
// 跳跃(跑酷)前进:开启放置时也允许跳跃搭路,避免过河/过缝时必须纯步行
|
|
settings.allowParkour.value = config.allowJump || config.allowPlace;
|
|
// 关键修复:开启放置时,配套允许“跑酷搭路放方块”。
|
|
// 若仅开 allowPlace 而不给 allowParkourPlace,Baritone 在边缘会把
|
|
// “下蹲放方块”与“跳跃过去”两条腿计划打架:想放又判定不该放,
|
|
// 于是原地反复下蹲+跳跃却始终放不出方块(用户观察到的“原地抽搐”)。
|
|
settings.allowParkourPlace.value = config.allowPlace;
|
|
// 降低放方块的路径代价:Baritone 默认对搭路惩罚较高,会倾向犹豫/绕行;
|
|
// 归零后它更愿意稳定搭路,而不是在缺口边反复空跳。
|
|
settings.blockPlacementPenalty.value = 0.0;
|
|
settings.avoidance.value = config.avoidMobs;
|
|
}
|
|
|
|
/**
|
|
* 让 Baritone 寻路前往指定区块中心。
|
|
*
|
|
* <p>使用 Baritone <b>原生</b>{@link GoalXZ}(目标区块中心单格):原生 GoalXZ 对
|
|
* 可达地形几乎不会误判“目标不可达”,是最好的默认选择。早期用自定义
|
|
* {@code ChunkGoal}(曾加入高度硬约束)疑似是“平原上一按 W 就能走、Baritone 却秒
|
|
* CALC_FAILED”的根因——自定义 Goal 在某些站位/边界下会把可达目标判成不可达。
|
|
* 到达判定仍由控制器 {@code playerChunk.equals(target)} 保证,与 Goal 自身容差无关。</p>
|
|
*
|
|
* @param chunk 目标区块
|
|
*/
|
|
public void pathTo(ChunkPos chunk) {
|
|
IBaritone baritone = this.primary();
|
|
if (baritone == null) {
|
|
return;
|
|
}
|
|
baritone.getCustomGoalProcess().setGoalAndPath(new GoalXZ(chunk.centerBlockX(), chunk.centerBlockZ()));
|
|
}
|
|
|
|
/** 强制取消当前寻路任务。 */
|
|
public void cancel() {
|
|
IBaritone baritone = this.primary();
|
|
if (baritone == null) {
|
|
return;
|
|
}
|
|
baritone.getPathingBehavior().forceCancel();
|
|
}
|
|
|
|
/** @return 当前是否正在寻路 */
|
|
public boolean isPathing() {
|
|
IBaritone baritone = this.primary();
|
|
return baritone != null && baritone.getPathingBehavior().isPathing();
|
|
}
|
|
|
|
/** @return Baritone 是否可用(已加载并存在主实例) */
|
|
public boolean isAvailable() {
|
|
return this.primary() != null;
|
|
}
|
|
|
|
/**
|
|
* 获取 Baritone 主实例;加载失败或异常时返回 null。
|
|
* 首次成功获取时,向 Baritone 事件总线注册一个转发器,
|
|
* 把路径事件分发给所有已注册的 {@link PathListener}。
|
|
*
|
|
* @return 主 Baritone 实例,或 null
|
|
*/
|
|
private IBaritone primary() {
|
|
try {
|
|
IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
|
|
if (baritone != null && !this.eventListenerRegistered) {
|
|
this.eventListenerRegistered = true;
|
|
baritone.getGameEventHandler().registerEventListener(new AbstractGameEventListener() {
|
|
@Override
|
|
public void onPathEvent(PathEvent event) {
|
|
for (PathListener listener : BaritoneBridge.this.pathListeners) {
|
|
try {
|
|
listener.onPathEvent(event);
|
|
} catch (Throwable ignored) {
|
|
// 单个监听器异常不影响其他监听器
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
return baritone;
|
|
} catch (Throwable ignored) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|