fix(ui): select and examine favorite spells like retail
This commit is contained in:
parent
043ab10b3c
commit
3e31b0ac70
23 changed files with 974 additions and 34 deletions
|
|
@ -158,6 +158,14 @@ three-pixel drag threshold. Target mode is intercepted at that same press.
|
|||
Bag opening, item use/equip, and shortcut activation remain completed
|
||||
click/double-click actions, so a drag or target-consumed press cannot also
|
||||
activate the item.
|
||||
The corresponding favorite-spell branch is now ported without conflating a
|
||||
spell ID with a physical object GUID. Favorite selection occurs on left press;
|
||||
right-click opens the authored local Spell examination subview with
|
||||
name, school, mana, duration, range, description, and the current appropriate
|
||||
component formula. It sends no Appraise request and takes no busy reference,
|
||||
so the status-bar magnifier remains object-only. Switching the shared floaty
|
||||
from a pending object appraisal to a spell releases exactly that appraisal
|
||||
transaction before showing the SpellPanel.
|
||||
|
||||
**Files:** `src/AcDream.Core.Net/Messages/AppraiseInfoParser.cs`;
|
||||
`src/AcDream.App/UI/RetailUiRuntime.cs`;
|
||||
|
|
@ -185,6 +193,9 @@ Right-clicking an occupied retained item cell selects and examines it without
|
|||
using, equipping, looting, or dragging it.
|
||||
Left-pressing one selects it before the button is released; holding and
|
||||
dragging preserves that selection without activating the item.
|
||||
Left-pressing a favorite spell likewise changes its selection immediately.
|
||||
Right-clicking it opens the spell examination subview; selecting it and using
|
||||
the status-bar magnifier does not examine the spell.
|
||||
The Black Phyntos Hive specifically reads `Value: ???`, `Burden: Unknown`,
|
||||
then its description after one retail paragraph break, without the bogus
|
||||
255-item/255-container line.
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ AP-94..AP-112 for the confirmed retail-UI completion gaps.
|
|||
| ~~AP-107~~ | **RETIRED 2026-07-11 (Wave 3.3 / #197)** — typed `OfferPrimaryClick` returns `NotActive`, `ConsumedSuccess`, or `ConsumedRejected`; every retained item surface plus radar/world offers active target mode before local selection/open/use fallback. Rejections are consumed and cannot drift selection. | `src/AcDream.App/UI/ItemInteractionController.cs`; inventory/paperdoll/toolbar/radar/world call sites | — | — | `UIElement_ItemList::HandleTargetedUseLeftClick @ 0x004E24D0` |
|
||||
| AP-108 | Paperdoll/AutoWield still omit the remaining missile/held restrictions and corrupt-mask branch of full `AutoWieldIsLegal`, dual-wield/off-hand rules, double-click examine/drag from the doll, body-part selection lighting, and retail's synchronous `" - cannot unwield the %s"` failure suffix (the current send seam reports rejection asynchronously). **AutoWear legality retired from this row 2026-07-23:** inventory activation and paperdoll drops now apply the retail clothing-priority/location blocker lookup and exact `"You must remove your %s to wear that"` system notice. **Primary replacement retired 2026-07-14; Aetheria retired 2026-07-13.** | `src/AcDream.App/UI/Layout/PaperdollController.cs`; `src/AcDream.App/UI/AutoWieldController.cs` | Basic equip slots, Aetheria, live doll, AutoWear conflict reporting, and primary weapon/incompatible shield/mismatched ammo blocker sequencing work in peace and war | Remaining illegal/off-hand cases, asynchronous dequip rejection wording, doll examine/drag, and selection lighting still differ functionally | `CPlayerSystem::AutoWieldIsLegal @ 0x0055ED60`; `CPlayerSystem::AutoWearIsLegal @ 0x0055EF40`; `CPlayerSystem::AutoWield @ 0x00560A60`; `gmPaperDollUI @ 0x004A3590..0x004A5F90` |
|
||||
| AP-109 | Character Titles page is inert and live displayed-title/luminance state is absent | `src/AcDream.App/UI/Layout/CharacterStatController.cs`; `CharacterSheetProvider.cs` | Attributes/skills core output is user-accepted | Titles cannot be selected/displayed and level-200 luminance fields are missing | `gmCharacterTitleUI @ 0x0049A610`; `gmStatManagementUI::UpdateExperience @ 0x004F0A70` |
|
||||
| AP-110 | Remaining retained gameplay panels and world HUD are absent: advanced-combat powerbar, residual social/floating chat, quests/map/options/smartbox, vendor/trade/salvage/tinkering, mini-game gameplay, Link Status NAK/retransmission packet-loss averaging, and D.6 nameplates/floaters. Examination has its independent authored floaty layout, inscription transaction, retail creature stat/rating/animated-preview presentation, default selection-follow, and the full EoR item-report dispatch: appraisal-only unknowns; exact equipment-set/rating/tinkering/weapon/armor/caster/requirement/XP/healer/rare prose and intentional blank section rows; ordinary/enchantment DAT spell descriptions; live material-decorated appropriate titles plus DAT material and creature names; expiry, decorated material/gem descriptions; and portal/PK restrictions with authored item colors. It still lacks item-object preview, player-dependent effective shield projection, live cooldown-remaining projection, localized augmentation-cost `StringInfo`, exhaustive character detail regions, and exact creature appraisal FontInfo-list selection. | `src/AcDream.App/UI/RetailUiRuntime.cs`; `src/AcDream.App/UI/Layout/AppraisalUiController.cs`; `src/AcDream.App/UI/Layout/ItemAppraisalTextFormatter.cs`; `src/AcDream.App/UI/Layout/RetailAppraisalNameResolver.cs`; `src/AcDream.App/UI/Layout/CreatureAppraisalRows.cs`; `src/AcDream.App/Rendering/CreatureAppraisalPresentation.cs`; `src/AcDream.Core.Net/LinkStatusSnapshot.cs`; D.5/D.6 roadmap | Basic combat, M3 magic/Link/Vitae surfaces, and the core examination request/presentation/inscription/creature-preview/item-report loop cover the active loops; the residual examination mechanisms require live player/enchantment/localization state or object-preview ownership rather than fabricated content | Item assessments omit only the listed live/localized/preview projections; enchanted/incomplete creature appraisal rows use the normal authored font until the exact FontInfo list is bound; other absent panels remain unavailable; real packet loss is displayed as 0.00% instead of retail's moving average | `BasicCreatureExamineUI::Init @ 0x004AB9C0`; `CreatureExamineUI::SetAppraiseInfo @ 0x004B3FF0`; `gmExaminationUI::RecvNotice_SelectionChanged @ 0x004AB3D0`; `AttributeInfoRegion::Update @ 0x004F1D90`; `gmExaminationUI::SetAppraiseInfo @ 0x004ADAE0`; `ACCWeenieObject::GetObjectName @ 0x0058E6E0`; `ItemExamineUI::SetAppraiseInfo @ 0x004B72B0`; `ItemExamineUI::AddItemInfo @ 0x004AC050`; `ItemExamineUI::Appraisal_ShowCapacity @ 0x004B2680`; `ItemExamineUI::Appraisal_ShowSpecialProperties @ 0x004B0140`; `ItemExamineUI::Appraisal_ShowWeaponAndArmorData @ 0x004B10E0`; `ItemExamineUI::Appraisal_ShowMagicInfo @ 0x004B2E10`; `ItemExamineUI::Appraisal_ShowDescription @ 0x004B6990`; `MaterialTypeEnumMapper::MaterialTypeToString @ 0x005CD500`; `ItemExamineUI::SetInscription @ 0x004AE2F0`; `CM_Writing::Event_SetInscription @ 0x006A98B0`; `CLinkStatusAverages::GetAveragePacketLoss @ 0x00546610`; LayoutDesc catalog |
|
||||
| AP-110 | Remaining retained gameplay panels and world HUD are absent: advanced-combat powerbar, residual social/floating chat, quests/map/options/smartbox, vendor/trade/salvage/tinkering, mini-game gameplay, Link Status NAK/retransmission packet-loss averaging, and D.6 nameplates/floaters. Examination has its independent authored floaty layout, inscription transaction, retail creature stat/rating/animated-preview presentation, default selection-follow, authored local spell subview with appropriate-formula component state, and the full EoR item-report dispatch: appraisal-only unknowns; exact equipment-set/rating/tinkering/weapon/armor/caster/requirement/XP/healer/rare prose and intentional blank section rows; ordinary/enchantment DAT spell descriptions; live material-decorated appropriate titles plus DAT material and creature names; expiry, decorated material/gem descriptions; and portal/PK restrictions with authored item colors. It still lacks item-object preview, player-dependent effective shield projection, live cooldown-remaining projection, localized augmentation-cost `StringInfo`, exhaustive character detail regions, and exact creature appraisal FontInfo-list selection. | `src/AcDream.App/UI/RetailUiRuntime.cs`; `src/AcDream.App/UI/Layout/AppraisalUiController.cs`; `src/AcDream.App/UI/Layout/ItemAppraisalTextFormatter.cs`; `src/AcDream.App/UI/Layout/RetailAppraisalNameResolver.cs`; `src/AcDream.App/UI/Layout/CreatureAppraisalRows.cs`; `src/AcDream.App/Rendering/CreatureAppraisalPresentation.cs`; `src/AcDream.Core.Net/LinkStatusSnapshot.cs`; D.5/D.6 roadmap | Basic combat, M3 magic/Link/Vitae surfaces, and the core examination request/presentation/inscription/creature-preview/item-report loop cover the active loops; the residual examination mechanisms require live player/enchantment/localization state or object-preview ownership rather than fabricated content | Item assessments omit only the listed live/localized/preview projections; enchanted/incomplete creature appraisal rows use the normal authored font until the exact FontInfo list is bound; other absent panels remain unavailable; real packet loss is displayed as 0.00% instead of retail's moving average | `BasicCreatureExamineUI::Init @ 0x004AB9C0`; `CreatureExamineUI::SetAppraiseInfo @ 0x004B3FF0`; `gmExaminationUI::RecvNotice_SelectionChanged @ 0x004AB3D0`; `gmExaminationUI::ExamineSpell @ 0x004B6900`; `SpellExamineUI::ExamineSpell @ 0x004B6210`; `AttributeInfoRegion::Update @ 0x004F1D90`; `gmExaminationUI::SetAppraiseInfo @ 0x004ADAE0`; `ACCWeenieObject::GetObjectName @ 0x0058E6E0`; `ItemExamineUI::SetAppraiseInfo @ 0x004B72B0`; `ItemExamineUI::AddItemInfo @ 0x004AC050`; `ItemExamineUI::Appraisal_ShowCapacity @ 0x004B2680`; `ItemExamineUI::Appraisal_ShowSpecialProperties @ 0x004B0140`; `ItemExamineUI::Appraisal_ShowWeaponAndArmorData @ 0x004B10E0`; `ItemExamineUI::Appraisal_ShowMagicInfo @ 0x004B2E10`; `ItemExamineUI::Appraisal_ShowDescription @ 0x004B6990`; `MaterialTypeEnumMapper::MaterialTypeToString @ 0x005CD500`; `ItemExamineUI::SetInscription @ 0x004AE2F0`; `CM_Writing::Event_SetInscription @ 0x006A98B0`; `CLinkStatusAverages::GetAveragePacketLoss @ 0x00546610`; LayoutDesc catalog |
|
||||
| ~~AP-111~~ | **RETIRED 2026-07-11 (M2 held-object parenting)** — equipped hand items are no longer omitted from the render world. CreateObject now preserves Placement/Parent/position timestamp bootstrap; live `0xF749` ParentEvent is parsed with retail sequence freshness; a focused render controller resolves `Setup.HoldingLocations`, applies the child's placement frame, and recomposes the separate child entity after every parent animation tick. Pickup retains the weenie's visual metadata for a later wield. | `src/AcDream.Core.Net/Messages/{CreateObject,ParentEvent}.cs`; `src/AcDream.Core/Meshing/EquippedChildAttachment.cs`; `src/AcDream.App/Rendering/EquippedChildRenderController.cs` | — | — | `ClientCombatSystem::GetDefaultCombatMode @ 0x0056B310`; `SmartBox::HandleParentEvent @ 0x004535D0`; `CPhysicsObj::set_parent @ 0x00515A90`; `CPhysicsObj::UpdateChild @ 0x00512D50` |
|
||||
| AP-112 | The basic combat bar ports visibility, height selection, desired-power slider, exact 1.0/0.8-second charge, ready-stance gating, request/release, `MaybeStopCompletely`, server-response queueing, and auto-repeat, but still omits `StartAttackRequest`'s `FinishJump` call and exact trained-Recklessness visibility semantics (IA-20 keeps the dark range as the accepted baseline) | `src/AcDream.App/Combat/CombatAttackController.cs`; `src/AcDream.App/UI/Layout/CombatUiController.cs` | The shared player movement owner now performs retail's server-control-gated full stop and movement report before an attack build; the remaining seams require the jump owner and a distinct Recklessness treatment | Starting an attack while charging a jump may not finish that jump exactly when retail does; trained/untrained Recklessness presentation is identical | `ClientCombatSystem::StartAttackRequest @ 0x0056C040`; `CommandInterpreter::MaybeStopCompletely @ 0x006B3B90`; `gmCombatUI::ListenToElementMessage @ 0x004CC430` |
|
||||
| AP-113 | Invalid lifestone-command arguments display the local text `Usage: /lifestone`; retail definitely emits a local usage/error line but Binary Ninja misidentifies the referenced wide-string address, so its exact wording is not yet recovered | `src/AcDream.UI.Abstractions/Panels/Chat/ChatCommandRouter.cs`; `RetailClientCommandCatalog.cs` | The behavior boundary is exact (handled locally, no chat and no game action); only a low-impact diagnostic sentence differs | `/ls now` can show different wording/color from retail while still refusing the invalid request correctly | `ClientCommunicationSystem::DoLifestone @ 0x0056FC70` |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# acdream — strategic roadmap
|
||||
|
||||
**Status:** Living document. Updated 2026-07-23. **M3 landed; M4 is active.** M3's retail casting/UI, R6 locomotion/collision/projectile/teleport/radar rebaseline, deterministic fresh-login/portal world lifecycle, and final two-client portal observer flow are user-gated. All eight slices of the behavior-preserving ownership campaign in [`docs/architecture/code-structure.md`](../architecture/code-structure.md), their automated closeout, and the user's connected visual matrix are complete. Issue #225's lifestone/particle alpha comparison remains a separate rendering visual gate.
|
||||
**Status:** Living document. Updated 2026-07-24. **M3 landed; M4 is active.** M3's retail casting/UI, R6 locomotion/collision/projectile/teleport/radar rebaseline, deterministic fresh-login/portal world lifecycle, and final two-client portal observer flow are user-gated. All eight slices of the behavior-preserving ownership campaign in [`docs/architecture/code-structure.md`](../architecture/code-structure.md), their automated closeout, and the user's connected visual matrix are complete. Issue #225's lifestone/particle alpha comparison remains a separate rendering visual gate.
|
||||
**Purpose:** One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under `docs/superpowers/specs/`, not in this file.
|
||||
|
||||
---
|
||||
|
|
@ -38,7 +38,14 @@ selects and appraises occupied inventory, external-container, paperdoll, and
|
|||
physical-shortcut cells through the same request owner. Its shared physical
|
||||
left-click contract now also matches retail's press-time selection: the
|
||||
selection frame updates on MouseDown before drag promotion, while completed
|
||||
click/double-click remains the activation boundary. Slice 3's first connected gate exposed
|
||||
click/double-click remains the activation boundary. The same timing is now
|
||||
ported for favorite spells through a distinct catalog contract: left press
|
||||
selects without waiting for release; right-click opens the examination
|
||||
floaty's authored SpellPanel locally; and spell IDs never enter global object
|
||||
selection or the status-bar magnifier path. The view projects retail's
|
||||
name/school/mana/duration/range/description and authored appropriate-formula
|
||||
component cells, including live missing-component state. Its connected visual
|
||||
gate is pending. Slice 3's first connected gate exposed
|
||||
three deeper defects, now corrected: the response enum mislabeled ACE's
|
||||
creature bit `0x0100` and dropped monster packets while retaining the busy
|
||||
cursor; the imported 310 x 400 examination layout was incorrectly hosted as
|
||||
|
|
|
|||
|
|
@ -108,6 +108,12 @@ The same shared ItemList contract now ports retail's left-button-down
|
|||
selection timing across inventory, loot, paperdoll, and physical shortcuts:
|
||||
selection is visible before release or drag promotion, while use/open/equip
|
||||
remains release-completed.
|
||||
Favorite spells now use the parallel retail catalog contract: MouseDown
|
||||
selects immediately, right-click opens the examination floaty's authored
|
||||
SpellPanel locally, and no spell ID enters global object selection or the
|
||||
status-bar magnifier command. Exact spell fields and the current appropriate
|
||||
formula's authored component cells are automated; the connected visual gate
|
||||
is pending.
|
||||
Slice 3's first connected gate found and corrected the real remaining defects:
|
||||
ACE creature flag `0x0100` was mislabeled as a weapon profile and left the
|
||||
appraisal busy reference held, retail's examination UI had been mounted as a
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ shared-panel mount, and its missing inscription transaction. All three are
|
|||
corrected and live-confirmed. The creature-page follow-up now has retail's
|
||||
ordered stat rows and animated private preview. The follow-up item report and
|
||||
authored 310 x 400 layout correction are implemented; their connected visual
|
||||
gate is pending.
|
||||
gate is pending. Favorite-spell press-time selection and right-click local
|
||||
SpellPanel examination are implemented and await their connected visual gate.
|
||||
**Milestone:** M4 prerequisite/preamble.
|
||||
**Architecture:** retained gameplay UI over shared selection, object, and
|
||||
interaction state. `GameWindow` remains a composition/callback shell.
|
||||
|
|
@ -249,6 +250,16 @@ and the retained green frame update during left-button down, before the
|
|||
three-pixel drag threshold. Target mode is offered first. Opening, using,
|
||||
equipping, looting, and shortcut activation remain completed-click or
|
||||
double-click actions and are suppressed when target mode consumed the press.
|
||||
Favorite spells now use the parallel non-weenie path:
|
||||
`gmSpellcastingUI::ListenToElementMessage @ 0x004C7AB0` selects the favorite
|
||||
on left press, while the spell branch of
|
||||
`UIElement_ItemList::ListenToElementMessage @ 0x004E4D50` opens the authored
|
||||
SpellPanel locally on right-click. Spell IDs never enter `SelectionState` or
|
||||
the status-bar magnifier path, and no Appraise/busy transaction is invented.
|
||||
The view projects exact spell fields and the current appropriate formula
|
||||
through authored component template `0x1000032E`; its connected visual gate is
|
||||
pending. The 61-test focused App gate, Release solution build, 3,553 App tests
|
||||
/ 3 skips, and 7,984 complete-solution tests / 5 skips pass.
|
||||
|
||||
## Slice 1 — spell-bar overflow arrows
|
||||
|
||||
|
|
@ -371,6 +382,11 @@ Named retail references and executable pseudocode are recorded in
|
|||
refresh; closing the examination window must stop refreshes.
|
||||
- Keep Examination open while opening/moving Inventory or Skills and confirm
|
||||
both windows coexist with independent rectangles.
|
||||
- On the combat spell bar, press and hold a different favorite: its selection
|
||||
and name should update before release. Right-click a favorite: the same
|
||||
examination floaty should show the SpellPanel with name, school, mana,
|
||||
duration, range, description, and component formula. The toolbar magnifier
|
||||
must not treat the selected spell as an object.
|
||||
- Assess an owned inscribable weapon. Edit and clear its inscription by
|
||||
clicking elsewhere, then reassess it. An item authored by another player is
|
||||
read-only and reports the exact retail permission line when clicked.
|
||||
|
|
|
|||
|
|
@ -219,6 +219,85 @@ Outbound character events (`CM_Character`):
|
|||
0x0224 SetDesiredComponentLevel(componentDid:u32, amount:i32)
|
||||
```
|
||||
|
||||
### Favorite press selection and local spell examination
|
||||
|
||||
Retail:
|
||||
|
||||
- `gmSpellcastingUI::ListenToElementMessage @ 0x004C7AB0`
|
||||
- `SpellCastSubMenu::SetSelected @ 0x004C5B00`
|
||||
- `UIElement_ItemList::ListenToElementMessage @ 0x004E4D50`
|
||||
- `ClientUISystem::ExamineSpell @ 0x00564A70`
|
||||
- `gmExaminationUI::ExamineSpell @ 0x004B6900`
|
||||
- `SpellExamineUI::ExamineSpell @ 0x004B6210`
|
||||
- `SpellExamineUI::DetermineSpellRange @ 0x004AD450`
|
||||
|
||||
A favorite spell is selected on the UIItem's left-button-down message, not on
|
||||
button release. Double-click remains a completed gesture and casts the spell
|
||||
that the press already selected.
|
||||
|
||||
```text
|
||||
favorite UIItem message:
|
||||
if message parameter == 7: // left press
|
||||
submenu.SetSelected(spellId)
|
||||
if message parameter == 10: // completed double click
|
||||
Cast()
|
||||
|
||||
UIElement_ItemList right click:
|
||||
if itemId != 0:
|
||||
select itemId as the global weenie selection
|
||||
ExamineObject(itemId)
|
||||
else if spellId != 0:
|
||||
ClientUISystem.ExamineSpell(spellId)
|
||||
```
|
||||
|
||||
The spell branch is deliberately local. It never stores the spell ID in
|
||||
`ACCWeenieObject::selectedID`, never sends an Appraise request, and never takes
|
||||
a new UI-busy reference. The toolbar magnifying glass therefore remains an
|
||||
object-only command; selecting a favorite cannot make it assess that spell.
|
||||
|
||||
The examination floaty is shared between object and spell subviews. Switching
|
||||
to a spell cancels only an in-flight/current object appraisal:
|
||||
|
||||
```text
|
||||
gmExaminationUI::ExamineSpell(spellId):
|
||||
if awaiting object appraisal:
|
||||
clear pending object
|
||||
decrement that appraisal's UI-busy reference
|
||||
clear current object
|
||||
send Appraise(0)
|
||||
else if a current object appraisal exists:
|
||||
clear current object
|
||||
send Appraise(0)
|
||||
|
||||
SpellExamineUI.ExamineSpell(spellId)
|
||||
activate SpellPanel
|
||||
show examination window
|
||||
```
|
||||
|
||||
The authored spell subview is part of LayoutDesc `0x2100006B`:
|
||||
|
||||
```text
|
||||
SpellPanel 0x10000153
|
||||
school text 0x1000015E
|
||||
spell icon 0x1000015F
|
||||
mana text 0x10000160
|
||||
duration text 0x10000161
|
||||
range text 0x10000162
|
||||
description/components text 0x10000163
|
||||
formula list 0x1000032D
|
||||
formula-cell template 0x1000032E
|
||||
missing-component overlay 0x10000330
|
||||
```
|
||||
|
||||
Presentation uses the current appropriate formula, preserving its order and
|
||||
duplicates. Each component icon keeps the authored missing-component overlay
|
||||
until the player owns that component. Duration is shown as integer seconds
|
||||
below one minute and integer minutes from one minute upward. Range is
|
||||
`min(baseConstant + baseModifier * schoolSkill, 75) / 0.9144`, displayed with
|
||||
one decimal place in yards. School skill IDs are Creature `0x1F`, Item `0x20`,
|
||||
Life `0x21`, War `0x22`, and Void `0x2B`; an unclassified spell uses the
|
||||
highest of those five skills.
|
||||
|
||||
## Spellbook and component book
|
||||
|
||||
Retail: `gmSpellbookUI::PostInit` `0x0048B2B0` and
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue