BattleSessionFaintHookStateManager.kt

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

import io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow.BattleRuntimeSnapshot

/**
 * session faint hook 内部工作位管理器。
 *
 * 设计意图:
 * - 把 `faintHookProcessed` 的清理、写入与读取逻辑
 *   从生命周期处理器里拆出来;
 * - 让 `BattleSessionHookLifecycleProcessor` 只关心扫描和调度顺序;
 * - 明确这是一层内部 session work-state 管理,而不是 battle 规则本身。
 */
internal class BattleSessionFaintHookStateManager {
    fun clearRecoveredFaintFlags(snapshot: BattleRuntimeSnapshot): BattleRuntimeSnapshot {
        val nextUnits =
            snapshot.units.mapValues { (_, unit) ->
                if (unit.currentHp > 0 && unit.sessionState.faintHookProcessed) {
                    unit.copy(sessionState = unit.sessionState.copy(faintHookProcessed = false))
                } else {
                    unit
                }
            }
        return if (nextUnits == snapshot.units) {
            snapshot
        } else {
            snapshot.copy(units = nextUnits)
        }
    }

    fun firstUnhandledFaintedUnitId(snapshot: BattleRuntimeSnapshot): String? =
        snapshot.units.values
            .firstOrNull { unit ->
                unit.currentHp <= 0 &&
                    !unit.sessionState.faintHookProcessed
            }?.id

    fun markFaintHookProcessed(
        snapshot: BattleRuntimeSnapshot,
        unitId: String,
    ): BattleRuntimeSnapshot {
        val unit = snapshot.units[unitId] ?: return snapshot
        if (unit.sessionState.faintHookProcessed) {
            return snapshot
        }
        return snapshot.copy(
            units =
                snapshot.units +
                    (
                        unitId to
                            unit.copy(
                                sessionState = unit.sessionState.copy(faintHookProcessed = true),
                            )
                    ),
        )
    }

    fun clearFaintHookProcessed(
        snapshot: BattleRuntimeSnapshot,
        unitId: String,
    ): BattleRuntimeSnapshot {
        val unit = snapshot.units[unitId] ?: return snapshot
        if (!unit.sessionState.faintHookProcessed) {
            return snapshot
        }
        return snapshot.copy(
            units =
                snapshot.units +
                    (
                        unitId to
                            unit.copy(
                                sessionState = unit.sessionState.copy(faintHookProcessed = false),
                            )
                    ),
        )
    }
}