feat(D.5.1): mount the toolbar window under ACDREAM_RETAIL_UI

Wire IconComposer + ToolbarController.Bind + the LayoutDesc 0x21000016
import into the if (_options.RetailUi) block in GameWindow, mirroring
the vitals/chat pattern. Add UseItemByGuid helper (direct send, no
proximity gate) near the B.4b use-item path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-16 22:44:52 +02:00
parent 383a969c70
commit 3b6f293dc8

View file

@ -1780,6 +1780,11 @@ public sealed class GameWindow : IDisposable
return (t, w, h); return (t, w, h);
} }
// Phase D.5.1 — icon composer for the toolbar shortcut slots.
// Constructed once here so the closure below can capture it; needs
// the same cache reference that ResolveChrome uses above.
var iconComposer = new AcDream.App.UI.IconComposer(_dats!, cache);
// Phase D.2b — optional retail stylesheet. controls.ini lives under // Phase D.2b — optional retail stylesheet. controls.ini lives under
// the AC install (ACDREAM_AC_DIR); absent → source-verified fallback. // the AC install (ACDREAM_AC_DIR); absent → source-verified fallback.
var controls = _options.AcDir is { } acDir var controls = _options.AcDir is { } acDir
@ -1902,6 +1907,29 @@ public sealed class GameWindow : IDisposable
} }
else Console.WriteLine("[D.2b] chat: LayoutDesc 0x21000006 not found."); else Console.WriteLine("[D.2b] chat: LayoutDesc 0x21000006 not found.");
// Phase D.5.1 — toolbar window, data-driven from LayoutDesc 0x21000016
// (gmToolbarUI). Mirrors the vitals/chat import+bind+mount pattern above.
AcDream.App.UI.Layout.ImportedLayout? toolbarLayout;
lock (_datLock)
toolbarLayout = AcDream.App.UI.Layout.LayoutImporter.Import(
_dats!, 0x21000016u, ResolveChrome, vitalsDatFont);
if (toolbarLayout is not null)
{
AcDream.App.UI.Layout.ToolbarController.Bind(
toolbarLayout, Items,
() => Shortcuts,
iconIds: (icon, under, over) => iconComposer.GetIcon(icon, under, over),
useItem: guid => UseItemByGuid(guid));
var toolbarRoot = toolbarLayout.Root;
toolbarRoot.Left = 10; toolbarRoot.Top = 300;
toolbarRoot.Anchors = AcDream.App.UI.AnchorEdges.Left | AcDream.App.UI.AnchorEdges.Top;
toolbarRoot.Draggable = true;
_uiHost.Root.AddChild(toolbarRoot);
Console.WriteLine("[D.5.1] retail toolbar window from LayoutDesc importer (0x21000016).");
}
else Console.WriteLine("[D.5.1] toolbar: LayoutDesc 0x21000016 not found.");
// Drain plugin-registered markup panels (buffered before the GL // Drain plugin-registered markup panels (buffered before the GL
// window opened) into the same UiRoot tree. A faulty plugin markup // window opened) into the same UiRoot tree. A faulty plugin markup
// file is isolated — logged + skipped, never crashes the client. // file is isolated — logged + skipped, never crashes the client.
@ -11594,6 +11622,17 @@ public sealed class GameWindow : IDisposable
} }
} }
// Phase D.5.1 — direct use-by-guid for toolbar shortcut clicks.
// Mirrors the B.4b far-range send path; no proximity / auto-walk needed
// for items already in the player's inventory.
private void UseItemByGuid(uint guid)
{
if (_liveSession is null) return;
var seq = _liveSession.NextGameActionSequence();
var body = AcDream.Core.Net.Messages.InteractRequests.BuildUse(seq, guid);
_liveSession.SendGameAction(body);
}
private void SendPickUp(uint itemGuid) private void SendPickUp(uint itemGuid)
{ {
if (_liveSession is null if (_liveSession is null