diff --git a/CHANGELOG.md b/CHANGELOG.md index e9e23de..7a3293f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ ### Bug Fixes +- **[Map - Hide Callboard Quests: Robust Board Detection]** (#10) The "hide repeatable quests below level 60" option only hid quests flagged repeatable in the DB, but Ascension's Call Board / Contract Board bounties (e.g. NPC 24 "Outlaw's Contract Board") aren't reliably flagged repeatable, so their `!` markers still showed. Added `QuestieDB.IsBoardQuest(questId)` which detects these by their starter NPC/object name containing "board" (cached per quest), and the hide-below-60 option now hides a quest when it is repeatable **or** a board quest — closing the gap in both the available-quest draw path and the icon visibility check. - **[Tooltip - ElvUI Style No Longer On By Default]** (#16) The "ElvUI tooltip style" option shipped enabled by default, so Questie restyled every default WoW tooltip — stripping the border — for users who never asked for it and don't run ElvUI. It is now opt-in (default off), and a one-time migration resets it off for existing installs so their default tooltips return. Users who want the flat style can re-enable it in the General tab. - **[Quest - Turned-In Quests Misclassified As Abandoned]** (#9) On Ascension some turn-ins (notably crafting/auto-complete quests) fire `QUEST_REMOVED` without a preceding `QUEST_TURNED_IN`, so Questie's 1-second abandon timer ran `MarkQuestAsAbandoned`. By then `QuestLogCache.RemoveQuest` had already cleared the quest, so the `IsComplete` check returned 0 and the *turned-in* quest was treated as abandoned — leaving its objective pins and turn-in `?` lingering on the map and minimap. The completion state is now snapshotted at `QUEST_REMOVED` time (while the quest is still in the cache) and used by the abandon timer, so a quest that was complete at removal is correctly completed (pins/`?` cleared) rather than abandoned. - **[Map - Minimap Range Cutoff No Longer Clips Visible Icons]** (#17) The "Minimap Icon Range Cutoff" added in a prior build hid every quest icon beyond its yard value *before* checking whether the icon was within the minimap's visible circle. Because the minimap's view radius is 133–466 yards depending on zoom, a cutoff of 100 (the default) hid icons that were clearly on the minimap — they only appeared once the player was very close. The cutoff now only clips icons that fall *outside* the minimap's visible radius: in HBD's pin renderer it is gated on `dist > 1` (outside the visible circle), and in `QuestieMap`'s minimap `FadeLogic` the effective cutoff is raised to at least the current minimap view radius (read from the new `HBDPins:GetMinimapRadius()`). Icons within the visible minimap always show again; the cutoff still controls how far edge-floating icons reach for far-apart objectives when zoomed out. diff --git a/Database/QuestieDB.lua b/Database/QuestieDB.lua index 2e93624..89a27d1 100644 --- a/Database/QuestieDB.lua +++ b/Database/QuestieDB.lua @@ -831,6 +831,42 @@ function QuestieDB.IsRepeatable(questId) return flags and bitband(flags, 1) ~= 0 end +local _boardQuestCache = {} +--- Detects Ascension "board" quests — the Call Board / Contract Board repeatable +--- bounties (e.g. NPC 24 "Outlaw's Contract Board"). These are given by a starter +--- NPC/object whose name contains "board" but are NOT reliably flagged repeatable in +--- the DB, so QuestieDB.IsRepeatable alone misses them. Used by the "hide repeatable +--- quests below level 60" option so Callboard `!` markers are actually hidden (#10). +--- Result is cached per quest since starter names never change at runtime. +---@param questId number +---@return boolean +function QuestieDB.IsBoardQuest(questId) + local cached = _boardQuestCache[questId] + if cached ~= nil then + return cached + end + + local result = false + local startedBy = QuestieDB.QueryQuestSingle(questId, "startedBy") + if type(startedBy) == "table" then + local function _AnyNameHasBoard(ids, querySingle) + if type(ids) ~= "table" then return false end + for _, id in ipairs(ids) do + local name = querySingle(id, "name") + if type(name) == "string" and string.find(string.lower(name), "board", 1, true) then + return true + end + end + return false + end + result = _AnyNameHasBoard(startedBy[1], QuestieDB.QueryNPCSingle) + or _AnyNameHasBoard(startedBy[2], QuestieDB.QueryObjectSingle) + end + + _boardQuestCache[questId] = result + return result +end + ---@param questId number ---@return boolean function QuestieDB.IsDailyQuest(questId) diff --git a/Modules/FramePool/QuestieFrame.lua b/Modules/FramePool/QuestieFrame.lua index c311cf4..234ec1b 100644 --- a/Modules/FramePool/QuestieFrame.lua +++ b/Modules/FramePool/QuestieFrame.lua @@ -542,7 +542,7 @@ function _Qframe:ShouldBeHidden() and ((not DailyQuests:IsActiveDailyQuest(questId)) -- hide not-today-dailies or ((not profile.enableAvailable) and normal) or ((not profile.showRepeatableQuests) and repeatable) - or (profile.hideRepeatableBelowMaxLevel and repeatable and (UnitLevel("player") or 0) < 60) -- Hide Callboard/repeatable quests below 60 (#10) + or (profile.hideRepeatableBelowMaxLevel and (repeatable or QuestieDB.IsBoardQuest(questId)) and (UnitLevel("player") or 0) < 60) -- Hide Callboard/repeatable quests below 60 (#10) or ((not profile.showEventQuests) and event) or ((not profile.showDungeonQuests) and dungeon) or ((not profile.showRaidQuests) and raid) diff --git a/Modules/Quest/AvailableQuests.lua b/Modules/Quest/AvailableQuests.lua index 1bab3f9..f331ea9 100644 --- a/Modules/Quest/AvailableQuests.lua +++ b/Modules/Quest/AvailableQuests.lua @@ -166,7 +166,7 @@ _CalculateAvailableQuests = function() if ( ((not showRepeatableQuests) and QuestieDB.IsRepeatable(questId)) or -- Don't show repeatable quests if option is disabled - (hideRepeatableBelowMax and QuestieDB.IsRepeatable(questId)) or -- Hide repeatable (Callboard) quests below level 60 (#10) + (hideRepeatableBelowMax and (QuestieDB.IsRepeatable(questId) or QuestieDB.IsBoardQuest(questId))) or -- Hide repeatable / Callboard quests below level 60 (#10) ((not showPvPQuests) and QuestieDB.IsPvPQuest(questId)) or -- Don't show PvP quests if option is disabled ((not showDungeonQuests) and QuestieDB.IsDungeonQuest(questId)) or -- Don't show dungeon quests if option is disabled ((not showRaidQuests) and QuestieDB.IsRaidQuest(questId)) or -- Don't show raid quests if option is disabled