comparison WorldPlan.lua @ 30:8cb750e79952

WorldPlan: - Reworking filters to utilize newly added CVars
author Nenue
date Fri, 28 Oct 2016 14:06:07 -0400
parents c1612c2c1840
children d0114b51cdea
comparison
equal deleted inserted replaced
29:c1612c2c1840 30:8cb750e79952
1 -- Veneer
2 -- WorldPlan.lua 1 -- WorldPlan.lua
3 -- Created: 8/16/2016 8:19 AM 2 -- Created: 8/16/2016 8:19 AM
4 -- %file-revision% 3 -- %file-revision%
5 --[[ 4
6 Summary: 5 local addonName, db = ...
7 Adds reward icons to the world quest POI markers, and adds said markers to the continent map.
8
9 Issues:
10 Dalaran quests aren't visible until that map has been specifically viewed by the player.
11 --]]
12 6
13 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" 7 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark"
14 local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" 8 local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up"
15 9
16 local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background" 10 local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background"
20 local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64" 14 local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64"
21 local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64" 15 local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64"
22 16
23 WorldPlanCore = { 17 WorldPlanCore = {
24 defaults = {}, 18 defaults = {},
25 19 modules = {},
20 }
21 WorldPlanQuestsMixin = {
22 QuestsByZone = {},
23 QuestsByID = {},
24 freePins = {},
26 } 25 }
27 WorldPlanPOIMixin = {} 26 WorldPlanPOIMixin = {}
28 WorldPlanFilterPinMixin = {} 27 WorldPlanFilterPinMixin = setmetatable({ QuestsByID = {}, freePins = {} }, {__tostring = function() return 'QuestHandler' end})
29 local WorldPlanFlightMapMixin = setmetatable({}, {__tostring = function() return 'FlightMapHandler' end}) 28 local WorldPlanFlightMapMixin = setmetatable({}, {__tostring = function() return 'FlightMapHandler' end})
30 local WorldQuests = setmetatable({ QuestsByID = {}, freePins = {} }, {__tostring = function() return 'QuestHandler' end}) 29 local WorldQuests = WorldPlanQuestsMixin
31 local FilterBar = setmetatable({ SummaryHeaders = {} }, {__tostring = function() return 'FilterBar' end}) 30
32 31
33 local WorldPlan = WorldPlanCore 32 local WorldPlan = WorldPlanCore
34 local QuestPOI = WorldPlanPOIMixin 33 local QuestPOI = WorldPlanPOIMixin
35 local FilterPin = WorldPlanFilterPinMixin 34 local FilterPin = WorldPlanFilterPinMixin
36 local WP_VERSION = "1.0" 35 local WP_VERSION = "1.0"
60 59
61 local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID 60 local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID
62 local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo 61 local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo
63 62
64 63
65 local PinBaseIndex = 1600
66 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
67
68 -- maps where we do our own anchors
69 local CONTINENT_MAPS = { [BROKEN_ISLES_ID] = BROKEN_ISLES_ID, }
70 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah",
71 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', }
72 -- default color templates 64 -- default color templates
73 local ARTIFACT_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT] 65 local ARTIFACT_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT]
74 local MONEY_COLOR = {hex ='|cFFFFFF00', r=1, g=1, b=0} 66 local MONEY_COLOR = {hex ='|cFFFFFF00', r=1, g=1, b=0}
75 local COMMON_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON] 67 local COMMON_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON]
76 local DEFAULT_TYPE = { 68 local DEFAULT_TYPE = {
80 desaturated = true, 72 desaturated = true,
81 pinMask = POI_BORDER_MASK, 73 pinMask = POI_BORDER_MASK,
82 rewardMask = POI_BORDER_MASK, 74 rewardMask = POI_BORDER_MASK,
83 texture = POI_BORDER_FILL, 75 texture = POI_BORDER_FILL,
84 continent = { 76 continent = {
85 PinSize = 18, 77 PinSize = 14,
86 Border = 3, 78 Border = 2,
87 TrackingBorder = 2, 79 TrackingBorder = 1,
88 TagSize = 6, 80 TagSize = 6,
89 TimeleftStage = 3, 81 TimeleftStage = 0,
90 showNumber = true, 82 showNumber = true,
83 numberFontObject = 'WorldPlanFont'
91 }, 84 },
92 zone = { 85 zone = {
93 PinSize = 22, 86 PinSize = 22,
94 Border = 3, 87 Border = 3,
95 TrackingBorder = 2, 88 TrackingBorder = 2,
96 TagSize = 12, 89 TagSize = 12,
97 TimeleftStage = 3, 90 TimeleftStage = 3,
98 showNumber = true, 91 showNumber = true,
92 numberFontObject = 'WorldPlanNumberFontThin'
99 }, 93 },
100 minimized = { 94 minimized = {
101 PinSize = 4, 95 PinSize = 4,
102 Border = 1, 96 Border = 0,
103 TrackingBorder = 2, 97 TrackingBorder = 1,
104 NoIcon = true, 98 NoIcon = true,
105 TimeleftStage = 1, 99 TimeleftStage = 1,
106 showNumber = false, 100 showNumber = false,
107 } 101 }
108 } 102 }
163 local superTrackedID 157 local superTrackedID
164 local currentMapName 158 local currentMapName
165 local hasNewQuestPins 159 local hasNewQuestPins
166 local isContinentMap 160 local isContinentMap
167 local numPins = 0 161 local numPins = 0
168 local QuestsByZone = {}
169 local QuestsByFaction = {}
170 local QuestsByReward = {}
171 local QuestsByTag = {}
172 local QuestsByID = {}
173 local QuestPositions = {}
174 local FilterInclusions = {rewardType = {}, worldQuestType = {}, factionID = {}} 162 local FilterInclusions = {rewardType = {}, worldQuestType = {}, factionID = {}}
175 local NotificationTypes = {} 163 local NotificationTypes = {}
176 local ZoneInfo = {} 164 local ZoneInfo = {}
177 local SummaryHeaders = {} 165 local SummaryHeaders = {}
178 166
181 169
182 local hasPendingQuestData 170 local hasPendingQuestData
183 local notifyPlayed 171 local notifyPlayed
184 local scanner, wmtt, WorldMapPOIFrame 172 local scanner, wmtt, WorldMapPOIFrame
185 173
186 WorldPlanCore.QuestsByID = QuestsByID
187 WorldPlanCore.QuestsByZone = QuestsByZone
188 174
189 local tasksQueue = {} 175 local tasksQueue = {}
190 local function OnNext (func) 176 local function OnNext (func)
191 if #tasksQueue == 0 then 177 if #tasksQueue == 0 then
192 _G.WorldPlan:SetScript('OnUpdate', function() 178 _G.WorldPlan:SetScript('OnUpdate', function()
200 end) 186 end)
201 end 187 end
202 print('inserting task #', #tasksQueue+1, func) 188 print('inserting task #', #tasksQueue+1, func)
203 tinsert(tasksQueue, func) 189 tinsert(tasksQueue, func)
204 end 190 end
205
206 -- combines templates
207 local function DoMixins(frame,...)
208 for i = 1, select('#', ...) do
209 for k,v in pairs(select(i,...)) do
210 frame[k] = v
211 end
212 end
213 return frame
214 end
215
216 191
217 -- update a masked texture without messing up its blending mask 192 -- update a masked texture without messing up its blending mask
218 local SetMaskedTexture = function(region, file, mask) 193 local SetMaskedTexture = function(region, file, mask)
219 mask = mask or POI_BORDER_MASK 194 mask = mask or POI_BORDER_MASK
220 region:SetMask(nil) 195 region:SetMask(nil)
241 msg = (msg and (msg .. ' ') or '') .. tostring(select(i, ...)) 216 msg = (msg and (msg .. ' ') or '') .. tostring(select(i, ...))
242 end 217 end
243 DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FFWorldPlan|r: " .. msg) 218 DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FFWorldPlan|r: " .. msg)
244 end 219 end
245 220
221 local current_type_owner
222 function WorldPlan:AddHandler (frame, defaults)
223 print('|cFFFFFF00'..self:GetName()..':AddHandler()', frame:GetName())
224 tinsert(self.modules, frame)
225 self.defaults[frame] = defaults
226 frame.GetTypeInfo = function(frame, typeID)
227 return self:GetTypeInfo(frame, typeID)
228 end
229 end
230
246 function WorldPlan:OnLoad () 231 function WorldPlan:OnLoad ()
247 232
248 self.Types = setmetatable({}, { 233 self.Types = setmetatable({}, {
249 __newindex = function(t, k, v) 234 __newindex = function(t, k, v)
250 print('adding type', k)
251 if type(v) == 'table' then 235 if type(v) == 'table' then
252 v = setmetatable(v, {__index = function(t,k) 236 print('adding owner', k)
253 print('##deferring to default key', k) 237 v = setmetatable(v, {
254 return DEFAULT_TYPE[k] 238 __newindex = function(t2,k2,v2)
239 if type(v2) == 'table' then
240 print('adding type', k2)
241 v2 = setmetatable(v2, {__index = function(t3,k3)
242 --print('##deferring to default key', k3)
243 return DEFAULT_TYPE[k3]
244 end})
245 end
246 rawset(t2,k2,v2)
255 end}) 247 end})
256 end 248 end
257 rawset(t,k,v) 249 rawset(t,k,v)
258 end 250 end
259 }) 251 })
260 252
261 local rgbWhite = {1, 1, 1} 253 self.Types[self] = {}
262 self.Types[REWARD_REAGENT] = { r = 0, g = 1, b = 1 }
263 self.Types[REWARD_ARTIFACT_POWER] = { r = 1, g = .25, b = .5, hasNumeric = true, numberRGB = rgbWhite }
264 self.Types[REWARD_GEAR] = { r = .1, g = .2, b = 1 }
265 self.Types[REWARD_CURRENCY] = { r = 1, g = 1, b = 0, hasNumeric = true, numberRGB = rgbWhite, }
266 self.Types[REWARD_CASH] = { r = 0, g = 0, b = 0, }
267 254
268 for index, color in pairs(ITEM_QUALITY_COLORS) do 255 for index, color in pairs(ITEM_QUALITY_COLORS) do
269 self.Types[(index+127)] = { r = color.r, g = color.g, b = color.b, hex = color.hex, } 256 self:AddTypeInfo(self, index, { r = color.r, g = color.g, b = color.b, hex = color.hex, })
270 end 257 end
271 258
272 WorldPlan = self 259 WorldPlan = self
273 scanner = _G.WorldPlanTooltip 260 scanner = _G.WorldPlanTooltip
274 wmtt = _G.WorldMapTooltip 261 wmtt = _G.WorldMapTooltip
283 self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED") 270 self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED")
284 self:RegisterEvent("SKILL_LINES_CHANGED") 271 self:RegisterEvent("SKILL_LINES_CHANGED")
285 self:RegisterEvent("ARTIFACT_XP_UPDATE") 272 self:RegisterEvent("ARTIFACT_XP_UPDATE")
286 self:RegisterEvent("ADDON_LOADED") 273 self:RegisterEvent("ADDON_LOADED")
287 self:SetParent(WorldMapFrame) 274 self:SetParent(WorldMapFrame)
288
289 WorldPlan.modules = {
290 WorldQuests, FilterBar, WorldPlanFlightMapMixin,
291 }
292 end 275 end
293 276
294 function WorldPlan:OnShow() 277 function WorldPlan:OnShow()
295 print(self:GetName()..':OnShow()') 278 print(self:GetName()..':OnShow()')
296 if self.isStale then 279 if self.isStale then
297 self:RefreshAll() 280 self:Refresh()
298 end 281 end
299 282
300 end 283 end
301 284
302 function WorldPlan:OnEvent (event, ...) 285 function WorldPlan:OnEvent (event, ...)
312 if IsLoggedIn() and not self.initialized then 295 if IsLoggedIn() and not self.initialized then
313 self:Setup() 296 self:Setup()
314 end 297 end
315 elseif event == 'WORLD_MAP_UPDATE' then 298 elseif event == 'WORLD_MAP_UPDATE' then
316 self.currentMapID = GetCurrentMapAreaID() 299 self.currentMapID = GetCurrentMapAreaID()
317 self:RefreshAll() 300 print('|cFFFF4400currentMapID =', self.currentMapID)
301 self:Refresh()
318 else 302 else
319 for i, module in ipairs(self.modules) do 303 for i, module in ipairs(self.modules) do
320 if module.OnEvent then 304 if module.OnEvent then
321 print('forwarding to', tostring(module)) 305 print('forwarding to', tostring(module))
322 module:OnEvent(event, ...) 306 module:OnEvent(event, ...)
358 self.initialized = true 342 self.initialized = true
359 343
360 hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize) 344 hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize)
361 end 345 end
362 346
363 function WorldPlan:GetTypeInfo(typeID) 347 function WorldPlan:AddTypeInfo(owner, id, info)
348 self.Types[owner] = self.Types[owner] or {}
349 self.Types[owner][id] = info
350 print('Type('..owner:GetName()..')('..id..') = '.. tostring(info))
351 end
352
353 function WorldPlan:GetTypeInfo(owner, typeID)
364 local info, extraInfo 354 local info, extraInfo
365 if (not typeID) or (not self.Types[typeID]) then 355 if not owner then
366 qprint('## sent default type') 356 --print('## deferring to default type list')
357 else
358 --print('## pulling for', owner:GetName(), 'id =', typeID)
359 end
360
361 owner = owner or self
362 if (not typeID) or (not self.Types[owner][typeID]) then
363 --print('## sending list default')
367 info = DEFAULT_TYPE 364 info = DEFAULT_TYPE
368 else 365 else
369 qprint('## sent defined type', typeID) 366 --print('## sent list definition', typeID)
370 info = self.Types[typeID] 367 info = self.Types[owner][typeID]
371 end 368 end
372 369
373 if isContinentMap then 370 if isContinentMap then
374 extraInfo = info.continent 371 extraInfo = info.continent
375 qprint('### continent subtype', extraInfo) 372 --print('### continent subtype', extraInfo)
376 else 373 else
377 extraInfo = info.zone 374 extraInfo = info.zone
378 375
379 qprint('### zone subtype', extraInfo) 376 --print('### zone subtype', extraInfo)
380 end 377 end
381 return info, extraInfo 378 return info, extraInfo
382 end 379 end
383 380
384 do 381 do
411 end 408 end
412 return nil, nil 409 return nil, nil
413 end 410 end
414 end 411 end
415 412
416 function WorldPlan:RefreshAll (forced) 413 function WorldPlan:Refresh (forced)
414 print('|cFFFFFF00'..self:GetName()..':Refresh()|r forced:', forced, 'init:', self.initialized)
417 if not self.initialized then 415 if not self.initialized then
418 return 416 return
419 end 417 end
420 418
421 POI_DEFAULT_TYPE = db.defaultPinStyle 419 POI_DEFAULT_TYPE = db.defaultPinStyle
515 info.checked = db.DisplayContinentSummary 513 info.checked = db.DisplayContinentSummary
516 info.func = DropDown_OnClick 514 info.func = DropDown_OnClick
517 UIDropDownMenu_AddButton(info) 515 UIDropDownMenu_AddButton(info)
518 end 516 end
519 517
518 --------------------------------------------------------------------------------------------------------------------
519 --------------------------------------------------------------------------------------------------------------------
520
521 local PinBaseIndex = 1600
522 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
523
524 -- maps where we do our own anchors
525 local CONTINENT_MAPS = { [BROKEN_ISLES_ID] = BROKEN_ISLES_ID, }
526 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah",
527 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', }
528
520 function WorldQuests:Setup() 529 function WorldQuests:Setup()
521 530
522 531
523 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do 532 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
524 QuestsByZone[mapID] = {} 533 self.QuestsByZone[mapID] = {}
525 end 534 end
526 535
527 536
528 -- refresh positions any time blizzard does so (i.e. mousewheel zoom) 537 -- refresh positions any time blizzard does so (i.e. mousewheel zoom)
529 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() 538 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function()
540 end 549 end
541 end) 550 end)
542 551
543 end 552 end
544 553
554 local defaults = {}
555 function WorldQuests:OnLoad()
556 print('|cFF00FF88'..self:GetName()..':OnLoad')
557
558 WorldPlan:AddHandler(self, defaults)
559
560 local rgbWhite = {1, 1, 1}
561 WorldPlan:AddTypeInfo(self, REWARD_REAGENT, { r = 0, g = 1, b = 1 })
562 WorldPlan:AddTypeInfo(self, REWARD_ARTIFACT_POWER, { r = 1, g = .25, b = .5, hasNumeric = true, numberRGB = rgbWhite })
563 WorldPlan:AddTypeInfo(self, REWARD_GEAR, { r = .1, g = .2, b = 1 })
564 WorldPlan:AddTypeInfo(self, REWARD_CURRENCY, { r = 1, g = 1, b = 0, hasNumeric = true, numberRGB = {1,1,0}, })
565 WorldPlan:AddTypeInfo(self, REWARD_CASH, { r = 0, g = 0, b = 0, })
566
567 for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
568 self.QuestsByZone[areaID] = {}
569 end
570
571 self:RegisterEvent('QUEST_LOG_UPDATE')
572 self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
573 self:RegisterEvent('SKILL_LINES_CHANGED')
574
575
576 end
577
545 function WorldQuests:OnEvent (event, ...) 578 function WorldQuests:OnEvent (event, ...)
546 print('|cFFFFFF00'..tostring(self)..':OnEvent()'..event..'|r', GetTime(), ...) 579 local print = wqprint
580 print('|cFFFFFF00'..self:GetName()..':OnEvent()'..event..'|r', GetTime(), ...)
547 if event == 'QUEST_LOG_UPDATE' then 581 if event == 'QUEST_LOG_UPDATE' then
548 local questID, added = ... 582 local questID, added = ...
549 if questID and added then 583 if questID and added then
550 local questPOI = self:AcquirePin(questID) 584 local questPOI = self:AcquirePin(questID)
551 self.hasUpdate, self.isPending = questPOI:RefreshData() 585 self.hasUpdate, self.isPending = questPOI:RefreshData()
552 else 586 else
553 self:RefreshData() 587 self:RefreshData()
554 end 588 end
555 print('WorldMapFrame', WorldMapFrame:IsVisible(), 'doRefresh:', hasNewQuestPins) 589 print('WorldMapFrame', WorldMapFrame:IsVisible(), 'hasUpdates:', self.hasUpdate)
556 if WorldMapFrame:IsVisible() and hasNewQuestPins then
557 self:Refresh(true)
558 end
559
560 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then 590 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
561 local questID = ... 591 local questID = ...
562 if questID and QuestsByID[questID] then 592 if questID and self.QuestsByID[questID] then
563 self:ReleasePin(QuestsByID[questID]) 593 self:ReleasePin(self.QuestsByID[questID])
564 end 594 end
565 elseif event == 'SKILL_LINES_CHANGED' then 595 elseif event == 'SKILL_LINES_CHANGED' then
596 self.hasUpdate = true
597 end
598 end
599
600 function WorldQuests:OnUpdate()
601 if self.hasUpdate then
602 wqprint('|cFF00FF00pushing update')
566 self:Refresh(true) 603 self:Refresh(true)
567 end 604 end
568 end 605 end
606
569 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation 607 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
570 function WorldQuests:AcquirePin (questID, mapID) 608 function WorldQuests:AcquirePin (questID, mapID)
571 local pin = QuestsByID[questID] 609 local pin = self.QuestsByID[questID]
572 local isNew = false 610 local isNew = false
573 if not pin then 611 if not pin then
574 isNew = true 612 isNew = true
575 local numFree = #self.freePins 613 local numFree = #self.freePins
576 if numFree >= 1 then 614 if numFree >= 1 then
580 local name = 'WorldPlanQuestMarker' .. NumPinFrames 618 local name = 'WorldPlanQuestMarker' .. NumPinFrames
581 --print('|cFF00FF00Creating', name) 619 --print('|cFF00FF00Creating', name)
582 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') 620 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
583 621
584 pin:SetFrameStrata('HIGH') 622 pin:SetFrameStrata('HIGH')
623 pin.GetTypeInfo = function(frame, typeID)
624 return self:GetTypeInfo(typeID)
625 end
585 NumPinFrames = NumPinFrames + 1 626 NumPinFrames = NumPinFrames + 1
586 --pin.iconBorder:SetVertexColor(0,0,0,1) 627 --pin.iconBorder:SetVertexColor(0,0,0,1)
587 end 628 end
588 pin:SetID(questID) 629 pin:SetID(questID)
589 pin.isNew = true 630 pin.isNew = true
591 632
592 -- used by TaskPOI_x scripts 633 -- used by TaskPOI_x scripts
593 pin.questID = questID 634 pin.questID = questID
594 pin.worldQuest = true 635 pin.worldQuest = true
595 636
596 QuestsByID[questID] = pin 637 self.QuestsByID[questID] = pin
597 else 638 else
598 --print('|cFF00FF00Using', pin:GetName()) 639 --print('|cFF00FF00Using', pin:GetName())
599 end 640 end
600 mapID = mapID or TQ_GetQuestZoneID(questID) 641 mapID = mapID or TQ_GetQuestZoneID(questID)
601 QuestsByZone[mapID][questID] = pin 642 self.QuestsByZone[mapID][questID] = pin
602 643
603 return pin, isNew 644 return pin, isNew
604 end 645 end
605 646
606 -- remove from index and add it to the recycling heap 647 -- remove from index and add it to the recycling heap
607 function WorldQuests:ReleasePin (pin) 648 function WorldQuests:ReleasePin (pin)
608 649
609 local id = pin.questId 650 local id = pin.questId
610 if id then 651 if id then
611 QuestsByID[id] = nil 652 self.QuestsByID[id] = nil
612 for i, zone in pairs(QuestsByZone) do 653 for i, zone in pairs(self.QuestsByZone) do
613 print('-', i, zone[i]) 654 print('-', i, zone[i])
614 zone[id] = nil 655 zone[id] = nil
615 end 656 end
616 end
617 if pin.factionID then
618 QuestsByFaction[pin.factionID][id] = nil
619 end 657 end
620 pin:Hide() 658 pin:Hide()
621 pin:ClearAllPoints() 659 pin:ClearAllPoints()
622 tinsert(self.freePins, pin) 660 tinsert(self.freePins, pin)
623 print('|cFFFF4400Clearing out', pin:GetName(),id) 661 print('|cFFFF4400Clearing out', pin:GetName(),id)
630 superTrackedID = GetSuperTrackedQuestID() 668 superTrackedID = GetSuperTrackedQuestID()
631 if not mapID then 669 if not mapID then
632 -- info not available yet 670 -- info not available yet
633 return 671 return
634 end 672 end
673
674 print('|cFF00FF88'..self:GetName()..':RefreshData()|r', 'map:', mapID, 'realMap:', GetCurrentMapAreaID())
675
635 if mapID == BROKEN_ISLES_ID then 676 if mapID == BROKEN_ISLES_ID then
636 self.hasUpdate = false 677 self.hasUpdate = false
637 print('|cFF00FFFFRefreshQuestsForMap|r', mapID, GetMapNameByID(mapID), superTrackedID) 678 print('|cFF00FFFFContinent:|r', mapID, GetMapNameByID(mapID), superTrackedID)
638 self.fullSearch = true 679 self.fullSearch = true
639 for i = 1, MC_GetNumZones(mapID) do 680 for i = 1, MC_GetNumZones(mapID) do
640 local submapID, name, depth = MC_GetZoneInfo(mapID, i) 681 local submapID, name, depth = MC_GetZoneInfo(mapID, i)
641 self:RefreshData(submapID) 682 self:RefreshData(submapID)
642 end 683 end
643 self.fullSearch = nil 684 self.fullSearch = nil
644 elseif QuestsByZone[mapID] then 685 elseif self.QuestsByZone[mapID] then
645 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID) 686 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID)
646 local quest = QuestsByZone[mapID]
647 local numQuests = 0 687 local numQuests = 0
648 if taskInfo and #taskInfo >= 1 then 688 if taskInfo and #taskInfo >= 1 then
649 print('|cFF00FFFFRefreshQuestsForMap|r', mapID, GetMapNameByID(mapID), #taskInfo) 689 print('|cFF00FFFF Zone:|r', mapID, GetMapNameByID(mapID), #taskInfo)
650 wipe(QuestsByZone[mapID]) 690 wipe(self.QuestsByZone[mapID])
651 ZoneInfo[mapID] = taskInfo 691 ZoneInfo[mapID] = taskInfo
692 qprint('|cFFFF4400START of', GetMapNameByID(mapID))
652 for taskID, info in pairs(taskInfo) do 693 for taskID, info in pairs(taskInfo) do
653 print('-', taskID)
654 local questID = info.questId 694 local questID = info.questId
655 info.mapID = mapID 695 info.mapID = mapID
656 local questPOI = self:AcquirePin(questID, mapID) 696 local questPOI = self:AcquirePin(questID, mapID)
657 local hasUpdate, isPending = questPOI:RefreshData(taskInfo) 697 local hasUpdate, isPending = questPOI:RefreshData(info)
658 self.hasUpdate = (self.hasUpdate or hasUpdate) 698 self.hasUpdate = (self.hasUpdate or hasUpdate)
659 self.isPending = (self.isPending or isPending) 699 self.isPending = (self.isPending or isPending)
660 numQuests = numQuests + 1 700 numQuests = numQuests + 1
661 end 701 end
662 end 702 qprint('|cFFFF4400END of', GetMapNameByID(mapID))
663 end 703 end
664 704 end
665 print(' hasUpdate:', self.hasUpdate, 'isPending:', self.isPending, 'timer:', self.OnNext) 705
666 if self.hasUpdate then 706 if not self.fullSearch then
667 self.OnNext = self.OnNext or C_Timer.NewTimer(0.25, function() 707 print(' hasUpdate:', self.hasUpdate, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or ''))
668 self:Refresh(true) 708
669 self.OnNext = nil 709 end
670 end) 710
671 end
672 end 711 end
673 712
674 function WorldQuests:Refresh(forced) 713 function WorldQuests:Refresh(forced)
675 local print = wqprint 714 local print = wqprint
676 print('|cFF00FF88'..tostring(self)..':Refresh()|r') 715 print('|cFF00FF88'..self:GetName()..':Refresh()|r')
677 if not WorldMapPOIFrame:IsVisible() then 716 if not WorldMapPOIFrame:IsVisible() then
678 return 717 return
679 end 718 end
680 if forced then 719 if forced then
681 self:Reset() 720 self:Reset()
688 end 727 end
689 728
690 -- prepares elements for a map update 729 -- prepares elements for a map update
691 function WorldQuests:Reset () 730 function WorldQuests:Reset ()
692 local print = wqprint 731 local print = wqprint
693 print('|cFF00FF88'..tostring(self)..':Reset()|r') 732 print('|cFF00FF88'..self:GetName()..':Reset()|r')
694 wipe(QuestPositions) 733 for questID, pin in pairs(self.QuestsByID) do
695 wipe(QuestsByReward)
696 wipe(QuestsByTag)
697 for questID, pin in pairs(QuestsByID) do
698 pin.used = nil 734 pin.used = nil
699 end 735 end
700 end 736 end
701 737
702 -- update visibility states of all pins 738 -- update visibility states of all pins
713 749
714 if submapID == BROKEN_ISLES_ID and (not db.DisplayContinentPins) then 750 if submapID == BROKEN_ISLES_ID and (not db.DisplayContinentPins) then
715 print('not updating map for reasons') 751 print('not updating map for reasons')
716 return 752 return
717 end 753 end
718 print('|cFF88FF00'..tostring(self)..':UpdateAnchors|r', submapID, GetMapNameByID(submapID), 'pin count:', numPins) 754 print('|cFF88FF00'..self:GetName()..':UpdateAnchors|r', submapID, GetMapNameByID(submapID), 'pin count:', numPins)
719 local numZones = MC_GetNumZones(submapID) 755 local numZones = MC_GetNumZones(submapID)
720 if numZones then 756 if numZones then
721 for i = 1, numZones do 757 for i = 1, numZones do
722 local subMapID = MC_GetZoneInfo(submapID, i) 758 local subMapID = MC_GetZoneInfo(submapID, i)
723 self:UpdateAnchors(subMapID) 759 self:UpdateAnchors(subMapID)
724 end 760 end
725 end 761 end
726 local pins = QuestsByZone[submapID] 762 local pins = self.QuestsByZone[submapID]
727 763
728 if pins then 764 if pins then
729 local hostFrame = WorldMapPOIFrame 765 local hostFrame = WorldMapPOIFrame
730 local mapWidth, mapHeight = hostFrame:GetSize() 766 local mapWidth, mapHeight = hostFrame:GetSize()
731 for questID, pin in pairs(pins) do 767 for questID, pin in pairs(pins) do
768 pin.hasUpdate = true
732 pin:IsShowable() 769 pin:IsShowable()
733 if pin.used then 770 if pin.used then
734 pin:SetFrameLevel(PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins) 771 pin:SetFrameLevel(PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins)
735 print('level', PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins) 772 print('level', PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins)
736 pin:SetAnchor(WorldMapPOIFrame, currentMap, mapWidth, mapHeight) 773 pin:SetAnchor(WorldMapPOIFrame, currentMap, mapWidth, mapHeight)
756 wipe(debug_hide) 793 wipe(debug_hide)
757 -- continent or zone sizing 794 -- continent or zone sizing
758 local fadeGrouped = (db.FadeWhileGrouped and IsInGroup()) 795 local fadeGrouped = (db.FadeWhileGrouped and IsInGroup())
759 796
760 numPins = 0 797 numPins = 0
761 for questID, pin in pairs(QuestsByID) do 798 for questID, pin in pairs(self.QuestsByID) do
762 -- can we show it? 799 -- can we show it?
763 if showQuestPOI and (pin.used) then 800 if showQuestPOI and (pin.used) then
764 801
802 pin.hasUpdate = true
765 if fadeGrouped then 803 if fadeGrouped then
766 pin:SetAlpha(0.25) 804 pin:SetAlpha(0.25)
767 else 805 else
768 pin:SetAlpha(1) 806 pin:SetAlpha(1)
769 end 807 end
788 print('animating? ', questID, 'filtered:', pin.filtered) 826 print('animating? ', questID, 'filtered:', pin.filtered)
789 end 827 end
790 -- trap new but animating pins here 828 -- trap new but animating pins here
791 else 829 else
792 -- hard show existing pin 830 -- hard show existing pin
793 print('refresh #', questID, 'filtered:', pin.filtered) 831 print('refresh #', questID, 'filtered:', pin.filtered, 'hasUpdate', pin.hasUpdate)
794 pin.hasUpdate = true 832 pin:Show()
795 pin:Show(true)
796 tinsert(debug_show,questID) 833 tinsert(debug_show,questID)
797 end 834 end
798 else 835 else
799 if pin:IsShown() then 836 if pin:IsShown() then
800 tinsert(debug_hide,questID) 837 tinsert(debug_hide,questID)
807 print(' adding:', table.concat(debug_animate, ',' )) 844 print(' adding:', table.concat(debug_animate, ',' ))
808 print(' refresh:', table.concat(debug_show, ',' )) 845 print(' refresh:', table.concat(debug_show, ',' ))
809 print(' hiding:', table.concat(debug_hide, ',' )) 846 print(' hiding:', table.concat(debug_hide, ',' ))
810 hasNewQuestPins = nil 847 hasNewQuestPins = nil
811 notifyPlayed = nil 848 notifyPlayed = nil
849 self.hasUpdate = nil
812 end 850 end
813 851
814 -- data provider manipulations for the taxi map 852 -- data provider manipulations for the taxi map
815 WorldPlan.OnFlightMapLoaded = function() 853 WorldPlan.OnFlightMapLoaded = function()
816 if true then return end 854 if true then return end
831 WorldPlan:GetPinsForMap(self:GetMapID()) 869 WorldPlan:GetPinsForMap(self:GetMapID())
832 870
833 for pin in self:EnumerateAllPins() do 871 for pin in self:EnumerateAllPins() do
834 if pin.worldQuest then 872 if pin.worldQuest then
835 --print('got pin #', pin.questID) 873 --print('got pin #', pin.questID)
836 local wp = QuestsByID[pin.questID] 874 local wp = self.QuestsByID[pin.questID]
837 if wp then 875 if wp then
838 wp:ClearAllPoints() 876 wp:ClearAllPoints()
839 wp:SetParent(FlightMapFrame.ScrollContainer) 877 wp:SetParent(FlightMapFrame.ScrollContainer)
840 wp:SetFrameStrata('MEDIUM') 878 wp:SetFrameStrata('MEDIUM')
841 wp:SetPoint('CENTER', pin, 'CENTER') 879 wp:SetPoint('CENTER', pin, 'CENTER')
871 self.filtered = nil 909 self.filtered = nil
872 self.used = true 910 self.used = true
873 911
874 print(' |cFFFF4400IsShowable()|r', self.title) 912 print(' |cFFFF4400IsShowable()|r', self.title)
875 913
876 local isIncluded 914 if not self.passesBlizzFilters then
877 for filterKey, filterValues in pairs(WorldPlan.UsedFilters) do 915 self.filtered = true
878 local controlValue = self[filterKey] 916 end
879 if controlValue then
880 local filterType = filterValues[controlValue]
881 if filterType == true then
882 isIncluded = true
883 print(' include? ', filterKey, controlValue, filterType)
884 end
885 end
886 self.filtered = (not isIncluded)
887 end
888
889
890 if not TQ_IsActive(self.questID) then 917 if not TQ_IsActive(self.questID) then
891 self.used = nil 918 self.used = nil
892 end 919 elseif qType == LE_QUEST_TAG_TYPE_PROFESSION then
893 if qType == LE_QUEST_TAG_TYPE_PROFESSION then
894 if not (db.ShowAllProfessionQuests or (self.tradeskillLineIndex and GetProfessionInfo(self.tradeskillLineIndex))) then 920 if not (db.ShowAllProfessionQuests or (self.tradeskillLineIndex and GetProfessionInfo(self.tradeskillLineIndex))) then
895 self.used = nil 921 self.used = nil
896 end 922 end
897 end 923 end
898 return self.used, self.filtered 924 return self.used, self.filtered
902 print('|cFF0088FFUpdatePinTimer()|r') 928 print('|cFF0088FFUpdatePinTimer()|r')
903 end 929 end
904 930
905 --- Fixes icons upon size update 931 --- Fixes icons upon size update
906 function QuestPOI:UpdateSize (style, subStyle) 932 function QuestPOI:UpdateSize (style, subStyle)
907 self.style = self.style or POI_DEFAULT_TYPE
908 style = style or self.style 933 style = style or self.style
909 subStyle = subStyle or self.subStyle 934 subStyle = subStyle or self.subStyle
910 935
911 qprint('|cFF00FF88'..self:GetName()..'|r:UpdateSize()', style, subStyle) 936 --qprint('|cFF00FF88'..self:GetName()..'|r:UpdateSize()', style, subStyle)
912 937
913 self.currentWidth = subStyle.PinSize 938 self.currentWidth = subStyle.PinSize
914 self.borderSize = subStyle.Border 939 self.borderSize = subStyle.Border
915 self.trackingBorderSize = subStyle.TrackingBorder 940 self.trackingBorderSize = subStyle.TrackingBorder
916 self.tagSize = subStyle.TagSize 941 self.tagSize = subStyle.TagSize
964 989
965 990
966 end 991 end
967 992
968 993
969 function FilterBar:OnEvent(event)
970 if event == 'QUEST_LOG_UPDATE' then
971 self:Refresh()
972 end
973 end
974
975 function FilterBar:PassesFilterSet(filterKey, pin)
976 local passesFilter = true
977 for filterKey, filters in pairs(QuestFilters) do
978 for rewardType, value in pairs(QuestFilters[filterKey]) do
979 if value == 1 and rewardType == pin[filterKey] then
980 passesFilter = true
981 elseif value == -1 and rewardType == pin[filterKey] then
982 passesFilter = false
983 end
984 end
985 end
986 return passesFilter
987 end
988
989
990 local bountyIndex
991 local debug_headers = {}
992
993 function FilterBar:Setup()
994 self:GetFilters()
995 end
996
997 function FilterBar:OnEvent(event,...)
998 if event == 'QUEST_LOG_UPDATE' then
999 self:Reset()
1000 self:Refresh()
1001 end
1002 end
1003
1004 function FilterBar:GetFilters()
1005
1006 local print = fbprint
1007 wipe(WorldPlan.FilterOptions)
1008
1009 for index, info in ipairs(POI_FILTER_OPTIONS) do
1010 tinsert(WorldPlan.FilterOptions, info)
1011 end
1012 self.bounties, self.numBounties = GetQuestBountyInfoForMapID(WorldPlan.currentMapID)
1013 self.BountyFilters = {}
1014 for index, data in ipairs(self.bounties) do
1015 local info = self.BountyFilters[index]
1016 if not info then
1017 info = {}
1018 self.BountyFilters[index] = info
1019 end
1020
1021 local questTitle = GetQuestLogTitle(GetQuestLogIndexByID(data.questID))
1022
1023 info.filterKey = 'factionID'
1024 info.filterValue = data.factionID
1025 info.label = questTitle
1026 info.texture = data.icon
1027 print('loading emissary', questTitle)
1028 tinsert(WorldPlan.FilterOptions, info)
1029 --{ filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", },
1030 end
1031 end
1032
1033 function FilterBar:Reset()
1034 self:GetFilters()
1035 end
1036
1037 function FilterBar:Refresh(forced)
1038 local print = fbprint
1039 local blocks = self.SummaryHeaders
1040 local relativeFrame = WorldMapFrame.UIElementsFrame.TrackingOptionsButton
1041 local numHeaders = 0
1042 print('|cFF00FF88'..tostring(self)..':Refresh()|r', 'currentMap=',WorldPlan.currentMapID)
1043
1044
1045 local quests = QuestsByZone[WorldPlan.currentMapID] or QuestsByID
1046
1047
1048 for index, info in ipairs(WorldPlan.FilterOptions) do
1049 local numQuests = 0
1050
1051 for questID, pin in pairs(quests) do
1052 if pin.used then
1053 if not info.filterKey then
1054 numQuests = numQuests + 1
1055 elseif pin[info.filterKey] == info.filterValue then
1056 numQuests = numQuests + 1
1057 end
1058 end
1059 end
1060 print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')')
1061
1062 if numQuests >= 1 then
1063 numHeaders = numHeaders + 1
1064 local button = blocks[numHeaders]
1065 if not blocks[numHeaders] then
1066 button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, WorldMapScrollFrame, 'WorldPlanFilterPin')
1067 for k,v in pairs(info)do print(k,v) end
1068 button.iconBorder:SetTexture(info.fill or POI_BORDER_FILL)
1069 button.iconBorder:SetMask(info.mask or POI_BORDER_MASK)
1070 button.iconBorder:SetDesaturated(info.desaturated)
1071 button.supertrackBorder:SetTexture(info.fill or POI_BORDER_FILL)
1072 button.supertrackBorder:SetMask(info.mask or POI_BORDER_MASK)
1073 button.supertrackBorder:SetDesaturated(true)
1074 blocks[numHeaders] = button
1075 end
1076
1077 button:SetID(index)
1078 button.spacing = ((info.filterKey ~= relativeFrame.filterKey) and 10) or 0
1079 button.relativeFrame = relativeFrame
1080 button:Refresh(info, (numHeaders == 1), numQuests)
1081 button:Show()
1082 relativeFrame = button
1083 end
1084
1085 end
1086
1087 self.numHeaders = numHeaders
1088 for i = numHeaders + 1, #WorldPlan.FilterOptions do
1089 if self.SummaryHeaders[i] then
1090 self.SummaryHeaders[i]:Hide()
1091 end
1092 end
1093 end
1094
1095 function FilterBar:Cleanup()
1096
1097 -- hide trailing buttons
1098 end
1099
1100
1101 function FilterPin:Refresh(info, isFirst, numQuests)
1102 local print = fbprint
1103 isFirst = isFirst or self.isFirst
1104 numQuests = numQuests or self.numQuests
1105
1106 if info then
1107 self.isFirst = isFirst
1108 self.numQuests = numQuests
1109 self.filterKey = info.filterKey
1110 self.filterValue = info.filterValue
1111 self.tagID = info.tagID
1112
1113 self.icon:ClearAllPoints()
1114 self.icon:SetTexture(info.texture)
1115 self.icon:SetAllPoints(self)
1116 self.supertrackBorder:Hide()
1117 self.count:SetText(numQuests)
1118 self:Show()
1119 end
1120
1121
1122 self.itemTexture = self.texture
1123
1124 if isFirst then
1125 self:SetPoint('TOP', self.relativeFrame, 'BOTTOM', 0, -5)
1126 else
1127 self:SetPoint('TOPRIGHT', self.relativeFrame, 'BOTTOMRIGHT', 0, -(3*2 + 1 + (self.spacing or 0)))
1128
1129 end
1130 print('anchor to', self.relativeFrame:GetName())
1131
1132 local r, g, b, a = 1,1,1,1
1133 local used = WorldPlan.UsedFilters[self.filterKey]
1134 if used and self.filterKey then
1135 if used[self.filterValue] == true then
1136 r, g, b = 0, 1, 0
1137 elseif used[self.filterValue] == false then
1138 r, g, b = 1, 0, 0
1139 end
1140 end
1141 self.iconBorder:SetVertexColor(r, g, b, a)
1142 self:UpdateSize()
1143 end
1144
1145 function FilterPin:OnLoad()
1146 self:RegisterForClicks('AnyUp')
1147 self:SetFrameStrata('HIGH')
1148 self:SetFrameLevel(151)
1149 self:SetScript('OnUpdate', nil)
1150 self.style = db.filterStyle
1151 self.subStyle = db.defaultPinStyle.continent
1152 end
1153
1154 function FilterPin:OnUpdate ()
1155
1156 end
1157
1158 function FilterPin:OnLeave ()
1159 if GameTooltip:IsOwned(self) then
1160 GameTooltip:Hide()
1161 end
1162 end
1163
1164 -- shift-click: reset filter
1165 -- click: rotate through include(1), exclude(-1), ignore(nil)
1166 function FilterPin:OnClick (button)
1167 local print = fbprint
1168 local filterKey = self.filterKey
1169 local filterValue = self.filterValue
1170
1171
1172 local operation = opPrefix
1173 local setInclude = (button == 'LeftButton')
1174
1175
1176 if not filterKey then
1177 -- resetting
1178 wipe(WorldPlan.UsedFilters)
1179
1180 elseif IsShiftKeyDown() then
1181 WorldPlan.UsedFilters[filterKey] = nil
1182 else
1183 WorldPlan.UsedFilters[filterKey] = WorldPlan.UsedFilters[filterKey] or {}
1184 WorldPlan.UsedFilters[filterKey][filterValue] = setInclude
1185 print(filterKey, filterValue, '=', setInclude)
1186
1187 for index, info in ipairs(WorldPlan.FilterOptions) do
1188 if info.filterKey == filterKey then
1189 if (not IsControlKeyDown()) and (filterValue ~= info.filterValue) then
1190 WorldPlan.UsedFilters[filterKey][info.filterValue] = (not setInclude)
1191 print(filterKey, info.filterValue, '=', WorldPlan.UsedFilters[filterKey][info.filterValue])
1192 end
1193 end
1194 end
1195
1196 end
1197 print('|cFF00FF88Filter Update:', filterKey, filterValue, operation)
1198 WorldPlan:RefreshAll()
1199 end
1200 994
1201 --%debug% 995 --%debug%
1202 local SetTimedCallbackForAllPins = function(seconds, callback) 996 local SetTimedCallbackForAllPins = function(seconds, callback)
1203 C_Timer.After(seconds, function() 997 C_Timer.After(seconds, function()
1204 for id, pin in pairs(QuestsByID) do 998 for id, pin in pairs(WorldPlanQuests.QuestsByID) do
1205 callback(pin) 999 callback(pin)
1206 end 1000 end
1207 end) 1001 end)
1208 end 1002 end
1209 1003