From cee005fc63d7177485a3a6f5f3ffaaf0327b3659 Mon Sep 17 00:00:00 2001 From: Xurkon Date: Wed, 10 Jun 2026 20:34:20 -0500 Subject: [PATCH] fix(map): pixel-snap minimap icons to align with native blips at fractional scales (#6) At fractional UI scales (e.g. 0.71 game scale + Windows display scaling) the raw fractional pin offset landed icons between physical pixels, rendering blurry and offset from the engine-drawn native quest blips. Snap the offset to a whole physical pixel via the minimap's effective scale so Questie's icons sit on the same grid as native markers. --- CHANGELOG.md | 1 + Compat/HBD.lua | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a3293f..049c069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ ### Bug Fixes +- **[Map - Minimap Icon Pixel Snapping At Fractional Scales]** (#6) Minimap quest icons are now snapped to the physical pixel grid when positioned. At fractional UI scales (e.g. a 0.71 game scale combined with Windows display scaling) the raw fractional offset placed icons between physical pixels, making them render blurry and visibly offset from the engine-drawn native quest blips. Rounding the pin offset to a whole physical pixel (via the minimap's effective scale) keeps Questie's icons on the same grid as the native markers, improving alignment at non-integer scales. - **[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. diff --git a/Compat/HBD.lua b/Compat/HBD.lua index 495dd8a..99f554b 100644 --- a/Compat/HBD.lua +++ b/Compat/HBD.lua @@ -490,7 +490,19 @@ local function drawMinimapPin(pin, data) if dist <= 1 or (data.floatOnEdge and ((pin.texture and pin.texture.a and pin.texture.a ~= 0) or pin.texture == nil)) then pin:Show() pin:ClearAllPoints() - pin:SetPoint("CENTER", pins.Minimap, "CENTER", diffX * minimapWidth, -diffY * minimapHeight) + -- Snap the icon offset to the physical pixel grid. At fractional UI scales (e.g. a + -- 0.71 game scale combined with Windows display scaling) a raw fractional offset lands + -- the icon between physical pixels, so it renders blurry and visibly misaligned with the + -- engine-drawn native quest blips that ARE pixel-aligned (#6). Rounding the offset to a + -- whole physical pixel keeps Questie's pins on the same grid as the native markers. + local ox = diffX * minimapWidth + local oy = -diffY * minimapHeight + local eScale = pins.Minimap:GetEffectiveScale() + if eScale and eScale > 0 then + ox = math.floor(ox * eScale + 0.5) / eScale + oy = math.floor(oy * eScale + 0.5) / eScale + end + pin:SetPoint("CENTER", pins.Minimap, "CENTER", ox, oy) data.onEdge = (dist > 1) else pin:Hide()