comparison WorldQuests.lua @ 45:db570c6a0ffb v1.0-rc12

- Fixed filter buttons losing their anchor after FlightMap interactions - Fixed flickering tooltips - Fixed a source of hangs while opening the world map, particularly in non-Broken-Isle continents. - Workaround for World Map Action Button: Temporarily activate blizzard POI buttons while a quest-targeting spell is on the cursor.
author Nenue
date Mon, 26 Dec 2016 10:20:52 -0500
parents 77c2ffb5c7f5
children 733785e306a3
comparison
equal deleted inserted replaced
44:59e9d66195dd 45:db570c6a0ffb
1 -- WorldPlan 1 -- WorldPlan
2 -- WorldQuests.lua 2 -- WorldQuests.lua
3 -- Created: 11/2/2016 3:40 PM 3 -- Created: 11/2/2016 3:40 PM
4 -- %file-revision% 4 -- %file-revision%
5 local _, db = ... 5 local _, db = ...
6 local WorldQuests = WorldPlanQuestsMixin 6 local Module = WorldPlanQuestsMixin
7 7
8 local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo 8 local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo
9 local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented 9 local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented
10 local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID 10 local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID
11 local GetMapInfo = GetMapInfo 11 local GetMapInfo = GetMapInfo
12 local print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end 12 local print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end
13 local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or function() end 13 local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or function() end
14 local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end 14 local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end
15 local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end 15 local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end
16 local mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or function() end 16 local mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or function() end
17 17 local pairs = pairs
18 18
19 local PinBaseIndex = 1200 19 local PinBaseIndex = 1200
20 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 20 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
21 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah", 21 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah",
22 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', } 22 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', }
28 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS 28 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS
29 29
30 30
31 local numPins = 0 31 local numPins = 0
32 local NumPinFrames = 1 32 local NumPinFrames = 1
33 WorldQuests.TasksByID = {} 33 Module.TasksByID = {}
34 34
35 --%debug% 35 --%debug%
36 local SetTimedCallbackForAllPins = function(seconds, callback) 36 local SetTimedCallbackForAllPins = function(seconds, callback)
37 C_Timer.After(seconds, function() 37 C_Timer.After(seconds, function()
38 for id, pin in pairs(WorldPlanQuests.QuestsByID) do 38 for id, pin in pairs(WorldPlanQuests.QuestsByID) do
39 callback(pin) 39 callback(pin)
40 end 40 end
41 end) 41 end)
42 end 42 end
43 43
44 function WorldQuests:OnUpdate(sinceLast) 44 function Module:OnUpdate(sinceLast)
45 if self.filtersDirty or self.isStale then 45 if self.filtersDirty or self.isStale then
46 self:Refresh() 46 self:Refresh()
47 end 47 end
48 end 48 end
49 49
50 function WorldQuests:Setup() 50 function Module:Setup()
51 print('|cFFFF4400'..self:GetName()..':Setup()') 51 print('|cFFFF4400'..self:GetName()..':Setup()')
52 52
53 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do 53 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
54 db.QuestsByZone[mapID] = {} 54 db.QuestsByZone[mapID] = {}
55 end 55 end
56 56
57 57 hooksecurefunc("ClickWorldMapActionButton", function () self:OnClickWorldMapActionButton() end)
58 -- refresh positions any time blizzard does so (i.e. mousewheel zoom) 58 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function () self:Refresh() end)
59 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() 59 hooksecurefunc("WorldMap_UpdateQuestBonusObjectives", function () self:OnUpdateQuestBonusObjectives() end)
60 print('|cFFFF4400WorldMapScrollFrame_ReanchorQuestPOIs') 60 end
61 self:Refresh(true) 61
62 end) 62 local InternalHideButton = function(button, index)
63 63 button:Hide()
64 64 if button.questID and db.QuestsByID[button.questID] then
65 -- hide the original world quest POIs 65 if db.QuestsByID[button.questID].used and not db.QuestsByID[button.questID].filtered then
66 66 db.QuestsByID[button.questID]:SetShown(true)
67 hooksecurefunc("WorldMap_UpdateQuestBonusObjectives", function() 67 end
68 print('|cFFFF4400WorldMap_UpdateQuestBonusObjectives') 68 end
69 for i = 1, NUM_WORLDMAP_TASK_POIS do 69 end
70 local button = _G['WorldMapFrameTaskPOI'..i] 70 local InternalShowButton = function(button, index)
71 if button and button.worldQuest then 71 button:Show()
72 button:Hide() 72 if button.questID and db.QuestsByID[button.questID] then
73 end 73 db.QuestsByID[button.questID]:SetShown(false)
74 end 74 end
75 end) 75 end
76 end 76
77 function Module:OnUpdateQuestBonusObjectives()
78 print('|cFFFF4400WorldMap_UpdateQuestBonusObjectives')
79 local func = SpellCanTargetQuest() and InternalShowButton or InternalHideButton
80 print(SpellCanTargetQuest())
81 for i = 1, NUM_WORLDMAP_TASK_POIS do
82 local button = _G['WorldMapFrameTaskPOI'..i]
83 if button and button.worldQuest then
84 func(button, i)
85 end
86 end
87 end
88
89 function Module:OnClickWorldMapActionButton()
90 self.IsTargeting = SpellCanTargetQuest()
91 self:OnUpdateQuestBonusObjectives()
92 end
93
77 local defaults = {} 94 local defaults = {}
78 local REWARD_UNKNOWN = 768 95 local REWARD_UNKNOWN = 768
79 function WorldQuests:OnLoad() 96 function Module:OnLoad()
80 print('|cFFFF4400'..self:GetName()..':OnLoad()') 97 print('|cFFFF4400'..self:GetName()..':OnLoad()')
81 98
82 self:SetParent(WorldMapFrame) 99 self:SetParent(WorldMapFrame)
83 WorldPlan:AddHandler(self, defaults) 100 WorldPlan:AddHandler(self, defaults)
84 101
100 117
101 WorldMapPOIFrame = _G.WorldMapPOIFrame 118 WorldMapPOIFrame = _G.WorldMapPOIFrame
102 119
103 end 120 end
104 121
105 function WorldQuests:OnMapInfo() 122 function Module:OnMapInfo()
106 if self:IsVisible() then 123 if self:IsVisible() then
107 self:Refresh() 124 self:Refresh()
108 else 125 else
109 self.isStale = true 126 self.isStale = true
110 end 127 end
111 end 128 end
112 129
113 function WorldQuests:OnEvent (event, ...) 130 function Module:OnEvent (event, ...)
114 131
115 print('|cFFFFFF00'..self:GetName()..':OnEvent() '..event..'|r', GetTime(), ...) 132 print('|cFFFFFF00'..self:GetName()..':OnEvent() '..event..'|r', GetTime(), ...)
116 if event == 'QUEST_LOG_UPDATE' then 133 if event == 'QUEST_LOG_UPDATE' then
117 local questID, added = ... 134 local questID, added = ...
118 if questID and added then 135 if questID and added then
135 end 152 end
136 end 153 end
137 154
138 local totalPins = 0 155 local totalPins = 0
139 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation 156 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
140 function WorldQuests:AcquirePin (info) 157 function Module:AcquirePin (info)
141 local questID = info.questId 158 local questID = info.questId
142 if not questID then 159 if not questID then
143 return nil 160 return nil
144 end 161 end
145 162
192 C_TaskQuest.RequestPreloadRewardData(info.questId) 209 C_TaskQuest.RequestPreloadRewardData(info.questId)
193 return pin 210 return pin
194 end 211 end
195 212
196 -- remove from index and add it to the recycling heap 213 -- remove from index and add it to the recycling heap
197 function WorldQuests:ReleasePin (pin) 214 function Module:ReleasePin (pin)
198 215
199 local id = pin.questID 216 local id = pin.questID
200 if id then 217 if id then
201 db.QuestsByID[id] = nil 218 db.QuestsByID[id] = nil
202 219
211 tinsert(db.FreePins, pin) 228 tinsert(db.FreePins, pin)
212 229
213 print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title) 230 print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title)
214 end 231 end
215 232
216 function WorldQuests:GetBonusObjectives() 233 function Module:GetBonusObjectives()
217 234
218 235
219 local tasksTable = GetTasksTable() 236 local tasksTable = GetTasksTable()
220 if tasksTable ~= nil then 237 if tasksTable ~= nil then
221 print('|cFF00FF88'..self:GetName()..':BonusObjectives()|r ') 238 print('|cFF00FF88'..self:GetName()..':BonusObjectives()|r ')
258 275
259 276
260 277
261 278
262 -- use tooltip object to extract item details 279 -- use tooltip object to extract item details
263 function WorldQuests:GetRewardHeader(questID) 280 function Module:GetRewardHeader(questID)
264 local name, icon, quantity, quality, _, itemID = GetQuestLogRewardInfo(1, questID) 281 local name, icon, quantity, quality, _, itemID = GetQuestLogRewardInfo(1, questID)
265 local scanner = _G.WorldPlanTooltip 282 local scanner = _G.WorldPlanTooltip
266 local print = qprint 283 local print = qprint
267 if not itemID then 284 if not itemID then
268 return 285 return
317 end 334 end
318 335
319 local GetCurrentMapAreaID, GetMapNameByID= GetCurrentMapAreaID, GetMapNameByID 336 local GetCurrentMapAreaID, GetMapNameByID= GetCurrentMapAreaID, GetMapNameByID
320 local wipe, pairs = wipe, pairs 337 local wipe, pairs = wipe, pairs
321 -- create of update quest pins for a map and its underlying zones 338 -- create of update quest pins for a map and its underlying zones
322 function WorldQuests:UpdateWorldQuests (mapID) 339 function Module:UpdateWorldQuests (mapID)
323 340
324 mapID = mapID or db.currentMapID 341 mapID = mapID or db.currentMapID
325 if not mapID then 342 if not mapID then
326 -- info not available yet 343 -- info not available yet
327 return 344 return
367 if self.isStale and self:IsVisible() then 384 if self.isStale and self:IsVisible() then
368 self:Refresh() 385 self:Refresh()
369 end 386 end
370 end 387 end
371 388
372 function WorldQuests:Report() 389 function Module:Report()
373 for i, pin in ipairs(db.UsedPins) do 390 for i, pin in ipairs(db.UsedPins) do
374 db:print(i, pin.questID, pin.title) 391 db:print(i, pin.questID, pin.title)
375 end 392 end
376 393
377 for id, pin in pairs(db.QuestsByID) do 394 for id, pin in pairs(db.QuestsByID) do
378 db:print(id, pin.worldQuestType, pin.rewardType, pin.title) 395 db:print(id, pin.worldQuestType, pin.rewardType, pin.title)
379 end 396 end
380 end 397 end
381 398
382 function WorldQuests:Refresh(fromUser) 399 function Module:Refresh(fromUser)
383 self.currentMapID = GetCurrentMapAreaID() 400 self.currentMapID = GetCurrentMapAreaID()
384 print('|cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal') 401 print('|cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal')
385 if not self:IsVisible() then 402 if not self:IsVisible() then
386 print(' not visible, flag for later') 403 print(' not visible, flag for later')
387 self.isStale = true 404 self.isStale = true
389 end 406 end
390 wprint(' |cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal') 407 wprint(' |cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal')
391 408
392 for index, pin in pairs(db.QuestsByID) do 409 for index, pin in pairs(db.QuestsByID) do
393 pin.used = nil 410 pin.used = nil
394 pin:SetShown(false)
395 end 411 end
396 412
397 self:SetFilteredPins(db.QuestsByID) 413 self:SetFilteredPins(db.QuestsByID)
398 self:UpdateAnchors(nil, fromUser) 414 self:UpdateAnchors(nil, fromUser)
399 self:Cleanup (fromUser) 415 self:Cleanup (fromUser)
400 self.isStale = nil 416 self.isStale = nil
401 end 417 end
402 418
403 -- update visibility states of all pins 419 -- update visibility states of all pins
404 function WorldQuests:SetFilteredPins(pins) 420 function Module:SetFilteredPins(pins)
405 print(' |cFFFFFF00'..self:GetName()..':SetFilteredPins()|r', pins) 421 print(' |cFFFFFF00'..self:GetName()..':SetFilteredPins()|r', pins)
406 pins = pins or db.QuestsByID 422 pins = pins or db.QuestsByID
407 for questID, pin in pairs(pins) do 423 for questID, pin in pairs(pins) do
408 pin.filtered = pin:IsFiltered() 424 pin.filtered = pin:IsFiltered()
409 pin.isStale = true 425 pin.isStale = true
410 rprint('|cFF00FF00filter', pin.questID, pin.filtered, 'used:', pin.used) 426 rprint('|cFF00FF00filter', pin.questID, pin.filtered, 'used:', pin.used)
411 end 427 end
412 end 428 end
413 429
414 local abs = math.abs 430 local abs = math.abs
415 function WorldQuests:UpdateQuestButton(info, mapID) 431 function Module:UpdateQuestButton(info, mapID)
416 local questID, x, y = info.questId, info.x, info.y 432 local questID, x, y = info.questId, info.x, info.y
417 local pin = self:AcquirePin(info) 433 local pin = self:AcquirePin(info)
418 if not pin then 434 if not pin then
419 return 435 return
420 end 436 end
443 end 459 end
444 db.QuestsByZone[mapID][questID] = pin 460 db.QuestsByZone[mapID][questID] = pin
445 end 461 end
446 end 462 end
447 463
448 function WorldQuests:UpdateMap(taskInfo, mapID) 464 function Module:UpdateMap(taskInfo, mapID)
449 print('Map', GetMapNameByID(mapID), GetMapNameByID(self.currentMapID)) 465 print('Map', GetMapNameByID(mapID), GetMapNameByID(self.currentMapID))
450 for index, info in pairs(taskInfo) do 466 for index, info in pairs(taskInfo) do
451 self:UpdateQuestButton(info, mapID) 467 self:UpdateQuestButton(info, mapID)
452 end 468 end
453 end 469 end
454 470
455 function WorldQuests:UpdateAnchors (fromUser) 471 function Module:UpdateAnchors (fromUser)
456 472
457 473
458 wipe(self.UsedPositions) 474 wipe(self.UsedPositions)
459 print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()', fromUser) 475 print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()', fromUser)
460 self.hostFrame = WorldMapPOIFrame 476 self.hostFrame = WorldMapPOIFrame
487 self:SetFilteredPins(db.QuestsByID) 503 self:SetFilteredPins(db.QuestsByID)
488 end 504 end
489 end 505 end
490 506
491 -- shows, animates, or hides pins based on their current visibility flags 507 -- shows, animates, or hides pins based on their current visibility flags
492 function WorldQuests:Cleanup (fromUser) 508 function Module:Cleanup (fromUser)
493 509
494 print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') 510 print('|cFFFFFF00'..self:GetName()..':Cleanup()|r')
495 local print = rprint 511 local print = rprint
496 print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') 512 print('|cFFFFFF00'..self:GetName()..':Cleanup()|r')
497 --local showQuestPOI = db.Config.EnablePins 513 --local showQuestPOI = db.Config.EnablePins
498 for questID, pin in pairs(db.QuestsByID) do 514 for questID, pin in pairs(db.QuestsByID) do
499 local oV = pin:IsShown() 515 local oV = pin:IsShown()
500 if pin.used then 516 if pin.used then
501 pin:SetShown(true) 517
502 pin.throttle = 1 518 pin.throttle = 1
503 if oV == false then 519 if oV == false then
504 print('|cFF00FF00cleanup +|r', questID, pin.title) 520 print('|cFF00FF00cleanup +|r', questID, pin.title)
505 end 521 end
506 else 522 else
507 if oV == true then 523 if oV == true then
508 print('|cFFFF4400 -|r', questID, pin.title) 524 print('|cFFFF4400 -|r', questID, pin.title)
509 end 525 end
510 end 526 end
527 pin:SetShown(pin.used or false)
511 528
512 if pin.worldQuest and (not C_TaskQuest.IsActive(pin.questID)) then 529 if pin.worldQuest and (not C_TaskQuest.IsActive(pin.questID)) then
513 self:ReleasePin(pin) 530 self:ReleasePin(pin)
514 end 531 end
515 pin.isStale = true 532 pin.isStale = true