|
|
本帖最后由 吾奶常煽赵子龙 于 2024-6-21 10:33 AM 编辑
上一篇讲了Ni辅助的简单使用,这一篇来讲讲Ni的脚本如何编写。这一部分需要有一定的lua语言编程能力,不会lua的需要先学下lua的基础知识。
上一篇讲了Ni的脚本分为两种:职业脚本和通用脚本。他们的区别仅仅是脚本放的位置(目录)不一样,在脚本结构上没有任何区别。
这里我们创建一个通用脚本,在 addon\Rotations\Generic\ 目录下创建一个文件:常用功能.lua
Ni脚本的名字可以用英文,也可以用中文,各有各的好处:
英文:好处是在调试阶段,如果脚本有报错,提示信息里可以明确看出是哪个脚本文件报错的;
中文:好处是在游戏里的Ni配置界面,脚本选择那里看着比较友好,但是如果脚本报错了,提示信息里就是乱码,看不出是哪个脚本报错了;
一个脚本的基本结构如下:
[Lua] 纯文本查看 复制代码
local queue = {
"自动复活",
"自动弹框确认"
};
local function AutoConfirm()
if StaticPopup1Button1:IsVisible() then
StaticPopup1Button1:Click();
end
end
local abilities = {
["自动复活"] = function()
if UnitIsDeadOrGhost("player") then
ni.player.runtext("/o .fh");
return true;
end
end,
["自动弹框确认"] = AutoConfirm,
};
ni.bootstrap.profile("常用功能", queue, abilities);
上面的代码分为三个部分:queue、abilities、ni.bootstrap.profile。
addon\Rotations\下面的脚本在进入游戏后会全部加载,而不是在启动脚本的时候才加载。因此进入游戏后,ni.bootstrap.profile("常用功能", queue, abilities);就会被执行(脚本文件从上到下被执行一遍)。
abilities在定义行为函数的时候,是可以有返回值的(比如上面的"自动复活"的行为函数里在满足条件后会返回true)。这里的返回值含义是:如果某个动作的函数返回了真(比如返回true、1等),那么在这一轮中,该动作后面的其他动作就不会被执行了。
比如上面的自动复活:如果角色死亡了,就尝试执行/o .fh进行复活(sf里一般用这个命令进行复活),同时会返回true,表示后面的自动弹框确认在本轮中就不会被执行了。如果角色没有死亡,在执行自动复活时不会返回true,那么自动弹框确认就会被正常执行。
上面就是一个最简单的脚本模板了。我们继续来加点东西:
[Lua] 纯文本查看 复制代码
local queue = {
"自动复活",
"自动弹框确认"
};
local function AutoConfirm()
if StaticPopup1Button1:IsVisible() then
StaticPopup1Button1:Click();
end
end
local abilities = {
["自动复活"] = function()
if UnitIsDeadOrGhost(p) then
ni.player.runtext("/o .fh");
return true;
end
end,
["自动弹框确认"] = AutoConfirm,
};
local function OnLoad()
ni.vars.debug = true;
print("脚本开始执行");
end
local function OnUnload()
print("脚本停止执行");
end
ni.bootstrap.profile("常用功能", queue, abilities, OnLoad, OnUnload);
上面的代码我们在ni.bootstrap.profile后面增加了两个参数OnLoad和OnUnload。这两个是回调函数,分别是脚本启动的时候执行和脚本停止的时候执行。
通用脚本默认是按F3开始和停止执行脚本,那么第一次按F3,将会先执行OnLoad,然后才会返回执行queue里定义的行为。再次按F3,会执行OnUnload。
ni.vars.debug是一个全局变量,指定脚本是否是以debug模式运行,在调试脚本的时候,开启debug模式可以看到更多的调试信息,方便我们查找问题。
由于ni.vars.debug是一个全局变量,那么只要有一个脚本修改了,其他脚本也会开启或关闭调试。所以有的会把ni.vars.debug放到外外面,而我喜欢放到OnLoad里。
因为如果放到外面,那么最后debug是开启还是关闭的完全不可控,在多个修改了该值的脚本中,由最后加载的那个脚本决定,但是哪个脚本是最后加载的我们决定不了。
OnLoad和OnUnload这两个函数一般是用来在脚本开始时做初始化操作和脚本停止时作一些资源释放操作。比如我们来监控一下战斗日志:
[Lua] 纯文本查看 复制代码
local dialogHasShow = false;
local queue = {
"自动复活",
"自动弹框确认"
};
local function AutoConfirm()
if StaticPopup1Button1:IsVisible() then
StaticPopup1Button1:Click();
end
end
local abilities = {
["自动复活"] = function()
if UnitIsDeadOrGhost(p) then
ni.player.runtext("/o .fh");
return true;
end
end,
["自动弹框确认"] = AutoConfirm,
};
local function CombatEventCatcher(event, ...)
if event == "COMBAT_LOG_EVENT_UNFILTERED" then
local _, subevent, _, _, _, _, destName = select(1, ...);
if subevent == "UNIT_DIED" and destName then
print("【" .. destName .. "】死亡了。");
end
end
end
local function OnLoad()
ni.vars.debug = true;
ni.combatlog.registerhandler("SomeEvent", CombatEventCatcher);
print("脚本开始执行");
end
local function OnUnload()
ni.combatlog.unregisterhandler("SomeEvent");
print("脚本停止执行");
end
ni.bootstrap.profile("常用功能", queue, abilities, OnLoad, OnUnload);
上面我们在OnLoad里注册了一个wow事件处理器,用于处理wow的事件,在OnUnload取消了注册。
"SomeEvent"是事件注册的key,保证唯一就行,其他没有什么要求。
wow是事件驱动的,游戏里发生的各种事情都是以事件的方式进行更新。
上面我们还定义了一个dialogHasShow变量,用来记录实现显示过弹框了,如果没有显示过,当显示弹框就点击确认按钮,如果显示过就不点击。(这里只是为了讲这个变量,具体的弹框处理逻辑不要过多纠结)。
按照上面的写法,会发现弹框会自动点击一次确认,以后的就不会点击了,即便了按F3停止脚本然后再按开启脚本也是没用的。
前面说了由于我们的脚本是一进入游戏就被加载了(而不是按F3的时候才加载),所以我们在函数外定义的文件级别的变量都可以理解成是全局变量。只要游戏不重新加载,那么变量就会一直存在。那么想要每次启动脚本的时候这些变量都恢复成初始值,那么就要在OnLoad里进行初始化了。
Ni辅助的脚本编写入门就讲到这里,下一篇讲讲脚本的UI如何使用。
|
|