矿辞典注册
[!INFO] Git Commit:
d3dbd5f| Updated: 2026-10-01
OreDict.register() 是本 mod 唯一的实际功能(由 init 阶段调用,见
mod 元信息与打包数据)。它把 其它 mod 的植物 登记到 crop* 前缀的矿辞典名字下,
使下游作物 mod(BerriesPP)能通过 OreDict.BSget(name, cropCard) 把这些植物注册为 IC2 作物的基础种子。
全仓共 70 次 registerOre 调用、34 个不同的矿辞典名字,其中 20 个以 crop 开头。
注册流程与门控
OreDict.register() 用 isregistered 静态标志保证幂等(OreDict.java:88),执行顺序固定:
| 顺序 | 目标 | 门控方式 | 生效条件 |
|---|---|---|---|
| 1 | Tinkers’ Construct | OreDictRegistrator.register() |
Loader.isModLoaded("TConstruct") |
| 2 | Thaumcraft | 同上 | Loader.isModLoaded("Thaumcraft") |
| 3 | Biomes O’ Plenty | 同上 | Loader.isModLoaded("BiomesOPlenty") |
| 4 | Natura | 同上 | Loader.isModLoaded("Natura") |
| 5 | Witchery | OreDict.java:93 显式 if |
Loader.isModLoaded("witchery") |
| 6 | Thaumic Bases | OreDictRegistrator.register() |
Loader.isModLoaded("thaumicbases") |
| 7 | 浆果聚合(5 个) | 无 | 源矿辞典名非空 |
| 8 | 原版 | 无门控 | 总是执行 |
OreDictRegistrator 是一个只有 2 个方法的接口(OreDictRegistrator.java):
public interface OreDictRegistrator extends Runnable {
String getModWhichRegisters();
default void register() {
if (Loader.isModLoaded(getModWhichRegisters())) run();
}
}
Witchery 被双重门控:OreDict.java:93 先用 if 判断,RegisterWitchery 自己又实现了
OreDictRegistrator——但 OreDict.java 调用的是 new RegisterWitchery().register(),而
register() 是接口的 default 方法,会再查一次 isModLoaded("witchery")。结论一致,只是多查一次。
原版与浆果聚合不走 OreDictRegistrator,因为它们不依赖任何 mod。
各 mod 登记的具体内容
原版(RegisterVanilla,9 次)
全部用数字 item id,不使用 Item.getItemByName:
| 矿辞典名 | 物品 id | 1.7.10 对应 |
|---|---|---|
cropVine |
106 | 藤蔓 |
cropVines |
106 | 藤蔓(复数形式,与 cropVine 指向同一条) |
cropGrass |
32:0 | 玫瑰丛 |
cropGrass |
31:2 | 枯萎的灌木 |
cropGrass |
31:1 | 蕨 |
cropGrass |
175:2 | 巨型蘑菇(红) |
cropGrass |
175:3 | 巨型蘑菇(褐) |
cropCacti |
81:0 | 仙人掌 |
cropCactus |
81:0 | 仙人掌(单数别名) |
注意 3 处成对别名:cropVine/cropVines、cropCacti/cropCactus 是同物品的两个名字。
这是为了兼容不同下游 mod 的命名习惯(cropCacti 供 Berry 类 mod,cropCactus 供通用用途)。
Tinkers’ Construct(2 次)
| 矿辞典名 | 内容 |
|---|---|
cropGrass |
TinkerWorld.slimeGrass meta 0 |
cropGrass |
TinkerWorld.slimeTallGrass meta 0 |
Thaumcraft(3 次)
用 thaumcraft.api.ItemApi.getBlock(name, meta) 取方块:
| 矿辞典名 | 内容 |
|---|---|
cropShimmerleaf |
blockCustomPlant meta 2 |
cropCinderpearl |
blockCustomPlant meta 3 |
cropGrass |
blockTaintFibres meta 1 |
cropGrass 收集的是污秽纤维,不是草——Thaumcraft 没有真正的草方块。
Biomes O’ Plenty(23 次,本 mod 最大的 Register 类)
| 矿辞典名 | 内容 | 次数 |
|---|---|---|
cropGrass |
BOPCBlocks.plants meta 0–3 |
4 |
cropGrass |
BOPCBlocks.foliage meta 1, 2, 5, 7, 9, 10, 11, 12, 13 |
9 |
cropVine / cropFloweringVines |
BOPCBlocks.flowerVine meta 0 |
各 1 |
cropVine / cropIvy |
BOPCBlocks.ivy meta 0 |
各 1 |
cropCacti / cropSmallCactus |
BOPCBlocks.plants meta 12 |
各 1 |
cropBerry / listAllberry |
BOPCItems.food meta 0 |
各 1 |
cropEyebulb |
BOPCBlocks.flowers meta 13 与 14 |
2 |
BoP 的 plants 方块 meta 12 同时被登记为 cropCacti(仙人掌)与 cropSmallCactus(小仙人掌),
与原版的 cropCacti/cropCactus 别名策略一致。
Natura(7 次)
| 矿辞典名 | 内容 |
|---|---|
cropSaguaroBerry / listAllberry |
NContent.seedFood meta 0 |
cropGooseberry |
NContent.berryItem meta 3 |
cropCacti / cropSaguaro |
NContent.saguaro(不指定 meta,默认 0) |
cropVine / cropThornVines |
NContent.thornVines(不指定 meta) |
Witchery(20 次)
分 5 组,全部用 com.emoniph.witchery.Witchery 的常量,物品类以 GENERIC + metadata 区分:
| 组 | 矿辞典名 | 内容 |
|---|---|---|
| 草药 | listAllherb |
SEEDS_GARLIC |
| 蔬菜 | listAllveggie |
GENERIC meta 69 |
| 植物 | cropGlintWeed |
Blocks.GLINT_WEED |
| 植物 | cropSpanishMoss |
Blocks.SPANISH_MOSS |
| 植物 | cropEmberMoss |
Blocks.EMBER_MOSS |
| 种子 | seedWaterArtichoke / seedWolfsBane / seedMandrake / seedSnowbell / seedBelladonna |
5 个 SEEDS_* 常量 |
| 种子 | listAllseed |
同上 5 个,各 1 次 |
| 物品 | cropArtichoke |
GENERIC meta 69 |
| 物品 | itemWolfsBane |
GENERIC meta 156 |
| 物品 | itemMandrake |
GENERIC meta 22 |
| 物品 | itemSnowbell |
GENERIC meta 78 |
| 物品 | itemBelladonna |
GENERIC meta 21 |
GENERIC:69 同时被 listAllveggie 与 cropArtichoke 登记,即朝鲜蓟既是蔬菜也是作物。
本类中另有 3 条被注释掉的注册(RegisterWitchery.java:40-41、:47、:50)——
itemWaterArtichoke、itemGypsum、dustQuicklime。这三条并未生效,其中 itemWaterArtichoke
与 cropArtichoke 是同一物品(GENERIC:69),看起来是改用 crop 前缀后的遗留。
Thaumic Bases(1 次)
| 矿辞典名 | 内容 |
|---|---|
nuggetThauminite |
TBItems.resource meta 0 |
这是全部 34 个名字中唯一与作物无关的——它登记的是锭(nugget)而非植物,
与本 mod 其余部分的 crop* 模式完全不符,属于功能上的离群项。
浆果聚合(OreDict.java:96-119)
5 段结构完全相同的代码,把已有的 crop* 浆果名复制到 listAllberry:
| 源矿辞典名 | 目标 |
|---|---|
cropBlackberry |
listAllberry |
cropBlueberry |
listAllberry |
cropGooseberry |
listAllberry |
cropRaspberry |
listAllberry |
cropStrawberry |
listAllberry |
每段都是「源列表非空 → 遍历 → 目标列表不含该 ItemStack 才 registerOre」,即去重后再登记。
这 5 个源名字不由本 mod 创建——本 mod 只创建 cropGooseberry(Natura),
另外 4 个必须由 BerriesPP 或其它浆果 mod 先注册。因此这是本 mod 与下游 mod 的唯一数据契约。
cropGooseberry 因此被登记两次:一次由 RegisterNatura 指向 NContent.berryItem:3,
一次由本段复制进 listAllberry。
OreDict 的 3 个工具方法
OreDict 除 register() 外还暴露 3 个静态方法供下游 mod 使用:
ISget(String)(OreDict.java:28-32)
返回该矿辞典名列表的最后一个 ItemStack,列表为空时返回 null。
取"最后一个"而非第一个,意味着依赖 mod 的加载顺序。
BSget(String, CropCard)(OreDict.java:34-48)—— 含一处缺陷
本方法把矿辞典中的物品注册为 IC2 基础种子,是 registerBaseSeed 的唯一调用点:
public static void BSget(String name, CropCard crop) {
String hname;
if (OreDictionary.getOres(name).size() != 0) for (int i = 0; ...)
Crops.instance.registerBaseSeed(OreDictionary.getOres(name).get(i), crop, 1, 1, 1, 1);
if (name.contains("crop")) {
hname = name.replace("crop", "seed");
if (OreDictionary.getOres(name).size() != 0) for (int i = 0; ...)
Crops.instance.registerBaseSeed(OreDictionary.getOres(name).get(i), crop, 1, 1, 1, 1); // ← 应为 hname
}
if (name.contains("seed")) {
hname = name.replace("seed", "crop");
if (OreDictionary.getOres(hname).size() != 0) for (int i = 0; ...)
Crops.instance.registerBaseSeed(OreDictionary.getOres(hname).get(i), crop, 1, 1, 1, 1);
}
}
OreDict.java:40-41 是复制粘贴缺陷:crop → seed 分支里算出了 hname,却再次遍历
getOres(name) 而非 getOres(hname)。后果是该分支对同一个 name 重复注册了一遍
(内容与第 36-37 行完全相同),而 crop* 到 seed* 的实际查询从未发生。
对比第 43-47 行的 seed → crop 分支:该分支正确地用了 hname。两个分支写法不对称,
说明第 41 行是笔误而非有意设计。
registerBaseSeed(stack, crop, 1, 1, 1, 1) 的 4 个参数全部硬编码为 1——
基础种子没有产量、成长速度或营养加成修饰,即"完全按该作物卡的默认值生长"。
get_subtypes(List<Item>, boolean)(OreDict.java:50-84)
枚举某个物品的全部 metadata 变体,用于把"一个 Item + N 个 meta"展开成完整物品列表。
CleanList 为 true 时先用 HashSet 去重。
主动跳过 Binnie 与 Forestry 的物品(OreDict.java:66-67):
if (!((cleansubtypes.get(i).getClass().toString().contains("binnie"))
|| (cleansubtypes.get(i).getClass().toString().contains("forestry")))) {
即这两个 mod 的物品整个被排除,不会进入结果列表。源码未给出原因。
对保留下来的物品,用 do...while(!k) 从 meta 0 开始递增,循环条件(OreDict.java:69-77)在满足
任一情况时停止:当前 meta 与上一 meta 显示名相同、显示名含 .、显示名含当前 meta 数字、
或当前与后两 meta 显示名相同。这是靠启发式推断变体数量,没有上界保护——
若上述条件始终不成立会一直递增。该方法内唯一的日志调用(:51)已被注释掉。