右键拖拽替换(RMBTweak)

基本信息

属性 值
配置字段 MTConfig.RMBTweak
类型 boolean
默认值 true(MTConfig.java 字段初始值)
运行时总开关 Main.DisableRMBTweak(public static boolean,默认 false,本仓库内无处赋值)
实现类 yalter.mousetweaks.handlers.ClickHandler#handleRMBTweak
作用方式 完全替换原版 RMB 拖拽机制

功能

按住右键从一个栏位拖出物品堆后,每经过一个栏位就对它单独按一次右键, 因此同一个栏位可以被反复经过并反复投入物品——这正是它与原版拖拽的唯一差别 (原版一次拖拽只会在每个栏位投入一次)。

命中条件(三者同时满足):

  1. MTConfig.RMBTweak == true 且 Main.DisableRMBTweak == false;
  2. 鼠标上确实拿着物品(stackOnMouse != null),且与目标栏位里的物品 areStacksCompatible(isItemEqual + areItemStackTagsEqual,NBT 必须完全一致);
  3. 目标栏位不是合成产物栏位(context.isCraftingOutputSlot 为 false)。

满足后执行 context.clickSlot(currentScreen, selectedSlot, 1, false)—— 即对该栏位发一次「鼠标键 1、不按 Shift」的点击。

首个栏位与 shouldClick 状态机

RMB 拖拽需要先确定「第一次按下的栏位」,ClickHandler 用三个状态字段跟踪:

字段 作用
firstSlot 拖拽起点的栏位(尚未结算)
firstSlotClicked 起点是否已经补过一次点击
shouldClick 关闭原版拖拽时,是否需要对起点补一次右键点击

状态迁移规则:

  • updateShouldClickFromRmbState:若右键按下、且 stackOnMouse != oldStackOnMouse、 且 oldStackOnMouse == null,说明原版机制刚刚自己从鼠标上拿起了整堆物品, 此时把 shouldClick 置为 false——即接管得太晚,不再补点,避免重复取物。
  • 起点捕获:Mouse.isButtonDown(1) && !firstSlotClicked && firstSlot == null && oldSelectedSlot != null 时,若鼠标上的物品与 oldSelectedSlot 里的物品不兼容,说明起点本身无法再投入, 同样把 shouldClick 置为 false。
  • 无起点兜底:Mouse.isButtonDown(1) && oldSelectedSlot == null && !firstSlotClicked && firstSlot == null 时无条件 shouldClick = false。
  • 结算:selectedSlot == null(鼠标移出所有栏位)或命中可投入的栏位时, 调用 context.disableRMBDragIfRequired(currentScreen, firstSlot, shouldClick), 把 firstSlot 清空并置 firstSlotClicked = true。
  • 释放复位:resetDragStateOnRightButtonRelease() 在右键松开时复位 firstSlotClicked / firstSlot / shouldClick。

disableRMBDragIfRequired 对原版容器的实现是 disableVanillaRMBDrag():

guiContainer.field_146995_H = true;
guiContainer.field_147007_t = false;

即通过 访问转换器 提升为 public 的两个混淆字段,把原版的 「正在拖拽中」与「正在拆分拖拽中」两个状态强制清掉,让原版不再继续处理这次拖拽。

已知限制

  • 合成产物栏位被完全排除(见 容器兼容性 中各容器的产物栏位表), 所以在产物栏上悬停不会触发本 tweak。
  • Forestry 容器的 disableRMBDragIfRequired 在 ModCompatibility 里落到 default: 分支, 不做任何事(既不关闭原版拖拽也不补点起点点击)。
  • Main.DisableRMBTweak 是留给他人(其他 mod / 脚本)通过反射或直接调用关停本 tweak 的挂钩点, 本仓库内没有写入方,因此正常游玩时恒为 false。

相关条目