GUI 处理器
基本信息
| 属性 | 值 |
|---|---|
| 注册入口 | NetworkRegistry.INSTANCE.registerGuiHandler(instance, proxy)(common/ThaumicHorizons.java:774,init 阶段) |
| 服务端分派 | common/CommonProxy.java:70-104,getServerGuiElement |
| 客户端分派 | client/ClientProxy.java:262-291,getClientGuiElement |
| GUI ID | 9(ID 1–9,default 分支返回 null) |
| 每 ID 的容器 / 界面类 | 各 1 个,共 9 + 9 = 18 个类 |
Thaumcraft 4 用一个整数 ID 把「哪个方块 / 物品打开了哪个界面」映射到容器类。模组只要在两侧各写一个 switch,两侧 ID 必须一一对应,否则界面会与槽位错位。
ID 对照表
| ID | 服务端容器 | 客户端界面 | 打开方式 |
|---|---|---|---|
| 1 | ContainerVisDynamo |
GuiVisDynamo |
右击 visDynamo 方块(blocks/BlockVisDynamo.java:50) |
| 2 | ContainerSoulExtractor |
GuiSoulExtractor |
右击 soulSieve 方块(blocks/BlockSoulExtractor.java:46) |
| 3 | ContainerInspiratron |
GuiInspiratron |
右击 inspiratron 方块(blocks/BlockInspiratron.java:49) |
| 4 | ContainerSoulforge |
GuiSoulforge |
未找到 openGui 调用点(见下) |
| 5 | ContainerBloodInfuser |
GuiBloodInfuser |
右击 bloodInfuser 方块(blocks/BlockBloodInfuser.java:46) |
| 6 | ContainerInjector |
GuiInjector |
潜行右击 injector 物品(items/ItemInjector.java:112) |
| 7 | ContainerVat |
GuiVat |
治疗槽交互(tiles/TileVat.java:258) |
| 8 | ContainerCase |
GuiCase |
右击 lensCase 物品(items/lenses/ItemLensCase.java:63) |
| 9 | ContainerFingers |
GuiFingers |
键位触发(lib/THKeyHandler.java:107)与封包触发(lib/networking/PacketFingersToServer.java:46) |
服务端容器构造签名与客户端界面一一对应:ContainerVisDynamo(player, (TileVisDynamo) world.getTileEntity(x, y, z)) ↔ GuiVisDynamo(player, (TileVisDynamo) world.getTileEntity(x, y, z))。ID 6、8、9 的容器不取方块实体(new ContainerInjector(player) / new ContainerCase(player.inventory, world, x, y, z) / new ContainerFingers(player.inventory)),因为它们由物品和玩家状态打开而非方块;其中 ID 8 仍用世界坐标,但取的是方块本身的物品堆而非 TileEntity。
ID 4(灵魂熔炉):无调用点
ContainerSoulforge 与 GuiSoulforge 两个类都存在、都被 switch 正确分派,但全仓 331 个 .java 文件中没有一处 openGui(..., 4, ...)。
已核查:用括号配平的方式枚举了 src/main/java 下全部 openGui( 调用点,共 10 处,ID 分别为 1、2、3、5、6、7、7、9、9、8 —— 无 4;displayGuiScreen 在全仓 0 命中;BlockSoulforge.onBlockActivated(blocks/BlockSoulforge.java:45-49)转调的是 TileSoulforge.activate(world, player),而该方法(tiles/TileSoulforge.java:51 起)做的是取出灵魂罐并随机召唤村民(读 VillagerRegistry.getRegisteredVillagers() 拼出可召唤的职业表),不开界面。
结论:ID 4 在两侧 switch 中都真实注册(不是只有方法名),但在本源码树内无法核实其触发路径。可能性包括:由 Wand 触发器或客户端逻辑以非常规方式打开、供其他模组通过 player.openGui(instance, 4, ...) 复用、或上游遗留的保留 ID。本条按「未找到调用点」记录,不臆测其行为。
数值
| 数值名 | 值 |
|---|---|
| GUI ID 总数 | 9(1–9) |
| 确认有打开路径的 ID | 8 |
| 未找到打开路径的 ID | 1(ID 4) |
openGui( 调用点总数(全仓) |
10 |
| 容器类 / 界面类 | 9 / 9 |
| 接收方块实体的容器 | 6(ID 1、2、3、4、5、7,构造时强转对应 TileEntity) |
| 不接收方块实体的容器 | 3(ID 6、8、9) |