fix: 主世界岩浆卡死 + 下界挖矿多项修复 (v2.2.3)
主世界:目标点岩浆卡死——同目标不再重复下发、无进展20秒放弃跳过、绕道仅空闲时低频重发,避免玩家被拉回岩浆边 下界:垃圾清单补灵魂沙/灵魂土/岩浆块/沙砾/下界砖;进食不再被切工具打断;挖矿中不再每秒重发mineByName(解决灵魂沙抽搐/来回折返);寻路失败不再误判完成、自动转移新矿区续挖
这个提交包含在:
@@ -6,11 +6,13 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
@@ -41,6 +43,12 @@ public final class NetherMiner {
|
||||
|
||||
/** 背包满去抖阈值(tick):连续这么久都满才认定为真满 */
|
||||
private static final int FULL_DEBOUNCE_TICKS = 20;
|
||||
/** Baritone 空闲(附近矿已挖完/寻路失败)连续这么久后,转移到新区域继续找(tick) */
|
||||
private static final int RELOCATE_TICKS = 60;
|
||||
/** 转移的随机水平距离(方块) */
|
||||
private static final int RELOCATE_DISTANCE = 16;
|
||||
/** 转移寻路超时(毫秒):超过则放弃转移,原地继续挖 */
|
||||
private static final long RELOCATE_TIMEOUT_MS = 15_000;
|
||||
|
||||
/** 常见矿物方块 id -> 掉落物品 id(挖掘产物与方块本身不同的情况) */
|
||||
private static final Map<String, String> ORE_TO_DROP = Map.ofEntries(
|
||||
@@ -85,6 +93,14 @@ public final class NetherMiner {
|
||||
private boolean baselineSet;
|
||||
/** 背包满连续持续的 tick 数(去抖) */
|
||||
private int fullTicks;
|
||||
/** Baritone 空闲连续持续的 tick 数(用于触发转移新区域) */
|
||||
private int idleTicks;
|
||||
/** 是否正在转移到新矿区 */
|
||||
private boolean relocating;
|
||||
/** 转移目标点 */
|
||||
private BlockPos relocateTarget;
|
||||
/** 转移开始时间戳 */
|
||||
private long relocateStart;
|
||||
|
||||
public NetherMiner(BaritoneBridge bridge) {
|
||||
this.bridge = bridge;
|
||||
@@ -103,6 +119,10 @@ public final class NetherMiner {
|
||||
this.baselineCount = 0;
|
||||
this.baselineSet = false;
|
||||
this.fullTicks = 0;
|
||||
this.idleTicks = 0;
|
||||
this.relocating = false;
|
||||
this.relocateTarget = null;
|
||||
this.relocateStart = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,30 +209,15 @@ public final class NetherMiner {
|
||||
} else if (this.minedEnough(config, player)) {
|
||||
// 已挖够目标数量
|
||||
this.miningStarted = false;
|
||||
this.relocating = false;
|
||||
if (config.netherAutoReturn) {
|
||||
this.stage = Stage.RETURN_PORTAL;
|
||||
} else {
|
||||
this.done = true;
|
||||
}
|
||||
} else if (this.miningStarted && !this.bridge.isActive()) {
|
||||
// 挖矿进程已跑完(挖够数量或附近无矿可挖)
|
||||
this.miningStarted = false;
|
||||
if (config.netherAutoReturn) {
|
||||
this.stage = Stage.RETURN_PORTAL;
|
||||
} else {
|
||||
this.stage = Stage.GO_COMMIT; // 停在下界继续挖(不返回)
|
||||
}
|
||||
} else {
|
||||
// 先派发挖矿指令;派发成功后 miningStarted 置位,
|
||||
// 之后才能用 isActive()==false 判定「挖完了」
|
||||
this.issue(() -> {
|
||||
List<String> ores = config.getNetherOreList();
|
||||
if (!ores.isEmpty()) {
|
||||
int count = config.netherTargetCount > 0 ? config.netherTargetCount : -1;
|
||||
this.bridge.mineByName(count, ores.toArray(String[]::new));
|
||||
this.miningStarted = true;
|
||||
}
|
||||
});
|
||||
// 未挖够目标数量:持续挖矿,绝不因 Baritone 空闲误判"任务完成"
|
||||
this.mineTick(config, player);
|
||||
}
|
||||
}
|
||||
case RETURN_PORTAL -> {
|
||||
@@ -228,13 +233,76 @@ public final class NetherMiner {
|
||||
|
||||
/** 判断是否已挖够目标矿物数量(按背包产物计数,扣除任务开始时的基线)。 */
|
||||
private boolean minedEnough(DigConfig config, PlayerEntity player) {
|
||||
this.minedCount = this.countProducts(config, player) - this.baselineCount;
|
||||
if (config.netherTargetCount <= 0) {
|
||||
return false; // -1 或 0 表示无限挖
|
||||
}
|
||||
this.minedCount = this.countProducts(config, player) - this.baselineCount;
|
||||
return this.minedCount >= config.netherTargetCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 未挖够目标时的挖矿驱动:空闲转移到新矿区、持续派发挖矿指令。
|
||||
*
|
||||
* <p>关键:Baritone 空闲(附近矿挖完或寻路失败)时,不再把它当成"任务完成"
|
||||
* 回主世界,而是转移到附近新位置继续找矿;无限目标(-1)下只要没背包满/
|
||||
* 血量低/装备耐久低,就一直在下界挖。</p>
|
||||
*/
|
||||
private void mineTick(DigConfig config, PlayerEntity player) {
|
||||
if (this.relocating) {
|
||||
double d = this.distanceSq(player, this.relocateTarget);
|
||||
if (d <= 4.0) {
|
||||
// 已到新矿区
|
||||
this.relocating = false;
|
||||
this.relocateTarget = null;
|
||||
this.miningStarted = false;
|
||||
} else if (System.currentTimeMillis() - this.relocateStart > RELOCATE_TIMEOUT_MS) {
|
||||
// 转移超时(目标点不可达):放弃转移,原地继续挖
|
||||
this.relocating = false;
|
||||
this.relocateTarget = null;
|
||||
this.bridge.cancelAll();
|
||||
} else if (!this.bridge.isActive()) {
|
||||
// 转移途中寻路失败/停下:重发
|
||||
this.bridge.gotoBlock(this.relocateTarget);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.miningStarted && !this.bridge.isActive()) {
|
||||
// 附近矿已挖完或寻路失败:连续空闲一段时间后转移到新区域继续找
|
||||
this.idleTicks++;
|
||||
if (this.idleTicks >= RELOCATE_TICKS) {
|
||||
this.idleTicks = 0;
|
||||
this.miningStarted = false;
|
||||
this.relocateToNewArea(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!this.miningStarted) {
|
||||
this.idleTicks = 0;
|
||||
List<String> ores = config.getNetherOreList();
|
||||
if (!ores.isEmpty()) {
|
||||
// 无限目标(-1),实际战果由 minedEnough 计数
|
||||
this.bridge.mineByName(-1, ores.toArray(String[]::new));
|
||||
this.miningStarted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 转移到玩家附近的新位置(随机水平偏移),继续找矿。 */
|
||||
private void relocateToNewArea(PlayerEntity player) {
|
||||
int dx = ThreadLocalRandom.current().nextInt(-RELOCATE_DISTANCE, RELOCATE_DISTANCE);
|
||||
int dz = ThreadLocalRandom.current().nextInt(-RELOCATE_DISTANCE, RELOCATE_DISTANCE);
|
||||
this.relocateTarget = player.getBlockPos().add(dx, 0, dz);
|
||||
this.relocateStart = System.currentTimeMillis();
|
||||
this.relocating = true;
|
||||
this.bridge.gotoBlock(this.relocateTarget);
|
||||
}
|
||||
|
||||
private double distanceSq(PlayerEntity player, BlockPos target) {
|
||||
double dx = player.getX() - (target.getX() + 0.5);
|
||||
double dz = player.getZ() - (target.getZ() + 0.5);
|
||||
return dx * dx + dz * dz;
|
||||
}
|
||||
|
||||
/** 统计背包中目标矿物产物的总数量(方块 id 映射到掉落物 id)。 */
|
||||
private int countProducts(DigConfig config, PlayerEntity player) {
|
||||
List<String> ores = config.getNetherOreList();
|
||||
|
||||
在新工单中引用
屏蔽一个用户