BoostFromRelayActionExecutor.kt

package io.github.lishangbu.avalon.game.battle.engine.core.runtime.action

import io.github.lishangbu.avalon.game.battle.engine.core.constant.BattleBoostRelaySelectionValues
import io.github.lishangbu.avalon.game.battle.engine.core.dsl.ActionNode
import io.github.lishangbu.avalon.game.battle.engine.core.dsl.action.BoostFromRelayActionNode
import io.github.lishangbu.avalon.game.battle.engine.core.event.EventContext
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.BoostMutation
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.ActionExecutor
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.ActionResult
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.BattleBoostContextSupport
import io.github.lishangbu.avalon.game.battle.engine.core.type.ActionTypeId
import io.github.lishangbu.avalon.game.battle.engine.core.type.StandardActionTypeIds

/**
 * `boost_from_relay` 动作执行器。
 *
 * 说明:
 * - 只在当前 relay 本身是 boost map 时生效;
 * - 会先按统一规则规范化 boost 负载,再根据 selection 过滤;
 * - 如果过滤后为空,则不生成 mutation,但也不会报错。
 */
class BoostFromRelayActionExecutor : ActionExecutor {
    override val type: ActionTypeId = StandardActionTypeIds.BOOST_FROM_RELAY

    override fun execute(
        action: ActionNode,
        context: EventContext,
    ): ActionResult {
        require(action is BoostFromRelayActionNode) { "Action must be BoostFromRelayActionNode." }
        val normalizedBoosts = BattleBoostContextSupport.normalizeBoostMap(context.relay) ?: return ActionResult()
        val selectedBoosts =
            when (action.selection) {
                BattleBoostRelaySelectionValues.ALL -> normalizedBoosts
                BattleBoostRelaySelectionValues.POSITIVE -> normalizedBoosts.filterValues { delta -> delta > 0 }
                BattleBoostRelaySelectionValues.NEGATIVE -> normalizedBoosts.filterValues { delta -> delta < 0 }
                else -> emptyMap()
            }
        if (selectedBoosts.isEmpty()) {
            return ActionResult()
        }
        return ActionResult(
            mutations = listOf(BoostMutation(action.target, selectedBoosts)),
        )
    }
}