annotate WorldMap.lua @ 117:a4dfdd4f1cf3 v7.3.2-20171215

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