chore(D.5.1): remove temp geometry probe + add RestrictionDB-skip parse test
Task 1: remove the [D.5.1 PROBE] bottom-right rect-dump block from the toolbar mount in GameWindow.cs. The block iterated 7 element ids and logged ScreenPosition/Width/Height/Type; it was marked temporary and is now superseded by the chrome window-frame fix. The kept [D.5.1] startup diagnostic Console.WriteLines (digit arrays, toolbar ready, window from LayoutDesc) are untouched. Task 2: add TryParse_HouseRestrictionsSkipped_ThenIconOverlayCaptured to CreateObjectTests.cs. Exercises the variable-length RestrictionDB skip (weenieFlags bit 0x04000000: 12-byte fixed header + 4-byte hash-table header + count*8 entries) followed immediately by IconOverlay (0x40000000) and IconUnderlay (weenieFlags2 0x01 via IncludesSecondHeader 0x04000000). Proves the skip lands the cursor at the right position for both capture fields. 301/301 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ceef739e1d
commit
0e7a083da6
2 changed files with 37 additions and 18 deletions
|
|
@ -2039,24 +2039,6 @@ public sealed class GameWindow : IDisposable
|
||||||
toolbarFrame.AddChild(toolbarRoot);
|
toolbarFrame.AddChild(toolbarRoot);
|
||||||
_uiHost.Root.AddChild(toolbarFrame);
|
_uiHost.Root.AddChild(toolbarFrame);
|
||||||
|
|
||||||
// [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).");
|
Console.WriteLine("[D.5.1] retail toolbar window from LayoutDesc importer (0x21000016).");
|
||||||
}
|
}
|
||||||
else Console.WriteLine("[D.5.1] toolbar: LayoutDesc 0x21000016 not found.");
|
else Console.WriteLine("[D.5.1] toolbar: LayoutDesc 0x21000016 not found.");
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,43 @@ public sealed class CreateObjectTests
|
||||||
Assert.Equal(0x06002222u, parsed!.Value.IconOverlayId);
|
Assert.Equal(0x06002222u, parsed!.Value.IconOverlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TryParse_HouseRestrictionsSkipped_ThenIconOverlayCaptured()
|
||||||
|
{
|
||||||
|
// Verifies that the variable-length RestrictionDB skip (weenieFlags bit
|
||||||
|
// 0x04000000) lands the cursor at the correct position so that
|
||||||
|
// IconOverlay (bit 0x40000000) immediately after it is still captured.
|
||||||
|
//
|
||||||
|
// Wire layout per ACE RestrictionDB (16 bytes, zero entries):
|
||||||
|
// Version(u32) + OpenStatus(u32) + MonarchId(u32) = 12 bytes
|
||||||
|
// count(u16) + numBuckets(u16) = 4 bytes
|
||||||
|
// entries: count(0) × 8 = 0 bytes
|
||||||
|
// total = 16 bytes
|
||||||
|
//
|
||||||
|
// Also exercises the IncludesSecondHeader / IconUnderlay path so that
|
||||||
|
// all three optional-tail branches that follow HouseOwner are covered
|
||||||
|
// in a single cursor sweep.
|
||||||
|
//
|
||||||
|
// weenieFlags: 0x04000000 (HouseRestrictions) | 0x40000000 (IconOverlay)
|
||||||
|
// objectDescriptionFlags: 0x04000000 (IncludesSecondHeader → weenieFlags2 present)
|
||||||
|
// weenieFlags2: 0x00000001 (IconUnderlay)
|
||||||
|
byte[] body = BuildMinimalCreateObjectWithWeenieHeader(
|
||||||
|
guid: 0x5000000Eu,
|
||||||
|
name: "HousePortal",
|
||||||
|
itemType: (uint)ItemType.Portal,
|
||||||
|
objectDescriptionFlags: 0x04000000u, // IncludesSecondHeader
|
||||||
|
weenieFlags: 0x04000000u | 0x40000000u, // HouseRestrictions + IconOverlay
|
||||||
|
weenieFlags2: 0x00000001u, // IconUnderlay
|
||||||
|
iconOverlayId: 0x3333u, // → 0x06003333
|
||||||
|
iconUnderlayId: 0x4444u); // → 0x06004444
|
||||||
|
|
||||||
|
var parsed = CreateObject.TryParse(body);
|
||||||
|
|
||||||
|
Assert.NotNull(parsed);
|
||||||
|
Assert.Equal(0x06003333u, parsed!.Value.IconOverlayId);
|
||||||
|
Assert.Equal(0x06004444u, parsed.Value.IconUnderlayId);
|
||||||
|
}
|
||||||
|
|
||||||
private static byte[] BuildMinimalCreateObjectWithWeenieHeader(
|
private static byte[] BuildMinimalCreateObjectWithWeenieHeader(
|
||||||
uint guid,
|
uint guid,
|
||||||
string name,
|
string name,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue