BattleMoveTargetCountDamageModifier.kt

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

import io.github.lishangbu.avalon.game.battle.engine.core.constant.BattleAttributeKeys
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.BattleMoveDataReader
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.EventContextAttributeReader
import kotlin.math.floor

/**
 * 多目标招式伤害修正器。
 *
 * 设计意图:
 * - 把“目标数量修正”从主伤害 phase 中拆开,使其成为一条可独立测试、可单独替换的规则。
 * - 明确区分“session 会把一招展开到多个目标”与“主线规则要求多目标伤害再乘倍率”这两个层次。
 *
 * 当前约定:
 * - 只有本次实际命中的目标数量大于 1 时,才应用多目标倍率。
 * - 仅对会命中多个战斗单位的目标模式生效,例如 `all-opponents`、`all-other-pokemon`、`all-pokemon`。
 * - 现代主线统一按 0.75 处理。
 */
class BattleMoveTargetCountDamageModifier {
    fun apply(
        damage: Int,
        moveData: Map<String, Any?>,
        attributes: Map<String, Any?>,
    ): Int {
        if (damage <= 0) {
            return damage
        }
        val resolvedTargetCount = EventContextAttributeReader.readInt(BattleAttributeKeys.TARGET_COUNT, attributes) ?: return damage
        if (resolvedTargetCount <= 1) {
            return damage
        }
        val rawTarget = BattleMoveDataReader.readTarget(moveData) ?: return damage
        if (rawTarget !in SPREAD_TARGETS) {
            return damage
        }
        return floor(damage * SPREAD_DAMAGE_MULTIPLIER).toInt()
    }

    private companion object {
        private const val SPREAD_DAMAGE_MULTIPLIER: Double = 0.75
        private val SPREAD_TARGETS: Set<String> =
            setOf(
                "all-opponents",
                "all-other-pokemon",
                "all-pokemon",
                "entire-field",
            )
    }
}