EnderStorageRecipe
基本信息
| 属性 | 值 |
|---|---|
| 类 | codechicken.enderstorage.common.EnderStorageRecipe |
| 接口 | IRecipe(RecipeSorter.Category.SHAPED,id enderstorage:recolour) |
| 注册点 | EnderStorageProxy.init → EnderStorageRecipe.init() |
| 配方数量 | 49 条(1 条改色 + 16×3 = 48 条颜色基础)+ 0/1 条原版 ender chest 配方 |
| OreDictionary | 16 色染料全部按 dyeBlack/Red/Green/.../White 字符串匹配 |
功能
EnderStorageRecipe 是 EnderStorage 全部合成配方的注册入口,负责三件事:
- 注册一个 6 槽的"染色"工作台配方(
enderstorage:recolour)。 - 注册 16 色 16 条 Ender Chest / 16 条 Ender Tank / 16 条 Ender Pouch 的基础合成。
removeVanillaChest(disable-vanilla=true时由proxy.preInit调用)替换/移除原版Blocks.ender_chest的物品并清理所有合成输出为Blocks.ender_chest的合成配方。
改色配方(enderstorage:recolour)
工作台布局(6 槽):
. X . ← 第 row 行放 1 个 Ender Chest/ItemEnderStorage(Pouch 不可染色)
Y D Y ← 第 row+1 行放 1 个染料(左侧红/中绿/右蓝)
. X .
代码侧只支持"左列 + 染料行"或"右列 + 染料行"两种 layout(offsetMatchesDyes(col=0, row) 双重循环);最终输出是一个 freq 分量被改写、其它分量保留的 Ender Chest/ItemEnderStorage(Pouch 不参与)。Pouch 在合成中只能作为"染色基础物品"的来源:但 stackMatches 检查的是 Item.getItemFromBlock(EnderStorage.blockEnderChest),所以 Pouch 不能被这个配方染色。
matches
for (int row = 0; row < 2; row++) if (offsetMatchesDyes(ic, 0, row)) return true;
return false;
offsetMatchesDyes(ic, col, row)
- 必须位置
(col+1, row+1)是 Ender Chest/ItemEnderStorage(任何 freq)。 - 整张 3×3 网格除了"(col+1, row+1) 这个 Ender Chest"以及"染料行的 3 格"以外必须为空。
- 染料行(
i=row)必须至少有一个染料(16 个 OreDictionary 名字 +Items.dye+EnderStorageDyeTool)。
getCraftingResult
recolour(0, row, freq, ic)、recolour(1, row, freq, ic)、recolour(2, row, freq, ic) 对每个颜色分量取"该位置是否放了染料"决定是替换还是保留,最后输出 getFreqFromColours(colour3, colour2, colour1) | (freqownerDamage & 0xF000)(保留种类 meta)。
注意
getFreqFromColours(c3, c2, c1)三个参数顺序与addTraceableCuboids中的 subHit 顺序一致(subHit=1→c1、subHit=2→c2、subHit=3→c3),但getCraftingResult这里传的是(c3, c2, c1)——这是 EnderStorage 配方设计上的一个反向语义:工作台中"左列染料=subHit 1"(红/高 4-bit)、“右列染料=subHit 3”(蓝/低 4-bit)。
基础合成(addNormalRecipies,16 色 ×3 = 48 条)
Ender Chest
b W b
O C O
b p b
b = Items.blaze_rodW = Blocks.wool(meta 0–15,循环 16 次)C = Blocks.chestO = Blocks.obsidianp = Items.ender_pearl- 输出:
enderstorage:enderChest(meta=0),freq =getFreqFromColours(i, i, i)。
Ender Tank
同 Ender Chest 模板,把 C 换成 Items.cauldron:
- 输出:
enderstorage:enderChest(meta =1 << 12),freq =getFreqFromColours(i, i, i)。
Ender Pouch
b l b
l p l
p b W
b = Items.blaze_powderl = Items.leatherp = Items.ender_pearlW = Blocks.wool(meta 0–15)- 输出:
enderstorage:enderPouch,freq =getFreqFromColours(i, i, i)。
模板字符行数为 4 而工作台只有 3 行——由代码生成的配方面板表示 4 行字符串(
"blb"/"lpl"/"pb"/"bWb")但 Forge 的 shaped 模板会把第 4 行当成无字符的位置(直接被默认跳过);实际配方效果取决于RecipeSorter.Category.SHAPED的长度定义。可以理解为把blb/lpl/pb/bWb看作"前 3 行实际在工作台 + 第 4 行注释",或者看作 4 行 but only first 3 in grid。
removeVanillaChest
仅在 EnderStorage.disableVanillaEnderChest = true 时调用:
GameDataManipulator.replaceItem(Block.getIdFromBlock(Blocks.ender_chest), new ItemEnderChestDummy())—— 把原版 ender chest 的物品替成空实现的 dummy(保留可合成性但不放置方块)。- 遍历
CraftingManager.getInstance().getRecipeList(),删除所有输出为Blocks.ender_chest的配方。 - 如果
EnderStorage.removeVanillaRecipe = false,重新注入原版配方("OOO" / "OeO" / "OOO")。 - 如果
EnderStorage.removeVanillaRecipe = true,原版配方就永远被删除。
该方法使用
codechicken.core.featurehack.GameDataManipulator直接改写游戏注册表(runtime hack),不持久化到世界数据。
getDyeType(ItemStack item)
按顺序匹配:
Items.dye→itemDamage- 16 个 OreDictionary 名字(
dyeBlack/dyeRed/…/dyeWhite)→OreDictionary.itemMatches(target, item, false) EnderStorageDyeTool→ 调getDye(item)- 都不匹配返回
-1
getDyeColour(String) 反向查表:根据 oreDictionaryNames[i].substring(3)(剥掉 dye 前缀)与字符串对比(不区分大小写),返回 0–15;找不到返回 -1(被 /enderstorage 命令用来校验三色字符串)。
第三方 mod 集成
- CodeChickenCore:
GameDataManipulator(来自codechicken.core.featurehack)做注册表替换。 - OreDictionary:所有 16 色染料 +
EnderStorageDyeTool在getDyeType路径中都可被识别,所以其他 mod 注册为标准染料的物品同样可用。 - DreamCraft:当
Loader.isModLoaded("dreamcraft")时addNormalRecipies()整体跳过,依赖 DreamCraft 自带的 GTNH 配方。
相关条目
- Ender Chest - 基础合成输出
- Ender Tank - 基础合成输出
- ItemEnderStorage - 染色配方的目标物品
- Ender Pouch - 基础合成输出
- EnderStorage API -
getFreqFromColours实现 - 配置项 -
removeVanillaRecipe/disableVanillaEnderChest