Commit graph

181 commits

Author SHA1 Message Date
Erik
5a45a7ac7f feat(chat): route retail lifestone commands
Separate retail client actions, ACE server commands, and ordinary chat at the shared router. Port lifestone/lif/ls from the named retail registry through a typed App controller to game action 0x0063, keep unknown verbs on ACE Talk, and cover both UI backends plus exact outbound bytes.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 11:43:19 +02:00
Erik
5090aa7217 fix #212: preserve shortcut tint in physical combat
Port the retail m_bShortcutGhosted meaning instead of treating SetShortcutNum's boolean as peace versus war. Keep occupied shortcut numbers on the gold sheet in NonCombat, Melee, and Missile, reserve the gray sheet for Magic, and lock the four-mode matrix with conformance tests and corrected research.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 11:21:12 +02:00
Erik
e74efc5c06 fix #210: stabilize mouse-up capture ownership
Pin each mouse-up to its original captured target before callbacks can hide a window or transfer capture. Classify double-clicks before dispatch, preserve replacement capture owners, and cover both re-entrant paths so jump/combat visibility changes cannot crash the UI root.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 10:27:27 +02:00
Erik
db03b4bda8 feat(ui): port retail jump power bar
Import gmFloatyPowerBarUI LayoutDesc 0x21000072, teach the meter factory its stateful single-image shape, and project the movement-owned retail jump charge through a focused retained controller. Preserve authored resize constraints and state-managed visibility, with named-decomp pseudocode plus controller, movement, and production-DAT conformance coverage.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 10:22:12 +02:00
Erik
edc9be3008 fix(paperdoll): port quest-gated Aetheria slots
Add the three authored blue, yellow, and red sigil backgrounds and drive their visibility from player PropertyInt.AetheriaBitfield bits 1/2/4 at login and on live updates, matching gmPaperDollUI::UpdateAetheria. Include the sigil equip masks in the shared slot table and narrow AP-108.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:55:20 +02:00
Erik
1be18cc4db fix(paperdoll): restore authored slot backgrounds
Port the retail UIItem catalog path so every supported equipment location resolves its exact empty-state silhouette from live DAT. Share one definition table between equip behavior and presentation, wire runtime plus UI Studio, pin all 21 prototypes and surfaces, and retire AP-66.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:43:21 +02:00
Erik
609ed8bfc2 fix(ui): select items before drag mesh
Port ItemList_BeginDrag's select-before-waiting order so a direct press-drag shows the selection indicator on its first frame across inventory, paperdoll, and toolbar item lists.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:28:28 +02:00
Erik
64a056e656 fix(inventory): correct drag overlay priority
Keep the persistent selection indicator above retail's waiting mesh, use the normal green accept circle for backpack-grid placement, and reserve the green drop-in arrow for bag-column containers as ItemList_DragOver does.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:21:22 +02:00
Erik
ace5880fed fix(ui): port retail item drag visuals
Keep retail's underlay-free m_pDragIcon separate from the full cell icon and reveal the authored ghost mesh on physical source cells for the complete drag lifecycle. This removes the backpack backing from the cursor and retires AP-47.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:14:24 +02:00
Erik
3e84027885 fix(inventory): complete switches on wield response
Clear retail AutoWield on the matching authoritative WieldObject instead of waiting for unrelated rollback bookkeeping to drain. This prevents a completed switch from consuming the next weapon activation locally, including crossbows.

Co-Authored-By: Codex <codex@openai.com>
2026-07-13 09:00:54 +02:00
Erik
ea5cf5b842 fix(inventory): await final wield confirmation
Keep the retail inventory transaction busy until authoritative WieldObject confirms the requested weapon. This prevents rapid weapon changes from overlapping on ACE and rejecting otherwise valid items such as spears.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 23:27:44 +02:00
Erik
815ce0dec4 fix(inventory): sequence secondary wield blockers
Preserve retail AmmoType from CreateObject and port BlocksUseOfShield so bow, caster, and two-handed switches remove incompatible shields, while mismatched missile ammo is also returned to the pack. Each blocker remains server-confirmed before AutoWield re-enters.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 23:12:07 +02:00
Erik
17b5712d53 feat(inventory): port retail weapon switching
Sequence primary weapon replacement through the server-confirmed AutoWield transaction: return the occupied weapon to the player pack, wait for its move event, then wield the requested item. Route authoritative CombatMode property updates so peace stays peace and war adopts the new weapon stance without client-synthesized animation.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 23:06:31 +02:00
Erik
8e9c538519 fix #208: keep combat bar hidden in peace mode
Treat combat-window visibility as gameplay-state owned so character layout restoration cannot replay a stale visible bit. Reset combat state to NonCombat at character-session entry, matching retail ClientCombatSystem::Begin.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 22:30:55 +02:00
Erik
e671b8a5c4 fix(combat): preserve authored meter child geometry
Carry the consumed dark-range child's own retail edge policy into the procedural scrollbar, widening it to the authored post-reflow interval without covering the rendered labels. Restore the bright layer to live attack-charge feedback across the full bar from the left.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 21:57:53 +02:00
Erik
f8c174d707 fix(combat): resolve power spans after layout
Derive the dark middle range from live post-anchor sibling geometry instead of freezing the inherited 800-pixel prototype during controller binding. Render the user-directed bright desired-power band independently from the absolute bar-left edge to the green thumb center.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 21:49:17 +02:00
Erik
707add8539 fix(combat): charge power bar from speed
Read the authored meter direction instead of inferring it from the combat element id, so the bright charge texture grows left-to-right from Speed. Keep the user-approved dark-red middle baseline visible independently and record its exact retail Recklessness visibility edge.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 21:25:24 +02:00
Erik
256c1930bd fix(combat): restore retail power bar layers
Preserve the authored gray track, trained-Recklessness range, live bright charge meter, and independent desired-power thumb while keeping Speed and Power over gray side regions. Correct retail text justification value 2 to left alignment and retain direct RenderSurface decoding in the texture inspection tool used to verify the assets.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 21:14:14 +02:00
Erik
0f2d98c501 fix(combat): synchronize auto-target presentation
Make the retained toolbar consume retail's payload-free selection notice from canonical live state so a reentrant Auto Target replacement cannot be erased by the outer clear. Restrict automatic acquisition to the requested hostile non-player monster policy and record the intentional PK edge divergence.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 20:26:00 +02:00
Erik
5276a83087 fix(combat): match retail live attack feedback
Keep AttackDone control statuses out of chat, preserve dead motion across zero-velocity position updates, render the authored power meter from right to left, and retain the rotatable viewer offset during target tracking.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 21:10:01 +02:00
Erik
927fa7881a fix(combat): restore retail combat bar controls
Resolve authored StringInfo labels from local.dat, port gmCombatUI's runtime option captions and checkbox widgets, and bind horizontal scrollbar media by retail structural roles so the green power jewel is a thumb instead of a tiled track. Persist the three combat options and make Auto Target govern target acquisition.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 20:26:52 +02:00
Erik
2215c76c7e feat(combat): port retail basic combat bar
Mount authored gmCombatUI, share one press/hold/release request state machine across DAT buttons and keybindings, and recover the exact 1.0s/0.8s power timing from matching retail x86. The same timer fixes jump charge, while ready-stance, response queueing, auto-repeat, layout binding, migration, and conformance coverage keep behavior architectural rather than panel-local.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 14:03:28 +02:00
Erik
564d39dfea feat(ui): port retail toolbar ammo count
Resolve stacked thrown weapons versus separately equipped missile ammo exactly like gmToolbarUI, normalize a zero stack to one, and refresh the authored missile indicator from equipment and stack events. Keep the decision in pure Core with retained and real-DAT conformance coverage.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 12:29:51 +02:00
Erik
d3d1c895a0 feat(ui): finish retail toolbar controls
Discover all seven panel launchers from their DAT panel-id attributes, route mounted panels through event-driven retained window state, and ghost unavailable panels. Port Use and Examine selection/target behavior with exact Appraise dispatch and retail cursor modes.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 12:11:53 +02:00
Erik
0b74d19475 fix(ui): port exact paperdoll body selection
Resolve and sample retail's authored nine-color paperdoll click map, preserve local click coordinates, and select the stable highest-priority worn item with the player fallback. Keep targeted-use body clicks routed to self and pin both synthetic and live-DAT conformance.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 11:56:26 +02:00
Erik
fa1da02783 feat(ui): port retail selected-item mana
Parse and route the complete 0x0264 guid/fraction/valid response, send exact 0x0263 item-mana queries, and reproduce retail meter visibility plus guid-zero cancellation for mana and health selection changes. Keep the behavior in Core state and the retained selected-object controller with wire/state/UI conformance coverage.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 11:16:21 +02:00
Erik
15aa3b9aff fix(ui): complete retail inventory scroll polish
Preserve pixel scroll offsets across inventory rebuilds, crop partially visible rows with nested geometry/UV clips, and replace the obsolete 560px resize ceiling with available screen height. Keep retail's row-sized wheel step while allowing continuous scrollbar thumb positions.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 10:56:33 +02:00
Erik
ea72c395c9 fix(ui): port retail partial stack transfers
Route the selected stack quantity through retail GetObjectSplitSize semantics, send exact split-to-container and split-to-ground actions, and keep the original object in place until the server publishes the newly guided stack. Cover selection scoping, wire bytes, container placement, and world drops with conformance tests.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 10:34:13 +02:00
Erik
6005c51c4d fix(ui): finish retail stack selector polish
Keep the horizontal thumb at its raw pointer position so both endpoints are reachable, honor the stack entry's authored right alignment, and preserve PublicWeenieDesc plural names from CreateObject through the object table. Port retail's singular s/es fallback when no plural was sent.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 10:22:11 +02:00
Erik
a20e5c68c7 feat(ui): port retail selected-stack quantity
Bind the authored stack count entry and horizontal slider to one Core split-quantity owner, preserve retail count-first naming and exact 1000-step rounding, refresh on stack changes, and consume the selected amount during merges. Conformance covers the production DAT fixture and retained pointer/focus paths.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 10:07:25 +02:00
Erik
dc1649c493 feat(ui): complete retail item drop branches
Give retained buttons a reusable item-drop seam, wire the toolbar backpack target, and port retail stack-merge legality, capacity clamping, wire dispatch, destination selection, and immediate shortcut rekey notice. Record the live ACE merge gate and keep split quantity under AP-101.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 09:46:32 +02:00
Erik
3281e0acb4 fix(ui): port source-aware toolbar drops
Plan retail shortcut drops from a complete post-lift snapshot so fresh inventory items use cyclic-right displacement while toolbar aliases restore to their vacated slot. Apply local mutations atomically, preserve raw shortcut fields, emit exact Remove/Add ordering, and retire AP-102 after the live ACE gate.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 09:26:57 +02:00
Erik
b5b230c860 feat(ui): preserve exact retail shortcut records
Carry signed index, object id, and raw spell word losslessly through PlayerDescription, session storage, drag mutation, and AddShortcut wire serialization while keeping gmToolbarUI object-only. Retire AP-103 and record the live ACE relog persistence gate.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 09:17:33 +02:00
Erik
e65119f0c6 feat(ui): complete retail quick-slot input
Port global toolbar use/select/create actions, migrate the collapsed Ctrl-number bindings, and route them through a focused retained-UI controller. Preserve shortcut aliases as aliases across inventory and paperdoll drops with retail's neutral/accept/reject drag states, preventing physical item moves such as unwielding an equipped helmet.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 08:59:49 +02:00
Erik
6fcc510d5d 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>
2026-07-11 08:31:40 +02:00
Erik
05f6222865 fix(ui): complete live targeted healing flow
Route ACE server commands through the existing chat path, bind the retail paperdoll hit mask instead of its obscured viewport, and prefer authoritative private health vitals. Record the user-confirmed live gate and pin the production DAT widget type in tests.
2026-07-11 07:58:59 +02:00
Erik
eb6229394a fix(ui): unify target-mode primary clicks 2026-07-11 01:36:43 +02:00
Erik
a8da4fd05a feat(ui): port retail item interaction policy 2026-07-11 01:26:14 +02:00
Erik
7983309d23 feat(ui): centralize retail selection state 2026-07-11 00:51:20 +02:00
Erik
5d9e98c118 refactor(ui): own retained controller lifetimes 2026-07-10 23:35:26 +02:00
Erik
921c388e2c feat(ui): persist retained window layouts 2026-07-10 23:17:29 +02:00
Erik
a8e9503d2e feat(ui): unify retained window mounts 2026-07-10 22:22:25 +02:00
Erik
6e9e10367f feat(ui): centralize retained window lifecycle 2026-07-10 21:31:18 +02:00
Erik
4bb37e302e fix(ui): bind visible skills scrollbar 2026-07-10 18:29:55 +02:00
Erik
f684f874df fix(ui): retain character sublayout reflow 2026-07-10 18:20:11 +02:00
Erik
accacecafe fix(ui): preserve cropped chat and button faces 2026-07-10 18:11:14 +02:00
Erik
d825572e31 feat(ui): port retained widget foundations 2026-07-10 17:55:41 +02:00
Erik
3cbe4b00a1 feat(ui): port retail radar and compass 2026-07-10 16:14:37 +02:00
Erik
769ebef30d fix(ui): retail target-cursor shape (pending over UI, world-object driven) + visible UseDone refusals
Visual gate round 2 (user, retail oracle): the target cursor over UI must
be the 0x27 four-arrows PENDING cursor — retail's UpdateCursorState
(0x00564630) keys valid/invalid solely off the SmartBox found object,
i.e. the WORLD entity under the cursor. And "can't heal myself" turned
out to be TWO stacked causes, both fixed:

- Cursor: UI hover no longer forces TargetInvalid (that arm was a
  non-retail invention) and the doll/status-bar hover providers are
  gone (UiElement.UseTargetGuidProvider deleted). Valid/invalid now
  come from (a) a hovered occupied item slot's own item, or (b) the
  world entity under the cursor via a new worldTargetProvider — the
  B.4b screen-rect picker extracted into GameWindow.PickWorldGuidAtCursor
  and shared by click + hover.
- Self-heal: the world picker always skipped the local player
  (skipServerGuid), so clicking your own toon in target mode could
  never acquire self. Target-use picks now include self (retail lets
  you kit-heal yourself by clicking your character); plain selection
  keeps the exclusion. The doll click still self-targets.
- Silent refusals: the [use-target] log proved the UseWithTarget action
  WAS sent (kit 0x00220008 / TargetType 0x10, target self) — ACE
  refused with WeenieError.YouArentTrainedInHealing (0x04FC) and we
  never parsed UseDone (0x01C7). Now dispatched + surfaced as a chat
  line via WeenieErrorText (interim subset map, register AP-74, #166
  ports the retail String-table lookup).

Full suite green (3,295).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:27:33 +02:00
Erik
047410ccc9 fix(ui): retail-faithful use-target compat gate + paperdoll doll self-target
Visual gate on the item-interaction slice found two target-use bugs:
the valid-target bullseye showed over inventory ITEMS (a coat is not a
valid healing-kit target) while the paperdoll doll showed blocked (it
should mean SELF).

- TargetCompatible is now a faithful port of
  ItemHolder::IsTargetCompatibleWithTargetingObject (0x00588070):
  a location constraint applies only when the least-limited target-use
  bit (ItemUses::GetLeastLimitedTargetUse 0x004fcd50, new
  ItemUseability.LeastLimitedTargetUse) is Contained/Wielded; the
  player as target requires the Self bit (IsUseable_SelfTarget
  0x004fcd30); and EVERY target passes retail's kind gate
  source._targetType & target->InqType(). The previous hand-rolled
  arms (Remote => accept anything, invented Viewed/Contained accepts,
  self path skipping the kind gate) were the yellow-over-items bug.
  Retail's tradeState refusal is skipped (no trade state yet).
- The paperdoll doll viewport now carries UseTargetGuidProvider =
  player and Clicked -> AcquireSelfTarget (UiViewport gains an opt-in
  Clicked handler), so hovering the doll resolves the self cursor and
  clicking it applies the armed kit to yourself.
- AcquireTarget logs one [use-target] line (wire useability, TargetType
  mask, target kind, decision) so live refusals are diagnosable from
  the launch log.
- Test fixtures updated from the guessed kit useability 0x000A0008 to
  the real USEABLE_SOURCE_CONTAINED_TARGET_REMOTE_OR_SELF (0x00220008,
  ACE Usable.SourceContainedTargetRemoteOrSelf) + TargetType masks;
  new coverage pins the kind gate, the Self-bit requirement, the
  missing-mask-matches-nothing shape, and the Contained location rule.

Full suite green (3,294).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:09:13 +02:00