ClearBoostsBattleMutationInterceptor.kt
package io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow
import io.github.lishangbu.avalon.game.battle.engine.core.event.StandardHookNames
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.BattleMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ClearBoostsMutation
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.BattleBoostContextSupport
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.BattleStatStageSupport
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.MutationTargetSelectorResolver
/**
* boost 清空 mutation 的生命周期拦截器。
*
* 设计意图:
* - 在 `ClearBoostsMutation` 真正清空前派发 `on_clear_boosts`;
* - 让目标可以拒绝被清能力阶级;
* - 把清空前的 boosts 快照通过 attributes 透传给 hook,便于规则做精确判断。
*/
class ClearBoostsBattleMutationInterceptor : BattleMutationInterceptor {
override val order: Int = 450
override fun supports(mutation: BattleMutation): Boolean = mutation is ClearBoostsMutation
override fun intercept(
context: BattleMutationInterceptionContext,
attachedEffectProcessor: BattleAttachedEffectProcessor,
): BattleMutationInterceptionResult {
val mutation =
context.mutation as? ClearBoostsMutation
?: return BattleMutationInterceptionResult(context.snapshot, true, context.mutation)
val targetUnitIds =
MutationTargetSelectorResolver.resolve(
mutation.target,
BattleMutationInterceptorSupport.mutationApplicationContext(context),
)
var currentSnapshot = context.snapshot
var blocked = false
targetUnitIds.forEach { affectedTargetId ->
val affectedUnit = currentSnapshot.units[affectedTargetId] ?: return@forEach
val currentBoosts = BattleStatStageSupport.normalizeStoredBoosts(affectedUnit.boosts)
val boostChanged = currentBoosts.isNotEmpty()
val result =
attachedEffectProcessor.process(
snapshot = currentSnapshot,
unitId = affectedTargetId,
hookName = StandardHookNames.ON_CLEAR_BOOSTS.value,
targetId = affectedTargetId,
sourceId = context.sourceId,
relay = true,
attributes =
BattleBoostContextSupport.createOnClearBoostsAttributes(
currentBoosts = currentBoosts,
targetRelation =
BattleMutationInterceptorSupport.resolveTargetRelation(
currentSnapshot,
context.sourceId,
affectedTargetId,
),
),
)
currentSnapshot = result.snapshot
if (boostChanged && (result.cancelled || result.relay == false)) {
blocked = true
}
}
return BattleMutationInterceptionResult(
snapshot = currentSnapshot,
allowed = !blocked,
mutation = mutation,
)
}
}