事件
事件其实是包含“事件”与“触发器”2个部分。你可以在任意对象上以某个事件名注册触发器,当该对象以该事件发起出事件时,便会被触发器接收到。发起事件时可以传入N个自定义参数,这些参数会被触发器接收到。你可以给同一个对象的某个事件名下注册多个触发器,当发起事件时,这些触发器会按照注册顺序反序执行。在这些触发器依次执行的过程中,删除一个还在排队等待执行的触发器,那么它将不会执行;新建该事件名的触发器,那么它本次也不会执行。
-- 发起一个事件,自定义参数为...
base.event_notify(obj, name, ...)
-- 也可以用这个方法来发起事件,区别之后再讲
base.event_dispatch(obj, name, ...)
-- 这个事件会被该触发器接收到
base.event_register(obj, name, function (trigger, ...)
-- 接收到的自定义参数为...
end)
为了方便起见,我们将一些常用对象做了封装
全局事件。
-- 发起
base.game:event_notify(name, ...)
base.game:event_dispatch(name, ...)
-- 接收
base.game:event(name, function (trigger, ...)
end)
玩家事件,玩家事件发起完毕后会使用同样的参数再发起一次全局事件。
-- 发起
player:event_notify(name, ...)
player:event_dispatch(name, ...)
-- 接收
player:event(name, function (trigger, ...)
end)
base.game:event(name, function (trigger, ...)
end)
单位事件,玩家事件发起完毕后会使用同样的参数再发起一次玩家事件和一次全局事件,发起玩家事件时玩家为单位的控制者。
-- 发起
unit:event_notify(name, ...)
unit:event_dispatch(name, ...)
-- 接收
unit:event(name, function (trigger, ...)
end)
unit:get_owner():event(name, function (trigger, ...)
end)
base.game:event(name, function (trigger, ...)
end)
event_notify与event_dispatch的区别在于,event_dispatch
可以获取到触发器的返回值:当接收事件的触发器返回了一个非nil
的值后,当前事件将被终止,并将返回值返回给event_dispatch
的调用方。而event_notify
的事件则无法被终止,也不关心返回值。
base.game:event('加法', function (trigger, a, b)
return a + b
end)
local result = base.game:event_dispatch('加法', 1, 2)
print(result) --> 3
方法
event_register
注册事件
- 参数
- object (table/userdata) - 对象
- name (string) - 事件名
- callback (function) - 回调函数
- 返回
- trigger (trigger) - 触发器对象
- 回调参数
- trigger (trigger) - 触发器对象
- ... (...) - 自定义数据
- 回调返回
- ... (...) - 自定义返回值(只有使用event_dispatch时有意义)
event_dispatch
发起事件(关心返回值)
- 参数
- name (string) - 事件名
- obj (table/userdata) - 对象
- ... (...) - 自定义数据
event_notify
发起事件(不关心返回值)
- 参数
- name (string) - 事件名
- obj (table/userdata) - 对象
- ... (...) - 自定义数据
内置事件
框架内置了许多事件,有些事件是通过event_dispatch发起的,意味着你可以给他设置返回值,这些事件会特别说明。
单位-初始化
- 参数
- unit (unit) - 创建的单位
此时单位还未添加技能,在这个事件中给单位添加技能可以阻止 HeroSkill 与 HideSkill 中的同槽位技能。
注意,此事件触发时该单位刚被创建,他会在当帧的后半阶段被同步给能看见他的玩家(包括自己)的客户端,因此,不要在初始化事件中立即该单位的id同步给客户端(包括使用player:set_hero也是一样效果),或者客户端拿到了不要立即使用(下一帧使用即可)。因为此时客户端还没有 收到该单位出现在视野的协议,立即使用可能会有些问题。
base.game:event('单位-初始化', function (trg, unit)
end)
单位-创建
- 参数
- unit (unit) - 创建的单位
此时技能已经添加完毕,如果是镜像的话单位属性也已经复制完毕。
和
单位-初始化
事件一样,单位本身此时还没有本同步给客户端。因此,不要在客户端立即使用该单位。下一帧再使用是可以的。
base.game:event('单位-创建', function (trg, unit)
end)
单位-即将死亡
- 参数
- damage (damage) - 即将杀死单位的伤害
当单位即将因为受到伤害而死亡时会触发此事件,返回 false
可以阻止单位被杀死。
unit:event('单位-即将死 亡', function (trg, damage)
return false
end)
单位-死亡
- 参数
- dead (unit) - 死者
- killer (unit) - 凶手
此时单位已经死亡。
unit:event('单位-死亡', function (trg, unit, killer)
end)
单位-复活
- 参数
- unit (unit) - 复活的单位
此时单位已经复活。
unit:event('单位-复活', function (trg, unit)
end)
单位- 升级
- 参数
- unit (unit) - 升级的单位
此时单位已经升级。
unit:event('单位-升级', function (trg, unit)
end)
单位-即将获得状态
- 参数
- u (unit) - 获得状态的单位
- buff (buff) - 获得的状态
返回false
可以阻止获得状态。
unit:event('单位-即将获得状态', function (trg, u , buff)
return false
end)
单位-获得状态
- 参数
- u (unit) - 获得状态的单位
- buff (buff) - 获得的状态
此时单位已经获得状态。
unit:event('单位-获得状态', function (trg, u , buff)
end)
单位-购买物品
- 参数
- unit (unit) - 购买物品的单位
- name (string) - 要购买的物品名
这是客户端请求购买物品的事件,由脚本库使用。
unit:event('单位-购买物品', function (trg, unit, name)
end)
单位-出售物品
- 参数
- unit (unit) - 出售物品的单位
- slot (integer) - 物品槽位ID
这是客户端请求出售物品的事件,由脚本库使用。
unit:event('单位-出售物品', function (trg, unit, slot)
end)
单位-撤销物品
- 参数
- unit (unit) - 撤销物品的单位
这是客户端请求撤销物品的事件,由脚本库使用。
unit:event('单位-撤销物品', function (trg, unit)
end)
单位-获得物品
- 参数
- unit (unit) - 获得物品的单位
- item (item) - 获得的物品
unit:event('单位-获得物品', function (trg, unit, item)
end)
单位-失去物品
- 参数
- unit (unit) - 失去物品的单位
- item (item) - 失去的物品
unit:event('单位-失去物品', function (trg, unit, item)
end)
单位-丢弃物品
- 参数
- unit (unit) - 丢弃物品的单位
- slot (integer) - 物品槽位ID
- target (point) - 丢弃位置
这是客户端请求丢弃物品的事件,由脚本库使用。
unit:event('单位-丢弃物品', function (trg, unit, slot, target)
end)
单位-攻击开始
- 参数
- damage (damage) - 此次攻击的伤害
在该事件中设置damage.crit_flag = true
可以令本次攻击使用暴击动画和暴击特效。
unit:event('单位-攻击开始', function (trg, damage)
damage.crit_flag = true
end)
单位-攻击出手
- 参数
- damage (damage) - 此次攻击的伤害
unit:event('单位-攻击出手', function (trg, damage)
end)
单位-请求命令
- 参数
- unit (unit) - 请求命令的单位
- command (string) - 命令,可能的值有:
stop
- 停止walk
- 移动attack
- 攻击walk-attack
- 攻击移动技能名
- 想要使用这个技能
- target (unit/point/nil) - 命令目标,他的类型由命令决定:
stop
- nilwalk
- unit/pointattack
- unitwalk-attack
- point技能名
- 由技能的目标类型决定
- state (integer) - 组合键
只有来自客户端的命令才会触发此事件,返回false
可以阻止命令。如果用户发布命令时按住了Alt
键,则state
为1。
unit:event('单位-请求命令', function (trg, unit, command, target, state)
return false
end)
单位-发布命令
- 参数
- unit (unit) - 发布命令的单位
- command (string) - 命令,可能的值有:
stop
- 停止walk
- 移动attack
- 攻击walk-attack
- 攻击移动技能名
- 想要使用这个技能
- target (unit/point/nil) - 命令目标,他的类型由命令决定:
stop
- nilwalk
- unit/pointattack
- unitwalk-attack
- point技能名
- 由技能的目标类型决定
- state (integer) - 组合键
只有来自客户端的命令才会触发此事件,触发此事件时单位还没有执行此命令。如果用户发布命令时按住了Alt
键,则state
为1。
unit:event('单位-发布命令', function (trg, unit, command, target, state)
end)
单位-执行命令
- 参数
- unit (unit) - 执行命令的单位
- command (string) - 命令,可能的值有:
stop
- 停止walk
- 移动attack
- 攻击walk-attack
- 攻击移动技能名
- 想要使用这个技能
- target (unit/point/nil) - 命令目标,他的类型由命令决定:
stop
- nilwalk
- unit/pointattack
- unitwalk-attack
- point技能名
- 由技能的目标类型决定
- state (integer) - 组合键
只有来自客户端的命令才会触发此事件,触发此事件时单位已经执行此命令。如果用户发布命令时按住了Alt
键,则state
为1。
unit:event('单位-执行命令', function (trg, unit, command, target, state)
end)
单位-移动
- 参数
- unit (unit) - 移动的单位
- last_point (point) - 之前的位置
- next_point (point) - 即将要去 的位置
单位移动时每帧触发一次,因此不要过多的注册此事件。
unit:event('单位-移动', function (trg, unit, last_point, next_point)
end)
单位-着陆
- 参数
- unit (unit) - 着陆的单位
- z_speed (float) - 着陆那一刻z轴的速度,必定是负数
unit:event('单位-着陆', function (trg, unit, z_speed)
end)
单位-撞头
- 参数
- unit (unit) - 撞头的单位(头上有障碍,跳起来的时候撞到了)
- z_speed (float) - 撞头那一刻z轴的速度,必定是正数
unit:event('单位-撞头', function (trg, unit, z_speed)
end)
单位-学习技能
- 参数
- unit (unit) - 学习技能的单位
- skill (skill) - 要学习的技能
单位想要学习技能时触发。脚本库会根据技能是否可以学习、单位是否拥有技能点等规则尝试升级技能并扣除技能点。你可以通过注册这个事件来实现自定义的学习技能规则,返回一个非nil
值来阻止脚本库的默认行为。
unit:event('单位-学习技能', function (trg, unit, skill)
return false
end)
单位-学习技能完成
- 参数
- unit (unit) - 学习技能的单位
- skill (skill) - 学习的技能
当脚本库成功学习一个技能后触发。
unit:event('单位-学习技能完成', function (trg, unit, skill)
end)
单位-即将获得经验
- 参数
- unit (unit) - 单位
- data (data) - 数据
- exp (number) - 经验值
当使用add_exp给单位增加经验时触发,修改exp
可以修改获得的经验。
unit:event('单位-即将获得经验', function (trg, data)
data.exp = data.exp * 2.0
end)
单位-获得经验
- 参数
- unit (unit) - 单位
- data (data) - 数据
- exp (number) - 经验值
当使用add_exp给单位增加经验时触发,此时经验已经增加完毕。
unit:event('单位-获得经验', function (trg, data)
end)
技能-获得
- 参数
- unit (unit) - 获得技能的单位
- skill (skill) - 获得的技能
unit:event('技能-获得', function (trg, unit, skill)
end)
技能-失去
- 参数
- unit (unit) - 失去技能的单位
- skill (skill) - 失去的技能
unit:event('技能-失去', function (trg, unit, skill)
end)
技能-即将施法
- 参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
返回false
可以阻止施法。接着还可以返回一个字符串,这个字符串会显示在客户端上,告诉玩家为何阻止施法。
unit:event('技能-即将施法', function (trg, unit, cast)
return false, '你的爱不够'
end)
技能-即将打断
- 参数
- unit (unit) - 施法单位
- cast (skill) - 当前施法
- new (skill) - 新的施法
只有当处于施法状态时,尝试使用发动另一个技能才会触发此事件。返回false
表示不允许打断。
unit:event('技能-即将打断', function (trg, unit, cast, new)
if new:get_name() ~= '二段施法' then
return false
end
new['一段施法'] = cast
end)
技能-施法开始
- 参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
unit:event('技能-施法开始', function (trg, unit, cast)
end)
技能-施法打断
- 参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
unit:event('技能-施法打断', function (trg, unit, cast)
end)
技能-施法引导
- 参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
unit:event('技能-施法引导', function (trg, unit, cast)
end)
技能-施法出手
- 参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
unit:event('技能-施法出手', function (trg, unit, cast)
end)
技能-施法完成
- 参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
unit:event('技能-施法完成', function (trg, unit, cast)
end)
技能-施法停止
- 参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
unit:event('技能-施法停止', function (trg, unit, cast)
end)
技能-施法失败
-
参数
- unit (unit) - 施法单位
- cast (skill) - 施法对象
- failed_code(number) 施法失败错误码
施法失败的出发时机和失败枚举值, 参见on_cast_failed
unit:event('技能-施法失败', function (trg, unit, cast, failed_code)
end)
技能-冷却完成
- 参数
- unit (unit) - 拥有技能的单位
- skill (skill) - 完成冷却的技能
unit:event('技能-冷却完成', function (trg, unit, skill)
end)