BattleSessionEffectAttributeResolver.kt

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

import io.github.lishangbu.avalon.game.battle.engine.core.constant.BattleAttributeKeys
import io.github.lishangbu.avalon.game.battle.engine.core.constant.BattleTargetRelationValues

/**
 * session effect attributes 补全器。
 *
 * 设计意图:
 * - 把 move/item 执行前的随机字段补全与目标关系推导从执行主逻辑中拆出来;
 * - 保持 `BattleSessionActionExecutionSupport` 更聚焦于动作编排本身。
 */
internal object BattleSessionEffectAttributeResolver {
    fun completeRandomAttributes(
        session: BattleSession,
        accuracy: Int?,
        attributes: Map<String, Any?>,
    ): Map<String, Any?> {
        var resolvedAttributes = attributes
        if (accuracy != null && resolvedAttributes[BattleAttributeKeys.ACCURACY_ROLL] == null) {
            resolvedAttributes += BattleAttributeKeys.ACCURACY_ROLL to session.nextPercentageRoll()
        }
        if (resolvedAttributes[BattleAttributeKeys.CHANCE_ROLL] == null) {
            resolvedAttributes += BattleAttributeKeys.CHANCE_ROLL to session.nextPercentageRoll()
        }
        return resolvedAttributes
    }

    fun withResolvedTargetCount(
        attributes: Map<String, Any?>,
        targetCount: Int,
    ): Map<String, Any?> =
        if (BattleAttributeKeys.TARGET_COUNT in attributes) {
            attributes
        } else {
            attributes + (BattleAttributeKeys.TARGET_COUNT to targetCount)
        }

    fun withDerivedTargetRelation(
        attributes: Map<String, Any?>,
        session: BattleSession,
        actorUnitId: String,
        targetUnitId: String,
    ): Map<String, Any?> {
        if (BattleAttributeKeys.TARGET_RELATION in attributes) {
            return attributes
        }
        val actorSideId = session.sideIdOfUnit(actorUnitId) ?: return attributes
        val targetSideId = session.sideIdOfUnit(targetUnitId) ?: return attributes
        val relation =
            when {
                actorUnitId == targetUnitId -> BattleTargetRelationValues.SELF
                actorSideId == targetSideId -> BattleTargetRelationValues.ALLY
                else -> BattleTargetRelationValues.FOE
            }
        return attributes + (BattleAttributeKeys.TARGET_RELATION to relation)
    }
}