Forestry 集成
基本信息
| 属性 | 值 |
|---|---|
| 类型 | 4 个 NEI 配方页 + 搜索索引注入(Forestry addon) |
@Mod 类 |
net.bdew.neiaddons.forestry.AddonForestry,modid NEIAddons|Forestry |
| 目标 mod | Forestry,版本要求 Forestry@[4.0.8.36,) |
| 侧 | 双端 init(),但全部实际注册在 loadClient()(客户端) |
| 事件 | 客户端 MinecraftForge.EVENT_BUS.register(this) 订阅 NEIRegisterHandlerInfosEvent |
| 编译期依赖 | implementation('com.github.GTNewHorizons:ForestryMC:4.11.31:dev') |
| 开关 | 12 个,见 配置文件 |
AddonForestry 覆写了 preInit(打 @Mod.EventHandler)但没有 init 的 @EventHandler 注解——init(Side) 由主类在 FMLInitializationEvent 里手动调。
4 个配方处理器
全部在 loadClient() → BeeHelper.setup() / TreeHelper.setup() / ButterflyHelper.setup() 中按开关注册,且每个都成对调 API.registerRecipeHandler + API.registerUsageHandler。
| Handler | 开关 | 物种 root | 配方 ID | 图标栈 |
|---|---|---|---|---|
BeeBreedingHandler |
Show Bee Mutations |
rootBees |
beebreeding |
Forestry:beeQueenGE |
BeeProduceHandler |
Show Bee Products |
rootBees |
beeproduce |
Forestry:beeQueenGE |
TreeBreedingHandler |
Show Tree Mutations |
rootTrees |
treebreeding |
Forestry:saplingGE |
TreeProduceHandler |
Show Tree Products |
rootTrees |
treeproduce |
Forestry:saplingGE |
ButterflyBreedingHandler |
Show Butterfly Mutations |
rootButterflies |
butterflybreeding |
Forestry:butterflyGE |
前四个是 Forestry 专属;ButterflyBreedingHandler 属 Lepidopterology(蝶类)子系统,与蜂/树同属 Forestry 但独立 root。
HandlerInfo 与隐藏按钮
三个 registerHandlerInfo 方法(BeeHelper / TreeHelper / ButterflyHelper 各一)通过 NEIRegisterHandlerInfosEvent.registerHandlerInfo 注册,构造方式是 new HandlerInfo.Builder(<HandlerClass>.class, Constants.MOD, Constants.ID),即借 Forestry 自己的 modid 与内部 ID注册自己的 handler 身份。
每个 HandlerInfo 都设了 .setShowOverlayButton(false).setShowFavoritesButton(false)——叠加层按钮与收藏按钮全部关闭,因为这些 handler 依赖 3D 基因组数据,塞进背包或做 2D 叠加都没有意义。
育种页(BaseBreedingRecipeHandler)
三个育种 handler 共用同一套基类。GUI 贴图统一 neiaddons:textures/gui/breeding.png(附带同名 .psd 源文件)。
每条配方由一个 IMutation 构造,三个带标签的槽位:
| 槽位 | 坐标 | 标签 | RecipePosition |
|---|---|---|---|
parrent1 |
(22, 19) | mutation.getAllele0().getName() |
Parent1 |
parrent2 |
(75, 19) | mutation.getAllele1().getName() |
Parent2 |
result |
(129, 19) | mutation.getTemplate()[0].getName() |
Offspring |
GeneticsUtils.RecipePosition 是 Parent1 / Parent2 / Offspring / Producer 四个枚举值,各自映射到 EnumBeeType 或 EnumGermlingType 的 ordinal:
| 位置 | 蜂 | 树 |
|---|---|---|
Parent1 |
PRINCESS |
SAPLING |
Parent2 |
DRONE |
(静态块内定义) |
Offspring |
QUEEN |
— |
Producer |
QUEEN |
— |
配方载入走 speciesRoot.getMutations(false)(不过滤 secret),随后由 if (!mutation.isSecret() || AddonForestry.showSecret) 决定是否收录——所以 Show Secret Mutations 是唯一的 secret 开关。
转移矩形两个:(49, 26, 15, 15) 父代区与 (98, 26, 21, 18) 结果区。
drawExtras 画三处标签 + 一处概率数字,位置固定 (108, 15),配色分支:
| 条件 | 文本 | 颜色 |
|---|---|---|
rec.derp 为真(getSpecialConditions 抛异常) |
DERP |
neiChanceTextRed |
requirements 非空且 showReqs |
[<概率>] |
neiChanceTextRed |
| 其它 | <概率> |
neiChanceTextNormal |
概率文本格式:chance < 1 时写死 "<1%",否则 String.format("%.0f%%", chance)。也就是说 0.5% 与 0.99% 显示完全一样。
handleTooltip 只在鼠标悬停于 (108-24, 15-2) 尺寸 48×12 的矩形内时追加:先是 rec.requirements 全部内容,再是 bdew.neiaddons.breeding.mutationchance(“Precise Mutation Chance”)+ rec.chance + "%"(这里显示的是原始浮点值,不是四舍五入后的文本)。条件非空、开关打开、tooltip 当前为空(currenttip.isEmpty())三者同时满足才触发。
产物页(BaseProduceRecipeHandler)
两个产物 handler 共用。GUI 贴图 neiaddons:textures/gui/products_dynamic.png(高度随产物数量动态变化,另有 .psd 源文件)。ROW_HEIGHT = 27。
布局:左侧一个生产者是唯一 ingredient,右侧 3 列网格分「Prod:」与「Spec:」两段。
| 元素 | 坐标 |
|---|---|
| 生产者 | (22, 19),标签 species.getName() |
| Prod 行 | x = 96 + 22×(i%3),y = 8 + (i/3)×27 |
| Spec 行 | x = 96 + 22×(i%3),y = 36 + ((i/3) + (numProductRows-1))×27 |
段标题 bdew.neiaddons.produce.prod |
(65, 12),色 neiProd |
段标题 bdew.neiaddons.produce.spec |
(65, 40 + (numProductRows-1)×27),色 neiSpec |
getRecipeHeight() 返回 (numProductRows + numSpecRows) * 27 + 10,所以这一页能无限增高。
产物来源两路:
| 来源 | 蜂 | 树 |
|---|---|---|
| Prod | IAlleleBeeSpecies.getProductChances() |
ITree.getProduceList()(由 root.getTemplate(uid) → templateAsIndividual 取出模板实例) |
| Spec | IAlleleBeeSpecies.getSpecialtyChances() |
ITree.getSpecialtyList() |
两者都先过 Utils.mergeStacks:同 Item + 同概率值 + 同 NBT 的合并成一个并把 stackSize 累加,NBT 用 Utils.isSameItem 逐字段比较。概率文本用 new DecimalFormat("0.#") 格式化 值×100 + "%"(所以 33.33% 显示 33.3%)。
蜜蜂专属:当 species 实现 IAlleleBeeSpeciesCustom 且 getJubilanceProvider() 非 null 时,provider.getDescription() 被写成灰色 tooltip 挂在每一个 specialty 项上。树没有对应逻辑。
isNoOutput()(prod + spec 都空)时该 species 不生成任何配方条目。getOtherStacks() 返回除首个产物外的其余项,getResult() 恒为 products.get(0)。
搜索索引注入
三个 helper 各有一轮遍历 species 调 Utils.safeAddNBTItem(内部是 API.addItemListEntry),并对 null 做静默跳过:
| 注入物 | 开关 | 来源类 |
|---|---|---|
蜂种(QUEEN / DRONE / PRINCESS 三形态) |
Add Bees to Search |
BeeHelper |
蝴蝶种(BUTTERFLY / CATERPILLAR / SERUM 三形态) |
Add Bees to Search |
ButterflyHelper(复用了蜂的开关) |
树苗 SAPLING |
Add Saplings to Search |
TreeHelper |
花粉 POLLEN |
Add Pollen to Search |
TreeHelper |
| 蜂蜡子物品的全部 metadata 变体 | Add Combs to Search |
BeeHelper |
蝴蝶挂在 addBees 开关下是源码原样(ButterflyHelper 里写的判断条件是 AddonForestry.addBees),名字与作用不符。
蜂蜡子物品的 mod 探测
BeeHelper.getMobCombs() 用 Loader.isModLoaded 依次探测三个来源,全部通过反射取物品:
| modid | 取法 | 失败处理 |
|---|---|---|
Forestry |
GameRegistry.findItem("Forestry", "beeCombs") |
为 null 时打 "Failed to get forestry bee comb item, something is messed up" |
ExtraBees |
Class.forName("binnie.extrabees.ExtraBees").getField("comb") |
catch (Throwable) → "Error locating Extra Bees comb item";字段不是 Item → "Extra Bees comb is not Item subclass!" |
MagicBees |
Class.forName("magicbees.main.Config").getField("combs") |
同上 |
这三个是通过反射探测的第三方集成,不需要对应的 @Mod 容器、也不需要 getDependencies() 声明——getDependencies() 只有 Forestry@[4.0.8.36,) 一条。
Add Combs to Search 打开时,会把每个 comb 物品用 getSubItems(item, null, combs) 展开出的全部子物品逐个 API.addItemListEntry,并逐条打 "Registering comb variant for %s: %s"。
与 NEIPlugins 的 IMC 握手
AddonForestry.registerWithNEIPlugins(name, id) 每次注册 handler 后调一次:
FMLInterModComms.sendRuntimeMessage(
this, "NEIPlugins", "register-crafting-handler",
String.format("%s@%s@%s", I18n.format("bdew.neiaddons.genetics"), name, id));
频道 NEIPlugins,键 register-crafting-handler,值形如 Forestry Genetics@Bee Breeding@beebreeding。I18n.format 意味着发出去的已经是翻译后的本地化字符串,非英文环境下传给 NEIPlugins 的名字也会跟着变。
AddonBotany 有同名同格式的方法(见 Botany 集成)。
相关条目
- 配置文件 - 12 个开关及其门控范围
- NEI 接口实现总表 - 4 个 handler 的接口归属
- Mutation 转储工具 - 同一批突变数据的 CSV 导出
- 叠加层与 GUI 挂钩 - 5 个
ColorResource的定义 - Addon 架构与加载顺序 -
Forestry@[4.0.8.36,)的版本校验