Pace combat resolution across phases instead of resolving instantly

Convert CombatManager's phase state machine to coroutines so drawing,
interpreter-queue cards, and enemy actions each resolve one at a time
with visible delays, instead of an entire phase mutating state in a
single synchronous frame. Delays are skipped when UIPreferences.ReducedMotion
is set. Also drops the UI's old artificial cascade stagger for queued-card
animations since real per-card timing now provides the spacing.
This commit is contained in:
Claude
2026-07-08 16:18:13 +00:00
parent 54906bbba1
commit 2395e5108c
3 changed files with 85 additions and 67 deletions
+3 -14
View File
@@ -61,7 +61,6 @@ namespace KernelPanic.UI
private readonly Dictionary<CombatantState, int> previousUptime = new();
private readonly Dictionary<CombatantState, int> previousShield = new();
private readonly HashSet<CardInstance> knownHandCards = new();
private int queueCascadeIndex;
private void Awake()
{
@@ -1048,14 +1047,9 @@ namespace KernelPanic.UI
if (payload.Track == ResolutionTrack.InterpreterQueue)
{
int delay = UIPreferences.ReducedMotion ? 0 : Mathf.Min(queueCascadeIndex * 120, 600);
queueCascadeIndex++;
ScheduleFeedback(() =>
{
VisualElement chip = queueChipElements.TryGetValue(payload.Card, out VisualElement queuedChip) ? queuedChip : interpreterStrip;
PlayElementBeat(chip, "queue-chip-resolve", 260);
FlyCardGhost(payload.Card, chip, turnResourceGrid, "feedback-card-discard");
}, delay);
VisualElement chip = queueChipElements.TryGetValue(payload.Card, out VisualElement queuedChip) ? queuedChip : interpreterStrip;
PlayElementBeat(chip, "queue-chip-resolve", 260);
FlyCardGhost(payload.Card, chip, turnResourceGrid, "feedback-card-discard");
return;
}
@@ -1069,11 +1063,6 @@ namespace KernelPanic.UI
private void HandlePhaseChanged(PhaseChangedEvent payload)
{
if (payload.NextPhase == TurnPhase.Interpret)
{
queueCascadeIndex = 0;
}
ScheduleFeedback(() => PlayElementBeat(phaseLabel, "phase-pulse", 260), 0);
}