配方页实现

模板化配方页

所有 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 条配方。

相关条目