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@72
|
6 local print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end
|
Nenue@72
|
7 local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or function() end
|
Nenue@72
|
8 local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end
|
Nenue@72
|
9 local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end
|
Nenue@72
|
10 local mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or function() end
|
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
|
Nick@64
|
20 local pairs, ipairs, tinsert, tremove, wipe = pairs, ipairs, tinsert, tremove, table.wipe
|
Nick@64
|
21 local GetTaskInfo, GetTasksTable, HaveQuestData = GetTaskInfo, GetTasksTable, HaveQuestData
|
Nick@64
|
22 local GetTime = GetTime
|
Nenue@69
|
23 local SpellCanTargetQuest, IsQuestIDValidSpellTarget = SpellCanTargetQuest, IsQuestIDValidSpellTarget
|
Nick@64
|
24 local tonumber, abs = tonumber, math.abs
|
Nick@64
|
25 local GetQuestLogRewardInfo = GetQuestLogRewardInfo
|
Nick@64
|
26 local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID
|
Nenue@72
|
27 local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete
|
Nenue@72
|
28 local IsQuestCriteriaForBounty = IsQuestCriteriaForBounty
|
Nenue@33
|
29
|
Nenue@69
|
30 local ToggleButton = {}
|
Nenue@69
|
31 local callbacks = {}
|
Nenue@40
|
32 local PinBaseIndex = 1200
|
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@72
|
46
|
Nenue@72
|
47 local layoutDirty = true
|
Nenue@72
|
48 local bountiesDirty = true
|
Nenue@69
|
49 local currentScale = WorldMapDetailFrame:GetScale()
|
Nenue@69
|
50 local canTargetQuests
|
Nenue@65
|
51 local numShown = 0
|
Nenue@65
|
52 local numLoaded = 0
|
Nenue@69
|
53 local isDataLoaded = true
|
Nenue@69
|
54 local numOverlays = 1
|
Nenue@66
|
55 local scaleConstant = 1
|
Nenue@45
|
56 Module.TasksByID = {}
|
Nenue@33
|
57
|
Nenue@33
|
58 --%debug%
|
Nenue@33
|
59 local SetTimedCallbackForAllPins = function(seconds, callback)
|
Nenue@33
|
60 C_Timer.After(seconds, function()
|
Nenue@33
|
61 for id, pin in pairs(WorldPlanQuests.QuestsByID) do
|
Nenue@33
|
62 callback(pin)
|
Nenue@33
|
63 end
|
Nenue@33
|
64 end)
|
Nenue@33
|
65 end
|
Nenue@33
|
66
|
Nenue@45
|
67 function Module:OnUpdate(sinceLast)
|
Nenue@67
|
68
|
Nenue@67
|
69 if self.filtersDirty or self.isStale then
|
Nenue@40
|
70 self:Refresh()
|
Nenue@40
|
71 end
|
Nenue@67
|
72 if #db.UpdatedPins >= 1 then
|
Nenue@67
|
73 print('|cFF00FF88pending updates', #db.UpdatedPins)
|
Nenue@72
|
74 self:RefreshIfQueued()
|
Nenue@67
|
75 end
|
Nenue@67
|
76
|
Nenue@40
|
77 end
|
Nenue@40
|
78
|
Nenue@52
|
79
|
Nenue@45
|
80 function Module:Setup()
|
Nenue@40
|
81 print('|cFFFF4400'..self:GetName()..':Setup()')
|
Nenue@33
|
82 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
|
Nenue@40
|
83 db.QuestsByZone[mapID] = {}
|
Nenue@33
|
84 end
|
Nenue@69
|
85 for target, arg in pairs(callbacks) do
|
Nenue@69
|
86 print(type(target))
|
Nenue@69
|
87 if type(target) == 'table' then
|
Nenue@71
|
88 local callerName = target:GetName() or tostring(target)
|
Nenue@69
|
89 for name, method in pairs(arg) do
|
Nenue@69
|
90 print(callerName, arg)
|
Nenue@69
|
91 hooksecurefunc(target, name, function(...)
|
Nenue@71
|
92 self:OnSecureHook(callerName .. '.' .. name, method, ...)
|
Nenue@69
|
93 end)
|
Nenue@69
|
94 end
|
Nenue@69
|
95 else
|
Nenue@69
|
96 hooksecurefunc(target, function(...)
|
Nenue@69
|
97 self:OnSecureHook(target, arg, ...)
|
Nenue@69
|
98 end)
|
Nenue@69
|
99 end
|
Nenue@69
|
100 end
|
Nenue@65
|
101
|
Nenue@65
|
102 self.Status = CreateFrame('Frame', nil, self)
|
Nenue@65
|
103 self.Status:SetPoint('TOPLEFT', WorldMapPOIFrame, 'TOPLEFT', 0, 0)
|
Nenue@65
|
104 self.Status:SetPoint('BOTTOMRIGHT', WorldMapPOIFrame, 'TOPRIGHT', 0, -4)
|
Nenue@65
|
105 self.Status.t = self.Status:CreateTexture(nil, 'OVERLAY')
|
Nenue@65
|
106 self.Status.b = self.Status:CreateTexture(nil, 'BACKGROUND')
|
Nenue@65
|
107 self.Status.b:SetColorTexture(0,0,0,.25)
|
Nenue@65
|
108 self.Status.b:SetAllPoints(self.Status)
|
Nenue@65
|
109 self.Status.t:SetColorTexture(1,1,1,.5)
|
Nenue@65
|
110 self.Status.t:SetPoint('TOP')
|
Nenue@65
|
111 self.Status.t:SetPoint('BOTTOM')
|
Nenue@65
|
112 self.Status.t:SetPoint('LEFT')
|
Nenue@65
|
113 local translationEnd, translationStart
|
Nenue@65
|
114 self.Status:SetScript('OnUpdate', function(status)
|
Nenue@65
|
115 local translateTo
|
Nenue@65
|
116 if numLoaded < numShown then
|
Nenue@65
|
117 translateTo = numLoaded/numShown * status:GetWidth()
|
Nenue@65
|
118 status.t:SetWidth(translateTo)
|
Nenue@65
|
119 else
|
Nenue@65
|
120 translateTo = numShown * status:GetWidth()
|
Nenue@65
|
121 status.t:SetWidth(translateTo)
|
Nenue@65
|
122 end
|
Nenue@65
|
123 end)
|
Nenue@67
|
124
|
Nenue@67
|
125 self:SetAllPoints(WorldMapPOIFrame)
|
Nenue@67
|
126 for k,v in pairs( ToggleButton) do
|
Nenue@67
|
127 self.Toggle:SetScript(k,v)
|
Nenue@67
|
128 end
|
Nenue@72
|
129
|
Nenue@72
|
130 self:UpdateBounties('SETUP')
|
Nenue@72
|
131
|
Nenue@67
|
132 self:Show()
|
Nenue@67
|
133 end
|
Nenue@69
|
134 callbacks.ClickWorldMapActionButton = function(WorldQuests)
|
Nenue@73
|
135 WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON')
|
Nenue@69
|
136 end
|
Nenue@69
|
137 callbacks.WorldMap_UpdateQuestBonusObjectives = function(WorldQuests)
|
Nenue@73
|
138 WorldQuests:UpdateTaskPOIs()
|
Nenue@69
|
139 end
|
Nenue@69
|
140 callbacks.WorldMapFrame_UpdateMap = function(WorldQuests)
|
Nenue@69
|
141 WorldQuests:RefreshIfChanged()
|
Nenue@69
|
142 end
|
Nenue@69
|
143 callbacks.WorldMapScrollFrame_ReanchorQuestPOIs = function (WorldQuests)
|
Nenue@69
|
144 WorldQuests:RefreshIfChanged()
|
Nenue@69
|
145 end
|
Nenue@69
|
146
|
Nenue@72
|
147 callbacks[BountyBoard] = {}
|
Nenue@72
|
148 callbacks[BountyBoard].SetSelectedBountyIndex = function(WorldQuests)
|
Nenue@72
|
149 WorldQuests:UpdateBounties('BOUNTY_SELECTED')
|
Nenue@73
|
150 WorldQuests:Refresh('BOUNTY_SELECTED')
|
Nenue@72
|
151 end
|
Nenue@67
|
152
|
Nenue@72
|
153 callbacks[ActionButton] = {}
|
Nenue@72
|
154 callbacks[ActionButton].UpdateCastingState = function(WorldQuests)
|
Nenue@73
|
155 WorldQuests:Refresh('CASTING_STATE_CHANGED')
|
Nenue@67
|
156 end
|
Nenue@67
|
157
|
Nenue@49
|
158 function Module:OnConfigUpdate()
|
Nenue@67
|
159 print('|cFFFFFF00OnConfigUpdate()|r')
|
Nenue@49
|
160 if db.Config.FadeWhileGrouped then
|
Nenue@49
|
161 db.PinAlpha = 0.15
|
Nenue@49
|
162 else
|
Nenue@49
|
163 db.PinAlpha = 1
|
Nenue@49
|
164 end
|
Nenue@67
|
165
|
Nenue@67
|
166 if not db.Config.EnablePins then
|
Nenue@67
|
167 for _, pin in pairs(db.QuestsByID) do
|
Nenue@67
|
168 pin:SetShown(false)
|
Nenue@67
|
169 end
|
Nenue@67
|
170 end
|
Nenue@67
|
171
|
Nenue@67
|
172 ToggleButton.OnShow(self.Toggle)
|
Nenue@49
|
173 end
|
Nenue@49
|
174
|
Nenue@45
|
175 local InternalHideButton = function(button, index)
|
Nenue@45
|
176 button:Hide()
|
Nenue@45
|
177 end
|
Nenue@45
|
178 local InternalShowButton = function(button, index)
|
Nenue@45
|
179 button:Show()
|
Nenue@45
|
180 end
|
Nenue@33
|
181
|
Nenue@69
|
182 db.UsedPOIs = {}
|
Nenue@73
|
183 function Module:UpdateTaskPOIs()
|
Nenue@73
|
184 canTargetQuests = SpellCanTargetQuest()
|
Nenue@73
|
185 local func = canTargetQuests and 'Show' or 'Hide'
|
Nenue@45
|
186 for i = 1, NUM_WORLDMAP_TASK_POIS do
|
Nenue@45
|
187 local button = _G['WorldMapFrameTaskPOI'..i]
|
Nenue@45
|
188 if button and button.worldQuest then
|
Nenue@73
|
189 button[func](button)
|
Nenue@45
|
190 end
|
Nenue@45
|
191 end
|
Nenue@45
|
192 end
|
Nenue@40
|
193
|
Nenue@69
|
194 function Module:OnSecureHook(callbackName, func, ...)
|
Nenue@69
|
195 rprint('|cFFFF4400'..callbackName..'|r', ...)
|
Nenue@69
|
196 func(self, ...)
|
Nenue@45
|
197 end
|
Nenue@40
|
198
|
Nenue@33
|
199 local defaults = {}
|
Nenue@40
|
200 local REWARD_UNKNOWN = 768
|
Nenue@45
|
201 function Module:OnLoad()
|
Nenue@40
|
202 print('|cFFFF4400'..self:GetName()..':OnLoad()')
|
Nenue@33
|
203
|
Nenue@48
|
204 self:SetParent(WorldMapPOIFrame)
|
Nenue@33
|
205 WorldPlan:AddHandler(self, defaults)
|
Nenue@33
|
206
|
Nenue@33
|
207 for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
|
Nenue@40
|
208 db.QuestsByZone[areaID] = {}
|
Nenue@33
|
209 end
|
Nenue@33
|
210
|
Nenue@41
|
211 -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
|
Nenue@33
|
212 self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
|
Nenue@55
|
213 self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED')
|
Nenue@33
|
214 self:RegisterEvent('SKILL_LINES_CHANGED')
|
Nick@62
|
215 self:RegisterEvent('CURRENT_SPELL_CAST_CHANGED')
|
Nenue@69
|
216 self:RegisterEvent('ARTIFACT_UPDATE')
|
Nenue@73
|
217 self:RegisterEvent('QUEST_LOG_UPDATE')
|
Nenue@33
|
218 end
|
Nenue@33
|
219
|
Nenue@72
|
220 local artifactKnowledgeMultiplier
|
Nenue@65
|
221 local superTrackedQuestID
|
Nenue@45
|
222 function Module:OnEvent (event, ...)
|
Nenue@40
|
223
|
Nenue@40
|
224 print('|cFFFFFF00'..self:GetName()..':OnEvent() '..event..'|r', GetTime(), ...)
|
Nenue@69
|
225 if (event == 'QUEST_LOG_UPDATE') then
|
Nenue@73
|
226 self:UpdateBounties(event)
|
Nenue@73
|
227 self:RefreshIfChanged(event)
|
Nenue@33
|
228 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
|
Nenue@33
|
229 local questID = ...
|
Nenue@73
|
230 self:UpdateBounties(event)
|
Nenue@40
|
231 if questID and db.QuestsByID[questID] then
|
Nenue@74
|
232 db.QuestsByID[questID].complete = true
|
Nenue@33
|
233 end
|
Nenue@73
|
234 self:Refresh(event)
|
Nenue@65
|
235 elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then
|
Nenue@72
|
236 self:Refresh(event)
|
Nenue@59
|
237 elseif event == 'ARTIFACT_UPDATE' then
|
Nenue@72
|
238 local akCheck = C_ArtifactUI.GetArtifactKnowledgeMultiplier()
|
Nenue@72
|
239 if akCheck and (akCheck ~= artifactKnowledgeMultiplier) then
|
Nenue@72
|
240 if artifactKnowledgeMultiplier then
|
Nenue@72
|
241 print('push artifact knowledge update', artifactKnowledgeMultiplier, 'to', akCheck)
|
Nenue@72
|
242 for index, pin in pairs( db.QuestsByID) do
|
Nenue@72
|
243 if pin.rewardType == REWARD_ARTIFACT_POWER then
|
Nenue@72
|
244 db.log(pin.questID .. ' ' .. tostring(pin.title) .. ' Flagged for artifact power.')
|
Nenue@72
|
245 pin.itemNumber = 0
|
Nenue@72
|
246 pin.dataLoaded = nil
|
Nenue@72
|
247 end
|
Nenue@69
|
248 end
|
Nenue@72
|
249 else
|
Nenue@72
|
250
|
Nenue@72
|
251 print('artifact knowledge multiplier is known', akCheck)
|
Nick@62
|
252 end
|
Nenue@72
|
253 artifactKnowledgeMultiplier = akCheck
|
Nenue@59
|
254 end
|
Nenue@65
|
255 elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then
|
Nenue@65
|
256 if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then
|
Nenue@65
|
257 db.QuestsByID[superTrackedQuestID].isStale = true
|
Nenue@65
|
258 end
|
Nenue@65
|
259 local newID = GetSuperTrackedQuestID()
|
Nenue@65
|
260 if newID and db.QuestsByID[newID] then
|
Nenue@65
|
261 db.QuestsByID[newID].isStale = true
|
Nenue@65
|
262 end
|
Nenue@33
|
263 end
|
Nenue@33
|
264 end
|
Nenue@33
|
265
|
Nenue@72
|
266
|
Nenue@72
|
267
|
Nenue@73
|
268 local bountyQuests = {}
|
Nenue@72
|
269 local bountyInfo = {}
|
Nenue@72
|
270 local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID
|
Nenue@72
|
271 function Module:UpdateBounties(...)
|
Nenue@72
|
272 print('|cFF00FF88BountyInfo()|r', ...)
|
Nenue@72
|
273 wipe(db.BountiesByFactionID)
|
Nenue@73
|
274 wipe(bountyQuests)
|
Nenue@72
|
275
|
Nenue@72
|
276 db.selectedBounty = nil
|
Nenue@72
|
277 selectedBountyIndex = BountyBoard:GetSelectedBountyIndex()
|
Nenue@72
|
278 bountyInfo, bountyDisplayLocation, bountyLockedQuestID = GetQuestBountyInfoForMapID(db.currentMapID, bountyInfo)
|
Nenue@72
|
279 local numBounties = 0
|
Nenue@73
|
280 for index, info in ipairs(bountyInfo) do
|
Nenue@73
|
281 if info.factionID then
|
Nenue@72
|
282 numBounties = numBounties + 1
|
Nenue@73
|
283 info.index = index
|
Nenue@73
|
284 info.complete = IsQuestComplete(info.questID)
|
Nenue@73
|
285 if not info.complete then
|
Nenue@73
|
286 db.BountiesByFactionID[info.factionID] = info
|
Nenue@72
|
287 if index == selectedBountyIndex then
|
Nenue@73
|
288 db.selectedBounty = info
|
Nenue@73
|
289 selectedBountyQuestID = info.questID
|
Nenue@72
|
290 end
|
Nenue@73
|
291 print(' ', index, info.factionID, GetQuestLogTitle(GetQuestLogIndexByID(info.questID)), info.complete, (index == selectedBountyIndex) and 'SELECTED' or '')
|
Nenue@73
|
292 bountyQuests[info.questID] = info
|
Nenue@72
|
293 end
|
Nenue@72
|
294 end
|
Nenue@72
|
295 end
|
Nenue@73
|
296 bountiesDirty = nil
|
Nenue@72
|
297 end
|
Nenue@72
|
298
|
Nenue@72
|
299 function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
|
Nenue@72
|
300 if isNewMap then
|
Nenue@73
|
301 print('|cFF00FF88OnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
|
Nenue@72
|
302 if isMapOpen then
|
Nenue@72
|
303 self:Refresh(true)
|
Nenue@72
|
304 else
|
Nenue@72
|
305 self.isStale = true
|
Nenue@72
|
306 end
|
Nenue@72
|
307 else
|
Nenue@72
|
308
|
Nenue@72
|
309 rprint('|cFFFFFF00'..self:GetName()..':OnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
|
Nenue@72
|
310 end
|
Nenue@72
|
311 end
|
Nenue@72
|
312
|
Nenue@72
|
313
|
Nenue@40
|
314 local totalPins = 0
|
Nenue@33
|
315 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
|
Nenue@45
|
316 function Module:AcquirePin (info)
|
Nenue@40
|
317 local questID = info.questId
|
Nenue@40
|
318 if not questID then
|
Nenue@40
|
319 return nil
|
Nenue@40
|
320 end
|
Nenue@40
|
321
|
Nenue@40
|
322 if not QuestUtils_IsQuestWorldQuest(questID) then
|
Nenue@40
|
323 return nil
|
Nenue@40
|
324 end
|
Nenue@40
|
325
|
Nenue@49
|
326 -- if we're grabbing a pin, the filters need to be checked
|
Nenue@40
|
327 local pin = db.QuestsByID[questID]
|
Nenue@33
|
328 if not pin then
|
Nenue@40
|
329 local numFree = #db.FreePins
|
Nenue@33
|
330 if numFree >= 1 then
|
Nenue@40
|
331 pin = tremove(db.FreePins, numFree)
|
Nenue@33
|
332 --print('|cFF00FF00Re-using', pin:GetName())
|
Nenue@33
|
333 else
|
Nenue@40
|
334 totalPins = totalPins + 1
|
Nenue@69
|
335 local name = 'WorldPlanQuestMarker' .. numOverlays
|
Nenue@33
|
336 --print('|cFF00FF00Creating', name)
|
Nenue@33
|
337 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
|
Nenue@33
|
338
|
Nenue@33
|
339 pin:SetFrameStrata('HIGH')
|
Nenue@33
|
340 pin.GetTypeInfo = function(frame, typeID)
|
Nenue@33
|
341 return self:GetTypeInfo(typeID)
|
Nenue@33
|
342 end
|
Nenue@40
|
343 pin:SetID(totalPins)
|
Nenue@69
|
344 numOverlays = numOverlays + 1
|
Nenue@33
|
345 --pin.iconBorder:SetVertexColor(0,0,0,1)
|
Nenue@33
|
346 end
|
Nenue@40
|
347 pin.questID = questID
|
Nenue@40
|
348 pin.worldQuest = true
|
Nenue@40
|
349 pin.throttle = 1
|
Nenue@33
|
350 pin.isNew = true
|
Nenue@33
|
351 pin.currentWidth = nil
|
Nenue@40
|
352 db.QuestsByID[questID] = pin
|
Nenue@40
|
353 tinsert(db.UsedPins, pin)
|
Nenue@40
|
354 end
|
Nenue@33
|
355
|
Nenue@40
|
356 if pin and info then
|
Nenue@40
|
357 pin.inProgress = info.inProgress
|
Nenue@40
|
358 pin.floor = info.floor
|
Nenue@40
|
359 pin.numObjectives = info.numObjectives or 0
|
Nenue@40
|
360 if info.x and info.y then
|
Nenue@40
|
361 pin.x = info.x or pin.x
|
Nenue@40
|
362 pin.y = info.y or pin.y
|
Nenue@74
|
363 --rprint('|cFFFF4400coords|r', info.x, info.y)
|
Nenue@40
|
364 end
|
Nenue@40
|
365 end
|
Nenue@33
|
366
|
Nick@62
|
367 if (not pin.dataLoaded) then
|
Nenue@65
|
368 local dataLoaded = pin:GetData()
|
Nenue@65
|
369 isDataLoaded = (isDataLoaded and dataLoaded)
|
Nick@63
|
370 WorldPlan.dataFlush = true
|
Nenue@49
|
371 end
|
Nenue@49
|
372
|
Nenue@66
|
373
|
Nick@64
|
374 pin.isActive = TQ_IsActive(questID)
|
Nenue@57
|
375 pin:CheckFilterRules()
|
Nenue@49
|
376 rprint(pin:GetID(), pin.filtered, pin.used)
|
Nenue@49
|
377
|
Nenue@40
|
378 return pin
|
Nenue@33
|
379 end
|
Nenue@33
|
380
|
Nenue@33
|
381 -- remove from index and add it to the recycling heap
|
Nenue@45
|
382 function Module:ReleasePin (pin)
|
Nenue@33
|
383
|
Nenue@40
|
384 local id = pin.questID
|
Nenue@33
|
385 if id then
|
Nenue@40
|
386 db.QuestsByID[id] = nil
|
Nenue@40
|
387
|
Nenue@40
|
388 for i, zone in pairs(db.QuestsByZone) do
|
Nenue@33
|
389 print('-', i, zone[i])
|
Nenue@33
|
390 zone[id] = nil
|
Nenue@33
|
391 end
|
Nenue@40
|
392 db.TasksByID[id] = nil
|
Nenue@33
|
393 end
|
Nick@64
|
394 pin.isActive = nil
|
Nick@64
|
395 pin.dataLoaded = nil
|
Nick@62
|
396 pin:HideFrames()
|
Nenue@40
|
397 tinsert(db.FreePins, pin)
|
Nenue@40
|
398
|
Nick@63
|
399 WorldPlan.dataFlush = true
|
Nenue@40
|
400 print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title)
|
Nenue@33
|
401 end
|
Nenue@33
|
402
|
Nenue@72
|
403 -- re-anchors and scales pins that have had either of these changed due to data loading delays
|
Nenue@72
|
404 function Module:RefreshIfQueued()
|
Nenue@72
|
405 print('|cFF00FF88RefreshIfQueued()')
|
Nenue@67
|
406 local pin = tremove(db.UpdatedPins)
|
Nenue@67
|
407 while pin do
|
Nenue@67
|
408 pin:CheckFilterRules()
|
Nenue@67
|
409
|
Nenue@67
|
410 local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
|
Nenue@67
|
411 print(pin.title, pin.dataLoaded and not pin.filtered, scaleFactor)
|
Nenue@71
|
412 if pin.used then
|
Nenue@71
|
413 pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor)
|
Nenue@71
|
414 if pin.isNew then
|
Nenue@71
|
415 pin:OnShow()
|
Nenue@71
|
416 end
|
Nenue@69
|
417 end
|
Nenue@69
|
418
|
Nenue@67
|
419 pin = tremove(db.UpdatedPins)
|
Nenue@69
|
420
|
Nenue@67
|
421 end
|
Nenue@67
|
422 end
|
Nenue@67
|
423
|
Nenue@40
|
424
|
Nenue@72
|
425 local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF'
|
Nenue@72
|
426 function Module:Refresh(...)
|
Nenue@33
|
427
|
Nenue@72
|
428 rprint(msg, ...)
|
Nenue@34
|
429 if not self:IsVisible() then
|
Nenue@73
|
430 rprint('|cFF00FF88WorldQuests:Refresh()|r', ...)
|
Nenue@34
|
431 self.isStale = true
|
Nenue@57
|
432 return self:MarkAllPins()
|
Nenue@73
|
433 else
|
Nenue@73
|
434 rprint('|cFF00FF88WorldQuests:Refresh()|r', ...)
|
Nenue@73
|
435 print('|cFF00FF88WorldQuests:Refresh()|r', ...)
|
Nenue@40
|
436 end
|
Nenue@73
|
437
|
Nenue@67
|
438 if not db.Config.EnablePins then
|
Nenue@69
|
439 numShown = 0
|
Nenue@67
|
440 return
|
Nenue@67
|
441 end
|
Nenue@72
|
442 wprint(' '..msg)
|
Nenue@67
|
443
|
Nenue@72
|
444 scaleConstant = db.isContinentMap and 2 or 3
|
Nenue@72
|
445 canTargetQuests = SpellCanTargetQuest()
|
Nenue@67
|
446
|
Nenue@40
|
447 for index, pin in pairs(db.QuestsByID) do
|
Nenue@40
|
448 pin.used = nil
|
Nenue@40
|
449 end
|
Nenue@40
|
450
|
Nenue@69
|
451 self:UpdateAnchors()
|
Nenue@72
|
452 if bountiesDirty then
|
Nenue@72
|
453 print(' bounties dirty, pushing that')
|
Nenue@72
|
454 self:UpdateBounties()
|
Nenue@72
|
455 end
|
Nenue@72
|
456
|
Nick@60
|
457
|
Nenue@69
|
458 -- calculate quests shown
|
Nenue@65
|
459 numShown = 0
|
Nenue@65
|
460 numLoaded = 0
|
Nick@60
|
461 for questID, pin in pairs(db.QuestsByID) do
|
Nick@60
|
462 local oV = pin:IsShown()
|
Nick@60
|
463 if pin.used then
|
Nick@60
|
464 pin.throttle = 1
|
Nick@60
|
465 if oV == false then
|
Nenue@67
|
466 rprint('|cFF00FF00cleanup +|r', questID, pin.title)
|
Nick@60
|
467 end
|
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
|
Nick@60
|
474 else
|
Nick@60
|
475 if oV == true then
|
Nenue@67
|
476 rprint('|cFFFF4400 -|r', questID, pin.title)
|
Nick@60
|
477 end
|
Nenue@69
|
478 pin.hideReason = "Not used in map area " .. (db.currentMapID)
|
Nick@62
|
479 pin:HideFrames()
|
Nick@60
|
480 end
|
Nick@60
|
481 end
|
Nick@60
|
482
|
Nenue@71
|
483
|
Nenue@71
|
484
|
Nenue@73
|
485 print(' ', numShown, 'shown,', numLoaded, 'with data')
|
Nenue@65
|
486 if numShown > numLoaded then
|
Nenue@65
|
487 self.Status:Show()
|
Nenue@65
|
488 end
|
Nenue@65
|
489
|
Nenue@65
|
490
|
Nenue@73
|
491 layoutDirty = nil
|
Nenue@40
|
492 self.isStale = nil
|
Nenue@54
|
493 self.sizesDirty = nil
|
Nenue@66
|
494 self.isZoomDirty = nil
|
Nenue@40
|
495 end
|
Nenue@40
|
496
|
Nenue@73
|
497 local refreshReason
|
Nenue@69
|
498 function Module:RefreshIfChanged()
|
Nenue@69
|
499 local scaleCheck = WorldMapDetailFrame:GetScale()
|
Nenue@73
|
500 refreshReason = nil
|
Nenue@69
|
501 if scaleCheck ~= currentScale then
|
Nenue@73
|
502 refreshReason = 'map scale updated'
|
Nenue@72
|
503 self:Refresh('WORLD_MAP_SCALE_CHANGED')
|
Nenue@69
|
504 currentScale = scaleCheck
|
Nenue@72
|
505 elseif self.isStale or layoutDirty then
|
Nenue@73
|
506 refreshReason = 'layout is marked dirty'
|
Nenue@73
|
507 end
|
Nenue@73
|
508 if not refreshReason then
|
Nenue@73
|
509 return
|
Nenue@73
|
510 end
|
Nenue@73
|
511
|
Nenue@73
|
512
|
Nenue@73
|
513 if self:IsVisible() then
|
Nenue@73
|
514 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
|
Nenue@74
|
515 self:Refresh('WORLDMAP_QUEUED')
|
Nenue@73
|
516 else
|
Nenue@73
|
517 rprint('|cFF00FFFFRefreshIfChanged()|r flagging for later refresh', refreshReason)
|
Nenue@73
|
518 self.isStale = true
|
Nenue@69
|
519 end
|
Nenue@69
|
520 end
|
Nenue@69
|
521
|
Nenue@40
|
522 -- update visibility states of all pins
|
Nenue@57
|
523 function Module:MarkAllPins(pins)
|
Nenue@57
|
524 print(' |cFFFFFF00'..self:GetName()..':MarkAllPins()|r', pins)
|
Nenue@40
|
525 pins = pins or db.QuestsByID
|
Nenue@40
|
526 for questID, pin in pairs(pins) do
|
Nenue@40
|
527 pin.isStale = true
|
Nenue@40
|
528 rprint('|cFF00FF00filter', pin.questID, pin.filtered, 'used:', pin.used)
|
Nenue@40
|
529 end
|
Nenue@40
|
530 end
|
Nenue@40
|
531
|
Nenue@45
|
532 function Module:UpdateQuestButton(info, mapID)
|
Nenue@40
|
533 local questID, x, y = info.questId, info.x, info.y
|
Nenue@40
|
534 local pin = self:AcquirePin(info)
|
Nenue@40
|
535 if not pin then
|
Nenue@34
|
536 return
|
Nenue@34
|
537 end
|
Nenue@34
|
538
|
Nenue@74
|
539
|
Nenue@74
|
540 local doUpdate = pin:GetCriteriaState() or pin.isStale
|
Nenue@67
|
541 --print(' |- ', pin.questID, pin.title)
|
Nenue@57
|
542 rprint('|cFF00FF00update|r', pin.questID, pin.title)
|
Nenue@74
|
543
|
Nenue@74
|
544 print(doUpdate)
|
Nenue@74
|
545
|
Nenue@40
|
546 if x and y then
|
Nenue@66
|
547 local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
|
Nenue@49
|
548 pin:SetFrameLevel(PinBaseIndex+pin:GetID())
|
Nenue@57
|
549 pin.owningFrame = WorldMapFrame
|
Nenue@66
|
550 pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor)
|
Nenue@74
|
551 doUpdate = true
|
Nenue@54
|
552 --tinsert(self.UsedPositions, pin)
|
Nenue@40
|
553 end
|
Nenue@66
|
554
|
Nenue@74
|
555 if doUpdate then
|
Nenue@74
|
556 print(' changed', pin.title, pin.isCriteria, pin.isBounty, pin.scaleFactor)
|
Nenue@72
|
557 if pin:IsVisible() then
|
Nenue@72
|
558 --numUpdated = numUpdated + 1
|
Nenue@74
|
559 pin:Refresh('WORLDMAP_REFRESH')
|
Nenue@72
|
560 else
|
Nenue@72
|
561 --numHidden = numHidden + 1
|
Nenue@72
|
562 pin.isStale = true
|
Nenue@72
|
563 end
|
Nenue@72
|
564 end
|
Nenue@72
|
565
|
Nenue@40
|
566 if mapID then
|
Nenue@40
|
567 if not db.QuestsByZone[mapID] then
|
Nenue@40
|
568 db.QuestsByZone[mapID] = {}
|
Nenue@40
|
569 end
|
Nenue@40
|
570 db.QuestsByZone[mapID][questID] = pin
|
Nenue@33
|
571 end
|
Nenue@33
|
572 end
|
Nenue@33
|
573
|
Nenue@69
|
574 -- Updates quest markers in taskInfo while associating them with the given map
|
Nenue@69
|
575 function Module:UpdateQuestsForMap(taskInfo, mapID)
|
Nenue@49
|
576 rprint('Map', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID))
|
Nenue@40
|
577 for index, info in pairs(taskInfo) do
|
Nenue@40
|
578 self:UpdateQuestButton(info, mapID)
|
Nenue@40
|
579 end
|
Nenue@40
|
580 end
|
Nenue@33
|
581
|
Nenue@69
|
582 -- Used to refresh the visible quest markers
|
Nick@60
|
583 function Module:UpdateAnchors ()
|
Nenue@40
|
584 wipe(self.UsedPositions)
|
Nick@60
|
585 print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()')
|
Nenue@74
|
586 local hostWidth, hostHeight = WorldMapPOIFrame:GetSize()
|
Nenue@74
|
587
|
Nenue@74
|
588 if (hostWidth ~= self.hostWidth) or (hostHeight ~= self.hostHeight) then
|
Nenue@74
|
589 self.hostWidth, self.hostHeight = hostWidth, hostHeight
|
Nenue@74
|
590 layoutDirty = true
|
Nenue@74
|
591 end
|
Nenue@74
|
592
|
Nenue@67
|
593
|
Nenue@67
|
594 rprint('|cFF00FF00'..self:GetName()..':UpdateAnchors()')
|
Nenue@33
|
595 local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo()
|
Nenue@33
|
596 if isMicroDungeon then
|
Nenue@33
|
597 return
|
Nenue@33
|
598 end
|
Nenue@69
|
599
|
Nenue@65
|
600 isDataLoaded = true
|
Nenue@67
|
601 local taskInfo = TQ_GetQuestsForPlayerByMapID(db.currentMapID)
|
Nenue@40
|
602 if taskInfo then
|
Nenue@69
|
603 self:UpdateQuestsForMap(taskInfo, db.currentMapID)
|
Nenue@33
|
604 end
|
Nenue@67
|
605 local numZones = MC_GetNumZones(db.currentMapID)
|
Nenue@33
|
606 if numZones then
|
Nenue@33
|
607 for i = 1, numZones do
|
Nenue@67
|
608 local mapAreaID = MC_GetZoneInfo(db.currentMapID, i)
|
Nenue@67
|
609 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, db.currentMapID)
|
Nenue@40
|
610 if taskInfo then
|
Nenue@69
|
611 self:UpdateQuestsForMap(taskInfo, mapAreaID)
|
Nenue@40
|
612 end
|
Nenue@33
|
613 end
|
Nenue@33
|
614 end
|
Nenue@33
|
615 end
|
Nenue@33
|
616
|
Nenue@67
|
617 function ToggleButton:OnShow()
|
Nenue@67
|
618 self:SetChecked(db.Config.EnablePins and true or false)
|
Nenue@67
|
619 end
|
Nenue@67
|
620 function ToggleButton:OnClick()
|
Nenue@67
|
621 print(self:GetChecked())
|
Nenue@67
|
622 db.Config.EnablePins = self:GetChecked()
|
Nenue@67
|
623 _G.WorldPlan:OnConfigUpdate()
|
Nenue@67
|
624 end |