1.前言
什么是宏
在编程语言中,宏是一种在 编译时进行文本替换的机制。通过宏定义一个代码片段,方便在项目各处进行复用。宏可以简化代码、提高代码的可读性和可维护性,也可定义复杂的逻辑和算法(不推荐)。下面是一个 C 语言中定义宏的示例:
// 宏定义一个函数,作用是比较两个数字大小,返回较大值
#define MAX(a, b) a > b ? a : b
int main(void) {
// 调用宏比较 1 和 3,最终输出结果 3
printf("%d\n", MAX(1, 3));
return 0;
}
魔兽世界的宏
WOW 的宏允许玩家在游戏中 按照预设执行一个或多个操作,例如自动攻击、使用多个技能等,从而提高玩家的游戏效率和体验。本质上和编程语言中宏概念类似,但区别在于 WOW 对宏加入了诸多限制。下面是一个 WOW 中定义宏的示例:
#showtooltip
/cast 技能1
/cast 技能2
2.语法
注意
- 单个宏支持最大字符串长度为 255
- 宏只能使用英文标点符号,并且大小写敏感
- 宏命令每行代表一个语句,每条语句中包含一个
;
则代表新增一个子句 <xxx>
代表参数是可选的,[xxx]
代表参数是必填的
宏语法
常见的宏语法结构有以下几种:
# 1.执行命令+参数
/命令 <参数>
# 2.若 满足条件 则 执行命令+参数
/命令 <条件> <参数>
# 3.若 满足条件 则 执行命令+参数1 否则 执行命令+参数2(三元运算符 ?:)
/命令 <条件> <参数1>;<参数2>
# 4.若 满足条件1 则 执行命令+参数1;若 满足条件2 则 执行命令+参数2(if...else if)
/命令 <条件1> <参数1>;<条件2> <参数2>
# 5.不满足条件 则 执行命令+参数(非)
/命令 <no条件> <参数>
# 6.满足条件1 且 满足条件2 则 执行命令+参数(且)
/命令 <条件1,条件2> <参数>
# 7.满足条件1 或 满足条件2 则 执行命令+参数(或)
/命令 <条件1><条件2> <参数>
在 WOW 中宏的语法结构相对简单,按照从上到下、从左到右一个个子句执行。大多数情况下我们 需要基于某个条件来执行某个命令。
宏语句执行细节
当多个 /cast
命令绑定在一个宏上时,WOW 会按照 技能1
、技能2
、技能3
的顺序依次执行,但需注意 除了最后一个技能之外其他必须没有 GCD,否则会导致后续技能永远无法施放:
/cast 技能1 # 宏的冷却时间以技能 1 为准
/cast 技能2 # 如果技能 2 有 GCD,则技能 3 不会施放
/cast 技能3 # 因此有 GCD 的技能必须放在最后
不同于传统编程语言,在 WOW 的宏命令中 每行代表一条语句,每条语句中 存在 ;
则代表开启了一个新子句。子句容易导致和预期不相符的执行结果,因此需要慎重使用:
# 每行代表一条独立的语句
/cast 技能
# 该行语句中存在分号,等于被拆为两条子句
/cast [条件] 技能1;技能2
# 预期:宠物攻击敌对的焦点目标
# - 由于后面多加了 ; 导致被拆为两条子句
/petattack [@focus,harm];
# - 因此上面这条语句等价于下面这两条语句,即使焦点目标不存在,宠物也会攻击当前目标
/petattack [@focus,harm]
/petattack
# - 改为这样可以满足预期
/petattack [@focus,harm]
当同时使用 /castsequence
和 /cast
时,WOW 首先执行队列中的 技能1
和后续的 技能4
,然后按照队列顺序执行 技能2
、技能3
,如此反复。利用这个特性我们可以实现积累消耗特性的一键输出宏,需要注意 技能1
必须是个无冷却无 GCD 的技能或物品:
# 利用技能1和技能4会同时施放的特性组合积累消耗型宏命令
/castsequence 技能1,技能2,技能3
/cast 技能4
# 盗贼的影袭是积累连击点技能、剔骨是消耗连击点技能,如此实现有连击点放剔骨,没有放影袭
/castsequence 魔力探测石,影袭
/cast 剔骨
3.命令
命令是宏的核心,用于定义宏执行的具体操作。
图标显示
#showtooltip
必须放在宏的第一行起始位置,如果不指定技能名则默认采用当前技能图标。
# 显示指定技能的图标
#showtooltip <技能名参数>
基础操作
包含了 WOW 中常见的操作,例如施放技能、使用物品、终止宏命令等。大多数情况下 /cast
和 /use
是等价的,即都可以施放技能或使用物品。
# 1.开始自动攻击
/startattack
# 2.停止自动攻击
/stopattack
# 3.停止施法
/stopcasting
# 4.施放技能
/cast [技能名参数]
# 5.使用物品
/use [物品名参数]
# - 装备栏:13-第一个饰品、14-第二个饰品
/use [装备栏参数]
# - 背包:从右到左 0(行囊)、1、2、3、4
# - 背包栏:背包从左上到右下栏号依次为
# 1 2 3 4
# 5 6 7 8
/use [背包参数] [背包栏参数]
# 6.按照队列顺序循环施放技能或使用物品(如果某个技能放不出来,后续队列不会执行)
# - reset:重置参数,满足后面的条件会重置队列
# - n:n 秒未按 则 重置队列
# - target:切换目标 则 重置队列
# - combat:脱离战斗 则 重置队列
# - shift/alt/ctrl:按下 shift/alt/ctrl 则 重置队列
# - /:满足其中一个参数就触发重置
/castsequence <reset=n/target/combat/shift/alt/ctrl> [技能名参数1,物品名参数2...]
# 7.装备物品(当前物品可装备的默认位置)
/equip [物品名参数]
# 8.装备到指定位置
# - 装备栏:13-第一个饰品、14-第二个饰品
/equipslot [装备栏参数] [物品名参数]
# 9.终止宏命令(一般需要搭配条件使用)
/stopmacro
状态控制
用于控制角色本身的 buff、姿态等。
# 1.取消状态
/cancelaura [状态名参数]
# 2.取消姿态
/cancelform
技能栏控制
用于角色多个技能栏之间的切换。
# 1.切换到指定技能栏
/changeactionbar [技能栏参数]
# 2.在指定两个技能栏之间来回切换
/swapactionbar [技能栏参数1] [技能栏参数2]
选中目标
用于设置以何种方式选中目标。
# 1.选中指定目标
/target <目标名参数>
# 2.选中敌对目标(等同于默认 tab 切换)
/targetenemy
# 3.选中友方目标
/targetfriend
# 4.选中队伍成员
/targetparty
# 5.选中上一个目标
/targetlasttarget
# 6.切换上一个敌对目标
/targetlastenemy
# 7.选中鼠标指向的目标
/targetmouse
# 8.选中宠物
/targetpet
# 9.清除目标
/cleartarget
焦点目标
用于焦点目标的设置与清除。
# 1.当前目标设置为焦点
/focus <目标名参数>
# 2.清除焦点
/clearfocus
宠物控制
用于设置宠物的行为、技能、战斗模式等。
# 1.宠物攻击
/petattack
# 2.宠物跟随
/petfollow
# 3.宠物前往指定位置
/petmoveto
# 4.宠物停留
/petstay
# 5.宠物协助模式
/petassist
# 6.宠物防御模式
/petdefensive
# 7.宠物被动模式
/petpassive
# 8.宠物技能自动释放
/petautocaston <技能名参数>
# 9.宠物技能手动释放
/petautocastoff <技能名参数>
4.条件
条件是判断宏语句是否执行的依据,本质上类似于编程语言中的 if
分支判断语句。
分支判断
在编程语言中分支判断一般有 if
、if-else
、switch
三种,WOW 的宏命令实际上只支持 if
。下面以施放技能为例:
# 1.若 是友好目标 则 施放治疗术
/cast [help] 治疗术
# 2.若 不是友好目标 则 施放惩击
/cast [nohelp] 惩击
逻辑判断
在编程语言中逻辑判断就是 或、且、非 三种,WOW 的宏命令也遵循这个规则。下面以施放技能为例:
# 1.或(一真即真):若 是友好目标 或 是小队成员 则 施放治疗术
/cast [help][party] 治疗术
# 2.且(一假即假):若 是友好目标 且 是小队成员 则 施放治疗术
/cast [help,party] 治疗术
# 3.非(取反):若 不是小队成员 则 施放治疗术
/cast [noparty] 治疗术
可用条件
在 WOW 宏命令中,@player
等价于 target=player
。考虑到单个宏支持最大字符串长度为 255,建议采用前者缩短长度。
类型 | 条件语句 | 作用 | 取反 |
---|---|---|---|
作用目标 | @player | 玩家 | |
作用目标 | @pet | 玩家宠物 | |
作用目标 | @target | 当前目标 | |
作用目标 | @targettarget | 当前目标的目标 | |
作用目标 | @focus | 焦点目标 | |
作用目标 | @focustarget | 焦点目标的目标 | |
作用目标 | @mouseover | 鼠标指向目标 | |
作用目标 | @cursor | 鼠标指向位置 | |
目标状态 | harm | 敌对目标 | noharm |
目标状态 | help | 友好目标 | nohelp |
目标状态 | exists | 存在目标 | noexists |
目标状态 | dead | 死亡目标 | nodead |
目标状态 | party | 小队目标 | noparty |
目标状态 | raid | 团队目标 | noraid |
自身状态 | spec:1/2/3 | 当前专精 1/2/3 | nospec:1/2/3 |
自身状态 | stance:0/1/2 | 当前姿态 无/1/2 | nostance:0/1/2 |
自身状态 | form:0/1/2 | 当前姿态 无/1/2 | noform:0/1/2 |
自身状态 | actionbar:1/2/3 | 当前技能栏 1/2/3 | noactionbar:1/2/3 |
自身状态 | combat | 战斗中 | nocombat |
自身状态 | stealth | 潜行中 | nostealth |
自身状态 | channeling | 读条中 | nochanneling |
自身状态 | mounted | 骑乘中 | nomounted |
自身状态 | swimming | 游泳中 | noswimming |
自身状态 | group | 组队中 | nogroup |
所处环境 | indoors | 室内区域 | noindoors |
所处环境 | outdoors | 室外区域 | nooutdoors |
所处环境 | flyable | 可飞行区域 | noflyable |
组合按键 | mod:alt/ctrl/shift | 按下 alt/ctrl/shift 键 | nomod:alt/ctrl/shift |
组合按键 | button:1/2/3/4/5 | 按下鼠标 左/右/中/侧 键 | nomod:alt/ctrl/shift |
姿态编号
在 WOW 中部分职业可以通过技能进入特定的姿态中,例如德鲁伊的熊形态、猫形态、枭兽形态等。这类姿态在宏命令中统一用编号进行区分。
编号 | 德鲁伊 | 战士 | 暗牧 | 盗贼 | 萨满 |
---|---|---|---|---|---|
1 | 熊形态 | 战斗姿态 | 暗影形态 | 潜行 | 幽灵狼 |
2 | 海豹形态 | 防御姿态 | |||
3 | 豹形态 | ||||
4 | 旅行形态 | ||||
5 | 枭兽/树形态 | ||||
6 | 飞行形态 |
5.Lua 脚本
熟悉编程的朋友们都知道,WOW 本体是采用 C++ 编写的,同时外挂了 Lua 作为界面扩展脚本。对于有编程基础的人来说,可以使用 Lua 脚本结合 WOW API 可以实现很多有趣的功能。WOW 宏命令支持运行一些简单的 Lua 脚本:
# 1.运行 lua 脚本(推荐)
/run [lua 脚本]
# 2.运行 lua 脚本
/script [lua 脚本]
下面编写一个基于 Lua 脚本的恐惧宏,用于通知队友你已恐惧他当前正在攻击的目标:
--[[
WOW API 解析
1.GetNumPartyMembers():获取当前小队人数
2.UnitName(id):通过单位 id 获取单位名称
3.UnitIsUnit(id1, id2):判断两个单位 id 是否对应同一个单位
4.SendChatMessage(msg, chatType, languageId, target):发送聊天信息
]]
-- 根据小队人数 for 循环遍历
for i = 1, GetNumPartyMembers() - 1 do
-- 拼接小队成员 id
local unit = 'party'..i
-- 根据小队成员 id 获取小队成员名称
local name = UnitName(unit)
-- 判断小队成员目标与当前冰冻目标是否一致
if UnitIsUnit(unit..'target', 'target') then
-- 如果一致,则发送密语通知该小队成员停止攻击
SendChatMessage('我已恐惧你当前目标,请停止攻击!', 'WHISPER', nil, name)
end
end
别忘了 WOW 单个宏支持最大字符串长度为 255 的限制,尽量删掉不必要的换行符、注释、空格,整理后的宏命令如下:
#showtooltip
/cast 恐惧
/run for i=1,GetNumPartyMembers()-1 do local unit='party'..i local name=UnitName(unit) if UnitIsUnit(unit..'target','target') then SendChatMessage('我已恐惧你当前目标,请停止攻击!','WHISPER',nil,name) end end
更多 Lua 相关内容,请参阅 Lua 脚本入门。
6.CVar 系统变量
CVar 变量是 WOW 中用于控制游戏界面和行为的变量,例如自动变形、自动拾取等。
设置方式
设置 CVar 变量有两种方式:一种是通过 API 风格的 /run SetCVar("系统变量名", 值)
,另一种是通过控制台命令 /console 系统变量名 值
:
# 一.修改变量
/run SetCVar("scriptErrors", 1) # API 风格设置系统变量
/console scriptErrors 1 # 控制台命令风格设置系统变量
# 二.查询变量
/dump GetCVar("scriptErrors")
# 三.重置变量
/run SetCVar("scriptErrors", GetCVarDefault("scriptErrors"))
常用系统变量
建议每个版本开始前通过 /console cvar_default
重置系统变量,避免版本间差异:
# 重置所有 CVar 设定
/console cvar_default
# 重置单一 CVar 设定
/run SetCVar("系统变量名", GetCVarDefault("系统变量名"))
# 伤害数字是否显示:0-关闭、1-开启
/console floatingCombatTextCombatDamage 1
# 治疗数字是否显示:0-关闭、1-开启
/console floatingCombatTextCombatHealing 1
# 伤害数字大小:1-默认
/console WorldTextScale 1
# 伤害数字弹出方式:0-传统、1-随机
/console floatingCombatTextCombatDamageDirectionalScale 1
# 仇恨百分比是否显示:0-关闭、1-开启
/console threatShowNumeric 1
# 施放技能是否自动变形(例如德鲁伊愈合):0-关闭、1-开启
/console autoUnshift 0
# 敌方玩家姓名板是否显示职业颜色:0-关闭、1-开启
/console ShowClassColorlnNameplate 1
# 友方玩家姓名板是否显示职业颜色:0-关闭、1-开启
/console ShowClassColorlnFriendlyNameplate 1
# 姓名板是否显示施法条:0-关闭、1-开启
/console showVKeyCastbar 1
# 聊天和谐:'0'-关闭、'1'-开启
/console SET profanityFilter "0"
# tab 切换选择距离
/console SET targetNearestDistance "50"
# 最大视野距离倍数(默认 39 码):1-默认倍数、2.6-最大倍数
/console cameraDistanceMaxZoomFactor 2.6
# 查询角色当前移速
/script print(string.format("%d%%", GetUnitSpeed("player") / 7 * 100))