外观
攻击与伤害触发
一次玩家出手和一次目标受伤是两件事。挥空的攻击仍可能有动作后置;一次范围攻击可以只有一个动作后置,却有多笔伤害。两个事件分别在 M2 的“新触发”页启用。
玩家攻击与技能使用
OnBeforePlayerAction 在玩家实际出手及本次动作代价发生前运行,可以取消;OnAfterPlayerAction 在出手成立后运行。覆盖普通攻击、实际挥出的物理攻击技能,以及主动施放的技能。开启技能模式或准备一次后续挥击不算出手。怪物、英雄和召唤物自己的出手不使用这组回调。
前置参数类型为 TBeforePlayerActionContext,后置为 TAfterPlayerActionContext:
| 字段 | 类型 | 含义 |
|---|---|---|
Player | TPlayer | 出手玩家 |
SkillId | Integer | 实际动作的技能编号;0 为普通攻击,也用于按原生规则退回的普通挥击 |
Direction | Integer | 本次动作方向 |
X、Y | Integer | 本次动作对应的坐标;可为点击位置或目标位置,不是命中结果 |
前置另有 Cancelled: Boolean 和无参 Cancel。原生条件已拒绝、缺蓝、缺材料、技能尚未实际执行等请求不会得到成功后置;前置返回后引擎会复查玩家、目标和消耗条件。一个多目标技能仍只对应一次动作事件。
pascal
procedure OnBeforePlayerAction(Context: TBeforePlayerActionContext);
begin
if Context = nil then Exit;
if Context.SkillId = 0 then
Context.Player.PlayerNotice('普通攻击准备出手', 2);
// 要阻止本次出手时调用 Cancel,随后 Exit;提示消息由脚本自行发送。
end;
procedure OnAfterPlayerAction(Context: TAfterPlayerActionContext);
begin
if Context = nil then Exit;
// 本次出手已成立,不能据此推断命中数或造成的伤害。
end;物理攻击可能先同步结算伤害,再调用动作后置;飞行或延迟技能的伤害又可能晚于动作后置。需要按实际扣血做玩法时,请使用下面的伤害事件。
玩家参与的伤害结算
OnBeforeDamage 在最终待生效伤害已经算出、实际扣血之前运行;OnAfterDamage 报告这笔已提交的实际生命损失。前置可以调用 SetAmount(Amount: Int64) 替换最终伤害值,或调用无参 Cancel 阻止本笔伤害。修改后的数值不会再经过一轮防御、暴击计算。
前置参数类型为 TBeforeDamageContext,后置为 TAfterDamageContext:
| 字段 | 类型 | 含义 |
|---|---|---|
Player | TPlayer | 这笔伤害的玩家主体 |
OtherName | String | 另一参与者的名称 |
Amount | Int64 | 前置为待扣血值,后置为实际生命损失 |
SkillId | Integer | 关联技能编号;没有技能时为 0 |
Dealt | Boolean | True 表示主体造成伤害,False 表示主体受到伤害 |
前置另有 Cancelled: Boolean、SetAmount 和 Cancel;后置只读。玩家打怪、怪物打玩家以及玩家之间的伤害可进入此事件;怪物打怪不进入。玩家对玩家的一笔伤害只通知一次,以攻击玩家为主体。
pascal
procedure OnBeforeDamage(Context: TBeforeDamageContext);
begin
if Context = nil then Exit;
if Context.Amount > 100 then
Context.SetAmount(100);
end;
procedure OnAfterDamage(Context: TAfterDamageContext);
begin
if Context = nil then Exit;
Context.Player.PlayerNotice(
'本次实际伤害:' + IntToStr(Context.Amount), 2);
end;被取消或回调后参与对象失效的伤害没有后置。伤害前置内部再次造成的伤害不会递归进入同一前置。当前事件围绕战斗伤害结算;治疗、技能自身扣血代价和部分直接改血路径不应假定会产生该事件。