fix(tooltip): keep Item/NPC ID lines from vanishing on re-hover

The ID lines were gated by lastItemId/lastGuid (only added when the
hovered item/unit changed). WoW clears and re-fires OnTooltipSetItem/
OnTooltipSetUnit for the same item/unit and rebuilds the tooltip, so the
gate skipped re-adding the line on the rebuilt tooltip and the ID
disappeared. Add the ID line on every render instead, deduped per
tooltip via _TooltipHasLeftLine so it shows exactly once.
This commit is contained in:
Xurkon
2026-06-11 16:37:40 -05:00
parent 7bd14b80fc
commit 5abeff2768
2 changed files with 38 additions and 16 deletions
+1
View File
@@ -41,6 +41,7 @@
### Bug Fixes
- **[Tooltip - ID Lines No Longer Vanish On Re-Hover]** The "Item ID" / "NPC ID" lines were only added when the hovered item/unit *changed* (`lastItemId`/`lastGuid` gate). But WoW clears and re-fires `OnTooltipSetItem`/`OnTooltipSetUnit` for the *same* item/unit, rebuilding the tooltip — and the gate skipped re-adding the line on the rebuilt tooltip, so the ID disappeared (e.g. hovering the same quest item twice). The ID lines are now (re)added on every render and deduplicated per tooltip (via `_TooltipHasLeftLine`), so they're always present exactly once.
- **[Learner - Exclude Critters & Fix Sunstrider Object Mis-Key]** Critters (Rabbit, Deer, Sheep, Cow, Cat, …) are never quest-relevant but were being recorded by the learner when killed, polluting the DB. The learner now refuses to record critters (a static list of common classic critters plus runtime detection via `UnitCreatureType` for Ascension's custom critters, flagged the moment a unit token is available on mouseover/target), purges any already-recorded critters on `InjectLearnedData` and on sight, and skips them in every learn path. Also fixed object spawns mis-stored under the Eversong parent areaID `3430` (e.g. object 180516 "Shrine of Dath'Remar", which is on Sunstrider): the migration now moves any `3430`-keyed spawn — and the matching home-zone field — to Sunstrider's uiMapID `1241`, since legitimate Eversong data is always keyed by `1941`.
- **[Learner - InjectLearnedData Was Corrupting Saved Spawns]** The real cause of learner pins collapsing to one (and the data appearing to "not persist"): `InjectLearnedData` ran on every login/redraw and **rewrote the saved learner spawns**. Its zone-key migration was inverted — it called `GetAreaIdByUiMapId(1241)`, which returns the Eversong **parent areaId 3430**, and *moved* Sunstrider's coordinates there (rendering them on the wrong map) while `InsertIfNewBucket` silently deduped distinct coords away. On top of that, `Sanitize` re-deduplicated coordinates with the flat `COORD_GRID` (2.0) instead of the per-zone grid, collapsing Sunstrider's tightly-packed spawns (its grid is 0.5). Together these turned seven saved Arcane Wraith coordinates into one pin and persisted the damage back to SavedVariables. Fixed: the migration now converts only legacy areaId keys **forward** to the canonical uiMapId (never the reverse) and leaves uiMapId keys untouched; the `[9]`/`[5]` home-zone fields are normalized the same direction; and `Sanitize` now de-dups with the correct per-zone grid. A regression test (`Tests/QuestieLearnerMultiSpawn_spec.lua`) drives `InjectLearnedData` + `GetNPC` and asserts all distinct learner spawns survive.
- **[Learner - Sunstrider Shows Every Learned Pin Again]** Learner-recorded spawns on Sunstrider Isle were being collapsed to a single pin: a prior change kept clustering enabled there in learner mode, so several distinct learned coordinates (e.g. seven Arcane Wraith spots) consolidated into one icon — breaking the DB-building workflow where every learned spawn must be visible. Sunstrider (uiMapID 1241) now shows every distinct pin by default in **all** data-source modes; consolidation only happens if the player explicitly raises the Dense Pin Clustering Aggressiveness knob. (The data was correct in SavedVariables the whole time — this was purely a display/clustering regression.)
+37 -16
View File
@@ -367,6 +367,15 @@ function _QuestieTooltips:AddUnitDataToTooltip()
end
local guidType, _, _, _, _, npcId, _ = strsplit("-", guid or "");
-- NPC ID is (re)added on EVERY render so it survives WoW's tooltip rebuilds, not only the
-- first hover of a new unit. Deduped per tooltip so it never doubles up.
if name and (guidType == "Creature" or guidType == "Vehicle") and npcId
and Questie.db.profile.enableTooltipsNPCID == true
and not _TooltipHasLeftLine(self, "NPC ID") then
GameTooltip:AddDoubleLine("NPC ID", "|cFFFFFFFF" .. npcId .. "|r")
end
if name and (guidType == "Creature" or guidType == "Vehicle") and (
name ~= QuestieTooltips.lastGametooltipUnit or
(not QuestieTooltips.lastGametooltipCount) or
@@ -381,18 +390,11 @@ function _QuestieTooltips:AddUnitDataToTooltip()
-- tooltip, or the separate secondary learner frame when that option is enabled).
local tooltipData = QuestieTooltips:GetTooltip("m_" .. npcId, true);
-- NPC ID line is added above (every render, deduped); only the objective lines remain here.
if tooltipData then
if Questie.db.profile.enableTooltipsNPCID == true then
GameTooltip:AddDoubleLine("NPC ID", "|cFFFFFFFF" .. npcId .. "|r")
end
for _, v in next, tooltipData do
GameTooltip:AddLine(v)
end
else
-- Even if Questie has no objective tooltip for this NPC, we still want to show quest-starter drops.
if Questie.db.profile.enableTooltipsNPCID == true then
GameTooltip:AddDoubleLine("NPC ID", "|cFFFFFFFF" .. npcId .. "|r")
end
end
-- Data-source attribution is rendered by QuestieLearner's secondary tooltip frame
@@ -417,6 +419,25 @@ end
-- Rest of original file
-- =======================
-- True if the tooltip already shows a left-column line beginning with `label`. Used so the
-- ID lines can be (re)added on EVERY tooltip render without ever duplicating within a single
-- tooltip. The id lines must be added every render because WoW clears and re-fires
-- OnTooltipSetItem/OnTooltipSetUnit for the same item/unit, and the old "only when the id
-- changed" gate skipped re-adding the line on the rebuilt tooltip — so the ID vanished.
local function _TooltipHasLeftLine(tooltip, label)
local frameName = tooltip and tooltip.GetName and tooltip:GetName()
if not frameName then return false end
local numLines = tooltip:NumLines()
for i = 1, (numLines or 0) do
local fontString = _G[frameName .. "TextLeft" .. i]
local text = fontString and fontString:GetText()
if text and string.find(text, label, 1, true) == 1 then
return true
end
end
return false
end
local lastItemId = 0;
function _QuestieTooltips:AddItemDataToTooltip()
if (self.IsForbidden and self:IsForbidden()) or (not Questie.db.profile.enableTooltips) then
@@ -432,17 +453,17 @@ function _QuestieTooltips:AddItemDataToTooltip()
string.match(link,
"|?c?f?f?(%x*)|?H?([^:]*):?(%d+):?(%d*):?(%d*):?(%d*):?(%d*):?(%d*):?(%-?%d*):?(%-?%d*):?(%d*):?(%d*):?(%-?%d*)|?h?%[?([^%[%]]*)%]?|?h?|?r?"))
end
-- Item ID is (re)added on EVERY render so it survives WoW's tooltip rebuilds, not just the
-- first hover of a new item. Deduped per tooltip so it never doubles up.
if name and itemId and Questie.db.profile.enableTooltipsItemID == true
and not _TooltipHasLeftLine(self, "Item ID") then
self:AddDoubleLine("Item ID", "|cFFFFFFFF" .. itemId .. "|r")
end
if name and itemId and (lastItemId ~= itemId) then
QuestieTooltips.lastGametooltipItem = name
local tooltipData = QuestieTooltips:GetTooltip("i_" .. (itemId or 0));
-- Item ID is shown unconditionally for every item hover (matches the
-- behavior of NPC/Object tooltips), so users can always copy/paste
-- the ID even for items that have no quest objective or starter
-- data attached. The line is always added when the itemId changes
-- regardless of whether tooltipData is non-nil.
if Questie.db.profile.enableTooltipsItemID == true then
self:AddDoubleLine("Item ID", "|cFFFFFFFF" .. itemId .. "|r")
end
-- If the item starts a quest (the player must right-click/use it,
-- or talk to an NPC while it's in their bag), surface that so the
-- player can see which quest the item unlocks without first