Compound Singularity(复合奇点)
基本信息
| 属性 | 值 |
|---|---|
| 注册名 | eternalsingularity:combined_singularity |
| 注册调用 | GameRegistry.registerItem(compoundSingularityItem = new CompoundSingularityItem(compoundMax), "combined_singularity")(CommonProxy.java:103-105,postInit) |
| 资源名 | "combined_singularity"(两参重载,域取 eternalsingularity) |
| 构造参数 | compoundMax = 16(CommonProxy.java:97) |
| 子类型 | 16 个,meta 0–15(setHasSubtypes(true),CompoundSingularityItem.java:34) |
| 未本地化名 | item.combined.singularity.<clamp(damage,0,16)>(行 45) |
| 稀有度 | EnumRarity.uncommon(黄色)(行 40) |
| 贴图 | 每个 meta 一对:combined_singularity_<n>.png + _overlay.png(行 73-74) |
⚠️ 该物品是条件注册的:仅当 useCompoundSingularities 为真时
才在 postInit 注册(CommonProxy.java:102-105)。
配置为假时注册名 eternalsingularity:combined_singularity 根本不存在。
同理 ClientProxy 的渲染器注册也判空(ClientProxy.java:15)。
16 个子类型
meta 与名字一一对应(en_US.lang / zh_CN.lang):
| meta | 英文 | 中文 |
|---|---|---|
| 0 | Nitronic Singularity | 氮化奇点 |
| 1 | Psychotic Singularity | 癫狂奇点 |
| 2 | Spaghettic Singularity | 意面奇点 |
| 3 | Pneumatic Singularity | 气动奇点 |
| 4 | Cryptic Singularity | 密文奇点 |
| 5 | Historic Singularity | 历史奇点 |
| 6 | Meteoric Singularity | 气象奇点 |
| 7 | Gastronomic Singularity | 美食奇点 |
| 8 | Chromatic Singularity | 艳丽奇点 |
| 9 | Prismatic Singularity | 炫光奇点 |
| 10 | Arithmetic Singularity | 机器人奇点 |
| 11 | Galactic Singularity | 银河奇点 |
| 12 | Hydrolic Singularity | 液压奇点 |
| 13 | Geologic Singularity | 地质奇点 |
| 14 | Angelic Singularity | 天使奇点 |
| 15 | Chronic Singularity | 惯习奇点 |
getSubItems 只枚举 j < max(即 0–15,CompoundSingularityItem.java:50),
所以创造栏恰好显示 16 个。lang 里另有 60 余条注释掉的
「Unused Combined Singularities」名字,没有对应贴图和 meta,不是物品。
合成方式
9 个基础奇点 → 1 个复合奇点。全部 16 条配方在 postInit 用代码批量生成
(CommonProxy.java:107-118):
for i in 0..15: # 复合奇点档位
输出 = 1 × combined_singularity (meta i)
for s in 0..8: # 每档吃 9 个
pos = 9*i + s
if pos > singularityCount-1: break
输入 = eternalSingularityRecipeInputs[pos]
即 meta i 的复合奇点 = 第 9i+1 到 9i+9 个基础奇点(isItemEqual 意义上的副本)。
用 GameRegistry.addRecipe 注册(行 117),空输入的档位跳过不注册。
输入是无序(ShapelessOreRecipe),9 个可任意排列。
注意是 ((ItemStack) input).copy()(行 115)——按物品类型计数,
不消耗 meta/NBT 差异。
在总配方中的位置
复合模式下会把永恒奇点配方的输入整体替换为 16 个复合奇点各 1 个
(CommonProxy.java:119-121):
eternalSingularityRecipeInputs.clear();
for (int i = 0; i < compoundMax; i++)
eternalSingularityRecipeInputs.add(new ItemStack(compoundSingularityItem, 1, i));
⚠️ 循环无条件添加全部 16 个,不检查该档位是否真的有合成配方。 详见 复合奇点模式 的可合成性缺陷说明。
渲染特性
与永恒奇点同款 Avaritia 宇宙渲染,但参数不同:
| 特性 | 值 | 行号 |
|---|---|---|
drawHalo |
true |
92-94 |
getHaloSize |
4 |
102-104 |
getHaloColour |
-16777216(不透明黑) |
112-114 |
getMaskMultiplier |
1.0f |
61-63 |
drawPulseEffect |
false |
107-109 |
requiresMultipleRenderPasses |
true;getRenderPasses 未覆写 → 1 |
86-89 |
getIcon 按 stack.getItemDamage() % 长度 取贴图(行 81-82)——
不做范围校验,越界 meta 会回绕到合法档位而不是崩溃,
但显示的名字走 clamp_int(getDamage(stack), 0, max)(行 45),
故名字与贴图在非法 meta 下会不一致。
已知源码问题
getIcon与getUnlocalizedName的 meta 处理不一致:前者取模回绕、 后者 clamp。构造出damage >= 16的物品栈会显示 meta 0 的名字配0 % 16 = 0之外的贴图(damage为负时更明显)。 两处均为源码原样,未做防御。@SideOnly(Side.CLIENT)标在getSubItems上(行 48-49), 而getSubItems是原版Item的通用方法(服务端也会调用以枚举物品)。 该注解在此语义上不成立,依赖SideOnly注解不产生运行时代码的巧合。- 渲染器未注册时的 NPE 风险:
getIcon依赖foregroundIcons/backgroundIcons,二者在registerIcons中按max分配(行 69-70)。 若registerIcons未被调用(资源缺失等),数组为null, 行 81-82 的foregroundIcons.length会 NPE。
相关条目
- 复合奇点模式 - 何时启用、如何分组
- Eternal Singularity - 最终产物
- useCompoundSingularities - 决定本物品是否存在
- 无限催化剂配方替换 - 基础奇点从哪来