refactor(runtime): own combat and magic intent

Move attack build/repeat state, combat-mode policy, authoritative auto-target transitions, and spell-cast intent beneath RuntimeActionState. Keep App as the input, world-query, DAT-policy, transport, and presentation adapter while preserving retail request and busy ordering. Add direct/graphical parity, reset, failure, and instance-isolation coverage.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-26 11:56:40 +02:00
parent 81b31857c6
commit 20df9d155d
49 changed files with 1949 additions and 634 deletions

View file

@ -373,10 +373,15 @@ public sealed class GameWindow :
private readonly DeferredRenderFrameDiagnosticsSource _uiFrameDiagnostics = new();
private readonly AcDream.App.Combat.CombatAttackOperationsSlot
_combatAttackOperations = new();
private readonly AcDream.App.Combat.RuntimeCombatTargetOperationsSlot
_combatTargetOperations = new();
private readonly AcDream.App.Combat.RuntimeCombatModeOperationsSlot
_combatModeOperations = new();
private readonly AcDream.App.Spells.RuntimeSpellCastOperationsSlot
_spellCastOperations = new();
private readonly AcDream.App.Combat.CombatFeedbackSlot
_combatFeedback = new();
private AcDream.App.Combat.CombatAttackController? _combatAttackController;
private AcDream.App.Combat.CombatTargetController? _combatTargetController;
private RuntimeCombatAttackState? _combatAttackController;
private AcDream.App.UI.ItemInteractionController? _itemInteractionController;
private AcDream.App.World.ExternalContainerLifecycleController? _externalContainerLifecycle;
private AcDream.App.Spells.MagicRuntime? _magicRuntime;
@ -561,8 +566,14 @@ public sealed class GameWindow :
{
_options = options ?? throw new System.ArgumentNullException(nameof(options));
_runtimeInventory = new RuntimeInventoryState(_runtimeEntityObjects);
_runtimeActions = new RuntimeActionState(_runtimeInventory.Transactions);
_runtimeCharacter = new RuntimeCharacterState();
_runtimeActions = new RuntimeActionState(
_runtimeInventory.Transactions,
_runtimeCharacter.Spellbook,
_combatAttackOperations,
_combatTargetOperations,
_combatModeOperations,
_spellCastOperations);
var alphaScratchBudgets =
AcDream.App.Rendering.Residency.AlphaScratchBudgetProfile.Create(
_options.ResidencyBudgets.AlphaScratchBytes);
@ -905,7 +916,6 @@ public sealed class GameWindow :
{
ArgumentNullException.ThrowIfNull(result);
if (_combatAttackController is not null
|| _combatTargetController is not null
|| _externalContainerLifecycle is not null
|| _itemInteractionController is not null
|| _interactionUiLateBindings is not null
@ -921,10 +931,10 @@ public sealed class GameWindow :
}
_combatAttackController = result.CombatAttack;
_combatTargetController = result.CombatTarget;
_externalContainerLifecycle = result.ExternalContainerLifecycle;
_itemInteractionController = result.ItemInteraction;
_interactionUiLateBindings = result.LateBindings;
_magicRuntime = result.Magic;
if (result.RetainedUi is { } retained)
{
_uiHost = retained.Host;
@ -932,7 +942,6 @@ public sealed class GameWindow :
_vitalsVm ??= retained.Vitals;
_retailChatVm = retained.Chat;
_characterSheetProvider = retained.CharacterSheet;
_magicRuntime = retained.Magic;
_frameScreenshots = retained.Screenshots;
}
}
@ -1256,6 +1265,8 @@ public sealed class GameWindow :
_runtimeSettings,
_runtimeActions,
_combatAttackOperations,
_combatTargetOperations,
_spellCastOperations,
_runtimeInventory,
contentEffectsAudio.MagicCatalog,
_runtimeCharacter,
@ -1358,6 +1369,7 @@ public sealed class GameWindow :
_worldSceneDebugState,
_runtimeDiagnosticCommands,
_liveCombatModeCommands,
_combatModeOperations,
_hostQuiescence,
_physicsEngine,
_physicsDataCache,
@ -1564,8 +1576,7 @@ public sealed class GameWindow :
new LiveShutdownRoots(
_cameraPointerInput,
_retailUiLease,
_combatTargetController,
_combatAttackController,
_magicRuntime,
_itemInteractionController,
_externalContainerLifecycle,
_streamer,