Skip to content

如何配置战斗管线

管线 = 攻击方式。每个 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} @target

pp=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
  - thorns

per_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 -- 当前伤害类型 ID
  • source_type -- 来源类型(basic / skill)

Stage 之间的传值

每个 Stage 执行后,结果会自动进入后续 Stage 的上下文。

例如:

  • crit Stage 返回 true/false,后面的 crit_damage 可以直接读取 crit
  • damage Stage 返回数值,后面的 resistcrit_damage 可以直接读取 damage
  • modifier 类型的 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> 引用。

HN 系列插件文档