透明箱子渲染(transparentRender*)

基本信息

配置项位于 config/ironchest.cfg 的 general 段(IronChest.java:72-84),只影响 Crystal Chest ——因为全 mod 只有 CRYSTAL 的 isTransparent() 为 true。

键名 类型 默认值 字段 源码描述
transparentRenderInside boolean true IronChest.TRANSPARENT_RENDER_INSIDE “Whether or not transparent chests (i.e. crystal) should display their contents.”
transparentRenderDistance double 128D IronChest.TRANSPARENT_RENDER_DISTANCE “Maximum distance from a transparent chest, after which its contents will stop being displayed.”

两个都是纯客户端选项:读取发生在 preInit(两端都读),但只被 TileEntityIronChestRenderer.render 消费,服务端不参与判定。

行为

// TileEntityIronChestRenderer.java:133
if ((IronChest.TRANSPARENT_RENDER_INSIDE) && (type.isTransparent())
        && (tile.getDistanceFrom(mc.theWorld, mc.thePlayer) < IronChest.TRANSPARENT_RENDER_DISTANCE)) {
    // 渲染 topStacks
}

三个条件是逻辑与,缺一不可:

条件 关掉的后果
TRANSPARENT_RENDER_INSIDE = false 悬浮物品完全不渲染(topStacks 仍在服务端计算并同步,只是不画)
type.isTransparent() = false 只有水晶箱子受影响,其它箱子本来就不满足
距离 ≥ TRANSPARENT_RENDER_DISTANCE 远处水晶箱子不画悬浮物品,箱子本体照常渲染

getDistanceFrom 用的是世界坐标中心(this.field_147501_a.field_147560_j 等字段),所以距离判断与玩家视线方向无关——背后的水晶箱子也照常显示悬浮物品。

渲染出来的 8 个物品从哪来

悬浮物品取自 TileEntityIronChest.topStacks(长度 8 的 ItemStack[]),由 sortTopStacks() 计算,而 sortTopStacks() 开头就是:

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

所以:

  • 只有水晶箱子会维护 topStacks;其余 10 种箱子的 topStacks 永远是 8 个 null。
  • markDirty() 被覆写为 super.markDirty(); sortTopStacks();;getStackInSlot() 会置 inventoryTouched = true,updateEntity() 在服务端每 tick 检查该标志并重算。
  • 算法:遍历全部 108 格把 isItemEqual() 的物品合并堆叠数 → 按 stackSize 降序排序(o2.stackSize - o1.stackSize,null 排最后)→ 取前 8 个非空堆叠。
  • 若箱内从有东西变成空(!hasStuff && hadStuff),清空 topStacks 并 markBlockForUpdate。

[!NOTE] 合并的是堆叠数而不是"格子数",所以只有一种物品时 topStacks 只有 1 个非空槽。

渲染细节

事项 值
悬浮位置 固定 9 个三维偏移数组 shifts(4 个角点 y=0.45 + 4 个角点 y=0.1 + 1 个中心 (0.5, 0.32, 0.5))
物品缩放 blockScale = 0.70F;若 topStacks[1] == null(只有 1 种物品)则放大到 0.85F
旋转 绕 Y 轴,timeD = 360.0 * (System.currentTimeMillis() & 0x3FFF) / 0x3FFF 度
光照 渲染期间 glDisable(2896 /* GL_LIGHTING */),完成后 glEnable 恢复
物品动画 共享一个 EntityItem + 覆写 RenderItem:shouldBob() / shouldSpreadItems() 返回 false,getMiniBlockCount / getMiniItemCount 按 stackSize / 32 封顶 15 / 7
随机种子 random.setSeed(254L),保证同一箱子的悬浮位置稳定

网络同步

buildItemStackDataList() 只在 type.isTransparent() 时返回 8 个 topStacks,否则返回 null。PacketHandler 的 IronChestCodec 据此决定是否多写一个 boolean + 8 个 ItemStack(判别字只有 0,通道名 IronChest;type 与 facing 压在一个 byte:低 4 位 type、高 4 位 facing)。

客户端 handlePacketData 同样只在 VALUES[typeData].isTransparent() 时写入 topStacks。

数值

数值 默认值 单位
渲染开关 true —
最大渲染距离 128.0 格(方块坐标,< 128 才渲染)
悬浮物品数上限 8 个(topStacks.length,网络包也固定 8 个)

相关条目