feat(ui): drive toolbar use state from selection
Port the retail selected-object availability predicate into Core and project it through the shared interaction owner. The imported hand now follows canonical selection/object notices, keeps weapon and targeted-tool activation on the existing wield/use cursor paths, and ghosts empty or explicitly unusable selections per the connected UX requirement. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
0134122c28
commit
60387668d0
11 changed files with 269 additions and 16 deletions
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using AcDream.Core.Combat;
|
||||
using AcDream.Core.Items;
|
||||
using AcDream.Core.Net.Messages;
|
||||
using AcDream.Core.Selection;
|
||||
|
||||
namespace AcDream.App.UI.Layout;
|
||||
|
||||
|
|
@ -73,6 +74,7 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
private readonly ItemInteractionController? _itemInteraction;
|
||||
private readonly Action<uint>? _selectItem;
|
||||
private readonly Func<uint> _selectedObjectId;
|
||||
private readonly SelectionState? _selection;
|
||||
private readonly Func<uint>? _playerGuid;
|
||||
private readonly Action<uint, uint, int>? _sendPutItemInContainer;
|
||||
private uint _ammoObjectId;
|
||||
|
|
@ -106,6 +108,7 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
Action? toggleCombat = null,
|
||||
Action<uint>? selectItem = null,
|
||||
Func<uint>? selectedObjectId = null,
|
||||
SelectionState? selection = null,
|
||||
Func<uint>? playerGuid = null,
|
||||
Action<uint, uint, int>? sendPutItemInContainer = null,
|
||||
UiDatFont? ammoFont = null,
|
||||
|
|
@ -125,6 +128,7 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
_sendRemoveShortcut = sendRemoveShortcut;
|
||||
_selectItem = selectItem;
|
||||
_selectedObjectId = selectedObjectId ?? (() => 0u);
|
||||
_selection = selection;
|
||||
_playerGuid = playerGuid;
|
||||
_sendPutItemInContainer = sendPutItemInContainer;
|
||||
|
||||
|
|
@ -196,6 +200,8 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
// Wire live combat-mode changes if a CombatState was provided.
|
||||
if (_combatState is not null)
|
||||
_combatState.CombatModeChanged += SetCombatMode;
|
||||
if (_selection is not null)
|
||||
_selection.Changed += OnSelectionChanged;
|
||||
|
||||
// D.5.4: the table now holds ALL objects (creatures, NPCs, etc.), so filter
|
||||
// to our 18 shortcut guids — else every creature spawn in a busy zone
|
||||
|
|
@ -206,6 +212,7 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
repo.ObjectMoved += OnRepositoryObjectMoved;
|
||||
repo.Cleared += OnRepositoryCleared;
|
||||
RefreshAmmo();
|
||||
RefreshUseButton();
|
||||
}
|
||||
|
||||
private void OnRepositoryObjectChanged(ClientObject obj)
|
||||
|
|
@ -214,6 +221,8 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
RefreshAmmo();
|
||||
if (IsShortcutGuid(obj.ObjectId))
|
||||
Populate();
|
||||
if (obj.ObjectId == _selectedObjectId())
|
||||
RefreshUseButton();
|
||||
}
|
||||
|
||||
private void OnRepositoryObjectMoved(ClientObjectMove move)
|
||||
|
|
@ -234,6 +243,23 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
{
|
||||
RefreshAmmo();
|
||||
Populate();
|
||||
RefreshUseButton();
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(SelectionTransition _)
|
||||
=> RefreshUseButton();
|
||||
|
||||
private void RefreshUseButton()
|
||||
{
|
||||
if (_useButton is null)
|
||||
return;
|
||||
|
||||
// Retail normally leaves state 1 active when selectedID == 0 so the
|
||||
// click can enter generic TARGET_MODE_USE. acdream intentionally
|
||||
// ghosts that empty state per the connected UX requirement; every
|
||||
// selected-object classification below is the exact retail predicate.
|
||||
_useButton.Enabled =
|
||||
_itemInteraction?.IsToolbarUseEnabled(_selectedObjectId()) == true;
|
||||
}
|
||||
|
||||
private bool IsAmmoRelated(ClientObject obj)
|
||||
|
|
@ -330,6 +356,7 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
Action? toggleCombat = null,
|
||||
Action<uint>? selectItem = null,
|
||||
Func<uint>? selectedObjectId = null,
|
||||
SelectionState? selection = null,
|
||||
Func<uint>? playerGuid = null,
|
||||
Action<uint, uint, int>? sendPutItemInContainer = null,
|
||||
UiDatFont? ammoFont = null,
|
||||
|
|
@ -338,7 +365,7 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
var c = new ToolbarController(layout, repo, shortcuts, iconIds, useItem, combatState,
|
||||
regularDigits, ghostedDigits, emptyDigits, itemInteraction,
|
||||
sendAddShortcut, sendRemoveShortcut, toggleCombat, selectItem,
|
||||
selectedObjectId, playerGuid, sendPutItemInContainer, ammoFont,
|
||||
selectedObjectId, selection, playerGuid, sendPutItemInContainer, ammoFont,
|
||||
dragIconIds);
|
||||
c.Populate();
|
||||
return c;
|
||||
|
|
@ -736,6 +763,8 @@ public sealed class ToolbarController : IItemListDragHandler, IRetainedPanelCont
|
|||
|
||||
if (_combatState is not null)
|
||||
_combatState.CombatModeChanged -= SetCombatMode;
|
||||
if (_selection is not null)
|
||||
_selection.Changed -= OnSelectionChanged;
|
||||
_repo.ObjectAdded -= OnRepositoryObjectChanged;
|
||||
_repo.ObjectUpdated -= OnRepositoryObjectChanged;
|
||||
_repo.ObjectRemoved -= OnRepositoryObjectChanged;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue