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。

相关条目