原版门替换
基本信息
| 属性 | 值 |
|---|---|
| 开关 | config.modifyVanillaDoors,默认 true |
| 实现类 | net.malisis.core.util.replacement.ReplacementTool(来自内置 malisiscore 框架) |
| 调用位置 | Registers.init() 开头(Registers.java:85-89) |
| 替换目标数 | 4 个方块 + 2 个物品 |
| 实现层级 | 运行时反射改写 FML 注册表,非 FML coremod 转换 |
功能
开启 modifyVanillaDoors 后,模组把原版的木门、铁门、活板门、栅栏门在运行时整体换成自己的实现,从而让原版门也获得平滑动画。
Registers.init() 的入口(Registers.java:85-89):
if (MalisisDoorsSettings.modifyVanillaDoors.get()) {
registerVanillaDoors();
registerVanillaTrapDoor();
registerVanillaFenceGate();
}
替换清单
| 原版对象 | 注册 ID | SRG 字段名 | 替换为 | 出处 |
|---|---|---|---|---|
minecraft:wooden_door(方块) |
64 | field_150466_ao |
VanillaDoor(Material.wood).getBlock() |
Registers.java:131-132 |
minecraft:wooden_door(物品) |
324 | field_151135_aq |
VanillaDoor(Material.wood).getItem() |
Registers.java:129-130 |
minecraft:iron_door(方块) |
71 | field_150454_av |
VanillaDoor(Material.iron).getBlock() |
Registers.java:137 |
minecraft:iron_door(物品) |
330 | field_151139_aw |
VanillaDoor(Material.iron).getItem() |
Registers.java:136 |
minecraft:trapdoor(方块) |
96 | field_150415_aT |
new VanillaTrapDoor().getBlock() |
Registers.java:143-144 |
minecraft:fence_gate(方块) |
107 | field_150396_be |
FenceGate(Type.OAK) |
Registers.java:149 |
VanillaDoor、VanillaTrapDoor 两个描述符复用原版贴图名(VanillaTrapDoor.java:36-37 中 setName("trapdoor")、setTextureName("trapdoor")),因此视觉上与原版一致。
替换机制
ReplacementTool.replaceVanilla(ReplacementTool.java:112-145)通过反射完成 5 步:
- 冒名顶替注册名:
replDelegate.setName(vanDelegate.name())让替换方继承原版的注册名(ReplacementTool.java:121) - 改写注册表:反射调用
FMLControlledNamespacedRegistry.addObjectRaw(int, String, Object),用原版 ID 与"minecraft:" + name覆盖注册(ReplacementTool.java:60-62、123) - 改写
Blocks/Items静态字段:Fields.ofClass(clazz).getUntypedField(..., isObfEnv ? srgFieldName : name)——生产环境(混淆)用 SRG 名,开发环境用可读名(ReplacementTool.java:124-127)。isObfEnv由Launch.blackboard.get("fml.deobfuscatedEnvironment")取反得到(MalisisCore.java:91) - 改写原版
ItemBlock的方块引用:ib.field_150939_a = (Block) replacement(ReplacementTool.java:130-132) - 全量替换引用:遍历
CraftingManager.getRecipeList()与StatList.allStats,把配方与统计里的原版对象换成新对象(ReplacementTool.java:133-137)
客户端侧还要补注册贴图——因为原版方块已不在注册表中,图标注册回调不会再被调用,onTextureStitchEvent 手动为它们补注册(ReplacementTool.java:78-88)。
配方替换器
第 5 步由 5 个 ReplacementHandler 承担,构造时全部实例化(ReplacementTool.java:64-69):
| 处理器 | 作用 |
|---|---|
ShapedOreRecipeHandler |
有序物品字典配方 |
ShapedRecipesHandler |
有序普通配方 |
ShapelessRecipesHandler |
无序普通配方 |
ShapelessOreRecipeHandler |
无序物品字典配方 |
StatCraftingHandler |
合成统计 |
replaceIn 对列表中每个对象取 ReplacementHandler.getHandler(object),非空则调用 rh.replace(...)(ReplacementTool.java:145-158)。
数值
| 数值名 | 值 | 出处 |
|---|---|---|
| 替换方块数 | 4 | Registers.java:126-150 |
| 替换物品数 | 2 | Registers.java:130、136 |
| 配方替换处理器数 | 5 | ReplacementTool.java:64-69 |
| 默认开关状态 | true |
MalisisDoorsSettings.java:27 |
交互
| 场景 | 结果 |
|---|---|
| 开关开启 | 原版 4 类门被整体替换,本模组 木门、活板门、栅栏门 的动画同步作用于原版门 |
| 开关关闭 | 原版门保持原样;malisisdoors:fenceGate(橡木型)不注册,其余 6 种栅栏门与 7 种活板门正常注册 |
| 与其他改门 mod 共存 | 会冲突——en_US.lang:110-111 明确警告 “This replaces the doors entirely so conflicts may arise if another mod tries to modify them too.” |