BattleSessionChoiceActionMapper.kt

package io.github.lishangbu.avalon.game.battle.engine.core.session

/**
 * battle session choice 到 action 的映射器。
 *
 * 设计意图:
 * - 收敛 `BattleSessionChoice` 到具体 `BattleSessionAction` 的分派逻辑;
 * - 让默认命令工厂只负责对外暴露接口,不再自己持有大段 `when(choice)`;
 * - 让 choice/action 两类子工厂可以被显式复用。
 */
internal class BattleSessionChoiceActionMapper(
    private val actionFactory: BattleSessionActionFactory,
) {
    fun createAction(choice: BattleSessionChoice): BattleSessionAction =
        when (choice) {
            is MoveChoice -> {
                actionFactory.createMoveAction(
                    moveId = choice.moveId,
                    attackerId = choice.attackerId,
                    targetId = choice.targetId,
                    priority = choice.priority,
                    speed = choice.speed,
                    accuracy = choice.accuracy,
                    evasion = choice.evasion,
                    basePower = choice.basePower,
                    damage = choice.damage,
                    attributes = choice.attributes,
                )
            }

            is ItemChoice -> {
                actionFactory.createItemAction(
                    itemId = choice.itemId,
                    actorUnitId = choice.actorUnitId,
                    targetId = choice.targetId,
                    priority = choice.priority,
                    speed = choice.speed,
                    attributes = choice.attributes,
                )
            }

            is CaptureChoice -> {
                actionFactory.createCaptureAction(
                    playerId = choice.playerId,
                    ballItemId = choice.ballItemId,
                    sourceUnitId = choice.sourceUnitId,
                    targetId = choice.targetId,
                    priority = choice.priority,
                    speed = choice.speed,
                )
            }

            is SwitchChoice -> {
                actionFactory.createSwitchAction(
                    sideId = choice.sideId,
                    outgoingUnitId = choice.outgoingUnitId,
                    incomingUnitId = choice.incomingUnitId,
                    priority = choice.priority,
                    speed = choice.speed,
                )
            }

            is RunChoice -> {
                actionFactory.createRunAction(
                    sideId = choice.sideId,
                    priority = choice.priority,
                    speed = choice.speed,
                )
            }

            is WaitChoice -> {
                actionFactory.createWaitAction(
                    unitId = choice.unitId,
                    priority = choice.priority,
                    speed = choice.speed,
                )
            }

            else -> {
                error("Unsupported BattleSessionChoice type '${choice::class.qualifiedName}'.")
            }
        }
}