战利品袋预览界面(LootBag Preview GUI)

基本信息

属性 值
GUI ID GuiHandler.GUI_LOOTBAG = 1
客户端 GUI 类 client/gui/GuiLootBag.java(继承 GuiContainer)
容器类 core/ContainerLootBag.java(继承 Container)
格子类 core/SlotLootBag.java(继承 Slot)
背景贴图 assets/enhancedlootbags/textures/gui/lootbaggui.png
GUI 尺寸 238 × 256
格子布局 9 行 × 12 列 = 108 格(硬编码)

打开方式

if (pPlayer.capabilities.isCreativeMode && pPlayer.isSneaking()) {
    pPlayer.openGui(EnhancedLootBags.instance, GuiHandler.GUI_LOOTBAG, pWorld, ...);
    return pStack;   // 不消耗
}
条件 结果
创造模式 + 潜行 + 右键 打开预览界面,不消耗袋子
创造模式 + 普通右键 不打开界面,照常开袋掉 loot。⚠️ 代码没有为创造模式豁免消耗,pStack.stackSize -= 1 照常执行
生存模式 + 潜行 + 右键 无效,按普通开袋处理
生存模式 + 普通右键 正常开袋掉 loot

GuiHandler.getServerGuiElement 额外校验手持物必须是 ItemLootBag,否则返回 null(不开界面)。

README 原文:“Enter creative mode and Shift-Right click any LootBag you wish to inspect. … Also normal players are unable to open that Interface”。

界面性质:纯只读"幽灵物品"展示

这不是一个容器,是一个假库存(ContainerLootBag.FakeLootBagInventory)渲染出来的物品墙。所有交互被逐层封死:

层级 方法 返回 效果
SlotLootBag isItemValid(ItemStack) false 不能放入任何物品
SlotLootBag canTakeStack(EntityPlayer) false 不能取走任何物品
FakeLootBagInventory isItemValidForSlot(int, ItemStack) false 同上
FakeLootBagInventory decrStackSize(int, int) null 取出永远返回空
FakeLootBagInventory getStackInSlotOnClosing(int) null 关闭界面不返还任何物品
FakeLootBagInventory setInventorySlotContents(int, ItemStack) 空实现 写入被忽略
FakeLootBagInventory markDirty() 空实现 不触发存档
FakeLootBagInventory isUseableByPlayer(EntityPlayer) true —
FakeLootBagInventory getInventoryStackLimit() 64 显示用堆叠上限
ContainerLootBag transferStackInSlot(EntityPlayer, int) null Shift+点击什么都不做
ContainerLootBag mergeItemStack(...) false 明确不合并、不移动
ContainerLootBag slotClick(...) 手持物所在槽直接 null 防止把刚打开的袋子移走导致复制
ContainerLootBag canInteractWith(EntityPlayer) true —

transferStackInSlot 与 mergeItemStack 的注释写得很直白:// Just do nothing on shift click / // No, we don't merge。

界面里显示什么

createFakeInventoryFromID(groupID, 108) 遍历该组 <Loot> 列表,逐条构造 ItemStack 填入 108 格:

行为 说明
组不存在 记 error 日志,界面全空
某条 ItemName 解析失败 记 error 日志并 continue 跳过该条(其它条目仍显示)
组内 <Loot> 超过 108 条 截断,并打 warn:LootBagID %d contains more items than the GUI can currently display! (%d) The result will be truncated
少于 108 条 剩余格子留空

预览不含垃圾组战利品——createFakeInventoryFromID 只读本组 lg.getDrops(),合并进来的垃圾是运行时行为,不会出现在这里。

增强 tooltip(LootBagDrop NBT)

每个预览物品被塞入一个 NBT 复合标签 LootBagDrop,悬停时由 LootGroupsHandler.onToolTip(监听 ItemTooltipEvent)渲染成详细面板:

NBT 键 显示内容
LBDID DropID — 掉落标识(定位 XML 用)
LBDAmount Amount — 数量
LBDRnd Random — 数量是否随机
LBDLimit Limit — 每玩家限额
LBDWeight Weight — 权重
LBDGroup IGroup — 捆绑组名,空时显示 - no group -
LBDTrash Merges w Trash — 该组是否合并垃圾组
LBDCF0~LBDCF3 Drop % (F0/1/2/3) — 时运 0/1/2/3 下的实际中奖率

面板分两段标题:== Drop Information == 与 == Trash/Fortune Behavior ==,格式码经 TextFormatHelper.DecodeStringCodes 解码。

这就是 README 说的:“The GUI will show enhanced tooltips if you hover the items, to make it easier to find the correct entry in the XML file, if you want to change something.”

插入 / 抽取 / 漏斗 / 管道 / 升级槽

项目 状态
插入物品 不支持(isItemValid 全 false)
抽取物品 不支持(canTakeStack 全 false)
漏斗交互 不存在。战利品袋不是方块、无 TileEntity,漏斗无法对准它
管道交互 不存在。同理
升级槽 不存在。mod 未注册任何升级物品,也没有升级槽位代码
过滤器 / 黑名单 / 白名单 不存在。源码中 filter / blacklist / whitelist 关键词零命中;玩家无法给袋子设置任何物品过滤

相关条目