自用 D3 GHub 鼠标宏。
虽然是为 Diablo 3 编写的游戏脚本,但其实可以简单扩展出任意需要有规律点击的宏操作。
- 操作简单 -
Copy/Paste方式,直接把脚本代码复制粘贴到 GHub 配置文件的代码编辑器里并保存 - 使用方便 - 如下代码中的
dofile()方式,有两点好处:
- 更方便用编辑器修改保存代码
- 修改保存代码后切换回游戏 会自动生效, 不用每次都打开 GHub 进行复制粘贴
GHub 自动切换配置文件时会重新加载并运行配置文件的脚本代码
-- 把 `%s` 替换成你保存 `gls.lua` 文件的路径
dofile("%s/gls.lua")- 鼠标中键
- 宏任务运行期间按下鼠标中键,会 终止宏任务
- 非宏任务运行期间按下鼠标中键,会触发 血岩赌博 功能
- 非宏任务运行期间按下鼠标中键 +
Alt键,会触发 自动分解 功能
- DPI 切换键 - GHub 键位码为
6 - 侧后键 - GHub 键位码为
4 - 侧前键 - GHub 键位码为
5
参考代码里对 DPI 切换键,侧后键,侧前键 的绑定方式:
- 先从 GHub 中鼠标的设置界面找到按键对应的键位码,比如 “鼠标按键 4” 中的
4, “鼠标按键 5” 中的5 - 然后用
Gm:setMouseAssignment(keyCode, task)方法来绑定宏任务
Gm:setMouseAssignment(4, function()
Builds.Monk:LoDWoL()
end)参考 Builds.Wiz:VryLollipop, Builds.DH:DevouringStrafe, Builds.Monk:LoDWoL, Builds.Crus:AoVFist 等 Build 的实现
由于 GHub 只能检测 lshift, lctrl, lalt 以及鼠标 “中键” 和 “右键” 的按下状态,
为了便于操作和舒适性,在使用鼠标宏时我们的手自然会放在键盘左下角靠近控制键的地方,
这通常会跟不使用鼠标宏时手的摆放位置大不相同,需要的键位设定也会不一样。
这样,我们会需要适配 2 种不同模式的键位配置:
- 手动模式的键位配置
- 适合 “开荒”、“挑战秘境” 等 BD 不成形没法用宏的场景
- 适合 “塔格奥新星” 等鼠标宏派不上用场的场景
- 宏模式的键位配置
- 像 “冰吞” 一样可以完全交给鼠标宏来点击和攻击,自己只需要偶尔点下控制键切换输出或跑路模式
- 类似 “散钟”、“娜塔亚陷阱” 这类需要鼠标宏配合手工操作才能顺畅游戏的玩法
为了 “尽量少改键位” 并良好适配上面 2 中模式,强烈推荐参考下面的键位配置:
-
动作条技能 1: 默认的
1和a- 手动模式用
1 - 宏模式用
a
- 手动模式用
-
动作条技能 2: 默认的
2和x- 手动模式用
2 - 宏模式用
x
- 手动模式用
-
强制移动:
spacebar和z- 手动模式下用
spacebar - 宏模式下用
z
- 手动模式下用
-
强制站立:
c- 手动模式下用
c - 宏模式下通过控制键事件来按
c(没有位置合适的按键了/使用场景也不多)
- 手动模式下用
-
药水:默认的
q和5- 手动模式用
5 - 宏模式用
q
- 手动模式用
-
关闭所有打开的窗口:
w- 默认的
spacebar已改作它用
- 默认的
-
隐藏界面:
alt + w- 默认的
alt + z在宏模式时容易误触发
- 默认的
-
切换镜头缩放:
h- 默认的
z要改作它用 - 相比
u它离常用的i更远,不容易误触
- 默认的
- 打开:自动切换到文稿的输入法(Automatically switch to a document's input source)
- 关闭:自动大写字词的首字母(Capitalize words automatically)
GetMousePosition()返回的坐标值最大并不一定是65535,会受多屏影响- 在 “MacOS + 多显示器” 环境下,
GetMousePosition()返回的鼠标位置会受屏幕布局影响,可能是负值
如果 自动分解时鼠标移动位置不准,请搜索
Inventory并调整各个数值,直到在你的屏幕上鼠标能准确移动到相关位置为止
-
Mac 下,
EnablePrimaryMouseButtonEvents无效 -
Mac 下,鼠标宏按下的 “强制移动” 在一些情况下会意外失效导致人物不动,需要重新触发
-
Mac 下,
rctrl这类r开头的控制按键都会识别成l开头的IsModifierPressed可以识别ctrl和lctrl- 但
PressKey等按键相关方法只识别l/r开头的 - 所以,为了保证键盘按键相关方法都能正确执行,键盘控制键统一使用带
l前缀的
-
所有键盘 keyname 都为
string, 所有鼠标 keycode 都为number, 这个特点可以用来区分鼠标和键盘按键 -
IsKeyLockOn 有效但不好用
capslock键在 Mac 下默认是切换输入法,不要使用!scrolllock和numlock两个键位置不好,也不要使用!
-
鼠标按键 API 和鼠标事件
- 所有鼠标按键相关 API 都只支持
1~5这 5 个按键码 - 调用这些 API 进行的鼠标按键操作,不会触发
OnEvent - Mac 下
IsMouseButtonPressed只能正确识别1~3这三个键的状态 - 由于左键和右键不适合绑定其它功能,那么
1~3三个键中就只有Mouse.Middle可作为多功能控制键 onEvent方法报告的按键码2为鼠标右键,3为鼠标中键- 鼠标按键 API 使用的按键码
2为鼠标中键,3为鼠标右键 - 针对这种不一致,我们以 鼠标按键 API 为准,因为
onEvent方法只会用一次
- 所有鼠标按键相关 API 都只支持
-
OnEvent中鼠标按键事件的选择- 监听
MOUSE_BUTTON_RELEASED而不是MOUSE_BUTTON_PRESSED - 这有机会让
Mouse.Middle键在MOUSE_BUTTON_PRESSED这个前序状态中做一些事情,比如下面说的 “多功能控制键” - 不监听 "鼠标左键" 和 "鼠标右键"(Mac 下左键也无法监听),这俩键功能太多且无法完全自定义
- 监听
-
关于 “多功能控制键“
- 目前的 “多功能” 主要指 绑定一个宏任务的同时,在宏任务运行期间通过
Pressed触发Gm:stop()逻辑 - 如果不做额外控制,会出现 Pressed 结束一个动作后 Released 又触发动作 的问题,进入死循环
- 所以增加了一个
Gm._updateLastRunningEvent标记来记录触发Gm._running状态变化的按键信息 - 通过记录的信息可以分析当前按键动作和上次按键动作的关系:是不是同一按键,是不是从 “结束(Press)” 到 “触发(Release)”
- 如果 “按下(
PressAndRelease)” 动作的Pressed部分已经用作触发Gm:stop(), 就要阻止后续的Released动作触发绑定的宏任务,从而解决上面提到的 “任务无法终止” 等问题 - 目前来看
Mouse.Middle最适合做多功能控制键 Mouse.Right可酌情做多功能控制键,虽然不在OnEvent监听它无法触发宏任务,但它本身的右键技能 + 绑定任务 也算是一个多功能控制键- 为鼠标按键绑定控制事件,请只使用
Pressed- 因为Released用于接收OnEvent
- 目前的 “多功能” 主要指 绑定一个宏任务的同时,在宏任务运行期间通过
-
GHub 的
Sleep方法不支持小数和负数(各种 0 值除外) -
GHub 的
PlayMacro/AbortMacro等方法只支持 绑定到按键的录制宏,在脚本里并不能用 -
GHub 的 “宏” 只支持录制不支持脚本,也就意味着无法通过 UI 界面绑定脚本宏
-
关于
pcall- 只对
Gm:_start使用pcall并打印错误信息,这样才容易确定宏脚本是没问题的
- 只对
-
关于脚本引擎的 “暂停状态”
- 暂停状态使用场景很少很少,不值得增加复杂性 - 日常操作和实现上的双重复杂性
- 对于类似 “过图后重对元素戒” 的场景,绑定一个 “对元素” 的控制键事件就行
-
关于
action:shouldDeferExecution- 返回
true表示当前 action 进入 “稍后再试” 状态 - 不同于 "暂停状态",Defer 时脚本引擎会持续运行并跳过已经 ready 的 action,
- 等 Defer 状态退出后被 “稍后再试” 的 action 会被立刻执行
- 这通常用于 “捡东西”、“读条” 和其它一些需要 “防打断” 但又不值当停止宏的场景
- 返回
-
关于定时器
timer/setTimeout- 目前设计,timer 背后也是 Action, 但不受
shouldDeferExecution约束
- 目前设计,timer 背后也是 Action, 但不受
-
关于
alert()- 这种需求很少很少,目前仅保留
Keys.Alert键位配以备不时之需
- 这种需求很少很少,目前仅保留
-
关于 “按键按下持续时间”
- 这种需求很少很少,可通过一对儿加
delay的 action 来实现,不再增加复杂性 - 甚至按下后先
sleep()然后再释放也不是不行
- 这种需求很少很少,可通过一对儿加
-
关于 “强制站立/移动”
- 不在 “强制移动” 和 “强制站立” 相关方法里进行 “sleep 延时”,因为不同场景需要的 ”延时“ 需求不同
- 类似
Gm:TownPortal(),跟随具体场景设置延时更合适
-
关于 “长时间 Action/ControlKeyEvent”
- 长时间运行的
Action/ControlKeyEvent会严重影响操作流畅性,要尽量避免 - 如果无法避免,尽量维持在
1300ms以下可极大改善阻滞感 - 保持操作节奏,一通乱按不但加巨阻滞感,也无法打出伤害
- 长时间运行的
-
关于
action.key支持 “多键”- 这种需求很少很少,可通过
action.func()来实现,不再增加复杂性 - 另外也无法处理
PressKey()等 API 按下多键时的顺序和间隔时间 - 鼠标按键相关的 按下/释放 按键函数不支持多键
- 这种需求很少很少,可通过
-
关于运行时
data处理- 保持简单,直接按 Lua
table的存取方式,不再提供get/set等方法
- 保持简单,直接按 Lua