annotate WorldMap.lua @ 113:03e4a8b93012 v7.3.0-2

7.3 Updates - Added some map frame adjustments to keep the filter bar from obstructing edge of zone clicks KNOWN ISSUES: - Argus quests can only be filtered when viewing Argus maps - Main Argus map in the WorldMapFrame has misaligned pins; this is due to it using a different map texture from what is used in the teleporter map, so all the POI coordinates are based on that map in the client info
author Nenue
date Tue, 05 Sep 2017 03:14:34 -0400
parents e8b6c5433128
children a4dfdd4f1cf3
rev   line source
Nenue@33 1 -- WorldPlan
Nenue@109 2 -- WorldMap.lua
Nenue@33 3 -- Created: 11/2/2016 3:40 PM
Nenue@33 4 -- %file-revision%
Nenue@72 5
Nenue@75 6 local print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or nop
Nenue@75 7 local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or nop
Nenue@75 8 local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or nop
Nenue@75 9 local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or nop
Nenue@75 10 local mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or nop
Nenue@40 11 local _, db = ...
Nenue@109 12 local Module = {
Nenue@109 13 UsedPositions = {},
Nenue@109 14 }
Nenue@109 15 WorldPlanMapMixin = Module
Nenue@33 16
Nick@64 17 local _G = _G
Nenue@72 18 local type, tostring, tonumber, pairs, ipairs = type, tostring, tonumber, pairs, ipairs
Nenue@33 19 local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo
Nenue@33 20 local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented
Nenue@33 21 local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID
Nick@64 22 local TQ_IsActive = C_TaskQuest.IsActive
Nenue@75 23 local TQ_RequestPreloadRewardData = C_TaskQuest.RequestPreloadRewardData
Nick@64 24 local pairs, ipairs, tinsert, tremove, wipe = pairs, ipairs, tinsert, tremove, table.wipe
Nick@64 25 local GetTaskInfo, GetTasksTable, HaveQuestData = GetTaskInfo, GetTasksTable, HaveQuestData
Nick@64 26 local GetTime = GetTime
Nenue@69 27 local SpellCanTargetQuest, IsQuestIDValidSpellTarget = SpellCanTargetQuest, IsQuestIDValidSpellTarget
Nick@64 28 local tonumber, abs = tonumber, math.abs
Nick@64 29 local GetQuestLogRewardInfo = GetQuestLogRewardInfo
Nick@64 30 local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID
Nenue@72 31 local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete
Nenue@93 32 local HaveQuestRewardData = HaveQuestRewardData
Nenue@93 33 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
Nenue@96 34 local InCombatLockdown, hooksecurefunc = InCombatLockdown, hooksecurefunc
Nenue@33 35
Nenue@69 36 local ToggleButton = {}
Nenue@33 37 local BROKEN_ISLES_ID, DALARAN_ID, AZSUNA_ID, VALSHARAH_ID, HIGHMOUNTAIN_ID, STORMHEIM_ID, SURAMAR_ID, EOA_ID = 1007, 1014, 1015,1018, 1024, 1017, 1033, 1096
Nenue@33 38 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah",
Nenue@33 39 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', }
Nenue@33 40
Nenue@33 41 local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD
Nenue@33 42 local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER
Nenue@33 43 local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT
Nenue@33 44 local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES
Nenue@33 45 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS
Nenue@72 46 local SCALE_FACTORS = { 0.25, 0.7, 1 }
Nenue@33 47
Nenue@72 48 local BountyBoard = WorldMapFrame.UIElementsFrame.BountyBoard
Nenue@72 49 local ActionButton = WorldMapFrame.UIElementsFrame.ActionButton
Nenue@93 50 local defaults = {}
Nenue@103 51 local completedQuests = {}
Nenue@72 52
Nenue@93 53 local continentScanned
Nenue@93 54 local layoutDirty = true
Nenue@93 55 local bountiesDirty = true
Nenue@93 56 local artifactPowerDirty = true
Nenue@96 57 local hooksDirty = true
Nenue@93 58 local currentScale = WorldMapDetailFrame:GetScale()
Nenue@93 59 local canTargetQuests
Nenue@93 60 local isDataLoaded = true
Nenue@93 61 local artifactKnowledgeLevel
Nenue@93 62 local superTrackedQuestID
Nenue@93 63 local lastRefresh
Nenue@93 64 local refreshReason
Nenue@93 65
Nenue@93 66 local bountyQuests = {}
Nenue@93 67 local bountyInfo = {}
Nenue@93 68 local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID
Nenue@93 69
Nenue@93 70 local totalPins = 0
Nenue@93 71 local numShown = 0
Nenue@93 72 local numLoaded = 0
Nenue@93 73 local numOverlays = 1
Nenue@93 74 local scaleConstant = 1
Nenue@100 75 local pinBaseIndex = 1550
Nenue@100 76 local overlayBaseIndex = 1600
Nenue@93 77
Nenue@93 78 local artifactKnowldegeSpells = {
Nenue@93 79 [207856] = true,
Nenue@93 80 [209203] = true,
Nenue@93 81 [209204] = true,
Nenue@93 82 [209205] = true,
Nenue@93 83 [209206] = true,
Nenue@93 84 [209207] = true,
Nenue@93 85 [209208] = true,
Nenue@93 86 [209209] = true,
Nenue@93 87 [209210] = true,
Nenue@93 88 [209211] = true,
Nenue@93 89 [209212] = true,
Nenue@93 90 [219978] = true,
Nenue@93 91 [227852] = true,
Nenue@93 92 [236477] = true,
Nenue@93 93 [236489] = true,
Nenue@93 94 [236302] = true,
Nenue@93 95 [236488] = true,
Nenue@93 96 [236490] = true,
Nenue@93 97 [240475] = true,
Nenue@93 98 [243176] = true,
Nenue@93 99 [243177] = true,
Nenue@93 100 [243178] = true,
Nenue@93 101 [243182] = true,
Nenue@93 102 [243183] = true,
Nenue@93 103 [243187] = true,
Nenue@93 104 [245133] = true,
Nenue@93 105 }
Nenue@33 106
Nenue@33 107 --%debug%
Nenue@33 108 local SetTimedCallbackForAllPins = function(seconds, callback)
Nenue@33 109 C_Timer.After(seconds, function()
Nenue@33 110 for id, pin in pairs(WorldPlanQuests.QuestsByID) do
Nenue@33 111 callback(pin)
Nenue@33 112 end
Nenue@33 113 end)
Nenue@33 114 end
Nenue@33 115
Nenue@93 116 function Module:OnLoad()
Nenue@93 117 --print('|cFFFF4400'..self:GetName()..':OnLoad()')
Nenue@52 118
Nenue@93 119 self:SetParent(WorldMapFrame.UIElementsFrame)
Nenue@93 120 WorldPlan:AddHandler(self, defaults)
Nenue@93 121
Nenue@93 122 for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
Nenue@93 123 db.QuestsByZone[areaID] = {}
Nenue@33 124 end
Nenue@93 125
Nenue@93 126 -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
Nenue@93 127 self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
Nenue@93 128 self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED')
Nenue@93 129 self:RegisterEvent('SKILL_LINES_CHANGED')
Nenue@93 130 self:RegisterEvent('ARTIFACT_UPDATE')
Nenue@93 131 self:RegisterEvent('QUEST_LOG_UPDATE')
Nenue@93 132 self:RegisterEvent('UNIT_SPELLCAST_STOP')
Nenue@93 133 end
Nenue@93 134
Nenue@93 135 function Module:OnEvent (event, ...)
Nenue@93 136 print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...)
Nenue@93 137 if (event == 'QUEST_LOG_UPDATE') then
Nenue@93 138 self:UpdateBounties(event)
Nenue@93 139 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
Nenue@93 140 local questID = ...
Nenue@93 141 if questID and db.QuestsByID[questID] then
Nenue@110 142 -- client-side quest completion status isn't updated until the next event stack
Nenue@103 143 completedQuests[questID] = true
Nenue@93 144 db.QuestsByID[questID]:Release()
Nenue@93 145 end
Nenue@93 146 self:Refresh(event)
Nenue@93 147 elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then
Nenue@93 148 self:Refresh(event)
Nenue@93 149 elseif event == 'ARTIFACT_UPDATE' then
Nenue@93 150 self:UpdateArtifactPower()
Nenue@93 151 elseif event == 'MODIFIER_STATE_CHANGED' then
Nenue@93 152 self:UpdateModifierState()
Nenue@93 153 elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then
Nenue@93 154 if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then
Nenue@93 155 db.QuestsByID[superTrackedQuestID].isStale = true
Nenue@93 156 end
Nenue@93 157 local newID = GetSuperTrackedQuestID()
Nenue@93 158 if newID and db.QuestsByID[newID] then
Nenue@93 159 db.QuestsByID[newID].isStale = true
Nenue@93 160 end
Nenue@93 161 elseif event == 'UNIT_SPELLCAST_STOP' then
Nenue@93 162 local name, _, _, _, spellID = ...
Nenue@93 163 if artifactKnowldegeSpells[spellID] then
Nenue@93 164 db.log('AK spellcast ended ' .. tostring(name) .. ' ('.. tostring(spellID)..')')
Nenue@93 165 self:UpdateArtifactPower()
Nenue@93 166 end
Nenue@93 167 end
Nenue@93 168 end
Nenue@93 169
Nenue@93 170 function Module:OnUpdate(sinceLast)
Nenue@93 171 if WorldPlanData.DebugEnabled then
Nenue@93 172 if self.refreshBenchMarkTicker then
Nenue@93 173 --print(self.refreshBenchMarkTicker)
Nenue@93 174 self.refreshBenchMarkTicker = self.refreshBenchMarkTicker - 1
Nenue@93 175
Nenue@93 176 if self.refreshBenchMarkTicker == 0 then
Nenue@93 177
Nenue@93 178 self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000)
Nenue@93 179 self.debugMessage:SetText(self.refreshTime)
Nenue@93 180 self.refreshBenchMarkTicker = nil
Nenue@69 181 end
Nenue@69 182 else
Nenue@93 183 self.refreshBenchMark = GetTime()
Nenue@69 184 end
Nenue@69 185 end
Nenue@65 186
Nenue@93 187 if self.filtersDirty or self.isStale then
Nenue@93 188 self:Refresh()
Nenue@67 189 end
Nenue@72 190
Nenue@93 191 if #db.UpdatedPins >= 1 then
Nenue@93 192 --print('|cFF00FF88pending update', #db.UpdatedPins)
Nenue@93 193 self:UpdateNext()
Nenue@93 194 end
Nenue@93 195 end
Nenue@72 196
Nenue@93 197 local callbacks = {}
Nenue@69 198 callbacks.ClickWorldMapActionButton = function(WorldQuests)
Nenue@73 199 WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON')
Nenue@69 200 end
Nenue@69 201 callbacks.WorldMap_UpdateQuestBonusObjectives = function(WorldQuests)
Nenue@73 202 WorldQuests:UpdateTaskPOIs()
Nenue@69 203 end
Nenue@69 204 callbacks.WorldMapFrame_UpdateMap = function(WorldQuests)
Nenue@75 205 WorldQuests:RefreshIfChanged('WMF_UPDATE')
Nenue@69 206 end
Nenue@69 207 callbacks.WorldMapScrollFrame_ReanchorQuestPOIs = function (WorldQuests)
Nenue@75 208 WorldQuests:RefreshIfChanged('WMF_REANCHOR')
Nenue@69 209 end
Nenue@69 210
Nenue@72 211 callbacks[BountyBoard] = {}
Nenue@72 212 callbacks[BountyBoard].SetSelectedBountyIndex = function(WorldQuests)
Nenue@72 213 WorldQuests:UpdateBounties('BOUNTY_SELECTED')
Nenue@100 214 for questID, pin in pairs(db.QuestsByID) do
Nenue@100 215 pin.checkCriteria = true
Nenue@100 216 pin:Refresh()
Nenue@100 217 end
Nenue@72 218 end
Nenue@67 219
Nenue@72 220 callbacks[ActionButton] = {}
Nenue@72 221 callbacks[ActionButton].UpdateCastingState = function(WorldQuests)
Nenue@100 222 for questID, pin in pairs(db.QuestsByID) do
Nenue@100 223 pin.checkCursor = true
Nenue@100 224 pin:Refresh()
Nenue@100 225 end
Nenue@67 226 end
Nenue@67 227
Nenue@96 228 callbacks.UseWorldMapActionButtonSpellOnQuest = function(questID)
Nenue@97 229 local pin = db.QuestsByID[questID]
Nenue@97 230 -- calling this implies that the pin is used in some way
Nenue@97 231 if pin then
Nenue@100 232 db.log(pin.title .. ' completed by spell?', IsQuestComplete(pin.questID))
Nenue@100 233 pin:OnFilters()
Nenue@98 234 pin.isStale = true
Nenue@93 235 end
Nenue@96 236 end
Nenue@96 237
Nenue@96 238 function Module:SetupCallbacks()
Nenue@96 239 if InCombatLockdown() then
Nenue@97 240 return true
Nenue@96 241 end
Nenue@96 242 print('SetupCallbacks()')
Nenue@93 243 for target, arg in pairs(callbacks) do
Nenue@93 244 --print(type(target))
Nenue@93 245 if type(target) == 'table' then
Nenue@93 246 local callerName = target:GetName() or tostring(target)
Nenue@93 247 for name, method in pairs(arg) do
Nenue@93 248 --print(callerName, arg)
Nenue@93 249 hooksecurefunc(target, name, function(...)
Nenue@93 250 self:OnSecureHook(callerName .. '.' .. name, method, ...)
Nenue@93 251 end)
Nenue@93 252 end
Nenue@93 253 else
Nenue@93 254 hooksecurefunc(target, function(...)
Nenue@93 255 self:OnSecureHook(target, arg, ...)
Nenue@93 256 end)
Nenue@93 257 end
Nenue@93 258 end
Nenue@96 259 end
Nenue@96 260
Nenue@96 261 function Module:Setup()
Nenue@96 262 --print('|cFFFF4400'..self:GetName()..':Setup()')
Nenue@96 263 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
Nenue@96 264 db.QuestsByZone[mapID] = {}
Nenue@96 265 end
Nenue@96 266
Nenue@96 267 hooksDirty = self:SetupCallbacks()
Nenue@96 268
Nenue@93 269 self:SetAllPoints(WorldMapFrame.UIElementsFrame)
Nenue@93 270 self:UpdateArtifactPower()
Nenue@93 271 self:UpdateBounties('SETUP')
Nenue@93 272 self:Show()
Nenue@93 273 end
Nenue@93 274
Nenue@93 275 function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
Nenue@93 276 if isNewMap or self.isStale then
Nenue@93 277 print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
Nenue@93 278 layoutDirty = true
Nenue@93 279 self:Refresh('WORLD_MAP_CHANGED')
Nenue@93 280 end
Nenue@93 281 end
Nenue@93 282
Nenue@49 283 function Module:OnConfigUpdate()
Nenue@75 284 --print('|cFFFFFF00OnConfigUpdate()|r')
Nenue@49 285 if db.Config.FadeWhileGrouped then
Nenue@49 286 db.PinAlpha = 0.15
Nenue@49 287 else
Nenue@49 288 db.PinAlpha = 1
Nenue@49 289 end
Nenue@67 290
Nenue@67 291 if not db.Config.EnablePins then
Nenue@67 292 for _, pin in pairs(db.QuestsByID) do
Nenue@67 293 pin:SetShown(false)
Nenue@67 294 end
Nenue@67 295 end
Nenue@45 296 end
Nenue@33 297
Nenue@69 298 function Module:OnSecureHook(callbackName, func, ...)
Nenue@98 299 print('|cFFFF4400'..callbackName..'|r', ...)
Nenue@69 300 func(self, ...)
Nenue@45 301 end
Nenue@40 302
Nenue@93 303 function Module:UpdateModifierState()
Nenue@33 304
Nenue@33 305 end
Nenue@33 306
Nenue@93 307 function Module:UpdateTaskPOIs()
Nenue@93 308 canTargetQuests = SpellCanTargetQuest()
Nenue@93 309 for i = 1, NUM_WORLDMAP_TASK_POIS do
Nenue@93 310 local poiFrame = _G['WorldMapFrameTaskPOI'..i]
Nenue@93 311 if poiFrame and poiFrame.worldQuest then
Nenue@93 312 local pin = db.QuestsByID[poiFrame.questID]
Nenue@93 313 if pin and pin.used and canTargetQuests and IsQuestIDValidSpellTarget(pin.questID) then
Nenue@93 314 poiFrame:Show()
Nenue@93 315 else
Nenue@93 316 poiFrame:Hide()
Nenue@93 317 end
Nenue@93 318 end
Nenue@93 319 end
Nenue@93 320 end
Nenue@93 321 -- re-anchors and scales pins that have had either of these changed due to data loading delays
Nenue@93 322 function Module:UpdateNext()
Nenue@93 323 --print('|cFF00FF88UpdateNext()')
Nenue@93 324 local pin = tremove(db.UpdatedPins)
Nenue@100 325 pin:OnFilters()
Nenue@40 326
Nenue@93 327 local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
Nenue@93 328 --print(pin.title, pin.dataLoaded and not pin.filtered, scaleFactor)
Nenue@93 329 if pin.used then
Nenue@96 330 pin:SetShown(true)
Nenue@93 331 pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor)
Nenue@96 332 pin:Refresh()
Nenue@96 333 else
Nenue@96 334 print('|cFFFF4400flagging queued pin that got hidden:', pin.title)
Nenue@96 335 pin.isStale = true
Nenue@33 336 end
Nenue@33 337 end
Nenue@33 338
Nenue@72 339 function Module:UpdateBounties(...)
Nenue@102 340 bountiesDirty = nil
Nenue@102 341 print('|cFF00FF88BountyInfo()|r', ...)
Nenue@72 342 wipe(db.BountiesByFactionID)
Nenue@75 343 wipe(db.BountiesByQuestID)
Nenue@72 344
Nenue@72 345 db.selectedBounty = nil
Nenue@72 346 selectedBountyIndex = BountyBoard:GetSelectedBountyIndex()
Nenue@75 347 db.Bounties, bountyDisplayLocation, bountyLockedQuestID = GetQuestBountyInfoForMapID(db.currentMapID, db.Bounties)
Nenue@72 348 local numBounties = 0
Nenue@75 349 for index, info in ipairs(db.Bounties) do
Nenue@72 350 numBounties = numBounties + 1
Nenue@73 351 info.index = index
Nenue@73 352 info.complete = IsQuestComplete(info.questID)
Nenue@73 353 if not info.complete then
Nenue@73 354 db.BountiesByFactionID[info.factionID] = info
Nenue@75 355 db.BountiesByQuestID[info.questID] = info
Nenue@72 356 if index == selectedBountyIndex then
Nenue@73 357 db.selectedBounty = info
Nenue@73 358 selectedBountyQuestID = info.questID
Nenue@72 359 end
Nenue@73 360 print(' ', index, info.factionID, GetQuestLogTitle(GetQuestLogIndexByID(info.questID)), info.complete, (index == selectedBountyIndex) and 'SELECTED' or '')
Nenue@72 361 end
Nenue@72 362 end
Nenue@72 363 end
Nenue@72 364
Nenue@93 365 -- check current artifact knowledge and update pins accordingly
Nenue@93 366 function Module:UpdateArtifactPower(overrideLevel)
Nenue@93 367 if InCombatLockdown() then
Nenue@93 368 artifactPowerDirty = true
Nenue@93 369 return
Nenue@40 370 end
Nenue@40 371
Nenue@93 372 print('|cFF00FF88UpdateArtifactPower()|r')
Nenue@93 373 local _, akLevel = GetCurrencyInfo(1171)
Nenue@93 374 if overrideLevel then
Nenue@93 375 akLevel = overrideLevel
Nenue@40 376 end
Nenue@40 377
Nenue@93 378 --db.print('current AK', akLevel)
Nenue@93 379 if akLevel and (akLevel ~= artifactKnowledgeLevel) or (not artifactKnowledgeLevel) then
Nenue@93 380 --print('new ak level', akLevel)
Nenue@93 381 db.log('AK update ' .. tostring(artifactKnowledgeLevel) .. ' to '.. tostring(akLevel))
Nenue@93 382 for _, pin in pairs(db.QuestsByID) do
Nenue@93 383 if (pin.rewardType == REWARD_ARTIFACT_POWER) then
Nenue@93 384 print(pin.title, pin.itemNumber)
Nenue@93 385 local newAP = pin:UpdateArtifactPower()
Nenue@93 386 if newAP then
Nenue@93 387 pin.itemNumber = newAP
Nenue@93 388 print(newAP)
Nenue@93 389 else
Nenue@93 390 pin.dataLoaded = nil
Nenue@93 391 end
Nenue@93 392 pin.isStale = true
Nenue@93 393 end
Nenue@33 394 end
Nenue@93 395 artifactKnowledgeLevel = akLevel
Nenue@40 396 end
Nenue@93 397 artifactPowerDirty = nil
Nenue@75 398 end
Nenue@40 399
Nenue@72 400 local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF'
Nenue@72 401 function Module:Refresh(...)
Nenue@96 402
Nenue@96 403 if hooksDirty then
Nenue@96 404 hooksDirty = self:SetupCallbacks()
Nenue@96 405 end
Nenue@96 406
Nenue@96 407
Nenue@34 408 if not self:IsVisible() then
Nenue@75 409 print('|cFFFF4400Refresh()|r', ...)
Nenue@75 410 return
Nenue@73 411 else
Nenue@75 412 if lastRefresh == GetTime() then
Nenue@75 413 print('|cFFFF4400multiple refreshes tried')
Nenue@75 414 end
Nenue@75 415 lastRefresh = GetTime()
Nenue@75 416 print(msg, lastRefresh, ...)
Nenue@40 417 end
Nenue@73 418
Nenue@102 419
Nenue@102 420 if bountiesDirty then
Nenue@102 421 self:UpdateBounties()
Nenue@102 422 end
Nenue@102 423
Nenue@67 424 if not db.Config.EnablePins then
Nenue@69 425 numShown = 0
Nenue@76 426 self.refreshBenchMark = GetTime()
Nenue@76 427 self.refreshBenchMarkTicker = 2
Nenue@76 428 print('starting bench', self.refreshBenchMark)
Nenue@67 429 return
Nenue@67 430 end
Nenue@67 431
Nenue@72 432 scaleConstant = db.isContinentMap and 2 or 3
Nenue@72 433 canTargetQuests = SpellCanTargetQuest()
Nenue@67 434
Nenue@40 435 for index, pin in pairs(db.QuestsByID) do
Nenue@40 436 pin.used = nil
Nenue@40 437 end
Nenue@40 438
Nenue@95 439 self:UpdateAnchors(...)
Nenue@72 440
Nenue@93 441 if artifactPowerDirty and not InCombatLockdown() then
Nenue@93 442 self:UpdateArtifactPower()
Nenue@93 443 end
Nenue@69 444 -- calculate quests shown
Nenue@65 445 numShown = 0
Nenue@65 446 numLoaded = 0
Nick@60 447 for questID, pin in pairs(db.QuestsByID) do
Nick@60 448 local oV = pin:IsShown()
Nick@60 449 if pin.used then
Nenue@96 450 print('show', pin.title)
Nick@60 451 pin.throttle = 1
Nick@60 452 pin:SetShown(true)
Nenue@65 453 numShown = numShown + 1
Nenue@65 454 if pin.dataLoaded then
Nenue@65 455 numLoaded = numLoaded + 1
Nenue@65 456 end
Nenue@65 457
Nenue@100 458 pin.checkCriteria = true
Nenue@100 459 pin.checkFilters = true
Nenue@100 460 pin:Refresh('WORLDMAP_REFRESH ' .. GetTime())
Nenue@100 461
Nick@60 462 else
Nenue@96 463 if pin:IsShown() then
Nenue@96 464 print('|cFFFF4400need to remove', pin.title)
Nenue@96 465
Nick@60 466 end
Nenue@96 467
Nenue@69 468 pin.hideReason = "Not used in map area " .. (db.currentMapID)
Nenue@75 469 pin:SetShown(false)
Nick@60 470 end
Nenue@93 471
Nick@60 472 end
Nenue@93 473
Nenue@65 474
Nenue@75 475 --
Nenue@93 476 self.refreshBenchMark = GetTime()
Nenue@93 477 self.refreshBenchMarkTicker = 2
Nenue@93 478 print('starting bench', self.refreshBenchMark)
Nenue@76 479
Nenue@75 480 --
Nenue@65 481
Nenue@73 482 layoutDirty = nil
Nenue@40 483 self.isStale = nil
Nenue@54 484 self.sizesDirty = nil
Nenue@66 485 self.isZoomDirty = nil
Nenue@75 486
Nenue@93 487 if WorldPlanSummary then
Nenue@93 488 WorldPlanSummary.isStale = true
Nenue@93 489 end
Nenue@93 490
Nenue@40 491 end
Nenue@40 492
Nenue@75 493 function Module:RefreshIfChanged(event)
Nenue@69 494 local scaleCheck = WorldMapDetailFrame:GetScale()
Nenue@73 495 refreshReason = nil
Nenue@69 496 if scaleCheck ~= currentScale then
Nenue@73 497 refreshReason = 'map scale updated'
Nenue@69 498 currentScale = scaleCheck
Nenue@75 499 layoutDirty = true
Nenue@72 500 elseif self.isStale or layoutDirty then
Nenue@73 501 refreshReason = 'layout is marked dirty'
Nenue@73 502 end
Nenue@73 503 if not refreshReason then
Nenue@73 504 return
Nenue@73 505 end
Nenue@73 506
Nenue@73 507 if self:IsVisible() then
Nenue@73 508 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
Nenue@75 509 self:Refresh(event)
Nenue@73 510 else
Nenue@75 511 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
Nenue@73 512 self.isStale = true
Nenue@69 513 end
Nenue@69 514 end
Nenue@69 515
Nenue@93 516 -- Walks the current map tree and fires updates as needed
Nenue@95 517 function Module:UpdateAnchors (event)
Nenue@40 518 wipe(self.UsedPositions)
Nenue@74 519 local hostWidth, hostHeight = WorldMapPOIFrame:GetSize()
Nenue@74 520
Nenue@74 521 if (hostWidth ~= self.hostWidth) or (hostHeight ~= self.hostHeight) then
Nenue@74 522 self.hostWidth, self.hostHeight = hostWidth, hostHeight
Nenue@74 523 layoutDirty = true
Nenue@74 524 end
Nenue@74 525
Nenue@95 526 print('|cFF00FF00UpdateAnchors()', event)
Nenue@33 527 local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo()
Nenue@33 528 if isMicroDungeon then
Nenue@33 529 return
Nenue@33 530 end
Nenue@69 531
Nenue@65 532 isDataLoaded = true
Nenue@67 533 local taskInfo = TQ_GetQuestsForPlayerByMapID(db.currentMapID)
Nenue@111 534 local transformFlags = (db.currentMapID == 1184) and Enum.MapTransform.IsForFlightMap or nil
Nenue@40 535 if taskInfo then
Nenue@69 536 self:UpdateQuestsForMap(taskInfo, db.currentMapID)
Nenue@33 537 end
Nenue@67 538 local numZones = MC_GetNumZones(db.currentMapID)
Nenue@33 539 if numZones then
Nenue@33 540 for i = 1, numZones do
Nenue@67 541 local mapAreaID = MC_GetZoneInfo(db.currentMapID, i)
Nenue@111 542 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, db.currentMapID, transformFlags)
Nenue@82 543
Nenue@82 544 db.QuestsByZone[mapAreaID] = db.QuestsByZone[mapAreaID] or {}
Nenue@82 545
Nenue@40 546 if taskInfo then
Nenue@111 547 self:UpdateQuestsForMap(taskInfo, mapAreaID, transformFlags)
Nenue@40 548 end
Nenue@33 549 end
Nenue@33 550 end
Nenue@111 551
Nenue@111 552
Nenue@33 553 end
Nenue@33 554
Nenue@96 555 -- Attempt to display the pins for quests in taskInfo
Nenue@111 556 function Module:UpdateQuestsForMap(taskInfo, mapID, transformFlags)
Nenue@93 557 print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty)
Nenue@93 558 if db.QuestsByZone[mapID] then
Nenue@93 559 wipe(db.QuestsByZone[mapID])
Nenue@93 560 elseif db.isBrokenIsle then
Nenue@93 561 continentScanned = true
Nenue@93 562 end
Nenue@108 563 db.PinStrata = WorldMapFrame_InWindowedMode() and 'HIGH' or 'FULLSCREEN'
Nenue@96 564 print('layoutDirty =',layoutDirty)
Nenue@93 565
Nenue@93 566 for index, info in pairs(taskInfo) do
Nenue@93 567 local questID, x, y = info.questId, info.x, info.y
Nenue@111 568
Nenue@111 569 -- rough workaround for argus map; flightmap and world map images are different, so not completely accurate
Nenue@111 570 if transformFlags and x and y then
Nenue@111 571 print(x,y)
Nenue@111 572 x = x / 2 + .25
Nenue@111 573 y = y / 2 + .30
Nenue@111 574 print(x,y)
Nenue@111 575 end
Nenue@111 576
Nenue@111 577
Nenue@93 578 local pin = self:AcquirePin(info)
Nenue@100 579 if pin then
Nenue@100 580 if pin.canShow then
Nenue@100 581 pin.used = true
Nenue@100 582 print('using', pin.title, (pin.owningFrame ~= WorldMapFrame))
Nenue@100 583 if layoutDirty or (pin.owningFrame ~= WorldMapFrame) then
Nenue@100 584 local scaleFactor = SCALE_FACTORS[(not pin.filtered and scaleConstant) or 1]
Nenue@100 585 pin.owningFrame = WorldMapFrame
Nenue@100 586 pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor)
Nenue@93 587
Nenue@93 588 end
Nenue@100 589 if db.QuestsByZone[mapID] then
Nenue@100 590 db.QuestsByZone[mapID][questID] = pin
Nenue@100 591 end
Nenue@100 592 else
Nenue@100 593 print('|cFFFF4400discarding|r', pin.title)
Nenue@93 594 end
Nenue@93 595 end
Nenue@93 596 end
Nenue@67 597 end
Nenue@93 598
Nenue@93 599 -- locates or creates a corresponding pin frame for the provided TaskInfo data
Nenue@93 600 function Module:AcquirePin (info)
Nenue@93 601 local questID = info.questId
Nenue@93 602 if not (questID and QuestUtils_IsQuestWorldQuest(questID)) then
Nenue@93 603 return nil
Nenue@93 604 end
Nenue@103 605 local pin = db.QuestsByID[questID]
Nenue@103 606 -- check to avoid creating unnecessary frames
Nenue@103 607 if IsQuestComplete(questID) or completedQuests[questID] then
Nenue@103 608 completedQuests[questID] = true
Nenue@103 609 if pin then
Nenue@103 610 pin:Release()
Nenue@103 611 end
Nenue@100 612 return nil
Nenue@100 613 end
Nenue@100 614
Nenue@93 615 if not pin then
Nenue@93 616 local numFree = #db.FreePins
Nenue@93 617 if numFree >= 1 then
Nenue@93 618 pin = tremove(db.FreePins, numFree)
Nenue@100 619 print('|cFF00FF00Acquire()|r Re-using', pin:GetName())
Nenue@93 620 else
Nenue@93 621 totalPins = totalPins + 1
Nenue@93 622 local name = 'WorldPlanQuestMarker' .. numOverlays
Nenue@100 623 print('|cFF00FF00Acquire()|r Creating', name)
Nenue@93 624 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
Nenue@93 625
Nenue@93 626 pin:SetID(totalPins)
Nenue@93 627 numOverlays = numOverlays + 1
Nenue@93 628 --pin.iconBorder:SetVertexColor(0,0,0,1)
Nenue@93 629 end
Nenue@93 630 pin.questID = questID
Nenue@93 631 pin.throttle = pin.updateRate
Nenue@93 632 pin.currentWidth = nil
Nenue@100 633
Nenue@93 634 db.QuestsByID[questID] = pin
Nenue@93 635 tinsert(db.UsedPins, pin)
Nenue@93 636 end
Nenue@93 637
Nenue@103 638 if info then
Nenue@93 639 pin.inProgress = info.inProgress
Nenue@93 640 pin.floor = info.floor
Nenue@93 641 pin.numObjectives = info.numObjectives or 0
Nenue@93 642 if info.x and info.y then
Nenue@93 643 if (info.x ~= pin.x) or (info.y ~= pin.y) then
Nenue@93 644 pin.isStale = true
Nenue@93 645 --rprint('|cFFFF4400SetCoords|r', info.x, info.y)
Nenue@93 646 end
Nenue@93 647 end
Nenue@93 648 end
Nenue@93 649
Nenue@93 650 pin.x = info.x or pin.x
Nenue@93 651 pin.y = info.y or pin.y
Nenue@93 652
Nenue@93 653 if not HaveQuestRewardData(questID) then
Nenue@93 654 TQ_RequestPreloadRewardData(questID);
Nenue@93 655 end
Nenue@93 656
Nenue@93 657 if (not pin.dataLoaded) then
Nenue@93 658 local dataLoaded = pin:GetData()
Nenue@93 659 if dataLoaded then
Nenue@93 660 WorldPlan.dataFlush = true
Nenue@93 661 else
Nenue@93 662 isDataLoaded = false
Nenue@93 663 end
Nenue@93 664 end
Nenue@93 665
Nenue@100 666 pin:OnFilters()
Nenue@93 667 pin.isActive = TQ_IsActive(questID)
Nenue@93 668 --rprint(pin:GetID(), pin.filtered, pin.used)
Nenue@93 669 return pin
Nenue@93 670 end
Nenue@93 671
Nenue@93 672 function Module:Debug(...)
Nenue@93 673 print(...)
Nenue@67 674 end