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@65
|
191
|
Nenue@93
|
192 if self.filtersDirty or self.isStale then
|
Nenue@93
|
193 self:Refresh()
|
Nenue@67
|
194 end
|
Nenue@72
|
195
|
Nenue@117
|
196
|
Nenue@117
|
197
|
Nenue@93
|
198 if #db.UpdatedPins >= 1 then
|
Nenue@93
|
199 --print('|cFF00FF88pending update', #db.UpdatedPins)
|
Nenue@93
|
200 self:UpdateNext()
|
Nenue@93
|
201 end
|
Nenue@93
|
202 end
|
Nenue@72
|
203
|
Nenue@93
|
204 local callbacks = {}
|
Nenue@69
|
205 callbacks.ClickWorldMapActionButton = function(WorldQuests)
|
Nenue@73
|
206 WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON')
|
Nenue@69
|
207 end
|
Nenue@69
|
208 callbacks.WorldMap_UpdateQuestBonusObjectives = function(WorldQuests)
|
Nenue@73
|
209 WorldQuests:UpdateTaskPOIs()
|
Nenue@69
|
210 end
|
Nenue@69
|
211 callbacks.WorldMapFrame_UpdateMap = function(WorldQuests)
|
Nenue@75
|
212 WorldQuests:RefreshIfChanged('WMF_UPDATE')
|
Nenue@69
|
213 end
|
Nenue@69
|
214 callbacks.WorldMapScrollFrame_ReanchorQuestPOIs = function (WorldQuests)
|
Nenue@75
|
215 WorldQuests:RefreshIfChanged('WMF_REANCHOR')
|
Nenue@69
|
216 end
|
Nenue@69
|
217
|
Nenue@72
|
218 callbacks[BountyBoard] = {}
|
Nenue@72
|
219 callbacks[BountyBoard].SetSelectedBountyIndex = function(WorldQuests)
|
Nenue@72
|
220 WorldQuests:UpdateBounties('BOUNTY_SELECTED')
|
Nenue@100
|
221 for questID, pin in pairs(db.QuestsByID) do
|
Nenue@100
|
222 pin.checkCriteria = true
|
Nenue@100
|
223 pin:Refresh()
|
Nenue@100
|
224 end
|
Nenue@72
|
225 end
|
Nenue@67
|
226
|
Nenue@72
|
227 callbacks[ActionButton] = {}
|
Nenue@72
|
228 callbacks[ActionButton].UpdateCastingState = function(WorldQuests)
|
Nenue@100
|
229 for questID, pin in pairs(db.QuestsByID) do
|
Nenue@100
|
230 pin.checkCursor = true
|
Nenue@100
|
231 pin:Refresh()
|
Nenue@100
|
232 end
|
Nenue@67
|
233 end
|
Nenue@67
|
234
|
Nenue@96
|
235 callbacks.UseWorldMapActionButtonSpellOnQuest = function(questID)
|
Nenue@97
|
236 local pin = db.QuestsByID[questID]
|
Nenue@97
|
237 -- calling this implies that the pin is used in some way
|
Nenue@97
|
238 if pin then
|
Nenue@100
|
239 db.log(pin.title .. ' completed by spell?', IsQuestComplete(pin.questID))
|
Nenue@100
|
240 pin:OnFilters()
|
Nenue@98
|
241 pin.isStale = true
|
Nenue@93
|
242 end
|
Nenue@96
|
243 end
|
Nenue@96
|
244
|
Nenue@96
|
245 function Module:SetupCallbacks()
|
Nenue@96
|
246 if InCombatLockdown() then
|
Nenue@97
|
247 return true
|
Nenue@96
|
248 end
|
Nenue@96
|
249 print('SetupCallbacks()')
|
Nenue@93
|
250 for target, arg in pairs(callbacks) do
|
Nenue@93
|
251 --print(type(target))
|
Nenue@93
|
252 if type(target) == 'table' then
|
Nenue@93
|
253 local callerName = target:GetName() or tostring(target)
|
Nenue@93
|
254 for name, method in pairs(arg) do
|
Nenue@93
|
255 --print(callerName, arg)
|
Nenue@93
|
256 hooksecurefunc(target, name, function(...)
|
Nenue@93
|
257 self:OnSecureHook(callerName .. '.' .. name, method, ...)
|
Nenue@93
|
258 end)
|
Nenue@93
|
259 end
|
Nenue@93
|
260 else
|
Nenue@93
|
261 hooksecurefunc(target, function(...)
|
Nenue@93
|
262 self:OnSecureHook(target, arg, ...)
|
Nenue@93
|
263 end)
|
Nenue@93
|
264 end
|
Nenue@93
|
265 end
|
Nenue@96
|
266 end
|
Nenue@96
|
267
|
Nenue@96
|
268 function Module:Setup()
|
Nenue@96
|
269 --print('|cFFFF4400'..self:GetName()..':Setup()')
|
Nenue@96
|
270 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
|
Nenue@96
|
271 db.QuestsByZone[mapID] = {}
|
Nenue@96
|
272 end
|
Nenue@96
|
273
|
Nenue@96
|
274 hooksDirty = self:SetupCallbacks()
|
Nenue@96
|
275
|
Nenue@93
|
276 self:SetAllPoints(WorldMapFrame.UIElementsFrame)
|
Nenue@93
|
277 self:UpdateArtifactPower()
|
Nenue@93
|
278 self:UpdateBounties('SETUP')
|
Nenue@93
|
279 self:Show()
|
Nenue@93
|
280 end
|
Nenue@93
|
281
|
Nenue@93
|
282 function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
|
Nenue@93
|
283 if isNewMap or self.isStale then
|
Nenue@93
|
284 print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
|
Nenue@93
|
285 layoutDirty = true
|
Nenue@93
|
286 self:Refresh('WORLD_MAP_CHANGED')
|
Nenue@93
|
287 end
|
Nenue@93
|
288 end
|
Nenue@93
|
289
|
Nenue@49
|
290 function Module:OnConfigUpdate()
|
Nenue@75
|
291 --print('|cFFFFFF00OnConfigUpdate()|r')
|
Nenue@49
|
292 if db.Config.FadeWhileGrouped then
|
Nenue@49
|
293 db.PinAlpha = 0.15
|
Nenue@49
|
294 else
|
Nenue@49
|
295 db.PinAlpha = 1
|
Nenue@49
|
296 end
|
Nenue@67
|
297
|
Nenue@67
|
298 if not db.Config.EnablePins then
|
Nenue@67
|
299 for _, pin in pairs(db.QuestsByID) do
|
Nenue@67
|
300 pin:SetShown(false)
|
Nenue@67
|
301 end
|
Nenue@67
|
302 end
|
Nenue@45
|
303 end
|
Nenue@33
|
304
|
Nenue@69
|
305 function Module:OnSecureHook(callbackName, func, ...)
|
Nenue@98
|
306 print('|cFFFF4400'..callbackName..'|r', ...)
|
Nenue@69
|
307 func(self, ...)
|
Nenue@45
|
308 end
|
Nenue@40
|
309
|
Nenue@93
|
310 function Module:UpdateModifierState()
|
Nenue@33
|
311
|
Nenue@33
|
312 end
|
Nenue@33
|
313
|
Nenue@93
|
314 function Module:UpdateTaskPOIs()
|
Nenue@93
|
315 canTargetQuests = SpellCanTargetQuest()
|
Nenue@117
|
316
|
Nenue@119
|
317 --if InCombatLockdown() then
|
Nenue@117
|
318 self.tasksDirty = true
|
Nenue@119
|
319 -- return
|
Nenue@119
|
320 --end
|
Nenue@117
|
321
|
Nenue@117
|
322
|
Nenue@93
|
323 for i = 1, NUM_WORLDMAP_TASK_POIS do
|
Nenue@93
|
324 local poiFrame = _G['WorldMapFrameTaskPOI'..i]
|
Nenue@93
|
325 if poiFrame and poiFrame.worldQuest then
|
Nenue@93
|
326 local pin = db.QuestsByID[poiFrame.questID]
|
Nenue@93
|
327 if pin and pin.used and canTargetQuests and IsQuestIDValidSpellTarget(pin.questID) then
|
Nenue@93
|
328 poiFrame:Show()
|
Nenue@93
|
329 else
|
Nenue@93
|
330 poiFrame:Hide()
|
Nenue@93
|
331 end
|
Nenue@93
|
332 end
|
Nenue@93
|
333 end
|
Nenue@117
|
334
|
Nenue@119
|
335 self.tasksDirty = nil
|
Nenue@93
|
336 end
|
Nenue@93
|
337 -- re-anchors and scales pins that have had either of these changed due to data loading delays
|
Nenue@93
|
338 function Module:UpdateNext()
|
Nenue@93
|
339 --print('|cFF00FF88UpdateNext()')
|
Nenue@93
|
340 local pin = tremove(db.UpdatedPins)
|
Nenue@100
|
341 pin:OnFilters()
|
Nenue@40
|
342
|
Nenue@93
|
343 local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
|
Nenue@93
|
344 --print(pin.title, pin.dataLoaded and not pin.filtered, scaleFactor)
|
Nenue@93
|
345 if pin.used then
|
Nenue@96
|
346 pin:SetShown(true)
|
Nenue@93
|
347 pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor)
|
Nenue@96
|
348 pin:Refresh()
|
Nenue@96
|
349 else
|
Nenue@96
|
350 print('|cFFFF4400flagging queued pin that got hidden:', pin.title)
|
Nenue@96
|
351 pin.isStale = true
|
Nenue@33
|
352 end
|
Nenue@33
|
353 end
|
Nenue@33
|
354
|
Nenue@72
|
355 function Module:UpdateBounties(...)
|
Nenue@102
|
356 bountiesDirty = nil
|
Nenue@102
|
357 print('|cFF00FF88BountyInfo()|r', ...)
|
Nenue@72
|
358 wipe(db.BountiesByFactionID)
|
Nenue@75
|
359 wipe(db.BountiesByQuestID)
|
Nenue@72
|
360
|
Nenue@72
|
361 db.selectedBounty = nil
|
Nenue@72
|
362 selectedBountyIndex = BountyBoard:GetSelectedBountyIndex()
|
Nenue@75
|
363 db.Bounties, bountyDisplayLocation, bountyLockedQuestID = GetQuestBountyInfoForMapID(db.currentMapID, db.Bounties)
|
Nenue@72
|
364 local numBounties = 0
|
Nenue@75
|
365 for index, info in ipairs(db.Bounties) do
|
Nenue@72
|
366 numBounties = numBounties + 1
|
Nenue@73
|
367 info.index = index
|
Nenue@73
|
368 info.complete = IsQuestComplete(info.questID)
|
Nenue@73
|
369 if not info.complete then
|
Nenue@73
|
370 db.BountiesByFactionID[info.factionID] = info
|
Nenue@75
|
371 db.BountiesByQuestID[info.questID] = info
|
Nenue@72
|
372 if index == selectedBountyIndex then
|
Nenue@73
|
373 db.selectedBounty = info
|
Nenue@73
|
374 selectedBountyQuestID = info.questID
|
Nenue@72
|
375 end
|
Nenue@73
|
376 print(' ', index, info.factionID, GetQuestLogTitle(GetQuestLogIndexByID(info.questID)), info.complete, (index == selectedBountyIndex) and 'SELECTED' or '')
|
Nenue@72
|
377 end
|
Nenue@72
|
378 end
|
Nenue@72
|
379 end
|
Nenue@72
|
380
|
Nenue@93
|
381 -- check current artifact knowledge and update pins accordingly
|
Nenue@93
|
382 function Module:UpdateArtifactPower(overrideLevel)
|
Nenue@93
|
383 if InCombatLockdown() then
|
Nenue@93
|
384 artifactPowerDirty = true
|
Nenue@93
|
385 return
|
Nenue@40
|
386 end
|
Nenue@40
|
387
|
Nenue@93
|
388 print('|cFF00FF88UpdateArtifactPower()|r')
|
Nenue@93
|
389 local _, akLevel = GetCurrencyInfo(1171)
|
Nenue@93
|
390 if overrideLevel then
|
Nenue@93
|
391 akLevel = overrideLevel
|
Nenue@40
|
392 end
|
Nenue@40
|
393
|
Nenue@93
|
394 --db.print('current AK', akLevel)
|
Nenue@93
|
395 if akLevel and (akLevel ~= artifactKnowledgeLevel) or (not artifactKnowledgeLevel) then
|
Nenue@93
|
396 --print('new ak level', akLevel)
|
Nenue@93
|
397 db.log('AK update ' .. tostring(artifactKnowledgeLevel) .. ' to '.. tostring(akLevel))
|
Nenue@93
|
398 for _, pin in pairs(db.QuestsByID) do
|
Nenue@93
|
399 if (pin.rewardType == REWARD_ARTIFACT_POWER) then
|
Nenue@93
|
400 print(pin.title, pin.itemNumber)
|
Nenue@93
|
401 local newAP = pin:UpdateArtifactPower()
|
Nenue@93
|
402 if newAP then
|
Nenue@93
|
403 pin.itemNumber = newAP
|
Nenue@93
|
404 print(newAP)
|
Nenue@93
|
405 else
|
Nenue@93
|
406 pin.dataLoaded = nil
|
Nenue@93
|
407 end
|
Nenue@93
|
408 pin.isStale = true
|
Nenue@93
|
409 end
|
Nenue@33
|
410 end
|
Nenue@93
|
411 artifactKnowledgeLevel = akLevel
|
Nenue@40
|
412 end
|
Nenue@93
|
413 artifactPowerDirty = nil
|
Nenue@75
|
414 end
|
Nenue@40
|
415
|
Nenue@72
|
416 local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF'
|
Nenue@72
|
417 function Module:Refresh(...)
|
Nenue@96
|
418
|
Nenue@96
|
419 if hooksDirty then
|
Nenue@96
|
420 hooksDirty = self:SetupCallbacks()
|
Nenue@96
|
421 end
|
Nenue@96
|
422
|
Nenue@96
|
423
|
Nenue@34
|
424 if not self:IsVisible() then
|
Nenue@75
|
425 print('|cFFFF4400Refresh()|r', ...)
|
Nenue@75
|
426 return
|
Nenue@73
|
427 else
|
Nenue@75
|
428 if lastRefresh == GetTime() then
|
Nenue@75
|
429 print('|cFFFF4400multiple refreshes tried')
|
Nenue@75
|
430 end
|
Nenue@75
|
431 lastRefresh = GetTime()
|
Nenue@75
|
432 print(msg, lastRefresh, ...)
|
Nenue@40
|
433 end
|
Nenue@73
|
434
|
Nenue@102
|
435
|
Nenue@102
|
436 if bountiesDirty then
|
Nenue@102
|
437 self:UpdateBounties()
|
Nenue@102
|
438 end
|
Nenue@102
|
439
|
Nenue@67
|
440 if not db.Config.EnablePins then
|
Nenue@69
|
441 numShown = 0
|
Nenue@76
|
442 self.refreshBenchMark = GetTime()
|
Nenue@76
|
443 self.refreshBenchMarkTicker = 2
|
Nenue@76
|
444 print('starting bench', self.refreshBenchMark)
|
Nenue@67
|
445 return
|
Nenue@67
|
446 end
|
Nenue@67
|
447
|
Nenue@72
|
448 scaleConstant = db.isContinentMap and 2 or 3
|
Nenue@72
|
449 canTargetQuests = SpellCanTargetQuest()
|
Nenue@67
|
450
|
Nenue@40
|
451 for index, pin in pairs(db.QuestsByID) do
|
Nenue@40
|
452 pin.used = nil
|
Nenue@40
|
453 end
|
Nenue@40
|
454
|
Nenue@95
|
455 self:UpdateAnchors(...)
|
Nenue@72
|
456
|
Nenue@93
|
457 if artifactPowerDirty and not InCombatLockdown() then
|
Nenue@93
|
458 self:UpdateArtifactPower()
|
Nenue@93
|
459 end
|
Nenue@69
|
460 -- calculate quests shown
|
Nenue@65
|
461 numShown = 0
|
Nenue@65
|
462 numLoaded = 0
|
Nick@60
|
463 for questID, pin in pairs(db.QuestsByID) do
|
Nick@60
|
464 local oV = pin:IsShown()
|
Nick@60
|
465 if pin.used then
|
Nenue@96
|
466 print('show', pin.title)
|
Nick@60
|
467 pin.throttle = 1
|
Nick@60
|
468 pin:SetShown(true)
|
Nenue@65
|
469 numShown = numShown + 1
|
Nenue@65
|
470 if pin.dataLoaded then
|
Nenue@65
|
471 numLoaded = numLoaded + 1
|
Nenue@65
|
472 end
|
Nenue@65
|
473
|
Nenue@100
|
474 pin.checkCriteria = true
|
Nenue@100
|
475 pin.checkFilters = true
|
Nenue@100
|
476 pin:Refresh('WORLDMAP_REFRESH ' .. GetTime())
|
Nenue@100
|
477
|
Nick@60
|
478 else
|
Nenue@96
|
479 if pin:IsShown() then
|
Nenue@96
|
480 print('|cFFFF4400need to remove', pin.title)
|
Nenue@96
|
481
|
Nick@60
|
482 end
|
Nenue@96
|
483
|
Nenue@69
|
484 pin.hideReason = "Not used in map area " .. (db.currentMapID)
|
Nenue@75
|
485 pin:SetShown(false)
|
Nick@60
|
486 end
|
Nenue@93
|
487
|
Nick@60
|
488 end
|
Nenue@93
|
489
|
Nenue@65
|
490
|
Nenue@75
|
491 --
|
Nenue@93
|
492 self.refreshBenchMark = GetTime()
|
Nenue@93
|
493 self.refreshBenchMarkTicker = 2
|
Nenue@93
|
494 print('starting bench', self.refreshBenchMark)
|
Nenue@76
|
495
|
Nenue@75
|
496 --
|
Nenue@65
|
497
|
Nenue@73
|
498 layoutDirty = nil
|
Nenue@40
|
499 self.isStale = nil
|
Nenue@54
|
500 self.sizesDirty = nil
|
Nenue@66
|
501 self.isZoomDirty = nil
|
Nenue@75
|
502
|
Nenue@93
|
503 if WorldPlanSummary then
|
Nenue@93
|
504 WorldPlanSummary.isStale = true
|
Nenue@93
|
505 end
|
Nenue@93
|
506
|
Nenue@40
|
507 end
|
Nenue@40
|
508
|
Nenue@75
|
509 function Module:RefreshIfChanged(event)
|
Nenue@69
|
510 local scaleCheck = WorldMapDetailFrame:GetScale()
|
Nenue@73
|
511 refreshReason = nil
|
Nenue@69
|
512 if scaleCheck ~= currentScale then
|
Nenue@73
|
513 refreshReason = 'map scale updated'
|
Nenue@69
|
514 currentScale = scaleCheck
|
Nenue@75
|
515 layoutDirty = true
|
Nenue@72
|
516 elseif self.isStale or layoutDirty then
|
Nenue@73
|
517 refreshReason = 'layout is marked dirty'
|
Nenue@73
|
518 end
|
Nenue@73
|
519 if not refreshReason then
|
Nenue@73
|
520 return
|
Nenue@73
|
521 end
|
Nenue@73
|
522
|
Nenue@73
|
523 if self:IsVisible() then
|
Nenue@73
|
524 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
|
Nenue@75
|
525 self:Refresh(event)
|
Nenue@73
|
526 else
|
Nenue@75
|
527 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
|
Nenue@73
|
528 self.isStale = true
|
Nenue@69
|
529 end
|
Nenue@69
|
530 end
|
Nenue@69
|
531
|
Nenue@93
|
532 -- Walks the current map tree and fires updates as needed
|
Nenue@95
|
533 function Module:UpdateAnchors (event)
|
Nenue@40
|
534 wipe(self.UsedPositions)
|
Nenue@74
|
535 local hostWidth, hostHeight = WorldMapPOIFrame:GetSize()
|
Nenue@74
|
536
|
Nenue@74
|
537 if (hostWidth ~= self.hostWidth) or (hostHeight ~= self.hostHeight) then
|
Nenue@74
|
538 self.hostWidth, self.hostHeight = hostWidth, hostHeight
|
Nenue@74
|
539 layoutDirty = true
|
Nenue@74
|
540 end
|
Nenue@74
|
541
|
Nenue@95
|
542 print('|cFF00FF00UpdateAnchors()', event)
|
Nenue@33
|
543 local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo()
|
Nenue@33
|
544 if isMicroDungeon then
|
Nenue@33
|
545 return
|
Nenue@33
|
546 end
|
Nenue@69
|
547
|
Nenue@65
|
548 isDataLoaded = true
|
Nenue@67
|
549 local taskInfo = TQ_GetQuestsForPlayerByMapID(db.currentMapID)
|
Nenue@111
|
550 local transformFlags = (db.currentMapID == 1184) and Enum.MapTransform.IsForFlightMap or nil
|
Nenue@40
|
551 if taskInfo then
|
Nenue@69
|
552 self:UpdateQuestsForMap(taskInfo, db.currentMapID)
|
Nenue@33
|
553 end
|
Nenue@67
|
554 local numZones = MC_GetNumZones(db.currentMapID)
|
Nenue@33
|
555 if numZones then
|
Nenue@33
|
556 for i = 1, numZones do
|
Nenue@67
|
557 local mapAreaID = MC_GetZoneInfo(db.currentMapID, i)
|
Nenue@111
|
558 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, db.currentMapID, transformFlags)
|
Nenue@82
|
559
|
Nenue@82
|
560 db.QuestsByZone[mapAreaID] = db.QuestsByZone[mapAreaID] or {}
|
Nenue@82
|
561
|
Nenue@40
|
562 if taskInfo then
|
Nenue@111
|
563 self:UpdateQuestsForMap(taskInfo, mapAreaID, transformFlags)
|
Nenue@40
|
564 end
|
Nenue@33
|
565 end
|
Nenue@33
|
566 end
|
Nenue@111
|
567
|
Nenue@119
|
568 -- Argus inset
|
Nenue@119
|
569
|
Nenue@111
|
570
|
Nenue@33
|
571 end
|
Nenue@33
|
572
|
Nenue@96
|
573 -- Attempt to display the pins for quests in taskInfo
|
Nenue@111
|
574 function Module:UpdateQuestsForMap(taskInfo, mapID, transformFlags)
|
Nenue@93
|
575 print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty)
|
Nenue@93
|
576 if db.QuestsByZone[mapID] then
|
Nenue@93
|
577 wipe(db.QuestsByZone[mapID])
|
Nenue@93
|
578 elseif db.isBrokenIsle then
|
Nenue@93
|
579 continentScanned = true
|
Nenue@93
|
580 end
|
Nenue@108
|
581 db.PinStrata = WorldMapFrame_InWindowedMode() and 'HIGH' or 'FULLSCREEN'
|
Nenue@96
|
582 print('layoutDirty =',layoutDirty)
|
Nenue@93
|
583
|
Nenue@93
|
584 for index, info in pairs(taskInfo) do
|
Nenue@93
|
585 local questID, x, y = info.questId, info.x, info.y
|
Nenue@111
|
586
|
Nenue@119
|
587 -- rough workaround for argus continent map that uses a different image
|
Nenue@119
|
588 if x and y and(db.currentMapID == 1184) then
|
Nenue@111
|
589 print(x,y)
|
Nenue@111
|
590 x = x / 2 + .25
|
Nenue@111
|
591 y = y / 2 + .30
|
Nenue@111
|
592 print(x,y)
|
Nenue@111
|
593 end
|
Nenue@111
|
594
|
Nenue@111
|
595
|
Nenue@93
|
596 local pin = self:AcquirePin(info)
|
Nenue@100
|
597 if pin then
|
Nenue@100
|
598 if pin.canShow then
|
Nenue@100
|
599 pin.used = true
|
Nenue@100
|
600 print('using', pin.title, (pin.owningFrame ~= WorldMapFrame))
|
Nenue@100
|
601 if layoutDirty or (pin.owningFrame ~= WorldMapFrame) then
|
Nenue@100
|
602 local scaleFactor = SCALE_FACTORS[(not pin.filtered and scaleConstant) or 1]
|
Nenue@100
|
603 pin.owningFrame = WorldMapFrame
|
Nenue@100
|
604 pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor)
|
Nenue@93
|
605
|
Nenue@93
|
606 end
|
Nenue@100
|
607 if db.QuestsByZone[mapID] then
|
Nenue@100
|
608 db.QuestsByZone[mapID][questID] = pin
|
Nenue@100
|
609 end
|
Nenue@117
|
610
|
Nenue@117
|
611 if SUBCONTINENT_MAPS[mapID] then
|
Nenue@117
|
612 db.QuestsByZone[SUBCONTINENT_MAPS[mapID]] = db.QuestsByZone[SUBCONTINENT_MAPS[mapID]] or {}
|
Nenue@117
|
613 db.QuestsByZone[SUBCONTINENT_MAPS[mapID]][questID] = pin
|
Nenue@117
|
614 end
|
Nenue@117
|
615
|
Nenue@117
|
616
|
Nenue@100
|
617 else
|
Nenue@100
|
618 print('|cFFFF4400discarding|r', pin.title)
|
Nenue@93
|
619 end
|
Nenue@93
|
620 end
|
Nenue@93
|
621 end
|
Nenue@67
|
622 end
|
Nenue@93
|
623
|
Nenue@93
|
624 -- locates or creates a corresponding pin frame for the provided TaskInfo data
|
Nenue@93
|
625 function Module:AcquirePin (info)
|
Nenue@93
|
626 local questID = info.questId
|
Nenue@93
|
627 if not (questID and QuestUtils_IsQuestWorldQuest(questID)) then
|
Nenue@93
|
628 return nil
|
Nenue@93
|
629 end
|
Nenue@103
|
630 local pin = db.QuestsByID[questID]
|
Nenue@103
|
631 -- check to avoid creating unnecessary frames
|
Nenue@103
|
632 if IsQuestComplete(questID) or completedQuests[questID] then
|
Nenue@103
|
633 completedQuests[questID] = true
|
Nenue@103
|
634 if pin then
|
Nenue@103
|
635 pin:Release()
|
Nenue@103
|
636 end
|
Nenue@100
|
637 return nil
|
Nenue@100
|
638 end
|
Nenue@100
|
639
|
Nenue@93
|
640 if not pin then
|
Nenue@93
|
641 local numFree = #db.FreePins
|
Nenue@93
|
642 if numFree >= 1 then
|
Nenue@93
|
643 pin = tremove(db.FreePins, numFree)
|
Nenue@100
|
644 print('|cFF00FF00Acquire()|r Re-using', pin:GetName())
|
Nenue@93
|
645 else
|
Nenue@93
|
646 totalPins = totalPins + 1
|
Nenue@93
|
647 local name = 'WorldPlanQuestMarker' .. numOverlays
|
Nenue@100
|
648 print('|cFF00FF00Acquire()|r Creating', name)
|
Nenue@93
|
649 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
|
Nenue@93
|
650
|
Nenue@93
|
651 pin:SetID(totalPins)
|
Nenue@93
|
652 numOverlays = numOverlays + 1
|
Nenue@93
|
653 --pin.iconBorder:SetVertexColor(0,0,0,1)
|
Nenue@93
|
654 end
|
Nenue@93
|
655 pin.questID = questID
|
Nenue@93
|
656 pin.throttle = pin.updateRate
|
Nenue@93
|
657 pin.currentWidth = nil
|
Nenue@100
|
658
|
Nenue@93
|
659 db.QuestsByID[questID] = pin
|
Nenue@93
|
660 tinsert(db.UsedPins, pin)
|
Nenue@93
|
661 end
|
Nenue@93
|
662
|
Nenue@103
|
663 if info then
|
Nenue@93
|
664 pin.inProgress = info.inProgress
|
Nenue@93
|
665 pin.floor = info.floor
|
Nenue@93
|
666 pin.numObjectives = info.numObjectives or 0
|
Nenue@93
|
667 if info.x and info.y then
|
Nenue@93
|
668 if (info.x ~= pin.x) or (info.y ~= pin.y) then
|
Nenue@93
|
669 pin.isStale = true
|
Nenue@93
|
670 --rprint('|cFFFF4400SetCoords|r', info.x, info.y)
|
Nenue@93
|
671 end
|
Nenue@93
|
672 end
|
Nenue@93
|
673 end
|
Nenue@93
|
674
|
Nenue@93
|
675 pin.x = info.x or pin.x
|
Nenue@93
|
676 pin.y = info.y or pin.y
|
Nenue@93
|
677
|
Nenue@93
|
678 if not HaveQuestRewardData(questID) then
|
Nenue@93
|
679 TQ_RequestPreloadRewardData(questID);
|
Nenue@93
|
680 end
|
Nenue@93
|
681
|
Nenue@93
|
682 if (not pin.dataLoaded) then
|
Nenue@93
|
683 local dataLoaded = pin:GetData()
|
Nenue@93
|
684 if dataLoaded then
|
Nenue@93
|
685 WorldPlan.dataFlush = true
|
Nenue@93
|
686 else
|
Nenue@93
|
687 isDataLoaded = false
|
Nenue@93
|
688 end
|
Nenue@93
|
689 end
|
Nenue@93
|
690
|
Nenue@100
|
691 pin:OnFilters()
|
Nenue@93
|
692 pin.isActive = TQ_IsActive(questID)
|
Nenue@93
|
693 --rprint(pin:GetID(), pin.filtered, pin.used)
|
Nenue@93
|
694 return pin
|
Nenue@93
|
695 end
|
Nenue@93
|
696
|
Nenue@93
|
697 function Module:Debug(...)
|
Nenue@93
|
698 print(...)
|
Nenue@67
|
699 end |