比较提交
| 作者 | SHA1 | 提交日期 | |
|---|---|---|---|
|
|
5193b2e379 | ||
|
|
2309f01291 | ||
|
|
3cddee2abb | ||
|
|
28fe848fb6 | ||
|
|
340fb2ddf1 | ||
|
|
fc14e51894 |
+1
-1
@@ -7,7 +7,7 @@ yarn_mappings=1.21.4+build.8
|
||||
loader_version=0.19.3
|
||||
|
||||
# Mod Properties
|
||||
mod_version=1.2.1
|
||||
mod_version=1.2.3
|
||||
maven_group=autostore
|
||||
archives_base_name=autostore
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ 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;
|
||||
@@ -55,12 +56,27 @@ public final class BaritoneBridge {
|
||||
settings.allowSprint.value = config.allowSprint;
|
||||
settings.allowBreak.value = config.allowBreak;
|
||||
settings.allowPlace.value = config.allowPlace;
|
||||
settings.allowParkour.value = config.allowJump;
|
||||
// 跳跃(跑酷)前进:开启放置时也允许跳跃搭路,避免过河/过缝时必须纯步行
|
||||
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 寻路前往指定区块(以“到达区块内”为完成条件)。
|
||||
* 让 Baritone 寻路前往指定区块中心。
|
||||
*
|
||||
* <p>使用 Baritone <b>原生</b>{@link GoalXZ}(目标区块中心单格):原生 GoalXZ 对
|
||||
* 可达地形几乎不会误判“目标不可达”,是最好的默认选择。早期用自定义
|
||||
* {@code ChunkGoal}(曾加入高度硬约束)疑似是“平原上一按 W 就能走、Baritone 却秒
|
||||
* CALC_FAILED”的根因——自定义 Goal 在某些站位/边界下会把可达目标判成不可达。
|
||||
* 到达判定仍由控制器 {@code playerChunk.equals(target)} 保证,与 Goal 自身容差无关。</p>
|
||||
*
|
||||
* @param chunk 目标区块
|
||||
*/
|
||||
@@ -69,11 +85,7 @@ public final class BaritoneBridge {
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
// 使用自定义 ChunkGoal:完成条件为“玩家脚下方块落在目标区块内”,
|
||||
// 与控制器 playerChunk.equals(target) 的判定一致。避免 Baritone 自带
|
||||
// GoalXZ(容差 0,精确到区块中心单格)在中心不可达时停在相邻区块,
|
||||
// 造成目标区块错位与反复寻路。
|
||||
baritone.getCustomGoalProcess().setGoalAndPath(new ChunkGoal(chunk));
|
||||
baritone.getCustomGoalProcess().setGoalAndPath(new GoalXZ(chunk.centerBlockX(), chunk.centerBlockZ()));
|
||||
}
|
||||
|
||||
/** 强制取消当前寻路任务。 */
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 本文件为 AutoStore 模组自定义的 Baritone 寻路目标。
|
||||
*/
|
||||
package autostore.client.bridge;
|
||||
|
||||
import autostore.client.territory.ChunkPos;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
|
||||
/**
|
||||
* 以“到达目标区块内”为完成条件的寻路目标。
|
||||
*
|
||||
* <p>修复“目标区块错位”问题:Baritone 自带的 {@code GoalXZ} 容差为 0,
|
||||
* 会要求玩家精确站在区块中心的单个方块上(如 {@code x*16+8, z*16+8})。
|
||||
* 一旦该方块不可达(被树、石头、水、建筑等占据),玩家会被停在区块边缘甚至
|
||||
* 相邻区块,导致玩家所在区块与目标区块错位、反复寻路。</p>
|
||||
*
|
||||
* <p>本目标把完成条件放宽为“玩家脚下方块落在目标区块内”,与控制器中
|
||||
* {@code playerChunk.equals(target)} 的判定完全一致,从而彻底消除
|
||||
* 中心点不可达带来的错位。</p>
|
||||
*/
|
||||
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;
|
||||
|
||||
public ChunkGoal(ChunkPos chunk) {
|
||||
this.targetX = chunk.x();
|
||||
this.targetZ = chunk.z();
|
||||
this.centerX = chunk.centerBlockX();
|
||||
this.centerZ = chunk.centerBlockZ();
|
||||
}
|
||||
|
||||
/** 判断玩家脚下方块是否落在目标区块内 */
|
||||
@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;
|
||||
return Math.sqrt(dx * dx + dz * dz);
|
||||
}
|
||||
}
|
||||
@@ -93,6 +93,8 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
||||
private boolean eating;
|
||||
/** Baritone 最近一次路径计算是否失败(目标不可达);由事件监听设置,寻路阶段消费 */
|
||||
private volatile boolean pathCalcFailed;
|
||||
/** 等待开拓时段自动开始:不在 11:00-22:00 时点击开始会暂存配置,进入时段后自动启动(null 表示无等待任务) */
|
||||
private ExpansionConfig pendingStart;
|
||||
|
||||
public ExpansionController(TerritoryDataService dataService) {
|
||||
this.dataService = dataService;
|
||||
@@ -140,6 +142,11 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
||||
return this.state != State.IDLE && this.state != State.COMPLETE && this.state != State.STOPPED;
|
||||
}
|
||||
|
||||
/** @return 是否处于"等待开拓时段自动开始"状态 */
|
||||
public boolean isWaitingForClaimTime() {
|
||||
return this.pendingStart != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前现实时间(本地时区)是否在允许开拓的时间段内。
|
||||
* 仅 11:00(含)到 22:00(不含)允许开拓,其余时段服务器会拒绝开拓。
|
||||
@@ -171,14 +178,15 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
||||
this.status = "Baritone \u5c1a\u672a\u521d\u59cb\u5316\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5";
|
||||
return false;
|
||||
}
|
||||
// 现实时间限制:仅 11:00-22:00 允许开拓,其余时段服务器会拒绝开拓(等待超时)
|
||||
// 现实时间限制:仅 11:00-22:00 允许开拓,其余时段服务器会拒绝开拓(等待超时)。
|
||||
// 不在时段时不再直接拒绝,而是登记"等待自动开始":进入时段后由 tick() 自动启动。
|
||||
if (!ExpansionController.isWithinClaimTime()) {
|
||||
this.status = "\u4e0d\u5728\u5f00\u62d3\u65f6\u9650\u5185\uff0811:00-22:00\uff09\uff0c\u65e0\u6cd5\u5f00\u62d3";
|
||||
this.setState(State.IDLE, this.status);
|
||||
this.log("\u542f\u52a8\u5931\u8d25\uff1a\u4e0d\u5728\u5f00\u62d3\u65f6\u9650\u5185\uff0c\u5f53\u524d\u73b0\u5b9e\u65f6\u95f4 " + LocalTime.now().format(LOG_TIME_FORMAT));
|
||||
this.pendingStart = requestedConfig.copy();
|
||||
this.setState(State.IDLE, "\u7b49\u5f85\u5f00\u62d3\u65f6\u6bb5\uff0c11:00 \u81ea\u52a8\u5f00\u59cb");
|
||||
this.log("\u4e0d\u5728\u5f00\u62d3\u65f6\u6bb5\u5185\uff0811:00-22:00\uff09\uff0c\u5df2\u767b\u8bb0\u81ea\u52a8\u5f00\u59cb\uff0c\u5f53\u524d\u73b0\u5b9e\u65f6\u95f4 " + LocalTime.now().format(LOG_TIME_FORMAT));
|
||||
// 给玩家发送聊天栏提示,避免玩家未打开 GUI 时看不到原因
|
||||
client.player.sendMessage(Text.literal("[AutoStore] \u4e0d\u5728\u5f00\u62d3\u65f6\u9650\u5185\uff0811:00-22:00\uff09\uff0c\u65e0\u6cd5\u5f00\u62d3"), false);
|
||||
return false;
|
||||
client.player.sendMessage(Text.literal("[AutoStore] \u4e0d\u5728\u5f00\u62d3\u65f6\u6bb5\u5185\uff0811:00-22:00\uff09\uff0c\u5df2\u767b\u8bb0\uff1a\u8fdb\u5165\u65f6\u6bb5\u540e\u81ea\u52a8\u5f00\u59cb"), false);
|
||||
return true;
|
||||
}
|
||||
this.config = requestedConfig.copy();
|
||||
this.model = this.dataService.model();
|
||||
@@ -214,8 +222,14 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 手动停止任务:取消 Baritone 寻路并进入 STOPPED 状态 */
|
||||
/** 手动停止任务:取消 Baritone 寻路并进入 STOPPED 状态;若处于等待自动开始,则取消等待 */
|
||||
public void stop() {
|
||||
if (this.pendingStart != null) {
|
||||
this.pendingStart = null;
|
||||
this.setState(State.IDLE, "\u5df2\u53d6\u6d88\u81ea\u52a8\u5f00\u59cb");
|
||||
this.log("\u5df2\u53d6\u6d88\u7b49\u5f85\u81ea\u52a8\u5f00\u59cb");
|
||||
return;
|
||||
}
|
||||
if (this.state == State.IDLE || this.state == State.COMPLETE || this.state == State.STOPPED) {
|
||||
return;
|
||||
}
|
||||
@@ -240,6 +254,13 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
||||
return;
|
||||
}
|
||||
this.playerChunk = this.playerChunk(client);
|
||||
// 等待开拓时段自动开始:进入 11:00-22:00 后自动启动已登记的任务
|
||||
if (this.pendingStart != null && ExpansionController.isWithinClaimTime()) {
|
||||
ExpansionConfig pending = this.pendingStart;
|
||||
this.pendingStart = null;
|
||||
this.log("\u5df2\u8fdb\u5165\u5f00\u62d3\u65f6\u6bb5\uff0c\u81ea\u52a8\u5f00\u59cb");
|
||||
this.start(pending);
|
||||
}
|
||||
// 现实时间限制:运行中超出 11:00-22:00 则自动停止,避免服务器拒绝开拓导致超时
|
||||
if (this.isRunning() && !ExpansionController.isWithinClaimTime()) {
|
||||
this.stop();
|
||||
@@ -336,11 +357,20 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
||||
if (this.skipIfTargetClaimed("\u76ee\u6807\u5df2\u88ab\u5360\u9886")) {
|
||||
return;
|
||||
}
|
||||
// Baritone 报告路径计算失败(目标不可达,如被悬崖/高山/水体完全隔断):立即跳过,不再傻等超时
|
||||
// Baritone 报告路径计算失败(目标不可达,如被悬崖/高山/水体完全隔断)。
|
||||
// 不立即跳过:CALC_FAILED 常因瞬时能力限制或起点卡位误报,先重新寻路一次
|
||||
//(相当于“往边上走两步再算一遍”),重试耗尽才跳过当前目标。
|
||||
if (this.pathCalcFailed) {
|
||||
this.pathCalcFailed = false;
|
||||
this.log("\u5bfb\u8def\u5931\u8d25\uff08\u76ee\u6807\u4e0d\u53ef\u8fbe\uff09\uff0c\u8df3\u8fc7 " + this.target.x() + "," + this.target.z());
|
||||
++this.retryCount;
|
||||
if (this.retryCount >= this.config.retries) {
|
||||
this.log("\u5bfb\u8def\u5931\u8d25\uff08\u76ee\u6807\u4e0d\u53ef\u8fbe\uff09\uff0c\u91cd\u8bd5\u8017\u5c3d\uff0c\u8df3\u8fc7 " + this.target.x() + "," + this.target.z());
|
||||
this.setState(State.FAIL, "\u5bfb\u8def\u5931\u8d25");
|
||||
} else {
|
||||
this.log("\u5bfb\u8def\u5931\u8d25\uff08\u76ee\u6807\u4e0d\u53ef\u8fbe\uff09\uff0c\u91cd\u65b0\u5bfb\u8def " + this.retryCount + "/" + this.config.retries);
|
||||
this.dataService.refreshAsync();
|
||||
this.retrySameTarget("\u5bfb\u8def\u5931\u8d25\uff0c\u91cd\u65b0\u5bfb\u8def");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 目标已不再与己方领土接壤(地图刷新后边界变化):立即跳过,避免走到无效区块
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"schemaVersion":1,"id":"autostore","version":"1.2.1","name":"AutoStore","description":"","authors":[],"contact":{},"license":"All-Rights-Reserved","environment":"client","entrypoints":{"fabric-datagen":["autostore.client.AutoStoreModDataGenerator"],"client":["autostore.client.AutoStoreModClient"],"main":["autostore.AutoStoreMod"]},"mixins":["autostore.mixins.json",{"config":"autostore.client.mixins.json","environment":"client"}],"depends":{"fabricloader":">=0.16.14","fabric-api":"*","minecraft":"1.21.4"},"jars":[{"file":"META-INF/jars/baritone-api-fabric-1.13.1.jar"}]}
|
||||
{"schemaVersion":1,"id":"autostore","version":"1.2.3","name":"AutoStore","description":"","authors":[],"contact":{},"license":"All-Rights-Reserved","environment":"client","entrypoints":{"fabric-datagen":["autostore.client.AutoStoreModDataGenerator"],"client":["autostore.client.AutoStoreModClient"],"main":["autostore.AutoStoreMod"]},"mixins":["autostore.mixins.json",{"config":"autostore.client.mixins.json","environment":"client"}],"depends":{"fabricloader":">=0.16.14","fabric-api":"*","minecraft":"1.21.4"},"jars":[{"file":"META-INF/jars/baritone-api-fabric-1.13.1.jar"}]}
|
||||
在新工单中引用
屏蔽一个用户