feat: Add Arrow options tab with scale, transparency, and debug settings; Fix zone filter bug that broke auto-tracking; Update .gitattributes and .gitignore to properly hide dev files from releases

This commit is contained in:
Xurkon
2026-04-02 18:21:30 -05:00
parent 9d68ba5d64
commit 67255ca5fb
12 changed files with 373 additions and 57 deletions
+113 -16
View File
@@ -67,6 +67,13 @@ local function _GetArrowScale()
return Questie.db.profile.arrowScale or 1
end
local function _GetArrowAlpha()
if not Questie or not Questie.db or not Questie.db.profile then
return 1.0
end
return Questie.db.profile.arrowAlpha or 1.0
end
local function _SetArrowScale(scale)
if not Questie or not Questie.db or not Questie.db.profile then
return
@@ -424,7 +431,8 @@ local function _CollectFinisherSpawns(finisher, quest)
local zone = value[1]
local x = value[2]
local y = value[3]
if not (autoLogic and zone ~= pZone and zone ~= pMap) then
-- Zone filtering disabled (zone ID vs area ID mismatch)
if true then
local uiMapId = ZoneDB:GetUiMapIdByAreaId(zone)
if uiMapId and x and y then
local tX, tY, tInst = HBD:GetWorldCoordinatesFromZone(x / 100.0, y / 100.0, uiMapId)
@@ -442,7 +450,8 @@ local function _CollectFinisherSpawns(finisher, quest)
end
end
else
if not (autoLogic and finisherZone ~= pZone and finisherZone ~= pMap) then
-- Zone filtering disabled (same zone ID vs area ID mismatch issue)
if true then
local x = coords[1]
local y = coords[2]
local uiMapId = ZoneDB:GetUiMapIdByAreaId(finisherZone)
@@ -467,7 +476,8 @@ local function _CollectFinisherSpawns(finisher, quest)
end
if finisher.waypoints then
for zone, waypoints in pairs(finisher.waypoints) do
if not (autoLogic and zone ~= pZone and zone ~= pMap) then
-- Zone filtering disabled (same zone ID vs area ID mismatch issue)
if true then
if waypoints and waypoints[1] and waypoints[1][1] and waypoints[1][1][1] then
local x = waypoints[1][1][1]
local y = waypoints[1][1][2]
@@ -501,18 +511,39 @@ local function _CollectObjective(objective, quest)
end
local pX, pY, pInst = _arrow_playerX, _arrow_playerY, _arrow_playerInstance
local autoLogic, pZone, pMap = _arrow_usingAutoLogic, _arrow_playerZoneId, _arrow_playerUiMapId
local debugCollect = Questie and Questie.db and Questie.db.profile and Questie.db.profile.debugArrow
if debugCollect then
print(string.format(" _CollectObjective: spawnList=%s", objective.spawnList and "yes" or "nil"))
end
if not objective.spawnList then return end
for _, spawnData in pairs(objective.spawnList) do
if debugCollect then
print(string.format(" spawnData=%s Spawns=%s", spawnData and "yes" or "nil", spawnData and spawnData.Spawns and "yes" or "nil"))
end
if spawnData and spawnData.Spawns then
for zone, spawns in pairs(spawnData.Spawns) do
if not (autoLogic and zone ~= pZone and zone ~= pMap) then
-- Zone filtering is disabled in auto mode because zone IDs and area IDs
-- are different systems that don't directly compare. The distance
-- calculation handles instance mismatches.
local zoneFiltered = false -- Disabled: autoLogic and zone ~= pZone and zone ~= pMap
if debugCollect then
print(string.format(" zone=%s filtered=%s (pZone=%s pMap=%s)", tostring(zone), tostring(zoneFiltered), tostring(pZone), tostring(pMap)))
end
if not zoneFiltered then
for _, spawn in pairs(spawns) do
local uiMapId = ZoneDB:GetUiMapIdByAreaId(zone)
if debugCollect then
print(string.format(" spawn=(%.1f,%.1f) uiMapId=%s", spawn[1], spawn[2], tostring(uiMapId)))
end
if uiMapId then
local tX, tY, tInst = HBD:GetWorldCoordinatesFromZone(spawn[1] / 100.0, spawn[2] / 100.0, uiMapId)
if tX and tY and tInst then
local dist = HBD:GetWorldDistance(tInst, pX, pY, tX, tY)
if dist then
if tInst ~= pInst then dist = 500000 + dist * 100 end
if debugCollect then
print(string.format(" ADDED dist=%.0f", dist))
end
table.insert(sortedTargets, {
x = spawn[1], y = spawn[2], uiMapId = uiMapId,
title = quest.name, questLevel = quest.level,
@@ -563,6 +594,8 @@ function QuestieArrow:UpdateNearestTargets()
local function _CollectQuestTargets(quest)
if not quest then return end
local debugCollect = Questie and Questie.db and Questie.db.profile and Questie.db.profile.debugArrow
-- Avoid spamming QuestieQuest:PopulateQuestLogInfo (it can trigger marker rebuilds and flicker).
-- Only populate when objective completion flags are missing, and throttle per quest id.
if QuestieQuest and QuestieQuest.PopulateQuestLogInfo and quest.Id then
@@ -585,6 +618,14 @@ function QuestieArrow:UpdateNearestTargets()
local isComplete = quest.isComplete or (QuestieDB.IsComplete(quest.Id) == 1)
if isComplete then quest.isComplete = true end
if debugCollect then
print(string.format(" _CollectQuestTargets: %s isComplete=%s hasObjectives=%s hasSpecialObjectives=%s hasFinisher=%s",
tostring(quest.name), tostring(isComplete),
tostring(quest.Objectives ~= nil),
tostring(quest.SpecialObjectives ~= nil),
tostring(quest.Finisher ~= nil)))
end
-- _GetCompleteIconType, _CollectFinisherSpawns, _CollectObjective are hoisted
-- to module level above; no closures are created here.
@@ -604,11 +645,15 @@ function QuestieArrow:UpdateNearestTargets()
end
if quest.Objectives then
if debugCollect then print(string.format(" Collecting %d objectives", #quest.Objectives)) end
for _, objective in pairs(quest.Objectives) do
_CollectObjective(objective, quest)
end
else
if debugCollect then print(" No Objectives") end
end
if quest.SpecialObjectives then
if debugCollect then print(string.format(" Collecting %d special objectives", #quest.SpecialObjectives)) end
for _, objective in pairs(quest.SpecialObjectives) do
_CollectObjective(objective, quest)
end
@@ -616,22 +661,36 @@ function QuestieArrow:UpdateNearestTargets()
end
if QuestiePlayer and QuestiePlayer.currentQuestlog then
local debugCollect = Questie and Questie.db and Questie.db.profile and Questie.db.profile.debugArrow
for questId, quest in pairs(QuestiePlayer.currentQuestlog) do
if debugCollect then
print(string.format("Processing questId=%d type=%s", questId, type(quest)))
end
if type(quest) == "number" then
if QuestieDB and QuestieDB.GetQuest then
quest = QuestieDB.GetQuest(questId)
end
end
if type(quest) == "table" then
local shouldTrack = false
if usingAutoLogic then
-- If using auto logic (implicit or explicit), verify not explicitly hidden
if not Questie.db.char.AutoUntrackedQuests[questId] then
if not Questie.db.char.AutoUntrackedQuests or not Questie.db.char.AutoUntrackedQuests[questId] then
shouldTrack = true
end
else
-- Strict manual tracking
if Questie.db.char.TrackedQuests[questId] then
if Questie.db.char.TrackedQuests and Questie.db.char.TrackedQuests[questId] then
shouldTrack = true
end
end
if debugCollect then
print(string.format(" questId=%d shouldTrack=%s usingAutoLogic=%s", questId, tostring(shouldTrack), tostring(usingAutoLogic)))
end
if shouldTrack then
if debugCollect then
print(string.format(" Calling _CollectQuestTargets for %s", tostring(quest.name)))
end
_CollectQuestTargets(quest)
end
end
@@ -650,16 +709,13 @@ function QuestieArrow:Refresh()
return
end
if hasManualTarget then
EnsureArrowFrame()
arrowFrame:Show()
return
end
QuestieArrow:UpdateNearestTargets()
EnsureArrowFrame()
local alpha = _GetArrowAlpha()
if sortedTargets[1] then
arrowFrame:SetAlpha(alpha)
arrowFrame:Show()
else
arrowFrame:Hide()
@@ -688,6 +744,7 @@ function QuestieArrow:SetTarget(title, zoneOrUiMapId, x, y)
} }
EnsureArrowFrame()
arrowFrame:SetAlpha(_GetArrowAlpha())
arrowFrame:Show()
end
@@ -741,6 +798,43 @@ function QuestieArrow:PrintTargetCoords()
print(" Distance: " .. string.format("%.0f", target.distance))
end
function QuestieArrow:DebugPrint()
print("=== Questie Arrow Debug ===")
print("sortedTargets count: " .. tostring(#sortedTargets))
print("hasManualTarget: " .. tostring(hasManualTarget))
print("_arrow_usingAutoLogic: " .. tostring(_arrow_usingAutoLogic))
print("_arrow_playerX: " .. tostring(_arrow_playerX))
print("_arrow_playerY: " .. tostring(_arrow_playerY))
print("_arrow_playerZoneId: " .. tostring(_arrow_playerZoneId))
print("_arrow_playerUiMapId: " .. tostring(_arrow_playerUiMapId))
if Questie and Questie.db and Questie.db.profile then
print("autoTrackQuests: " .. tostring(Questie.db.profile.autoTrackQuests))
end
if Questie and Questie.db and Questie.db.char then
local tracked = Questie.db.char.TrackedQuests or {}
local autoUntracked = Questie.db.char.AutoUntrackedQuests or {}
local trackedCount = 0
for _ in pairs(tracked) do trackedCount = trackedCount + 1 end
local autoUntrackedCount = 0
for _ in pairs(autoUntracked) do autoUntrackedCount = autoUntrackedCount + 1 end
print("TrackedQuests count: " .. tostring(trackedCount))
print("AutoUntrackedQuests count: " .. tostring(autoUntrackedCount))
end
if QuestiePlayer and QuestiePlayer.currentQuestlog then
local count = 0
for _ in pairs(QuestiePlayer.currentQuestlog) do count = count + 1 end
print("currentQuestlog count: " .. tostring(count))
end
if sortedTargets and #sortedTargets > 0 then
print("First 3 targets:")
for i = 1, math.min(3, #sortedTargets) do
local t = sortedTargets[i]
print(string.format(" [%d] %s (%.1f, %.1f) dist=%.0f", i, tostring(t.title), t.x, t.y, t.distance))
end
end
print("========================")
end
-- Also expose sortedTargets for external access
function QuestieArrow:GetTargets()
return sortedTargets
@@ -750,6 +844,9 @@ end
local _OriginalRefresh = QuestieArrow.Refresh
QuestieArrow.Refresh = function(self, ...)
_OriginalRefresh(self, ...)
-- You can uncomment the line below to see debug output every refresh:
-- QuestieArrow:PrintTargetCoords()
if Questie and Questie.db and Questie.db.profile and Questie.db.profile.debugArrow then
if sortedTargets and sortedTargets[1] then
QuestieArrow:PrintTargetCoords()
end
end
end
@@ -0,0 +1,164 @@
-------------------------
--Import modules.
-------------------------
---@type QuestieOptions
local QuestieOptions = QuestieLoader:ImportModule("QuestieOptions")
---@type QuestieOptionsUtils
local QuestieOptionsUtils = QuestieLoader:ImportModule("QuestieOptionsUtils")
---@type QuestieArrow
local QuestieArrow = QuestieLoader:ImportModule("QuestieArrow")
---@type QuestieTracker
local QuestieTracker = QuestieLoader:ImportModule("QuestieTracker")
---@type l10n
local l10n = QuestieLoader:ImportModule("l10n")
QuestieOptions.tabs.arrow = { ... }
function QuestieOptions.tabs.arrow:Initialize()
return {
name = function() return l10n('Arrow') end,
type = "group",
order = 2.5,
args = {
arrow_header = {
type = "header",
order = 1,
name = function() return l10n('Arrow Options') end,
},
arrowEnabled = {
type = "toggle",
order = 2,
width = 1.5,
name = function() return l10n("Enable Arrow") end,
desc = function() return l10n("Show the Questie arrow and auto-track the nearest objective or turn-in location.") end,
get = function() return Questie.db.profile.arrowEnabled ~= false end,
set = function(_, value)
Questie.db.profile.arrowEnabled = value
if QuestieArrow and QuestieArrow.Refresh then
if not value and QuestieArrow.ClearTarget then
QuestieArrow:ClearTarget()
end
QuestieArrow:Refresh()
end
end,
},
arrow_spacer_1 = QuestieOptionsUtils:Spacer(3),
arrow_scale = {
type = "range",
order = 4,
width = 1.5,
name = function() return l10n("Arrow Scale") end,
desc = function() return l10n("Change the size of the arrow") end,
min = 0.5,
max = 2.0,
step = 0.05,
get = function() return Questie.db.profile.arrowScale or 1 end,
set = function(_, value)
Questie.db.profile.arrowScale = value
if QuestieArrow and QuestieArrow.Refresh then
QuestieArrow:Refresh()
end
end,
},
arrow_alpha = {
type = "range",
order = 5,
width = 1.5,
name = function() return l10n("Arrow Transparency") end,
desc = function() return l10n("Change the transparency of the arrow") end,
min = 0.1,
max = 1.0,
step = 0.05,
get = function() return Questie.db.profile.arrowAlpha or 1.0 end,
set = function(_, value)
Questie.db.profile.arrowAlpha = value
if QuestieArrow and QuestieArrow.Refresh then
QuestieArrow:Refresh()
end
end,
},
arrow_spacer_2 = QuestieOptionsUtils:Spacer(6),
autoTrackQuests = {
type = "toggle",
order = 7,
width = 1.5,
name = function() return l10n("Auto-track Quests") end,
desc = function() return l10n("Automatically track all quests in your quest log. If disabled, only manually tracked quests will show on the arrow.") end,
get = function() return Questie.db.profile.autoTrackQuests end,
set = function(_, value)
Questie.db.profile.autoTrackQuests = value
if QuestieTracker and QuestieTracker.Update then
QuestieTracker:Update()
end
if QuestieArrow and QuestieArrow.Refresh then
QuestieArrow:Refresh()
end
end,
},
arrow_spacer_3 = QuestieOptionsUtils:Spacer(8),
resetArrowPosition = {
type = "execute",
order = 9,
width = 1.0,
name = function() return l10n("Reset Arrow Position") end,
desc = function() return l10n("Reset the arrow position to the center of the screen") end,
func = function()
Questie.db.profile.arrowPosition = nil
if QuestieArrow and QuestieArrow.Refresh then
QuestieArrow:Refresh()
end
end,
},
arrow_spacer_4 = QuestieOptionsUtils:Spacer(10),
debugArrow = {
type = "toggle",
order = 11,
width = 1.5,
name = function() return l10n("Debug Arrow") end,
desc = function() return l10n("Show debug information about the arrow target in chat") end,
get = function() return Questie.db.profile.debugArrow end,
set = function(_, value)
Questie.db.profile.debugArrow = value
end,
},
printArrowTarget = {
type = "execute",
order = 12,
width = 1.0,
name = function() return l10n("Print Current Target") end,
desc = function() return l10n("Print the current arrow target coordinates to chat") end,
func = function()
if QuestieArrow and QuestieArrow.PrintTargetCoords then
QuestieArrow:PrintTargetCoords()
end
end,
},
debugPrintArrow = {
type = "execute",
order = 12.5,
width = 1.0,
name = function() return l10n("Debug Print Arrow State") end,
desc = function() return l10n("Print detailed debug info about arrow state to chat") end,
func = function()
if QuestieArrow and QuestieArrow.DebugPrint then
QuestieArrow:DebugPrint()
end
end,
},
clearArrowTarget = {
type = "execute",
order = 13,
width = 1.0,
name = function() return l10n("Clear Target") end,
desc = function() return l10n("Clear the current arrow target and resume auto-tracking") end,
func = function()
if QuestieArrow and QuestieArrow.ClearTarget then
QuestieArrow:ClearTarget()
QuestieArrow:Refresh()
end
end,
},
},
}
end
+3
View File
@@ -123,6 +123,8 @@ _CreateOptionsTable = function()
--coroutine.yield()
local icons_tab = QuestieOptions.tabs.icons:Initialize()
coroutine.yield()
local arrow_tab = QuestieOptions.tabs.arrow:Initialize()
coroutine.yield()
local tracker_tab = QuestieOptions.tabs.tracker:Initialize()
coroutine.yield()
local auto_tab = QuestieOptions.tabs.auto:Initialize()
@@ -154,6 +156,7 @@ _CreateOptionsTable = function()
--minimap_tab = minimap_tab,
--map_tab = map_tab,
icons_tab = icons_tab,
arrow_tab = arrow_tab,
tracker_tab = tracker_tab,
auto_tab = auto_tab,
--tooltip_tab = tooltip_tab,
@@ -51,6 +51,8 @@ function QuestieOptionsDefaults:Load()
questMinimapObjectiveColors = false,
arrowEnabled = true,
arrowScale = 1,
arrowAlpha = 1.0,
debugArrow = false,
enableObjectives = true,
enableTurnins = true,
enableAvailable = true,