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 阶段就退出。

相关条目