无限催化剂配方替换(核心机制)
基本信息
| 属性 | 值 |
|---|---|
| 所属 | Eternal Singularity(modid eternalsingularity) |
| 发生阶段 | postInit(CommonProxy.postInit,CommonProxy.java:66-127) |
| 作用对象 | Avaritia 的 Grinder.catalyst(无限催化剂)配方 |
| 产物 | 交给 Eternal Singularity 的 ShapelessOreRecipe |
这是本 mod 的唯一实质功能:把散落在 Avaritia 无限催化剂配方里的 各种奇点抽走,改造成一个需要「集齐全部奇点」的聚合配方。
执行步骤
1. 前置判定(CommonProxy.java:67-70)
if (classSet.isEmpty() || craftingOnly) {
classSet = null; // Destroy reference
return;
}
两个条件都会直接 return,不打任何日志:
| 条件 | 含义 |
|---|---|
classSet.isEmpty() |
名单里的奇点物品类一个都没找到(见 奇点物品类名单) |
craftingOnly |
Avaritia 的 fox.spiteful.avaritia.Config.craftingOnly 为真(仅合成模式) |
⚠️ 早退时 eternalSingularityRecipe 保持 null,
但 preInit 已注册的 EternalSingularityItem 仍在创造栏里 —— 物品存在但无配方。
2. 抽取奇点(CommonProxy.java:71-81)
遍历 Grinder.catalyst.getInput(),对每个 ItemStack 取 getItem().getClass(),
若该类在 classSet 中则 iterator.remove() 移除,并 .copy() 存入 singularities。
| 细节 | 说明 |
|---|---|
| 匹配依据 | 物品的 Java 类,不是注册名、不是 ItemStack 相等 |
| meta / NBT | .copy() 保留原 meta;判定只看类 |
| 重复项 | 若无限催化剂里同一奇点出现多次,每份都单独收集 |
因为是移除,Avaritia 原无限催化剂配方里就不再有这些奇点了。
3. 构建聚合配方(CommonProxy.java:98-101)
(eternalSingularityRecipe = new ShapelessOreRecipe(
new ItemStack(EternalSingularityItem.instance,
easyMode ? MathHelper.clamp_int(compoundMax, 1, 64) : 1)))
.getInput().addAll(singularities);
无序配方,输出 1 个(或 easyMode 下 16 个)永恒奇点。
4. 挂载与回填(CommonProxy.java:123-124)
ExtremeCraftingManager.getInstance().getRecipeList().add(eternalSingularityRecipe);
Grinder.catalyst.getInput().add(new ItemStack(EternalSingularityItem.instance));
聚合配方进 Avaritia 终极合成管理器;同时把永恒奇点本身 加回无限催化剂配方,形成「聚合 ↔ 无限」的双向闭环。
最后 classSet = null(行 126)主动断开引用。
依赖
代码直接 import Avaritia 内部类(CommonProxy.java:3,22-23):
| 类 | 用途 |
|---|---|
fox.spiteful.avaritia.Config.craftingOnly |
仅合成模式判定 |
fox.spiteful.avaritia.crafting.ExtremeCraftingManager |
挂载聚合配方 |
fox.spiteful.avaritia.crafting.Grinder |
无限催化剂配方本体 |
@Mod 声明 required-after:Avaritia(EternalSingularityMod.java:30),
所以 Avaritia 缺失时 FML 直接拒绝加载,本 mod 无法单独运行。
已知源码问题
- 早退完全静默:行 67-70 两个失败条件都不打日志。 表现是「创造栏里有永恒奇点但怎么都做不出来」,玩家无从判断原因。
- 配方为 null 时脚本 API 会 NPE:
EternalRecipeTweaker在 preInit 就注册(CommonProxy.java:56,仅判Loader.isModLoaded("MineTweaker3")), 而脚本动作在 postInit 之后才 apply。若本 mod 在行 67 早退,getEternalSingularityRecipe()返回null,Add.apply()(EternalRecipeTweaker.java:48)会对null调getInput()抛 NPE。 源码未做判空。 EternalRecipeTweaker.Remove构造时即遍历:Remove的构造函数 (EternalRecipeTweaker.java:81-90)在构造阶段就遍历当前输入列表查找匹配项, 而apply()在之后才真正 remove(行 94)。若两者之间有其它脚本改动输入,this.itemStack会是null,此时canUndo()尚返回false(行 98-100), 但apply()已在remove(null)上执行 —— 对ArrayList而言无害, 源码却未做此防护。craftingOnly来自 Avaritia 的静态配置字段(行 3 的静态 import), 读取时机在 postInit。若 Avaritia 之后才加载该配置,本 mod 读到的是旧值。
相关条目
- Eternal Singularity - 聚合配方的产物
- 复合奇点模式 - 奇点太多时的分组打包
- 奇点物品类名单 - 决定从催化剂里抽走哪些
- easyMode - 影响本配方输出数量
- CraftTweaker 脚本接口 - 运行时改动本配方输入