fix(map): robustly hide Callboard/Contract Board quests below 60 (#10)

Ascension board bounties (e.g. NPC 24 'Outlaw's Contract Board') aren't
reliably flagged repeatable, so IsRepeatable missed them and their ! kept
showing below 60. Add QuestieDB.IsBoardQuest (detects starter NPC/object
names containing 'board', cached per quest); the hide-below-60 option now
hides repeatable OR board quests in both the draw path and ShouldBeHidden.
This commit is contained in:
Xurkon
2026-06-10 20:31:22 -05:00
parent e852e02d32
commit 6ad4308940
4 changed files with 39 additions and 2 deletions
+1
View File
@@ -40,6 +40,7 @@
### Bug Fixes ### 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. - **[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. - **[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 133466 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. - **[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 133466 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.
+36
View File
@@ -831,6 +831,42 @@ function QuestieDB.IsRepeatable(questId)
return flags and bitband(flags, 1) ~= 0 return flags and bitband(flags, 1) ~= 0
end 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 ---@param questId number
---@return boolean ---@return boolean
function QuestieDB.IsDailyQuest(questId) function QuestieDB.IsDailyQuest(questId)
+1 -1
View File
@@ -542,7 +542,7 @@ function _Qframe:ShouldBeHidden()
and ((not DailyQuests:IsActiveDailyQuest(questId)) -- hide not-today-dailies and ((not DailyQuests:IsActiveDailyQuest(questId)) -- hide not-today-dailies
or ((not profile.enableAvailable) and normal) or ((not profile.enableAvailable) and normal)
or ((not profile.showRepeatableQuests) and repeatable) 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.showEventQuests) and event)
or ((not profile.showDungeonQuests) and dungeon) or ((not profile.showDungeonQuests) and dungeon)
or ((not profile.showRaidQuests) and raid) or ((not profile.showRaidQuests) and raid)
+1 -1
View File
@@ -166,7 +166,7 @@ _CalculateAvailableQuests = function()
if ( if (
((not showRepeatableQuests) and QuestieDB.IsRepeatable(questId)) or -- Don't show repeatable quests if option is disabled ((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 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 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 ((not showRaidQuests) and QuestieDB.IsRaidQuest(questId)) or -- Don't show raid quests if option is disabled