BattleSessionChoiceRestrictionSupport.kt

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

import io.github.lishangbu.avalon.game.battle.engine.core.dsl.EffectDefinition
import io.github.lishangbu.avalon.game.battle.engine.core.model.UnitState
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.BattleMoveDataReader

/**
 * move/item 选择限制共享辅助。
 *
 * 设计意图:
 * - 收口 `taunt / heal-block / embargo` 这类限制状态的公共判定逻辑;
 * - 避免相同字符串键和标签判定在多个 specification 中继续散落;
 * - 后续继续补 `disable / encore / torment / magic-room` 时,也能沿这个入口扩展。
 */
internal object BattleSessionChoiceRestrictionSupport {
    private val healingMoveTags: Set<String> = setOf("healing", "recovery")

    fun hasTaunt(unit: UnitState): Boolean = hasAttachedState(unit, TAUNT_EFFECT_ID)

    fun hasHealBlock(unit: UnitState): Boolean = hasAttachedState(unit, HEAL_BLOCK_EFFECT_ID)

    fun hasEmbargo(unit: UnitState): Boolean = hasAttachedState(unit, EMBARGO_EFFECT_ID)

    fun isStatusMove(effect: EffectDefinition): Boolean =
        BattleMoveDataReader.readDamageClass(effect.data)?.equals("status", ignoreCase = true) == true ||
            "status" in effect.tags

    fun isHealingMove(effect: EffectDefinition): Boolean = effect.tags.any { tag -> tag in healingMoveTags }

    private fun hasAttachedState(
        unit: UnitState,
        effectId: String,
    ): Boolean = effectId in unit.volatileStates || effectId in unit.conditionStates

    private const val TAUNT_EFFECT_ID: String = "taunt"
    private const val HEAL_BLOCK_EFFECT_ID: String = "heal-block"
    private const val EMBARGO_EFFECT_ID: String = "embargo"
}