feat(ui): complete retail quick-slot input
Port global toolbar use/select/create actions, migrate the collapsed Ctrl-number bindings, and route them through a focused retained-UI controller. Preserve shortcut aliases as aliases across inventory and paperdoll drops with retail's neutral/accept/reject drag states, preventing physical item moves such as unwielding an equipped helmet. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
6fcc510d5d
commit
e65119f0c6
24 changed files with 650 additions and 69 deletions
71
src/AcDream.App/UI/Layout/ToolbarInputController.cs
Normal file
71
src/AcDream.App/UI/Layout/ToolbarInputController.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
using AcDream.Core.Selection;
|
||||
using AcDream.UI.Abstractions.Input;
|
||||
|
||||
namespace AcDream.App.UI.Layout;
|
||||
|
||||
/// <summary>
|
||||
/// Focused retained-toolbar adapter for retail global input actions. The input
|
||||
/// dispatcher owns chords/scopes; this class only maps semantic actions to the
|
||||
/// exact <c>gmToolbarUI::ListenToGlobalMessage @ 0x004BE4E0</c> slot intent.
|
||||
/// </summary>
|
||||
public sealed class ToolbarInputController
|
||||
{
|
||||
private readonly ToolbarController _toolbar;
|
||||
private readonly SelectionState _selection;
|
||||
|
||||
public ToolbarInputController(ToolbarController toolbar, SelectionState selection)
|
||||
{
|
||||
_toolbar = toolbar ?? throw new ArgumentNullException(nameof(toolbar));
|
||||
_selection = selection ?? throw new ArgumentNullException(nameof(selection));
|
||||
}
|
||||
|
||||
/// <summary>Returns true when <paramref name="action"/> belongs to the toolbar.</summary>
|
||||
public bool Handle(InputAction action)
|
||||
{
|
||||
if (TryMapShortcut(action, out int slot, out bool use))
|
||||
{
|
||||
_toolbar.UseShortcut(slot, use);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == InputAction.CreateShortcut)
|
||||
{
|
||||
_toolbar.CreateShortcutToItem(_selection.SelectedObjectId ?? 0u);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool TryMapShortcut(InputAction action, out int slot, out bool use)
|
||||
{
|
||||
int value = (int)action;
|
||||
if (value >= (int)InputAction.UseQuickSlot_1
|
||||
&& value <= (int)InputAction.UseQuickSlot_9)
|
||||
{
|
||||
slot = value - (int)InputAction.UseQuickSlot_1;
|
||||
use = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value >= (int)InputAction.SelectQuickSlot_1
|
||||
&& value <= (int)InputAction.SelectQuickSlot_9)
|
||||
{
|
||||
slot = value - (int)InputAction.SelectQuickSlot_1;
|
||||
use = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value >= (int)InputAction.UseQuickSlot_14
|
||||
&& value <= (int)InputAction.UseQuickSlot_18)
|
||||
{
|
||||
slot = 13 + value - (int)InputAction.UseQuickSlot_14;
|
||||
use = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
slot = -1;
|
||||
use = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue