智能工作台背包配方

[!INFO] 注册真源:RecipeHelper.registerRecipes() 末尾 GameRegistry.addRecipe(new RecipeIntelligentWorkbenchBackpack()) 实现类:de.eydamos.backpack.recipes.RecipeIntelligentWorkbenchBackpack

基本信息

给 工作台背包 打上 intelligent NBT 标记的配方。

属性 值
配方尺寸 getRecipeSize() 返回 2
形状 任意 2 格(一个包 + 一本书)
注册条件 无条件,不受任何 DISABLE_* 开关控制
NBT 键 Constants.NBT.INTELLIGENT = "intelligent"

匹配逻辑(RecipeIntelligentWorkbenchBackpack.matches)

for (int i = 0; i < craftingGridInventory.getSizeInventory(); i++) {
    slotStack = craftingGridInventory.getStackInSlot(i);
    if (slotStack != null) {
        if (slotStack.getItem() instanceof ItemWorkbenchBackpack) {
            if (backpack != null) return false;     // 不允许两个包
            backpack = slotStack;
        } else if (slotStack.getItem() == Items.writable_book) {
            if (book) return false;                // 不允许两本书
            book = true;
        } else { return false; }                   // 其它物品一律拒绝
    }
}
if (backpack != null && book) {
    result = backpack.copy();
    NBTItemStackUtil.setBoolean(result, Constants.NBT.INTELLIGENT, true);
}

要点:

  1. 空槽被静默跳过(if (slotStack != null) 无 else 分支), 所以合成栏里只放这 2 个物品即可,其余 7 格留空。
  2. 唯一合法的书是 Items.writable_book(可写书,即书与笔), 不是 written_book(已写书)。
  3. 结果是背包的 copy() —— UUID 保留,不丢容器数据。

intelligent 标记是一次性中转,会被事件处理器回收

这是本配方最容易被误解的地方:intelligent 不是写死在物品上的永久标签, 而是在合成瞬间挂到输出栈上、随后由事件处理器转存进背包存档的中转标记。

流程分三步:

  1. 配方(RecipeIntelligentWorkbenchBackpack:46)把 INTELLIGENT 写到 result 这个刚生成的 ItemStack 上:
    NBTItemStackUtil.setBoolean(result, Constants.NBT.INTELLIGENT, true);
    
  2. 事件(EventHandlerBackpack.itemCrafted:132,@SubscribeEvent)在 ItemCraftedEvent 中检测到该标记后,把它转存进 BackpackSave:
    BackpackSave backpackSave = new BackpackSave(craftedItem);
    backpackSave.setIntelligent();                                  // 写进存档 NBT
    NBTItemStackUtil.removeTag(craftedItem, Constants.NBT.INTELLIGENT);  // 回收中转标记
    
  3. 持久化(BackpackSave.setIntelligent:125)写入 NBTUtil.setBoolean(nbtTagCompound, Constants.NBT.INTELLIGENT, true), 并在非手动保存模式下立即 save()。

因此:

  • 背包存档 NBT 里长期保留 intelligent,tooltip 由此显示 tooltip.intelligent(ItemWorkbenchBackpack:61)。
  • 物品栈顶层的那个中转标签在合成完成后即被移除, 直接在物品 NBT 里看到 intelligent 的「裸标签」是不该出现的中间态。
  • 事件处理器只在物品是 ItemsBackpack.workbenchBackpack 时才处理, 所以这个中转标记对本配方是专属的。

⚠️ 死常量:Constants.NBT.RECIPES 与 NBT.RECIPE 从未被使用

Constants.NBT 中声明了:

public static final String INVENTORY_RECIPES = "recipes";
public static final String INVENTORY_RECIPE = "recipe-";

全仓 grep 后没有任何 Java 代码读取或写入这两个键(Constants.NBT.RECIPES / NBT.RECIPE 在 src/main/java 下零引用)。 即本模组没有「自动记忆上次摆放的配方」功能 —— 名称中的 intelligent 仅代表上面这个标记机制本身。任何关于配方记忆的说法都与源码不符。

书不被消耗

result 只复制背包,书既不进入结果也不减少数量。 对已带 intelligent 的背包再放一次,只会重复走一次 「转存 → 回收中转标签」的无害流程,最终状态不变。

与其它两个自定义配方的对照

配方 尺寸 是否要求满格 是否可递归应用
RecipeEnhanceBackpack 9 是(9 格全满) 改变 metadata
RecipeRecolorBackpack 不限 否 改变 metadata
本配方 2 否(空槽跳过) 幂等,仅置标记

三者都无条件或近乎无条件注册,但只有升级配方受 DISABLE_BIG_BACKPACKS 控制。

相关条目