From 248505deeecb8e2d46b492a434f27db7c24240dd Mon Sep 17 00:00:00 2001 From: lyizai <3945107889@qq.com> Date: Mon, 31 Aug 2026 13:37:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20v2.2.2=20=E6=97=A0=E8=B7=AF=E6=97=B6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=90=AD=E6=96=B9=E5=9D=97=EF=BC=88=E5=8F=AF?= =?UTF-8?q?=E5=BC=80=E5=85=B3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Baritone allowPlace/allowParkourPlace 改为配置驱动(默认开) - 新增 AutoScaffold 服务:快捷栏搭路方块不足时自动从背包补给 (只进空位/只与更小的搭路方块堆交换,不碰工具食物) - 搭路方块清单喂给 Baritone acceptableThrowawayItems(放置时从中挑选) - AutoTrash 永不丢弃快捷栏物品,与搭路补给协同 - GUI 新增开关与搭路方块清单设置;版本升至 2.2.2 --- README.md | 4 +- gradle.properties | 2 +- .../autodig/client/bridge/BaritoneBridge.java | 46 +++++- .../autodig/client/config/ConfigStore.java | 3 + .../java/autodig/client/config/DigConfig.java | 14 ++ .../client/controller/DigController.java | 5 +- .../java/autodig/client/gui/AutoDigGui.java | 20 +++ .../autodig/client/service/AutoScaffold.java | 135 ++++++++++++++++++ .../autodig/client/service/AutoTrash.java | 6 +- src/main/resources/fabric.mod.json | 2 +- 10 files changed, 227 insertions(+), 10 deletions(-) create mode 100644 src/main/java/autodig/client/service/AutoScaffold.java diff --git a/README.md b/README.md index de6d539..d0544b5 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,12 @@ - **目标矿物 id**:带不带 `minecraft:` 前缀均可识别(如 `diamond_ore` 与 `minecraft:diamond_ore` 等价)。 ### 智能辅助(可逐项开关) +- **无路自动搭方块**:开启后 Baritone 在没有路时(深渊、缺口、岩浆挡路)自动放置方块搭桥/垫脚;模组会自动把背包里的搭路方块(按清单)补进快捷栏供其使用,快捷栏物品永不自动丢弃。 - **工具自动选择**:挖掘前校验手持工具能否采掘目标矿物(如远古残骸必须钻石镐以上,铁镐只会白挖不掉落),不适用时自动从背包换上能采掘且耐久最高的工具;没有合适工具时提示并暂停矿物挖掘,放入工具后自动恢复。 - **自动切换工具**:由 Baritone 在挖掘途中自动选择最合适的工具。 - **自动进食**:饥饿度低时自动吃背包食物,跳过金苹果等特殊/珍贵食物。 - **自动换备用装备**:护甲/工具耐久过低时自动从背包换上同类备用装备。 -- **提前丢垃圾**:背包接近满(已用 ≥30 格)时就提前丢弃圆石、深板岩等垃圾,为矿物腾出空间,避免被误判"背包已满需返回"。 +- **提前丢垃圾**:背包接近满(已用 ≥30 格)时就提前丢弃圆石、深板岩等垃圾,为矿物腾出空间,避免被误判"背包已满需返回";快捷栏物品(搭路方块/工具/食物)永不丢弃。 - **杀戮光环**:自动攻击附近真正敌对生物,不误伤铁傀儡、僵尸猪灵、末影人等中立生物。 - **保命优先**:血线过低时暂停挖矿向上撤离,恢复后自动续任务。 - **装备耐久保护**:护甲/工具耐久低于阈值时暂停或换装,下界模式直接返程。 @@ -41,6 +42,7 @@ ## 版本记录 +- **v2.2.2**:新增无路自动搭方块(可开关):Baritone 放置方块搭桥/垫脚,自动补给快捷栏搭路方块并喂给 Baritone 可放置物品清单;AutoTrash 不再丢弃快捷栏物品。 - **v2.2.1**:移除自动火把;新增主世界矿物绕道挖掘(附近 10 格目标矿物自动挖掉,不漏矿);新增工具适用性检查(远古残骸等自动换钻石镐);支巷长度可配置(默认 10);矿物 id 兼容 `minecraft:` 前缀。 - **v2.2.0**:新增实时状态 HUD、`/autodig status` 命令;自动进食跳过特殊食物;背包接近满提前丢垃圾防误判返程;杀戮光环不再误伤中立生物;GUI 补全进食/保命/攻击范围等设置。 - **v2.1.0**:自动换备用装备 + 背包满自动丢垃圾。 diff --git a/gradle.properties b/gradle.properties index 0397cc1..4fa5103 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ yarn_mappings=1.21.4+build.8 loader_version=0.19.3 # Mod Properties -mod_version=2.2.1 +mod_version=2.2.2 maven_group=autodig archives_base_name=autodig diff --git a/src/main/java/autodig/client/bridge/BaritoneBridge.java b/src/main/java/autodig/client/bridge/BaritoneBridge.java index bbc123b..496b209 100644 --- a/src/main/java/autodig/client/bridge/BaritoneBridge.java +++ b/src/main/java/autodig/client/bridge/BaritoneBridge.java @@ -5,17 +5,22 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.utils.BlockOptionalMeta; +import java.util.ArrayList; import java.util.List; import net.minecraft.block.Block; import net.minecraft.block.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; /** * Baritone API 封装(桥接层)。 * *

把模组对 Baritone 的所有调用集中在此类:同步用户配置(工具切换、避岩浆、 - * 避怪、保命优先)、按名字/数量挖矿、前往指定坐标、前往最近传送门、 - * 取消任务等。(杀戮光环由 KillAura 近战实现,不经 Baritone。)

+ * 避怪、保命优先、无路时放置方块搭路)、按名字/数量挖矿、前往指定坐标、 + * 前往最近传送门、取消任务等。(杀戮光环由 KillAura 近战实现,不经 Baritone。)

* *

所有调用都做空安全保护,Baritone 未加载时相关操作会安全地静默失败。

*/ @@ -23,6 +28,9 @@ public final class BaritoneBridge { /** 上一次打印 gotoBlock 诊断日志的时间戳,用于节流 */ private long lastGotoLog; + /** 搭路方块缓存:原始配置串未变化时直接复用,避免每 tick 解析 */ + private String lastScaffoldRaw; + private List scaffoldItemsCache = List.of(); /** * 把模组配置同步到 Baritone 全局设置。 @@ -34,9 +42,9 @@ public final class BaritoneBridge { Settings settings = BaritoneAPI.getSettings(); settings.allowSprint.value = true; settings.allowBreak.value = true; // 挖矿必须允许挖方块 - settings.allowPlace.value = true; // 允许搭路/垫脚 + settings.allowPlace.value = config.allowPlace; // 无路时放置方块(搭桥/垫脚),可关 + settings.allowParkourPlace.value = config.allowPlace; // 跑酷垫脚同样受开关控制 settings.allowParkour.value = true; - settings.allowParkourPlace.value = true; settings.freeLook.value = true; // 自动切换最合适工具 settings.autoTool.value = config.autoTool; @@ -47,11 +55,41 @@ public final class BaritoneBridge { settings.blocksToAvoid.value = config.avoidLava ? List.of(Blocks.LAVA) : List.of(); + // 搭路方块:喂给 Baritone 的可放置/可消耗物品清单(放方块时从中挑选) + settings.acceptableThrowawayItems.value = this.scaffoldItems(config); } catch (Throwable ignored) { // Baritone 未就绪时静默失败,避免抛出异常中断每帧逻辑 } } + /** + * 解析搭路方块清单为物品列表(带缓存,配置串不变时不重复解析)。 + * 无法识别的 id 跳过;清单为空时返回空列表(Baritone 沿用其默认清单)。 + */ + private List scaffoldItems(DigConfig config) { + String raw = config.scaffoldBlocks; + if (raw == null || raw.isBlank()) { + return List.of(); + } + if (raw.equals(this.lastScaffoldRaw)) { + return this.scaffoldItemsCache; + } + List items = new ArrayList<>(); + for (String name : config.getScaffoldItemList()) { + Identifier id = Identifier.tryParse(name.contains(":") ? name : "minecraft:" + name); + if (id == null) { + continue; + } + Item item = Registries.ITEM.get(id); + if (item != null && item != Items.AIR) { + items.add(item); + } + } + this.lastScaffoldRaw = raw; + this.scaffoldItemsCache = items; + return items; + } + /** * 按方块 id 挖指定数量的矿。 * diff --git a/src/main/java/autodig/client/config/ConfigStore.java b/src/main/java/autodig/client/config/ConfigStore.java index ff38fcb..692ece0 100644 --- a/src/main/java/autodig/client/config/ConfigStore.java +++ b/src/main/java/autodig/client/config/ConfigStore.java @@ -89,6 +89,9 @@ public final class ConfigStore { if (c.trashItems == null || c.trashItems.isBlank()) { c.trashItems = "cobblestone,cobbled_deepslate,deepslate,tuff,dirt,granite,diorite,andesite,netherrack,blackstone,basalt"; } + if (c.scaffoldBlocks == null || c.scaffoldBlocks.isBlank()) { + c.scaffoldBlocks = "cobblestone,cobbled_deepslate,deepslate,netherrack,dirt,granite,diorite,andesite,tuff,blackstone,basalt"; + } return c; } diff --git a/src/main/java/autodig/client/config/DigConfig.java b/src/main/java/autodig/client/config/DigConfig.java index b578782..1af00b6 100644 --- a/src/main/java/autodig/client/config/DigConfig.java +++ b/src/main/java/autodig/client/config/DigConfig.java @@ -49,6 +49,13 @@ public class DigConfig { /** 优先绕开岩浆池(给岩浆方块额外寻路代价) */ public boolean avoidLava = true; + // ---- 搭路/放置 ---- + /** 允许 Baritone 放置方块:没有路(深渊/缺口/岩浆挡路)时自动搭桥、垫脚 */ + public boolean allowPlace = true; + /** 搭路方块清单(逗号分隔的物品 id,带不带 "minecraft:" 前缀均可); + * 会自动从背包挪一组到快捷栏供 Baritone 放置,同时喂给 Baritone 作为可放置物品 */ + public String scaffoldBlocks = "cobblestone,cobbled_deepslate,deepslate,netherrack,dirt,granite,diorite,andesite,tuff,blackstone,basalt"; + // ---- 杀戮光环 ---- /** 杀戮光环:自动攻击附近敌对生物 */ public boolean killAura = false; @@ -98,6 +105,11 @@ public class DigConfig { return parseOreList(this.trashItems); } + /** 获取搭路方块清单 */ + public List getScaffoldItemList() { + return parseOreList(this.scaffoldBlocks); + } + private static List parseOreList(String str) { if (str == null || str.isBlank()) { return List.of(); @@ -125,6 +137,8 @@ public class DigConfig { c.trashItems = this.trashItems; c.trashReserve = this.trashReserve; c.avoidLava = this.avoidLava; + c.allowPlace = this.allowPlace; + c.scaffoldBlocks = this.scaffoldBlocks; c.killAura = this.killAura; c.killAuraSafe = this.killAuraSafe; c.killRange = this.killRange; diff --git a/src/main/java/autodig/client/controller/DigController.java b/src/main/java/autodig/client/controller/DigController.java index 6a959a6..636ce4d 100644 --- a/src/main/java/autodig/client/controller/DigController.java +++ b/src/main/java/autodig/client/controller/DigController.java @@ -7,6 +7,7 @@ import autodig.client.miner.NetherMiner; import autodig.client.miner.OverworldMiner; import autodig.client.service.AutoEat; import autodig.client.service.AutoGear; +import autodig.client.service.AutoScaffold; import autodig.client.service.AutoTrash; import autodig.client.service.DeathRecorder; import autodig.client.service.KillAura; @@ -35,6 +36,7 @@ public final class DigController { private final KillAura killAura = new KillAura(); private final AutoGear autoGear = new AutoGear(); private final AutoTrash autoTrash = new AutoTrash(); + private final AutoScaffold autoScaffold = new AutoScaffold(); private final DeathRecorder deathRecorder = new DeathRecorder(); private final SessionStats stats = new SessionStats(); private final OverworldMiner overworld = new OverworldMiner(this.bridge); @@ -60,10 +62,11 @@ public final class DigController { } PlayerEntity player = client.player; - // 常驻能力:杀戮光环、自动进食、背包满丢垃圾、换装冷却 + // 常驻能力:杀戮光环、自动进食、背包满丢垃圾、搭路方块补给、换装冷却 this.killAura.tick(config); this.autoEat.tick(config); this.autoTrash.tick(config); + this.autoScaffold.tick(config); this.autoGear.tick(); // 死亡处理:记录死亡次数,暂停任务,重生后按需回到死亡坐标 diff --git a/src/main/java/autodig/client/gui/AutoDigGui.java b/src/main/java/autodig/client/gui/AutoDigGui.java index e11c6d9..1bc0755 100644 --- a/src/main/java/autodig/client/gui/AutoDigGui.java +++ b/src/main/java/autodig/client/gui/AutoDigGui.java @@ -58,6 +58,7 @@ public final class AutoDigGui extends Screen { private TextFieldWidget overworldOresField; private TextFieldWidget netherOresField; private TextFieldWidget trashField; + private TextFieldWidget scaffoldField; public AutoDigGui(AutoDigModClient mod) { super(Text.literal("AutoDig")); @@ -75,6 +76,7 @@ public final class AutoDigGui extends Screen { this.overworldOresField = null; this.netherOresField = null; this.trashField = null; + this.scaffoldField = null; // 面板宽度自适应窗口,最小 200 保证 +/- 与输入框可用 this.panelW = MathHelper.clamp(this.width - 16, 200, 400); @@ -120,6 +122,12 @@ public final class AutoDigGui extends Screen { this.config.autoTrash = v; this.init(); // 切换后显示/隐藏垃圾设置区 }); + y = this.checkPair(y, "允许搭方块(无路时自动放置)", () -> this.config.allowPlace, v -> { + this.syncFields(); // 保留输入框中未应用的编辑 + this.config.allowPlace = v; + this.init(); // 切换后显示/隐藏搭路设置区 + }, + null, null, null); y += 10; y = this.header(y, "进食/保命/攻击阈值"); @@ -149,6 +157,13 @@ public final class AutoDigGui extends Screen { y += 10; } + if (this.config.allowPlace) { + y = this.header(y, "搭路方块设置(无路时自动放置)"); + y = this.fieldRow(y, "搭路方块(逗号分隔,自动补进快捷栏)", + this.config.scaffoldBlocks, tf -> this.scaffoldField = tf); + y += 10; + } + if (this.config.task == MineTask.OVERWORLD) { y = this.header(y, "主世界设置"); y = this.numberRow(y, "挖掘层 (Y)", () -> this.config.overworldLevel, @@ -391,6 +406,9 @@ public final class AutoDigGui extends Screen { if (this.trashField != null) { this.config.trashItems = this.trashField.getText(); } + if (this.scaffoldField != null) { + this.config.scaffoldBlocks = this.scaffoldField.getText(); + } } /** 把界面临时配置写回 mod 全局配置并保存(供 controller 实时读取)。 */ @@ -399,6 +417,8 @@ public final class AutoDigGui extends Screen { target.task = this.config.task; target.survivalFirst = this.config.survivalFirst; target.avoidLava = this.config.avoidLava; + target.allowPlace = this.config.allowPlace; + target.scaffoldBlocks = this.config.scaffoldBlocks; target.autoEat = this.config.autoEat; target.eatHungerThreshold = this.config.eatHungerThreshold; target.autoTool = this.config.autoTool; diff --git a/src/main/java/autodig/client/service/AutoScaffold.java b/src/main/java/autodig/client/service/AutoScaffold.java new file mode 100644 index 0000000..5c9bde9 --- /dev/null +++ b/src/main/java/autodig/client/service/AutoScaffold.java @@ -0,0 +1,135 @@ +package autodig.client.service; + +import autodig.client.config.DigConfig; +import autodig.client.config.MineTask; +import java.util.HashSet; +import java.util.Set; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.slot.SlotActionType; + +/** + * 搭路方块补给服务。 + * + *

Baritone 放置方块(无路时搭桥/垫脚)时从快捷栏挑选方块。 + * 本服务在挖矿任务进行中周期性检查:快捷栏里搭路方块不足时,自动把主背包中 + * 数量最多的一组搭路方块(按 {@code scaffoldBlocks} 清单)挪进快捷栏空位; + * 快捷栏已满时,只与快捷栏中已有的小堆搭路方块做整体交换,绝不碰工具、 + * 食物等其他物品。操作走 {@code clickSlot} 正规网络包,单人/多人均可用。

+ * + *

与 AutoTrash 协同:AutoTrash 丢弃垃圾时不会丢快捷栏物品, + * {@code trashReserve} 保留的方块正是搭路补给的来源。

+ */ +public final class AutoScaffold { + + /** 检查间隔(毫秒) */ + private static final long CHECK_INTERVAL_MS = 2000; + /** 快捷栏搭路方块低于该数量时才补给 */ + private static final int MIN_HOTBAR_COUNT = 16; + + /** 上一次检查的时间戳(节流) */ + private long lastCheck; + + /** 每帧调用:快捷栏缺搭路方块时自动补给。 */ + public void tick(DigConfig config) { + if (!config.allowPlace || config.task == MineTask.NONE) { + return; + } + MinecraftClient client = MinecraftClient.getInstance(); + if (client.player == null || client.interactionManager == null) { + return; + } + if (client.currentScreen != null) { + return; // 有界面打开时不操作背包 + } + PlayerEntity player = client.player; + ScreenHandler handler = player.currentScreenHandler; + if (handler != player.playerScreenHandler) { + return; + } + if (!handler.getCursorStack().isEmpty()) { + return; + } + long now = System.currentTimeMillis(); + if (now - this.lastCheck < CHECK_INTERVAL_MS) { + return; + } + this.lastCheck = now; + + Set scaffold = new HashSet<>(config.getScaffoldItemList()); + if (scaffold.isEmpty()) { + return; + } + // 快捷栏(main 0-8)已有的搭路方块总数 + int hotbarCount = 0; + for (int i = 0; i < 9; i++) { + ItemStack s = player.getInventory().main.get(i); + if (!s.isEmpty() && isScaffold(s, scaffold)) { + hotbarCount += s.getCount(); + } + } + if (hotbarCount >= MIN_HOTBAR_COUNT) { + return; + } + // 主背包(main 9-35)里找数量最多的一组搭路方块 + int bestSlot = -1; + int bestCount = 0; + for (int i = 9; i < 36; i++) { + ItemStack s = player.getInventory().main.get(i); + if (!s.isEmpty() && isScaffold(s, scaffold) && s.getCount() > bestCount) { + bestCount = s.getCount(); + bestSlot = i; + } + } + if (bestSlot < 0) { + return; // 背包里没有搭路方块(trashReserve 为 0 或耗尽) + } + ItemStack bagStack = player.getInventory().main.get(bestSlot); + int bagScreenSlot = screenSlotOf(handler, bagStack); + if (bagScreenSlot < 0) { + return; + } + // 优先放进快捷栏空位(playerScreenHandler 槽位 36-44 对应快捷栏 0-8) + for (int i = 0; i < 9; i++) { + if (player.getInventory().main.get(i).isEmpty()) { + client.interactionManager.clickSlot(handler.syncId, bagScreenSlot, 0, SlotActionType.PICKUP, player); + client.interactionManager.clickSlot(handler.syncId, 36 + i, 0, SlotActionType.PICKUP, player); + return; + } + } + // 无空位:只与快捷栏里已有的更小堆搭路方块整体交换,不碰其他物品 + for (int i = 0; i < 9; i++) { + ItemStack s = player.getInventory().main.get(i); + if (!s.isEmpty() && isScaffold(s, scaffold) && s.getCount() < bagStack.getCount()) { + int hotScreenSlot = screenSlotOf(handler, s); + if (hotScreenSlot < 0) { + continue; + } + client.interactionManager.clickSlot(handler.syncId, hotScreenSlot, 0, SlotActionType.PICKUP, player); + client.interactionManager.clickSlot(handler.syncId, bagScreenSlot, 0, SlotActionType.PICKUP, player); + client.interactionManager.clickSlot(handler.syncId, hotScreenSlot, 0, SlotActionType.PICKUP, player); + return; + } + } + } + + /** 是否为清单内的搭路方块(BlockItem 且按 path 匹配,兼容命名空间前缀)。 */ + private static boolean isScaffold(ItemStack stack, Set scaffold) { + return stack.getItem() instanceof BlockItem + && scaffold.contains(Registries.ITEM.getId(stack.getItem()).getPath()); + } + + /** 按对象引用在 ScreenHandler 里找槽位下标。 */ + private static int screenSlotOf(ScreenHandler handler, ItemStack stack) { + for (int i = 0; i < handler.slots.size(); i++) { + if (handler.getSlot(i).getStack() == stack) { + return i; + } + } + return -1; + } +} diff --git a/src/main/java/autodig/client/service/AutoTrash.java b/src/main/java/autodig/client/service/AutoTrash.java index b27fb78..b17bf0e 100644 --- a/src/main/java/autodig/client/service/AutoTrash.java +++ b/src/main/java/autodig/client/service/AutoTrash.java @@ -21,7 +21,8 @@ import net.minecraft.screen.slot.SlotActionType; * *

背包接近满(已用格数达到阈值)时就主动把 {@code trashItems} 清单里的 * 垃圾物品丢出背包(圆石、凝灰岩、深板岩等挖掘副产物),为挖到的矿物提前 - * 腾出空间,避免背包彻底满后触发"背包已满需返回"而中断挖矿。方块类垃圾 + * 腾出空间,避免背包彻底满后触发"背包已满需返回"而中断挖矿。快捷栏 + * 物品永不自动丢弃(搭路方块/工具/食物常驻快捷栏)。方块类垃圾 * 保留 {@code trashReserve} 个供 Baritone 搭路/垫脚使用。丢弃通过 * {@code clickSlot(THROW)} 走正规网络包,单人/多人均可用。

*/ @@ -62,9 +63,10 @@ public final class AutoTrash { } // 收集背包里的垃圾,按物品 id 分组(并记录是否为可放置的方块) + // 从 main 9-35 收集:快捷栏(main 0-8)物品永不自动丢弃(搭路方块/工具/食物) Map> groups = new HashMap<>(); Map blockLike = new HashMap<>(); - for (int i = 0; i < 36; i++) { + for (int i = 9; i < 36; i++) { ItemStack s = player.getInventory().main.get(i); if (s.isEmpty()) { continue; diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index d967130..ccddaf5 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -3,7 +3,7 @@ "id": "autodig", "version": "${version}", "name": "AutoDig", - "description": "自动挖矿模组(内置 Baritone 1.13.1,无需另行安装):主世界模式与下界模式,均可自定义目标矿物(带不带 minecraft: 前缀均可)。主世界鱼骨巷道挖矿 + 附近目标矿物自动绕道挖掘;下界自动进出传送门挖矿并支持返程。自动切换最适用工具(远古残骸等自动换钻石镐)、自动进食(避开特殊食物)、杀戮光环(不误伤中立生物)、保命优先、优先绕开岩浆、装备耐久保护(自动换备用装备)、背包近满提前丢垃圾防误判返程、死亡重生回点、实时状态 HUD。", + "description": "自动挖矿模组(内置 Baritone 1.13.1,无需另行安装):主世界模式与下界模式,均可自定义目标矿物(带不带 minecraft: 前缀均可)。主世界鱼骨巷道挖矿 + 附近目标矿物自动绕道挖掘;下界自动进出传送门挖矿并支持返程。无路时自动放置方块搭桥/垫脚(自动补给快捷栏搭路方块)、自动切换最适用工具(远古残骸等自动换钻石镐)、自动进食(避开特殊食物)、杀戮光环(不误伤中立生物)、保命优先、优先绕开岩浆、装备耐久保护(自动换备用装备)、背包近满提前丢垃圾防误判返程、死亡重生回点、实时状态 HUD。", "authors": [], "contact": {}, "license": "All-Rights-Reserved",