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, then tightened the release filters so handoff notes, local dev settings, and other workspace-only artifacts stay out of the exported release archive.Arrow1 through Arrow4) plus one legacy sheet arrow (arrowold). The old default arrow.tga cache path was retired in favor of the new image-specific asset names, and the generator now keeps sheet-mode detection isolated so only arrowold or an explicitly custom sheet can enter the sprite-sheet path.
Icons\\Arrows, with matching generated preview TGAs so the dropdown can show a visible swatch for each style.