5a9dce0f13
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_<npcId> 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.
725 lines
32 KiB
Lua
725 lines
32 KiB
Lua
---@class QuestieTooltips
|
||
local QuestieTooltips = QuestieLoader:CreateModule("QuestieTooltips");
|
||
local _QuestieTooltips = QuestieTooltips.private
|
||
-------------------------
|
||
--Import modules.
|
||
-------------------------
|
||
---@type QuestieComms
|
||
local QuestieComms = QuestieLoader:ImportModule("QuestieComms");
|
||
---@type QuestieLib
|
||
local QuestieLib = QuestieLoader:ImportModule("QuestieLib");
|
||
---@type QuestiePlayer
|
||
local QuestiePlayer = QuestieLoader:ImportModule("QuestiePlayer");
|
||
---@type QuestieDB
|
||
local QuestieDB = QuestieLoader:ImportModule("QuestieDB");
|
||
---@type l10n
|
||
local l10n = QuestieLoader:ImportModule("l10n")
|
||
|
||
--- COMPATIBILITY ---
|
||
local UnitInParty = QuestieCompat.UnitInParty
|
||
local IsInGroup = QuestieCompat.IsInGroup
|
||
local GetClassColor = QuestieCompat.GetClassColor
|
||
|
||
local tinsert = table.insert
|
||
QuestieTooltips.lastGametooltip = ""
|
||
QuestieTooltips.lastGametooltipCount = -1;
|
||
QuestieTooltips.lastGametooltipType = "";
|
||
QuestieTooltips.lastFrameName = "";
|
||
|
||
QuestieTooltips.lookupByKey = {
|
||
--["u_Grell"] = {questid, {"Line 1", "Line 2"}}
|
||
}
|
||
QuestieTooltips.lookupKeysByQuestId = {
|
||
--["questId"] = {"u_Grell", ... }
|
||
}
|
||
|
||
local MAX_GROUP_MEMBER_COUNT = 6
|
||
-- Throttle: limit the OnUpdate object-tooltip check to 10 times per second.
|
||
-- Without this, the callback fires every frame (60–144 Hz) and hammers GetText()
|
||
-- + CountTooltip() even when the tooltip hasn't changed.
|
||
local _tooltipUpdateInterval = 0.10
|
||
local _tooltipLastUpdate = 0
|
||
local _tooltipLastText = ""
|
||
|
||
local _InitObjectiveTexts
|
||
|
||
local function _LearnerTooltipsEnabled()
|
||
return not (Questie.db and Questie.db.profile) or Questie.db.profile.learnerTooltips ~= false
|
||
end
|
||
|
||
local function _ResizeTooltipToFit(tooltip)
|
||
if not tooltip or not tooltip.GetName then
|
||
return
|
||
end
|
||
|
||
local tooltipName = tooltip:GetName()
|
||
if not tooltipName then
|
||
return
|
||
end
|
||
|
||
local maxWidth = 0
|
||
for i = 1, tooltip:NumLines() do
|
||
local left = _G[tooltipName .. "TextLeft" .. i]
|
||
local right = _G[tooltipName .. "TextRight" .. i]
|
||
if left and left:GetText() then
|
||
maxWidth = math.max(maxWidth, left:GetStringWidth() or 0)
|
||
end
|
||
if right and right:GetText() then
|
||
maxWidth = math.max(maxWidth, right:GetStringWidth() or 0)
|
||
end
|
||
end
|
||
|
||
if maxWidth <= 0 then
|
||
return
|
||
end
|
||
|
||
maxWidth = maxWidth + 24
|
||
local currentWidth = tooltip.GetWidth and tooltip:GetWidth() or 0
|
||
if currentWidth < maxWidth then
|
||
if tooltip.SetMinimumWidth then
|
||
tooltip:SetMinimumWidth(maxWidth)
|
||
end
|
||
tooltip:SetWidth(maxWidth)
|
||
end
|
||
end
|
||
|
||
function QuestieTooltips:ResizeTooltip(tooltip)
|
||
if not (Questie.db and Questie.db.profile) or Questie.db.profile.learnerTooltipAutoResize == false then
|
||
return
|
||
end
|
||
_ResizeTooltipToFit(tooltip)
|
||
end
|
||
|
||
local function _GetQuestObjectiveSummary(questId)
|
||
if not QuestieDB or not QuestieDB.GetQuest then
|
||
return nil
|
||
end
|
||
|
||
local quest = QuestieDB.GetQuest(questId)
|
||
if not quest or not quest.ObjectiveData then
|
||
return nil
|
||
end
|
||
|
||
local summary = {}
|
||
for _, objective in ipairs(quest.ObjectiveData) do
|
||
local text = objective and (objective.Text or objective.Description)
|
||
if type(text) == "string" and text ~= "" then
|
||
tinsert(summary, text)
|
||
end
|
||
end
|
||
|
||
if table.getn(summary) == 0 then
|
||
return nil
|
||
end
|
||
|
||
return summary
|
||
end
|
||
|
||
local function _BuildTooltipSourceLine(sourceFlags)
|
||
return nil
|
||
end
|
||
|
||
local function _GetTooltipSourceLine(key)
|
||
return nil
|
||
end
|
||
|
||
---@param questId number
|
||
---@param key string monster: m_, items: i_, objects: o_ + string name of the objective
|
||
---@param objective table
|
||
function QuestieTooltips:RegisterObjectiveTooltip(questId, key, objective)
|
||
if not QuestieTooltips.lookupByKey[key] then
|
||
QuestieTooltips.lookupByKey[key] = {};
|
||
end
|
||
if not QuestieTooltips.lookupKeysByQuestId[questId] then
|
||
QuestieTooltips.lookupKeysByQuestId[questId] = {}
|
||
end
|
||
local tooltip = {
|
||
questId = questId,
|
||
objective = objective,
|
||
};
|
||
QuestieTooltips.lookupByKey[key][tostring(questId) .. " " .. objective.Index] = tooltip
|
||
tinsert(QuestieTooltips.lookupKeysByQuestId[questId], key)
|
||
end
|
||
|
||
---@param questId number
|
||
---@param name string The name of the object or NPC the tooltip should show on
|
||
---@param starterId number The ID of the object or NPC the tooltip should show on
|
||
---@param key string @Either m_<npcId> or o_<objectId>
|
||
function QuestieTooltips:RegisterQuestStartTooltip(questId, name, starterId, key)
|
||
if not name then
|
||
return
|
||
end
|
||
if not QuestieTooltips.lookupByKey[key] then
|
||
QuestieTooltips.lookupByKey[key] = {};
|
||
end
|
||
if not QuestieTooltips.lookupKeysByQuestId[questId] then
|
||
QuestieTooltips.lookupKeysByQuestId[questId] = {}
|
||
end
|
||
local tooltip = {
|
||
questId = questId,
|
||
name = name,
|
||
starterId = starterId,
|
||
};
|
||
QuestieTooltips.lookupByKey[key][tostring(questId) .. " " .. name .. " " .. starterId] = tooltip
|
||
tinsert(QuestieTooltips.lookupKeysByQuestId[questId], key)
|
||
end
|
||
|
||
---@param questId number
|
||
function QuestieTooltips:RemoveQuest(questId)
|
||
if (not QuestieTooltips.lookupKeysByQuestId[questId]) then
|
||
-- Tooltip has already been removed
|
||
return
|
||
end
|
||
|
||
-- Remove tooltip related keys from quest table so that
|
||
-- it can be readded/registered by other quest functions.
|
||
local quest = QuestieDB.GetQuest(questId)
|
||
|
||
if quest then
|
||
for _, objective in next, quest.Objectives do
|
||
objective.AlreadySpawned = {}
|
||
objective.hasRegisteredTooltips = false
|
||
objective.registeredItemTooltips = false
|
||
end
|
||
|
||
for _, objective in next, quest.SpecialObjectives do
|
||
objective.AlreadySpawned = {}
|
||
objective.hasRegisteredTooltips = false
|
||
objective.registeredItemTooltips = false
|
||
end
|
||
end
|
||
|
||
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieTooltips:RemoveQuest]", questId)
|
||
|
||
for _, key in next, QuestieTooltips.lookupKeysByQuestId[questId] or {} do
|
||
--Count to see if we should remove the main object
|
||
local totalCount = 0
|
||
local totalRemoved = 0
|
||
for _, tooltipData in next, QuestieTooltips.lookupByKey[key] or {} do
|
||
--Remove specific quest
|
||
if (tooltipData.questId == questId and tooltipData.objective) then
|
||
QuestieTooltips.lookupByKey[key][tostring(tooltipData.questId) .. " " .. tooltipData.objective.Index] = nil
|
||
totalRemoved = totalRemoved + 1
|
||
elseif (tooltipData.questId == questId and tooltipData.name) then
|
||
QuestieTooltips.lookupByKey[key][tostring(tooltipData.questId) .. " " .. tooltipData.name .. " " .. tooltipData.starterId] = nil
|
||
totalRemoved = totalRemoved + 1
|
||
end
|
||
totalCount = totalCount + 1
|
||
end
|
||
if (totalCount == totalRemoved) then
|
||
QuestieTooltips.lookupByKey[key] = nil
|
||
end
|
||
end
|
||
|
||
QuestieTooltips.lookupKeysByQuestId[questId] = nil
|
||
end
|
||
|
||
-- This code is related to QuestieComms, here we fetch all the tooltip data that exist in QuestieCommsData
|
||
-- It uses a similar system like here with i_ID etc as keys.
|
||
local function _FetchTooltipsForGroupMembers(key, tooltipData)
|
||
local anotherPlayer = false;
|
||
if QuestieComms and QuestieComms.data:KeyExists(key) then
|
||
---@tooltipData @tooltipData[questId][playerName][objectiveIndex].text
|
||
local tooltipDataExternal = QuestieComms.data:GetTooltip(key);
|
||
for questId, playerList in next, tooltipDataExternal do
|
||
if (not tooltipData[questId]) then
|
||
tooltipData[questId] = {
|
||
title = QuestieLib:GetColoredQuestName(questId, Questie.db.profile.enableTooltipsQuestLevel, true, true)
|
||
}
|
||
end
|
||
for playerName, _ in next, playerList do
|
||
local playerInfo = QuestiePlayer:GetPartyMemberByName(playerName);
|
||
if playerInfo or QuestieComms.remotePlayerEnabled[playerName] then
|
||
anotherPlayer = true
|
||
break
|
||
end
|
||
end
|
||
if anotherPlayer then
|
||
break
|
||
end
|
||
end
|
||
end
|
||
|
||
if QuestieComms.data:KeyExists(key) and anotherPlayer then
|
||
---@tooltipData @tooltipData[questId][playerName][objectiveIndex].text
|
||
local tooltipDataExternal = QuestieComms.data:GetTooltip(key);
|
||
for questId, playerList in next, tooltipDataExternal do
|
||
if (not tooltipData[questId]) then
|
||
tooltipData[questId] = {
|
||
title = QuestieLib:GetColoredQuestName(questId, Questie.db.profile.enableTooltipsQuestLevel, true, true)
|
||
}
|
||
end
|
||
for playerName, objectives in next, playerList do
|
||
local playerInfo = QuestiePlayer:GetPartyMemberByName(playerName);
|
||
if playerInfo or QuestieComms.remotePlayerEnabled[playerName] then
|
||
anotherPlayer = true;
|
||
for objectiveIndex, objective in next, objectives do
|
||
if (not objective) then
|
||
objective = {}
|
||
end
|
||
|
||
tooltipData[questId].objectivesText = _InitObjectiveTexts(tooltipData[questId].objectivesText, objectiveIndex, playerName)
|
||
|
||
local text;
|
||
local color = QuestieLib:GetRGBForObjective(objective)
|
||
|
||
if objective.required then
|
||
text = " " .. color .. tostring(objective.fulfilled) .. "/" .. tostring(objective.required) .. " " .. objective.text;
|
||
else
|
||
text = " " .. color .. objective.text;
|
||
end
|
||
|
||
tooltipData[questId].objectivesText[objectiveIndex][playerName] = { ["color"] = color, ["text"] = text };
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
return anotherPlayer
|
||
end
|
||
|
||
local function _GetLearnerTooltipLines(key)
|
||
-- key format: "m_<npcId>" for NPCs, "o_<objectId>" for objects, "i_<itemId>" for items
|
||
local id = tonumber(key:sub(3))
|
||
if not id then return nil end
|
||
|
||
local QuestieLearner = QuestieLoader:ImportModule("QuestieLearner")
|
||
if not QuestieLearner or not QuestieLearner.IsEnabled or not QuestieLearner:IsEnabled() then
|
||
return nil
|
||
end
|
||
|
||
local learnedNpc = QuestieLearner.data and QuestieLearner.data.npcs and QuestieLearner.data.npcs[id]
|
||
if not learnedNpc then return nil end
|
||
|
||
local lines = {}
|
||
local guidSpawns = learnedNpc[8]
|
||
local spawnList = learnedNpc[7]
|
||
|
||
-- Count total distinct spawn points
|
||
local totalSpawns = 0
|
||
if spawnList then
|
||
for _ in pairs(spawnList) do totalSpawns = totalSpawns + 1 end
|
||
end
|
||
|
||
-- Find the most-visited spawn (highest count in guidSpawns)
|
||
local bestX, bestY, bestCount = nil, nil, 0
|
||
if guidSpawns then
|
||
for uid, entry in pairs(guidSpawns) do
|
||
local c = tonumber(entry.count) or 1
|
||
if c > bestCount then
|
||
bestCount = c
|
||
bestX = entry.x
|
||
bestY = entry.y
|
||
end
|
||
end
|
||
end
|
||
|
||
if bestX and bestY then
|
||
tinsert(lines, string.format(" |cFF808080Learned spawn|r (|cFFFFFFFF%.1f, %.1f|r) |cFF808080from %d kills|r", bestX, bestY, bestCount))
|
||
end
|
||
|
||
if totalSpawns > 0 then
|
||
tinsert(lines, string.format(" |cFF808080Total spawns learned|r |cFFFFFFFF%d|r", totalSpawns))
|
||
end
|
||
|
||
local mc = tonumber(learnedNpc.mc) or 0
|
||
if mc > 0 then
|
||
tinsert(lines, string.format(" |cFF808080Total kills recorded|r |cFFFFFFFF%d|r", mc))
|
||
end
|
||
|
||
if #lines > 0 then
|
||
return lines
|
||
end
|
||
return nil
|
||
end
|
||
|
||
---@param key string
|
||
---@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
|
||
end
|
||
|
||
if (QuestiePlayer.numberOfGroupMembers or 0) > MAX_GROUP_MEMBER_COUNT then
|
||
return nil -- temporary disable tooltips in raids, we should make a proper fix
|
||
end
|
||
|
||
--Do not remove! This is the datastrucutre for tooltipData!
|
||
--[[tooltipdata[questId] = {
|
||
title = coloredTitle,
|
||
objectivesText = {
|
||
[objectiveIndex] = {
|
||
[playerName] = {
|
||
[color] = color,
|
||
[text] = text
|
||
}
|
||
}
|
||
}
|
||
}]]
|
||
--
|
||
local tooltipData = {}
|
||
local tooltipLines = {}
|
||
|
||
if (not QuestieTooltips.lookupByKey[key]) then
|
||
local QuestieLearner = QuestieLoader:ImportModule("QuestieLearner")
|
||
local QuestLogCache = QuestieLoader:ImportModule("QuestLogCache")
|
||
local mode = QuestieLearner and QuestieLearner.GetDataSourceMode and QuestieLearner:GetDataSourceMode() or "auto"
|
||
if QuestieLearner and QuestieLearner.data and mode ~= "static" and mode ~= "none" then
|
||
-- Try to find in learned NPCs or objects
|
||
local id = tonumber(key:sub(3))
|
||
if id then
|
||
if key:sub(1,2) == "m_" then
|
||
local learnedNpc = QuestieLearner.data.npcs[id]
|
||
-- npc[10] from _AddToArray is an array of questIds, not {questId -> objList}
|
||
if learnedNpc and learnedNpc[10] then
|
||
for _, questId in ipairs(learnedNpc[10]) do
|
||
local qData = QuestieLearner.data.quests[questId]
|
||
if qData and qData[10] then
|
||
for slotIdx = 1, #qData[10] do
|
||
local objSlot = qData[10][slotIdx]
|
||
if objSlot then
|
||
for oIndex = 1, #objSlot do
|
||
local objEntry = objSlot[oIndex]
|
||
if objEntry and objEntry[2] then
|
||
local objText = objEntry[2]
|
||
local needed, collected
|
||
local objectives = QuestLogCache.GetQuestObjectives(questId)
|
||
if objectives then
|
||
for _, obj in next, objectives do
|
||
if obj.text and objText and (obj.text == objText or string.find(obj.text, objText, 1, true) or string.find(objText, obj.text, 1, true)) then
|
||
needed = obj.numRequired
|
||
collected = obj.numFulfilled
|
||
break
|
||
end
|
||
end
|
||
end
|
||
QuestieTooltips:RegisterObjectiveTooltip(questId, key, {
|
||
Index = 0,
|
||
Description = objText,
|
||
Needed = needed,
|
||
Collected = collected,
|
||
Update = function(self)
|
||
local objs = QuestLogCache.GetQuestObjectives(questId)
|
||
if objs then
|
||
for _, o in next, objs do
|
||
if o.text and self.Description and (o.text == self.Description or string.find(o.text, self.Description, 1, true) or string.find(self.Description, o.text, 1, true)) then
|
||
self.Needed = o.numRequired
|
||
self.Collected = o.numFulfilled
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
})
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
if learnedNpc.mc and _LearnerTooltipsEnabled() and Questie.db.profile.learnerTooltipShowConfidence ~= false then
|
||
tinsert(tooltipLines, "|cFF5EBAF3(Learned - Confidence: " .. tostring(learnedNpc.mc) .. ")|r")
|
||
end
|
||
end
|
||
elseif key:sub(1,2) == "o_" then
|
||
local learnedObj = QuestieLearner.data.objects[id]
|
||
-- obj[2] from _AddToArray is an array of questIds (questStarts), not {questId -> objList}
|
||
if learnedObj and learnedObj[2] then
|
||
for _, questId in ipairs(learnedObj[2]) do
|
||
local qData = QuestieLearner.data.quests[questId]
|
||
if qData and qData[10] then
|
||
for slotIdx = 1, #qData[10] do
|
||
local objSlot = qData[10][slotIdx]
|
||
if objSlot then
|
||
for oIndex = 1, #objSlot do
|
||
local objEntry = objSlot[oIndex]
|
||
if objEntry and objEntry[2] then
|
||
local objText = objEntry[2]
|
||
local needed, collected
|
||
local objectives = QuestLogCache.GetQuestObjectives(questId)
|
||
if objectives then
|
||
for _, obj in next, objectives do
|
||
if obj.text and objText and (obj.text == objText or string.find(obj.text, objText, 1, true) or string.find(objText, obj.text, 1, true)) then
|
||
needed = obj.numRequired
|
||
collected = obj.numFulfilled
|
||
break
|
||
end
|
||
end
|
||
end
|
||
QuestieTooltips:RegisterObjectiveTooltip(questId, key, {
|
||
Index = 0,
|
||
Description = objText,
|
||
Needed = needed,
|
||
Collected = collected,
|
||
Update = function(self)
|
||
local objs = QuestLogCache.GetQuestObjectives(questId)
|
||
if objs then
|
||
for _, o in next, objs do
|
||
if o.text and self.Description and (o.text == self.Description or string.find(o.text, self.Description, 1, true) or string.find(self.Description, o.text, 1, true)) then
|
||
self.Needed = o.numRequired
|
||
self.Collected = o.numFulfilled
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
})
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
if learnedObj.mc and _LearnerTooltipsEnabled() and Questie.db.profile.learnerTooltipShowConfidence ~= false then
|
||
tinsert(tooltipLines, "|cFF5EBAF3(Learned - Confidence: " .. tostring(learnedObj.mc) .. ")|r")
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if QuestieTooltips.lookupByKey[key] then
|
||
local playerName = UnitName("player")
|
||
local hasObjectiveEntries = false
|
||
for _, tooltip in next, QuestieTooltips.lookupByKey[key] do
|
||
if not tooltip.name then
|
||
hasObjectiveEntries = true
|
||
break
|
||
end
|
||
end
|
||
|
||
for k, tooltip in next, QuestieTooltips.lookupByKey[key] do
|
||
if tooltip.name then
|
||
if Questie.db.profile.showQuestsInNpcTooltip then
|
||
local questString = QuestieLib:GetColoredQuestName(tooltip.questId, Questie.db.profile.enableTooltipsQuestLevel, true, true)
|
||
tinsert(tooltipLines, questString)
|
||
if not hasObjectiveEntries then
|
||
local objectiveSummary = _GetQuestObjectiveSummary(tooltip.questId)
|
||
if objectiveSummary then
|
||
for _, objectiveText in ipairs(objectiveSummary) do
|
||
tinsert(tooltipLines, " |cFFcbcbcb" .. objectiveText .. "|r")
|
||
end
|
||
end
|
||
end
|
||
end
|
||
else
|
||
local objective = tooltip.objective
|
||
if objective and not (objective.IsSourceItem or objective.IsRequiredSourceItem) and objective.Update then
|
||
-- Tooltip was registered for a sourceItem or requiredSourceItem and not a real "objective"
|
||
objective:Update()
|
||
end
|
||
|
||
local questId = tooltip.questId
|
||
local objectiveIndex = objective.Index;
|
||
if (not tooltipData[questId]) then
|
||
tooltipData[questId] = {
|
||
title = QuestieLib:GetColoredQuestName(questId, Questie.db.profile.enableTooltipsQuestLevel, true, true)
|
||
}
|
||
end
|
||
|
||
if not QuestiePlayer.currentQuestlog[questId] then
|
||
-- TODO: Is this still required?
|
||
QuestieTooltips.lookupByKey[key][k] = nil
|
||
else
|
||
tooltipData[questId].objectivesText = _InitObjectiveTexts(tooltipData[questId].objectivesText, objectiveIndex, playerName)
|
||
|
||
-- Try to get the name of the NPC/Object from the spawnList if possible
|
||
local creatureName
|
||
local idFromKey = tonumber(key:sub(3))
|
||
if idFromKey and objective.spawnList and objective.spawnList[idFromKey] then
|
||
creatureName = objective.spawnList[idFromKey].Name
|
||
end
|
||
|
||
local text;
|
||
local color = QuestieLib:GetRGBForObjective(objective)
|
||
|
||
if objective.Type == "spell" and objective.spawnList[idFromKey] and objective.spawnList[idFromKey].ItemId then
|
||
text = " " .. color .. tostring(QuestieDB.QueryItemSingle(objective.spawnList[idFromKey].ItemId, "name"));
|
||
elseif objective.Needed then
|
||
text = " " .. color .. tostring(objective.Collected) .. "/" .. tostring(objective.Needed) .. " " .. tostring(objective.Description);
|
||
else
|
||
text = " " .. color .. tostring(objective.Description);
|
||
end
|
||
|
||
-- If we found a creature name, prepend it to the text
|
||
if creatureName then
|
||
text = " |cFFDDDDDD" .. creatureName .. "|r\n " .. text
|
||
end
|
||
|
||
tooltipData[questId].objectivesText[objectiveIndex][playerName] = { ["color"] = color, ["text"] = text };
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
local anotherPlayer = false
|
||
if IsInGroup() then
|
||
anotherPlayer = _FetchTooltipsForGroupMembers(key, tooltipData)
|
||
end
|
||
|
||
local playerName = UnitName("player")
|
||
|
||
for questId, questData in next, tooltipData do
|
||
local hasObjective = false
|
||
local tempObjectives = {}
|
||
for _, playerList in next, questData.objectivesText or {} do
|
||
for objectivePlayerName, objectiveInfo in next, playerList do
|
||
local playerInfo = QuestiePlayer:GetPartyMemberByName(objectivePlayerName)
|
||
local playerColor
|
||
local playerType = ""
|
||
if playerInfo then
|
||
playerColor = "|c" .. playerInfo.colorHex
|
||
elseif QuestieComms.remotePlayerEnabled[objectivePlayerName] and QuestieComms.remoteQuestLogs[questId] and QuestieComms.remoteQuestLogs[questId][objectivePlayerName] and (not Questie.db.profile.onlyPartyShared or UnitInParty(objectivePlayerName)) then
|
||
playerColor = QuestieComms.remotePlayerClasses[playerName]
|
||
if playerColor then
|
||
playerColor = Questie:GetClassColor(playerColor)
|
||
playerType = " (" .. l10n("Nearby") .. ")"
|
||
end
|
||
end
|
||
if objectivePlayerName == playerName and anotherPlayer then -- why did we have this case
|
||
local _, classFilename = UnitClass("player");
|
||
local _, _, _, argbHex = GetClassColor(classFilename)
|
||
objectiveInfo.text = objectiveInfo.text .. " (|c" .. argbHex .. objectivePlayerName .. "|r" .. objectiveInfo.color .. ")|r"
|
||
elseif playerColor and objectivePlayerName ~= playerName then
|
||
objectiveInfo.text = objectiveInfo.text .. " (" .. playerColor .. objectivePlayerName .. "|r" .. objectiveInfo.color .. ")|r" .. playerType
|
||
end
|
||
-- We want the player to be on top.
|
||
if objectivePlayerName == playerName then
|
||
tinsert(tempObjectives, 1, objectiveInfo.text);
|
||
hasObjective = true
|
||
elseif playerColor then
|
||
tinsert(tempObjectives, objectiveInfo.text);
|
||
hasObjective = true
|
||
end
|
||
end
|
||
end
|
||
if hasObjective then
|
||
tinsert(tooltipLines, questData.title);
|
||
for _, text in next, tempObjectives do
|
||
tinsert(tooltipLines, text);
|
||
end
|
||
end
|
||
end
|
||
|
||
-- Append learner spawn data when the learner has recorded this NPC.
|
||
-- 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
|
||
|
||
return tooltipLines
|
||
end
|
||
|
||
_InitObjectiveTexts = function(objectivesText, objectiveIndex, playerName)
|
||
if (not objectivesText) then
|
||
objectivesText = {}
|
||
end
|
||
if (not objectivesText[objectiveIndex]) then
|
||
objectivesText[objectiveIndex] = {}
|
||
end
|
||
if (not objectivesText[objectiveIndex][playerName]) then
|
||
objectivesText[objectiveIndex][playerName] = {}
|
||
end
|
||
return objectivesText
|
||
end
|
||
|
||
function QuestieTooltips:Initialize()
|
||
-- For the clicked item frame.
|
||
ItemRefTooltip:HookScript("OnTooltipSetItem", _QuestieTooltips.AddItemDataToTooltip)
|
||
ItemRefTooltip:HookScript("OnHide", function(self)
|
||
if (not self.IsForbidden) or (not self:IsForbidden()) then -- do we need this here also
|
||
QuestieTooltips.lastGametooltip = ""
|
||
QuestieTooltips.lastItemRefTooltip = ""
|
||
QuestieTooltips.lastGametooltipItem = nil
|
||
QuestieTooltips.lastGametooltipUnit = nil
|
||
QuestieTooltips.lastGametooltipCount = 0
|
||
QuestieTooltips.lastFrameName = "";
|
||
end
|
||
end)
|
||
|
||
-- For the hover frame.
|
||
GameTooltip:HookScript("OnTooltipSetUnit", function(self)
|
||
if QuestiePlayer.numberOfGroupMembers > MAX_GROUP_MEMBER_COUNT then
|
||
-- When in a raid, we want as little code running as possible
|
||
return
|
||
end
|
||
|
||
_QuestieTooltips.AddUnitDataToTooltip(self)
|
||
end)
|
||
GameTooltip:HookScript("OnTooltipSetItem", _QuestieTooltips.AddItemDataToTooltip)
|
||
GameTooltip:HookScript("OnShow", function(self)
|
||
if QuestiePlayer.numberOfGroupMembers > MAX_GROUP_MEMBER_COUNT then
|
||
-- When in a raid, we want as little code running as possible
|
||
return
|
||
end
|
||
|
||
if (not self.IsForbidden) or (not self:IsForbidden()) then -- do we need this here also
|
||
QuestieTooltips.lastGametooltipItem = nil
|
||
QuestieTooltips.lastGametooltipUnit = nil
|
||
QuestieTooltips.lastGametooltipCount = 0
|
||
QuestieTooltips.lastFrameName = "";
|
||
end
|
||
end)
|
||
GameTooltip:HookScript("OnHide", function(self)
|
||
if QuestiePlayer.numberOfGroupMembers > MAX_GROUP_MEMBER_COUNT then
|
||
-- When in a raid, we want as little code running as possible
|
||
return
|
||
end
|
||
|
||
if (not self.IsForbidden) or (not self:IsForbidden()) then -- do we need this here also
|
||
QuestieTooltips.lastGametooltip = ""
|
||
QuestieTooltips.lastItemRefTooltip = ""
|
||
QuestieTooltips.lastGametooltipItem = nil
|
||
QuestieTooltips.lastGametooltipUnit = nil
|
||
QuestieTooltips.lastGametooltipCount = 0
|
||
end
|
||
end)
|
||
|
||
-- Fired whenever the cursor hovers something with a tooltip. And then on every frame.
|
||
-- Throttled to _tooltipUpdateInterval (100ms) to avoid per-frame C API pressure.
|
||
GameTooltip:HookScript("OnUpdate", function(self)
|
||
if QuestiePlayer.numberOfGroupMembers > MAX_GROUP_MEMBER_COUNT then
|
||
return
|
||
end
|
||
|
||
local now = GetTime()
|
||
if now - _tooltipLastUpdate < _tooltipUpdateInterval then return end
|
||
_tooltipLastUpdate = now
|
||
|
||
if (not self.IsForbidden) or (not self:IsForbidden()) then
|
||
-- Only fires for non-unit, non-item, non-spell tooltips (i.e. object/world tooltips)
|
||
local uName, unit = self:GetUnit()
|
||
local iName, link = self:GetItem()
|
||
local sName, spell = self:GetSpell()
|
||
if (uName == nil and unit == nil and iName == nil and link == nil and sName == nil and spell == nil) and (not self.ShownAsMapIcon) then
|
||
local currentText = GameTooltipTextLeft1:GetText()
|
||
if currentText ~= _tooltipLastText
|
||
or (not QuestieTooltips.lastGametooltipCount)
|
||
or _QuestieTooltips:CountTooltip() < QuestieTooltips.lastGametooltipCount
|
||
or QuestieTooltips.lastGametooltipType ~= "object" then
|
||
_QuestieTooltips:AddObjectDataToTooltip(currentText)
|
||
QuestieTooltips.lastGametooltipCount = _QuestieTooltips:CountTooltip()
|
||
_tooltipLastText = currentText
|
||
end
|
||
QuestieTooltips.lastGametooltip = currentText
|
||
end
|
||
end
|
||
end)
|
||
end
|
||
|
||
return QuestieTooltips
|