Mercurial > wow > worldplan
comparison WorldPlan.lua @ 29:c1612c2c1840
WorldPlan:
- Optimizations to in a lot of areas that should lead to better load-times and snappier world map.
* Responding to quest log and map events by setting flags instead of tailing into the complete works.
* Using a generic getter function for resolving pin visual attributes. and making use of blizzard constants for sanity's sake.
author | Nenue |
---|---|
date | Thu, 27 Oct 2016 13:50:56 -0400 |
parents | 4a7e89bffbcb |
children | 8cb750e79952 |
comparison
equal
deleted
inserted
replaced
28:3f4368c4a49b | 29:c1612c2c1840 |
---|---|
8 | 8 |
9 Issues: | 9 Issues: |
10 Dalaran quests aren't visible until that map has been specifically viewed by the player. | 10 Dalaran quests aren't visible until that map has been specifically viewed by the player. |
11 --]] | 11 --]] |
12 | 12 |
13 WorldPlanCore = {} | 13 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" |
14 local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" | |
15 | |
16 local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background" | |
17 local POI_BORDER_FILL = "Interface\\BUTTONS\\YELLOWORANGE64" | |
18 local POI_BORDER_BLUE = "Interface\\BUTTONS\\GRADBLUE" | |
19 local POI_BORDER_RED = "Interface\\BUTTONS\\RedGrad64" | |
20 local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64" | |
21 local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64" | |
22 | |
23 WorldPlanCore = { | |
24 defaults = {}, | |
25 | |
26 } | |
14 WorldPlanPOIMixin = {} | 27 WorldPlanPOIMixin = {} |
15 WorldPlanFilterPinMixin = {} | 28 WorldPlanFilterPinMixin = {} |
16 local WorldPlanFlightMapMixin = setmetatable({}, {__tostring = function() return 'FlightMapHandler' end}) | 29 local WorldPlanFlightMapMixin = setmetatable({}, {__tostring = function() return 'FlightMapHandler' end}) |
17 local WorldQuests = setmetatable({ QuestsByID = {}, freePins = {} }, {__tostring = function() return 'QuestHandler' end}) | 30 local WorldQuests = setmetatable({ QuestsByID = {}, freePins = {} }, {__tostring = function() return 'QuestHandler' end}) |
18 local FilterBar = setmetatable({ SummaryHeaders = {} }, {__tostring = function() return 'FilterBar' end}) | 31 local FilterBar = setmetatable({ SummaryHeaders = {} }, {__tostring = function() return 'FilterBar' end}) |
28 local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end | 41 local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end |
29 local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end | 42 local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end |
30 local fbprint = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or function() end | 43 local fbprint = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or function() end |
31 | 44 |
32 local wipe, tremove, tinsert, pairs, floor, tContains = table.wipe, table.remove, table.insert, pairs, floor, tContains | 45 local wipe, tremove, tinsert, pairs, floor, tContains = table.wipe, table.remove, table.insert, pairs, floor, tContains |
33 local TQ_GetQuestInfoByQuestID = C_TaskQuest.GetQuestInfoByQuestID -- Return the name of a quest with a given ID | |
34 local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented | 46 local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented |
35 local TQ_GetQuestTimeLeftMinutes = C_TaskQuest.GetQuestTimeLeftMinutes | 47 local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID |
36 local TQ_RequestPreloadRewardData = C_TaskQuest.RequestPreloadRewardData | |
37 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation | |
38 local TQ_IsActive = C_TaskQuest.IsActive | 48 local TQ_IsActive = C_TaskQuest.IsActive |
39 local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS | 49 local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS |
40 local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters | 50 local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters |
41 local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest | 51 local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest |
42 local GameTooltip = GameTooltip | 52 local GameTooltip = GameTooltip |
61 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', } | 71 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', } |
62 -- default color templates | 72 -- default color templates |
63 local ARTIFACT_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT] | 73 local ARTIFACT_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT] |
64 local MONEY_COLOR = {hex ='|cFFFFFF00', r=1, g=1, b=0} | 74 local MONEY_COLOR = {hex ='|cFFFFFF00', r=1, g=1, b=0} |
65 local COMMON_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON] | 75 local COMMON_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON] |
66 | 76 local DEFAULT_TYPE = { |
67 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" | |
68 local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" | |
69 | |
70 local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background" | |
71 local POI_BORDER_FILL = "Interface\\BUTTONS\\YELLOWORANGE64" | |
72 local POI_BORDER_BLUE = "Interface\\BUTTONS\\GRADBLUE" | |
73 local POI_BORDER_RED = "Interface\\BUTTONS\\RedGrad64" | |
74 local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64" | |
75 local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64" | |
76 | |
77 local REWARD_CASH = 1001 | |
78 local REWARD_ARTIFACT_POWER = 1002 | |
79 local REWARD_GEAR = 1003 | |
80 local REWARD_CURRENCY = 1004 | |
81 local REWARD_ITEM = 1005 | |
82 local REWARD_REAGENT = 1006 | |
83 | |
84 local POI_DEFAULT_TYPE = { | |
85 a = 1, | 77 a = 1, |
86 r = 1, g = 1, b = 1, | 78 r = 1, g = 1, b = 1, |
87 x = 0, y = 0, | 79 x = 0, y = 0, |
88 desaturated = true, | 80 desaturated = true, |
89 pinMask = POI_BORDER_MASK, | 81 pinMask = POI_BORDER_MASK, |
112 NoIcon = true, | 104 NoIcon = true, |
113 TimeleftStage = 1, | 105 TimeleftStage = 1, |
114 showNumber = false, | 106 showNumber = false, |
115 } | 107 } |
116 } | 108 } |
117 local POI_REWARD_TYPE = setmetatable({}, { | 109 |
118 __newindex = function(t, k, v) | 110 |
119 if type(v) == 'table' then | |
120 setmetatable(v, {__index = POI_DEFAULT_TYPE}) | |
121 end | |
122 rawset(t,k,v) | |
123 end | |
124 }) | |
125 local POI_FILTER_STYLE = setmetatable({ | 111 local POI_FILTER_STYLE = setmetatable({ |
126 continentBorder = 2, | 112 continentBorder = 2, |
127 zoneBorder = 2, | 113 zoneBorder = 2, |
128 }, {__index = POI_DEFAULT_TYPE}) | 114 }, {__index = DEFAULT_TYPE}) |
129 | |
130 local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP | |
131 local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE | |
132 local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON | |
133 local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION | |
134 local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL | |
135 | |
136 -- Pin color/display variables | |
137 POI_REWARD_TYPE[REWARD_ITEM] = { | |
138 r = 1, g = 1, b = 1, | |
139 } | |
140 POI_REWARD_TYPE[REWARD_REAGENT] = { | |
141 r = 0, g = 1, b = 1, | |
142 } | |
143 POI_REWARD_TYPE[REWARD_ARTIFACT_POWER] = { | |
144 r = 1, g = .25, b = .5, | |
145 hasNumeric = true, | |
146 numberRGB = {1, 1, 1}, | |
147 } | |
148 POI_REWARD_TYPE[REWARD_GEAR] = { | |
149 r = .1, g = .2, b = 1, | |
150 } | |
151 POI_REWARD_TYPE[REWARD_CURRENCY] = { | |
152 r = 1, g = 1, b = 0, | |
153 hasNumeric = true, | |
154 numberRGB = {1, 1, 1}, | |
155 } | |
156 POI_REWARD_TYPE[REWARD_CASH] = { | |
157 r = 0, g = 0, b = 0, | |
158 --x = 0, y = -1, | |
159 --mask = ICON_MONEY, | |
160 --continentBorder = 1, | |
161 --zoneBorder = 1, | |
162 } | |
163 | |
164 | 115 |
165 | 116 |
166 local defaults = { | 117 local defaults = { |
167 defaultPinStyle = POI_DEFAULT_TYPE, | 118 defaultPinStyle = POI_DEFAULT_TYPE, |
168 rewardStyle = POI_REWARD_TYPE, | 119 rewardStyle = POI_REWARD_TYPE, |
174 EnablePins = true, | 125 EnablePins = true, |
175 FadeWhileGrouped = true, | 126 FadeWhileGrouped = true, |
176 } | 127 } |
177 | 128 |
178 -- Summary header structure | 129 -- Summary header structure |
130 | |
131 local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD | |
132 local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER | |
133 local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT | |
134 local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES | |
135 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS | |
136 | |
137 | |
138 local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP | |
139 local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE | |
140 local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON | |
141 local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION | |
142 local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL | |
179 local POI_FILTER_OPTIONS = { | 143 local POI_FILTER_OPTIONS = { |
180 { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" }, | 144 { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" }, |
181 { filterKey= 'rewardType', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" }, | 145 { filterKey= 'rewardType', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" }, |
182 { filterKey= 'rewardType', filterValue = REWARD_CURRENCY,label = 'Currency', texture = "Interface\\ICONS\\inv_misc_elvencoins" }, | 146 { filterKey= 'rewardType', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\ICONS\\inv_misc_elvencoins" }, |
183 { filterKey= 'rewardType', filterValue = REWARD_ITEM, label = 'Item', texture = "Interface\\ICONS\\inv_crate_01" }, | |
184 { filterKey= 'rewardType', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" }, | 147 { filterKey= 'rewardType', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" }, |
185 { filterKey= 'rewardType', filterValue = REWARD_REAGENT, label = 'Reagents', texture = 1417744 }, | 148 { filterKey= 'rewardType', filterValue = REWARD_REAGENT, label = 'Materials', texture = 1417744 }, |
186 { filterKey= 'rewardType', filterValue = REWARD_CASH, label = 'Reagents', texture = ICON_MONEY }, | 149 { filterKey= 'rewardType', filterValue = REWARD_CASH, label = 'Gold', texture = ICON_MONEY }, |
187 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 }, | 150 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 }, |
188 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", }, | 151 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", }, |
189 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", }, | 152 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", }, |
190 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", }, | 153 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", }, |
191 } | 154 } |
248 end | 211 end |
249 end | 212 end |
250 return frame | 213 return frame |
251 end | 214 end |
252 | 215 |
253 -- use tooltip object to extract item details | |
254 local ParseItemReward = function(questID) | |
255 local rewardType = REWARD_ITEM | |
256 local name, icon, quantity, quality, _, itemID = GetQuestLogRewardInfo(1, questID) | |
257 if not itemID then | |
258 return REWARD_ITEM | |
259 end | |
260 | |
261 scanner:SetOwner(WorldPlan, "ANCHOR_NONE") | |
262 scanner:SetItemByID(itemID) | |
263 local ttl1 = _G['WorldPlanTooltipTextLeft1'] | |
264 local ttl2 = _G['WorldPlanTooltipTextLeft2'] | |
265 local ttl3 = _G['WorldPlanTooltipTextLeft3'] | |
266 local ttl4 = _G['WorldPlanTooltipTextLeft4'] | |
267 if ttl2 then | |
268 local text = ttl2:GetText() | |
269 -- Artifact Power | |
270 if text and text:match("|cFFE6CC80") then | |
271 --print('AP token!', text) | |
272 local power | |
273 if ttl4 then | |
274 local text = ttl4:GetText() | |
275 --print('tip line 4', text) | |
276 if text then | |
277 power = text:gsub("%p", ""):match("%d+") | |
278 power = tonumber(power) | |
279 end | |
280 | |
281 end | |
282 rewardType = REWARD_ARTIFACT_POWER | |
283 icon = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" | |
284 quantity = power | |
285 elseif text and text:match("Item Level") then | |
286 --print('equipment!', text) | |
287 rewardType = REWARD_GEAR | |
288 quantity = text:match("Item Level ([%d\+]+)") | |
289 end | |
290 end | |
291 if ttl3 then | |
292 local text = ttl3:GetText() | |
293 -- Crafting Reagent | |
294 if text and text:match("Crafting Reagent") then | |
295 --print('reagent', text) | |
296 rewardType = REWARD_REAGENT | |
297 end | |
298 end | |
299 iprint(' item:', name, rewardType, icon, quantity) | |
300 return rewardType, icon, quantity, name, itemID | |
301 end | |
302 | 216 |
303 -- update a masked texture without messing up its blending mask | 217 -- update a masked texture without messing up its blending mask |
304 local SetMaskedTexture = function(region, file, mask) | 218 local SetMaskedTexture = function(region, file, mask) |
305 mask = mask or POI_BORDER_MASK | 219 mask = mask or POI_BORDER_MASK |
306 region:SetMask(nil) | 220 region:SetMask(nil) |
328 end | 242 end |
329 DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FFWorldPlan|r: " .. msg) | 243 DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FFWorldPlan|r: " .. msg) |
330 end | 244 end |
331 | 245 |
332 function WorldPlan:OnLoad () | 246 function WorldPlan:OnLoad () |
247 | |
248 self.Types = setmetatable({}, { | |
249 __newindex = function(t, k, v) | |
250 print('adding type', k) | |
251 if type(v) == 'table' then | |
252 v = setmetatable(v, {__index = function(t,k) | |
253 print('##deferring to default key', k) | |
254 return DEFAULT_TYPE[k] | |
255 end}) | |
256 end | |
257 rawset(t,k,v) | |
258 end | |
259 }) | |
260 | |
261 local rgbWhite = {1, 1, 1} | |
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 | |
268 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, } | |
270 end | |
271 | |
333 WorldPlan = self | 272 WorldPlan = self |
334 scanner = _G.WorldPlanTooltip | 273 scanner = _G.WorldPlanTooltip |
335 wmtt = _G.WorldMapTooltip | 274 wmtt = _G.WorldMapTooltip |
336 WorldMapPOIFrame = _G.WorldMapPOIFrame | 275 WorldMapPOIFrame = _G.WorldMapPOIFrame |
337 | 276 |
417 end | 356 end |
418 end | 357 end |
419 self.initialized = true | 358 self.initialized = true |
420 | 359 |
421 hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize) | 360 hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize) |
361 end | |
362 | |
363 function WorldPlan:GetTypeInfo(typeID) | |
364 local info, extraInfo | |
365 if (not typeID) or (not self.Types[typeID]) then | |
366 qprint('## sent default type') | |
367 info = DEFAULT_TYPE | |
368 else | |
369 qprint('## sent defined type', typeID) | |
370 info = self.Types[typeID] | |
371 end | |
372 | |
373 if isContinentMap then | |
374 extraInfo = info.continent | |
375 qprint('### continent subtype', extraInfo) | |
376 else | |
377 extraInfo = info.zone | |
378 | |
379 qprint('### zone subtype', extraInfo) | |
380 end | |
381 return info, extraInfo | |
382 end | |
383 | |
384 do | |
385 local timeStates = { | |
386 {maxSeconds = 60, | |
387 r=1, g=0.25, b =0, format = function (minutes) return '|cFFFF4400'.. minutes .. 'm' end, | |
388 }, | |
389 {maxSeconds = 240, | |
390 r=1, g=.5, b=0, format = function(minutes) return '|cFFFF4400'.. floor(minutes/60) .. 'h' end, | |
391 }, | |
392 {maxSeconds = 1440, | |
393 r=1, g=1, b=0, format = function(minutes) return '|cFFFFFF00'.. floor(minutes/60) .. 'h' end, | |
394 }, | |
395 {maxSeconds = 10081, | |
396 r=0, g=1, b=0, | |
397 }, -- 7 days + 1 minute | |
398 } | |
399 -- Generates a timeleft string | |
400 function WorldPlan:GetTimeInfo(timeLeft, limit) | |
401 limit = limit or #timeStates | |
402 for index = 1, limit do | |
403 local state = timeStates[index] | |
404 if timeLeft <= state.maxSeconds then | |
405 local text | |
406 if state.format then | |
407 text = state.format(timeLeft) | |
408 end | |
409 return text, index | |
410 end | |
411 end | |
412 return nil, nil | |
413 end | |
422 end | 414 end |
423 | 415 |
424 function WorldPlan:RefreshAll (forced) | 416 function WorldPlan:RefreshAll (forced) |
425 if not self.initialized then | 417 if not self.initialized then |
426 return | 418 return |
524 info.func = DropDown_OnClick | 516 info.func = DropDown_OnClick |
525 UIDropDownMenu_AddButton(info) | 517 UIDropDownMenu_AddButton(info) |
526 end | 518 end |
527 | 519 |
528 function WorldQuests:Setup() | 520 function WorldQuests:Setup() |
521 | |
522 | |
523 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do | |
524 QuestsByZone[mapID] = {} | |
525 end | |
526 | |
527 | |
529 -- refresh positions any time blizzard does so (i.e. mousewheel zoom) | 528 -- refresh positions any time blizzard does so (i.e. mousewheel zoom) |
530 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() | 529 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() |
531 self:Refresh(true) | 530 self:Refresh(true) |
532 end) | 531 end) |
533 | 532 |
546 function WorldQuests:OnEvent (event, ...) | 545 function WorldQuests:OnEvent (event, ...) |
547 print('|cFFFFFF00'..tostring(self)..':OnEvent()'..event..'|r', GetTime(), ...) | 546 print('|cFFFFFF00'..tostring(self)..':OnEvent()'..event..'|r', GetTime(), ...) |
548 if event == 'QUEST_LOG_UPDATE' then | 547 if event == 'QUEST_LOG_UPDATE' then |
549 local questID, added = ... | 548 local questID, added = ... |
550 if questID and added then | 549 if questID and added then |
551 self:GetPinByQuestID(questID) | 550 local questPOI = self:AcquirePin(questID) |
551 self.hasUpdate, self.isPending = questPOI:RefreshData() | |
552 else | 552 else |
553 self:GetPinsForMap() | 553 self:RefreshData() |
554 end | 554 end |
555 print('WorldMapFrame', WorldMapFrame:IsVisible(), 'doRefresh:', hasNewQuestPins) | 555 print('WorldMapFrame', WorldMapFrame:IsVisible(), 'doRefresh:', hasNewQuestPins) |
556 if WorldMapFrame:IsVisible() and hasNewQuestPins then | 556 if WorldMapFrame:IsVisible() and hasNewQuestPins then |
557 self:Refresh(true) | 557 self:Refresh(true) |
558 end | 558 end |
564 end | 564 end |
565 elseif event == 'SKILL_LINES_CHANGED' then | 565 elseif event == 'SKILL_LINES_CHANGED' then |
566 self:Refresh(true) | 566 self:Refresh(true) |
567 end | 567 end |
568 end | 568 end |
569 | 569 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation |
570 function WorldQuests:AcquirePin (questID, pinTable) | 570 function WorldQuests:AcquirePin (questID, mapID) |
571 local pin = QuestsByID[questID] | 571 local pin = QuestsByID[questID] |
572 local isNew = false | 572 local isNew = false |
573 if not pin then | 573 if not pin then |
574 isNew = true | 574 isNew = true |
575 local numFree = #self.freePins | 575 local numFree = #self.freePins |
578 --print('|cFF00FF00Re-using', pin:GetName()) | 578 --print('|cFF00FF00Re-using', pin:GetName()) |
579 else | 579 else |
580 local name = 'WorldPlanQuestMarker' .. NumPinFrames | 580 local name = 'WorldPlanQuestMarker' .. NumPinFrames |
581 --print('|cFF00FF00Creating', name) | 581 --print('|cFF00FF00Creating', name) |
582 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') | 582 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') |
583 | |
583 pin:SetFrameStrata('HIGH') | 584 pin:SetFrameStrata('HIGH') |
584 | |
585 NumPinFrames = NumPinFrames + 1 | 585 NumPinFrames = NumPinFrames + 1 |
586 | |
587 --pin.iconBorder:SetVertexColor(0,0,0,1) | 586 --pin.iconBorder:SetVertexColor(0,0,0,1) |
588 | 587 end |
589 end | 588 pin:SetID(questID) |
590 QuestsByID[questID] = pin | |
591 pin.isNew = true | 589 pin.isNew = true |
592 pin.currentWidth = nil | 590 pin.currentWidth = nil |
593 | 591 |
594 -- used by TaskPOI_x scripts | 592 -- used by TaskPOI_x scripts |
595 pin.questID = questID | 593 pin.questID = questID |
596 pin.worldQuest = true | 594 pin.worldQuest = true |
597 | 595 |
598 pin.Reset = function(self) | 596 QuestsByID[questID] = pin |
599 WorldQuests:GetPinByQuestID(questID) | |
600 end | |
601 else | 597 else |
602 --print('|cFF00FF00Using', pin:GetName()) | 598 --print('|cFF00FF00Using', pin:GetName()) |
603 end | 599 end |
604 | 600 mapID = mapID or TQ_GetQuestZoneID(questID) |
605 -- set display flags accordingly | 601 QuestsByZone[mapID][questID] = pin |
606 if pinTable then | 602 |
607 for k,v in pairs(pinTable) do | |
608 pin[k] = v | |
609 end | |
610 end | |
611 pin.throttle = nil | |
612 pin.timeThreschold = nil | |
613 return pin, isNew | 603 return pin, isNew |
614 end | 604 end |
615 | 605 |
616 -- remove from index and add it to the recycling heap | 606 -- remove from index and add it to the recycling heap |
617 function WorldQuests:ReleasePin (pin) | 607 function WorldQuests:ReleasePin (pin) |
632 tinsert(self.freePins, pin) | 622 tinsert(self.freePins, pin) |
633 print('|cFFFF4400Clearing out', pin:GetName(),id) | 623 print('|cFFFF4400Clearing out', pin:GetName(),id) |
634 end | 624 end |
635 | 625 |
636 -- create of update quest pins for a map and its underlying zones | 626 -- create of update quest pins for a map and its underlying zones |
637 function WorldQuests:GetPinsForMap (mapID) | 627 function WorldQuests:RefreshData (mapID) |
638 local print = wqprint | 628 local print = wqprint |
639 mapID = mapID or GetCurrentMapAreaID() | 629 mapID = mapID or GetCurrentMapAreaID() |
640 superTrackedID = GetSuperTrackedQuestID() | 630 superTrackedID = GetSuperTrackedQuestID() |
641 if not mapID then | 631 if not mapID then |
642 -- info not available yet | 632 -- info not available yet |
643 return | 633 return |
644 end | 634 end |
645 if mapID == BROKEN_ISLES_ID then | 635 if mapID == BROKEN_ISLES_ID then |
646 hasPendingQuestData = nil | 636 self.hasUpdate = false |
647 print('|cFF00FFFFRefreshQuestsForMap|r', mapID, GetMapNameByID(mapID), superTrackedID) | 637 print('|cFF00FFFFRefreshQuestsForMap|r', mapID, GetMapNameByID(mapID), superTrackedID) |
648 self.fullSearch = true | 638 self.fullSearch = true |
649 for i = 1, MC_GetNumZones(mapID) do | 639 for i = 1, MC_GetNumZones(mapID) do |
650 local submapID, name, depth = MC_GetZoneInfo(mapID, i) | 640 local submapID, name, depth = MC_GetZoneInfo(mapID, i) |
651 self:GetPinsForMap(submapID) | 641 self:RefreshData(submapID) |
652 end | 642 end |
653 self.fullSearch = nil | 643 self.fullSearch = nil |
654 elseif QuestsByZone[mapID] then | 644 elseif QuestsByZone[mapID] then |
655 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID) | 645 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID) |
656 local quest = QuestsByZone[mapID] | 646 local quest = QuestsByZone[mapID] |
658 if taskInfo and #taskInfo >= 1 then | 648 if taskInfo and #taskInfo >= 1 then |
659 print('|cFF00FFFFRefreshQuestsForMap|r', mapID, GetMapNameByID(mapID), #taskInfo) | 649 print('|cFF00FFFFRefreshQuestsForMap|r', mapID, GetMapNameByID(mapID), #taskInfo) |
660 wipe(QuestsByZone[mapID]) | 650 wipe(QuestsByZone[mapID]) |
661 ZoneInfo[mapID] = taskInfo | 651 ZoneInfo[mapID] = taskInfo |
662 for taskID, info in pairs(taskInfo) do | 652 for taskID, info in pairs(taskInfo) do |
653 print('-', taskID) | |
663 local questID = info.questId | 654 local questID = info.questId |
664 | |
665 info.mapID = mapID | 655 info.mapID = mapID |
666 QuestsByZone[mapID][questID] = self:GetPinByQuestID(questID, info) | 656 local questPOI = self:AcquirePin(questID, mapID) |
657 local hasUpdate, isPending = questPOI:RefreshData(taskInfo) | |
658 self.hasUpdate = (self.hasUpdate or hasUpdate) | |
659 self.isPending = (self.isPending or isPending) | |
667 numQuests = numQuests + 1 | 660 numQuests = numQuests + 1 |
668 end | 661 end |
669 end | 662 end |
670 end | 663 end |
671 end | 664 |
672 | 665 print(' hasUpdate:', self.hasUpdate, 'isPending:', self.isPending, 'timer:', self.OnNext) |
673 -- create or update the pin using the given questID and C_TaskQuest results | 666 if self.hasUpdate then |
674 function WorldQuests:GetPinByQuestID (questID, taskInfo) | 667 self.OnNext = self.OnNext or C_Timer.NewTimer(0.25, function() |
675 | 668 self:Refresh(true) |
676 local questTitle, rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality, _ | 669 self.OnNext = nil |
677 local pin = self:AcquirePin(questID, taskInfo) | 670 end) |
678 | 671 end |
679 if pin.isNew then | |
680 if not hasNewQuestPins then | |
681 print('triggering new quest pins event') | |
682 end | |
683 | |
684 hasNewQuestPins = true | |
685 end | |
686 | |
687 if not HaveQuestData(questID) then | |
688 print('|cFFFF4400Retrieval failed.') | |
689 TQ_RequestPreloadRewardData(questID) | |
690 hasPendingQuestData = true | |
691 else | |
692 wqprint('|cFF00FF88Quest Data Received|r') | |
693 pin.mapID = pin.mapID or C_TaskQuest.GetQuestZoneID(questID) | |
694 | |
695 -- set reward category | |
696 local numRewards = GetNumQuestLogRewards(questID) | |
697 local numCurrency = GetNumQuestLogRewardCurrencies(questID) | |
698 local money = GetQuestLogRewardMoney(questID) | |
699 if numRewards >= 1 then | |
700 rewardType, rewardIcon, rewardCount, rewardName, itemID = ParseItemReward(questID) | |
701 elseif numCurrency >= 1 then | |
702 rewardName, rewardIcon, rewardCount = GetQuestLogRewardCurrencyInfo(1, questID) | |
703 rewardType = REWARD_CURRENCY | |
704 elseif money >= 1 then | |
705 rewardIcon = ICON_MONEY | |
706 rewardName = GetMoneyString(money) | |
707 rewardType = REWARD_CASH | |
708 end | |
709 rewardStyle = POI_REWARD_TYPE[rewardType] or POI_DEFAULT_TYPE | |
710 | |
711 pin.itemNumber = rewardCount or pin.itemNumber | |
712 pin.rewardType = rewardType or REWARD_ITEM | |
713 pin.style = rewardStyle | |
714 QuestsByID[questID] = pin | |
715 | |
716 -- title, faction, capped state | |
717 local questTitle, factionID, capped = TQ_GetQuestInfoByQuestID(questID) | |
718 if factionID then | |
719 QuestsByFaction[factionID] = QuestsByFaction[factionID] or {} | |
720 QuestsByFaction[factionID][questID] = pin | |
721 end | |
722 pin.factionID = factionID | |
723 pin.capped = capped | |
724 | |
725 -- set tag details | |
726 local tagID, tagName, worldQuestType, rarity, isElite, tradeskillLineIndex = GetQuestTagInfo(questID); | |
727 local tagAtlas | |
728 if worldQuestType == LE_QUEST_TAG_TYPE_PET_BATTLE then | |
729 tagAtlas = "worldquest-icon-petbattle" | |
730 elseif worldQuestType == LE_QUEST_TAG_TYPE_PVP then | |
731 tagAtlas = "worldquest-icon-pvp-ffa" | |
732 elseif worldQuestType == LE_QUEST_TAG_TYPE_PROFESSION then | |
733 local id = tradeskillLineIndex and select(7, GetProfessionInfo(tradeskillLineIndex)) | |
734 if id then | |
735 tagAtlas = WORLD_QUEST_ICONS_BY_PROFESSION[id] | |
736 end | |
737 elseif worldQuestType == LE_QUEST_TAG_TYPE_DUNGEON then | |
738 tagAtlas = "worldquest-icon-dungeon" | |
739 end | |
740 | |
741 pin.tagID = tagID | |
742 pin.tagName = tagName | |
743 pin.worldQuestType = worldQuestType | |
744 pin.isElite = isElite | |
745 pin.tradeskillLineIndex = tradeskillLineIndex | |
746 pin.rarity = rarity | |
747 pin.tagAtlas = tagAtlas | |
748 | |
749 -- flag unresolved info | |
750 if not (rewardIcon and rewardName) then | |
751 if not pin.isPending then | |
752 pin.isPending = true | |
753 TQ_RequestPreloadRewardData (questID) | |
754 pin.rewardType = pin.rewardType or REWARD_ITEM | |
755 pin.style = pin.style or POI_REWARD_TYPE[REWARD_ITEM] | |
756 | |
757 if not hasPendingQuestData then | |
758 hasPendingQuestData = true | |
759 PlaySoundKitID(229) | |
760 end | |
761 --WorldPlan:print('|cFFFFFF00'..tostring(pin.title)..'|r waiting on texture info') | |
762 end | |
763 else | |
764 if (rewardIcon and rewardName) then | |
765 --WorldPlan:print('|cFF00FF00'..tostring(pin.title)..'|r has info', rewardIcon, rewardName) | |
766 pin.hasUpdate = true | |
767 end | |
768 pin.isPending = nil | |
769 end | |
770 | |
771 pin.title = questTitle or "|cFFFF0000Retrieving..." | |
772 pin.itemTexture = rewardIcon or pin.itemTexture | |
773 pin.itemName = rewardName or pin.itemName | |
774 | |
775 qprint(' |cFF00FFFF'..questID..'|r:->', (HaveQuestData(questID) and "|cFF00FF00HaveQuestData" or "-"), (C_TaskQuest.IsActive(questID) and "|cFF88FF00IsActive|r" or "")) | |
776 qprint(' ', pin.title, pin.itemTexture, 'rewardType:', pin.rewardType, 'tag:', pin.tagID, 'style', pin.style ) | |
777 end | |
778 return QuestsByID[questID] | |
779 end | 672 end |
780 | 673 |
781 function WorldQuests:Refresh(forced) | 674 function WorldQuests:Refresh(forced) |
782 local print = wqprint | 675 local print = wqprint |
783 print('|cFF00FF88'..tostring(self)..':Refresh()|r') | 676 print('|cFF00FF88'..tostring(self)..':Refresh()|r') |
1169 if numQuests >= 1 then | 1062 if numQuests >= 1 then |
1170 numHeaders = numHeaders + 1 | 1063 numHeaders = numHeaders + 1 |
1171 local button = blocks[numHeaders] | 1064 local button = blocks[numHeaders] |
1172 if not blocks[numHeaders] then | 1065 if not blocks[numHeaders] then |
1173 button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, WorldMapScrollFrame, 'WorldPlanFilterPin') | 1066 button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, WorldMapScrollFrame, 'WorldPlanFilterPin') |
1067 for k,v in pairs(info)do print(k,v) end | |
1174 button.iconBorder:SetTexture(info.fill or POI_BORDER_FILL) | 1068 button.iconBorder:SetTexture(info.fill or POI_BORDER_FILL) |
1175 button.iconBorder:SetMask(info.mask or POI_BORDER_MASK) | 1069 button.iconBorder:SetMask(info.mask or POI_BORDER_MASK) |
1176 button.iconBorder:SetDesaturated(info.desaturated) | 1070 button.iconBorder:SetDesaturated(info.desaturated) |
1177 button.supertrackBorder:SetTexture(info.fill or POI_BORDER_FILL) | 1071 button.supertrackBorder:SetTexture(info.fill or POI_BORDER_FILL) |
1178 button.supertrackBorder:SetMask(info.mask or POI_BORDER_MASK) | 1072 button.supertrackBorder:SetMask(info.mask or POI_BORDER_MASK) |
1218 | 1112 |
1219 self.icon:ClearAllPoints() | 1113 self.icon:ClearAllPoints() |
1220 self.icon:SetTexture(info.texture) | 1114 self.icon:SetTexture(info.texture) |
1221 self.icon:SetAllPoints(self) | 1115 self.icon:SetAllPoints(self) |
1222 self.supertrackBorder:Hide() | 1116 self.supertrackBorder:Hide() |
1223 self.label:SetText(numQuests) | 1117 self.count:SetText(numQuests) |
1224 self:Show() | 1118 self:Show() |
1225 end | 1119 end |
1226 | 1120 |
1227 | 1121 |
1228 self.itemTexture = self.texture | 1122 self.itemTexture = self.texture |
1323 SetTimedCallbackForAllPins(0, function(self) self.FadeIn:Play() self.FlashIn:Play() end) | 1217 SetTimedCallbackForAllPins(0, function(self) self.FadeIn:Play() self.FlashIn:Play() end) |
1324 SetTimedCallbackForAllPins(5, function(self) self.PendingFade:Play() end) | 1218 SetTimedCallbackForAllPins(5, function(self) self.PendingFade:Play() end) |
1325 SetTimedCallbackForAllPins(8, function(self) self.PendingFade:Stop() end) | 1219 SetTimedCallbackForAllPins(8, function(self) self.PendingFade:Stop() end) |
1326 end | 1220 end |
1327 --%end-debug% | 1221 --%end-debug% |
1328 | |
1329 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do | |
1330 QuestsByZone[mapID] = {} | |
1331 end | |
1332 for index, color in pairs(ITEM_QUALITY_COLORS) do | |
1333 POI_REWARD_TYPE[index] = { | |
1334 r = color.r, g = color.g, b = color.b, | |
1335 hex = color.hex, | |
1336 } | |
1337 end |