皮肤模式开关

基本信息

属性 值
数据字段 boolean[] isSkinArmor = new boolean[4](InventoryCosArmor)
默认值 全部 false(即默认正常显示时装护甲)
作用域 每个玩家、每个槽位独立
服务端 权威值,存于服务端 InventoryCosArmor
客户端 影子副本,仅用于按钮绘制与渲染判定
持久化 随 时装护甲数据文件 一同写入 NBT

功能

每个槽位带一个独立的「不穿」布尔开关。打开后,该槽的时装护甲既不渲染也不替换原版护甲,玩家的皮肤直接裸露显示——这解决了时装护甲遮挡皮肤(尤其是自定义皮肤 mod)的问题。

切换流程

  1. 玩家在成品界面点击成品界面右侧的 5×5 皮肤模式按钮(ID 80~83,见 界面与按钮)。
  2. GuiCosArmorInventory.actionPerformed()(第 87~94 行)先在客户端本地翻转:
    int i = button.id - 80;
    InventoryCosArmor inv = ...getCosArmorInventoryClient(mc.thePlayer.getUniqueID());
    inv.setSkinArmor(i, !inv.isSkinArmor(i));
    inv.markDirty();
    ((GuiCosArmorToggleButton) button).state = inv.isSkinArmor(i) ? 1 : 0;
    
  3. 随后发送 PacketSetSkinArmor(mc.thePlayer, i) 到服务端。
  4. 服务端 handlePacketServer() 写入权威值并 markDirty();下一 tick 的 PlayerTickEvent 会把改动广播给所有客户端。

按钮状态在 initGui() 里按 isSkinArmor(3 - i) 预读,保证重开界面时显示正确。

对渲染的影响

PlayerRenderHandler.swapForCosmeticArmor()(第 76~82 行)逐槽判定:

for (int i = 0; i < cosArmor.length; i++) {
    if (invCosArmor.isSkinArmor(i)) {
        armor[i] = null;                 // 皮肤模式:该部位渲染为空气
    } else if (cosArmor[i] != null) {
        armor[i] = cosArmor[i];          // 正常:时装护甲顶替原版护甲
    }
}

isSkinArmor 优先级高于时装物品本身:即使槽里有物品,只要开关打开就渲染为 null。注意该分支在客户端读取(getCosArmorInventoryClient),所以其他玩家的皮肤模式也由服务端下发的封包决定,全服可见。

限制

  • 皮肤模式对原版护甲格无效——只作用于时装护甲的 4 个槽。
  • 渲染替换整体可被 客户端渲染开关 关闭,此时所有 isSkinArmor 状态都不产生任何视觉效果。
  • 该字段无法通过命令或配置批量设置(本 mod 无指令),只能在成品界面逐槽点击。

相关条目