feat(ui): world-object hover tooltip — UIElement_SmartBoxWrapper::RecvNotice_SmartBoxObjectFound port
NOT the UI-element dwell-timer path. Retail's mechanism is UIElement_SmartBoxWrapper::RecvNotice_SmartBoxObjectFound @0x004E5AD0, fed every frame by FindObject @0x004E5430/Global_Loop @0x004E5620 using the current mouse position regardless of input focus. It fires IMMEDIATELY (no dwell wait) on the found-object id CHANGING, gated by the PlayerModule::ShowTooltips character option (already modeled in CharacterOptionTable, default true), with text ACCWeenieObject::GetObjectName(id, NAME_APPROPRIATE, 0) — the SAME name call as item tooltips, but WITHOUT the item-cell's separate stack-count prefix (a ground pile of arrows shows "Arrows", not "20 Arrows" — a real, decomp-confirmed asymmetry). Ported as RetailTooltipPresenter.UpdateWorldHoverTooltip, driven by the SAME world-hover pick CursorFeedbackController's own found-cursor already uses (WorldSelectionQuery.PickAtCursor, includeSelf: true — own player is included on that precedent) and the SAME ClientObjectTable-backed name resolver SocialAllegiancePageController's ResolveWorldObjectName already established as this codebase's pattern. New WorldTooltipRuntimeBindings threads it through RetailUiRuntimeBindings; wired at InteractionRetainedUiComposition alongside the existing cursorFeedback construction. Queried only when no UI element is hovered — a narrowing from retail's literal "raycast even under non-item UI chrome" (FindObject's m_pElementLastOver check), called out in the class's own doc note as a scoped interpretation rather than a byte-exact port. The exact popup skin is an inference, not a measured value: an exhaustive live-DAT sweep found UIElement_SmartBoxWrapper (class 0x10000030) has NO authored ElementDesc anywhere installed — unlike every other tooltip trigger, it is evidently constructed directly by gmGamePlayUI's own mode setup, not from a walkable LayoutDesc. This port reuses the same P0x47=0x10000395/P0x48=0x21000041 pair every other game-code SetTooltip caller in this family resolves to — the best-evidenced choice, called out in register row TS-85 rather than silently assumed exact. Live-verified against a connected ACE session (session-config launch, +Acdream): hovering a "Silver Tusker" near spawn mounted the correct popup text and simultaneously flipped the cursor to its DefaultFound variant, confirming the shared found-object pipeline drives both. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e29c61a3a4
commit
fe1bc70753
5 changed files with 436 additions and 8 deletions
|
|
@ -333,6 +333,17 @@ public sealed record RetailUiCursorBindings(
|
|||
CursorFeedbackController Feedback,
|
||||
RetailCursorManager Manager);
|
||||
|
||||
/// <summary>
|
||||
/// #409 follow-on (docs/ISSUES.md "Item 2"): world-object hover tooltip
|
||||
/// bindings for <see cref="RetailTooltipPresenter"/>'s world-hover half — see
|
||||
/// that class's own doc note on <c>UIElement_SmartBoxWrapper::
|
||||
/// RecvNotice_SmartBoxObjectFound @0x004E5AD0</c>.
|
||||
/// </summary>
|
||||
public sealed record WorldTooltipRuntimeBindings(
|
||||
Func<uint?> HoverGuidAtCursor,
|
||||
Func<uint, string?> ResolveName,
|
||||
Func<bool> Enabled);
|
||||
|
||||
public sealed record ConfirmationRuntimeBindings(
|
||||
Action<uint, uint, bool> SendResponse);
|
||||
|
||||
|
|
@ -435,6 +446,7 @@ public sealed record RetailUiRuntimeBindings(
|
|||
ExternalContainerRuntimeBindings ExternalContainer,
|
||||
VendorRuntimeBindings Vendor,
|
||||
RetailUiCursorBindings Cursor,
|
||||
WorldTooltipRuntimeBindings WorldTooltip,
|
||||
ConfirmationRuntimeBindings Confirmations,
|
||||
AppraisalRuntimeBindings Appraisal,
|
||||
OptionsRuntimeBindings Options,
|
||||
|
|
@ -3366,7 +3378,15 @@ public sealed class RetailUiRuntime : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
TooltipPresenter = new RetailTooltipPresenter(Host.Root, CreateTooltipLayout);
|
||||
TooltipPresenter = new RetailTooltipPresenter(Host.Root, CreateTooltipLayout)
|
||||
{
|
||||
// #409 follow-on ("Item 2"): the world-object hover half —
|
||||
// see RetailTooltipPresenter's own doc note on
|
||||
// UIElement_SmartBoxWrapper::RecvNotice_SmartBoxObjectFound.
|
||||
WorldHoverGuidProvider = () => _bindings.WorldTooltip.HoverGuidAtCursor(),
|
||||
WorldHoverNameResolver = _bindings.WorldTooltip.ResolveName,
|
||||
WorldTooltipsEnabled = () => _bindings.WorldTooltip.Enabled(),
|
||||
};
|
||||
|
||||
if (_bindings.Chat.Store is { } store)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue