战利品袋预览界面(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 关键词零命中;玩家无法给袋子设置任何物品过滤 |
相关条目
- 战利品袋(LootBag) - 唯一物品与开袋流程
- 战利品组等级体系 - 108 格的来源与组属性
- 掉落条目规则 - tooltip 中各字段的语义
- 垃圾组合并机制 - 为什么预览里看不到垃圾