TableBlockMixin
基本信息
| 属性 | 值 |
|---|---|
| Mixin 目标 | thaumcraft.common.blocks.BlockTable |
| 注入方式 | @Redirect(不是 @Inject) |
| 注入方法 | onBlockActivated |
| Mixin 数量 | 1 个(mixins.ThaumcraftResearchTweaks.json 的 mixins 数组仅 "TableBlockMixin") |
require |
4 |
配置文件
src/main/resources/mixins.ThaumcraftResearchTweaks.json:
{
"required": true,
"minVersion": "0.7.11",
"package": "elan.tweaks.thaumcraft.research.frontend.integration.table.mixin",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8",
"mixins": ["TableBlockMixin"],
"injectors": { "defaultRequire": 1 }
}
注意 refmap 字段在源码中存在(mixins.ThaumcraftResearchTweaks.refmap.json),由构建生成。
require = 4 与 TC 源码精确对应
BlockTable.onBlockActivated 中恰好有 4 处 EntityPlayer.openGui 调用(thaumcraft4/thaumcraft/common/blocks/BlockTable.java):
| 行号 | GUI ID | 触发方块 |
|---|---|---|
| 181 | 13 | TileArcaneWorkbench(奥术工作台) |
| 185 | 8 | TileDeconstructionTable(解构台) |
| 189 | 10 | TileResearchTable(研究台,本方块) |
| 197 | 10 | 相邻方块中的 TileResearchTable(扫描 4 个水平方向) |
require = 4 与之精确匹配——若 TC 增减 openGui 调用点,Mixin 会因 required: true + defaultRequire: 1 而启动失败,而非静默失效。
重定向逻辑
@Mixin(BlockTable::class)
abstract class TableBlockMixin {
private val `tcrt$THAUMCRAFT_RESEARCH_TABLE_GUI_ID`: Int = 10
@Redirect(method = ["onBlockActivated"],
at = At(value = "INVOKE",
target = "net.minecraft.entity.player.EntityPlayer.openGui(Ljava/lang/Object;ILnet/minecraft/world/World;III)V",
remap = false),
require = 4)
private fun correctGuiCallFor(entityPlayer, mod, modGuiId, world, x, y, z) {
return if (modGuiId == `tcrt$THAUMCRAFT_RESEARCH_TABLE_GUI_ID`) {
entityPlayer.openGui(ThaumcraftResearchTweaks, ThaumcraftResearchGuiHandler.IDs.RESEARCH_TABLE, world, x, y, z)
} else {
entityPlayer.openGui(mod, modGuiId, world, x, y, z) // 原样放行
}
}
}
| 输入 GUI ID | 处理 |
|---|---|
| 10(研究台) | 改开 TRT 自己的 GUI,ID = 0 |
| 13 / 8 | 原样放行,仍打开 TC 本体 GUI |
remap = false是必需的:目标是net.minecraft.entity.player.EntityPlayer.openGui,一个未混淆的 Minecraft 类;若让 SpongePowered 尝试重映射会失败。
相邻研究台(GUI 10 第二处)行为正确
TC 的第 197 行会扫描 4 个水平方向找相邻的研究台,并以偏移后坐标打开 GUI:
for (int a = 2; a < 6; a++) {
TileEntity tile = world.getTileEntity(x + ForgeDirection.getOrientation(a).offsetX, ...);
if (tile != null && tile instanceof TileResearchTable) {
player.openGui(Thaumcraft.instance, 10, world,
x + ForgeDirection.getOrientation(a).offsetX,
y + ForgeDirection.getOrientation(a).offsetY,
z + ForgeDirection.getOrientation(a).offsetZ);
break;
}
}
Mixin 处理函数声明的 7 个参数恰好对应 openGui 的 7 个实参,故 x, y, z 绑定的是调用点传入的坐标(此处理解为偏移坐标),重定向后仍传偏移坐标。
TRT 的 GUI 处理器据此取 TileEntity(ThaumcraftResearchGuiHandler.kt):
private fun World.getTableTileEntity(x: Int, y: Int, z: Int) =
getTileEntity(x, y, z) as TileResearchTable
坐标一致,取到的仍是 TileResearchTable,行为正确。
新 GUI ID
ThaumcraftResearchGuiHandler.IDs.RESEARCH_TABLE = 0(ThaumcraftResearchGuiHandler.kt:21-23):
object IDs { const val RESEARCH_TABLE = 0 }
与 TC 的 8 / 10 / 13 不冲突(不同模组的 GUI ID 空间独立,且由 NetworkRegistry.INSTANCE.registerGuiHandler(ThaumcraftResearchTweaks, …) 注册)。
处理器对未知 ID 记 logger.error("Received unknown gui id: $id") 并返回 null。
相关条目
- Research Table GUI - 被重定向到的目标界面
- Config
- Thaumcraft -
BlockTable与TileResearchTable