透明箱子渲染(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 个) |
相关条目
- Crystal Chest - 唯一受影响的箱子
- Iron Chest 方块 -
TRANSPARENT_RENDER_*字段的读取处 - 箱子类型开关 · 猫与箱子行为 · 升级黑名单 - 其余配置项