diff --git a/CHANGELOG.md b/CHANGELOG.md index 69c4ca5..87267ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Bug Fixes - **[Docs - Release Metadata Sync]** Updated the README badge, documentation version badges, and in-game addon version to `v1.6.3`, then tightened the release filters so handoff notes, local dev settings, and other workspace-only artifacts stay out of the exported release archive. +- **[Docs — Minimap Range Cutoff]** Documented the new minimap icon range cutoff slider and its real-time refresh behavior so the published release notes match the current UI and runtime behavior. - **[Fix - Arrow Asset Regression]** Restored the default `Arrow1` asset from the original `XPArrow4.png` source, renamed the bundled image arrows to `Arrow1` through `Arrow4`, regenerated the bundled arrow manifest from the actual image data, and added a busted regression test so `arrowold` remains the only bundled sprite sheet. - **[Fix - Arrow UI / Attachment Redesign]** Reworked the Arrow tab so the arrow and objective text can be detached, reattached, locked independently, and reset independently. Added an attached-gap slider, objective transparency slider, distance-unit selector, larger font sizing, and drop-in preview support for the generated arrow swatches. - **[Fix - Arrow Asset Size Reduction]** Rewrote the bundled image arrows to their visible bounds and saved them with TGA RLE compression, which keeps the same in-game appearance while reducing the arrow asset footprint dramatically. diff --git a/Compat/HBD.lua b/Compat/HBD.lua index 862769c..6661311 100644 --- a/Compat/HBD.lua +++ b/Compat/HBD.lua @@ -468,6 +468,19 @@ local function drawMinimapPin(pin, data) -- data.floatOnEdge is replaced by (data.floatOnEdge and ((pin.texture and pin.texture.a and pin.texture.a ~= 0) or pin.texture == nil)) -- icons will now only float on edge if they have an opacity which is not 0 or if no texture exist. data.distanceFromMinimapCenter = dist + local minimapVisibilityCutoff = pin.minimapVisibilityCutoff + or (Questie and Questie.db and Questie.db.profile and Questie.db.profile.minimapIconRangeCutoff) + if minimapVisibilityCutoff and lastXY and lastYY and data.x and data.y then + local xd, yd = lastXY - data.x, lastYY - data.y + local distance = (xd * xd + yd * yd)^0.5 + if distance > minimapVisibilityCutoff then + pin:Hide() + data.onEdge = nil + data.keep = nil + return + end + end + 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() @@ -708,6 +721,24 @@ local function UpdateMinimapZoom() end end +function pins:RefreshMinimap() + queueFullUpdate = true + UpdateMinimapPins(true) + UpdateMinimapIconPosition() +end + +function pins:SetMinimapVisibilityCutoff(cutoff) + for pin, data in pairs(minimapPins) do + pin.minimapVisibilityCutoff = cutoff + data.minimapVisibilityCutoff = cutoff + end + + for pin, data in pairs(activeMinimapPins) do + pin.minimapVisibilityCutoff = cutoff + data.minimapVisibilityCutoff = cutoff + end +end + ------------------------------------------------------------------------------------------- -- WorldMap data provider diff --git a/Icons/Arrows/AllianceArrow.tga b/Icons/Arrows/AllianceArrow.tga index 4f2c3cf..e0e7ac9 100644 Binary files a/Icons/Arrows/AllianceArrow.tga and b/Icons/Arrows/AllianceArrow.tga differ diff --git a/Icons/Arrows/AllianceArrow_preview.tga b/Icons/Arrows/AllianceArrow_preview.tga index 606585c..3f18e32 100644 Binary files a/Icons/Arrows/AllianceArrow_preview.tga and b/Icons/Arrows/AllianceArrow_preview.tga differ diff --git a/Icons/Arrows/Arrow1.tga b/Icons/Arrows/Arrow1.tga index 302d15c..ddbfadd 100644 Binary files a/Icons/Arrows/Arrow1.tga and b/Icons/Arrows/Arrow1.tga differ diff --git a/Icons/Arrows/Arrow1_preview.tga b/Icons/Arrows/Arrow1_preview.tga index fe3e466..1bd62bb 100644 Binary files a/Icons/Arrows/Arrow1_preview.tga and b/Icons/Arrows/Arrow1_preview.tga differ diff --git a/Icons/Arrows/Arrow2.tga b/Icons/Arrows/Arrow2.tga index 08b88ca..aa47011 100644 Binary files a/Icons/Arrows/Arrow2.tga and b/Icons/Arrows/Arrow2.tga differ diff --git a/Icons/Arrows/Arrow2_preview.tga b/Icons/Arrows/Arrow2_preview.tga index 680a324..1b640bf 100644 Binary files a/Icons/Arrows/Arrow2_preview.tga and b/Icons/Arrows/Arrow2_preview.tga differ diff --git a/Icons/Arrows/Arrow3.tga b/Icons/Arrows/Arrow3.tga index 6c22dbd..14eb740 100644 Binary files a/Icons/Arrows/Arrow3.tga and b/Icons/Arrows/Arrow3.tga differ diff --git a/Icons/Arrows/Arrow3_preview.tga b/Icons/Arrows/Arrow3_preview.tga index 45f3663..b37994e 100644 Binary files a/Icons/Arrows/Arrow3_preview.tga and b/Icons/Arrows/Arrow3_preview.tga differ diff --git a/Icons/Arrows/Arrow4.tga b/Icons/Arrows/Arrow4.tga index 0f32146..d8667d2 100644 Binary files a/Icons/Arrows/Arrow4.tga and b/Icons/Arrows/Arrow4.tga differ diff --git a/Icons/Arrows/Arrow4_preview.tga b/Icons/Arrows/Arrow4_preview.tga index d740ee0..f71fc7d 100644 Binary files a/Icons/Arrows/Arrow4_preview.tga and b/Icons/Arrows/Arrow4_preview.tga differ diff --git a/Icons/Arrows/HordeArrow.tga b/Icons/Arrows/HordeArrow.tga index 8cfdf5f..f54feaf 100644 Binary files a/Icons/Arrows/HordeArrow.tga and b/Icons/Arrows/HordeArrow.tga differ diff --git a/Icons/Arrows/HordeArrow_preview.tga b/Icons/Arrows/HordeArrow_preview.tga index 38e426f..3b69eb2 100644 Binary files a/Icons/Arrows/HordeArrow_preview.tga and b/Icons/Arrows/HordeArrow_preview.tga differ diff --git a/Modules/Arrow/QuestieArrow.lua b/Modules/Arrow/QuestieArrow.lua index efe0d3a..a886ce4 100644 --- a/Modules/Arrow/QuestieArrow.lua +++ b/Modules/Arrow/QuestieArrow.lua @@ -254,7 +254,15 @@ end local function _GetArrowPreviewPath() local style = _GetArrowStyle() - return style.previewPath + if not style then + return nil + end + + if style.previewPath and (type(DoesFileExist) ~= "function" or DoesFileExist(style.previewPath)) then + return style.previewPath + end + + return style.texturePath end local function _IsArrowSpriteSheet() @@ -355,13 +363,9 @@ local function _UpdateObjectiveFramePosition() end if _IsObjectiveAttached() and arrowFrame then - local style = arrowFrame._arrowStyle or _GetArrowStyle() - local inset = (style and style.visualBottomInset) or 0 - local scale = _GetArrowScale() - local visibleBottomOffset = math.floor(inset * scale + 0.5) local gap = _GetObjectiveGap() objectiveFrame:ClearAllPoints() - objectiveFrame:SetPoint("TOP", arrowFrame, "BOTTOM", 0, gap - visibleBottomOffset) + objectiveFrame:SetPoint("TOP", arrowFrame, "BOTTOM", 0, gap) objectiveFrame._useDefaultPosition = false return end @@ -810,9 +814,12 @@ EnsureArrowFrame = function() local dist = HBD:GetWorldDistance(targetInstance, playerX, playerY, targetX, targetY) if dist then local area = 1 - local alpha = dist - area - alpha = alpha > 1 and 1 or alpha - alpha = alpha < 0.5 and 0.5 or alpha + local alpha = 1 + if dist <= area then + alpha = dist / area + alpha = alpha > 1 and 1 or alpha + alpha = alpha < 0.5 and 0.5 or alpha + end local texalpha = (1 - alpha) * 2 texalpha = texalpha > 1 and 1 or texalpha diff --git a/Modules/Arrow/QuestieArrowAssets.lua b/Modules/Arrow/QuestieArrowAssets.lua index e42a120..07ceed4 100644 --- a/Modules/Arrow/QuestieArrowAssets.lua +++ b/Modules/Arrow/QuestieArrowAssets.lua @@ -13,9 +13,9 @@ QuestieArrowAssets.styles = { displayWidth = 71, displayHeight = 96, visualBottomInset = 0, - textureCoordLeft = 0.187500, - textureCoordRight = 0.812500, - textureCoordTop = 0.078125, + textureCoordLeft = 0.195312, + textureCoordRight = 0.808594, + textureCoordTop = 0.093750, textureCoordBottom = 0.917969, }, ["arrow2"] = { @@ -28,7 +28,7 @@ QuestieArrowAssets.styles = { visualBottomInset = 0, textureCoordLeft = 0.082031, textureCoordRight = 0.917969, - textureCoordTop = 0.097656, + textureCoordTop = 0.101562, textureCoordBottom = 0.898438, }, ["arrow3"] = { @@ -36,13 +36,13 @@ QuestieArrowAssets.styles = { texture = "Icons\\Arrows\\Arrow3.tga", preview = "Icons\\Arrows\\Arrow3_preview.tga", mode = "image", - displayWidth = 65, + displayWidth = 66, displayHeight = 96, visualBottomInset = 0, - textureCoordLeft = 0.214844, - textureCoordRight = 0.785156, - textureCoordTop = 0.078125, - textureCoordBottom = 0.914062, + textureCoordLeft = 0.218750, + textureCoordRight = 0.781250, + textureCoordTop = 0.093750, + textureCoordBottom = 0.917969, }, ["arrow4"] = { label = "Arrow 4", @@ -52,21 +52,21 @@ QuestieArrowAssets.styles = { displayWidth = 68, displayHeight = 96, visualBottomInset = 0, - textureCoordLeft = 0.203125, - textureCoordRight = 0.796875, - textureCoordTop = 0.078125, - textureCoordBottom = 0.917969, + textureCoordLeft = 0.347656, + textureCoordRight = 0.648438, + textureCoordTop = 0.289062, + textureCoordBottom = 0.714844, }, ["hordearrow"] = { label = "Horde Arrow", texture = "Icons\\Arrows\\HordeArrow.tga", preview = "Icons\\Arrows\\HordeArrow_preview.tga", mode = "image", - displayWidth = 84, + displayWidth = 120, displayHeight = 96, visualBottomInset = 0, - textureCoordLeft = 0.207031, - textureCoordRight = 0.789062, + textureCoordLeft = 0.078125, + textureCoordRight = 0.917969, textureCoordTop = 0.078125, textureCoordBottom = 0.917969, }, @@ -75,50 +75,11 @@ QuestieArrowAssets.styles = { texture = "Icons\\Arrows\\AllianceArrow.tga", preview = "Icons\\Arrows\\AllianceArrow_preview.tga", mode = "image", - displayWidth = 116, + displayWidth = 177, displayHeight = 96, visualBottomInset = 0, - textureCoordLeft = 0.222656, - textureCoordRight = 0.773438, - textureCoordTop = 0.078125, - textureCoordBottom = 0.917969, - }, - ["minimal1"] = { - label = "Waypoint 1", - texture = "Icons\\Arrows\\Minimal1.tga", - preview = "Icons\\Arrows\\Minimal1_preview.tga", - mode = "image", - displayWidth = 68, - displayHeight = 96, - visualBottomInset = 0, - textureCoordLeft = 0.203125, - textureCoordRight = 0.796875, - textureCoordTop = 0.078125, - textureCoordBottom = 0.917969, - }, - ["minimal2"] = { - label = "Waypoint 2", - texture = "Icons\\Arrows\\Minimal2.tga", - preview = "Icons\\Arrows\\Minimal2_preview.tga", - mode = "image", - displayWidth = 74, - displayHeight = 96, - visualBottomInset = 0, - textureCoordLeft = 0.175781, - textureCoordRight = 0.820312, - textureCoordTop = 0.078125, - textureCoordBottom = 0.917969, - }, - ["minimal3"] = { - label = "Waypoint 3", - texture = "Icons\\Arrows\\Minimal3.tga", - preview = "Icons\\Arrows\\Minimal3_preview.tga", - mode = "image", - displayWidth = 83, - displayHeight = 96, - visualBottomInset = 0, - textureCoordLeft = 0.132812, - textureCoordRight = 0.863281, + textureCoordLeft = 0.078125, + textureCoordRight = 0.917969, textureCoordTop = 0.078125, textureCoordBottom = 0.917969, }, @@ -144,9 +105,6 @@ QuestieArrowAssets.order = { "arrow4", "hordearrow", "alliancearrow", - "minimal1", - "minimal2", - "minimal3", "arrowold", } diff --git a/Modules/Map/QuestieMap.lua b/Modules/Map/QuestieMap.lua index 57502cf..74f0b2d 100644 --- a/Modules/Map/QuestieMap.lua +++ b/Modules/Map/QuestieMap.lua @@ -256,6 +256,7 @@ function QuestieMap:ProcessShownMinimapIcons() while true do count = 0 playerX, playerY = getWorldPos() + xd = (playerX or 0) - (QuestieMap.playerX or 0) yd = (playerY or 0) - (QuestieMap.playerY or 0) totalDistance = totalDistance + (xd * xd + yd * yd) @@ -296,6 +297,30 @@ function QuestieMap:ProcessShownMinimapIcons() end end +function QuestieMap:RefreshMinimapIconVisibility() + if not HBDPins or not HBDPins.activeMinimapPins then + return + end + + local minimapVisibilityCutoff = Questie.db.profile.minimapIconRangeCutoff or 100 + if HBDPins.SetMinimapVisibilityCutoff then + HBDPins:SetMinimapVisibilityCutoff(minimapVisibilityCutoff) + end + if HBDPins.RefreshMinimap then + HBDPins:RefreshMinimap() + end + + for minimapFrame, data in pairs(HBDPins.activeMinimapPins) do + if minimapFrame and minimapFrame.miniMapIcon and minimapFrame.FadeLogic then + minimapFrame.minimapVisibilityCutoff = minimapVisibilityCutoff + minimapFrame:FadeLogic() + if minimapFrame.GlowUpdate then + minimapFrame:GlowUpdate() + end + end + end +end + function QuestieMap:QueueDraw(drawType, ...) if (not isDrawQueueDisabled) then if _G.QuestieDebugPins then @@ -570,6 +595,71 @@ function QuestieMap:DrawManualIcon(data, areaID, x, y, typ) iconMinimap.texture:SetTexture(texture) iconMinimap.texture:SetVertexColor(colorsMinimap[1], colorsMinimap[2], colorsMinimap[3], 1); iconMinimap.miniMapIcon = true; + iconMinimap.minimapVisibilityCutoff = Questie.db.profile.minimapIconRangeCutoff or 100 + + if (not iconMinimap.FadeLogic) then + function iconMinimap:SetFade(value) + if self.lastGlowFade ~= value then + self.lastGlowFade = value + if self.glowTexture then + local r, g, b = self.glowTexture:GetVertexColor() + self.glowTexture:SetVertexColor(r, g, b, value) + end + self.texture:SetVertexColor(colorsMinimap[1], colorsMinimap[2], colorsMinimap[3], value) + end + end + + function iconMinimap:FadeLogic() + local profile = Questie.db.profile + if self.miniMapIcon and self.x and self.y and self.texture and self.UiMapID and self.texture.SetVertexColor and HBD and HBD.GetPlayerZonePosition then + if (QuestieMap.playerX and QuestieMap.playerY) then + local x, y + if not self.worldX then + x, y = HBD:GetWorldCoordinatesFromZone(self.x / 100, self.y / 100, self.UiMapID) + self.worldX = x + self.worldY = y + else + x = self.worldX + y = self.worldY + end + if (x and y) then + local xd = QuestieMap.playerX - x + local yd = QuestieMap.playerY - y + local distance = math.sqrt(xd * xd + yd * yd) + local minimapVisibilityCutoff = self.minimapVisibilityCutoff or profile.minimapIconRangeCutoff or 100 + + if (distance > minimapVisibilityCutoff) then + self:FakeHide() + return + elseif self.hidden then + self:FakeShow() + elseif (distance > profile.fadeLevel) then + local fade = 1 - (math.min(10, (distance - profile.fadeLevel)) * normalizedValue) + self:SetFade(fade) + elseif (distance < profile.fadeOverPlayerDistance) and profile.fadeOverPlayer then + local fadeAmount = profile.fadeOverPlayerLevel + distance * (1 - profile.fadeOverPlayerLevel) / profile.fadeOverPlayerDistance + if self.faded and fadeAmount > profile.iconFadeLevel then + fadeAmount = profile.iconFadeLevel + end + self:SetFade(fadeAmount) + else + if self.faded then + self:SetFade(profile.iconFadeLevel) + else + self:SetFade(1) + end + end + end + else + if self.faded then + self:SetFade(profile.iconFadeLevel) + else + self:SetFade(1) + end + end + end + end + end QuestieMap:QueueDraw(QuestieMap.ICON_MINIMAP_TYPE, Questie, iconMinimap, iconMinimap.UiMapID, x / 100, y / 100, true, true); tinsert(QuestieMap.manualFrames[typ][data.id], iconMinimap:GetName()) @@ -650,6 +740,7 @@ function QuestieMap:DrawWorldIcon(data, areaID, x, y, showFlag) iconMinimap.AreaID = areaID iconMinimap.UiMapID = uiMapId iconMinimap.miniMapIcon = true; + iconMinimap.minimapVisibilityCutoff = Questie.db.profile.minimapIconRangeCutoff or 100 iconMinimap:UpdateTexture(Questie.usedIcons[data.Icon]); if (not iconMinimap.FadeLogic) then @@ -680,9 +771,17 @@ function QuestieMap:DrawWorldIcon(data, areaID, x, y, showFlag) if (x and y) then local xd = QuestieMap.playerX - x local yd = QuestieMap.playerY - y - local distance = math.sqrt(xd * xd + yd * yd) / 10; + local distance = math.sqrt(xd * xd + yd * yd); + local minimapVisibilityCutoff = self.minimapVisibilityCutoff or profile.minimapIconRangeCutoff or 100; - if (distance > profile.fadeLevel) then + -- Hard stop: keep minimap pins from remaining visible beyond + -- the configured minimap range cutoff. + if (distance > minimapVisibilityCutoff) then + self:FakeHide() + return + elseif self.hidden then + self:FakeShow() + elseif (distance > profile.fadeLevel) then local fade = 1 - (math.min(10, (distance - profile.fadeLevel)) * normalizedValue); self:SetFade(fade) elseif (distance < profile.fadeOverPlayerDistance) and profile.fadeOverPlayer then diff --git a/Modules/Options/IconsTab/QuestieOptionsIcons.lua b/Modules/Options/IconsTab/QuestieOptionsIcons.lua index 23294d9..1361b54 100644 --- a/Modules/Options/IconsTab/QuestieOptionsIcons.lua +++ b/Modules/Options/IconsTab/QuestieOptionsIcons.lua @@ -510,6 +510,21 @@ function QuestieOptions.tabs.icons:Initialize() QuestieFramePool:UpdateColorConfig(true, value) end, }, + minimapIconRangeCutoff = { + type = "range", + order = 4.35, + name = function() return l10n('Minimap Icon Range Cutoff'); end, + desc = function() return l10n('How far away minimap icons can remain visible.\n(Default: %s)', optionsDefaults.profile.minimapIconRangeCutoff); end, + width = 3.1, + min = 25, + max = 200, + step = 5, + disabled = function() return ((not Questie.db.profile.enabled) or (not Questie.db.profile.enableMiniMapIcons)); end, + get = function(info) return QuestieOptions:GetProfileValue(info); end, + set = function (info, value) + QuestieOptions:SetProfileValue(info, value) + end, + }, fadeLevel = { type = "range", order = 4.4, diff --git a/Modules/Options/QuestieOptions.lua b/Modules/Options/QuestieOptions.lua index 49b4266..444e431 100644 --- a/Modules/Options/QuestieOptions.lua +++ b/Modules/Options/QuestieOptions.lua @@ -102,10 +102,18 @@ end -- set option value function QuestieOptions:SetProfileValue(info, value) - if debug and Questie.db.profile[info[#info]] ~= value then - Questie:Debug(Questie.DEBUG_SPAM, "DEBUG: global option", info[#info], "changed from '" .. tostring(Questie.db.profile[info[#info]]) .. "' to '" .. tostring(value) .. "'") + local key = info[#info] + if debug and Questie.db.profile[key] ~= value then + Questie:Debug(Questie.DEBUG_SPAM, "DEBUG: global option", key, "changed from '" .. tostring(Questie.db.profile[key]) .. "' to '" .. tostring(value) .. "'") + end + Questie.db.profile[key] = value + + if key == "minimapIconRangeCutoff" then + local QuestieMap = QuestieLoader:ImportModule("QuestieMap") + if QuestieMap and QuestieMap.RefreshMinimapIconVisibility then + QuestieMap:RefreshMinimapIconVisibility() + end end - Questie.db.profile[info[#info]] = value end function QuestieOptions:ClusterRedraw() diff --git a/Modules/Options/QuestieOptionsDefaults.lua b/Modules/Options/QuestieOptionsDefaults.lua index a235706..f206e88 100644 --- a/Modules/Options/QuestieOptionsDefaults.lua +++ b/Modules/Options/QuestieOptionsDefaults.lua @@ -20,7 +20,8 @@ function QuestieOptionsDefaults:Load() objectScale = 1, globalScale = 0.6, globalMiniMapScale = 0.7, - fadeLevel = 20, + minimapIconRangeCutoff = 100, + fadeLevel = 100, fadeOverPlayer = true, fadeOverPlayerLevel = 0.5, fadeOverPlayerDistance = 5, diff --git a/README.md b/README.md index a0c7154..e71be6e 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,6 @@ Bundled arrow assets are detected automatically as either sprite sheets or regul - `Arrow1` through `Arrow4` are the bundled image styles, while `arrowold` remains the only bundled sprite sheet. - `Horde Arrow` and `Alliance Arrow` add faction-themed styles with their insignia built into the art. -- `Waypoint 1` through `Waypoint 3` add a calmer, lower-profile look for players who want something closer to a plain game marker. - The dropdown now uses generated preview swatches from `Icons/Arrows`, so each bundled style shows a live thumbnail instead of a text-only entry. - Image arrows rotate as a single texture and keep their native art, while sprite sheets only use sheet-cell logic when the style is explicitly `arrowold` or a custom sheet is marked as such. - The arrow and objective text can be detached or reattached independently, locked separately, and reset with one-click actions. @@ -224,6 +223,7 @@ Bundled arrow assets are detected automatically as either sprite sheets or regul - Fixed `RequestMapUpdate` logic that caused completed quest icons to persist across zone transitions. - Downgraded spurious `[CRITICAL] No AreaId found for UiMapId` log spam to debug level. On some servers, `C_Map.GetBestMapForUnit` returns a continent-level UiMapId for capital cities; the nil return was already handled gracefully but was incorrectly logged as critical. - Fixed map pins for `killCredit`-type objectives not resolving spawn locations correctly. +- Added a configurable minimap icon range cutoff so players can choose how far away quest icons remain visible before fading out. ### Tooltips diff --git a/docs/changelog.html b/docs/changelog.html index 546010f..e1da012 100644 --- a/docs/changelog.html +++ b/docs/changelog.html @@ -179,6 +179,7 @@

[v1.6.3] — Arrow Redesign, Minimap Pin Drift Fix (Live API + Corrected Pixel Math), Sunstrider Isle Arrow Distance, Map Pins, Tooltip Schema Fixes, QuestData String Safety