diff --git a/CHANGELOG.md b/CHANGELOG.md index 79e3215..e0751d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ - **[Map - Completed Quest Icon Cleanup Hardened]** (#9) Completed/removed quest cleanup now purges quest-owned frames from Questie's registry, pending map/minimap draw queues, and HBD's active map/minimap pin tables. The removed-quest fallback also snapshots the last known completion state before clearing the quest cache, so Ascension quest-log removals without clean turn-in events are completed instead of misclassified as abandoned. - **[Map - Native POIs Respect Hidden Available-Quest Filters]** (#10, #11) Blizzard/server POI suppression now also hides native available-quest buttons when Questie's own available-quest filters intentionally hide that quest, such as Callboard/repeatable quests below 60 or dungeon quests while dungeon quests are disabled. This covers the case where Questie correctly hides its own `!`, leaving no visible duplicate frame for the older suppression logic to detect. Active quest-log entries are excluded so native turn-in/objective POIs are not suppressed just because Questie lacks a visible frame. - **[Quest Events - Completed Objective Refresh Hardened]** (#21) `QUEST_WATCH_UPDATE` now dirties the updated quest and schedules debounced quest-log scans itself instead of relying on a later `QUEST_LOG_UPDATE` that Ascension may not send. A second delayed pass catches server-side objective-counter lag, so fully completed objective pins are removed and the finisher pin can replace them without waiting for the periodic refresh. +- **[Map - Patrol Quest Giver Deduping]** (#9) Quest starters and finishers with waypoint route data now draw one quest icon at the route start plus the route line, instead of drawing every raw spawn point as a separate `!` / `?` in the same zone. Static multi-location NPCs without waypoint routes still show all known locations. - **[Options - Instant Quest Text Toggle]** Fixed the General tab "Enable Instant Quest Text" checkbox so it can be toggled even when the client reports the backing `instantQuestText` CVar as unset before the first write. - **[Learner - Secondary Tooltip Without Spawn Coordinates]** Unit-hover learner tooltips now still open the secondary learner tooltip when the learner has confidence data but no recorded spawn coordinates yet. The normal unit tooltip suppression path also suppresses the old inline learner confidence line, so secondary mode no longer leaks learner-only lines back into the main tooltip. - **[Map - Suppress Duplicate Native Quest POIs]** Rather than globally disabling the server/Blizzard objective POIs, Questie now keeps them enabled and hides only the individual Blizzard POI buttons for quests that already have a visible Questie POI (per-quest duplicate-POI suppression in `QuestieCompat`, hooked at init). Blizzard POIs still appear for quests Questie does not cover, but no longer stack on top of Questie's own objective icons. diff --git a/Modules/Quest/AvailableQuests.lua b/Modules/Quest/AvailableQuests.lua index f331ea9..1353cfb 100644 --- a/Modules/Quest/AvailableQuests.lua +++ b/Modules/Quest/AvailableQuests.lua @@ -41,6 +41,14 @@ local dungeons = ZoneDB:GetDungeons() local _CalculateAvailableQuests, _DrawChildQuests, _AddStarter, _DrawAvailableQuest, _GetQuestIcon, _GetIconScaleForAvailable, _HasProperDistanceToAlreadyAddedSpawns +local function _GetFirstWaypointCoord(waypoints) + if waypoints and waypoints[1] and waypoints[1][1] and waypoints[1][1][1] and waypoints[1][1][2] then + return waypoints[1][1] + end + + return nil +end + ---@param callback function | nil function AvailableQuests.CalculateAndDrawAll(callback) Questie:Debug(Questie.DEBUG_INFO, "[AvailableQuests.CalculateAndDrawAll]") @@ -348,7 +356,8 @@ _AddStarter = function(starter, quest, tooltipKey) local zoneId, spawns = next(starter.spawns or {}) while zoneId do local alreadyAddedSpawns = {} - if spawns then + local waypointStart = starter.waypoints and _GetFirstWaypointCoord(starter.waypoints[zoneId]) + if spawns and not waypointStart then local spawnIndex = 1 while spawns[spawnIndex] do local coords = spawns[spawnIndex] @@ -396,7 +405,8 @@ _AddStarter = function(starter, quest, tooltipKey) if starter.waypoints then local zone, waypoints = next(starter.waypoints or {}) while zone do - if not dungeons[zone] and waypoints[1] and waypoints[1][1] and waypoints[1][1][1] then + local waypointStart = _GetFirstWaypointCoord(waypoints) + if not dungeons[zone] and waypointStart then if not starterIcons[zone] then local data = { Id = quest.Id, @@ -408,10 +418,12 @@ _AddStarter = function(starter, quest, tooltipKey) Name = starter.name, IsObjectiveNote = false, } - starterIcons[zone] = QuestieMap:DrawWorldIcon(data, zone, waypoints[1][1][1], waypoints[1][1][2]) - starterLocs[zone] = { waypoints[1][1][1], waypoints[1][1][2] } + starterIcons[zone] = QuestieMap:DrawWorldIcon(data, zone, waypointStart[1], waypointStart[2]) + starterLocs[zone] = { waypointStart[1], waypointStart[2] } + end + if starterIcons[zone] then + QuestieMap:DrawWaypoints(starterIcons[zone], waypoints, zone) end - QuestieMap:DrawWaypoints(starterIcons[zone], waypoints, zone) end zone, waypoints = next(starter.waypoints, zone) end diff --git a/Modules/Quest/QuestieQuest.lua b/Modules/Quest/QuestieQuest.lua index 9a6c4c5..34d070d 100644 --- a/Modules/Quest/QuestieQuest.lua +++ b/Modules/Quest/QuestieQuest.lua @@ -1326,6 +1326,14 @@ local function _GetIconScaleForAvailable() return Questie.db.profile.availableScale or 1.3 end +local function _GetFirstWaypointCoord(waypoints) + if waypoints and waypoints[1] and waypoints[1][1] and waypoints[1][1][1] and waypoints[1][1][2] then + return waypoints[1][1] + end + + return nil +end + ---@param quest Quest function QuestieQuest:AddFinisher(quest) --We should never ever add the quest if IsQuestFlaggedComplete true. @@ -1413,7 +1421,8 @@ function QuestieQuest:AddFinisher(quest) local finisherZone, spawns = next(finisher.spawns or {}) while finisherZone do - if (finisherZone ~= nil and spawns ~= nil) then + local waypointStart = finisher.waypoints and _GetFirstWaypointCoord(finisher.waypoints[finisherZone]) + if (finisherZone ~= nil and spawns ~= nil and not waypointStart) then local _, coords = next(spawns) while _ do local data = { @@ -1469,8 +1478,9 @@ function QuestieQuest:AddFinisher(quest) if finisher.waypoints then local zone, waypoints = next(finisher.waypoints) while zone do - if (not ZoneDB.IsDungeonZone(zone)) then - if not finisherIcons[zone] and waypoints[1] and waypoints[1][1] and waypoints[1][1][1] then + local waypointStart = _GetFirstWaypointCoord(waypoints) + if (not ZoneDB.IsDungeonZone(zone)) and waypointStart then + if not finisherIcons[zone] then local data = { Id = questId, Icon = Questie.ICON_TYPE_COMPLETE, @@ -1490,12 +1500,13 @@ function QuestieQuest:AddFinisher(quest) data.Icon = Questie.ICON_TYPE_REPEATABLE_COMPLETE end - finisherIcons[zone] = QuestieMap:DrawWorldIcon(data, zone, waypoints[1][1][1], - waypoints[1][1][2]) - finisherLocs[zone] = { waypoints[1][1][1], waypoints[1][1][2] } + finisherIcons[zone] = QuestieMap:DrawWorldIcon(data, zone, waypointStart[1], waypointStart[2]) + finisherLocs[zone] = { waypointStart[1], waypointStart[2] } end - QuestieMap:DrawWaypoints(finisherIcons[zone], waypoints, zone) + if finisherIcons[zone] then + QuestieMap:DrawWaypoints(finisherIcons[zone], waypoints, zone) + end end zone, waypoints = next(finisher.waypoints, zone) end