皮肤模式开关
基本信息
| 属性 | 值 |
|---|---|
| 数据字段 | boolean[] isSkinArmor = new boolean[4](InventoryCosArmor) |
| 默认值 | 全部 false(即默认正常显示时装护甲) |
| 作用域 | 每个玩家、每个槽位独立 |
| 服务端 | 权威值,存于服务端 InventoryCosArmor |
| 客户端 | 影子副本,仅用于按钮绘制与渲染判定 |
| 持久化 | 随 时装护甲数据文件 一同写入 NBT |
功能
每个槽位带一个独立的「不穿」布尔开关。打开后,该槽的时装护甲既不渲染也不替换原版护甲,玩家的皮肤直接裸露显示——这解决了时装护甲遮挡皮肤(尤其是自定义皮肤 mod)的问题。
切换流程
- 玩家在成品界面点击成品界面右侧的 5×5 皮肤模式按钮(ID 80~83,见 界面与按钮)。
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;
- 随后发送
PacketSetSkinArmor(mc.thePlayer, i)到服务端。 - 服务端
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 无指令),只能在成品界面逐槽点击。