通用方块 addon(AddonGenericTiles)
基本信息
| 属性 | 值 |
|---|---|
| 文件 | src/main/java/net/darkhax/wawla/addons/generic/AddonGenericTiles.java(204 行) |
| 实现接口 | mcp.mobius.waila.api.IWailaDataProvider |
| 注册方式 | Wawla.java:50-51 无条件 IMC |
| 注册粒度 | registerBodyProvider(dataProvider, Block.class)(:191)——对所有方块生效 |
| 配置分类 | Wawla-General(局部变量名 catagory,拼写错误) |
| 配置项数 | 10 |
这是 WAWLA 覆盖面最广的一个 addon:它注册在 Block.class 上,因此每一行 HUD 都会经过它。
9 个注册方法中只有 Body 被重写
| WAILA 回调 | 本类实现 |
|---|---|
getWailaStack |
原样返回 data.getStack() |
getWailaHead |
空实现 |
getWailaBody |
全部逻辑在这里 |
getWailaTail |
空实现 |
getNBTData |
if (te != null) te.writeToNBT(tag) |
⚠️ registerNBTProvider 从未被调用——AddonGenericTiles 只注册了 body provider,方法体里的 getNBTData 因此不会被本 addon 触发。AddonVanillaTiles 同样只注册了 registerBodyProvider + registerNBTProvider(成对),而本类连 NBT 都没注册。
HUD 行逐条拆解
按 getWailaBody 的执行顺序:
1. 可否采集 / 需求工具 / 需求等级
前置条件:item != null 且 手持物的工具类包含该方块的 getHarvestTool(),或 AddonTinkersTiles.canHarvest(item, tool) 为真。
| 条件 | 输出行 | 门控键 |
|---|---|---|
blockLevel <= itemLevel || blockLevel == 0 |
可采集: 是(深绿) |
wawla.harvest.showHarvest |
| 否则 | 可采集: 否(红) |
同上 |
| 否则 | 需求等级: <blockLevel> |
wawla.harvest.showTier |
| 否则 | 所需工具: <本地化名 或 tool> |
wawla.harvest.showTool |
工具名的本地化走 tooltip.wawla.tooltype.<tool>(lang 里只有 shovel/pickaxe/axe 三个),并用 translation.startsWith("tooltip.wawla.tooltype.") 判定是否缺翻译,缺了就退回显示原始 tool 字符串。
"凿子"修正逻辑(:50-55):Chisel(Equivalent Trades 3)会把方块的 getHarvestTool() 报成 "chisel",导致采集判定恒为假。源码对此做了特判——Blocks.stone 当作 pickaxe、Blocks.planks 当作 axe。
2. 亮度等级
触发条件:方块正上方不是正常立方体 或 正上方是空气。
| 显示 | 门控键 |
|---|---|
亮度等级: <night> —— ≤7 深红、>7 绿 |
wawla.light.monsterSpawn |
追加 (<day>),黄色 |
wawla.light.showDay |
day/night 分别用 Utilities.getBlockLightLevel(world, x, y, z, true/false),该方法读的是 y + 1(正上方一格),且 day=true 传遮蔽值 0、false 传 16。
⚠️ 若 monsterSpawn 与 showDay 都关闭,display 仍会是一个只有前缀 "亮度等级: " 的空行并被 tip.add(:114-125)——会留下一行没有数值的提示。
3. 硬度 / 爆炸抗性(默认关闭)
| 行 | 门控键 | 默认 |
|---|---|---|
硬度: <getBlockHardness> |
wawla.info.showHardness |
false |
爆炸抗性: <getExplosionResistance(player)> |
wawla.info.showResistance |
false |
爆炸抗性传的是 data.getPlayer(),即当前玩家——不同玩家的结果可能不同。
4. 挖掘进度(仅客户端)
:141 用 data.getPlayer().worldObj.isRemote 兜底判断客户端。进度 = Utilities.getBlockDamage()(反射读 PlayerControllerMP)取整后 ×100 显示为 工作时间: N%。progress > 0 才输出。
5. 床可睡性
block.isBed(...) 为真时输出 可睡眠: <true/false>,判定逻辑见 Utilities.canPlayerSleep(未在睡 + 存活 + 世界时间 ∈ (12541, 23458))。
⚠️ 源码缺陷
缺陷 1:block 被解引用但只在同行局部做了 null 保护,逻辑不自洽
:43-46:
Block block = data.getBlock();
ItemStack item = data.getPlayer().getHeldItem();
String tool = (block != null) ? block.getHarvestTool(data.getMetadata()) : "";
int blockLevel = block.getHarvestLevel(data.getMetadata()); // ← 无 null 保护
作者明确考虑了 block 可能为 null(:45 写了三元判断),但紧接着 :46 直接解引用。同样的不一致还有 :151 的 block.isBed(...)。
这在实践中大概率不会崩(WAILA 对 Block.class provider 一般传非 null 的 block),但同文件内两套 null 策略并存是客观的不一致。真正依赖这个 null 安全的是 :52-54 的凿子特判——tool 在 block == null 时是 "",.equalsIgnoreCase("chisel") 为假,因此不会走到 block == Blocks.stone。
缺陷 2:亮度行可能输出空值
见上文第 2 条——两个着色开关都关时仍 tip.add。
缺陷 3:display 字符串拼接把格式码和数值粘在一起,末尾无重置码
:118-123 用 EnumChatFormatting.DARK_RED + "" + nightLevel + " " 的方式拼接。nightLevel 与 dayLevel 之间插的是 split = EnumChatFormatting.WHITE + " | "(在 神秘时代 里),本方法里括号部分前也没有显式重置色。
缺陷 4:变量名 catagory 拼写错误
:179 String catagory = "Wawla-General";。仅命名问题,不影响功能。
与其他 addon 的耦合
AddonGenericTiles 会跨 addon 调用 AddonTinkersTiles.canHarvest(item, tool)(:59),这是 WAWLA 内部唯一的 addon 间调用。该方法内部用 isEnabled 守卫,而 isEnabled 存在初始化顺序缺陷——见 Tinkers 集成。
相关条目
- 配置项 —
Wawla-General的 10 个开关 - 工具类 —
getBlockLightLevel/canPlayerSleep/getBlockDamage - Tinkers 集成 —
canHarvest的实现与缺陷 - 原版方块 addon — 同样是
Block.class粒度的兄弟实现