refactor(runtime): close canonical gameplay ownership

Unify the toolbar shortcut manager with Runtime inventory state, route retail-ordered shortcut and spellbook command effects through the canonical owners, and make retained controllers borrow those exact instances. Remove the item-interaction transaction fallback and add graphical/no-window parity plus failure-safe terminal ownership-ledger coverage.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-26 09:48:51 +02:00
parent ce6fae7b38
commit 89e6b207f8
36 changed files with 1433 additions and 251 deletions

View file

@ -209,7 +209,6 @@ public sealed class SpellcastingUiController : IRetainedPanelController
}
int position = spells.Count;
_addFavorite?.Invoke(_activeTab, position, spellId);
_spellbook.SetFavorite(_activeTab, position, spellId);
SelectSpell(spellId);
}
@ -424,13 +423,15 @@ public sealed class SpellcastingUiController : IRetainedPanelController
private void BeginFavoriteDrag(SpellFavoriteDragPayload payload)
=> _removeFavorite?.Invoke(payload.SourceTab, payload.SpellId);
private void EndFavoriteDrag(SpellFavoriteDragPayload payload)
=> _spellbook.RemoveFavorite(payload.SourceTab, payload.SpellId);
private static void EndFavoriteDrag(SpellFavoriteDragPayload payload)
{
// The press-time command already performed retail's PlayerModule
// removal on the one Runtime-owned Spellbook.
}
private void DropFavorite(SpellFavoriteDragPayload payload, int targetTab, int targetPosition)
{
_addFavorite?.Invoke(targetTab, targetPosition, payload.SpellId);
_spellbook.SetFavorite(targetTab, targetPosition, payload.SpellId);
_selected[targetTab] = payload.SpellId;
}
@ -443,7 +444,6 @@ public sealed class SpellcastingUiController : IRetainedPanelController
// CM_Magic::SendNotice_AddSpellShortcut; the open spellcasting menu
// chooses the favorite tab/position and persists it.
_addFavorite?.Invoke(targetTab, targetPosition, payload.SpellId);
_spellbook.SetFavorite(targetTab, targetPosition, payload.SpellId);
_selected[targetTab] = payload.SpellId;
}