Ex Nihilo 集成
基本信息
| 属性 | 值 |
|---|---|
| 类型 | WAILA(Waila)数据提供者注册(Ex Nihilo addon) |
@Mod 类 |
net.bdew.neiaddons.exnihilo.AddonExnihilo,modid NEIAddons|ExNihilo |
| 目标 mod | exnihilo + Waila(两条裸 modid 依赖) |
| 侧 | 仅客户端(checkSide(side) { return side.isClient(); }) |
| 接口 | mcp.mobius.waila.api.IWailaDataProvider × 3(不是 NEI 接口) |
| 注册方式 | FMLInterModComms 发给 Waila,不走 NEI |
| 编译期依赖 | implementation('com.github.GTNewHorizons:waila:1.19.30:dev') |
这是全 mod 唯一完全不含 NEI 代码的 addon。loadClient() 的方法体是空的,只有一行注释:
// Currently this addon includes only some WAILA handlers
它注册的东西只在 NEI 物品列表里间接可见(tooltip 文本),不会出现在 NEI 配方页里。
注册链路
init(Side) 只有两句:
active = true;
FMLInterModComms.sendMessage("Waila", "register", "net.bdew.neiaddons.exnihilo.WailaHandler.loadCallback");
Waila 侧反序列化并回调 WailaHandler.loadCallback(IWailaRegistrar reg),那里才是真正的注册:
| 目标 TileEntity 类 | 绑定的 provider |
|---|---|
exnihilo.blocks.tileentities.TileEntityBarrel |
waila/BarrelHandler |
exnihilo.blocks.tileentities.TileEntityCrucible |
waila/CrucibleHandler |
exnihilo.blocks.tileentities.TileEntityBeeTrap |
waila/BeeTrapHandler |
三个类都用 Utils.getAndCheckClass(..., TileEntity.class) 反射加载。loadClasses() 抛异常或任一 registerBodyProvider 失败时,被 catch (Throwable t) 兜住并打 "WAILA support load failed: %s"(%s 接的是 t.toString())。
三个 provider 的输出
三者都实现完整的 IWailaDataProvider 契约,但行为高度收敛:getNBTData 只 return tag 原样透传;getWailaStack 一律 return null(不改变 Waila 显示的物品图标);getWailaHead 与 getWailaTail 一律 return currenttip 不加工。全部逻辑都在 getWailaBody。
数值格式化:BarrelHandler 与 BeeTrapHandler 用 new DecimalFormat("0.0"),CrucibleHandler 用字段 dec(同样是 DecimalFormat("0.0"))。
| Provider | 读的 NBT 键 | 显示条件 | 文案 |
|---|---|---|---|
BarrelHandler |
volume(float)、timer(int)、fluid(short) |
fluid.getID() == FluidRegistry.LAVA.getID() 且 volume > 0 且 accessor.getBlock().getMaterial().getCanBurn() |
bdew.exnihilo.barrel.burn = "Will burn in %s seconds!!!",参数 decFormat.format((400F - timer) / 20),整行包 RED…RESET |
CrucibleHandler |
fluidVolume(float)、content(String 方块名)、contentMeta(int)、fluid(short) |
液体:fluid != null && fluidVolume > 0;固体:!content.isEmpty() && solidVolume > 0 |
液体 bdew.exnihilo.crucible.fluid = "Fluid: %s %s mB"(本地化名 + mB 数);固体 bdew.exnihilo.crucible.solid = "Solid: %s %s"(stack.getDisplayName() + 体积) |
BeeTrapHandler |
timer(int) |
timer > 0 |
bdew.exnihilo.beetrap.spawn = "Spawning: %s%%"(注意这里是字面双百分号),参数 decFormat.format(100F * timer / 6000) |
BarrelHandler 的语义是倒计时预警:Ex Nihilo 里装满熔岩的桶 400 tick(20 秒)后烧穿,它提前把剩余秒数报到 tooltip 上。公式 (400F - timer) / 20 直接把 tick 换成秒。
BeeTrapHandler 的进度分母是 private static int TIMER_MAX = 6000(300 秒),所以显示的是「还需多少秒出蜂」的百分比。
液体重解析
BarrelHandler 与 CrucibleHandler 都用 FluidRegistry.getFluid(tag.getShort("fluid")) 把数值 ID 换回 Fluid 对象,为 null 时直接跳过该行。跨模组组包后 Fluid ID 可能对不上,这种情况下 tooltip 会静默少一行而不会报错。
CrucibleHandler 的固体分支用 Block.blockRegistry.getObject(content) 按名字反查方块;反查失败返回 null 时 new ItemStack((Block) null, 1, contentMeta) 会抛 NPE,但 registerBodyProvider 已注册,Waila 调用 getWailaBody 时没有 try/catch,异常会冒到 Waila 的调用栈。
与 NEI 的实际关联
Waila 的 IWailaRegistrar 与 NEI 无任何关系。两者在本 mod 里的唯一交集是时机:loadClient() 由 NEI 的 IConfigureNEI.loadConfig() 触发,但这个 addon 的 loadClient() 是空方法,实际注册早在 init() 的 IMC 消息里就完成了。
换句话说:装了 NEI Addons 但禁用了 NEI 本身,Ex Nihilo 的 Waila 提示照常工作(因为注册走 IMC,不依赖 NEI 回调)。反过来,Waila 没装时整个 addon 因 getDependencies() 含 Waila 而在 doPreInit 阶段就退出。
相关条目
- 配置文件 -
Ex Nihilo开关 - Addon 架构与加载顺序 -
checkSide与getDependencies的判定顺序 - NEI 接口实现总表 - 3 个
IWailaDataProvider在接口清单中的位置 - 网络协议 - 本 addon 不走网络