伤害结算前的窗口是战斗的收口裁决点:吸血的回血、反伤的弹回、减伤的触发全在攻击前的那一瞬。attackdamage 触发在人物攻击前的节点,战斗的衍生机制都挂在这个钩子上。
---attackdamage: 人物攻击前触发
function attackdamage(self, Target, Hiter, MagicId)
local player = class(self)
if not player then return end
-- 吸血属性:伤害的 8% 转化为生命
local lifesteal = tonumber(getplayvar(self, 2, "Lifesteal")) or 0
if lifesteal > 0 and Target then
local heal = math.floor(MagicId * 0 + lifesteal)
humanhp(self, "+", heal)
sendmsg(self, 1, "吸血回复 " .. heal .. " 点")
end
end
攻击前触发的时机是衍生机制的天堂:吸血按攻击者的属性折算回血、反伤把即将受到的伤害记账、破防标记在结算前打上。吸血的来源是装备的词条与内功的加成,属性的叠加走统一的面板聚合——吸血的总量有上限(每次不超过最大生命的 2%),生存的滚雪球被上限按住。
---反伤:受击方的回弹标记
function Damage.thorns(actor, attacker, dmg)
local player = class(actor)
if not player then return end
local thorns = tonumber(getplayvar(actor, 2, "Thorns")) or 0
if thorns <= 0 or not attacker then return end
-- 反伤为受到伤害的 15%,不超过 200 点
local back = math.min(math.floor(dmg * 0.15), 200)
setplayvar(attacker, 2, "PendingThorns", back, 0)
sendmsg(actor, 1, "反伤预备 " .. back .. " 点")
end
反伤的实现借攻击前的窗口记账:受击方的反伤属性把回弹的伤害记到攻击者的待结算槽,攻击结算时一并处理——反伤不触发反伤的递归(回弹的伤不进 attackdamage),循环的地狱在规则里被明确禁止。攻击前的修正与攻击后的统计是两条链:修正管这次伤害的形态,统计管战斗的总账(伤害统计、连击计数),两条链在同一触发的不同分支里各走各路。战报的完整性靠前置钩子喂料:每一次修正(吸血多少、反伤多少)都进战斗日志,复盘的颗粒度到每一次挥刀。
吸血与反伤的触发流水抽样核对,属性面板与实际结算的偏差不超 1%;反伤的递归保护测试,构造互反的双方验证不进入死循环。
吸血曾经按攻击力而非最终伤害计算,堆攻击的收益双重放大,口径统一为最终伤害。反伤的回弹曾经触发受击方的反伤,两块反弹的镜子互相弹到天荒地老,递归的禁止条款写进文档。触发的执行曾经阻塞了伤害结算,钩子里的慢查询让全场攻击卡顿,钩子内禁 IO 的纪律立下。
吸血与反伤的上限、比例进技能与装备表,数值的调整不改代码。触发的钩子保持轻量:禁数据库、禁广播风暴,衍生的通知走异步队列。战斗的统计与修正分链,统计的账不受修正的影响。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 明拍容易被大号威慑,普通玩家不敢出手。秘宝暗拍改为全服暗标:每周一件秘宝,玩家密价投标一次,截标前互相看…
实战应用:用在哪里 充值返利活动被风控规则误判成套利,480 个大额充值账号被批量封禁 24 小时,申诉两小时破千条。误封风…
实战应用:用在哪里 五人小队打沃玛教主,队友的血量状态只能靠点头像逐个看,集火转火慢半拍。小队血条在屏幕侧边紧凑排布四条队友…
实战应用:用在哪里 好友申请藏在好友面板的角标里,玩家半天不看一眼,申请积压让社交转化掉了一半。好友申请浮窗把新申请推到屏幕…
实战应用:用在哪里 矿洞产出人人有份等于人人不重视,矿位租赁把矿洞变成可经营资产:矿位按 24 小时租给个人或行会,产出归租…
实战应用:用在哪里 击杀 BOSS 后要同时做三件事:发奖励、记流水、刷新排行榜,全都写在 killmon 触发里互相拖累,…