ApplyConditionActionExecutor.kt

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

import io.github.lishangbu.avalon.game.battle.engine.core.dsl.ActionNode
import io.github.lishangbu.avalon.game.battle.engine.core.dsl.action.ApplyConditionActionNode
import io.github.lishangbu.avalon.game.battle.engine.core.event.EventContext
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ApplyConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ApplyFieldConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ApplySideConditionMutation
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.type.ActionTypeId
import io.github.lishangbu.avalon.game.battle.engine.core.type.StandardActionTypeIds
import io.github.lishangbu.avalon.game.battle.engine.core.type.StandardTargetSelectorIds

/**
 * `apply_condition` 动作执行器。
 */
class ApplyConditionActionExecutor : ActionExecutor {
    override val type: ActionTypeId = StandardActionTypeIds.APPLY_CONDITION

    override fun execute(
        action: ActionNode,
        context: EventContext,
    ): ActionResult {
        require(action is ApplyConditionActionNode) { "Action must be ApplyConditionActionNode." }
        val resolvedDuration =
            AttachedEffectDurationResolver.resolve(
                explicitDuration = action.duration,
                effectId = action.value,
                context = context,
            )
        return ActionResult(
            mutations =
                listOf(
                    when (action.target) {
                        StandardTargetSelectorIds.SIDE,
                        StandardTargetSelectorIds.FOE_SIDE,
                        -> {
                            ApplySideConditionMutation(
                                target = action.target,
                                conditionEffectId = action.value,
                                duration = resolvedDuration,
                                sourceId = context.source?.id ?: context.self?.id,
                            )
                        }

                        StandardTargetSelectorIds.FIELD -> {
                            ApplyFieldConditionMutation(
                                conditionEffectId = action.value,
                                duration = resolvedDuration,
                                sourceId = context.source?.id ?: context.self?.id,
                            )
                        }

                        else -> {
                            ApplyConditionMutation(
                                target = action.target,
                                conditionEffectId = action.value,
                                duration = resolvedDuration,
                                sourceId = context.source?.id ?: context.self?.id,
                            )
                        }
                    },
                ),
        )
    }
}