Crucible Recipes
Crucible crafting is performed at the Crucible and transforms items by cooking them in aspect-tagged liquid. It is the primary way to create alchemical ingredients and some Thaumcraft components.
Registration
ThaumcraftApi.addCrucibleRecipe(String key, // Research key
ItemStack result, // Output item
Object catalyst, // ItemStack, String (Ore Dict), or ArrayList<ItemStack>
AspectList tags) // Aspect requirements
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
String |
Research key required to discover/use this recipe |
result |
ItemStack |
The output item |
catalyst |
Object |
Input item(s) being cooked; ItemStack, String (Ore Dict), or ArrayList<ItemStack> |
tags |
AspectList |
Aspects that must be present in the crucible for the recipe to fire |
Example: Single Item Catalyst
ThaumcraftApi.addCrucibleRecipe("RESEARCH_KEY",
new ItemStack(TCItems.itemResource, 1, 2), // Salis Mundus
new ItemStack(Items.diamond),
new AspectList()
.add(Aspect.EARTH, 10)
.add(Aspect.ORDER, 5));
Example: Ore Dictionary Catalyst
// Uses any item registered to the "gemDiamond" Ore Dictionary entry
ThaumcraftApi.addCrucibleRecipe("RESEARCH_KEY",
new ItemStack(TCItems.itemResource, 1, 2),
"gemDiamond", // String → OreDictionary
new AspectList()
.add(Aspect.EARTH, 10)
.add(Aspect.ORDER, 5));
Example: Multiple Possible Catalysts
ThaumcraftApi.addCrucibleRecipe("RESEARCH_KEY",
new ItemStack(TCItems.itemResource, 1, 3),
new ArrayList<ItemStack>(Arrays.asList(
new ItemStack(Blocks.dirt),
new ItemStack(Blocks.cobblestone)
)),
new AspectList().add(Aspect.EARTH, 8));
CrucibleRecipe Class
public class CrucibleRecipe {
private ItemStack recipeOutput;
public Object catalyst;
public AspectList aspects;
public String key;
public int hash;
}
Constructor
public CrucibleRecipe(String researchKey, ItemStack result, Object cat, AspectList tags)
The constructor accepts the same parameters as addCrucibleRecipe. When catalyst is a String, it resolves immediately to an ArrayList<ItemStack> via OreDictionary.getOres().
A hash is computed from researchKey + result.toString() plus, for each entry, tag + amount, plus the catalyst.
⚠️ 订正:原文写成
... + all aspect tags/amounts + catalyst.toString()——催化剂部分的描述不准确。 真实逻辑(crafting/CrucibleRecipe.java构造器内hc累加):
hc = researchKey + result.toString()- 遍历
tags:对每个Aspect追加a.getTag() + amount- 若
catalyst instanceof ItemStack:追加该 ItemStack 的toString()- 否则(
ArrayList):逐个追加每个 ItemStack 的toString()即追加的是各个 ItemStack 的
toString(),不是ArrayList.toString()。 反查入口是getCrucibleRecipeFromHash(int hash)(ThaumcraftApi.java:274)。
Methods
| Method | Returns | Description |
|---|---|---|
matches(AspectList itags, ItemStack cat) |
boolean |
Checks if the given aspects and catalyst satisfy this recipe |
catalystMatches(ItemStack cat) |
boolean |
Checks if the catalyst matches (without checking aspects) |
removeMatching(AspectList itags) |
AspectList |
Returns a new AspectList with this recipe’s aspects removed |
getRecipeOutput() |
ItemStack |
The output ItemStack |
matches()
public boolean matches(AspectList itags, ItemStack cat)
Returns true only if:
- The catalyst matches the input item (
ThaumcraftApiHelper.itemMatchesor Ore Dictionary match) - The crucible’s aspect pool contains at least the required amount of each aspect
// Aspect sufficiency check
for (Aspect tag : aspects.getAspects()) {
if (itags.getAmount(tag) < aspects.getAmount(tag)) return false;
}
removeMatching()
public AspectList removeMatching(AspectList itags)
Returns a new AspectList with this recipe’s aspect costs subtracted. The original AspectList is not modified.
AspectList remaining = recipe.removeMatching(currentAspectsInCrucible);
catalystMatches()
public boolean catalystMatches(ItemStack cat)
A fast check for catalyst compatibility without validating aspect requirements.
Finding Recipes
// By output ItemStack
CrucibleRecipe recipe = ThaumcraftApi.getCrucibleRecipe(ItemStack stack);
// By computed hash
CrucibleRecipe recipe = ThaumcraftApi.getCrucibleRecipeFromHash(int hash);
// Iterate all crucible recipes
for (Object r : ThaumcraftApi.getCraftingRecipes()) {
if (r instanceof CrucibleRecipe) {
CrucibleRecipe cr = (CrucibleRecipe) r;
// ...
}
}
Research Key Caching
⚠️ 已订正(两处)
① 键类型错:原文写「maps output ItemStacks to their research key and page index」且
private static HashMap<Object, Object[]> keyCache——类型错。真实声明是private static HashMap<int[], Object[]> keyCache(证据:ThaumcraftApi.java:289), 键是int[]{itemId, itemDamage}二元组,不是 ItemStack 本身。 写入处可见键的构造:key = new int[]{stack.getItem().getId(), stack.getItemDamage()}(ThaumcraftApi.java:307,写入见309、316)。② 更新者错:原文写「The
getCrucibleRecipemethod also updates this cache」——这是错的。getCrucibleRecipe(ThaumcraftApi.java:260-268)只读不写 keyCache; 实际读写该缓存的是getCraftingRecipeKey(EntityPlayer, ItemStack)(ThaumcraftApi.java:290-330:读293-296,写309、316、325)。 全仓 grepkeyCache只命中ThaumcraftApi.java的289/293/294/295/296/309/316/325八行,均在getCraftingRecipeKey作用域内。
缓存值是 new Object[]{ri.key, a}(ThaumcraftApi.java:309/316),即 {研究键, 页码索引}。
getCraftingRecipeKey 会先用 ThaumcraftApiHelper.isResearchComplete(playerName, (String)keyCache.get(key)[0])
判断该研究是否已完成(ThaumcraftApi.java:295),未完成则返回 null。
缓存用途按 javadoc 是 thaumonomicon 的 drilldown(钻取)功能,不是「解锁配方提示」。