fix(D.5.1): occupancy-gated slot numbers (empty=0x1000005e bg digit) + bottom-right rect probe
FIX 1: UIElement_UIItem::SetShortcutNum (decomp 229481) has a three-way source branch: occupied+peace -> 0x10000042 (peace digit set), occupied+war -> 0x10000043 (war digit set), empty (ItemId==0) -> 0x1000005e (background digit, stance-independent). acdream previously only had the peace/war pair and drew them regardless of occupancy. Changes: - GameWindow.cs: read property 0x1000005e into toolbarEmptyDigits (no fallback; null is safe). Logs entry count. Passes emptyDigits to Bind. Adds [D.5.1 probe] block logging screen pos + size of 7 bottom-right element ids via ScreenPosition. - ToolbarController.cs: adds _emptyDigits field, emptyDigits ctor+Bind param (null default). RestampShortcutNumbers sets cell.EmptyDigits. Comments cite decomp 229481. - UiItemSlot.cs: adds EmptyDigits property + ActiveDigitArray() internal testable seam (occupied -> peace/war by stance; empty -> EmptyDigits). OnDraw uses it. Comment updated with three-way source table. - Tests: 5 new UiItemSlotTests (ActiveDigitArray occupancy), 2 new ToolbarControllerTests (emptyDigits injection + null-safe). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7d5a88cd15
commit
a7cad5566b
5 changed files with 200 additions and 24 deletions
|
|
@ -1913,12 +1913,15 @@ public sealed class GameWindow : IDisposable
|
|||
// (gmToolbarUI). Mirrors the vitals/chat import+bind+mount pattern above.
|
||||
|
||||
// Read the shortcut-slot digit sprite DID arrays from LayoutDesc 0x21000037
|
||||
// (the UIItem cell template): element 0x1000034A under composite 0x10000346,
|
||||
// StateDesc.Properties[0x10000042] = peace digits, [0x10000043] = war digits.
|
||||
// (the UIItem cell template): element 0x1000034A under composite 0x10000346.
|
||||
// Retail ref: UIElement_UIItem::SetShortcutNum (acclient_2013_pseudo_c.txt:229465);
|
||||
// gmToolbarUI::RecvNotice_SetCombatMode (196610-196621) re-stamps per stance.
|
||||
// Occupancy branch (decomp 229481):
|
||||
// occupied → StateDesc.Properties[0x10000042] (peace) / [0x10000043] (war)
|
||||
// empty → StateDesc.Properties[0x1000005e] (background digit, stance-independent)
|
||||
uint[]? toolbarPeaceDigits = null;
|
||||
uint[]? toolbarWarDigits = null;
|
||||
uint[]? toolbarEmptyDigits = null;
|
||||
lock (_datLock)
|
||||
{
|
||||
var uiItemLd = _dats!.Get<DatReaderWriter.DBObjs.LayoutDesc>(0x21000037u);
|
||||
|
|
@ -1948,6 +1951,19 @@ public sealed class GameWindow : IDisposable
|
|||
if (arrWar.Value[i] is DatReaderWriter.Types.DataIdBaseProperty d)
|
||||
toolbarWarDigits[i] = d.Value;
|
||||
}
|
||||
// Empty-slot background digit: property 0x1000005e, stance-independent.
|
||||
// Retail ref: UIElement_UIItem::SetShortcutNum (decomp 229481) —
|
||||
// else branch when m_elem_Icon->m_state == 0x1000001c (empty state).
|
||||
// No fallback constants — if absent, empty slots draw no digit (safe).
|
||||
if (props.TryGetValue(0x1000005Eu, out var rawEmpty)
|
||||
&& rawEmpty is DatReaderWriter.Types.ArrayBaseProperty arrEmpty)
|
||||
{
|
||||
toolbarEmptyDigits = new uint[arrEmpty.Value.Count];
|
||||
for (int i = 0; i < arrEmpty.Value.Count; i++)
|
||||
if (arrEmpty.Value[i] is DatReaderWriter.Types.DataIdBaseProperty d)
|
||||
toolbarEmptyDigits[i] = d.Value;
|
||||
}
|
||||
Console.WriteLine($"[D.5.1] empty digit array: {toolbarEmptyDigits?.Length ?? 0} entries.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1966,7 +1982,7 @@ public sealed class GameWindow : IDisposable
|
|||
{ 0x06001ACCu, 0x06001ACDu, 0x06001ACEu, 0x06001ACFu, 0x06001AD0u,
|
||||
0x06001AD1u, 0x06001AD2u, 0x06001AD3u, 0x06001AD4u };
|
||||
// Report the arrays actually used (after any fallback substitution).
|
||||
Console.WriteLine($"[D.5.1] toolbar digit arrays ready: peace={toolbarPeaceDigits.Length}, war={toolbarWarDigits.Length} entries.");
|
||||
Console.WriteLine($"[D.5.1] toolbar digit arrays ready: peace={toolbarPeaceDigits.Length}, war={toolbarWarDigits.Length}, empty={toolbarEmptyDigits?.Length ?? 0} entries.");
|
||||
|
||||
AcDream.App.UI.Layout.ImportedLayout? toolbarLayout;
|
||||
lock (_datLock)
|
||||
|
|
@ -1980,8 +1996,9 @@ public sealed class GameWindow : IDisposable
|
|||
iconIds: (type, icon, under, over) => iconComposer.GetIcon(type, icon, under, over),
|
||||
useItem: guid => UseItemByGuid(guid),
|
||||
combatState: Combat,
|
||||
peaceDigits: toolbarPeaceDigits,
|
||||
warDigits: toolbarWarDigits);
|
||||
peaceDigits: toolbarPeaceDigits,
|
||||
warDigits: toolbarWarDigits,
|
||||
emptyDigits: toolbarEmptyDigits);
|
||||
|
||||
var toolbarRoot = toolbarLayout.Root;
|
||||
toolbarRoot.Left = 10; toolbarRoot.Top = 300;
|
||||
|
|
@ -1993,6 +2010,25 @@ public sealed class GameWindow : IDisposable
|
|||
toolbarRoot.ClickThrough = false;
|
||||
toolbarRoot.Draggable = true;
|
||||
_uiHost.Root.AddChild(toolbarRoot);
|
||||
|
||||
// [D.5.1 PROBE] Bottom-right geometry rect dump — temporary diagnostic.
|
||||
// Localises the bottom-right mismatch reported by the user; remove once fixed.
|
||||
// ScreenPosition walks Parent chain (UiElement.cs:54-63); Left/Top are parent-relative.
|
||||
// IDs: root=0x10000191, backpack-btn=0x100001B1, backpack-drag=0x1000046C,
|
||||
// last top slot=0x100001AF, last bottom slot=0x100006BF,
|
||||
// row1 right-cap=0x100001B0, row2 right-cap=0x100006C0.
|
||||
{
|
||||
uint[] probeIds = { 0x10000191u, 0x100001B1u, 0x1000046Cu, 0x100001AFu, 0x100006BFu, 0x100001B0u, 0x100006C0u };
|
||||
foreach (var pid in probeIds)
|
||||
{
|
||||
var pe = toolbarLayout.FindElement(pid);
|
||||
if (pe is not null)
|
||||
Console.WriteLine($"[D.5.1 probe] 0x{pid:X8} ({pe.GetType().Name}): screen=({pe.ScreenPosition.X:F1},{pe.ScreenPosition.Y:F1}) left={pe.Left:F1} top={pe.Top:F1} w={pe.Width:F1} h={pe.Height:F1}");
|
||||
else
|
||||
Console.WriteLine($"[D.5.1 probe] 0x{pid:X8}: not found in layout");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("[D.5.1] retail toolbar window from LayoutDesc importer (0x21000016).");
|
||||
}
|
||||
else Console.WriteLine("[D.5.1] toolbar: LayoutDesc 0x21000016 not found.");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue