部件材料 NBT 与 metadata 方案
28 个 ItemTGregPart 实例共用一套"材料即变体"的编码:metadata 存材料 ID,NBT 存材料名。
这是理解本 mod 全部物品行为的基础。
双字段方案
| 载体 | 字段 | 类型 | 值 |
|---|---|---|---|
ItemStack metadata |
getItemDamage() |
int | TGregworks.registry.matIDs.get(材料),默认从 1500 起分配 |
| NBT Compound | material |
String | GT Materials.mName,如 Iron / Osmiridium |
ItemTGregPart.setHasSubtypes(true) 让 metadata 参与区分物品,但这不是 0/1/2… 的定长 subtype,
而是一张最多 16383 项的动态材料 ID 表。
TGregUtils:三个 NBT 助手
vexatos.tgregworks.util.TGregUtils:
| 方法 | 行为 |
|---|---|
getTagCompound(stack) |
有则返回,没有就 new 一个并 setTagCompound 写回 |
getCompoundTag(tag, key) / getCompoundTag(stack, key) |
同上,作用在嵌套 Compound 上 |
getMaterialID(stack) |
无 material → 返回 -1;Materials.get(名字) 查不到 → 返回 0;否则返回 matIDs.get(m) |
newItemStack(m, p, amount) |
造一个 toolParts.get(p) 的 stack,metadata = matIDs.get(m),NBT material = m.mName |
getMaterialID 是 ItemTGregPart.getMaterialID(stack) 的实现体,也是 TiC IToolPart 接口要求的方法。
注意它有两个不同的"查不到"返回值:-1(连 NBT 都没有)与 0(NBT 有但材料不存在)。
0 恰好是 getDisplayName 判定"旧存档/无效物品 → 追加 (Deprecated)"的阈值。
onUpdate:自动修复 metadata
ItemTGregPart.onUpdate(stack, world, entity, par4, par5) 在物品每 tick 位于某实体(含玩家背包)
中时调用:
data = getTagCompound(stack)
if (!data.hasKey("material")) return; // 无 material → 不动
m = Materials.get(data.getString("material"))
matID = TGregworks.registry.matIDs.get(m)
if (matID != null && matID != stack.getItemDamage())
stack.setItemDamage(matID); // 同步 metadata
这条逻辑是旧存档迁移路径:早期版本用 damage = 0 + NBT 区分材料,
后来改成 damage = 材料ID + NBT 冗余。放进背包一次就自动升级。
废弃标记
getItemStackDisplayName(stack):
material缺失 或Materials.get(名字) == Materials._NULL→ 材料名取本地化键tgregworks.materials.unknown(zh_CN「未知」);- 否则取
Materials.get(名字).mLocalizedName; - 把语言条目
tgregworks.toolpart.<partname 去空格转小写>里的%%material替换成材料名 ——语言条目本身已经写成%%material Pickaxe Head这种形状,替换后得到铁 Pickaxe Head; stack.getItemDamage() == 0时追加tgregworks.tool.deprecated(en(Deprecated)/ zh_CN(不推荐使用))。
getUnlocalizedName(stack) 返回 Materials.get(...).mDefaultLocalName(无本地化,
仅用于 debug/日志),getUnlocalizedName() 无参版返回 type.getPartName()(即 "Pickaxe Head" 这类英文原串)。
getSubItems:创造栏枚举
ItemTGregPart.getSubItems(Item b, CreativeTabs tab, List list) 对每个 toolMaterials
造 new ItemStack(b, 1, matIDs.get(m)) + NBT material,
所以创造栏里 28 个部件各自会列出全部入选材料(数量 = 入选材料数,不是 28)。
颜色
| 方法 | 行为 |
|---|---|
getRGBa(stack)(静态) |
无 material 或查不到 → Materials._NULL.mRGBa;否则返回 m.mRGBa(并就地 clamp 到 0–255,会改到 GT 的共享数组) |
getColorFromItemStack(stack, pass) |
无 material → 交给父类;否则把 RGBa 的前三个分量打包成 int 传给客户端 |
getIcon / getIconFromDamage / getIconIndex |
全部无条件返回 icons[0] —— 每个部件只有一张贴图,颜色全靠上面那条 |
registerIcons 只建 new IIcon[1],图标 = modTexPrefix + ":" + folder + textureNames[0]
= tgregworks:items/parts/<texture>。
⚠️
getRGBa里的 clamp 是就地写m.mRGBa[i],会修改 GTMaterials单例共享的数组。 对正常材料(0–255)无影响,但如果某个 mod 注册了溢出的颜色,本 mod 会把它永久改掉。
创造栏
TConstructCreativeTab("tabTGregworks"),本地化 itemGroup.tabTGregworks
= Tinkers' Gregworks / zh_CN 匠魂|GT材料。
preInit 结尾往里塞了一个样例:PartTypes.LargeSwordBlade + NBT material = Osmiridium
(即"黑铱宽剑刃"),作为 tab 的显示图标。
相关条目
- 工具材料注册 —
matIDs/materialIDMap从哪来 - 材料倍率配置 —
materials.material-id.<材料>的自动分配 - 工具配方表 —
TGregToolRecipe.validHead/Handle/Accessory/Extra如何接受本部件 - 碎片 ——
PartTypes.Chunk是 28 个里唯一pattern == null的 - Legacy Metal Pattern 兼容层 — pattern 物品在无 Smeltery 时的替代