fix(tracker): group quests under their quest log header for server categories
Ascension files its main quest chain under a header of its own, "Ascension Main Quest", which exists in no zone table. The tracker fell back to the quest's zoneOrSort, and for anything the Learner recorded that is the zone the quest was picked up in -- so the whole chain showed up under "Red Cloud Mesa". A header that resolves to no area is a category the server invented, and the client's own grouping is the only thing that knows about it, so use it. Headers are now mapped in a single pass per draw instead of a walk of the quest log per quest.
This commit is contained in:
@@ -676,27 +676,37 @@ local function GetAreaIdByZoneName(zoneName)
|
|||||||
return l10n:GetAreaIdByLocalName(zoneName)
|
return l10n:GetAreaIdByLocalName(zoneName)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Walk the quest log to find the zone header for a given questId.
|
-- questId -> the header the client filed it under in the quest log. In 3.3.5 those headers are
|
||||||
-- In 3.3.5, zone names appear as isHeader=true entries above their quests.
|
-- isHeader=true entries sitting above the quests they cover. Built in one pass and kept, because
|
||||||
-- Returns the header title string, or nil if not found.
|
-- the tracker asks per quest and redraws often -- walking the log once per quest is quadratic.
|
||||||
|
local questLogHeaders = {}
|
||||||
|
|
||||||
|
local function BuildQuestLogHeaders()
|
||||||
|
local headers = {}
|
||||||
|
local header
|
||||||
|
|
||||||
|
for i = 1, (GetNumQuestLogEntries and GetNumQuestLogEntries() or 0) do
|
||||||
|
local title, _, _, isHeader, _, _, _, logId = GetQuestLogTitle(i)
|
||||||
|
if isHeader then
|
||||||
|
if title and title ~= "" then
|
||||||
|
header = title
|
||||||
|
end
|
||||||
|
elseif logId and header then
|
||||||
|
headers[logId] = header
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
questLogHeaders = headers
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the header title string, or nil if the quest is not in the log under one.
|
||||||
local function GetQuestLogZoneName(questId)
|
local function GetQuestLogZoneName(questId)
|
||||||
local targetIndex = nil
|
if not questLogHeaders[questId] then
|
||||||
local total = GetNumQuestLogEntries and GetNumQuestLogEntries() or 0
|
-- Asked about a quest the last pass did not see, so the log has moved on since.
|
||||||
for i = 1, total do
|
BuildQuestLogHeaders()
|
||||||
local _, _, _, isHeader, _, _, _, logId = GetQuestLogTitle(i)
|
|
||||||
if not isHeader and logId == questId then
|
|
||||||
targetIndex = i
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if not targetIndex then return nil end
|
return questLogHeaders[questId]
|
||||||
for i = targetIndex, 1, -1 do
|
|
||||||
local title, _, _, isHeader = GetQuestLogTitle(i)
|
|
||||||
if isHeader and title and title ~= "" then
|
|
||||||
return title
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _GetZoneName(zoneOrSort, questId, zoneNameOverride)
|
local function _GetZoneName(zoneOrSort, questId, zoneNameOverride)
|
||||||
@@ -707,6 +717,19 @@ local function _GetZoneName(zoneOrSort, questId, zoneNameOverride)
|
|||||||
local zoneName
|
local zoneName
|
||||||
local sortObj = Questie.db.profile.trackerSortObjectives
|
local sortObj = Questie.db.profile.trackerSortObjectives
|
||||||
if sortObj == "byZone" or sortObj == "byZoneComplete" or sortObj == "byZoneCompleteReversed" or sortObj == "byZonePlayerProximity" or sortObj == "byZonePlayerProximityReversed" then
|
if sortObj == "byZone" or sortObj == "byZoneComplete" or sortObj == "byZoneCompleteReversed" or sortObj == "byZonePlayerProximity" or sortObj == "byZonePlayerProximityReversed" then
|
||||||
|
-- A server can file quests under categories of its own -- Ascension's "Ascension Main
|
||||||
|
-- Quest" -- and those exist nowhere in the zone tables, so the quest data points at a zone
|
||||||
|
-- instead: for anything the Learner recorded, whichever zone it was picked up in. A header
|
||||||
|
-- that does not resolve to an area is one of those categories, and the client's own
|
||||||
|
-- grouping is the only thing that knows about it.
|
||||||
|
local logHeader = GetQuestLogZoneName(questId)
|
||||||
|
if logHeader and logHeader ~= "" then
|
||||||
|
local headerAreaId = GetAreaIdByZoneName(logHeader)
|
||||||
|
if (not headerAreaId) or headerAreaId == 0 then
|
||||||
|
return logHeader
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if (zoneOrSort) > 0 then
|
if (zoneOrSort) > 0 then
|
||||||
zoneName = TrackerUtils:GetZoneNameByID(zoneOrSort)
|
zoneName = TrackerUtils:GetZoneNameByID(zoneOrSort)
|
||||||
if not zoneName or zoneName == "Unknown Zone" then
|
if not zoneName or zoneName == "Unknown Zone" then
|
||||||
@@ -813,6 +836,9 @@ function TrackerUtils:GetSortedQuestIds()
|
|||||||
local sortedQuestIds = {}
|
local sortedQuestIds = {}
|
||||||
local questDetails = {}
|
local questDetails = {}
|
||||||
local sortObj = Questie.db.profile.trackerSortObjectives
|
local sortObj = Questie.db.profile.trackerSortObjectives
|
||||||
|
|
||||||
|
-- One walk of the quest log for the whole draw, so the per-quest zone lookups below are reads.
|
||||||
|
BuildQuestLogHeaders()
|
||||||
-- Update quest objectives
|
-- Update quest objectives
|
||||||
|
|
||||||
for questId, quest in pairs(QuestiePlayer.currentQuestlog) do
|
for questId, quest in pairs(QuestiePlayer.currentQuestlog) do
|
||||||
|
|||||||
Reference in New Issue
Block a user