fix(ui): Map/House panel — marker tooltips use the wrong property

Live verification (slice 5) found town-marker tooltips never appeared:
RetailTooltipPresenter.OnTooltipShow gates unconditionally on
AuthoredTooltipRootElementId == 0 -> return, with no fallback, but the
markers only set AuthoredTooltipText/Enabled (the DAT-authored P0x49
path). gmMapUI::AddMapNote's UIElement::SetTooltip call is retail's
RUNTIME m_TTText/SetTooltip mechanism, not the authored path — the
correct seam is UiButton.TooltipText (backing GetTooltipText()'s
override), which ResolveTooltipText consults before authored text.

The popup-skin locator (AuthoredTooltipRootElementId/LayoutDid) is
still required even on the runtime-text path with no built-in
fallback, so markers now hardcode the same shared popup skin
UiItemSlot already uses (0x10000395/0x21000041) — matching that
established precedent exactly.

Verified live: hovering a town marker (Aerlinthe Island) now renders
its tooltip correctly. 21/21 Map/House controller tests still pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-17 02:43:40 +02:00
parent 22b6281192
commit e5629d713d
2 changed files with 54 additions and 13 deletions

View file

@ -200,6 +200,22 @@ public sealed class MapPageController
return lines;
}
/// <summary>
/// Live-DAT-confirmed 2026-08-17: the SAME shared popup skin
/// <see cref="UiItemSlot"/> hardcodes for its own runtime-text tooltips
/// (its own class doc has the full "one of the four popup skins
/// RetailTooltipPresenter already mounts" citation). The map-note
/// template (<c>0x100001F0</c>) authors no individual tooltip-popup
/// locator of its own (a plain 10x10 hotspot dot), so
/// <c>RetailTooltipPresenter.OnTooltipShow</c>'s unconditional
/// <c>AuthoredTooltipRootElementId == 0 -&gt; return</c> guard needs one
/// supplied — reusing the item catalog's proven-working skin is the
/// same "best-evidenced inference, not a measured retail value" shape
/// TS-85's own <c>UpdateWorldHoverTooltip</c> fallback already uses.
/// </summary>
private const uint MarkerTooltipRootElementId = 0x10000395u;
private const uint MarkerTooltipLayoutDid = 0x21000041u;
/// <summary>
/// Instantiates the 53 static town hotspots (<c>gmMapUI::AddMapNote</c>)
/// from <c>m_pMap</c>'s own <c>0x47</c>/<c>0x48</c> template attrs. A
@ -226,12 +242,19 @@ public sealed class MapPageController
marker.Width = loc.Width;
marker.Height = loc.Height;
// gmMapUI::AddMapNote's UIElement::SetTooltip call — a LITERAL
// string (StringInfo::SetLiteralValue), not a DAT table lookup.
// AuthoredTooltipText/Enabled is the exact seam
// RetailTooltipPresenter already serves (closes register row
// TS-85's last item, gmMapUI::AddMapNote @0x004A1C51).
marker.AuthoredTooltipText = loc.Name;
marker.AuthoredTooltipEnabled = true;
// string (StringInfo::SetLiteralValue), not a DAT table lookup —
// i.e. retail's RUNTIME m_TTText mechanism, not the authored
// P0x49 path. UiButton.TooltipText is the exact settable seam
// backing UiElement.GetTooltipText()'s override, which
// RetailTooltipPresenter.ResolveTooltipText consults BEFORE the
// authored text (closes register row TS-85's last item,
// gmMapUI::AddMapNote @0x004A1C51). AuthoredTooltipRootElementId/
// LayoutDid still gate the popup SKIN unconditionally even on
// the runtime-text path — see MarkerTooltipRootElementId's doc.
if (marker is UiButton markerButton)
markerButton.TooltipText = loc.Name;
marker.AuthoredTooltipRootElementId = MarkerTooltipRootElementId;
marker.AuthoredTooltipLayoutDid = MarkerTooltipLayoutDid;
_map!.AddChild(marker);
}
}