复合奇点模式(9 合 1 分组)
基本信息
| 属性 | 值 |
|---|---|
| 所属 | Eternal Singularity(modid eternalsingularity) |
| 开关 | 配置 useCompoundSingularities(见 配置项) |
| 常量 | compoundMax = 16(CommonProxy.java:97) |
| 代码位置 | CommonProxy.java:102-122 |
奇点种类多时,聚合配方的输入会过长(原版 GUI 3×3 摆不下)。 复合模式把全部奇点按 每 9 个一组打包成最多 16 个 Compound Singularity, 再用「16 个复合奇点」作为聚合配方的新输入。
分组算法
CommonProxy.java:107-118:
for (int i = 0; i < compoundMax; i++) { // i = 0..15
final ShapelessOreRecipe compoundRecipe = new ShapelessOreRecipe(
new ItemStack(compoundSingularityItem, 1, MathHelper.clamp_int(i, 0, 64)));
for (int s = 0; s < 9; s++) {
final int pos = 9 * i + s;
if (pos > singularityCount - 1) break;
final Object input = eternalSingularityRecipeInputs.get(pos);
if (!(input instanceof ItemStack)) continue;
compoundRecipe.getInput().add(((ItemStack) input).copy());
}
if (!compoundRecipe.getInput().isEmpty()) GameRegistry.addRecipe(compoundRecipe);
}
| 规则 | 值 |
|---|---|
| 每组容量 | 9 个基础奇点 |
| 组数上限 | 16(compoundMax) |
| 总容量 | 9 × 16 = 144 个基础奇点 |
| 分组依据 | 抽取顺序(singularities 列表下标),不是按种类,同类可分散在不同组 |
| 输入类型 | ItemStack.copy(),按物品类型计数,不区分 meta/NBT |
| 空组 | if (!compoundRecipe.getInput().isEmpty()) 跳过,不注册空配方(行 117) |
替换聚合配方输入(行 119-121):
eternalSingularityRecipeInputs.clear();
for (int i = 0; i < compoundMax; i++)
eternalSingularityRecipeInputs.add(new ItemStack(compoundSingularityItem, 1, i));
已知源码问题:可合成性缺口
聚合配方无条件要求全部 16 个复合奇点(行 120-121 的循环不看
该档位是否有配方),但只有非空档位才有合成配方(行 117)。
因此当基础奇点数量 singularityCount 不足时,
永恒奇点配方会引用无法获取的复合奇点 → 整条聚合配方做不出来。
按代码推算,meta 15 需要的首个下标是 9*15 = 135,
而循环条件是 pos > singularityCount - 1 才 break,
故需要 singularityCount >= 136 才能让 16 档全部非空。
而自动启用阈值是 singularityCount > 81(CommonProxy.java:84),
81 < 136。即当奇点数量落在 82–135 区间时:
useCompoundSingularities被强制为真(行 90 的|| aboveTheLimit)- 只有前 ⌈N/9⌉ 档有配方
- 聚合配方却要求 16 档 → 永恒奇点不可合成
源码未对「档位总数 < compoundMax」做任何回退或裁剪。 实际整合包通常奇点数量远超 136,故该缺陷不易触发。
其它源码问题
- 分组顺序依赖抽取顺序:
singularities的顺序来自对Grinder.catalyst.getInput()的遍历顺序(见 无限催化剂配方替换), 而该顺序由 Avaritia 及其它 mod 的注册顺序决定。 因此同样的奇点集合在不同整合包/不同加载顺序下可能被分到不同档位, 复合奇点的 meta 与内容不保证稳定对应。 - 物品在 postInit 才注册(行 103-105),
但
Class/ItemStack引用在EternalItemRenderer注册时判空处理 (ClientProxy.java:15),逻辑上没错,但使该物品无法被其它 postInit 更早的 mod 依赖。 MathHelper.clamp_int(i, 0, 64)是冗余的(行 109):i来自for (i = 0; i < compoundMax=16; ...),恒在 0–15 内, clamp 永远不会改变取值。属防御性死代码。
相关条目
- Compound Singularity - 16 个 meta 的定义与名字
- 无限催化剂配方替换 -
singularities从何而来 - useCompoundSingularities - 开关与自动阈值 81
- easyMode - 影响聚合配方输出数量