Wand Crafting Handler(魔杖合成)
基本信息
| 属性 | 值 |
|---|---|
| 类型 | NEI Recipe / Usage Handler |
| 源码类 | com.gtnewhorizons.aspectrecipeindex.nei.arcaneworkbench.WandRecipeHandler |
| 基类 | ShapedArcaneRecipeHandler |
| Overlay ID | thaumcraft.wands |
| 界面名 | aspectrecipeindex.wand_crafting.title = “Wand Crafting” |
| IMC 关联物品 | Thaumcraft:WandCasting(handler 高度 144);催化剂 Thaumcraft:blockTable:15 |
| 双分支 | GTNH_WAND_RECIPES = Loader.isModLoaded("gtnhtcwands") |
功能:展示魔杖与法杖的合成配方。这是本模组唯一不依赖 Thaumcraft 配方注册表而是自己生成配方的 handler。
常量
| 常量 | 值 | 说明 |
|---|---|---|
SCEPTRE |
"SCEPTRE" |
法杖研究键 |
ROD_WOOD |
"ROD_wood" |
木杖柄研究键——lang 覆写为 tc.research_name.ROD_wood = “Basic Thaumaturgy” |
CAP_IRON |
"CAP_iron" |
铁杖帽研究键——lang 覆写为 tc.research_name.CAP_iron = “Basic Thaumaturgy” |
GTNH_WAND_RECIPES |
Loader.isModLoaded("gtnhtcwands") |
static final,类加载时求值一次 |
VALID_RESEARCH |
WandRecipeHandler::validResearch |
谓词:研究键是否合法 |
VISIBLE_RESEARCH |
WandRecipeHandler::show |
谓词:研究键是否合法且已对玩家可见 |
ROD_wood 与 CAP_iron 被 validResearch 特判为恒定合法(否则 Thaumcraft 没有这两个 ResearchItem),同时用 lang 覆写给它们补上可读名称"基础神秘学"。
配方生成的两条路径
路径 A:无 GTNH-TC-Wands
forEachRodCap(BiConsumer, Predicate) 遍历 WandRod.rods.values() × WandCap.caps.values(),双层用 researchCheck 过滤,然后:
generateRecipes(rod, cap, researchCheck)— 先建普通魔杖配方addRecipe(wand, rod, cap, false);若researchCheck.test(SCEPTRE)通过,再generateScepterRecipe(wand.copy(), rod, cap)。generateScepterRecipe调makeScepter(wand)后addRecipe(..., true)。
makeScepter(ItemStack):写 NBT 标签 sceptre(值为 1 的 NBTTagByte),并把 metadata 设为 原值 * 3 / 2。
两种配对的材料布局(3×3,null 表示空格):
| 配方 | 布局 |
|---|---|
| 魔杖 | 第 1 行:空、空、杖帽;第 2 行:杖柄、空、杖帽;第 3 行:全部空 |
| 法杖 | 第 1 行:空、杖帽、itemResource metadata 15;第 2 行:杖柄、杖帽、杖帽;第 3 行:全部空 |
ConfigItems.itemResource 的 metadata 15 即 Thaumcraft 的"奥术核心"类资源。
路径 B:有 GTNH-TC-Wands
改用 GTNH-TC-Wands 的 API:外层遍历 TCWandAPI.getWandWrappers(),内层遍历 TCWandAPI.getCaps(),每对取 wand.getRecipe(cap) 直接拿它生成的 ShapedArcaneRecipe。杖柄与杖帽两侧都要 validResearch / show 通过。
用途查询因此拆成 5 个独立方法(见下)。
vis 成本计算
getWandVisCost(ItemStack) 是 static 公共方法:
- 非
ItemWandCasting→ 返回空AspectList。 cost = rod.getCraftCost() * cap.getCraftCost()。- 若是法杖 →
cost = cost * 3 / 2(源码注释*= 1.5)。 - 若杖柄研究为
ROD_wood且杖帽研究为CAP_iron且不是法杖 → 直接返回空(源码注释 “Stick + iron cap wand (not scepter) costs no vis”)。 - 否则对
Aspect.getPrimalAspects()里每一个原始元素都add(aspect, cost)。
第 5 步是刻意为之:奥法工作台消耗的是"所有原始元素各多少点"的总和,而不是某几个具体元素。
createWand(rod, cap) 造出的魔杖物品,metadata 被设为 getWandVisCost(stack).getAmount(Aspect.AIR)——源码注释说明这是"折扣前的合成成本",即 metadata 直接编码成本值。
可见性判定
shouldShowWandRecipe(ItemStack):
showLockedRecipes
|| (杖柄研究已完成 && 杖帽研究已完成 && (SCEPTRE 已完成 || 该魔杖不是法杖))
三个研究键都要分别判定,因此魔杖配方可能显示出来但研究控件列出多个未完成项。
show(String research) = validResearch(research) && Util.shouldShowRecipe(research)。
用途查询
loadUsageRecipes(ItemStack) 在路径 B 下转给 loadGTNHUsageRecipes(component),依次跑 5 个方法:
| 方法 | 匹配条件 |
|---|---|
usagesForGTNHPrimalCharms |
itemResource metadata 15 且 show(SCEPTRE) → 遍历所有 SceptreWrapper × 全部 caps |
usagesForGTNHRods |
TCWandAPI.getWrapperForRod(component, false) 找到杖柄 → 遍历全部 caps 生成魔杖配方;法杖版杖柄另生成一批 |
usagesForGTNHCaps |
TCWandAPI.getWrapperForCap(component) 找到杖帽 → 遍历全部 wand wrappers |
usagesForGTNHScrewsAndConductors |
遍历 GTTier.values(),用 OreDictionary 查 screw + 材料名,或 OreDictionary.itemMatches(component, tier.getConductor(), true) 匹配导体;只处理第一个命中的 tier 后 return |
usagesForGTNHVis |
输入是 ItemAspect 且该元素 isPrimal() → wand × cap 全交叉(视作 vis 供给) |
路径 A 下 loadUsageRecipes 的 3 条分支:
itemResourcemetadata 15 且show(SCEPTRE)→ 全部法杖配方。- 输入是
ItemAspect且该元素isPrimal()→ 全部魔杖 + 法杖配方。 - 其他 → 用
OreDictionary.itemMatches分别试杖柄与杖帽,命中任一即生成全交叉。
这解释了 README 里"搜索 Gold Caps 的用途会显示它与每种杖柄的组合"。
加载路径(产物方向)
loadCraftingRecipes(ItemStack):只处理 instanceof ItemWandCasting。取出 wand.getRod(result) / wand.getCap(result) / wand.isSceptre(result),两侧研究都 validResearch 才继续;可见性用 shouldShowWandRecipe。路径 B 下用 wrapper 取配方,路径 A 下用 ArcaneWandCachedRecipe。
前置研究
| 缓存类 | 追加的研究键 |
|---|---|
ArcaneWandCachedRecipe |
法杖时先加 SCEPTRE,再加杖帽研究、杖柄研究 |
GTNHWandCachedRecipe |
wandWrapper instanceof SceptreWrapper 时加 SCEPTRE,再加杖帽研究、wandWrapper.getResearchName() |
addResearch 内部对空名与查不到 ResearchItem 的情况会跳过(addResearch 判空串,addResearch → new ResearchInfo(...) 允许 null researchItem 并显示 “N/A”)。
相关条目
- Shaped Arcane Crafting Handler - 父类,含 vis 布局与
getOtherStacks - Arcane Workbench 覆盖 - 消费本 handler 的 vis 需求来自动换魔杖
- 兼容性 -
gtnhtcwands的双分支门控 - IMC 注册消息 -
Thaumcraft:WandCasting的 handler 关联