/emt_outputs

基本信息

属性 值
指令名 /emt_outputs(无参数)
实现类 CommandOutputs extends CommandBase
源码 emt/command/CommandOutputs.java
注册位置 emt/EMT.java:112,FMLServerStartingEvent 阶段
权限 无限制(canCommandSenderUseCommand 恒 true,:105-107)
Tab 补全 无(addTabCompletionOptions 返回 null,:110-112)
产物 一本成书(Items.written_book),记录所有精华的 EU 产出
@Mod.EventHandler
public void onFMLServerStart(FMLServerStartingEvent event) {
    event.registerServerCommand(new CommandOutputs());
}

(emt/EMT.java:110-113)

功能

生成一本把当前所有精华的 EU 产出值列成表的书,交给执行者。processCommand(:124-131):

ItemStack book = mkbook();
if (!command.getEntityWorld().getPlayerEntityByName(command.getCommandSenderName()).inventory
        .addItemStackToInventory(book))
    command.getEntityWorld().getPlayerEntityByName(command.getCommandSenderName()).entityDropItem(book, 0);

先尝试放入背包,背包放不下则掉落在脚下(entityDropItem)。

书本结构

mkbook()(:21-92)遍历 Aspect.aspects.values(),按每 11 个元素一页切分。生成的 book NBT:

NBT 字段 值 源码
author Tombenpotter, bartimaeusnek :76
title 本地化键 gui.EMT.book.aspect.output.eu.title :26,77
pages 3 段:①单方块页 ②全书 EU 页 ③EU/t 页 :81-90

每一页的数值来自 EMTEssentiasOutputs.outputs 这个 HashMap<String, Double>(emt/util/EMTEssentiasOutputs.java:10),key 是精华 tag。

两种单位

段落 计算式 含义
EU 页 outputs.get(tag) 单方块一次产出的 EU
EU/t 页 outputs.get(tag) / 20D 折算为每 tick(1.7.10 中 1 秒 = 20 tick)
单方块页 outputs.get(tag) / 20D / 20D 再除 20,即折算为每秒

单方块页只包含 6 个原始精华(:37-41 的白名单):ENERGY / TREE / FIRE / AURA / GREED / AIR。

[!WARNING] 单方块页的白名单与其余两页使用的 Aspect.aspects.values() 不一致。若白名单中的某个精华在 outputs 表中没有对应条目,outputs.get(tag) 返回 null,null / 20D / 20D 经自动装箱后按 0.0 参与运算,该行将显示为 <tag>: 0.0EU。 实际是否发生取决于 Thaumcraft 原版 Aspect.aspects 表中这些 tag 的 isPrimal() 判定——该表属 Thaumcraft 本体,/Users/evlos/a/mirror/ 下无 Thaumcraft 源码(已 find 确认仅有 ThaumcraftMobAspects),故白名单中哪些 tag 会缺失无法核实。可复现方式:装上本 mod 后执行 /emt_outputs 查看单方块页是否有 0.0EU 行。

产出值的来源

EMTEssentiasOutputs 是一张由 6 个原始精华推导出全部复合精华的表:

方法 行为 源码
addPrimalOutputs() 用 6 个配置项填入原始精华 :32-39
addOutputs() 遍历所有非原始精华,逐个合成 :25-30
addOutput(Aspect) 复合精华 = parents[0] + parents[1];outputCap != -1 时取 min(和, cap) :12-23

6 个原始精华的默认产出(emt/util/EMTConfigHandler.java:221-227):

精华 配置键 默认 EU
IGNIS Ignis Output 20000
AQUA Aqua Output 5000
ORDO Ordo Output 16000
PERDITIO Perditio Output 10000
TERRA Terra Output 2000
AER Aer Output 15000
(全局上限) Output Cap -1 = 不封顶

每个复合精华的产出因此是其两个父精华之和,高阶精华的数值会指数级放大(如 METALLURGY 类四级精华可达数百万 EU)。

源码缺陷

  • getPlayerEntityByName 被连续调用两次(:127-130):第一个表达式取 .inventory,若失败则第二个表达式重新查找一次玩家。中间若玩家离开则 null,会直接 NPE。
  • 服务器上执行依赖服务端有该玩家:processCommand 通过 command.getEntityWorld().getPlayerEntityByName(command.getCommandSenderName()) 取玩家,从控制台执行时 getCommandSenderName() 不是玩家名(返回 "CONSOLE" 等),getPlayerEntityByName 返回 null → NPE。该指令只能由游戏内玩家执行。
  • 数字拼接不做小数格式化(:42-59):直接 String.valueOf(double),会输出 20000.0EU 这类带 .0 的形式,且复合精华可能出现 1.0E7 科学计数法。
  • 重复计算 outputs.get 三次(:42-44、:47-52、:54-59):每个精华在三个段落中各取一次,无缓存。
  • 计数器复用导致分页不稳定(:32-35、:64):counter 在内层 else 分支末尾被重置为 0,但 ++counter 在循环开头自增,净效果是每 11 个元素分一页——逻辑正确但极易读错。

相关条目