Crystal Chest(水晶箱子)

基本信息

属性 值
注册名 IronChest:BlockIronChest @ metadata 5
metadata 来源 IronChestType.CRYSTAL.ordinal()
显示名 tile.ironchest:CRYSTAL.name = Crystal Chest
枚举常量 CRYSTAL
TileEntity cpw.mods.ironchest.TileEntityCrystalChest(唯一实现 super(IronChestType.CRYSTAL))
硬度 3.0F
爆炸抗性 否(resistance = 0)
容量 108(size = 108)
槽位形状 108 / 12 = 9 行 × 12 列
物品栏堆叠上限 64
GUI 尺寸 238 × 256(GUIChest.GUI.CRYSTAL),贴图 ironchest:textures/gui/diamondcontainer.png(借用钻石箱子的)
箱子等级 tier = 5
材质 blockGlass
物品过滤 无
是否配置可关 否(isEnabled() 恒 true)

全 mod 唯一的透明箱子

IronChestType.isTransparent() 是无参返回 this == CRYSTAL 的一行判断,全 mod 只有水晶箱子为 true。它触发三处独有行为:

1. sortTopStacks() 内容压缩

TileEntityIronChest.sortTopStacks() 开头就是:

if (!type.isTransparent() || (worldObj != null && worldObj.isRemote)) return;

非透明箱子直接返回,完全不计算。所以水晶箱子是唯一会维护 topStacks(长度 8 的 ItemStack[])的箱子。它的算法:

  1. 遍历全部 108 格,把 isItemEqual() 的物品合并堆叠数(不是合并格子)。
  2. 复制一份数组,用 Comparator 按 stackSize 降序排序(o2.stackSize - o1.stackSize,null 排最后)。
  3. 取前 8 个非空堆叠填入 topStacks。
  4. 若箱内从有东西变成空(!hasStuff && hadStuff),清空 topStacks 并 markBlockForUpdate。
  5. 调 worldObj.markBlockForUpdate 通知客户端重渲染。

markDirty() 被覆写为 super.markDirty(); sortTopStacks();,getStackInSlot() 也会置 inventoryTouched = true(在 updateEntity() 里服务端每 tick 检查并重算)。

2. 悬浮物品渲染

TileEntityIronChestRenderer.render(TileEntityIronChestRenderer.java:133):

if (TRANSPARENT_RENDER_INSIDE && type.isTransparent()
        && tile.getDistanceFrom(mc.theWorld, mc.thePlayer) < TRANSPARENT_RENDER_DISTANCE) { ... }

渲染最多 8 个 topStacks 物品:每个挂在一个固定偏移点(shifts 9 个三维偏移数组)上,关光照(glDisable(2896))绕 Y 轴用 timeD 旋转,缩放 blockScale = 0.70F;若 topStacks[1] == null(即只有 1 种物品)则放大到 0.85 并整体下移。用一个共享的 EntityItem + 覆写的 RenderItem(getMiniBlockCount / getMiniItemCount 按 stackSize/32 封顶 15/7,shouldBob/shouldSpreadItems 返回 false)绘制。

3. 独立的网络同步

buildItemStackDataList() 只在 type.isTransparent() 时返回 8 个 topStacks,否则返回 null。PacketHandler 的 IronChestCodec 因此对水晶箱子多写一个 boolean + 8 个 ItemStack(判别字只有 0,通道名 IronChest;type 与 facing 压在一个 byte 里:低 4 位 type、高 4 位 facing)。客户端 handlePacketData 同样只对 VALUES[typeData].isTransparent() 生效。

配置项 透明箱子渲染 控制这两项。

配方

字段 值 实际生成的配方
recipeDirect "mmmmPmmmm" → mmm/mPm/mmm getRegistredChestsByTier(CRYSTAL, 5, -1) 返回 tier 5 的 3 个箱子(钻石/水晶/黑曜石),跳过自身后剩 2 条:8 玻璃围 1 钻石箱子 / 8 玻璃围 1 黑曜石箱子
recipeUpgradeOneTier null 无
recipeUpgradeTwoTiers null 无

水晶箱子的 recipeDirect 中 'm' 是 blockGlass(它的材质),与 'G'(固定玻璃)是同一个东西,所以配方实际就是 8 玻璃 + 1 个同级箱子。

升级关系

来源:

来源 形态
Diamond to Crystal Chest Upgrade GGG/GOG/GGG
配方 recipeDirect 8 玻璃围钻石箱子 或 8 玻璃围黑曜石箱子

去向:

升级器 目标 配方
Crystal to Dark Steel Chest Upgrade Dark Steel Chest OOO/msm/OOO(108 → 135)

水晶箱子是唯一不能直接升级到下界合金箱子的 tier 5 箱子——ChestChangerType 里 OBSIDIANNETHERITE 的 source 是 OBSIDIAN,不是 CRYSTAL。

语言文件里另有两条没有对应枚举常量的残留键:item.ironchest:DIAMONDNETHERITE.name(Diamond to Netherite Chest Upgrade)和 item.ironchest:CRYSTALNETHERITE.name(Crystal to Netherite Chest Upgrade)。它们在 ChestChangerType 中不存在,属于上游 mod 移除这两个升级器后遗留的未使用本地化键。

NBT 字段

Items(TAG_Compound 列表,每项含 Slot byte)、facing(byte)。TileEntityCrystalChest 无任何覆写。

[!NOTE] topStacks 是纯内存字段,从不写进 NBT。水晶箱子重新加载世界后,服务端 readFromNBT 末尾会调一次 sortTopStacks() 重建,但客户端必须等下一次描述包(getDescriptionPacket)才会看到悬浮物品。

渲染

事项 值
方块图标 ironchest:crystal_top / crystal_front / crystal_side
模型贴图 ironchest:textures/model/crystalchest.png
GUI 贴图 ironchest:textures/gui/diamondcontainer.png(借用)
悬浮物品 8 个 topStacks,受 transparentRenderInside / transparentRenderDistance 控制

相关条目