压缩物品(Compress Item)
基本信息
| 属性 | 值 |
|---|---|
| 键位 ID | key.craftingtweaks.compress |
| 默认按键 | Keyboard.KEY_NONE(未绑定) |
| 分类 | key.categories.craftingtweaks |
| 注册位置 | ClientProxy.init() → ClientRegistry.registerKeyBinding |
| 触发方式 | TickEvent.ClientTickEvent 边沿触发 |
英文显示名 Compress Item,中文「压缩物品」。
触发条件
比 旋转 宽松:只需要
- 玩家存在、
openContainer != null currentScreen instanceof GuiContainer- 不要求
getModSupportState为ENABLED/HOTKEYS_ONLY(判定块在 provider 之外)
但操作本身要求鼠标悬停在某个有物品的槽位上(mouseSlot != null 且
mouseSlot.getHasStack()),否则静默跳过。mouseSlot 在
GuiScreenEvent.DrawScreenEvent.Post 里通过 Mixin 的
callGetSlotAtPosition(mouseX, mouseY) 每帧刷新。
行为
| 按键组合 | 行为 |
|---|---|
| 直接按 | 压缩一组:合成 1 个产物 |
| 按住 Ctrl(左右任一) | 反转成拆分,等价于 拆分物品 |
| 按住 Shift | compressAll = false,即只压缩一组而非全部 |
isDecompress = LCONTROL || RCONTROL,compressAll = !isShiftDown。
服务端路径发送 MessageCompress(id 6,三个字段
slotNumber / isDecompress / compressAll);无服务端时客户端自行实现。
前置的强制清空
客户端 ClientProvider.compress 的第一步固定是
clearGrid(provider, player, container, 0, false),随后逐槽校验网格确实空了,
只要还有物品残留就整个操作中止(静默返回)。也就是说压缩/拆分会先清场,
玩家在网格里未取出的产物会被退回背包。
客户端路径还额外要求 canClear(...) 为真,即
!provider.requiresServerSide()(容器未开 phantomItems)。
服务端路径(HandlerCompress)不要求 provider 存在,但受配置
compressAnywhere 门控:未开启该配置且 provider 为 null 时直接 return。
完整压缩/拆分算法见 压缩与拆分。