feat(ui): port retail appraisal panel

Preserve retail's one-pending-appraisal busy lifetime, parse the complete gated response, and mount the authored examination layout in the shared main-panel host. Keep known 3D preview and inscription-write gaps explicit in AP-110.
This commit is contained in:
Erik 2026-07-23 11:34:08 +02:00
parent 6b1ae4fb76
commit 643cdfe66e
24 changed files with 17132 additions and 40 deletions

View file

@ -1,9 +1,10 @@
# World interaction completion — pre-M4 program
**Status:** Slice 1 user-accepted 2026-07-23. Slice 2 Use-hand selection,
zero-useability, carried direct-use, and AutoWear correction passed their
connected gates. The requested shared item-cooldown follow-up is code-complete
and awaits its visual gate before Assess continues.
zero-useability, carried direct-use, AutoWear correction, and the requested
shared item-cooldown follow-up passed their connected gates. The existing
retail Assess command has been reconciled and Slice 3's examination panel is
code-complete; its connected visual gate is next.
**Milestone:** M4 prerequisite/preamble.
**Architecture:** retained gameplay UI over shared selection, object, and
interaction state. `GameWindow` remains a composition/callback shell.
@ -106,6 +107,26 @@ The focused parser/Core/UI/production-DAT tests, warning-free Release solution
build, 3,482 App tests / 3 skips, and 7,875 complete-solution tests / 5 skips
pass. AP-123 records only the retained toolkit's procedural-child adaptation;
the visible assets, ordering, timing, and shared-group behavior are exact.
The user accepted the live cooldown presentation 2026-07-23.
Slice 3 preserves the existing toolbar/keyboard Assess command and ports the
retail response owner around it. One shared UI-busy reference covers the
latest pending GUID, stale replies are rejected, the accepted reply becomes
the current appraisal, and combat-time creature/player refreshes occur every
0.75 seconds only while the examination window is visible. Complete
`IdentifyObjectResponse` parsing now includes the three-word HookProfile and
rejects truncated gated payloads rather than continuing from a corrupt cursor.
LayoutDesc `0x2100006B`, root `0x100005F2`, supplies the complete 310 x 400
floaty chrome, title, item/creature/character subviews, close control, and
authored scrollbars. The panel participates in the canonical one-active
main-panel geometry/lifecycle rather than owning a parallel location. Basic
item, creature, and player reports are live; exact 3D preview/specialized
detail regions, conditional inscription editing, and selection-follow remain
the narrowed AP-110 residual. Research:
[`../research/2026-07-23-retail-appraisal-ui-pseudocode.md`](../research/2026-07-23-retail-appraisal-ui-pseudocode.md).
The focused parser/router/request/controller/fixture tests pass, as do the
Release solution build with 17 pre-existing tracked test warnings, 3,488 App
tests / 3 skips, and 7,885 complete-solution tests / 5 skips.
## Slice 1 — spell-bar overflow arrows
@ -183,11 +204,40 @@ Named retail references and executable pseudocode are recorded in
request owner, and targeted items enter `UseItemOnTarget`, which already
owns the retail target cursor.
### Remaining Slice 2 work
### Slice 2 closeout
- Run the connected visual gate for the shared item cooldown: use Blackmoor's
Favor or a summon/stone and verify its inventory and shortcut aliases count
down together, then clear.
- Port the magnifying-glass Assess command state and activation.
- Continue directly into the Assess information slice after the combined
status-control gate.
- The shared item-cooldown visual gate passed.
- `gmToolbarUI::ListenToElementMessage @ 0x004BEE90` confirms the existing
magnifying-glass path was already correct: assess the selected GUID
immediately, otherwise enter one-shot Examine target mode.
- Slice 3 owns the response lifetime and retained examination presentation;
Slice 2 adds no duplicate command path.
## Slice 3 — assessment information panel
### Implemented ownership
1. `AppraiseInfoParser` owns the complete positional response payload,
including HookProfile and strict truncation failure.
2. `ItemInteractionController` owns the pending/current GUID pair and the
balanced shared busy reference.
3. `AppraisalUiController` owns response acceptance, item/creature/character
subview selection, report projection, scroll preservation, first-response
visibility, and visible-combat refresh.
4. `RetailUiRuntime` imports the retail layout and registers it with
`RetailPanelUiController`, so Inventory, Skills, Spellbook, effects, and
Examination remain views of the same movable/resizable main panel.
5. Network workers deliver immutable parsed data through the existing
session router; retained state changes remain on the update thread.
### Connected gate
- Select an item and click the magnifying glass (or press Assess): the shared
panel should show its name, available properties, descriptions,
inscription/signature, retail chrome, and working scrollbar.
- Assess a monster, NPC, and player: the correct creature/character page
should appear and the busy cursor should clear.
- In combat, leave a creature assessment open long enough to observe a health
refresh; closing it or opening another shared panel must stop refreshes.
- Move/resize Examination, switch to Inventory or Skills, and confirm the
shared rectangle is retained.