伤害系统
Attribute 的伤害类型位于 damage_types/*.yml。当前伤害系统采用 stages 多阶段管线计算,而不是固定公式。每个伤害类型都可以配置自己的攻击、防御、暴击、穿透和恢复规则。
伤害类型配置
顶层字段
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
id | string | 是 | — | 伤害类型唯一 ID,例如 physical、projectile、spell。 |
display_name | string | 否 | 同 id | 显示名称。 |
aliases | list<string> | 否 | [] | 别名列表,用于兼容旧配置或简写。 |
hard_lock | boolean | 否 | false | 是否强接管该类型伤害。为 true 时,匹配的原版伤害事件会被完全替换为属性伤害计算。 |
allowed_events | list<string> | 否 | [] | 允许触发此伤害类型的事件名白名单。空列表表示不限制。 |
description | string | 否 | "" | 描述文本。 |
message | string | 否 | — | 攻击者和目标共用的战斗消息。可被下面两个字段覆盖。 |
attacker_message | string | 否 | — | 攻击者收到的消息。 |
target_message | string | 否 | — | 目标收到的消息。 |
stages | list | 否 | [] | 伤害计算阶段列表。 |
recovery | object | 否 | — | 战后恢复或吸血计算配置。 |
内置伤害类型
默认生成三个伤害类型文件:
physical.yml— 物理伤害(近战)projectile.yml— 投射物伤害(弓箭、三叉戟)spell.yml— 法术伤害
stages 多阶段管线
伤害计算按 stages 列表顺序执行。每个阶段读取指定属性,按规则计算后叠加到最终伤害值上。
stage 字段
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
id | string | 否 | "stage" | 阶段 ID,用于调试输出。 |
kind | enum | 否 | FLAT_PERCENT | 计算类型。 |
source | enum | 否 | ATTACKER | 属性来源。 |
mode | enum | 否 | ADD | 结果叠加方式。 |
flat_attributes | list<string> | 否 | [] | 参与平坦加成的属性 ID 列表。 |
percent_attributes | list<string> | 否 | [] | 参与百分比加成的属性 ID 列表。 |
chance_attributes | list<string> | 否 | [] | 参与概率触发的属性 ID 列表。 |
multiplier_attributes | list<string> | 否 | [] | 参与乘数的属性 ID 列表。 |
expression | string | 否 | "" | 自定义计算表达式(kind=CUSTOM 时使用)。 |
variables | map | 否 | {} | 本阶段的自定义变量(kind=CUSTOM 时可被 expression 引用)。 |
min_result | double | 否 | — | 阶段结果下限。 |
max_result | double | 否 | — | 阶段结果上限。 |
min_chance | double | 否 | — | 概率下限。 |
max_chance | double | 否 | — | 概率上限。 |
min_multiplier | double | 否 | — | 乘数下限。 |
max_multiplier | double | 否 | — | 乘数上限。 |
kind 计算类型
| 值 | 说明 |
|---|---|
FLAT_PERCENT | 标准模式:先计算 flat 属性总和,再乘以 percent 属性加成,再判断 chance 触发和 multiplier 乘数。 |
CUSTOM | 自定义表达式模式:使用 expression 字段的公式计算。 |
CUSTOM 表达式变量
kind: CUSTOM 时,expression 中可使用下列变量:
| 变量 | 说明 |
|---|---|
%input% / %base% | 进入本阶段时的伤害值。 |
%flat% | flat_attributes 汇总值。 |
%percent% | percent_attributes 汇总值。 |
%chance% | chance_attributes 汇总概率。 |
%multiplier% | multiplier_attributes 汇总倍率。 |
%crit% | 本阶段是否判定暴击,暴击为 1,否则为 0。 |
内置 physical.yml 的用法示例:
- id: crit
kind: CUSTOM
source: ATTACKER
chance_attributes: [physical_crit_rate]
multiplier_attributes: [physical_crit_damage]
expression: "%input% * (1 + (%crit% * (%multiplier% / 100)))"
- id: defense
kind: CUSTOM
source: TARGET
flat_attributes: [physical_defense]
expression: "max(0, %input% - %flat%)"表达式为空或求值失败时回退到默认结果:没有概率属性时保持 %input% 不变,否则按暴击倍率折算。
阶段自定义变量
除内置变量外,每个阶段可以用 variables 声明自己的变量,供本阶段 expression 引用。变量值可以是数值、表达式或随机数值配置:
- id: overflow_soften
kind: CUSTOM
source: ATTACKER
variables:
soft_cap: 120
overflow: "max(0, %input% - %soft_cap%)"
jitter:
min: 0.95
max: 1.05
expression: "(%input% - %overflow% * 0.5) * %jitter%"规则:
- 变量可引用内置变量(如
%input%、%multiplier%)、伤害上下文变量,以及在它之前声明的其他变量。 - 变量按声明顺序解析,因此
overflow能引用先声明的soft_cap。自引用会被拒绝。 - 同名变量覆盖内置变量与上下文变量。
- 变量只对声明它的阶段有效,不会传递给后续阶段。
- 随机数值配置在同一次表达式求值内只掷一次(多处引用取值一致),但每个阶段、每次命中都会重新掷。
- 变量解析失败(例如值是非数值文本,或引用了未声明的变量)会导致整条表达式求值失败,该阶段结果为
0。这是表达式引擎的既有语义,改动variables后建议用/ea trace复核。
source 属性来源
| 值 | 说明 |
|---|---|
ATTACKER | 从攻击方读取属性。 |
TARGET | 从防御方读取属性。 |
CONTEXT | 从上下文读取(用于特殊场景)。 |
mode 叠加方式
| 值 | 说明 |
|---|---|
ADD | 将阶段结果加到当前伤害值上。 |
SUBTRACT | 将阶段结果从当前伤害值中减去。 |
内置物理伤害管线
内置 damage_types/physical.yml 的实际配置:
id: physical
display_name: "物理伤害"
aliases: [physical_damage, phys]
allowed_events:
- ENTITY_ATTACK
- ENTITY_SWEEP_ATTACK
hard_lock: true
stages:
- id: attack
kind: FLAT_PERCENT
source: ATTACKER
mode: ADD
flat_attributes: [physical_attack]
percent_attributes: [physical_damage_bonus]
- id: crit
kind: CUSTOM
source: ATTACKER
chance_attributes: [physical_crit_rate]
multiplier_attributes: [physical_crit_damage]
expression: "%input% * (1 + (%crit% * (%multiplier% / 100)))"
- id: defense
kind: CUSTOM
source: TARGET
flat_attributes: [physical_defense]
expression: "max(0, %input% - %flat%)"
recovery:
source: ATTACKER
resistance_source: TARGET
flat_attributes: [percentage_lifesteal]
percent_attributes: [lifesteal]
resistance_attributes: [lifesteal_resistance]阶段按列表顺序执行,前一阶段的输出作为下一阶段的输入。attacker_message / target_message 填空字符串时不发送对应消息,可减少刷屏。
recovery 恢复配置
恢复配置用于计算攻击后的吸血或回复效果。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
source | enum | ATTACKER | 回复属性来源。 |
resistance_source | enum | TARGET | 抗性属性来源。 |
flat_attributes | list<string> | [] | 平坦回复属性。 |
percent_attributes | list<string> | [] | 百分比回复属性(基于最终伤害的百分比)。 |
resistance_attributes | list<string> | [] | 抗性属性(减少回复效果)。 |
expression | string | "" | 自定义回复表达式。 |
min_result | double | — | 回复结果下限。 |
max_result | double | — | 回复结果上限。 |
原版伤害接管模式
全局 vanilla_event_damage.enabled 是当前原版伤害接管模式开关:
enabled: true:当前推荐的完美接管模式。Attribute 不取消原版伤害事件,而是在事件返回前同步结算 EA 伤害并原地改写最终伤害值。这样能保留原版副作用,例如着火僵尸点燃玩家、铁傀儡击飞、盾牌格挡、吸收之心、荆棘、死亡统计等。盾牌格挡的归属可由shield.mode改为交给 EA 结算,见下文「盾牌格挡」。enabled: false:兼容模式。按旧逻辑取消事件后由 Attribute 重放伤害与反馈,适合需要保留旧行为或与特殊战斗插件联调的服务器。
完美接管模式只改变“伤害如何施加”,不改变当前伤害数值管线。结算结果为闪避、事件取消或最终伤害小于等于 0 时,本次原版事件会被取消。吸血、战斗消息和攻击冷却等 Attribute 自身副作用仍由 Attribute 补发。
盾牌格挡
原版盾牌走 EntityDamageEvent.DamageModifier.BLOCKING,它独立于 EA 的伤害管线。全局 shield.mode 决定格挡由谁结算。
shield:
mode: vanilla
require_facing: true
facing_angle_degrees: 180| 字段 | 默认值 | 说明 |
|---|---|---|
mode | vanilla | vanilla 保留原版 BLOCKING;attribute 清零它并改由伤害阶段结算。 |
require_facing | true | 仅 attribute 模式生效,是否要求来源位于正面。 |
facing_angle_degrees | 180 | 正面判定张角。180 等价于原版的半平面判定。 |
两种模式的区别
mode: vanilla(默认,保持既有行为):举盾时原版 BLOCKING 把 EA 算出的伤害整体抹掉,因此 EA 的攻击、暴击、穿透在举盾时全部不生效。该模式下上下文变量 target_blocking 恒为 0,伤害类型里的 block 阶段等价于不改变伤害。
mode: attribute:EA 清零原版 BLOCKING,改由 block 阶段读取目标的 block_rate 与 block_reduction 结算,可做成百分比减伤。默认基线是 block_rate: 100 / block_reduction: 100,等价于原版全免,所以仅切换模式不会改变手感;把 block_reduction 调低即得到百分比格挡。
相关属性
两个属性都是普通 EA 属性,因此盾牌可以通过 Lore 词条或 PDC 提供数值,Gem、Strengthen、Forge、套装也能照常加成。
| 属性 ID | 含义 |
|---|---|
block_rate | 举盾时格挡的触发概率。为 0 时格挡永不触发。 |
block_reduction | 格挡触发后削减的伤害百分比。100 等价于原版全免。 |
数值基线写在 config.yml 的 default_profile.attributes,物品数值在基线之上叠加,总值受属性自身 max_value 截断。
block 阶段
内置 physical.yml 与 projectile.yml(原版盾牌同样能挡投射物)都带有该阶段;spell.yml 没有,因为原版盾牌不挡法术。
- id: block
kind: CUSTOM
source: TARGET
chance_attributes: [block_rate]
multiplier_attributes: [block_reduction]
expression: "%input% * (1 - (%target_blocking% * %crit% * (%multiplier% / 100)))"
min_result: 0%target_blocking% 是本次受击是否构成有效举盾(含正面判定),取 1 或 0。%crit% 在此表示 block_rate 概率是否命中。
注意事项
- 自定义
block阶段时chance_attributes必须保留block_rate且基线非零,否则%crit%恒为0,举盾将完全不减伤。 %target_blocking%在所有伤害阶段表达式中始终可用;不带目标实体的伤害请求会回落到0。- 环境伤害没有来源方向,
require_facing: true时不构成正面格挡。 - 格挡与暴击共用同一次随机骰值,这是 stages 管线的既有语义。
合成命中反馈
合成命中反馈主要服务于兼容模式;在完美接管模式下,原版通常会自然产生击退、受伤动画和音效。synthetic_hit_feedback 用于在需要时补发击退和受伤音效,让战斗反馈更接近原版体验。
synthetic_hit_feedback:
knockback: true
knockback_strength: 0.4
hurt_sound: true| 字段 | 说明 |
|---|---|
knockback | 是否补发击退。 |
knockback_strength | 击退强度。数值越高,目标位移越明显。 |
hurt_sound | 是否播放受伤音效。 |
调参建议:
- 如果服务器有自定义击退插件,先关闭
knockback测试兼容性。 - 如果战斗节奏偏快,过强的击退会影响近战连段,可降低
knockback_strength。 - 如果战斗消息、粒子和音效较多,可以关闭
hurt_sound降低反馈噪音。
hard_lock 与 allowed_events
hard_lock
hard_lock: true 表示该伤害类型会完全接管匹配的原版伤害事件。原版伤害值会被忽略,改为使用属性系统计算。
全局配置 config.yml 中的 hard_lock_damage 会影响未命中任何伤害类型白名单的原版伤害。配置时要谨慎:
- 设为
true:所有伤害都走属性系统,包括火焰、摔落、药水等。 - 设为
false:只有明确配置的伤害类型才走属性系统。
allowed_events
限制哪些原版伤害事件可以触发此伤害类型。空列表表示不限制。常见事件:
ENTITY_ATTACK— 近战攻击PROJECTILE— 投射物ENTITY_SWEEP_ATTACK— 横扫攻击