BattleSessionSwitchBoostStateSupport.kt
package io.github.lishangbu.avalon.game.battle.engine.core.session
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow.BattleRuntimeSnapshot
import io.github.lishangbu.avalon.game.battle.engine.core.runtime.support.BattleStoredBoostSupport
/**
* session 换人过程中的 boosts 清理与 Baton Pass 继承支持组件。
*
* 设计意图:
* - 把“离场清空 boosts”和“入场继承暂存 boosts”从多个 switch executor 中抽离;
* - 保证普通换人、强制换人、濒死替补三条路径共享同一套能力变化收口规则;
* - 让 Baton Pass 这类例外规则只在这一层表达,不污染通用 switch 编排主体。
*/
internal object BattleSessionSwitchBoostStateSupport {
/**
* 在单位离场时清空其当前 boosts,但保留待继承快照。
*/
fun clearOutgoingBoosts(
snapshot: BattleRuntimeSnapshot,
outgoingUnitId: String,
): BattleRuntimeSnapshot {
val outgoingUnit = snapshot.units[outgoingUnitId] ?: return snapshot
val normalizedCarry = BattleStoredBoostSupport.normalize(outgoingUnit.sessionState.pendingSwitchBoostCarry)
val nextOutgoingUnit =
outgoingUnit.copy(
boosts = emptyMap(),
sessionState = outgoingUnit.sessionState.copy(pendingSwitchBoostCarry = normalizedCarry),
)
return snapshot.copy(units = snapshot.units + (outgoingUnitId to nextOutgoingUnit))
}
/**
* 在新单位入场前消费上一位离场者的待继承 boosts。
*/
fun applyIncomingBoostCarry(
snapshot: BattleRuntimeSnapshot,
outgoingUnitId: String?,
incomingUnitId: String,
): BattleRuntimeSnapshot {
val incomingClearedSnapshot = clearIncomingCarry(snapshot, incomingUnitId)
if (outgoingUnitId == null) {
return incomingClearedSnapshot
}
val outgoingUnit = incomingClearedSnapshot.units[outgoingUnitId] ?: return incomingClearedSnapshot
val incomingUnit = incomingClearedSnapshot.units[incomingUnitId] ?: return incomingClearedSnapshot
val pendingCarry = BattleStoredBoostSupport.normalize(outgoingUnit.sessionState.pendingSwitchBoostCarry)
val nextOutgoingUnit = outgoingUnit.copy(sessionState = outgoingUnit.sessionState.copy(pendingSwitchBoostCarry = emptyMap()))
if (pendingCarry.isEmpty()) {
return incomingClearedSnapshot.copy(
units = incomingClearedSnapshot.units + (outgoingUnitId to nextOutgoingUnit),
)
}
val nextIncomingUnit =
incomingUnit.copy(
boosts = pendingCarry,
sessionState = incomingUnit.sessionState.copy(pendingSwitchBoostCarry = emptyMap()),
)
return incomingClearedSnapshot.copy(
units =
incomingClearedSnapshot.units +
(outgoingUnitId to nextOutgoingUnit) +
(incomingUnitId to nextIncomingUnit),
)
}
private fun clearIncomingCarry(
snapshot: BattleRuntimeSnapshot,
incomingUnitId: String,
): BattleRuntimeSnapshot {
val incomingUnit = snapshot.units[incomingUnitId] ?: return snapshot
if (incomingUnit.sessionState.pendingSwitchBoostCarry.isEmpty()) {
return snapshot
}
return snapshot.copy(
units =
snapshot.units +
(
incomingUnitId to
incomingUnit.copy(
sessionState = incomingUnit.sessionState.copy(pendingSwitchBoostCarry = emptyMap()),
)
),
)
}
}