BattleMoveResolutionContext.kt
package io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow
import io.github.lishangbu.avalon.game.battle.engine.core.dsl.EffectDefinition
/**
* 单次出招主流程在 pipeline 中共享的可变上下文。
*
* 设计意图:
* - 把 move resolution 的中间状态从 `DefaultBattleFlowEngine` 主体中抽离出来。
* - 让各个 phase step 只修改自己关注的字段,而不需要关心最终结果对象如何组装。
*
* @property moveEffect 当前正在结算的 effect 定义。
* @property attackerId 出手单位标识。
* @property targetId 当前目标单位标识。
* @property sourceId 本次结算的来源单位标识。
* @property attributes 透传给 hook phase 的附加属性。
* @property snapshot 当前阶段持有的最新 battle 快照。
* @property accuracy 当前阶段持有的命中值。
* @property evasion 当前阶段持有的回避值。
* @property basePower 当前阶段持有的威力值。
* @property damage 当前阶段持有的伤害值。
* @property forcedHitSuccessful 当前阶段是否已经被特殊规则显式判定为必中/必不中。
* @property skipAccuracyEvasionModifiers 当前阶段是否应跳过常规 accuracy/evasion 修正链。
* @property hitSuccessful 本次出招是否成功命中。
* @property criticalHit 本次出招是否击中要害。
* @property cancelled 本次出招是否已经在前置阶段被取消。
*/
class BattleMoveResolutionContext(
snapshot: BattleRuntimeSnapshot,
val moveEffect: EffectDefinition,
val attackerId: String,
val targetId: String,
val sourceId: String,
val attributes: Map<String, Any?>,
accuracy: Int?,
evasion: Int?,
basePower: Int,
damage: Int,
) {
/**
* 当前阶段持有的最新 battle 快照。
*/
var snapshot: BattleRuntimeSnapshot = snapshot
/**
* 当前阶段持有的命中值。
*/
var accuracy: Int? = accuracy
/**
* 当前阶段持有的回避值。
*/
var evasion: Int? = evasion
/**
* 当前阶段持有的威力值。
*/
var basePower: Int = basePower
/**
* 当前阶段持有的伤害值。
*/
var damage: Int = damage
/**
* 当前阶段是否已经被特殊规则显式判定为必中/必不中。
*
* 说明:
* - `null` 表示继续走标准命中策略;
* - 非空时表示命中结果已经由更高优先级规则收口。
*/
var forcedHitSuccessful: Boolean? = null
/**
* 当前阶段是否应跳过常规 accuracy/evasion 修正链。
*
* 设计意图:
* - 让 OHKO 这类已经在特殊规则阶段完成 accuracy 公式裁决的规则,
* 不再错误叠加普通命中/闪避 stage、特性或道具修正;
* - 与 `forcedHitSuccessful` 分离,避免“仍需进入标准命中策略掷骰,
* 但不应再改写 accuracy/evasion”的场景被迫伪装成显式命中或显式 miss。
*/
var skipAccuracyEvasionModifiers: Boolean = false
/**
* 本次出招是否成功命中。
*/
var hitSuccessful: Boolean = false
/**
* 本次出招是否击中要害。
*/
var criticalHit: Boolean = false
/**
* 本次伤害浮动使用的随机倍率。
*/
var damageRoll: Int? = null
/**
* 本次出招是否已经在前置阶段被取消。
*/
var cancelled: Boolean = false
/**
* 把当前上下文标记为已取消。
*
* @param nextSnapshot 取消时需要保留的最新快照。
*/
fun markCancelled(nextSnapshot: BattleRuntimeSnapshot) {
snapshot = nextSnapshot
cancelled = true
}
/**
* 把当前上下文收敛为最终的 move resolution 结果。
*
* @return 面向调用方的最终结算结果对象。
*/
fun toResult(): MoveResolutionResult =
MoveResolutionResult(
snapshot = snapshot,
cancelled = cancelled,
hitSuccessful = hitSuccessful,
criticalHit = criticalHit,
accuracy = accuracy,
evasion = evasion,
basePower = basePower,
damageRoll = damageRoll,
damage = damage,
)
}