DefaultMutationApplier.kt
package io.github.lishangbu.avalon.game.battle.engine.core.runtime.apply
import io.github.lishangbu.avalon.game.battle.engine.core.event.StandardHookNames
import io.github.lishangbu.avalon.game.battle.engine.core.model.FieldState
import io.github.lishangbu.avalon.game.battle.engine.core.model.SideState
import io.github.lishangbu.avalon.game.battle.engine.core.model.UnitState
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.AddVolatileMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ApplyConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ApplyFieldConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ApplySideConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.BattleMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.BoostMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ChangeTypeMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ClearBoostsMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ClearProbeMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ClearTerrainMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ClearWeatherMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ConsumeItemMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.DamageMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.ForceSwitchMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.HealMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.RemoveConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.RemoveFieldConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.RemoveSideConditionMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.RemoveStatusMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.RemoveVolatileMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.RestorePpMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.SetBoostsMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.SetProbeMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.SetStatusMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.SetSwitchBoostCarryMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.SetTerrainMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.SetWeatherMutation
import io.github.lishangbu.avalon.game.battle.engine.core.mutation.TriggerEventMutation
/**
* 默认 mutation 应用器。
*
* 设计意图:
* - 以不可变回写方式提交 mutation;
* - 自身只负责 mutation 类型分发与 triggered hook 聚合;
* - 具体 unit / side / field 写回细节交给独立 helper,避免继续堆成超大文件。
*/
class DefaultMutationApplier : MutationApplier {
override fun apply(
mutations: List<BattleMutation>,
context: MutationApplicationContext,
): MutationApplicationResult {
var currentUnits: Map<String, UnitState> = context.units
var currentField: FieldState = context.field
var currentSides: Map<String, SideState> = context.sides
val triggeredHooks = mutableListOf<io.github.lishangbu.avalon.game.battle.engine.core.type.HookName>()
for (mutation in mutations) {
when (mutation) {
is DamageMutation -> {
currentUnits = UnitMutationStateApplier.applyDamage(mutation, context, currentUnits)
}
is HealMutation -> {
currentUnits = UnitMutationStateApplier.applyHeal(mutation, context, currentUnits)
}
is SetStatusMutation -> {
currentUnits = UnitMutationStateApplier.applySetStatus(mutation, context, currentUnits)
}
is RemoveStatusMutation -> {
currentUnits = UnitMutationStateApplier.applyRemoveStatus(mutation, context, currentUnits)
}
is AddVolatileMutation -> {
currentUnits = UnitMutationStateApplier.applyAddVolatile(mutation, context, currentUnits)
}
is RemoveVolatileMutation -> {
currentUnits = UnitMutationStateApplier.applyRemoveVolatile(mutation, context, currentUnits)
}
is BoostMutation -> {
currentUnits = UnitMutationStateApplier.applyBoost(mutation, context, currentUnits)
}
is ClearBoostsMutation -> {
currentUnits = UnitMutationStateApplier.applyClearBoosts(mutation, context, currentUnits)
}
is SetBoostsMutation -> {
currentUnits = UnitMutationStateApplier.applySetBoosts(mutation, context, currentUnits)
}
is SetWeatherMutation -> {
currentField = FieldMutationStateApplier.applySetWeather(mutation, currentField)
triggeredHooks += StandardHookNames.ON_WEATHER_CHANGE
}
is ClearWeatherMutation -> {
currentField = currentField.copy(weatherState = null)
triggeredHooks += StandardHookNames.ON_WEATHER_CHANGE
}
is SetTerrainMutation -> {
currentField = FieldMutationStateApplier.applySetTerrain(mutation, currentField)
triggeredHooks += StandardHookNames.ON_TERRAIN_CHANGE
}
is ClearTerrainMutation -> {
currentField = currentField.copy(terrainState = null)
triggeredHooks += StandardHookNames.ON_TERRAIN_CHANGE
}
is ConsumeItemMutation -> {
currentUnits = UnitMutationStateApplier.applyConsumeItem(mutation, context, currentUnits)
}
is RestorePpMutation -> {
currentUnits = UnitMutationStateApplier.applyRestorePp(mutation, context, currentUnits)
}
is ChangeTypeMutation -> {
currentUnits = UnitMutationStateApplier.applyChangeType(mutation, context, currentUnits)
}
is ForceSwitchMutation -> {
currentUnits = UnitMutationStateApplier.applyForceSwitch(mutation, context, currentUnits)
}
is SetSwitchBoostCarryMutation -> {
currentUnits = UnitMutationStateApplier.applySetSwitchBoostCarry(mutation, context, currentUnits)
}
is ApplyConditionMutation -> {
currentUnits = UnitMutationStateApplier.applyAddCondition(mutation, context, currentUnits)
}
is ApplySideConditionMutation -> {
currentSides = SideMutationStateApplier.applyAddSideCondition(mutation, context, currentSides)
}
is ApplyFieldConditionMutation -> {
currentField = FieldMutationStateApplier.applyAddCondition(mutation, currentField)
}
is RemoveConditionMutation -> {
currentUnits = UnitMutationStateApplier.applyRemoveCondition(mutation, context, currentUnits)
}
is RemoveSideConditionMutation -> {
currentSides = SideMutationStateApplier.applyRemoveSideCondition(mutation, context, currentSides)
}
is RemoveFieldConditionMutation -> {
currentField = FieldMutationStateApplier.applyRemoveCondition(mutation, currentField)
}
is SetProbeMutation -> {
currentUnits = UnitMutationStateApplier.applySetProbe(mutation, context, currentUnits)
}
is ClearProbeMutation -> {
currentUnits = UnitMutationStateApplier.applyClearProbe(mutation, context, currentUnits)
}
is TriggerEventMutation -> {
triggeredHooks += mutation.hookName
}
}
}
return MutationApplicationResult(
battle = context.battle,
field = currentField,
units = currentUnits,
sides = currentSides,
triggeredHooks = triggeredHooks,
)
}
}