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