fix: real-time minimap pins + defensive GetAchievementNumCriteria shim
1. _InvalidateSpawnListsForNPC was setting objective.AlreadySpawned = nil,
causing _DetermineIconsToDraw to crash on nil-index when trying to draw
updated pins. The xpcall wrapper in UpdateObjectiveNotes swallowed the
error silently, so no icons appeared.
Fix: unload existing map/minimap icons explicitly, then set
AlreadySpawned = {} (empty table) instead of nil. Also clear
hasRegisteredTooltips so tooltips refresh.
2. Added GetAchievementNumCriteria defensive shim for Ascension servers
with incomplete achievement databases. Returns 0 for invalid IDs
instead of hard-erroring in Blizzard's WorldMapFrame.
This commit is contained in:
@@ -604,6 +604,24 @@ QuestieCompat.IsAchievementCompleted = QuestieCompat.IsAchievementCompleted or f
|
|||||||
return completed or false
|
return completed or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- GetAchievementNumCriteria Shim
|
||||||
|
-- Ascension and some custom servers have incomplete achievement databases.
|
||||||
|
-- Blizzard's WorldMapFrame calls this with invalid IDs, causing a hard error.
|
||||||
|
-- Wrap the global to return 0 for invalid inputs so the UI doesn't break.
|
||||||
|
do
|
||||||
|
local _original = GetAchievementNumCriteria
|
||||||
|
GetAchievementNumCriteria = function(achievementID)
|
||||||
|
if type(achievementID) ~= "number" or achievementID <= 0 then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
local ok, numCriteria = pcall(_original, achievementID)
|
||||||
|
if ok then
|
||||||
|
return numCriteria or 0
|
||||||
|
end
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- LibUIDropDownMenu Shim
|
--- LibUIDropDownMenu Shim
|
||||||
QuestieCompat.LibUIDropDownMenu = QuestieCompat.LibUIDropDownMenu or {}
|
QuestieCompat.LibUIDropDownMenu = QuestieCompat.LibUIDropDownMenu or {}
|
||||||
QuestieCompat.LibUIDropDownMenu.UIDropDownMenu_Menu_NewSize = function()
|
QuestieCompat.LibUIDropDownMenu.UIDropDownMenu_Menu_NewSize = function()
|
||||||
|
|||||||
@@ -309,8 +309,9 @@ local function _RefreshActiveQuestPins(questIdSet)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Invalidates cached objective.spawnList for any active quest whose objectives
|
-- Invalidates cached objective.spawnList for any active quest whose objectives
|
||||||
-- reference the given npcId. This forces the map system to rebuild spawn lists
|
-- reference the given npcId. Unloads existing world/minimap icons, resets
|
||||||
-- from QuestieDB on the next update, picking up newly learned coordinates.
|
-- tooltip registration, and forces the map system to rebuild spawn lists from
|
||||||
|
-- QuestieDB on the next update — picking up newly learned coordinates in real time.
|
||||||
local function _InvalidateSpawnListsForNPC(npcId)
|
local function _InvalidateSpawnListsForNPC(npcId)
|
||||||
if not QuestieQuest or not QuestiePlayer or not QuestiePlayer.currentQuestlog then return end
|
if not QuestieQuest or not QuestiePlayer or not QuestiePlayer.currentQuestlog then return end
|
||||||
local timer = (C_Timer) or (QuestieCompat and QuestieCompat.C_Timer)
|
local timer = (C_Timer) or (QuestieCompat and QuestieCompat.C_Timer)
|
||||||
@@ -318,6 +319,7 @@ local function _InvalidateSpawnListsForNPC(npcId)
|
|||||||
for questId, _ in pairs(QuestiePlayer.currentQuestlog) do
|
for questId, _ in pairs(QuestiePlayer.currentQuestlog) do
|
||||||
local quest = QuestieDB.GetQuest and QuestieDB.GetQuest(questId)
|
local quest = QuestieDB.GetQuest and QuestieDB.GetQuest(questId)
|
||||||
if quest and quest.Objectives then
|
if quest and quest.Objectives then
|
||||||
|
local needsUnload = false
|
||||||
for _, objective in pairs(quest.Objectives) do
|
for _, objective in pairs(quest.Objectives) do
|
||||||
local shouldInvalidate = false
|
local shouldInvalidate = false
|
||||||
-- Monster objectives reference NPCs directly in spawnList keys
|
-- Monster objectives reference NPCs directly in spawnList keys
|
||||||
@@ -337,12 +339,39 @@ local function _InvalidateSpawnListsForNPC(npcId)
|
|||||||
shouldInvalidate = true
|
shouldInvalidate = true
|
||||||
end
|
end
|
||||||
if shouldInvalidate then
|
if shouldInvalidate then
|
||||||
|
-- Unload existing icons manually so frames are removed from map/minimap.
|
||||||
|
-- We can't call QuestieQuest's local _UnloadAlreadySpawnedIcons from here,
|
||||||
|
-- so we iterate the refs directly.
|
||||||
|
if objective.AlreadySpawned then
|
||||||
|
for _, spawn in pairs(objective.AlreadySpawned) do
|
||||||
|
if spawn then
|
||||||
|
if spawn.mapRefs then
|
||||||
|
for _, mapIcon in ipairs(spawn.mapRefs) do
|
||||||
|
if mapIcon and mapIcon.Unload then mapIcon:Unload() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if spawn.minimapRefs then
|
||||||
|
for _, minimapIcon in ipairs(spawn.minimapRefs) do
|
||||||
|
if minimapIcon and minimapIcon.Unload then minimapIcon:Unload() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
objective.spawnList = nil
|
objective.spawnList = nil
|
||||||
objective.AlreadySpawned = nil
|
objective.AlreadySpawned = {} -- empty table, NOT nil (_DetermineIconsToDraw indexes this)
|
||||||
questsToRefresh[questId] = true
|
objective.hasRegisteredTooltips = false
|
||||||
break -- one invalidation per quest is enough
|
objective.registeredItemTooltips = false
|
||||||
|
needsUnload = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if needsUnload then
|
||||||
|
-- Also purge QuestieMap's quest frame registry so no stale refs remain.
|
||||||
|
if QuestieMap and QuestieMap.UnloadQuestFrames then
|
||||||
|
QuestieMap:UnloadQuestFrames(questId)
|
||||||
|
end
|
||||||
|
questsToRefresh[questId] = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
_RefreshActiveQuestPins(questsToRefresh)
|
_RefreshActiveQuestPins(questsToRefresh)
|
||||||
|
|||||||
Reference in New Issue
Block a user