主题
如何配置战斗管线
管线 = 攻击方式。每个 Pipeline 定义了一种攻击方式下 Stage 的执行顺序。
默认管线
v1.6.0 自带四条管线:
melee -- 近战攻击
yml
id: melee
description: "近战攻击"
stages:
- hit # 命中判定
- dodge # 闪避判定
- crit # 暴击判定
- block # 格挡判定
- collect # 收集伤害通道
- damage # 基础伤害计算
- resist # 按通道减伤
- crit_damage # 暴击伤害修正
- lifesteal # 吸血
- thorns # 反伤ranged -- 远程射击
yml
id: ranged
description: "远程射击"
stages:
- hit
- dodge
- crit
- collect
- damage
- resist
- crit_damage
- lifesteal与 melee 的区别:没有格挡、没有反伤。
spell -- 法术释放
yml
id: spell
description: "法术释放"
stages:
- hit
- dodge
- crit
- collect
- damage
- resist
- crit_damage
- lifesteal
- thorns与 melee 的区别:没有格挡。
dot -- 持续伤害
yml
id: dot
description: "持续伤害"
stages:
- collect
- resist最简管线,只做通道收集和减伤,不做命中/闪避/暴击判定。
如何自定义管线
新建管线
在 pipelines/ 目录下新建一个 yml 文件:
yml
# pipelines/vampiric_strike.yml
id: vampiric_strike
description: "吸血打击"
stages:
- hit
- crit
- collect
- damage
- resist
- crit_damage
- lifesteal这条管线跳过了闪避和格挡,适合"必中但可暴击"的吸血技能。
修改已有管线
直接编辑 pipelines/melee.yml 等文件,调整 stages 列表即可。
例如,给近战管线去掉反伤:
yml
id: melee
description: "近战攻击"
stages:
- hit
- dodge
- crit
- block
- collect
- damage
- resist
- crit_damage
- lifesteal
# thorns 已移除在技能中指定管线
yml
# 使用自定义管线
- hna-damage{a=100;pp=vampiric_strike;dt=physical;st=skill} @target
# 使用默认管线
- hna-damage{a=100;pp=true;dt=physical;st=skill} @targetpp=true 使用默认管线,pp=<管线ID> 使用指定管线。
如何自定义 Stage
Stage 定义在 stages/*.yml 中。每个文件定义一个独立的计算步骤。
新建一个 boolean Stage
yml
# stages/execute_check.yml
id: execute_check
type: boolean
stop_on_false: false
description: "斩杀判定"
formula: |-
def threshold = self_execute_threshold / 100
def target_hp_ratio = target_health / target_max_health
return target_hp_ratio <= threshold ? 1 : 0新建一个 modifier Stage
yml
# stages/execute_bonus.yml
id: execute_bonus
type: modifier
depends_on:
- damage
description: "斩杀增伤"
formula: |-
if (!execute_check) {
return damage
}
return damage * (1 + self_execute_bonus / 100)把新 Stage 加入管线
yml
# pipelines/melee.yml
id: melee
stages:
- hit
- dodge
- crit
- block
- collect
- damage
- resist
- crit_damage
- execute_check # 新增
- execute_bonus # 新增
- lifesteal
- thornsper_channel 变量注入
per_channel 类型的 Stage 会对每个伤害通道分别执行。系统自动注入以下变量:
| 变量 | 含义 | 来源 |
|---|---|---|
channel_type | 通道类型 ID | 如 physical, fire, thunder |
channel_value | 当前通道伤害值 | 来自 channel-role=damage 的属性 |
channel_resist | 当前通道抗性值 | 来自 channel-role=resist 的属性 |
channel_penetration_flat | 固定穿透 | 来自 channel-role=penetration_flat + 通用穿透 |
channel_penetration_rate | 百分比穿透 | 来自 channel-role=penetration_rate + 通用穿透 |
默认的 resist Stage 就是 per_channel 类型:
yml
id: resist
type: per_channel
description: "按通道减伤"
formula: |-
effective_resist = max(0, channel_resist - channel_penetration_flat) * (1 - channel_penetration_rate / 100)
return max(0, channel_value - effective_resist)如果某个 DamageType 配置了 resist-formula,则该通道会优先使用 DamageType 的公式。
公式中可用的变量
攻击者属性
self_<属性ID>-- 如self_attack_damage,self_crit_chance
受击者属性
target_<属性ID>-- 如target_defense,target_dodge
上游 Stage 结果
前面 Stage 的结果可以直接用 Stage ID 引用:
damage-- damage Stage 的结果crit-- crit Stage 的结果(true/false)dodge-- dodge Stage 的结果block-- block Stage 的结果
伤害上下文
input_damage-- 技能/API 传入的显式伤害值explicit_damage-- 是否有显式伤害输入damage_type-- 当前伤害类型 IDsource_type-- 来源类型(basic / skill)
Stage 之间的传值
每个 Stage 执行后,结果会自动进入后续 Stage 的上下文。
例如:
critStage 返回 true/false,后面的crit_damage可以直接读取critdamageStage 返回数值,后面的resist、crit_damage可以直接读取damagemodifier类型的 Stage 会把结果覆盖回depends_on指定的目标
常见错误
错误 1:Stage 顺序不对
collect 必须在 resist 之前,因为 resist 需要知道有哪些通道。damage 必须在 crit_damage 之前,因为 crit_damage 依赖 damage 的结果。
错误 2:modifier 没写 depends_on
modifier 必须声明 depends_on,否则系统不知道要修改哪个结果。
错误 3:新建了 Stage 但没加入管线
Stage 文件只是定义,必须在某个 Pipeline 的 stages 列表中引用才会执行。
错误 4:管线 ID 和文件名不一致
Pipeline 的 id 字段才是真正的标识,技能中用 pp=<id> 引用。
