LUACN论坛

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
热搜: YJWOW MagicStone BoL
查看: 1931|回复: 14

[综合] 魔兽世界事件教程

[复制链接]
发表于 2022-8-15 10:53:52 | 显示全部楼层 |阅读模式
本帖最后由 blxyz521 于 2022-8-15 01:36 PM 编辑

1、首先要知道什么是事件,官方对事件的解释翻译过来是“事件是《魔兽世界》客户端发送给UI代码的消息(通过OnEvent脚本处理器),主要是对游戏世界中发生的事情的反应。”看到这个解释可能大部分人都一头雾水,这不重要,看完后面的内容应该就能明白了。

2、其次事件能做什么?它可以对游戏世界中发生的事情做出反应。比如常用的喊话自动组队,别人在指定频道说指定的话,就会自动组他。别人在指定频道说话就是游戏世界中发生的事情(也就是事件),自动组他就是对这个事件做出的反应。通过事件可以对游戏中发生的基本上所有事情都可以做出自动反应,这才是我们想要的功能。

3、实例分析:工会喊话自动组队宏,按一下宏,开启自动组队,工会喊话“工会打111进组”,如果别人在工会频道说111就会自动组他。在按一下宏,关闭自动组队。

/runK,F="111",ForCreateFrame("Frame")F:RegisterEvent("CHAT_MSG_GUILD")ifIthen print("已关闭") I=nil else print("已开启,KeyWord="..K)SendChatMessage("工会打111进组","guild")I=function(_,_,m,s)ifm==Kthen InviteUnit(s)end end end F:SetScript("OnEvent",I)

上面是宏的写法,按照lua语言的格式重新排列一下

K,F="111",F orCreateFrame("Frame")--第一句改写成下面两句
K="111"
F=F or CreateFrame("Frame")
F:RegisterEvent("CHAT_MSG_GUILD")
F:SetScript("OnEvent",I)
if I then
   print("自动组队已关闭")
   I=nil
else
   print("自动组队已开启,关键字:"..K)
   SendChatMessage("工会打111进组","guild")
   I=function(_,_,m,s)
       if m==K then
           InviteUnit(s)
       end
    end
end

下面对每一句进行解释,首先是注册事件(蓝色部分)。

F=F or CreateFrame("Frame")--F如果有值就不变,如果为空就创建一个新框架(实际就是一个表),因为这个框架只是用来注册事件的,所以不需要其他参数,详见https://wowpedia.fandom.com/wiki/API_CreateFrame
F:RegisterEvent("CHAT_MSG_GUILD")--调用RegisterEvent函数,给F注册一个工会聊天消息事件(只要有人在工会频道说话就会触发)。
F:SetScript("OnEvent",I)--F设置一个脚本,每当事件被触发时就调用函数I(见红色部分)。

先不管紫色部分,看函数I,工会聊天事件只要有人在工会频道说话就会触发,我们就需要判断别人说的话是不是我们设定的关键字"111",并且需要获取说话人的姓名以便组队。这是需要给函数I传递参数。

I=function(_,_,m,s) --函数I第一个参数为F本身,第二个参数为被触发的事件,这两个参数是固定的,这里用不上,因此可以写成_,_,。后面的参数为该事件的参数,根据事件的不同,参数数量也不同,我们到https://wowpedia.fandom.com/wiki/Events上面查找CHAT_MSG_GUILD事件,发现它有17个参数(如下图),我们只需要用到第一个参数text说话的内容(设置成m传递进去),第二个参数playername(设置成s传递进去)说话人的姓名。
   if m==K then--判断说话的内容是否等于关键字
      InviteUnit(s)--组说话人
   end
end

再来看紫色色部分,用来开启关闭自动组队,附带打印出提示。

if I then--判断I是否为空
   print("自动组队已关闭")--提示
   I=nil--给函数I赋值为空,这样每次触发CHAT_MSG_GUILD事件也什么都不执行,达到关闭自动组队功能。
else
   print("自动组队已开启,关键字:"..K) --提示
   SendChatMessage("工会打111进组","guild")--工会说话"工会打111进组"
   -- 函数I
end

4、学习写自己想要的脚本。比如我们玩刷新服,想要拾取战利品后自动刷新,如果用连点器点刷新命令,经常打死怪还没拾取就点了刷新。如果用事件来做这个脚本的话,就不会存在这些问题,而且高效,基本无延迟。

首先要想象一下拾取战利品会触发什么事件,肯定会触发拾取事件,还有系统拾取信息事件,当不知道事件的名称,我们可以在https://wowpedia.fandom.com/wiki/Events上面查找与LOOT有关的事件,挑选看似可能的查看详细解释, 例如LOOT_READY发生在loot之前、LOOT_OPENED打开战利品、LOOT_CLOSED关闭战利品,和系统拾取信息事件CHAT_MSG_LOOT拾取每个战利品的系统信息。看一下触发的顺序就确定了要用LOOT_CLOSED事件才能保证所有的战利品都拾取,如果使用了快速拾取插件的话也可以使用其他事件,我以前用CHAT_MSG_LOOT也可以正常使用,但是会连续多次刷新。这里用LOOT_CLOSED事件来演示。

F=F or CreateFrame("Frame")
F:RegisterEvent("LOOT_CLOSED")
F:SetScript("OnEvent",I)
if I then
   print("自动刷新已关闭")
   I=nil
else
   print("自动刷新已开启)
   SendChatMessage(".respawn")
   I=function()—这里不需要任何参数
       SendChatMessage(".respawn")--这里是刷新命令
   end
end

上面的脚本可以用魔蜂来运行,也可以改成宏的写法(前面加上/run,删除所有的换行)
就是这么简单,这样只要我们拾取战利品完毕,就会自动刷新。

注意修改全局变量名F,I,以防与其他脚本冲突。

5、一个框架F可以注册多个事件,例如:

F=F or CreateFrame("Frame")
F:RegisterEvent("LOOT_CLOSED")--注册战利品关闭事件
F:RegisterEvent("LOOT_OPENED")--注册战利品打开事件
F:SetScript("OnEvent",I)
函数I就需要传递第二个参数判断触发的是什么事件。
    I=function(_,e)--这里需要传递参数Event事件。
       if e=="LOOT_CLOSED" then--判断触发的事件
           SendChatMessage(".respawn")--这里是刷新命令
        elseif e=="LOOT_OPENED" then
            print("拾取中")
        end
    end

6、还有一个常用的连点宏也可以按事件来理解,下面为了便于理解删除了时间。

F= F or CreateFrame("frame")
F:SetScript("OnUpdate",I)--这里不是用"OnEvent"触发事件,而是用"OnUpdate"帧刷新,这样每一帧都会调用一次函数I,实现连点。
if Ithen
    I=nil
    print("提示:连点开始")
else
    print("提示:连点关闭")
    I=function()
        ActionButton1:Click()
    end
end

回复

使用道具 举报

发表于 2022-8-15 11:07:21 | 显示全部楼层
支持,好帖子!希望再举点WA的例子,比如怎么判断目标受到什么技能伤害之类的
回复 支持 反对

使用道具 举报

发表于 2022-8-15 11:43:15 | 显示全部楼层
启发挺多的,感谢大佬。之前只会看api写简单语句
回复 支持 反对

使用道具 举报

发表于 2022-8-15 16:10:24 | 显示全部楼层
感谢分享,涨知识了
之前对事件的用法与应用场景只停留在技能监控上
没想到还有更广泛的应用场景
回复 支持 反对

使用道具 举报

发表于 2022-8-15 16:29:10 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

发表于 2022-8-29 23:59:23 | 显示全部楼层
好高端。。。吾辈学渣表示看不懂。。
回复 支持 反对

使用道具 举报

发表于 2022-11-28 16:59:10 | 显示全部楼层
说实话,看懂楼主说的内容还是要有一定的lua或者其他编程语言基础的,像我看完后还是一头雾水
回复 支持 反对

使用道具 举报

发表于 2023-2-2 11:08:26 | 显示全部楼层
大佬,想问下,就是在魔蜂单独建立个脚本,输入下面的代码后再启动,就能拾取后刷新了吗?
F=F or CreateFrame("Frame")
F:RegisterEvent("LOOT_CLOSED")
F:SetScript("OnEvent",I)
if I then
   print("自动刷新已关闭")
   I=nil
else
   print("自动刷新已开启)
   SendChatMessage(".respawn")
   I=function()—这里不需要任何参数
       SendChatMessage(".respawn")--这里是刷新命令
   end
end
回复 支持 反对

使用道具 举报

发表于 2023-2-15 10:58:37 来自手机 | 显示全部楼层
vshrd 发表于 2022-8-15 04:10 PM
感谢分享,涨知识了
之前对事件的用法与应用场景只停留在技能监控上
没想到还有更广泛的应用场景

技能错误提示的事件 怎么写 大佬
回复 支持 反对

使用道具 举报

发表于 2023-2-15 12:18:04 | 显示全部楼层
一壶漂泊 发表于 2023-2-15 10:58 AM
技能错误提示的事件 怎么写 大佬

战斗记录里
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

小黑屋|手机版|Archiver|LUACN论坛

GMT+8, 2024-5-2 07:22 PM , Processed in 0.064826 second(s), 31 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表