可选 mod 集成

基本信息

属性 值
检测真源 compat/Mods.java(枚举 Mods implements 6 个常量)
检测方式 Loader.isModLoaded(modid),结果一次性缓存
可选 mod 数 6
产生 HUD 行的 5(BACKHAND 不产生信息行)
@Mod 声明的依赖 无 —— InfoHUD.java:13-18 没有 dependencies 字段
@Mod(
    modid = InfoHUD.MODID,
    version = Tags.VERSION,
    name = InfoHUD.MODNAME,
    acceptedMinecraftVersions = "[1.7.10]",
    acceptableRemoteVersions = "*")

(InfoHUD.java:13-18)

⚠️ 本 mod 没有任何硬依赖声明——全部集成都是运行时可选的。 但实际上有两处「事实上的硬依赖」没被声明(见下方缺陷)。

6 个枚举与 modid

compat/Mods.java:9-17:

枚举 实际 modid 产生的 HUD 行 触发条件
BLOOD_MAGIC AWWayofTime InfoBloodMagic(LP) Mods.BLOOD_MAGIC.isLoaded()(Hud.java:74)
THAUMCRAFT Thaumcraft InfoThaumcraft(扭曲值) Mods.THAUMCRAFT.isLoaded()(Hud.java:78)
GREGTECH gregtech_nh InfoOreChunk(矿脉区块) Mods.GREGTECH.isLoaded()(Hud.java:82)
FORESTRY Forestry InfoForestry(气候) Mods.FORESTRY.isLoaded()(Hud.java:86)
NUTRIENT nutrition InfoNutrient(营养) Mods.NUTRIENT.isLoaded()(Hud.java:90)
BACKHAND backhand 无信息行(只影响护甲条) 见下

⚠️ modid 陷阱

枚举 用的是 常见误用 说明
GREGTECH gregtech_nh ❌ gregtech 运行时 modid 带 _nh 后缀。wiki 分类名是 gregtech,但 modid 不是
BLOOD_MAGIC AWWayofTime ❌ BloodMagic / bloodmagic 1.7.10 fork 的 modid。首字母大写 + AW 前缀
THAUMCRAFT Thaumcraft ❌ thaumcraft 首字母大写
FORESTRY Forestry ❌ forestry 首字母大写
NUTRIENT nutrition — 全小写
BACKHAND backhand — 全小写

这 6 个字符串同时也是 HudConfig.hudItems 里 3 个默认图标 ID 的域前缀 (AWWayofTime:weakBloodOrb、Thaumcraft:ItemEldritchObject、Forestry:beeDroneGE), 大小写与上表完全一致——改图标时别写成小写域。

isLoaded() 的缓存语义

public boolean isLoaded() {
    if (loaded == null) {
        if (supplier != null) {
            loaded = supplier.get();
        } else if (modid != null) {
            loaded = Loader.isModLoaded(modid);
        } else loaded = false;
    }
    return loaded;
}

(Mods.java:33-42)

首次调用即定型,永不失效(loaded 是 Boolean 字段,Mods.java:21)。 这在 mod 加载期是安全的。

⚠️ 源码缺陷(死代码):Mods 有一个 Mods(Supplier<Boolean> supplier) 构造器(Mods.java:28-31), 用于「modid 测不出时自定义判定」。但全部 6 个枚举都用了 String 构造器 (grep 确认 Mods(...) 在 Mods.java 之外零调用), 因此 supplier 恒为 null,isLoaded() 的 supplier 分支永不执行。

逐项细节

BLOOD_MAGIC(AWWayofTime)→ LP 行

InfoBloodMagic.java:16-24:

return tr("info_blood_magic", getCurrentLP(), getMaxLP());
...
return String.format("%,d", HudUtils.getPlayerLPTag(getPlayer()));

直接读玩家 NBT 的 LP 标签(HudUtils.getPlayerLPTag), 不经 Blood Magic API——这是本 mod 对它的全部耦合点。 另注册 BloodMagicEvent 到 MinecraftForge.EVENT_BUS (Hud.java:49-51,同样以 Mods.BLOOD_MAGIC.isLoaded() 为条件)。

图标默认 AWWayofTime:weakBloodOrb。

THAUMCRAFT(Thaumcraft)→ 扭曲值行

InfoThaumcraft.java:19-24 显示 4 个值: getWarpTotal / getWarpPerm / getWarpSticky / getWarpTemp。

HudUtils.getWarpTotal(HudUtils.java:60-63):

return Thaumcraft.proxy.getPlayerKnowledge()
    .getWarpTotal(player.getCommandSenderName()) + getWarpFromGear(player);

getWarpFromGear(HudUtils.java:65-79)扫描手持 + 4 件护甲 + 4 个饰品槽:

int w = EventHandlerRunic.getFinalWarp(player.getCurrentEquippedItem(), player);
for (int a = 0; a < 4; ++a) {
    w += EventHandlerRunic.getFinalWarp(player.inventory.armorItemInSlot(a), player);
}
IInventory baubles = BaublesApi.getBaubles(player);
for (int a = 0; a < 4; ++a) {
    w += EventHandlerRunic.getFinalWarp(baubles.getStackInSlot(a), player);
}

⚠️ 缺陷:Baubles 无守卫的隐藏硬依赖

项 内容
位置 hud/HudUtils.java:72(BaublesApi.getBaubles(player))
问题 没有 Loader.isModLoaded(...) 守卫,也不在 Mods 枚举里,更不在 @Mod(dependencies)
触发条件 装了 Thaumcraft 但没装 Baubles(Expanded) 时,渲染 Warp 行会走到 getWarpFromGear → BaublesApi 类不存在
后果 NoClassDefFoundError(类缺失)或 baubles == null 时的 NPE,在 HUD 渲染路径上抛异常
编译依赖 compileOnly('com.github.GTNewHorizons:Baubles-Expanded:2.2.11-GTNH:dev')(dependencies.gradle)——compileOnly 意味着运行时可选,与实际用法矛盾

实际门控是 Thaumcraft 而不是 Baubles(Hud.java:78), 因此「Thaumcraft ✓ + Baubles ✗」是唯一会出问题的组合。

GREGTECH(gregtech_nh)→ 矿脉区块行

InfoOreChunk.java:

return tr("info_orechunk");
...
return HudConfig.hudEnabled.OreChunkEnable && isOreChunk();

(InfoOreChunk.java:17、30)

只在「当前区块是矿脉区块」时显示,否则整行消失。 图标默认 minecraft:iron_ore(不指向任何 GT 物品)。

FORESTRY(Forestry)→ 气候行

InfoForestry.java:20-27:

return AlleleManager.climateHelper.toDisplay(temperature) + ": " + ...

直接调用 Forestry 的 AlleleManager——文本与语言包由 Forestry 提供, 本 mod 不翻译。图标默认 Forestry:beeDroneGE。

NUTRIENT(nutrition)→ 营养行

InfoNutrient.java:23-43 用 StringBuilder 自行拼装, 并有 switch (nutrientName.toLowerCase())(InfoNutrient.java:58)做营养素名映射。 不用 lang 键。图标默认 minecraft:milk_bucket。

BACKHAND(backhand)→ 不产生信息行

只影响护甲条的物品来源,共 2 处:

位置 行 行为
mixins/early/GuiIngameMixin.java:244 244 if (Mods.BACKHAND.isLoaded() && BackhandHandler.getBackHandItemStack(mc.thePlayer) != null) —— 从副手取护甲值
hud/core/BackhandHandler.java:13 13 if (!Mods.BACKHAND.isLoaded()) return null; —— 守卫

未使用的编译依赖

dependencies.gradle 声明了 10 个 compileOnly / runtimeOnly,但:

依赖 源码引用数 状态
OverloadedArmorBar:1.1.1 1(ArmorBarRenderMixin) ⚠️ 见 Mixin 与网络 的严重缺陷
Baubles-Expanded 1(HudUtils.java) ⚠️ 无守卫,见上
BloodMagic / Thaumcraft / Backhand / ForestryMC / GT5-Unofficial / Nutrition 均有引用 正常
AppleCore:3.3.11-GTNH 0 ❌ 完全未使用,且不在 Mods 枚举里
GTNHLib:0.9.53 implementation(非 compileOnly) 配置框架,运行时必需

关联