配方页实现
模板化配方页
所有 handler 都继承 RecipeHandlerBase(tonius/neiintegration/RecipeHandlerBase.java),而后者继承 NEI 的 TemplateRecipeHandler——基于模板的配方页。子类不逐像素绘制界面,只需声明槽位坐标与「机器 → 配方」映射,NEI 负责渲染进度条、流体槽与翻页。
通用贴图 assets/neiintegration/textures/basicProcessing.png 即该模板的底图。
类型继承链
IRecipeHandler 本 mod 接口,extends ICraftingHandler, IUsageHandler
└── RecipeHandlerBase 本 mod 抽象实现,extends TemplateRecipeHandler
└── 各具体 handler × 32 个类
IRecipeHandler 比 NEI 原生接口多一个 void prepare()——registerHandler 在注册前调用它。RecipeHandlerBase 中是空实现,作为子类覆写钩子。
CachedRecipe 体系
RecipeHandlerBase 内部定义 CachedBaseRecipe extends CachedRecipe(NEI 的缓存配方基类),提供:
| 方法 | 用途 |
|---|---|
getFluidTanks() |
收集本配方的流体槽列表 |
getFluidTank() |
取单个流体槽,默认返回 null |
setIngredientPermutationNBT(ingredients, ingredient) |
按 NBT 精确匹配物品变体 |
setIngredientPermutationNBT 的实现用 NEIServerUtils.areStacksSameType(ingredient, stack.items[i]) 找到同类型槽位,然后把 ingredient 的 meta 与 NBT 拷贝写进去:
stack.item.setItemDamage(ingredient.getItemDamage());
if (ingredient.hasTagCompound()) {
stack.item.setTagCompound((NBTTagCompound) ingredient.getTagCompound().copy());
}
注意 .copy() ——深拷贝 NBT,避免把配方的 tag 直接共享给 NEI 缓存槽位。
流体槽绘制
PositionedFluidTank(tonius/neiintegration/PositionedFluidTank.java)用 java.awt.Point / java.awt.Rectangle 描述槽位在 GUI 上的位置与大小,配合 org.lwjgl.opengl.GL11 与 codechicken.lib.gui.GuiDraw 绘制。RecipeHandlerBase 直接 import 了 GL11 与 GuiDraw。
PositionedStack 扩展
PositionedStackAdv 扩展 NEI 的 PositionedStack,让一个槽位携带多个候选物品(stack.items 数组)——NEI 原生已支持,这里是本 mod 的封装。
4 个未注册的基类
32 个 RecipeHandler*.java 中有 4 个是基类/支撑类,从不注册:
| 类 | 所属集成 | 说明 |
|---|---|---|
RecipeHandlerElnBase |
electricalage | 4 个 ELN handler 的公共基类 |
RecipeHandlerHCBase |
harvestcraft | 6 个 HarvestCraft handler 的公共基类 |
RecipeHandlerRollingMachine |
railcraft | Shaped/Shapeless 双 handler 的公共基类 |
RecipeHandlerDumper |
mcforge | dumper 输出的展示 handler |
RecipeHandlerDumper放在mods/mcforge/根目录而非mods/mcforge/dumpers/下,与其它 10 个 dumper 的目录约定不一致,见 源码缺陷。
注册后的可见性
每个 handler 经 registerHandler 调用两次注册(registerRecipeHandler + registerUsageHandler),因此 28 个 handler 各产生 1 个合成页 + 1 个使用页 = 56 个 NEI 页面。
但注意:注册成功 ≠ 有内容。RecipeHandlerFluidRegistry 与 RecipeHandlerOreDictionary 默认关闭其配方加载分支,注册了却产出 0 条配方。
相关条目
- 架构与客户端限定 -
registerHandler的成对注册 - Minecraft / Forge 集成 - 「注册但无内容」的两个 handler
- 集成目标总览 - 32 文件 / 28 注册对照