docs(D.5.2): retire IA-16, add IA-18/AP-43..45, roadmap + memory

Divergence register:
- Retire IA-16 (item-icon composite PARTIAL — D.5.2 now complete).
- Add IA-18 (effect overlay = ReplaceColor tint SOURCE, faithful retail
  behavior; anti-regression guard — do NOT re-implement as a blit layer;
  cites IconData::RenderIcons 0x0058d180 + ReplaceColor 0x00441530).
- Add AP-43 (effect tint = mean-opaque color; exact retail byte
  decompiler-ambiguous, visual/cdb confirmation pending).
- Add AP-44 (effects==0 black-fallback recolor skipped; regression-risk
  avoidance, pending visual/cdb confirm).
- Add AP-45 (0x02CE sequence byte not honored, latest-wins).
Section header counts updated: IA 15→17, AP 41→44.

Roadmap: mark D.5.2 shipped (419c3ac..2f789da; appraise dropped as no-op;
effect recolor + live 0x02CE).

Tests: update ToolbarControllerTests iconIds lambda arity 4→5 to match the
D.5.2 GetIcon signature change (was caught by the build).

Memory: project_d2b_retail_ui.md updated with D.5.2 shipped entry
(via claude-memory symlink to ~/.claude/projects/.../memory/).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-17 18:52:15 +02:00
parent 2f789da73d
commit 73adc3768c
3 changed files with 19 additions and 16 deletions

View file

@ -53,7 +53,7 @@ public class ToolbarControllerTests
{ new(Index: 0, ObjectGuid: 0x5001u, SpellId: 0, Layer: 0) };
ToolbarController.Bind(layout, repo, () => shortcuts,
iconIds: (_,_,_,_) => 0x77u, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0x77u, useItem: _ => { });
Assert.Equal(0x5001u, slots[Row1[0]].Cell.ItemId);
Assert.Equal(0x77u, slots[Row1[0]].Cell.IconTexture);
@ -69,7 +69,7 @@ public class ToolbarControllerTests
{ new(Index: 2, ObjectGuid: 0x5002u, SpellId: 0, Layer: 0) };
ToolbarController.Bind(layout, repo, () => shortcuts,
iconIds: (_,_,_,_) => 0x88u, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0x88u, useItem: _ => { });
Assert.Equal(0u, slots[Row1[2]].Cell.ItemId); // not bound yet
repo.AddOrUpdate(new ItemInstance { ObjectId = 0x5002u, WeenieClassId = 1u, IconId = 0x06005678u });
@ -88,7 +88,7 @@ public class ToolbarControllerTests
uint used = 0;
ToolbarController.Bind(layout, repo, () => shortcuts,
iconIds: (_,_,_,_) => 0x77u, useItem: g => used = g);
iconIds: (_,_,_,_,_) => 0x77u, useItem: g => used = g);
// UiEvent is a positional record struct: (SourceId, Target, Type, Data0..3, Payload)
slots[Row1[0]].Cell.OnEvent(new UiEvent(0u, null, UiEventType.MouseDown));
@ -110,7 +110,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) =>0u, useItem: _ => { });
iconIds: (_,_,_,_,_) =>0u, useItem: _ => { });
// Only peace indicator (index 0 = 0x10000192) is visible.
Assert.True (indicators[0x10000192u].Visible, "peace indicator should be visible after bind");
@ -130,7 +130,7 @@ public class ToolbarControllerTests
var ctrl = ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) =>0u, useItem: _ => { });
iconIds: (_,_,_,_,_) =>0u, useItem: _ => { });
ctrl.SetCombatMode(CombatMode.Melee);
@ -152,7 +152,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) =>0u, useItem: _ => { },
iconIds: (_,_,_,_,_) =>0u, useItem: _ => { },
combatState: combat);
// Initially NonCombat after bind.
@ -191,7 +191,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) => 0u, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
peaceDigits: FakePeace, warDigits: FakeWar);
// Top row: ShortcutNum == slot index, peace == true.
@ -216,7 +216,7 @@ public class ToolbarControllerTests
var repo = new ItemRepository();
var ctrl = ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) => 0u, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
peaceDigits: FakePeace, warDigits: FakeWar);
ctrl.SetCombatMode(CombatMode.Melee);
@ -243,7 +243,7 @@ public class ToolbarControllerTests
var repo = new ItemRepository();
var ctrl = ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) => 0u, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
peaceDigits: FakePeace, warDigits: FakeWar);
ctrl.SetCombatMode(CombatMode.Melee);
@ -265,7 +265,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) => 0u, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
peaceDigits: FakePeace, warDigits: FakeWar);
foreach (var id in Row1)
@ -287,7 +287,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) => 0u, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
peaceDigits: FakePeace, warDigits: FakeWar, emptyDigits: FakeEmpty);
foreach (var id in Row1)
@ -308,7 +308,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
() => Array.Empty<PlayerDescriptionParser.ShortcutEntry>(),
iconIds: (_,_,_,_) => 0u, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
peaceDigits: FakePeace, warDigits: FakeWar, emptyDigits: null);
foreach (var id in Row1)