Botania 兼容(Botania Compat)

基本信息

属性 值
类型 客户端 Late Mixin ×2
实现类 MixinClientProxy、MixinRenderTileSkullOverride
目标类 vazkii.botania.client.core.proxy.ClientProxy、vazkii.botania.client.render.tile.RenderTileSkullOverride
适用端 客户端
启用条件 Botania 已加载

功能

SimpleSkinBackport 处理 Botania 的两个渲染覆盖:

  1. MixinClientProxy —— 阻止 Botania 注册自己的 TileEntitySkullRenderer,因为 mod 直接在 ModelSkeletonHead 上加 hat layer(MixinModelSkull)
  2. MixinRenderTileSkullOverride —— 替换 Botania 的 Gaia Guardian skull 渲染纹理与模型

启用条件

if (loadedMods.contains("Botania")) {
    mixins.add("botania.MixinClientProxy");
    mixins.add("botania.MixinRenderTileSkullOverride");
}

Mixin 1: MixinClientProxy(阻止 skull renderer 注册)

Botania 原版会在 initRenderers 中为 TileEntitySkull 注册自己的 RenderTileSkullOverride。本 mixin 把这个 bindTileEntitySpecialRenderer 调用有条件地绕过:

@WrapOperation(method = "initRenderers", remap = false,
    at = @At(value = "INVOKE",
        target = "Lcpw/mods/fml/client/registry/ClientRegistry;bindTileEntitySpecialRenderer(Ljava/lang/Class;Lnet/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer;)V"))
private void disarmSkullRenderReplacer(Class<? extends TileEntity> tileEntityClass,
    TileEntitySpecialRenderer specialRenderer, Operation<Void> original) {
    if (tileEntityClass != TileEntitySkull.class) {
        // We provide our own hat layer directly on the skull, so Botania doesn't need to do this.
        original.call(tileEntityClass, specialRenderer);
    }
}

含义:mod 自己的 MixinModelSkull 已经给 skull 加了 hat layer,无需 Botania 再注册额外的 skull renderer。但 Botania 的其它 TESR 仍正常注册。

Mixin 2: MixinRenderTileSkullOverride(修正 Gaia Guardian skull)

Gaia Guardian 复制玩家的皮肤纹理。原版 Botania 用 192x192 风格模型 + 旧版 Steve 贴图;本 mod 替换为 64x64 模型 + 新版 Steve 贴图:

@Mixin(RenderTileSkullOverride.class)
public class MixinRenderTileSkullOverride extends TileEntitySkullRenderer {

    private ModelSkeletonHead skull = new ModelSkeletonHead(0, 0, 64, 64);  // 64x64 model

    @Redirect(method = "render",
        at = @At(value = "FIELD",
            target = "Lnet/minecraft/client/entity/AbstractClientPlayer;locationStevePng:Lnet/minecraft/util/ResourceLocation;"))
    private ResourceLocation fixDefaultTexture() {
        return DefaultPlayerSkin.STEVE.getResource();  // 用 mod 的 64x 史蒂夫贴图
    }

    @Redirect(method = "render",
        at = @At(value = "INVOKE",
            target = "Lvazkii/botania/client/model/ModelSkullOverride;render(Lnet/minecraft/entity/Entity;FFFFFF)V"))
    private void changeModel(ModelSkullOverride instance, Entity par1Entity, float par2, float par3, float par4,
        float par5, float par6, float par7) {
        skull.render(par1Entity, par2, par3, par4, par5, par6, par7);  // 用 vanilla 64x 模型
    }
}

行为细节

  1. 默认贴图重定向:AbstractClientPlayer.locationStevePng 字段引用被 @Redirect 改为 DefaultPlayerSkin.STEVE.getResource(),即 mod 内置的 assets/minecraft/textures/entity/player/wide/steve.png
  2. 模型替换:ModelSkullOverride.render(...) 调用被替换为 vanilla ModelSkeletonHead(0, 0, 64, 64).render(...) —— 因为 64x64 贴图与 Botania 自定义模型不兼容
  3. ModelSkeletonHead(0, 0, 64, 64) 构造器:4 个参数为 textureOffsetX, textureOffsetY, textureWidth, textureHeight

数值

数值 值 来源
ModelSkeletonHead 纹理宽高 64x64 new ModelSkeletonHead(0, 0, 64, 64)
Steve 贴图路径 minecraft:textures/entity/player/wide/steve.png DefaultPlayerSkin.STEVE.getResource()
Skip 的 TESR 注册 TileEntitySkull.class tileEntityClass != TileEntitySkull.class

关联机制

步骤 位置
1. 加载 Botania loadedMods.contains("Botania")
2. Mixin 1 跳过 verifyAndRenderSpecialTileEntitySkull MixinClientProxy.disarmSkullRenderReplacer
3. 玩家头颅渲染 TileEntitySkullRenderer(vanilla,未被覆盖)
4. Mixin 2 修正 Gaia Guardian skull MixinRenderTileSkullOverride.fixDefaultTexture + changeModel

第三方 mod 集成

  • Botania(必需):被 mixin 的两个类均来自 vazkii.botania.*
  • SimpleSkinBackport 内部:依赖 MixinModelSkull 在 ModelSkeletonHead 上加 hat layer;依赖 DefaultPlayerSkin.STEVE.getResource() 提供 64x Steve 贴图

相关条目