DefaultBattleSessionMoveChoiceSpecification.kt

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

import io.github.lishangbu.avalon.game.battle.engine.core.session.BattleSession
import io.github.lishangbu.avalon.game.battle.engine.spi.effect.EffectDefinitionRepository

/**
 * 默认 move 选择限制规格。
 *
 * 当前已覆盖最常见的一组限制类状态:
 * - `taunt`:禁止状态招式;
 * - `heal-block`:禁止回复类招式。
 */
class DefaultBattleSessionMoveChoiceSpecification(
    private val effectRepository: EffectDefinitionRepository,
) : BattleSessionMoveChoiceSpecification {
    override fun validate(
        session: BattleSession,
        moveId: String,
        actorUnitId: String,
    ): BattleSessionValidationResult {
        val actor =
            session.currentSnapshot.units[actorUnitId]
                ?: return BattleSessionValidationResult.rejected(
                    "Actor unit '$actorUnitId' was not found.",
                )
        if (!effectRepository.contains(moveId)) {
            return BattleSessionValidationResult.rejected("Move '$moveId' was not found.")
        }
        val move = effectRepository.get(moveId)

        if (BattleSessionChoiceRestrictionSupport.hasTaunt(actor) &&
            BattleSessionChoiceRestrictionSupport.isStatusMove(move)
        ) {
            return BattleSessionValidationResult.rejected(
                "Unit '$actorUnitId' is taunted and cannot use status move '$moveId'.",
            )
        }

        if (BattleSessionChoiceRestrictionSupport.hasHealBlock(actor) &&
            BattleSessionChoiceRestrictionSupport.isHealingMove(move)
        ) {
            return BattleSessionValidationResult.rejected(
                "Unit '$actorUnitId' is under heal block and cannot use healing move '$moveId'.",
            )
        }

        return BattleSessionValidationResult.satisfied()
    }
}