Forestry 集成

PluginForestry 是本 mod 中覆盖面最广的插件:引擎能量与温度、树苗基因、树叶授粉对象、蜂箱的蜂后/雄蜂物种与繁育状态。大量信息需要按住 Shift 才展开,因此它同时是交互最复杂的插件。

若进程中存在 MagicBees,插件会额外把 magicbees.tileentity.TileEntityMagicApiary 纳入注册。

基本信息

属性 值
插件类 tterrag.wailaplugins.plugins.PluginForestry
目标 mod Forestry(modid Forestry),可选附带 MagicBees(MagicBees)
@Plugin 注解 name = "Forestry", deps = { "Forestry" },order 未设置(默认 0)
注册类型 Body + NBT provider(TileForestry、TileTreeContainer、TileAlveary,+ 条件注册的 TileEntityMagicApiary)
默认启用 是([plugins] 段与 WAILA [modules] 段默认均为 true)
挂钩的 API forestry.api.apiculture.*、forestry.api.arboriculture.*、forestry.core.access.IOwnable、PluginApiculture
反射 构造函数反射 BeekeepingLogic.throttle,失败则退回 queenWorkCycleThrottle;另反射 TileEngine.maxHeat
Shift 键 用 Forestry 自己的 Proxies.common.isShiftDown() 判定,不走本 mod 的 proxy

注册明细

MagicBees 的条件注册在 load() 内实时判断:

if (Loader.isModLoaded("MagicBees")) {
    registerBody(TileEntityMagicApiary.class);
    registerNBT(TileEntityMagicApiary.class);
}

注意区分两个"引擎"类:本插件的 getNBTData 判定用 forestry.core.tiles.TileEngine(Forestry 自己的引擎),与 Railcraft 的 TileEngine 无关。

WAILA 元数据键(NBT)

NBT 键 类型 来源 含义
rfStored int TileEngine.getEnergyManager().getTotalEnergyStored() 已储存 RF
maxRfStored int TileEngine.getEnergyManager().getMaxEnergyStored() 最大 RF
engineHeat int TileEngine.getHeat() 引擎温度(显示时除以 10 并补 °C)
treeData NBTTagCompound ITree.writeToNBT 树苗基因数据
tileOwner String IOwnable.getOwner().getId().toString() 机器主人的 UUID
leafBredSpecies String TileLeaves.getTree().getMate() 的活跃 SPECIES 等位基因名 树叶授粉对象
queenStack NBTTagCompound IBeeHousingInventory.getQueen() 的 writeToNBT 蜂后物品数据
droneStack NBTTagCompound IBeeHousingInventory.getDrone() 的 writeToNBT 雄蜂物品数据
errors int[] IErrorLogic.getErrorStates() 的 ID 列表 繁育错误状态 ID 数组
breedProgress double 见下 繁育工作进度(0~1)
dummyProduction float BeeManager.beeRoot.createBeeHousingModifier(...) + 养蜂模式修正 有效产能倍率
isJubilant boolean 主基因与副基因 isJubilant(genome, housing) 同时为真 是否处于产蜜旺季

leafBredSpecies、breedProgress、dummyProduction、isJubilant 仅在存在蜂后物品且 PluginApiculture.items.beeQueenGE == queen.getItem()(即真正的蜂后而非工蜂)时写入。

breedProgress 的算法值得单列:取反射得到的节流值 throttle、蜂后最大血量 maxAge、当前血量 age = |health - maxAge|(即"已消耗的血量"作进度),再按 step * (throttle / PluginApiculture.ticksPerBeeWorkCycle) 在相邻两次繁育 tick 之间插值,最终为 (age / maxAge) + progress。

显示内容

引擎(power / heat)

开关 条件 显示
power NBT 含 rfStored <已存> / <最大> RF
heat NBT 含 engineHeat 温度: <getHeat()/10>°C

树苗(sapling)

NBT 含 treeData 时触发,并且先做归属校验:

UUID owner = UUID.fromString(tag.getString(OWNER));
if (owner.equals(player.getGameProfile().getId()) && (tree.isAnalyzed() || te instanceof TileLeaves)) {
    addTreeTooltip(tree, currenttip);
} else if (tree != null) {
    // 斜体提示
}

即必须同时满足:机器主人 UUID 等于当前玩家、且树已分析(或方块是树叶)。否则只显示一条斜体说明:

  • 树已分析但不归你所有 → 你不是该机器的主人
  • 未分析 → 无分析对象

通过校验后:

  • 按住 Shift → 展开 ITree.addTooltip 的完整基因列表
  • 不按 Shift → 只显示一行斜体 <gui.tooltip.tmi> 提示(“按住 Shift 显示更多信息”)

源码原注释:// XXX Leaf isAnalyzed is not working properly, wait for forestry fix ——即树叶方的 isAnalyzed 判定有已知问题,故代码对 TileLeaves 放宽了条件。

树叶(leaves)

TileLeaves.isPollinated() 为真时,追加 授粉对象: <leafBredSpecies>。注意此处读取的正是上文树苗分支所排除的 TileLeaves 情况。

蜂箱(apiary)

对任何 IBeeHousing 生效(TileAlveary 与 MagicBees 的 TileEntityMagicApiary 都实现该接口),依次输出:

  1. 主蜂行:有蜂后时 蜂后 <类型>: <物种名>。类型由物品判断(beeDroneGE → 雄蜂,beePrincessGE → 公主蜂,否则 蜂后),物种取活跃 SPECIES 等位基因名。蜂后已分析时追加缩进的基因信息(Shift 展开,否则给提示行)。
  2. 副蜂行:有雄蜂时 雄蜂 雄蜂: <物种名>。雄蜂来源优先取蜂后的 getMate(),否则退回 droneStack 物品。
  3. 产能行:NBT 含 dummyProduction 且有蜂后时 有效产能: b^0.52 * <值>。prodMod > 16 用红色,否则用青色。不按 Shift 只给"按住 Shift 查看预期产蜜量"提示;按住 Shift 则逐行列出产物与 每小时 <数值> 的产量。产量换算为 chance * 60 * 60 / 27.5(源码注释给出推导:物品数/蜂 tick × 60 秒 × 60 分 × 1 小时 ÷ 27.5 秒每蜂 tick)。副产物(secondary / specialty)的单次机会先除以 2,再按 Bee.getFinalChance(chance, speed, prodMod, t) 归一。
  4. 繁育状态:NBT 含 errors 或 breedProgress 时——若错误集合非空,逐条输出 Error: <描述>(描述取 Forestry 的 for 语言前缀 StringUtil.localize / forLang.localize,红色);否则输出 饲养进度: <百分比>(NumberFormat.getPercentInstance,两位小数,青色)。
  5. 产蜜旺季:NBT 含 isJubilant 时,是产蜜旺季(青色)或 不是产蜜旺季(红色)。

产蜜量汇总会把主产物、副产物、专精产物合并进同一个 TreeMap<Float, ItemStack[]>,按产量降序输出,同产量的物品合并为 名称, ... : 产量。

配置开关

5 个功能开关全部通过 addConfig(key) 注册,默认值均为 true。name = "Forestry" 非空且与依赖 modid 一致,故语言键前缀 wp.config.Forestry.* 与 getPluginName 结果匹配(这是本 mod 中语言键一致的一例,对照 血魔法集成 的失配情况):

开关 语言键 含义
power wp.config.Forestry.power 显示引擎能量
heat wp.config.Forestry.heat 显示引擎温度
sapling wp.config.Forestry.sapling 显示树苗信息
leaves wp.config.Forestry.leaves 显示树叶信息
apiary wp.config.Forestry.apiary 显示蜂箱信息

本插件另有插件级总开关 Forestry(enabled() 读取)。

源码提示:构造函数反射取得的 _maxHeat(TileEngine.maxHeat)在赋值并 setAccessible(true) 之后从未被使用;同理语言文件中的 wp.hud.msg.pollen 键在本源码中无对应调用。二者均为源码既有冗余,不影响功能。

相关条目