Crate Pile System

基本信息

属性 值
包路径 net.mcft.betterstorage.tile.crate
类数量 6
核心常量 TileEntityCrate.slotsPerCrate = 18
世界 Tick 钩子 CratePileCollection.onTick()

来源:src/main/java/net/mcft/betterstorage/tile/crate/。

功能

木箱的堆叠(pile)系统是本 mod 唯一不依赖固定槽位的容器模型。与箱子不同,木箱可以自由堆叠成 1×1 到 3×3 的立方体,同一堆的所有木箱共享同一份物品数据——拆掉其中一箱不会丢失内容。

类清单

类 职责
CratePileData 单个堆叠的数据:箱数、容量、内容、已占用槽位
CratePileCollection 世界内所有堆叠的集合,负责落盘
CratePileMap 坐标 → 堆叠的索引,支持快速查找
CrateItems 物品内容容器(Map<ItemIdentifier, ItemStack>)
TileCrate 方块类
TileEntityCrate TileEntity 类

容量计算

public int getCapacity() {
    return numCrates * TileEntityCrate.slotsPerCrate;
}

来源:src/main/java/net/mcft/betterstorage/tile/crate/CratePileData.java:53-55;常量定义 src/main/java/net/mcft/betterstorage/tile/crate/TileEntityCrate.java:34。

堆叠规模 箱数 容量(槽位)
1×1 1 18
2×2 4 72
3×3 9 162

物品存储模型

CrateItems 用 Map<ItemIdentifier, ItemStack> 存储,每种物品只有一个条目(src/main/java/net/mcft/betterstorage/tile/crate/CrateItems.java:19):

  • get(ItemIdentifier) 返回该物品数量,0 表示不存在(:39-42)
  • set(ItemIdentifier, int) 增删物品并自动更新 totalStacks(:51-74)
  • getUniqueItems() 返回物品种类数(:29-31)
  • getTotalStacks() 返回总占用槽位数(:34-36)
  • getItems() 遍历全部内容(:80-82)
  • getRandomStacks() / getRandomStacks(int) 返回随机顺序的栈(:88-110),用于破坏时掉落

CrateItems 内部维护一个 NavigableMap<Integer, ItemStack> weightedMap(:22),按栈数累加建立权重索引,使随机选取与堆大小成比例(:112-119)。源码注释指出这是一个待优化的实现:

// TODO: Find a better way than recreating the weighted map every time something changes.

来源:CrateItems.java:25-26。

随机掉落

ItemsIterator(CrateItems.java:121-154)实现随机且不重复的遍历:

  • 用 TreeSet<Integer> picked 记录已选索引
  • 每次随机取一个未选索引(:139)
  • 返回的栈会按 maxStackSize 拆分(:146)

落盘

CratePileData 的保存流程(src/main/java/net/mcft/betterstorage/tile/crate/CratePileData.java):

方法 行 作用
isDirty() 98 是否已标记为脏
markDirty() 103 标记为脏(已脏或已销毁则跳过)
save() 115 若为脏则写入 collection 并清除标记

markDirty / save 在 crateDebugMessages 开启时输出日志,格式为 [CRATE DEBUG] Marked crate pile at [x,y,z] as dirty.(:106-111, 119)。

世界级保存由 CratePileCollection.onTick() 在世界 tick 的服务端侧触发(src/main/java/net/mcft/betterstorage/proxy/CommonProxy.java:316-319):

if (event.side == Side.SERVER) CratePileCollection.getCollection(event.world).onTick();

GUI 行数

木箱 GUI 的行数随堆叠规模变化(src/main/java/net/mcft/betterstorage/tile/crate/TileEntityCrate.java:233-241):

PlayerUtils.openGui(player, getName(), getColumns(),
    2 * Math.min(data.getNumCrates(), 3), getContainerTitle(), createContainer(player));

即行数 = 2 × min(箱数, 3),最多 6 行。列数取自容器。

比较器输出

getComparatorSignalStengthInternal(TileEntityCrate.java:252-257):

return ((data.getOccupiedSlots() > 0) ? (1 + data.getOccupiedSlots() * 14 / data.getCapacity()) : 0);

无物品时为 0,否则为 1 + 已占用 * 14 / 容量,范围 1–15。

方块视图

InventoryCrateBlockView(src/main/java/net/mcft/betterstorage/inventory/InventoryCrateBlockView.java)把堆叠内容暴露为标准 IInventory:

  • getSizeInventory() 返回 numStacksStored + 1(:39-41),第 0 槽为过滤槽
  • 构造时通过 data.addWatcher(this) 注册为 ICrateWatcher(:33-37)
  • 维护 changed 与 accessed 两个标志(:25, 29)

该视图受 general.enableCrateInventoryInterface 控制(TileEntityCrate.java:296, 303)。

相关条目