fix: resolve QUEST_ACCEPTED log-index vs questID ambiguity and add quest-log fallback to tracker for DB-unknown quests
This commit is contained in:
+11
-12
@@ -648,18 +648,17 @@ function QuestieLearner:OnQuestComplete()
|
||||
end
|
||||
end
|
||||
|
||||
-- Fires when a quest is accepted; in 3.3.5 the first (and only) arg IS the questID directly
|
||||
function QuestieLearner:OnQuestAccepted(questId)
|
||||
-- Fallback: scan log for an unknown quest in case the server sends log index instead
|
||||
if not questId or questId <= 0 then
|
||||
for i = 1, GetNumQuestLogEntries() do
|
||||
local _, _, _, _, isHeader, _, _, _, id = GetQuestLogTitle(i)
|
||||
if not isHeader and id and id > 0 and not Questie.db.global.learnedData.quests[id] then
|
||||
if not (QuestieDB and QuestieDB.questData and QuestieDB.questData[id]) then
|
||||
questId = id
|
||||
break
|
||||
end
|
||||
end
|
||||
-- Fires when a quest is accepted.
|
||||
-- Ascension 3.3.5 passes the quest log index as the first arg; some builds pass questID directly.
|
||||
-- We detect which by checking if the value could be a log index and resolving via GetQuestLogTitle.
|
||||
function QuestieLearner:OnQuestAccepted(firstArg)
|
||||
local questId = firstArg
|
||||
local maxLog = GetNumQuestLogEntries and GetNumQuestLogEntries() or 25
|
||||
-- If arg looks like a log index (small int ≤ log size), resolve to quest ID via GetQuestLogTitle
|
||||
if firstArg and firstArg > 0 and firstArg <= maxLog then
|
||||
local resolvedId = select(8, GetQuestLogTitle(firstArg))
|
||||
if resolvedId and resolvedId > 0 then
|
||||
questId = resolvedId
|
||||
end
|
||||
end
|
||||
Questie:Debug(Questie.DEBUG_LEARNER, "[QuestieLearner] OnQuestAccepted id=" .. tostring(questId))
|
||||
|
||||
@@ -2375,8 +2375,16 @@ function QuestieTracker:AQW_Insert(index, expire)
|
||||
if Questie.IsSoD then
|
||||
QuestieDebugOffer.QuestTracking(questId)
|
||||
else
|
||||
Questie:Error("Missing quest " ..
|
||||
tostring(questId) .. "," .. tostring(expire) .. " during tracker update")
|
||||
-- Quest not in DB — try building a fallback object from the quest log
|
||||
local fallback = TrackerUtils:BuildFallbackQuest(questId)
|
||||
if fallback then
|
||||
QuestiePlayer.currentQuestlog[questId] = fallback
|
||||
QuestieCombatQueue:Queue(function()
|
||||
QuestieTracker:Update()
|
||||
end)
|
||||
else
|
||||
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieTracker] Quest " .. tostring(questId) .. " not in DB and not in quest log, skipping")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -694,6 +694,54 @@ end
|
||||
|
||||
---@return table sortedQuestIds Table with sorted Quest ID's by Sort Type
|
||||
---@return table questDetails Table with raw quest table from QuestiePlayer.currentQuestLog, percentage completed value per quest, and a "translated" zoneName
|
||||
-- Builds a minimal quest-like object from the quest log for quests not in QuestieDB.
|
||||
-- Returns nil if the quest is not currently in the quest log.
|
||||
function TrackerUtils:BuildFallbackQuest(questId)
|
||||
for i = 1, GetNumQuestLogEntries() do
|
||||
local title, level, _, isHeader, _, isComplete, _, logQuestId = GetQuestLogTitle(i)
|
||||
if not isHeader and logQuestId == questId then
|
||||
-- Parse objectives from the leaderboard
|
||||
local objectives = {}
|
||||
local numObj = GetNumQuestLeaderBoards and GetNumQuestLeaderBoards(i) or 0
|
||||
for j = 1, numObj do
|
||||
local text, _, finished = GetQuestLogLeaderBoard(j, i)
|
||||
if text then
|
||||
-- Parse "Description: X/Y" or just "Description"
|
||||
local collected, needed = string.match(text, ":.-(%d+)/(%d+)%s*$")
|
||||
collected = tonumber(collected) or (finished and 1 or 0)
|
||||
needed = tonumber(needed) or 1
|
||||
objectives[j] = {
|
||||
text = text,
|
||||
Needed = needed,
|
||||
Collected = collected,
|
||||
Finished = finished or (collected >= needed),
|
||||
Type = "fallback",
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local zoneId = GetCurrentMapAreaID and GetCurrentMapAreaID() or 0
|
||||
|
||||
local quest = {
|
||||
Id = questId,
|
||||
name = title or ("Quest " .. questId),
|
||||
level = level or 0,
|
||||
zoneOrSort = zoneId,
|
||||
Objectives = objectives,
|
||||
SpecialObjectives = {},
|
||||
isFallback = true,
|
||||
}
|
||||
-- IsComplete must be a method (called as quest:IsComplete())
|
||||
quest.IsComplete = function(self)
|
||||
return (isComplete == 1 or IsQuestFlaggedCompleted(questId)) and 1 or 0
|
||||
end
|
||||
|
||||
return quest
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function TrackerUtils:GetSortedQuestIds()
|
||||
local sortedQuestIds = {}
|
||||
local questDetails = {}
|
||||
@@ -711,6 +759,16 @@ function TrackerUtils:GetSortedQuestIds()
|
||||
end
|
||||
end
|
||||
|
||||
-- Fallback for quests not in QuestieDB (e.g. custom server quests).
|
||||
-- Build a minimal quest object from the quest log so the tracker can still display it.
|
||||
if type(quest) ~= "table" or not quest.IsComplete or not quest.Objectives then
|
||||
local fallback = TrackerUtils:BuildFallbackQuest(qid)
|
||||
if fallback then
|
||||
quest = fallback
|
||||
QuestiePlayer.currentQuestlog[qid] = fallback
|
||||
end
|
||||
end
|
||||
|
||||
if type(quest) == "table" and quest.IsComplete and quest.Objectives then
|
||||
-- Insert Quest Ids into sortedQuestIds table
|
||||
tinsert(sortedQuestIds, qid)
|
||||
|
||||
Reference in New Issue
Block a user