BattleSessionReplacementResolver.kt
package io.github.lishangbu.avalon.game.battle.engine.core.session
/**
* 负责濒死替补与胜负结算。
*
* 这是 `BattleSession` 里另一段很容易膨胀的逻辑:
* - 检查 active 单位是否倒下
* - 计算自动替补
* - 生成待处理替补请求
* - 更新最终胜者
*/
internal class BattleSessionReplacementResolver(
private val session: BattleSession,
) {
private val replacementPlanResolver: BattleSessionReplacementPlanResolver =
BattleSessionReplacementPlanResolver(session.replacementStrategy)
private val autoReplacementExecutor: BattleSessionAutoReplacementExecutor =
BattleSessionAutoReplacementExecutor(session)
private val winnerResolver: BattleSessionWinnerResolver = BattleSessionWinnerResolver(session)
/**
* 在给定快照上完成“濒死检查 + 自动替补 + 待替补请求 + 胜负更新”。
*
* @param snapshot 要处理的快照,默认使用会话当前快照
* @return 处理后的快照
*/
fun resolveFaintAndReplacement(snapshot: io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow.BattleRuntimeSnapshot = session.currentSnapshot): io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow.BattleRuntimeSnapshot {
var nextSnapshot = session.processFaintHooks(snapshot)
session.replacementRequests.clear()
nextSnapshot.sides.forEach { (sideId, side) ->
val currentUnits = nextSnapshot.units
val plan = replacementPlanResolver.resolve(sideId, side, currentUnits)
if (plan.requiresManualReplacement) {
session.replacementRequests +=
BattleSessionReplacementRequest(
sideId = plan.sideId,
outgoingUnitIds = plan.requiredOutgoingUnitIds,
candidateUnitIds = plan.candidateUnitIds,
)
return@forEach
}
nextSnapshot = autoReplacementExecutor.execute(nextSnapshot, plan)
}
return updateWinnerIfNeeded(nextSnapshot)
}
/**
* 根据仍有可战斗单位的 side 计算胜者。
*
* @param snapshot 待判定的快照
* @return 已更新胜者信息的快照
*/
fun updateWinnerIfNeeded(snapshot: io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow.BattleRuntimeSnapshot): io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow.BattleRuntimeSnapshot = winnerResolver.updateWinnerIfNeeded(snapshot)
}