TrinityCore 战斗系统深度解析:从命中暴击、护甲减伤到威胁值的完整链路 原创
战斗系统:MMO 数值规则的最终落地层
一次攻击从玩家按下技能,到目标头顶飘出伤害数字,中间要经过命中判定、护甲减伤、暴击判定、状态修正、威胁值转移等一长串计算。TrinityCore 把这套规则集中在战斗与单位模块里,是所有职业平衡、装备数值与副本难度的最终落点。本文按真实计算顺序拆解这条链路,并指出自定义战斗规则应该挂在哪一层。
总览:一次近战攻击的完整流程
攻击发起
→ 命中判定(未命中 / 闪避 / 招架 / 格挡 / 命中)
→ 暴击判定
→ 基础伤害计算(武器 + 攻击强度)
→ 护甲与抗性减伤
→ 吸收 / 光环 / 状态修正
→ 最终伤害落地,扣血
→ 生成威胁值,更新仇恨表
理解顺序很重要:命中表先决定”打不打得中”,减伤后才谈”打多痛”。把判定顺序写反(比如先算暴击再判定是否命中)是自定义战斗脚本的典型错误,会产生”暴击了却同时未命中”的矛盾结果。
第一层:攻击判定表(Attack Table)
近战白字攻击使用”单次掷骰、按优先级分摊”的攻击表。系统掷一次百分骰,按优先级依次检查各结果,第一个命中区间的结果生效:
| 结果 | 判定含义 | 主要影响因素 |
|---|---|---|
| 未命中 Miss | 攻击者命中等级不足 | 武器技能 vs 防御技能、命中等级 |
| 闪避 Dodge | 目标闪避 | 目标躲闪等级、敏捷 |
| 招架 Parry | 目标招架(正面) | 招架等级 |
| 格挡 Block | 目标格挡,减免部分伤害 | 格挡等级、格挡值 |
| 暴击 / 普通命中 | 剩余区间 | 暴击等级 |
因为是单次掷骰,这些结果互斥:理论上可能出现闪避+暴击,但单次白字攻击里不会同时发生。技能攻击(黄字)通常使用独立的双掷骰:先判命中,命中后再单独判暴击,所以技能可以”命中但不暴击”,也可能被招架。区分白字与黄字是理解战斗日志的前提。
第二层:基础伤害与攻击强度
通过命中判定后才计算伤害。物理伤害的基础来自武器伤害与攻击强度(Attack Power):
武器伤害 = 武器基础伤害(最小~最大,含随机)
攻击强度转化:
标准化武器速度下,AP 按系数换算成伤害加成
技能伤害 = 基础值 + 武器伤害 × 系数 + AP × 系数
瞬发技能采用”标准化武器速度”,避免慢速武器在百分比系数技能里获得不合理的巨大优势;而普通攻击仍使用武器真实速度。这个标准化规则是早期 WoW 数值平衡的关键设计,自定义技能若忽略它,会让慢速武器职业强度崩坏。
第三层:护甲减伤与魔法抗性
物理与魔法走两套减伤体系。物理靠护甲(Armor),魔法靠抗性(Resistance),二者曲线都是”边际递减”。
护甲减伤率:
reduction = Armor / (Armor + K)
// K 是与目标等级相关的常数
// 护甲越高,每点护甲的减伤收益越低,但有效血量近似线性
抗性(二元/部分抵抗):
根据抗性与等级算出平均抵抗比例,
再在 0%/25%/50%/75%/100% 抵抗档位间掷骰
关键认知:护甲不是”超过某值就废”,它对”有效生命值”的贡献近似线性——护甲翻倍,被物理打死所需的原始伤害也近似翻倍。魔法抗性则有随机性,同一发法术可能被抵抗 0% 到 100%。自定义”穿透””忽视护甲”效果,必须作用在这一层、减伤计算之前,放在扣血之后就没有意义。
第四层:修正、吸收与最终落地
减伤之后还有一串修正:伤害/治疗加成光环、百分比增伤减伤、伤害吸收盾、伤害上限(如某些斩杀机制)、免疫与伤害类型转换。最终值才真正扣除目标生命。
final = baseDamage
final = ApplyArmorReduction(final, armor)
final = ApplyAuraMultipliers(final, mods) // 增减伤光环
final = ApplyAbsorbShields(final) // 吸收盾优先吃伤害
DealDamage(target, final, school)
修改最终伤害的脚本应挂在引擎暴露的伤害修改点(如 Unit 的 damage-mod 钩子、AuraScript 的 absorb 钩子),用乘法叠加百分比修正、用加法处理固定值,并注意加法与乘法的结算次序。随意在扣血后直接改血量会绕过吸收、免疫和战斗日志,导致显示与实际不一致。
第五层:威胁值与仇恨表
伤害落地后必须更新仇恨,否则 Tank 拉不住怪。每个处于战斗中的单位都维护一张威胁表(threat list),记录每个敌对目标对它造成的威胁值。
威胁来源:
造成伤害 → 威胁 ≈ 伤害 × 系数
治疗 → 对战斗中所有敌对单位产生分摊威胁
Tank 技能 → 额外威胁倍数(如嘲讽强制复制最高仇恨)
目标选择:
通常攻击威胁表第一名;嘲讽 = 临时把施法者
拉到与最高威胁者持平并固定目标一段时间
嘲讽的实现不是”增加一点威胁”,而是让目标在持续时间内锁定施法者,并把其威胁值抬到当前最高水平。自定义 Tank 技能若只加固定威胁,会在高 DPS 队友面前瞬间 OT。正确做法是复制/超越最高威胁条目。
自定义规则的挂载原则
| 想实现的效果 | 应挂的层级 |
|---|---|
| 提高命中/降低被闪避 | 命中判定表,改等级属性 |
| 忽视护甲 / 法术穿透 | 减伤计算之前 |
| 百分比增减伤 | Aura 修正层(乘法叠加) |
| 伤害吸收盾 | OnEffectAbsorb 钩子 |
| 强制嘲讽 / 复制仇恨 | 威胁表层操作最高条目 |
调试与验证
# GM 与日志手段
.damage 1000 # 对目标造成固定伤害,验证扣血与战斗日志
/combattooltip 相关 # 查看属性换算后的命中/暴击/减伤
开启 World 战斗日志 # 观察每一步:miss/dodge/crit/被抵抗比例
# 平衡性验证:用同一目标重复攻击数百次,
# 统计闪避率、暴击率、平均伤害,与理论概率对照,
# 才能发现判定系数或常数 K 配置错误
小结
TrinityCore 战斗系统是一条严格有序的链路:攻击判定表决定命中结果,武器与攻击强度算出基础伤害,护甲与抗性分别做物理/魔法减伤,光环与吸收完成最终修正,伤害落地后更新威胁表决定目标选择。自定义规则的核心纪律是”挂在正确的计算层、保持正确的结算顺序”。数值平衡可以反复调,但判定顺序一旦错乱,整个战斗系统的可信度就会崩塌。