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:
parent
ce6fae7b38
commit
89e6b207f8
36 changed files with 1433 additions and 251 deletions
|
|
@ -71,6 +71,8 @@ internal sealed class CurrentGameRuntimeAdapter
|
|||
sessionHost,
|
||||
commands,
|
||||
_view,
|
||||
inventory,
|
||||
character,
|
||||
selectionState,
|
||||
selection,
|
||||
gameplayInput,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using AcDream.App.Net;
|
|||
using AcDream.Core.Selection;
|
||||
using AcDream.Core.Items;
|
||||
using AcDream.Runtime;
|
||||
using AcDream.Runtime.Gameplay;
|
||||
using AcDream.Runtime.Session;
|
||||
using AcDream.UI.Abstractions;
|
||||
using AcDream.UI.Abstractions.Input;
|
||||
|
|
@ -31,6 +32,8 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
private readonly LiveSessionHost _sessionHost;
|
||||
private readonly ICommandBus _commands;
|
||||
private readonly CurrentGameRuntimeViewAdapter _view;
|
||||
private readonly RuntimeInventoryState _inventory;
|
||||
private readonly RuntimeCharacterState _character;
|
||||
private readonly SelectionState _selectionState;
|
||||
private readonly SelectionInteractionController _selection;
|
||||
private readonly GameplayInputFrameController _gameplayInput;
|
||||
|
|
@ -42,6 +45,8 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
LiveSessionHost sessionHost,
|
||||
ICommandBus commands,
|
||||
CurrentGameRuntimeViewAdapter view,
|
||||
RuntimeInventoryState inventory,
|
||||
RuntimeCharacterState character,
|
||||
SelectionState selectionState,
|
||||
SelectionInteractionController selection,
|
||||
GameplayInputFrameController gameplayInput,
|
||||
|
|
@ -52,6 +57,8 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
_sessionHost = sessionHost ?? throw new ArgumentNullException(nameof(sessionHost));
|
||||
_commands = commands ?? throw new ArgumentNullException(nameof(commands));
|
||||
_view = view ?? throw new ArgumentNullException(nameof(view));
|
||||
_inventory = inventory ?? throw new ArgumentNullException(nameof(inventory));
|
||||
_character = character ?? throw new ArgumentNullException(nameof(character));
|
||||
_selectionState = selectionState
|
||||
?? throw new ArgumentNullException(nameof(selectionState));
|
||||
_selection = selection ?? throw new ArgumentNullException(nameof(selection));
|
||||
|
|
@ -288,8 +295,13 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus gate = Validate(expectedGeneration, requireWorld: true);
|
||||
if (gate != RuntimeCommandStatus.Accepted)
|
||||
return Result(gate);
|
||||
if (command.Index < 0
|
||||
|| (command.ObjectId == 0u && command.SpellId == 0u))
|
||||
var entry = new ShortcutEntry(
|
||||
command.Index,
|
||||
command.ObjectId,
|
||||
command.SpellId);
|
||||
if (!_inventory.TryAddShortcut(
|
||||
entry,
|
||||
() => _commands.Publish(new AddShortcutRuntimeCmd(entry))))
|
||||
{
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.InventoryState,
|
||||
|
|
@ -298,10 +310,6 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
command.ObjectId);
|
||||
}
|
||||
|
||||
_commands.Publish(new AddShortcutRuntimeCmd(new ShortcutEntry(
|
||||
command.Index,
|
||||
command.ObjectId,
|
||||
command.SpellId)));
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.InventoryState,
|
||||
operation: 0,
|
||||
|
|
@ -316,7 +324,10 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus gate = Validate(expectedGeneration, requireWorld: true);
|
||||
if (gate != RuntimeCommandStatus.Accepted)
|
||||
return Result(gate);
|
||||
if (index < 0)
|
||||
if (!_inventory.TryRemoveShortcut(
|
||||
index,
|
||||
() => _commands.Publish(
|
||||
new RemoveShortcutRuntimeCmd((uint)index))))
|
||||
{
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.InventoryState,
|
||||
|
|
@ -324,7 +335,6 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus.Rejected);
|
||||
}
|
||||
|
||||
_commands.Publish(new RemoveShortcutRuntimeCmd((uint)index));
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.InventoryState,
|
||||
operation: 1,
|
||||
|
|
@ -340,9 +350,14 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus gate = Validate(expectedGeneration, requireWorld: true);
|
||||
if (gate != RuntimeCommandStatus.Accepted)
|
||||
return Result(gate);
|
||||
if ((uint)tabIndex >= 8u
|
||||
|| position < 0
|
||||
|| spellId == 0u)
|
||||
if (!_character.TryAddFavorite(
|
||||
tabIndex,
|
||||
position,
|
||||
spellId,
|
||||
() => _commands.Publish(new AddFavoriteRuntimeCmd(
|
||||
spellId,
|
||||
position,
|
||||
tabIndex))))
|
||||
{
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
|
|
@ -351,10 +366,6 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
spellId);
|
||||
}
|
||||
|
||||
_commands.Publish(new AddFavoriteRuntimeCmd(
|
||||
spellId,
|
||||
position,
|
||||
tabIndex));
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
operation: 0,
|
||||
|
|
@ -370,7 +381,11 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus gate = Validate(expectedGeneration, requireWorld: true);
|
||||
if (gate != RuntimeCommandStatus.Accepted)
|
||||
return Result(gate);
|
||||
if ((uint)tabIndex >= 8u || spellId == 0u)
|
||||
if (!_character.TryRemoveFavorite(
|
||||
tabIndex,
|
||||
spellId,
|
||||
() => _commands.Publish(
|
||||
new RemoveFavoriteRuntimeCmd(spellId, tabIndex))))
|
||||
{
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
|
|
@ -379,7 +394,6 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
spellId);
|
||||
}
|
||||
|
||||
_commands.Publish(new RemoveFavoriteRuntimeCmd(spellId, tabIndex));
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
operation: 1,
|
||||
|
|
@ -394,7 +408,10 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus gate = Validate(expectedGeneration, requireWorld: true);
|
||||
if (gate != RuntimeCommandStatus.Accepted)
|
||||
return Result(gate);
|
||||
_commands.Publish(new SetSpellbookFilterRuntimeCmd(filters));
|
||||
_character.SetSpellbookFilter(
|
||||
filters,
|
||||
() => _commands.Publish(
|
||||
new SetSpellbookFilterRuntimeCmd(filters)));
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
operation: 2,
|
||||
|
|
@ -433,7 +450,12 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus gate = Validate(expectedGeneration, requireWorld: true);
|
||||
if (gate != RuntimeCommandStatus.Accepted)
|
||||
return Result(gate);
|
||||
if (componentId == 0u)
|
||||
if (!_character.TrySetDesiredComponent(
|
||||
componentId,
|
||||
amount,
|
||||
() => _commands.Publish(new SetDesiredComponentRuntimeCmd(
|
||||
componentId,
|
||||
amount))))
|
||||
{
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
|
|
@ -442,9 +464,6 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
componentId);
|
||||
}
|
||||
|
||||
_commands.Publish(new SetDesiredComponentRuntimeCmd(
|
||||
componentId,
|
||||
amount));
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
operation: 4,
|
||||
|
|
@ -458,7 +477,9 @@ internal sealed class CurrentGameRuntimeCommandAdapter
|
|||
RuntimeCommandStatus gate = Validate(expectedGeneration, requireWorld: true);
|
||||
if (gate != RuntimeCommandStatus.Accepted)
|
||||
return Result(gate);
|
||||
_commands.Publish(new ClearDesiredComponentsRuntimeCmd());
|
||||
_character.ClearDesiredComponents(
|
||||
() => _commands.Publish(
|
||||
new ClearDesiredComponentsRuntimeCmd()));
|
||||
return EmitResult(
|
||||
RuntimeCommandDomain.Spellbook,
|
||||
operation: 5,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue