UnitState.kt

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

/**
 * 战斗单位运行时状态骨架。
 *
 * 设计意图:
 * - 表示单个战斗单位的当前局内状态。
 * - 与静态物种模板、技能数据、effect 定义解耦。
 *
 * @property id 单位唯一标识。
 * @property currentHp 当前生命值。
 * @property maxHp 最大生命值。
 * @property statusState 主状态的运行时状态。
 * @property abilityId 当前特性标识。
 * @property itemId 当前道具标识。
 * @property typeIds 当前属性列表。
 * @property volatileStates 当前挥发状态的运行时状态表。
 * @property conditionStates 当前附着条件的运行时状态表。
 * @property boosts 当前 stage / boost 表。
 * @property stats 当前运行时属性值表。
 * @property movePp 当前招式剩余 PP。
 * @property metadata 当前单位的结构化规则元数据。
 * @property debugState 当前单位的调试/探针状态。
 * @property sessionState 仅供 session 编排使用的内部工作状态。
 * @property forceSwitchRequested 当前单位是否被标记为强制替换。
 *
 * 说明:
 * - `statusState / volatileStates / conditionStates` 是唯一合法的挂载效果表达;
 * - 不再保留旧的 id 镜像字段,避免状态真值来源分裂。
 * - `metadata` 用于承载会被战斗规则直接读取的结构化单位元数据;
 * - `debugState` 当前仅保留给测试探针与轻量调试上下文;
 * - `sessionState` 用于承载必须随快照持久化、但不应该暴露成探针式字符串状态位的
 *   session 内部工作位。
 */
data class UnitState(
    val id: String,
    val currentHp: Int,
    val maxHp: Int,
    val statusState: AttachedEffectState? = null,
    val abilityId: String? = null,
    val itemId: String? = null,
    val typeIds: Set<String> = emptySet(),
    val volatileStates: Map<String, AttachedEffectState> = emptyMap(),
    val conditionStates: Map<String, AttachedEffectState> = emptyMap(),
    val boosts: Map<String, Int> = emptyMap(),
    val stats: Map<String, Int> = emptyMap(),
    val movePp: Map<String, Int> = emptyMap(),
    val metadata: UnitMetadataState = UnitMetadataState(),
    val debugState: UnitDebugState = UnitDebugState(),
    val sessionState: UnitSessionState = UnitSessionState(),
    val forceSwitchRequested: Boolean = false,
)