神秘时代集成(Thaumcraft)
基本信息
| 属性 | 值 |
|---|---|
| 判定 modid | Thaumcraft(Wawla.java:65,大写 T) |
| 条件 | Loader.isModLoaded("Thaumcraft") |
| 文件 | src/main/java/net/darkhax/wawla/addons/thaumcraft/AddonThaumcraftTiles.java(241 行) |
| 实现接口 | IWailaDataProvider |
| 配置分类 | Thaumcraft(9 个键) |
| 跨 mod 依赖 | 零编译期依赖——12 个 Class.forName |
| GTNH 状态 | 整合包含 Thaumcraft,此 addon 会加载 |
反射缓存的 12 个类
| 字段 | 目标类 | static? |
|---|---|---|
classTileJarFillable |
thaumcraft.common.tiles.TileJarFillable |
❌ 实例字段 |
classTileJarFillableVoid |
thaumcraft.common.tiles.TileJarFillableVoid |
❌ 实例 |
classTileMirror |
thaumcraft.common.tiles.TileMirror |
❌ 实例 |
classTileMirrorEssentia |
thaumcraft.common.tiles.TileMirrorEssentia |
❌ 实例 |
classTileJarBrain |
thaumcraft.common.tiles.TileJarBrain |
❌ 实例 |
classTileWandPedestal |
thaumcraft.common.tiles.TileWandPedestal |
❌ 实例 |
classTilePedestal |
thaumcraft.common.tiles.TilePedestal |
❌ 实例 |
classTileDeconstructionTable |
thaumcraft.common.tiles.TileDeconstructionTable |
❌ 实例 |
classBlockJar |
thaumcraft.common.blocks.BlockJar |
✅ public static |
classBlockMirror |
thaumcraft.common.blocks.BlockMirror |
✅ public static |
classBlockStoneDevice |
thaumcraft.common.blocks.BlockStoneDevice |
✅ public static |
classBlockTable |
thaumcraft.common.blocks.BlockTable |
✅ public static |
⚠️ 8 个 TileEntity 类是实例字段(public Class 非 static),4 个 Block 类是 static(:229-240)。全部在构造函数里赋值(:23-48)。这个混用能工作(registerAddon 先 new 再用),但同一批字段用两套生命周期,是明确的风格不一致。
注册的 4 个方块
registerAddon(:209-216)对 4 个 Block 类各注册 body + NBT:
| Block 类 | 覆盖的 TileEntity |
|---|---|
BlockJar |
精华罐 / 虚空精华罐 / 脑缸 |
BlockMirror |
魔镜 / 精华魔镜 |
BlockStoneDevice |
基座 / 法杖基座 |
BlockTable |
解构台 |
⚠️ 4 个 body provider 全部只注册了 Block,没有注册对应的 TileEntity 类。这符合 WAILA 1.7.10 的 API(注册粒度是 Block,handler 内部自行 compareTileEntityByClass)。
5 组 HUD 行
整体前置守卫:data.getBlock() != null && data.getTileEntity() != null(:67)。5 组之间是平行的 if,不是 else if。
1. 精华罐 / 虚空精华罐
compareTileEntityByClass(te, classTileJarFillable) || ...(te, classTileJarFillableVoid)
| 门控键 | 输出 | 数据 | 附加条件 |
|---|---|---|---|
wawla.thaumcraft.jarAspect |
要素: <首字母大写> |
tag.getString("Aspect") |
!aspect.isEmpty() |
wawla.thaumcraft.jarAmount |
数量: <N> |
tag.getShort("Amount") |
amount > 0 |
⚠️ 两行的 if 条件里都硬编码了 true &&(:76 与 :80)——if (true && aspect != null && ...)。aspect 来自 getString,永不为 null(不存在的键返回空串),所以 aspect != null 判定也是死代码。这两个 true && 明显是调试时留下的残留。
2. 魔镜 / 精华魔镜
前置:... || ... 且 tag.getBoolean("linked")
| 门控键 | 输出 | 数据 |
|---|---|---|
wawla.thaumcraft.mirrorLink |
链接: X:<x> Y:<y> Z:<z> |
tag.getInteger("linkX"/"linkY"/"linkZ") |
wawla.thaumcraft.mirrorDim |
维度: <维度名> |
DimensionManager.getProvider(tag.getInteger("linkDim")).getDimensionName() |
⚠️ DimensionManager.getProvider(dimId) 无效 ID 会返回 null → .getDimensionName() NPE。linkDim 来自存档 NBT,跨维度传送或存档损坏时可能取到未注册的 ID。
3. 脑缸
wawla.thaumcraft.jarEXP 开启时输出 经验: <XP>,读 tag.getInteger("XP")。
⚠️ lang 键是 tooltip.wawla.thaumcraft.experience=经验,但 zh_CN 的选项文案是 是否显示缸中经验?(“缸”),而代码与 tooltip 键都用 “jar”(罐)。中英用词不一致。
4. 基座
wawla.thaumcraft.pedestalItem 开启时,用 Utilities.getInventoryStacks(tag, 1)[0] 取物品,非空则输出 物品: <名>。
⚠️ 必 NPE:getInventoryStacks 在 NBT 无 Items 键时返回 null,[0] 立即越界。空基座是常态。
5. 法杖基座(最复杂的一组)
⚠️ 外层也是 if (true)(:136)。
| 门控键 | 输出 | 附加条件 |
|---|---|---|
wawla.thaumcraft.wandItem |
只有法杖名,没有"物品: "前缀 | pedestalStack.hasTagCompound() |
wawla.thaumcraft.wandCharge |
6 种要素充能,用 | 分隔 |
额外要求 stackTagCompound.hasKey("aqua") |
6 种要素的着色与换算:
| 顺序 | 要素 | 颜色 | 换算 |
|---|---|---|---|
| 1 | aer(气) |
YELLOW |
/100f |
| 2 | terra(地) |
DARK_GREEN |
⚠️ / 100(整除) |
| 3 | ignis(火) |
RED |
/100f |
| 4 | aqua(水) |
DARK_AQUA |
/100f |
| 5 | ordo(秩序) |
GRAY |
/100f |
| 6 | perditio(否定) |
DARK_GRAY |
/100f |
⚠️ 缺陷:地元素充能因整除永远显示 0.0
AddonThaumcraftTiles.java:153:
+ (float) (pedestalStack.stackTagCompound.getInteger("terra") / 100)
其余 5 个都是 / 100f,唯独 terra 漏了 f 后缀。getInteger 返回 int,/ 100 是整型除法(结果 0),再转 float 恒为 0.0。
后果:任何法杖的地元素充能在 HUD 上永远显示 0.0,而其他 5 种正常。这是一处确定的 copy-paste 笔误(与 通用实体 里的 childDurationMultiplier 赋值错误同属一类)。
⚠️ 缺陷:整行用 (float) 强转会暴露 float 精度误差
getInteger("aer") / 100f 先做 int→float 的除法再强转回 float,例如 75 / 100f = 0.75f(可表示),但 1 / 100f = 0.01f(float 无法精确表示 0.01),HUD 上会显示 0.01 或 0.009999999。正确做法是保留 double。
⚠️ 缺陷:法杖名没有前缀
tip.add(pedestalStack.getDisplayName())(:142)——直接推物品名,没有 物品: 前缀,与基座那行(tooltip.wawla.item + ": ")风格不一致,玩家难以分辨这一行是什么。
⚠️ 其它缺陷
DimensionManager.getProvider 返回 null 未处理
见魔镜部分。
registerBodyProvider 收到 null 类的可能
:209-216 传 4 个 static Block 字段,Class.forName 失败时它们仍是 null(catch 只 printStackTrace,:45)。Thaumcraft 若换了包名(不同版本),这 4 次注册会全部传入 null。
upperCase 对空串不安全
:78 的 Utilities.upperCase(aspect) 有 !aspect.isEmpty() 守卫,安全;:117 由 hasKey("Aspect") 守卫——但 hasKey 为真时值仍可能是空串(写了空 Aspect),此时 Utilities.java:209 的 charAt(0) 会抛 StringIndexOutOfBoundsException。见 工具类 缺陷 5。
相关条目
- 配置项 —
Thaumcraft分类的 9 个键 - 架构与 WAILA 接入方式 — 反射取类机制与 static/实例字段混用
- 工具类 —
getInventoryStacks的 null 返回、upperCase的空串风险