From 5a9dce0f13da5e46fbca5508d225c481c09390c1 Mon Sep 17 00:00:00 2001 From: Xurkon Date: Tue, 9 Jun 2026 17:11:51 -0500 Subject: [PATCH] fix(tooltip): keep learner lines out of main NPC tooltip when using secondary Two parallel learner-tooltip systems both rendered on unit hover, so with the 'Use secondary learner tooltip' option on, learner spawn/kill lines still leaked into the main NPC tooltip instead of going solely to the secondary frame. QuestieLearner's OnTooltipSetUnit hook (toggle-aware, secondary-capable) already owns unit-hover learner display, routing it to the main tooltip (secondary off) or the separate secondary frame (secondary on). But Tooltip.lua's _GetLearnerTooltipLines also injected learner lines into the m_ tooltip data, redundantly. Add a suppressLearnerLines flag to QuestieTooltips:GetTooltip and pass it from the NPC unit-hover call in TooltipHandler so the inline lines are omitted there. Map-pin and object tooltips (no secondary frame) keep their learner lines. Also removes the latent duplicate present even with the secondary frame disabled. --- CHANGELOG.md | 1 + Modules/Tooltips/Tooltip.lua | 21 ++++++++++++++++----- Modules/Tooltips/TooltipHandler.lua | 5 ++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ae680a..00f4d6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ ### Bug Fixes +- **[Tooltip - Secondary Learner Tooltip Leak]** With the "Use secondary learner tooltip" option enabled, learner spawn/kill lines still appeared in the main NPC tooltip instead of going solely to the secondary frame. Two parallel learner-tooltip systems were both rendering on unit hover: QuestieLearner's `OnTooltipSetUnit` hook (toggle-aware, secondary-capable) and `Tooltip.lua`'s `_GetLearnerTooltipLines` (always injected "Learned spawn / Total spawns learned / Total kills recorded" into the `m_` tooltip data). `QuestieTooltips:GetTooltip` now takes a `suppressLearnerLines` flag, and the NPC unit-hover call in `TooltipHandler.lua` passes it so the inline learner lines are omitted there — the `OnTooltipSetUnit` hook owns that display and routes it to the main tooltip (secondary off) or the separate secondary frame (secondary on). Map-pin and object tooltips are unaffected and keep their learner lines. Also removes the latent duplicate learner lines that appeared in the main tooltip even with the secondary frame disabled. - **[Map - Completed Objective Pins Linger]** Added `QuestieMap:UnloadQuestFramesForObjective(questId, objectiveIndex)` and call it from every completion path in `QuestieQuest:PopulateObjective` (objective completed, hidden by `ShouldHideObjective`, and static no-`Update` objectives). Previously, removing a completed objective's map/minimap pins relied solely on `_UnloadAlreadySpawnedIcons`, which walks `objective.AlreadySpawned`. That table desyncs from the frames actually on screen after learner spawn-list invalidation or complete→abandon→reaccept cycles, so when it was reset to `{}` the live frames leaked and pins for fully-completed objectives (e.g. 6/6 kills, a collected item objective) stayed on the map even though tooltips updated correctly. The new function unloads frames deterministically off the map's own `questIdFrames` registry by matching `frame.data.ObjectiveIndex`, so completed-objective pins are removed regardless of `AlreadySpawned` state. Restricted to positive standard-objective indices; SpecialObjectives (sentinel index 0) keep using `AlreadySpawned` to avoid cross-unloading siblings. - **[QuestieLib - GetColoredQuestName Nil Guard]** Added a nil guard in `QuestieLib:GetColoredQuestName` so a synthetic `questId` (e.g. one used in a chat link on servers that do not have a real quest entry) no longer crashes with `attempt to index a nil value`. The function now checks `QuestieDB.GetQuest(questId)` before reading its `isComplete` flag. - **[Tooltip - Item Flicker on ElvUI Refresh]** Simplified the `AddItemDataToTooltip` redraw check to key purely on `itemId`. The previous condition also re-keyed on tooltip name, line count, and frame name — all of which ElvUI's tooltip-frame recycling transiently resets, so every refresh cycle looked like a new item and caused Questie's lines to flicker repeatedly. The new condition only re-adds when the actual itemId changes, so the tooltip stays stable across ElvUI's refresh ticks. diff --git a/Modules/Tooltips/Tooltip.lua b/Modules/Tooltips/Tooltip.lua index f0068f5..3fda0d6 100644 --- a/Modules/Tooltips/Tooltip.lua +++ b/Modules/Tooltips/Tooltip.lua @@ -334,7 +334,12 @@ local function _GetLearnerTooltipLines(key) end ---@param key string -function QuestieTooltips:GetTooltip(key) +---@param suppressLearnerLines boolean? When true, omit the inline learner spawn/kill +--- lines from System A. Used by the NPC unit-hover tooltip, where the learner data is +--- already rendered by QuestieLearner's OnTooltipSetUnit hook (main tooltip when the +--- secondary learner tooltip is off, or the separate secondary frame when it is on). +--- Map-pin and object tooltips leave this nil so they keep showing learner lines. +function QuestieTooltips:GetTooltip(key, suppressLearnerLines) Questie:Debug(Questie.DEBUG_SPAM, "[QuestieTooltips:GetTooltip]", key) if (not key) then return nil @@ -603,10 +608,16 @@ elseif key:sub(1,2) == "o_" then end -- Append learner spawn data when the learner has recorded this NPC. - local learnerLines = _GetLearnerTooltipLines(key) - if learnerLines then - for _, line in ipairs(learnerLines) do - tinsert(tooltipLines, line) + -- Skipped for the NPC unit-hover tooltip (suppressLearnerLines): QuestieLearner's + -- OnTooltipSetUnit hook owns that display and routes it to the main tooltip or the + -- separate secondary learner frame, so adding it here too would duplicate it (and, + -- with the secondary frame enabled, leak the lines back into the main tooltip). + if not suppressLearnerLines then + local learnerLines = _GetLearnerTooltipLines(key) + if learnerLines then + for _, line in ipairs(learnerLines) do + tinsert(tooltipLines, line) + end end end diff --git a/Modules/Tooltips/TooltipHandler.lua b/Modules/Tooltips/TooltipHandler.lua index c1d94b0..1fb3c27 100644 --- a/Modules/Tooltips/TooltipHandler.lua +++ b/Modules/Tooltips/TooltipHandler.lua @@ -310,7 +310,10 @@ function _QuestieTooltips:AddUnitDataToTooltip() ) then QuestieTooltips.lastGametooltipUnit = name - local tooltipData = QuestieTooltips:GetTooltip("m_" .. npcId); + -- Suppress System A's inline learner lines here: QuestieLearner's OnTooltipSetUnit + -- hook already renders learner spawn/kill data for the hovered unit (into the main + -- tooltip, or the separate secondary learner frame when that option is enabled). + local tooltipData = QuestieTooltips:GetTooltip("m_" .. npcId, true); if tooltipData then if Questie.db.profile.enableTooltipsNPCID == true then