使用指南
运行原理、上手步骤、模块开发与属性参考。
1运行原理
WA1 分两部分:桌面程序(WA1.exe)和自动装进游戏的插件。桌面程序发按键、管账号和模块;插件执行宏、把游戏内状态传回来。按住一个键,宏循环就自动跑。
一键宏引擎
每个宏配一个游戏内热键。运行时程序按设定节奏把热键发给游戏,触发对应的宏。你只管按住启动键,其余交给程序。
状态回传
血量、能量、光环剩余、技能冷却这些游戏内数据会实时同步回桌面程序,供你的判断逻辑使用。每个属性的当前值可在调试面板查看,数据是否就绪显示在主窗口状态栏。
工作模式与节奏
- 按键模式:按住绑定键期间持续执行,松开即停。
- 开关模式:按一下开始、再按一下停止。
- APM:每分钟操作数,决定执行节奏,可在设置里按档位调节,执行间隔带随机抖动。
2快速上手
第一次使用只需几步,先用现成的职业模块把流程跑通,再考虑自己改模块。
1. 下载与运行
从首页下载 wa1.zip,解压到任意目录,运行其中的 WA1.exe——免安装。
2. 注册与登录
首次使用先注册一个账号并登录。模块保存在云端,换电脑登录同一账号即可恢复。忘记密码可联系管理员重置,模块数据不受影响。
3. 选择模块
在主设置窗口的模块下拉里选一个与你职业对应的模块。没有合适的?可以向他人索取 .wa1 文件后用「导入模块」导入,或自己创建(见第 4 章)。
4. 绑定启动键与模式
- 把一个启动键(鼠标侧键或指定键盘键)绑定到模块里要执行的脚本。
- 按键模式:按住启动键期间持续执行,松开即停。
- 开关模式:按一下开始,再按一下停止。
- APM:决定执行节奏,按你的网络与手感在设置里挑一档即可。
5. 进游戏加载
进入游戏后输入 /reload 让插件加载模块内容。主窗口状态栏会提示当前该做什么:等待游戏通讯、模块已更新(按 F12 重载)、或已就绪。
6. 开始使用
一切就绪后,按住启动键(或在开关模式下按一下)即开始自动执行。展开调试面板可以看到每个属性的实时值,确认数据正常回传。
3注意事项
系统与客户端
- 仅支持 Windows x64(Windows 10 及以上)。
- 一键宏支持正式服(Midnight)与怀旧服;依赖游戏内插件的属性功能目前仅正式服。多客户端并存时,插件会装到当前按键目标所在的客户端,请用它进游戏。
- 正式服与怀旧服客户端默认都能识别。如果你的客户端 exe 名比较特殊(如私服),在程序目录的
wow_process.txt里加上进程名即可。 - 首次安装或更新模块后,需要在游戏内输入
/reload让插件加载最新内容;主窗口标题栏出现「模块已更新…按 F12」时,按 F12 即可重载。
账号与安全
- 单账号单会话:同一账号在新设备登录后,原设备会被立即踢下线(宏随之停止)。
- 忘记密码:联系管理员重置即可,云端模块数据不受影响、不会丢失。
- 模块只存云端:模块在本地加密后上传,服务器只保存密文,本地不落任何模块文件。
更新
- 程序在后台自动检查、下载并校验新版本,下次启动即为最新版,无需手动操作。
- 如需禁用自动更新,在程序目录放一个
noupgrade.txt空文件即可。
关于「受保护值」
正式服(Midnight)把部分战斗相关的数值(如单位血量、光环时间)对插件设为「受保护值」,不能直接参与运算。这对普通使用没有影响;但如果你要自己写模块的自定义代码,必须遵守相应的写法,详见下一章「模块开发」。
4模块开发
一个模块由属性、脚本、宏三个部件配合完成「判断」与「执行」。下面先讲清三者的关系,再依次介绍模块结构、决策脚本、热键、属性与编辑流程。
属性、脚本、宏:三个部件
一个能自动循环的模块靠三个部件配合:
- 属性(输入):把游戏内的数值或状态取回桌面端,例如血量、技能冷却、Buff 剩余时间。
- 脚本(决策):桌面端 Lua 脚本,读取属性、做判断,决定这一刻该放哪个技能。它是模块的大脑。
- 宏(动作):每个宏是一段游戏内宏命令(如
/cast 技能名)并绑定一个热键;脚本调用它即触发对应技能。
运行时你按住启动键,程序按 APM 节奏反复执行你绑定的脚本;脚本每轮根据当前属性值调用相应的宏。
模块结构
| 组成 | 说明 |
|---|---|
| 宏(150 行) | 每行一个宏:名称 + 宏文本 + 绑定的游戏内热键。其中后 45 行是 SelectTarget1..45 选择目标专用行,编号固定对应 player / party1-4 / raid1-40,只能改热键不能改编号。 |
| Lua 脚本(50 行) | 可复用的逻辑片段,绑定到鼠标键或热键来选择执行。 |
| 属性(45 行) | 把游戏内的一个数值/状态取回桌面端。每行一个属性,是模块判断逻辑的输入。 |
| 属性库 | 随模块存储的属性模板集合,新建模块自带 23 条预置(见第 4 章)。属性行可直接引用库条目。 |
| 职业 / 名称 / 版本 | 职业标签用于筛选;版本在每次保存时自动递增,回传给游戏端比对以提示重载。 |
决策脚本
脚本用 Lua 编写,是模块的决策核心。新建模块不带任何脚本,需要你自己写:在编辑器里双击一行 Lua 打开编辑器,给它起个名字并写入代码。
执行模型
脚本每次触发就从头完整跑一遍,不要在脚本里写死循环。「循环」来自外层:只要你按住启动键(按键模式)或开着开关(开关模式),程序就按 APM 节奏每轮调用一次你的脚本。所以脚本只需写「这一刻该做什么」的判断,为真就发一次宏、为假就什么都不做,下一轮再来。
可用函数
| 函数 | 用途 |
|---|---|
Prop(name) | 读某个属性的当前值(数字)。名字必须与属性表里的一致,否则本轮脚本报错中断。 |
Cast(name) | 触发某个宏(发送它绑定的热键)。找不到该宏名时静默跳过。 |
Select(index) | 选择目标,等价 Cast("SelectTarget"..index):1=自己、2-5=小队 1-4、6-45=团队 1-40。 |
CoolDown(name, ms) | 节流闸门:距上次调用满 ms 毫秒才返回 true 并重置。用来限制某个动作的触发频率。 |
SetTimeOut(name, ms)GetTimeOut(name) | 设置 / 查询一个定时点:ms 毫秒后到期,GetTimeOut 返回是否已到期。 |
Sleep(ms) | 阻塞等待若干毫秒(会卡住执行线程,一般用 CoolDown 代替)。 |
PressKey(code, [ms]) | 直接向游戏发送一个虚拟键码,可选按住时长。 |
此外可使用 Lua 标准库(math / string / table 等)。
示例
下面是一段示例脚本(需你按自己的属性名与宏名改写)。它每轮判断一次,用 CoolDown 避免每 tick 都触发:
-- 目标可攻击才输出
if Prop("目标可攻击") == 1 then
-- 血量低于 50% 且距上次补盾满 1.5 秒,补一次
if Prop("生命百分比") < 0.5 and CoolDown("补盾", 1500) then
Cast("治疗术")
-- 连击点满 5,放终结技
elseif Prop("连击点") >= 5 then
Cast("终结技")
else
Cast("主输出")
end
end
Prop("生命百分比") 是预置属性、返回 0~1 的小数;Prop("连击点") 返回原始点数。Cast 里的名字要与你宏表中的宏名对应。
绑定与运行
写好并命名脚本后,在主设置里把一个启动键(鼠标侧键或指定键盘键)绑定到这个脚本名。之后按住启动键(按键模式)或按一下(开关模式),程序就会按 APM 节奏反复执行它。
热键布局
热键全部由程序发送、你不用手按,所以布局的设计目标是「抗物理修饰键叠加」而非顺手。默认表用 30 个主键 × 5 个前缀 = 150 行,分三个互不相交的主键域:
- 宏 1–50:NUMPAD(小键盘)域
- 宏 51–90:标点键域(
, . / ; ' [ ] =) - 宏 91–105 与 SelectTarget:F 键域(F1–F12)
前缀(修饰键组合)只认这 5 种,其余写法会被拒绝或错发:
ALT-SHIFT-x CTRL-SHIFT-x SHIFT-x CTRL-x ALT-x
编辑器工作流
- 打开:在设置窗口点「模块编辑」,编辑的是当前选中模块的副本。
- 保存:点「保存」或按
Ctrl+S(编辑单元格时也生效)。保存需要登录,模块加密后上云;成功后编辑器自动关闭。 - 克隆:以当前内容为基础另存为一个新模块(名称自动加「克隆」后缀)。
- 导入 / 导出:通过 .wa1 文件在本地备份或分享模块;导入的模块会分配全新身份,不会覆盖他人的云端条目。
- 未保存守卫:关窗、新建、导入前若有改动会弹出确认。
属性的三种状态
属性表每行有「属性」下拉,三态由此决定:
| 状态 | 含义 |
|---|---|
| 不使用 | 空占位行,不生成、不回传。 |
| 自定义代码 | 这一行跑你自己写的 Lua 代码。给属性起个名字即自动启用。 |
| 库条目名 | 引用属性库里的某个模板,带入它的代码与默认参数;在行内点「编辑」改动代码即脱钩为自定义代码。 |
「参数」列最多填 3 段(逗号分隔),会注入为代码里的 arg1 / arg2 / arg3:能转成数字的按数字直传,其余当字符串,空段为 nil。同一段代码填不同参数即可复用(例如 player 和 target)。
自定义代码的运行环境
每个自定义属性的代码会被包成一个无参函数,与游戏端插件同处一个 Lua 作用域。生成后的形态如下(首行重新遮蔽了几个战斗数值函数,让你能拿到未处理的原始值;次行是参数注入):
SuperDPS.CustomFunc["属性名"] = function()
local UnitHealth, UnitHealthMax, UnitPower, UnitPowerMax =
SuperDPS.RawUnitHealth, SuperDPS.RawUnitHealthMax,
SuperDPS.RawUnitPower, SuperDPS.RawUnitPowerMax
local arg1, arg2, arg3 = "player", nil, nil -- 由「参数」列注入
-- 你的代码从这里开始,必须 return 一个值
return UnitHealth(arg1)
end
代码必须 return 一个值(数字或布尔)。布尔会以 1 / 0 回传;返回 nil 或运行出错都按 0 处理,且同一错误只在聊天框提示一次。因为与插件同作用域,你可以直接调用下面这些兼容层函数。
可直接调用的兼容层函数
GetSpellInfo(spell) GetSpellCooldown(spell) GetSpellCharges(id)
UnitAura(unit,i,filter) UnitBuff(unit,i) UnitDebuff(unit,i)
issecret(v) -- 判断是否为受保护值
SuperDPS 提供的接口
| 接口 | 用途 |
|---|---|
SuperDPS.GetUnitBuff(unit, aura)SuperDPS.GetUnitDebuff(unit, aura)SuperDPS.GetUnitAura(unit, aura, filter) | 查询光环。aura 可用法术 ID 或名称。返回 15 个值:name, icon, count, dispelType, duration, expirationTime, source, ...。其中 count / duration / expirationTime 已做消毒处理。Buff/Debuff 无 filter 参数。 |
SuperDPS.SN(v, "标记") | 消毒器:把受保护值或 nil 归 0,让它能参与比较/运算。需要计算前先经它处理。 |
SuperDPS.RawUnitHealth 等 4 个 Raw | 原始(未归零)的血量/能量函数。自定义代码里 UnitHealth 等名字已被指向它们。 |
SuperDPS.HekeliPrimary | Hekili 当前首个推荐技能的 ID(字段,非函数);未装 Hekili 时为 0。 |
SuperDPS.IsMidnight / SuperDPS.CleuAvailableSuperDPS.IsClassic() | 契约存根。前两个是布尔字段(分别恒 true / false),IsClassic() 是函数、恒返回 false。 |
受保护值(secret)的写法
正式服把部分战斗数值设为受保护值。判断一律以 issecret(v) 为准——注意 print() 能正常显示受保护值,「肉眼看到数字」不代表能运算。对受保护值的规则:
| 允许 | 禁止 |
|---|---|
直接 return、传参、字符串拼接、string.format / tostring、以及对非布尔值做 X or 0 / if not X 的真值判断 |
算术、比较(> == 等)、对布尔做真值判断、取长度、作表的键、索引访问、当函数调用 |
据此归纳出三档姿势:
- 直传档:只需把值取回、不做运算。直接
return即可,例如return UnitHealth(arg1)。 - 消毒档:需要比较或计算时,先经
SuperDPS.SN(v, "标记")归零再算。 - 自由档:确认非受保护的值(如
C_Spell.GetSpellCooldown().isActive、内置推荐技能 ID、UnitExists等)可自由做逻辑与运算。
UnitPercentHealthFromGUID(guid) 直接取 0~1 小数,不要用 UnitHealth / UnitHealthMax 做除法(会立即报受保护值算术错)。取 GUID 时记得判空。5内置属性与示例
新建模块自带以下 23 条预置属性,既可直接引用,也是编写自定义代码的范本。属性名为程序内置的固定中文名称。「参数」为该条的默认参数。
基础状态
player-- 战斗中可能为受保护值:只能直接返回,不可比较或运算
return UnitHealth(arg1)
取单位当前生命值(直传档范本)。
player-- 受保护值不可做除法,用 FromGUID 直传 0~1 小数
local guid = UnitGUID(arg1)
if not guid then return 0 end
return UnitPercentHealthFromGUID(guid)
生命百分比(0~1)。演示为什么不能自己算除法,以及 GUID 判空。
player,3-- 第二参数 3=能量;直接返回,不可比较或运算
return UnitPower(arg1, arg2)
取某类资源当前值(第二参数为资源类型 ID)。
player,4-- 第二参数 4=连击点;直接返回
return UnitPower(arg1, arg2)
与「能量」同一段代码、仅参数不同——演示代码复用。
-- 战斗中按 1、脱战按 0
return InCombatLockdown()
是否处于战斗中(布尔按 1/0 回传)。
return UnitExists("pet")
是否有召唤宠物。
target-- 目标存在且可攻击按 1(常用作输出总开关)
return UnitExists(arg1) and UnitCanAttack("player", arg1)
目标是否存在且可攻击(自由档,可直接逻辑判断)。
-- 可见敌对姓名板计数(AOE 张数);需在游戏内开启敌对姓名板
local n = 0
for i = 1, 40 do
local u = "nameplate" .. i
if UnitExists(u) and UnitCanAttack("player", u) then n = n + 1 end
end
return n
周围可见敌对目标数量,用于 AOE 判断。
技能与物品
5277-- timeUntilEndOfStartRecovery = 剩余秒数;直接返回,不可比较
-- (duration/startTime 战斗中受保护,勿仿)
local info = C_Spell.GetSpellCooldown(arg1)
return info and info.timeUntilEndOfStartRecovery or 0
某技能的冷却剩余秒数(参数为技能 ID)。
5277-- isActive/isOnGCD 官方保证永不受保护,可安全逻辑判断
local info = C_Spell.GetSpellCooldown(arg1)
if not info then return false end
return info.isActive and not info.isOnGCD
技能是否就绪(不在冷却、不在公共冷却)——自由档范本。
-- 61304 = 公共冷却专用查询 ID
local info = C_Spell.GetSpellCooldown(61304)
return info and info.timeUntilEndOfStartRecovery or 0
公共冷却剩余秒数。
108853-- 当前充能层数;直接返回(无充能机制的技能按 0)
local c = C_Spell.GetSpellCharges(arg1)
return c and c.currentCharges or 0
带充能技能的当前层数。
116,target-- 目标在射程内按 1;直接返回,不可做逻辑判断
return C_Spell.IsSpellInRange(arg1, arg2)
目标是否在某技能射程内(参数:技能 ID, 单位)。
5512-- 非战斗数值,可直接使用
return C_Item.GetItemCount(arg1)
背包内某物品数量(药水、治疗石等)。
光环
player,774-- 要做比较/减法,必须先经 SuperDPS.SN 消毒
local name, _, _, _, _, expire = SuperDPS.GetUnitBuff(arg1, arg2)
if not name then return 0 end
expire = SuperDPS.SN(expire, "lib.buffremain")
if expire == 0 then return 0 end
return expire - GetTime()
某增益的剩余秒数——消毒档核心范本(参数:单位, 法术 ID)。
player,774local _, _, count = SuperDPS.GetUnitBuff(arg1, arg2)
return count or 0
某增益的当前层数。
target,589local name, _, _, _, _, expire = SuperDPS.GetUnitDebuff(arg1, arg2)
if not name then return 0 end
expire = SuperDPS.SN(expire, "lib.debuffremain")
if expire == 0 then return 0 end
return expire - GetTime()
目标身上某减益的剩余秒数。
target,589local _, _, count = SuperDPS.GetUnitDebuff(arg1, arg2)
return count or 0
目标身上某减益的层数。
target,589-- 只认「自己施放」的减益(DoT 补覆盖判断)
local name, _, _, _, _, expire, source = SuperDPS.GetUnitDebuff(arg1, arg2)
if not name or source ~= "player" then return 0 end
expire = SuperDPS.SN(expire, "lib.mydotremain")
if expire == 0 then return 0 end
return expire - GetTime()
仅由你施放的减益剩余秒数,用于 DoT 补刷判断。
施法
target-- 正在施放/引导的法术 ID(打断判断),没在施法按 0
local id = select(9, UnitCastingInfo(arg1))
if not id then id = select(8, UnitChannelInfo(arg1)) end
return id or 0
目标正在施放或引导的法术 ID。
target-- 完成剩余秒数(打断时机);endTime 要算术,必须先 SN 消毒
local endMS = select(5, UnitCastingInfo(arg1))
if not endMS then endMS = select(5, UnitChannelInfo(arg1)) end
endMS = SuperDPS.SN(endMS, "lib.castremain")
if endMS == 0 then return 0 end
return endMS / 1000 - GetTime()
目标施法完成的剩余秒数。
技能推荐
-- 游戏内置「辅助作战」推荐的下一技能 ID,零插件依赖
return C_AssistedCombat and C_AssistedCombat.GetNextCastSpell() or 0
游戏内置推荐的下一个技能 ID(非受保护值,可直接比较)。
-- 未装 Hekili 时恒 0
return SuperDPS.HekeliPrimary
Hekili 插件当前首推荐技能 ID。