feat: port retail magic lifecycle and retained spell UI

Complete the retail cast-intent, target, component, enchantment, and busy-state paths; mount the DAT-authored spell bar, spellbook, component book, effects panels, and shared panel lifecycle; and add scoped input plus conformance coverage.

Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-15 10:55:22 +02:00
parent 7b7ffcd278
commit 07be994d97
84 changed files with 17822 additions and 1051 deletions

View file

@ -1,24 +1,36 @@
namespace AcDream.App.UI;
/// <summary>
/// Retail toolbar panel ids carried by DAT property <c>0x10000029</c>.
/// Retail reference: <c>gmToolbarUI::PostInit @ 0x004BEA80</c> discovers the
/// seven buttons and reads this property from each one.
/// Only panels mounted in the retained runtime are mapped; other authored
/// toolbar buttons remain present but ghosted until their panel ships.
/// Retail <c>gmPanelUI</c> panel ids carried by DAT property <c>0x10000029</c>.
/// The toolbar exposes only a subset of these ids; Helpful/Harmful effects use
/// the authored <c>gmUIElement_EffectsIndicator</c> buttons instead.
/// </summary>
public static class RetailPanelCatalog
{
public const uint PositiveEffects = 4u;
public const uint NegativeEffects = 5u;
public const uint Inventory = 7u;
public const uint Character = 11u;
public const uint Magic = 13u;
private static readonly (uint PanelId, string WindowName)[] Mounted =
{
(PositiveEffects, WindowNames.PositiveEffects),
(NegativeEffects, WindowNames.NegativeEffects),
(Inventory, WindowNames.Inventory),
(Character, WindowNames.Character),
(Magic, WindowNames.Spellbook),
};
private static readonly (uint PanelId, string WindowName)[] Toolbar =
{
(Inventory, WindowNames.Inventory),
(Character, WindowNames.Character),
(Magic, WindowNames.Spellbook),
};
public static IReadOnlyList<(uint PanelId, string WindowName)> MountedPanels => Mounted;
public static IReadOnlyList<(uint PanelId, string WindowName)> ToolbarPanels => Toolbar;
public static bool TryGetWindowName(uint panelId, out string windowName)
{