使用指南

运行原理、上手步骤、模块开发与属性参考。

1运行原理

WA1 分两部分:桌面程序(WA1.exe)和自动装进游戏的插件。桌面程序发按键、管账号和模块;插件执行宏、把游戏内状态传回来。按住一个键,宏循环就自动跑。

一键宏引擎

每个宏配一个游戏内热键。运行时程序按设定节奏把热键发给游戏,触发对应的宏。你只管按住启动键,其余交给程序。

状态回传

血量、能量、光环剩余、技能冷却这些游戏内数据会实时同步回桌面程序,供你的判断逻辑使用。每个属性的当前值可在调试面板查看,数据是否就绪显示在主窗口状态栏。

工作模式与节奏

  • 按键模式:按住绑定键期间持续执行,松开即停。
  • 开关模式:按一下开始、再按一下停止。
  • APM:每分钟操作数,决定执行节奏,可在设置里按档位调节,执行间隔带随机抖动。
一键宏在正式服(Midnight)与怀旧服都能用;依赖游戏内插件的属性功能目前仅正式服支持。

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 即可重载。

账号与安全

  • 单账号单会话:同一账号在新设备登录后,原设备会被立即踢下线(宏随之停止)。
  • 忘记密码:联系管理员重置即可,云端模块数据不受影响、不会丢失。
  • 模块只存云端:模块在本地加密后上传,服务器只保存密文,本地不落任何模块文件。
强烈建议定期用编辑器的「导出模块」把重要模块存成 .wa1 文件做本地备份——它不需要登录,也是账号异常时的逃生通道。

更新

  • 程序在后台自动检查、下载并校验新版本,下次启动即为最新版,无需手动操作。
  • 如需禁用自动更新,在程序目录放一个 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。同一段代码填不同参数即可复用(例如 playertarget)。

自定义代码的运行环境

每个自定义属性的代码会被包成一个无参函数,与游戏端插件同处一个 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.HekeliPrimaryHekili 当前首个推荐技能的 ID(字段,非函数);未装 Hekili 时为 0。
SuperDPS.IsMidnight / SuperDPS.CleuAvailable
SuperDPS.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,774
local _, _, count = SuperDPS.GetUnitBuff(arg1, arg2)
return count or 0

某增益的当前层数。

减益剩余target,589
local 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,589
local _, _, 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推荐无参数
-- 未装 Hekili 时恒 0
return SuperDPS.HekeliPrimary

Hekili 插件当前首推荐技能 ID。