feat(ui): complete retail cursor state machine

Port every reachable ClientUISystem cursor branch through the production DAT enum map, preserve global-default versus widget-local event ordering, and surface the registered OS fallback. Route all four toolbar stance indicators through the same combat toggle command as the key binding, with golden DAT and transition conformance coverage.

Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-11 08:31:40 +02:00
parent 05f6222865
commit 6fcc510d5d
16 changed files with 535 additions and 164 deletions

View file

@ -403,18 +403,39 @@ slot view. Full suite green at the final gate: 4,583 passed, 5 skipped.
### 3.4 Complete retail cursor precedence and catalog
- [ ] Port every reachable branch of `ClientUISystem::UpdateCursorState`, not only
- [x] Port every reachable branch of `ClientUISystem::UpdateCursorState`, not only
target enums `0x27/28/29`.
- [ ] Separate global world-interaction cursors from widget-local cursor media;
apply retail precedence so a slot hover cannot replace the global target bullseye.
- [ ] Cover default/combat/use/examine/busy, drag accept/reject, resize/move/text,
and target states with golden EnumIDMap tests.
- [ ] Keep OS cursor fallback only as an explicit registered adaptation with a
- [x] Separate global world-interaction cursors from widget-local cursor media;
preserve retail's event order: a global state change reasserts the default,
while a later captured/hovered widget cursor transition may override it.
- [x] Cover default/combat/use/examine/busy/target states with golden EnumIDMap
tests, and cover drag accept/reject, resize/move/text as widget-local semantic
states without inventing global enum meanings for unreachable `0x07..0x09`.
- [x] Keep OS cursor fallback only as an explicit registered adaptation with a
visible diagnostic.
**Implementation (2026-07-11):** `RetailGlobalCursorKind` now models all 15
reachable enum branches from `ClientUISystem::UpdateCursorState @ 0x00564630`.
Production DAT fixtures pin `0x01..0x06`, `0x0A..0x0F`, and `0x27..0x29` to
their exact RenderSurface DIDs. `CursorFeedbackController` owns the pure global
decision tree and reports only the active captured/hovered widget cursor;
`RetailCursorManager` applies global-change then widget-change transitions in
the same default/local layering used by `UIElementManager::CheckCursor @
0x0045ABF0`. The old semantic-state alias search (`TargetValid` borrowing
`Drag_rollover_accept`, etc.) is removed. AP-100 is retired; AP-72 remains the
single explicit DAT-failure adaptation and now emits one visible diagnostic per
failed global kind.
**Gate:** live use/drop/target matrix with retail cursor art and selection updates;
no click path bypasses the router; full suite and user visual gate.
**Acceptance (2026-07-11):** User-confirmed the complete non-debug Release
cursor matrix. A follow-up gate exposed that the four stance indicators were
display-only; wiring their exact retail click branch passed immediately. Mouse
click and quick key now both toggle peace/combat, update the visible indicator,
and drive the corresponding DAT cursor state. Final suite: 4,618 passed, 5
skipped.
---
## 7. Wave 4 -- toolbar and selected-object completion
@ -465,6 +486,14 @@ no click path bypasses the router; full suite and user visual gate.
- [ ] Add item-mana query/cancel state, health query cancellation, and one shared
split-quantity owner for the entry, slider, and item drag payload.
**Partial implementation (2026-07-11):** the four stance-specific combat
indicator buttons `0x10000192..0x10000195` now all dispatch one injected combat
toggle command. The key binding and retained toolbar therefore converge on
`GameWindow.ToggleLiveCombatMode`, matching `gmToolbarUI::ListenToElementMessage
@ 0x004BEE90`; the visible indicator continues to update from authoritative
`CombatState`. Use, Examine, remaining panel buttons, quick slots, and selected
object residuals remain in this wave.
**Oracles:** `gmToolbarUI @ 0x004BD0C0..0x004BF380`,
`UIElement_UIItem::SetShortcutNum`, shortcut wire builders.