using System; using System.IO; using AcDream.App.UI.Layout; using DatReaderWriter; using DatReaderWriter.Options; using Xunit; using Xunit.Abstractions; namespace AcDream.App.Tests.UI.Layout; /// /// Real-dat test for : the inventory /// item-lists must resolve their empty-slot sprite from the dat cell template (attribute /// 0x1000000e -> catalog 0x21000037 prototype's ItemSlot_Empty), NOT the generic toolbar /// square 0x060074CF. Also PRINTS the resolved ids — the "pin the exact asset" record. /// Skips when the live dat directory is absent (CI). /// public class ItemListCellTemplateTests { private const uint Generic = 0x060074CFu; // generic toolbar-shortcut empty square (the bug) private const uint ContentsLayout = 0x21000021u; private const uint ContentsGrid = 0x100001C6u; private const uint BackpackLayout = 0x21000022u; private const uint SideBag = 0x100001CAu; private const uint MainPack = 0x100001C9u; private readonly ITestOutputHelper _out; public ItemListCellTemplateTests(ITestOutputHelper o) => _out = o; private static string? DatDir() { var d = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Documents", "Asheron's Call"); return Directory.Exists(d) ? d : null; } [Fact] public void Inventory_lists_resolve_a_real_nongeneric_empty_sprite() { var datDir = DatDir(); if (datDir is null) return; // CI: no live dat — skip (smoke test) using var dats = new DatCollection(datDir, DatAccessType.Read); foreach (var (name, layout, elem) in new[] { ("contents", ContentsLayout, ContentsGrid), ("side-bag", BackpackLayout, SideBag), ("main-pack", BackpackLayout, MainPack), }) { uint sprite = ItemListCellTemplate.ResolveEmptySprite(dats, layout, elem); _out.WriteLine($"{name}: list 0x{elem:X8} (layout 0x{layout:X8}) -> empty sprite 0x{sprite:X8}"); Assert.True(sprite != 0u, $"{name}: resolved 0 (no 0x1000000e attr / prototype / media)"); Assert.True(sprite != Generic, $"{name}: resolved the generic 0x060074CF — the bug, not the fix"); Assert.True((sprite & 0xFF000000u) == 0x06000000u, $"{name}: 0x{sprite:X8} is not a 0x06 RenderSurface id"); } } [Fact] public void Inventory_lists_resolve_the_pinned_retail_sprites() { var datDir = DatDir(); if (datDir is null) return; // CI: no live dat — skip using var dats = new DatCollection(datDir, DatAccessType.Read); // Pinned from the live dat + the 2026-06-22 visual gate. Contents = the 32x32 prototype's // ItemSlot_Empty; the 36x36 container/main-pack resolve THROUGH inheritance to their inner // ItemSlot_Empty (NOT the 0x06005D9C open-container triangle the first cut grabbed — a // structural-only assertion let that wrong-but-valid 0x06 sprite pass, so we pin exacts). Assert.Equal(0x06004D20u, ItemListCellTemplate.ResolveEmptySprite(dats, ContentsLayout, ContentsGrid)); Assert.Equal(0x06000F6Eu, ItemListCellTemplate.ResolveEmptySprite(dats, BackpackLayout, SideBag)); Assert.Equal(0x06000F6Eu, ItemListCellTemplate.ResolveEmptySprite(dats, BackpackLayout, MainPack)); } }