Nenue@0
|
1 -- WorldPlan.lua
|
Nenue@0
|
2 -- Created: 8/16/2016 8:19 AM
|
Nenue@0
|
3 -- %file-revision%
|
Nenue@0
|
4
|
Nenue@30
|
5 local addonName, db = ...
|
Nenue@0
|
6
|
Nenue@29
|
7 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark"
|
Nenue@29
|
8 local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up"
|
Nenue@29
|
9
|
Nenue@29
|
10 local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background"
|
Nenue@29
|
11 local POI_BORDER_FILL = "Interface\\BUTTONS\\YELLOWORANGE64"
|
Nenue@29
|
12 local POI_BORDER_BLUE = "Interface\\BUTTONS\\GRADBLUE"
|
Nenue@29
|
13 local POI_BORDER_RED = "Interface\\BUTTONS\\RedGrad64"
|
Nenue@29
|
14 local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64"
|
Nenue@29
|
15 local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64"
|
Nenue@29
|
16
|
Nenue@29
|
17 WorldPlanCore = {
|
Nenue@29
|
18 defaults = {},
|
Nenue@30
|
19 modules = {},
|
Nenue@30
|
20 }
|
Nenue@30
|
21 WorldPlanQuestsMixin = {
|
Nenue@30
|
22 QuestsByZone = {},
|
Nenue@30
|
23 QuestsByID = {},
|
Nenue@30
|
24 freePins = {},
|
Nenue@29
|
25 }
|
Nenue@0
|
26 WorldPlanPOIMixin = {}
|
Nenue@30
|
27 WorldPlanFilterPinMixin = setmetatable({ QuestsByID = {}, freePins = {} }, {__tostring = function() return 'QuestHandler' end})
|
Nenue@0
|
28 local WorldPlanFlightMapMixin = setmetatable({}, {__tostring = function() return 'FlightMapHandler' end})
|
Nenue@30
|
29 local WorldQuests = WorldPlanQuestsMixin
|
Nenue@30
|
30
|
Nenue@0
|
31
|
Nenue@0
|
32 local WorldPlan = WorldPlanCore
|
Nenue@0
|
33 local QuestPOI = WorldPlanPOIMixin
|
Nenue@0
|
34 local FilterPin = WorldPlanFilterPinMixin
|
Nenue@0
|
35 local WP_VERSION = "1.0"
|
Nenue@0
|
36
|
Nenue@9
|
37 local db
|
Nenue@0
|
38 local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end
|
Nenue@7
|
39 local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end
|
Nenue@7
|
40 local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end
|
Nenue@9
|
41 local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end
|
Nenue@9
|
42 local fbprint = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or function() end
|
Nenue@7
|
43
|
Nenue@0
|
44 local wipe, tremove, tinsert, pairs, floor, tContains = table.wipe, table.remove, table.insert, pairs, floor, tContains
|
Nenue@0
|
45 local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented
|
Nenue@29
|
46 local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID
|
Nenue@0
|
47 local TQ_IsActive = C_TaskQuest.IsActive
|
Nenue@0
|
48 local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS
|
Nenue@0
|
49 local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters
|
Nenue@0
|
50 local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest
|
Nenue@0
|
51 local GameTooltip = GameTooltip
|
Nenue@0
|
52 local GetItemIcon = GetItemIcon
|
Nenue@0
|
53
|
Nenue@0
|
54
|
Nenue@0
|
55 local GetMapInfo, QuestPOIGetIconInfo = GetMapInfo, QuestPOIGetIconInfo
|
Nenue@0
|
56 local GetQuestTagInfo, HaveQuestData = GetQuestTagInfo, HaveQuestData
|
Nenue@0
|
57 local GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, GetQuestLogRewardMoney = GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, GetQuestLogRewardMoney
|
Nenue@0
|
58 local GetQuestLogRewardInfo, GetQuestLogRewardCurrencyInfo, GetMoneyString = GetQuestLogRewardInfo, GetQuestLogRewardCurrencyInfo, GetMoneyString
|
Nenue@0
|
59
|
Nenue@0
|
60 local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID
|
Nenue@0
|
61 local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo
|
Nenue@0
|
62
|
Nenue@0
|
63
|
Nenue@0
|
64 -- default color templates
|
Nenue@0
|
65 local ARTIFACT_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT]
|
Nenue@0
|
66 local MONEY_COLOR = {hex ='|cFFFFFF00', r=1, g=1, b=0}
|
Nenue@0
|
67 local COMMON_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON]
|
Nenue@29
|
68 local DEFAULT_TYPE = {
|
Nenue@0
|
69 a = 1,
|
Nenue@0
|
70 r = 1, g = 1, b = 1,
|
Nenue@0
|
71 x = 0, y = 0,
|
Nenue@0
|
72 desaturated = true,
|
Nenue@27
|
73 pinMask = POI_BORDER_MASK,
|
Nenue@27
|
74 rewardMask = POI_BORDER_MASK,
|
Nenue@0
|
75 texture = POI_BORDER_FILL,
|
Nenue@0
|
76 continent = {
|
Nenue@30
|
77 PinSize = 14,
|
Nenue@30
|
78 Border = 2,
|
Nenue@30
|
79 TrackingBorder = 1,
|
Nenue@0
|
80 TagSize = 6,
|
Nenue@30
|
81 TimeleftStage = 0,
|
Nenue@27
|
82 showNumber = true,
|
Nenue@30
|
83 numberFontObject = 'WorldPlanFont'
|
Nenue@0
|
84 },
|
Nenue@0
|
85 zone = {
|
Nenue@0
|
86 PinSize = 22,
|
Nenue@0
|
87 Border = 3,
|
Nenue@0
|
88 TrackingBorder = 2,
|
Nenue@0
|
89 TagSize = 12,
|
Nenue@0
|
90 TimeleftStage = 3,
|
Nenue@27
|
91 showNumber = true,
|
Nenue@30
|
92 numberFontObject = 'WorldPlanNumberFontThin'
|
Nenue@0
|
93 },
|
Nenue@0
|
94 minimized = {
|
Nenue@0
|
95 PinSize = 4,
|
Nenue@30
|
96 Border = 0,
|
Nenue@30
|
97 TrackingBorder = 1,
|
Nenue@0
|
98 NoIcon = true,
|
Nenue@0
|
99 TimeleftStage = 1,
|
Nenue@27
|
100 showNumber = false,
|
Nenue@0
|
101 }
|
Nenue@0
|
102 }
|
Nenue@29
|
103
|
Nenue@29
|
104
|
Nenue@0
|
105 local POI_FILTER_STYLE = setmetatable({
|
Nenue@0
|
106 continentBorder = 2,
|
Nenue@0
|
107 zoneBorder = 2,
|
Nenue@29
|
108 }, {__index = DEFAULT_TYPE})
|
Nenue@0
|
109
|
Nenue@9
|
110
|
Nenue@9
|
111 local defaults = {
|
Nenue@9
|
112 defaultPinStyle = POI_DEFAULT_TYPE,
|
Nenue@9
|
113 rewardStyle = POI_REWARD_TYPE,
|
Nenue@9
|
114 filterStyle = POI_FILTER_STYLE,
|
Nenue@27
|
115 ShowAllProfessionQuests = false,
|
Nenue@9
|
116 DisplayContinentSummary = true,
|
Nenue@9
|
117 DisplayContinentPins = true,
|
Nenue@9
|
118 NotifyWhenNewQuests = true,
|
Nenue@9
|
119 EnablePins = true,
|
Nenue@9
|
120 FadeWhileGrouped = true,
|
Nenue@9
|
121 }
|
Nenue@9
|
122
|
Nenue@0
|
123 -- Summary header structure
|
Nenue@29
|
124
|
Nenue@29
|
125 local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD
|
Nenue@29
|
126 local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER
|
Nenue@29
|
127 local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT
|
Nenue@29
|
128 local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES
|
Nenue@29
|
129 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS
|
Nenue@29
|
130
|
Nenue@29
|
131
|
Nenue@29
|
132 local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP
|
Nenue@29
|
133 local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE
|
Nenue@29
|
134 local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON
|
Nenue@29
|
135 local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION
|
Nenue@29
|
136 local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL
|
Nenue@0
|
137 local POI_FILTER_OPTIONS = {
|
Nenue@0
|
138 { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" },
|
Nenue@0
|
139 { filterKey= 'rewardType', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" },
|
Nenue@29
|
140 { filterKey= 'rewardType', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\ICONS\\inv_misc_elvencoins" },
|
Nenue@0
|
141 { filterKey= 'rewardType', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" },
|
Nenue@29
|
142 { filterKey= 'rewardType', filterValue = REWARD_REAGENT, label = 'Materials', texture = 1417744 },
|
Nenue@29
|
143 { filterKey= 'rewardType', filterValue = REWARD_CASH, label = 'Gold', texture = ICON_MONEY },
|
Nenue@0
|
144 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 },
|
Nenue@0
|
145 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", },
|
Nenue@0
|
146 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", },
|
Nenue@9
|
147 { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", },
|
Nenue@0
|
148 }
|
Nenue@8
|
149 WorldPlanCore.BrokenIsleID = BROKEN_ISLES_ID
|
Nenue@8
|
150 WorldPlanCore.FilterStyle = POI_FILTER_STYLE
|
Nenue@8
|
151
|
Nenue@9
|
152 WorldPlanCore.FilterOptions = {}
|
Nenue@14
|
153 WorldPlanCore.UsedFilters = {}
|
Nenue@0
|
154
|
Nenue@9
|
155
|
Nenue@9
|
156 -- operating flags
|
Nenue@9
|
157 local superTrackedID
|
Nenue@9
|
158 local currentMapName
|
Nenue@9
|
159 local hasNewQuestPins
|
Nenue@9
|
160 local isContinentMap
|
Nenue@0
|
161 local numPins = 0
|
Nenue@9
|
162 local FilterInclusions = {rewardType = {}, worldQuestType = {}, factionID = {}}
|
Nenue@1
|
163 local NotificationTypes = {}
|
Nenue@0
|
164 local ZoneInfo = {}
|
Nenue@0
|
165 local SummaryHeaders = {}
|
Nenue@0
|
166
|
Nenue@0
|
167 local FreePins = {}
|
Nenue@0
|
168 local NumPinFrames = 1
|
Nenue@0
|
169
|
Nenue@0
|
170 local hasPendingQuestData
|
Nenue@0
|
171 local notifyPlayed
|
Nenue@0
|
172 local scanner, wmtt, WorldMapPOIFrame
|
Nenue@0
|
173
|
Nenue@0
|
174
|
Nenue@0
|
175 local tasksQueue = {}
|
Nenue@0
|
176 local function OnNext (func)
|
Nenue@0
|
177 if #tasksQueue == 0 then
|
Nenue@0
|
178 _G.WorldPlan:SetScript('OnUpdate', function()
|
Nenue@0
|
179 local func = tremove(tasksQueue, 1)
|
Nenue@0
|
180 if func then
|
Nenue@0
|
181 func()
|
Nenue@0
|
182 end
|
Nenue@0
|
183 if #tasksQueue == 0 then
|
Nenue@0
|
184 _G.WorldPlan:SetScript('OnUpdate', nil)
|
Nenue@0
|
185 end
|
Nenue@0
|
186 end)
|
Nenue@0
|
187 end
|
Nenue@27
|
188 print('inserting task #', #tasksQueue+1, func)
|
Nenue@0
|
189 tinsert(tasksQueue, func)
|
Nenue@0
|
190 end
|
Nenue@0
|
191
|
Nenue@0
|
192 -- update a masked texture without messing up its blending mask
|
Nenue@0
|
193 local SetMaskedTexture = function(region, file, mask)
|
Nenue@0
|
194 mask = mask or POI_BORDER_MASK
|
Nenue@0
|
195 region:SetMask(nil)
|
Nenue@0
|
196 region:SetTexture(file)
|
Nenue@0
|
197 region:SetMask(mask)
|
Nenue@0
|
198 end
|
Nenue@0
|
199
|
Nenue@0
|
200 -- tracking menu toggler
|
Nenue@0
|
201 local DropDown_OnClick = function(self)
|
Nenue@0
|
202 local key = self.value
|
Nenue@0
|
203 if key then
|
Nenue@0
|
204 if WorldPlanData[key] then
|
Nenue@0
|
205 WorldPlanData[key] = nil
|
Nenue@0
|
206 else
|
Nenue@0
|
207 WorldPlanData[key] = true
|
Nenue@0
|
208 end
|
Nenue@0
|
209 end
|
Nenue@9
|
210 WorldPlan:RefreshAll()
|
Nenue@0
|
211 end
|
Nenue@0
|
212
|
Nenue@0
|
213 function WorldPlan:print(...)
|
Nenue@0
|
214 local msg
|
Nenue@0
|
215 for i = 1, select('#', ...) do
|
Nenue@0
|
216 msg = (msg and (msg .. ' ') or '') .. tostring(select(i, ...))
|
Nenue@0
|
217 end
|
Nenue@0
|
218 DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FFWorldPlan|r: " .. msg)
|
Nenue@0
|
219 end
|
Nenue@0
|
220
|
Nenue@30
|
221 local current_type_owner
|
Nenue@30
|
222 function WorldPlan:AddHandler (frame, defaults)
|
Nenue@30
|
223 print('|cFFFFFF00'..self:GetName()..':AddHandler()', frame:GetName())
|
Nenue@30
|
224 tinsert(self.modules, frame)
|
Nenue@30
|
225 self.defaults[frame] = defaults
|
Nenue@30
|
226 frame.GetTypeInfo = function(frame, typeID)
|
Nenue@30
|
227 return self:GetTypeInfo(frame, typeID)
|
Nenue@30
|
228 end
|
Nenue@30
|
229 end
|
Nenue@30
|
230
|
Nenue@0
|
231 function WorldPlan:OnLoad ()
|
Nenue@29
|
232
|
Nenue@29
|
233 self.Types = setmetatable({}, {
|
Nenue@29
|
234 __newindex = function(t, k, v)
|
Nenue@29
|
235 if type(v) == 'table' then
|
Nenue@30
|
236 print('adding owner', k)
|
Nenue@30
|
237 v = setmetatable(v, {
|
Nenue@30
|
238 __newindex = function(t2,k2,v2)
|
Nenue@30
|
239 if type(v2) == 'table' then
|
Nenue@30
|
240 print('adding type', k2)
|
Nenue@30
|
241 v2 = setmetatable(v2, {__index = function(t3,k3)
|
Nenue@30
|
242 --print('##deferring to default key', k3)
|
Nenue@30
|
243 return DEFAULT_TYPE[k3]
|
Nenue@30
|
244 end})
|
Nenue@30
|
245 end
|
Nenue@30
|
246 rawset(t2,k2,v2)
|
Nenue@29
|
247 end})
|
Nenue@29
|
248 end
|
Nenue@29
|
249 rawset(t,k,v)
|
Nenue@29
|
250 end
|
Nenue@29
|
251 })
|
Nenue@29
|
252
|
Nenue@30
|
253 self.Types[self] = {}
|
Nenue@29
|
254
|
Nenue@29
|
255 for index, color in pairs(ITEM_QUALITY_COLORS) do
|
Nenue@30
|
256 self:AddTypeInfo(self, index, { r = color.r, g = color.g, b = color.b, hex = color.hex, })
|
Nenue@29
|
257 end
|
Nenue@29
|
258
|
Nenue@0
|
259 WorldPlan = self
|
Nenue@0
|
260 scanner = _G.WorldPlanTooltip
|
Nenue@0
|
261 wmtt = _G.WorldMapTooltip
|
Nenue@0
|
262 WorldMapPOIFrame = _G.WorldMapPOIFrame
|
Nenue@0
|
263
|
Nenue@0
|
264 WorldPlan:print('v'..WP_VERSION)
|
Nenue@0
|
265
|
Nenue@0
|
266 self:RegisterEvent("QUESTLINE_UPDATE")
|
Nenue@0
|
267 self:RegisterEvent("QUEST_LOG_UPDATE")
|
Nenue@0
|
268 self:RegisterEvent("WORLD_MAP_UPDATE")
|
Nenue@0
|
269 self:RegisterEvent("WORLD_QUEST_COMPLETED_BY_SPELL")
|
Nenue@0
|
270 self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED")
|
Nenue@0
|
271 self:RegisterEvent("SKILL_LINES_CHANGED")
|
Nenue@0
|
272 self:RegisterEvent("ARTIFACT_XP_UPDATE")
|
Nenue@0
|
273 self:RegisterEvent("ADDON_LOADED")
|
Nenue@27
|
274 self:SetParent(WorldMapFrame)
|
Nenue@0
|
275 end
|
Nenue@0
|
276
|
Nenue@27
|
277 function WorldPlan:OnShow()
|
Nenue@27
|
278 print(self:GetName()..':OnShow()')
|
Nenue@27
|
279 if self.isStale then
|
Nenue@30
|
280 self:Refresh()
|
Nenue@27
|
281 end
|
Nenue@27
|
282
|
Nenue@27
|
283 end
|
Nenue@27
|
284
|
Nenue@0
|
285 function WorldPlan:OnEvent (event, ...)
|
Nenue@0
|
286 print()
|
Nenue@27
|
287 print(event, self.initialized)
|
Nenue@0
|
288 if event == 'ADDON_LOADED' then
|
Nenue@0
|
289 local addon = ...
|
Nenue@0
|
290 if addon == "Blizzard_FlightMap" then
|
Nenue@0
|
291 print('do mixin junk')
|
Nenue@0
|
292 self.OnFlightMapLoaded()
|
Nenue@0
|
293
|
Nenue@0
|
294 end
|
Nenue@0
|
295 if IsLoggedIn() and not self.initialized then
|
Nenue@0
|
296 self:Setup()
|
Nenue@0
|
297 end
|
Nenue@0
|
298 elseif event == 'WORLD_MAP_UPDATE' then
|
Nenue@9
|
299 self.currentMapID = GetCurrentMapAreaID()
|
Nenue@30
|
300 print('|cFFFF4400currentMapID =', self.currentMapID)
|
Nenue@30
|
301 self:Refresh()
|
Nenue@27
|
302 else
|
Nenue@27
|
303 for i, module in ipairs(self.modules) do
|
Nenue@27
|
304 if module.OnEvent then
|
Nenue@27
|
305 print('forwarding to', tostring(module))
|
Nenue@27
|
306 module:OnEvent(event, ...)
|
Nenue@27
|
307 end
|
Nenue@0
|
308 end
|
Nenue@0
|
309 end
|
Nenue@0
|
310 end
|
Nenue@0
|
311
|
Nenue@0
|
312
|
Nenue@0
|
313 function WorldPlan:Setup ()
|
Nenue@0
|
314 if not WorldPlanData then
|
Nenue@0
|
315 WorldPlanData = {key = 0 }
|
Nenue@0
|
316 end
|
Nenue@0
|
317 WorldPlanData.key = (WorldPlanData.key or 0) + 1
|
Nenue@0
|
318 self.db = WorldPlanData
|
Nenue@9
|
319 self.db.WorldQuests = self.db.WorldQuests or {}
|
Nenue@9
|
320 db = self.db
|
Nenue@9
|
321 for k,v in pairs(defaults) do
|
Nenue@18
|
322 --[===[@non-debug@
|
Nenue@18
|
323 if not db[k] then
|
Nenue@18
|
324 db[k] = v
|
Nenue@18
|
325 end
|
Nenue@18
|
326
|
Nenue@18
|
327 --@end-non-debug@]===]
|
Nenue@18
|
328 --@debug@
|
Nenue@9
|
329 db[k] = v
|
Nenue@18
|
330 --@end-debug@
|
Nenue@9
|
331 end
|
Nenue@9
|
332
|
Nenue@9
|
333 self.currentMapID = GetCurrentMapAreaID()
|
Nenue@0
|
334
|
Nenue@0
|
335 for i, module in ipairs(self.modules) do
|
Nenue@9
|
336 module.db = self.db
|
Nenue@0
|
337 if module.Setup then module:Setup() end
|
Nenue@0
|
338 if not module.RegisterEvent then
|
Nenue@0
|
339 module.RegisterEvent = self.RegisterEvent
|
Nenue@0
|
340 end
|
Nenue@0
|
341 end
|
Nenue@0
|
342 self.initialized = true
|
Nenue@0
|
343
|
Nenue@9
|
344 hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize)
|
Nenue@0
|
345 end
|
Nenue@0
|
346
|
Nenue@30
|
347 function WorldPlan:AddTypeInfo(owner, id, info)
|
Nenue@30
|
348 self.Types[owner] = self.Types[owner] or {}
|
Nenue@30
|
349 self.Types[owner][id] = info
|
Nenue@30
|
350 print('Type('..owner:GetName()..')('..id..') = '.. tostring(info))
|
Nenue@30
|
351 end
|
Nenue@30
|
352
|
Nenue@30
|
353 function WorldPlan:GetTypeInfo(owner, typeID)
|
Nenue@29
|
354 local info, extraInfo
|
Nenue@30
|
355 if not owner then
|
Nenue@30
|
356 --print('## deferring to default type list')
|
Nenue@30
|
357 else
|
Nenue@30
|
358 --print('## pulling for', owner:GetName(), 'id =', typeID)
|
Nenue@30
|
359 end
|
Nenue@30
|
360
|
Nenue@30
|
361 owner = owner or self
|
Nenue@30
|
362 if (not typeID) or (not self.Types[owner][typeID]) then
|
Nenue@30
|
363 --print('## sending list default')
|
Nenue@29
|
364 info = DEFAULT_TYPE
|
Nenue@29
|
365 else
|
Nenue@30
|
366 --print('## sent list definition', typeID)
|
Nenue@30
|
367 info = self.Types[owner][typeID]
|
Nenue@29
|
368 end
|
Nenue@29
|
369
|
Nenue@29
|
370 if isContinentMap then
|
Nenue@29
|
371 extraInfo = info.continent
|
Nenue@30
|
372 --print('### continent subtype', extraInfo)
|
Nenue@29
|
373 else
|
Nenue@29
|
374 extraInfo = info.zone
|
Nenue@29
|
375
|
Nenue@30
|
376 --print('### zone subtype', extraInfo)
|
Nenue@29
|
377 end
|
Nenue@29
|
378 return info, extraInfo
|
Nenue@29
|
379 end
|
Nenue@29
|
380
|
Nenue@29
|
381 do
|
Nenue@29
|
382 local timeStates = {
|
Nenue@29
|
383 {maxSeconds = 60,
|
Nenue@29
|
384 r=1, g=0.25, b =0, format = function (minutes) return '|cFFFF4400'.. minutes .. 'm' end,
|
Nenue@29
|
385 },
|
Nenue@29
|
386 {maxSeconds = 240,
|
Nenue@29
|
387 r=1, g=.5, b=0, format = function(minutes) return '|cFFFF4400'.. floor(minutes/60) .. 'h' end,
|
Nenue@29
|
388 },
|
Nenue@29
|
389 {maxSeconds = 1440,
|
Nenue@29
|
390 r=1, g=1, b=0, format = function(minutes) return '|cFFFFFF00'.. floor(minutes/60) .. 'h' end,
|
Nenue@29
|
391 },
|
Nenue@29
|
392 {maxSeconds = 10081,
|
Nenue@29
|
393 r=0, g=1, b=0,
|
Nenue@29
|
394 }, -- 7 days + 1 minute
|
Nenue@29
|
395 }
|
Nenue@29
|
396 -- Generates a timeleft string
|
Nenue@29
|
397 function WorldPlan:GetTimeInfo(timeLeft, limit)
|
Nenue@29
|
398 limit = limit or #timeStates
|
Nenue@29
|
399 for index = 1, limit do
|
Nenue@29
|
400 local state = timeStates[index]
|
Nenue@29
|
401 if timeLeft <= state.maxSeconds then
|
Nenue@29
|
402 local text
|
Nenue@29
|
403 if state.format then
|
Nenue@29
|
404 text = state.format(timeLeft)
|
Nenue@29
|
405 end
|
Nenue@29
|
406 return text, index
|
Nenue@29
|
407 end
|
Nenue@29
|
408 end
|
Nenue@29
|
409 return nil, nil
|
Nenue@29
|
410 end
|
Nenue@29
|
411 end
|
Nenue@29
|
412
|
Nenue@30
|
413 function WorldPlan:Refresh (forced)
|
Nenue@30
|
414 print('|cFFFFFF00'..self:GetName()..':Refresh()|r forced:', forced, 'init:', self.initialized)
|
Nenue@9
|
415 if not self.initialized then
|
Nenue@9
|
416 return
|
Nenue@9
|
417 end
|
Nenue@9
|
418
|
Nenue@9
|
419 POI_DEFAULT_TYPE = db.defaultPinStyle
|
Nenue@9
|
420 POI_REWARD_TYPE = db.rewardStyle
|
Nenue@9
|
421 POI_FILTER_STYLE = db.filterStyle
|
Nenue@9
|
422
|
Nenue@9
|
423
|
Nenue@9
|
424 for i, module in ipairs(self.modules) do
|
Nenue@9
|
425 if module.Reset then
|
Nenue@9
|
426 print(module, 'Reset()')
|
Nenue@9
|
427 module:Reset()
|
Nenue@9
|
428 end
|
Nenue@9
|
429 end
|
Nenue@9
|
430
|
Nenue@0
|
431 for i, module in ipairs(self.modules) do
|
Nenue@0
|
432 if module.Refresh then
|
Nenue@9
|
433 print(module, 'Refresh()')
|
Nenue@0
|
434 module:Refresh()
|
Nenue@0
|
435 end
|
Nenue@0
|
436 end
|
Nenue@9
|
437
|
Nenue@9
|
438 for i, module in ipairs(self.modules) do
|
Nenue@9
|
439 if module.Cleanup then
|
Nenue@9
|
440 print(module, 'Cleanup()')
|
Nenue@9
|
441 module:Cleanup()
|
Nenue@9
|
442 end
|
Nenue@9
|
443 end
|
Nenue@0
|
444 end
|
Nenue@0
|
445 function WorldPlan:UpdateAnchors ()
|
Nenue@0
|
446 for i, module in ipairs(self.modules) do
|
Nenue@0
|
447 if module.UpdateAnchors then
|
Nenue@0
|
448 module:UpdateAnchors()
|
Nenue@0
|
449 end
|
Nenue@0
|
450 end
|
Nenue@0
|
451 end
|
Nenue@0
|
452
|
Nenue@0
|
453 -- insert visual options into the tracking button menu
|
Nenue@0
|
454 WorldPlan.OnDropDownInitialize = function (self, callback, dropType)
|
Nenue@0
|
455 if self ~= WorldMapFrameDropDown then
|
Nenue@0
|
456 return
|
Nenue@0
|
457 end
|
Nenue@9
|
458 local db = WorldPlan.db
|
Nenue@0
|
459
|
Nenue@0
|
460 local info = UIDropDownMenu_CreateInfo()
|
Nenue@0
|
461 info.text = ""
|
Nenue@0
|
462 info.isTitle = true
|
Nenue@0
|
463 UIDropDownMenu_AddButton(info)
|
Nenue@0
|
464 info.text = "|cFF00AAFFWorldPlan|r"
|
Nenue@0
|
465 info.isTitle = true
|
Nenue@0
|
466 UIDropDownMenu_AddButton(info)
|
Nenue@0
|
467 info.isTitle = nil
|
Nenue@0
|
468 info.disabled = nil
|
Nenue@0
|
469 info.keepShownOnClick = true
|
Nenue@0
|
470 info.tooltipOnButton = 1
|
Nenue@0
|
471
|
Nenue@9
|
472 info.text = "Enable"
|
Nenue@9
|
473 info.isNotRadio = true
|
Nenue@9
|
474 info.value = "EnablePins"
|
Nenue@9
|
475 info.checked = db.EnablePins
|
Nenue@9
|
476 info.tooltipTitle = "Enable World Quest Overlays"
|
Nenue@9
|
477 info.tooltipText = "Toggle the detail layers here."
|
Nenue@9
|
478 info.func = DropDown_OnClick
|
Nenue@9
|
479 UIDropDownMenu_AddButton(info)
|
Nenue@9
|
480
|
Nenue@9
|
481 info.text = "Display All Profession Quests"
|
Nenue@0
|
482 info.isNotRadio = true
|
Nenue@0
|
483 info.value = "ShowAllProfessionQuests"
|
Nenue@9
|
484 info.checked = db.ShowAllProfessionQuests
|
Nenue@0
|
485 info.tooltipTitle = "Hidden Quests"
|
Nenue@0
|
486 info.tooltipText = "Display work order and profession-related quests that are skipped by the default UI."
|
Nenue@0
|
487 info.func = DropDown_OnClick
|
Nenue@0
|
488 UIDropDownMenu_AddButton(info)
|
Nenue@0
|
489
|
Nenue@0
|
490 info.text = "Show Continent Pins"
|
Nenue@0
|
491 info.isNotRadio = true
|
Nenue@0
|
492 info.value = "DisplayContinentPins"
|
Nenue@9
|
493 info.checked = db.DisplayContinentPins
|
Nenue@0
|
494 info.tooltipTitle = "Continent Pins"
|
Nenue@0
|
495 info.tooltipText = "Display quest pins on the continent map (may get cramped)."
|
Nenue@0
|
496 info.func = DropDown_OnClick
|
Nenue@0
|
497 UIDropDownMenu_AddButton(info)
|
Nenue@0
|
498
|
Nenue@0
|
499 info.text = "Show Summary"
|
Nenue@0
|
500 info.isNotRadio = true
|
Nenue@0
|
501 info.value = "DisplayContinentSummary"
|
Nenue@0
|
502 info.tooltipTitle = "Summary Bar"
|
Nenue@0
|
503 info.tooltipText = "Display a summary of active world quests. Note: requires directly viewing Broken Isle and Dalaran maps to gain complete info."
|
Nenue@9
|
504 info.checked = db.DisplayContinentSummary
|
Nenue@9
|
505 info.func = DropDown_OnClick
|
Nenue@9
|
506 UIDropDownMenu_AddButton(info)
|
Nenue@9
|
507
|
Nenue@9
|
508 info.text = "Fade In Groups"
|
Nenue@9
|
509 info.isNotRadio = true
|
Nenue@9
|
510 info.value = "FadeWhileGrouped"
|
Nenue@9
|
511 info.tooltipTitle = "Group Fade"
|
Nenue@9
|
512 info.tooltipText = "Reduce pin alpha when grouped, so player dots are easier to see."
|
Nenue@9
|
513 info.checked = db.DisplayContinentSummary
|
Nenue@0
|
514 info.func = DropDown_OnClick
|
Nenue@0
|
515 UIDropDownMenu_AddButton(info)
|
Nenue@0
|
516 end
|
Nenue@0
|
517
|
Nenue@30
|
518 --------------------------------------------------------------------------------------------------------------------
|
Nenue@30
|
519 --------------------------------------------------------------------------------------------------------------------
|
Nenue@30
|
520
|
Nenue@30
|
521 local PinBaseIndex = 1600
|
Nenue@30
|
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
|
Nenue@30
|
523
|
Nenue@30
|
524 -- maps where we do our own anchors
|
Nenue@30
|
525 local CONTINENT_MAPS = { [BROKEN_ISLES_ID] = BROKEN_ISLES_ID, }
|
Nenue@30
|
526 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah",
|
Nenue@30
|
527 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', }
|
Nenue@30
|
528
|
Nenue@0
|
529 function WorldQuests:Setup()
|
Nenue@29
|
530
|
Nenue@29
|
531
|
Nenue@29
|
532 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
|
Nenue@30
|
533 self.QuestsByZone[mapID] = {}
|
Nenue@29
|
534 end
|
Nenue@29
|
535
|
Nenue@29
|
536
|
Nenue@0
|
537 -- refresh positions any time blizzard does so (i.e. mousewheel zoom)
|
Nenue@0
|
538 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function()
|
Nenue@9
|
539 self:Refresh(true)
|
Nenue@0
|
540 end)
|
Nenue@0
|
541
|
Nenue@0
|
542 -- hide the original world quest POIs
|
Nenue@0
|
543 hooksecurefunc("WorldMap_UpdateQuestBonusObjectives", function()
|
Nenue@0
|
544 for i = 1, NUM_WORLDMAP_TASK_POIS do
|
Nenue@0
|
545 local button = _G['WorldMapFrameTaskPOI'..i]
|
Nenue@0
|
546 if button and button.worldQuest then
|
Nenue@0
|
547 button:Hide()
|
Nenue@0
|
548 end
|
Nenue@0
|
549 end
|
Nenue@0
|
550 end)
|
Nenue@0
|
551
|
Nenue@0
|
552 end
|
Nenue@0
|
553
|
Nenue@30
|
554 local defaults = {}
|
Nenue@30
|
555 function WorldQuests:OnLoad()
|
Nenue@30
|
556 print('|cFF00FF88'..self:GetName()..':OnLoad')
|
Nenue@30
|
557
|
Nenue@30
|
558 WorldPlan:AddHandler(self, defaults)
|
Nenue@30
|
559
|
Nenue@30
|
560 local rgbWhite = {1, 1, 1}
|
Nenue@30
|
561 WorldPlan:AddTypeInfo(self, REWARD_REAGENT, { r = 0, g = 1, b = 1 })
|
Nenue@30
|
562 WorldPlan:AddTypeInfo(self, REWARD_ARTIFACT_POWER, { r = 1, g = .25, b = .5, hasNumeric = true, numberRGB = rgbWhite })
|
Nenue@30
|
563 WorldPlan:AddTypeInfo(self, REWARD_GEAR, { r = .1, g = .2, b = 1 })
|
Nenue@30
|
564 WorldPlan:AddTypeInfo(self, REWARD_CURRENCY, { r = 1, g = 1, b = 0, hasNumeric = true, numberRGB = {1,1,0}, })
|
Nenue@30
|
565 WorldPlan:AddTypeInfo(self, REWARD_CASH, { r = 0, g = 0, b = 0, })
|
Nenue@30
|
566
|
Nenue@30
|
567 for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
|
Nenue@30
|
568 self.QuestsByZone[areaID] = {}
|
Nenue@30
|
569 end
|
Nenue@30
|
570
|
Nenue@30
|
571 self:RegisterEvent('QUEST_LOG_UPDATE')
|
Nenue@30
|
572 self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
|
Nenue@30
|
573 self:RegisterEvent('SKILL_LINES_CHANGED')
|
Nenue@30
|
574
|
Nenue@30
|
575
|
Nenue@30
|
576 end
|
Nenue@30
|
577
|
Nenue@0
|
578 function WorldQuests:OnEvent (event, ...)
|
Nenue@30
|
579 local print = wqprint
|
Nenue@30
|
580 print('|cFFFFFF00'..self:GetName()..':OnEvent()'..event..'|r', GetTime(), ...)
|
Nenue@0
|
581 if event == 'QUEST_LOG_UPDATE' then
|
Nenue@0
|
582 local questID, added = ...
|
Nenue@0
|
583 if questID and added then
|
Nenue@29
|
584 local questPOI = self:AcquirePin(questID)
|
Nenue@29
|
585 self.hasUpdate, self.isPending = questPOI:RefreshData()
|
Nenue@0
|
586 else
|
Nenue@29
|
587 self:RefreshData()
|
Nenue@0
|
588 end
|
Nenue@30
|
589 print('WorldMapFrame', WorldMapFrame:IsVisible(), 'hasUpdates:', self.hasUpdate)
|
Nenue@0
|
590 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
|
Nenue@0
|
591 local questID = ...
|
Nenue@30
|
592 if questID and self.QuestsByID[questID] then
|
Nenue@30
|
593 self:ReleasePin(self.QuestsByID[questID])
|
Nenue@0
|
594 end
|
Nenue@0
|
595 elseif event == 'SKILL_LINES_CHANGED' then
|
Nenue@30
|
596 self.hasUpdate = true
|
Nenue@30
|
597 end
|
Nenue@30
|
598 end
|
Nenue@30
|
599
|
Nenue@30
|
600 function WorldQuests:OnUpdate()
|
Nenue@30
|
601 if self.hasUpdate then
|
Nenue@30
|
602 wqprint('|cFF00FF00pushing update')
|
Nenue@9
|
603 self:Refresh(true)
|
Nenue@0
|
604 end
|
Nenue@0
|
605 end
|
Nenue@30
|
606
|
Nenue@29
|
607 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
|
Nenue@29
|
608 function WorldQuests:AcquirePin (questID, mapID)
|
Nenue@30
|
609 local pin = self.QuestsByID[questID]
|
Nenue@0
|
610 local isNew = false
|
Nenue@0
|
611 if not pin then
|
Nenue@0
|
612 isNew = true
|
Nenue@0
|
613 local numFree = #self.freePins
|
Nenue@0
|
614 if numFree >= 1 then
|
Nenue@0
|
615 pin = tremove(self.freePins, numFree)
|
Nenue@0
|
616 --print('|cFF00FF00Re-using', pin:GetName())
|
Nenue@0
|
617 else
|
Nenue@0
|
618 local name = 'WorldPlanQuestMarker' .. NumPinFrames
|
Nenue@0
|
619 --print('|cFF00FF00Creating', name)
|
Nenue@0
|
620 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
|
Nenue@29
|
621
|
Nenue@0
|
622 pin:SetFrameStrata('HIGH')
|
Nenue@30
|
623 pin.GetTypeInfo = function(frame, typeID)
|
Nenue@30
|
624 return self:GetTypeInfo(typeID)
|
Nenue@30
|
625 end
|
Nenue@0
|
626 NumPinFrames = NumPinFrames + 1
|
Nenue@0
|
627 --pin.iconBorder:SetVertexColor(0,0,0,1)
|
Nenue@0
|
628 end
|
Nenue@29
|
629 pin:SetID(questID)
|
Nenue@0
|
630 pin.isNew = true
|
Nenue@0
|
631 pin.currentWidth = nil
|
Nenue@0
|
632
|
Nenue@0
|
633 -- used by TaskPOI_x scripts
|
Nenue@0
|
634 pin.questID = questID
|
Nenue@0
|
635 pin.worldQuest = true
|
Nenue@7
|
636
|
Nenue@30
|
637 self.QuestsByID[questID] = pin
|
Nenue@0
|
638 else
|
Nenue@0
|
639 --print('|cFF00FF00Using', pin:GetName())
|
Nenue@0
|
640 end
|
Nenue@29
|
641 mapID = mapID or TQ_GetQuestZoneID(questID)
|
Nenue@30
|
642 self.QuestsByZone[mapID][questID] = pin
|
Nenue@0
|
643
|
Nenue@0
|
644 return pin, isNew
|
Nenue@0
|
645 end
|
Nenue@0
|
646
|
Nenue@0
|
647 -- remove from index and add it to the recycling heap
|
Nenue@0
|
648 function WorldQuests:ReleasePin (pin)
|
Nenue@0
|
649
|
Nenue@0
|
650 local id = pin.questId
|
Nenue@0
|
651 if id then
|
Nenue@30
|
652 self.QuestsByID[id] = nil
|
Nenue@30
|
653 for i, zone in pairs(self.QuestsByZone) do
|
Nenue@0
|
654 print('-', i, zone[i])
|
Nenue@0
|
655 zone[id] = nil
|
Nenue@0
|
656 end
|
Nenue@0
|
657 end
|
Nenue@0
|
658 pin:Hide()
|
Nenue@0
|
659 pin:ClearAllPoints()
|
Nenue@0
|
660 tinsert(self.freePins, pin)
|
Nenue@0
|
661 print('|cFFFF4400Clearing out', pin:GetName(),id)
|
Nenue@0
|
662 end
|
Nenue@0
|
663
|
Nenue@0
|
664 -- create of update quest pins for a map and its underlying zones
|
Nenue@29
|
665 function WorldQuests:RefreshData (mapID)
|
Nenue@9
|
666 local print = wqprint
|
Nenue@0
|
667 mapID = mapID or GetCurrentMapAreaID()
|
Nenue@0
|
668 superTrackedID = GetSuperTrackedQuestID()
|
Nenue@0
|
669 if not mapID then
|
Nenue@0
|
670 -- info not available yet
|
Nenue@0
|
671 return
|
Nenue@0
|
672 end
|
Nenue@30
|
673
|
Nenue@30
|
674 print('|cFF00FF88'..self:GetName()..':RefreshData()|r', 'map:', mapID, 'realMap:', GetCurrentMapAreaID())
|
Nenue@30
|
675
|
Nenue@0
|
676 if mapID == BROKEN_ISLES_ID then
|
Nenue@29
|
677 self.hasUpdate = false
|
Nenue@30
|
678 print('|cFF00FFFFContinent:|r', mapID, GetMapNameByID(mapID), superTrackedID)
|
Nenue@0
|
679 self.fullSearch = true
|
Nenue@0
|
680 for i = 1, MC_GetNumZones(mapID) do
|
Nenue@0
|
681 local submapID, name, depth = MC_GetZoneInfo(mapID, i)
|
Nenue@29
|
682 self:RefreshData(submapID)
|
Nenue@0
|
683 end
|
Nenue@0
|
684 self.fullSearch = nil
|
Nenue@30
|
685 elseif self.QuestsByZone[mapID] then
|
Nenue@0
|
686 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID)
|
Nenue@0
|
687 local numQuests = 0
|
Nenue@0
|
688 if taskInfo and #taskInfo >= 1 then
|
Nenue@30
|
689 print('|cFF00FFFF Zone:|r', mapID, GetMapNameByID(mapID), #taskInfo)
|
Nenue@30
|
690 wipe(self.QuestsByZone[mapID])
|
Nenue@0
|
691 ZoneInfo[mapID] = taskInfo
|
Nenue@30
|
692 qprint('|cFFFF4400START of', GetMapNameByID(mapID))
|
Nenue@0
|
693 for taskID, info in pairs(taskInfo) do
|
Nenue@0
|
694 local questID = info.questId
|
Nenue@0
|
695 info.mapID = mapID
|
Nenue@29
|
696 local questPOI = self:AcquirePin(questID, mapID)
|
Nenue@30
|
697 local hasUpdate, isPending = questPOI:RefreshData(info)
|
Nenue@29
|
698 self.hasUpdate = (self.hasUpdate or hasUpdate)
|
Nenue@29
|
699 self.isPending = (self.isPending or isPending)
|
Nenue@0
|
700 numQuests = numQuests + 1
|
Nenue@0
|
701 end
|
Nenue@30
|
702 qprint('|cFFFF4400END of', GetMapNameByID(mapID))
|
Nenue@0
|
703 end
|
Nenue@0
|
704 end
|
Nenue@0
|
705
|
Nenue@30
|
706 if not self.fullSearch then
|
Nenue@30
|
707 print(' hasUpdate:', self.hasUpdate, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or ''))
|
Nenue@30
|
708
|
Nenue@0
|
709 end
|
Nenue@30
|
710
|
Nenue@0
|
711 end
|
Nenue@0
|
712
|
Nenue@0
|
713 function WorldQuests:Refresh(forced)
|
Nenue@9
|
714 local print = wqprint
|
Nenue@30
|
715 print('|cFF00FF88'..self:GetName()..':Refresh()|r')
|
Nenue@0
|
716 if not WorldMapPOIFrame:IsVisible() then
|
Nenue@0
|
717 return
|
Nenue@0
|
718 end
|
Nenue@9
|
719 if forced then
|
Nenue@9
|
720 self:Reset()
|
Nenue@9
|
721 end
|
Nenue@0
|
722 self:UpdateAnchors()
|
Nenue@9
|
723
|
Nenue@9
|
724 if forced then
|
Nenue@9
|
725 self:Cleanup ()
|
Nenue@9
|
726 end
|
Nenue@0
|
727 end
|
Nenue@0
|
728
|
Nenue@0
|
729 -- prepares elements for a map update
|
Nenue@0
|
730 function WorldQuests:Reset ()
|
Nenue@9
|
731 local print = wqprint
|
Nenue@30
|
732 print('|cFF00FF88'..self:GetName()..':Reset()|r')
|
Nenue@30
|
733 for questID, pin in pairs(self.QuestsByID) do
|
Nenue@0
|
734 pin.used = nil
|
Nenue@0
|
735 end
|
Nenue@0
|
736 end
|
Nenue@0
|
737
|
Nenue@0
|
738 -- update visibility states of all pins
|
Nenue@0
|
739 function WorldQuests:UpdateAnchors (submapID)
|
Nenue@9
|
740 local print = wqprint
|
Nenue@9
|
741 local db = WorldPlan.db
|
Nenue@0
|
742 local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo()
|
Nenue@0
|
743 if isMicroDungeon then
|
Nenue@0
|
744 return
|
Nenue@0
|
745 end
|
Nenue@0
|
746
|
Nenue@0
|
747 local currentMap = GetCurrentMapAreaID()
|
Nenue@0
|
748 local submapID = submapID or currentMap
|
Nenue@0
|
749
|
Nenue@9
|
750 if submapID == BROKEN_ISLES_ID and (not db.DisplayContinentPins) then
|
Nenue@0
|
751 print('not updating map for reasons')
|
Nenue@0
|
752 return
|
Nenue@0
|
753 end
|
Nenue@30
|
754 print('|cFF88FF00'..self:GetName()..':UpdateAnchors|r', submapID, GetMapNameByID(submapID), 'pin count:', numPins)
|
Nenue@0
|
755 local numZones = MC_GetNumZones(submapID)
|
Nenue@0
|
756 if numZones then
|
Nenue@0
|
757 for i = 1, numZones do
|
Nenue@0
|
758 local subMapID = MC_GetZoneInfo(submapID, i)
|
Nenue@0
|
759 self:UpdateAnchors(subMapID)
|
Nenue@0
|
760 end
|
Nenue@0
|
761 end
|
Nenue@30
|
762 local pins = self.QuestsByZone[submapID]
|
Nenue@0
|
763
|
Nenue@0
|
764 if pins then
|
Nenue@0
|
765 local hostFrame = WorldMapPOIFrame
|
Nenue@0
|
766 local mapWidth, mapHeight = hostFrame:GetSize()
|
Nenue@0
|
767 for questID, pin in pairs(pins) do
|
Nenue@30
|
768 pin.hasUpdate = true
|
Nenue@9
|
769 pin:IsShowable()
|
Nenue@9
|
770 if pin.used then
|
Nenue@9
|
771 pin:SetFrameLevel(PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins)
|
Nenue@9
|
772 print('level', PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins)
|
Nenue@0
|
773 pin:SetAnchor(WorldMapPOIFrame, currentMap, mapWidth, mapHeight)
|
Nenue@0
|
774 numPins = numPins + 1
|
Nenue@0
|
775 end
|
Nenue@0
|
776 end
|
Nenue@0
|
777 end
|
Nenue@0
|
778 end
|
Nenue@0
|
779
|
Nenue@0
|
780 -- shows, animates, or hides pins based on their current visibility flags
|
Nenue@0
|
781 local debug_show = {}
|
Nenue@0
|
782 local debug_animate = {}
|
Nenue@0
|
783 local debug_hide = {}
|
Nenue@0
|
784 function WorldQuests:Cleanup ()
|
Nenue@9
|
785 local print = wqprint
|
Nenue@9
|
786 local showQuestPOI = db.EnablePins
|
Nenue@0
|
787 print('|cFFFFFF00'..tostring(self)..':Cleanup()|r')
|
Nenue@9
|
788 local mapID = GetCurrentMapAreaID()
|
Nenue@9
|
789 isContinentMap = (mapID == BROKEN_ISLES_ID)
|
Nenue@9
|
790
|
Nenue@0
|
791 wipe(debug_show)
|
Nenue@0
|
792 wipe(debug_animate)
|
Nenue@0
|
793 wipe(debug_hide)
|
Nenue@0
|
794 -- continent or zone sizing
|
Nenue@9
|
795 local fadeGrouped = (db.FadeWhileGrouped and IsInGroup())
|
Nenue@0
|
796
|
Nenue@0
|
797 numPins = 0
|
Nenue@30
|
798 for questID, pin in pairs(self.QuestsByID) do
|
Nenue@0
|
799 -- can we show it?
|
Nenue@0
|
800 if showQuestPOI and (pin.used) then
|
Nenue@0
|
801
|
Nenue@30
|
802 pin.hasUpdate = true
|
Nenue@9
|
803 if fadeGrouped then
|
Nenue@9
|
804 pin:SetAlpha(0.25)
|
Nenue@9
|
805 else
|
Nenue@9
|
806 pin:SetAlpha(1)
|
Nenue@9
|
807 end
|
Nenue@0
|
808 -- is it a new quest?
|
Nenue@0
|
809 if pin.isNew then
|
Nenue@0
|
810 if not pin.isAnimating then
|
Nenue@0
|
811 pin.isAnimating = true
|
Nenue@0
|
812 OnNext(function()
|
Nenue@27
|
813 pin:ShowNew()
|
Nenue@0
|
814 end)
|
Nenue@0
|
815 if not notifyPlayed then
|
Nenue@1
|
816 for k,v in pairs(NotificationTypes) do
|
Nenue@1
|
817 if v[pin[k]] then
|
Nenue@1
|
818 notifyPlayed = true
|
Nenue@1
|
819 PlaySoundKitID(23404)
|
Nenue@1
|
820 end
|
Nenue@1
|
821 end
|
Nenue@0
|
822 end
|
Nenue@0
|
823 tinsert(debug_animate,questID)
|
Nenue@9
|
824 else
|
Nenue@9
|
825
|
Nenue@9
|
826 print('animating? ', questID, 'filtered:', pin.filtered)
|
Nenue@0
|
827 end
|
Nenue@1
|
828 -- trap new but animating pins here
|
Nenue@0
|
829 else
|
Nenue@0
|
830 -- hard show existing pin
|
Nenue@30
|
831 print('refresh #', questID, 'filtered:', pin.filtered, 'hasUpdate', pin.hasUpdate)
|
Nenue@30
|
832 pin:Show()
|
Nenue@0
|
833 tinsert(debug_show,questID)
|
Nenue@0
|
834 end
|
Nenue@0
|
835 else
|
Nenue@9
|
836 if pin:IsShown() then
|
Nenue@9
|
837 tinsert(debug_hide,questID)
|
Nenue@9
|
838 end
|
Nenue@9
|
839 pin.isAnimating = nil
|
Nenue@9
|
840 pin.FadeIn:Stop()
|
Nenue@0
|
841 pin:Hide()
|
Nenue@0
|
842 end
|
Nenue@0
|
843 end
|
Nenue@0
|
844 print(' adding:', table.concat(debug_animate, ',' ))
|
Nenue@9
|
845 print(' refresh:', table.concat(debug_show, ',' ))
|
Nenue@9
|
846 print(' hiding:', table.concat(debug_hide, ',' ))
|
Nenue@0
|
847 hasNewQuestPins = nil
|
Nenue@1
|
848 notifyPlayed = nil
|
Nenue@30
|
849 self.hasUpdate = nil
|
Nenue@0
|
850 end
|
Nenue@0
|
851
|
Nenue@0
|
852 -- data provider manipulations for the taxi map
|
Nenue@0
|
853 WorldPlan.OnFlightMapLoaded = function()
|
Nenue@0
|
854 if true then return end
|
Nenue@0
|
855 -- todo: figure out how to layer inside the map canvas
|
Nenue@0
|
856 local res = {}
|
Nenue@0
|
857 local t = {}
|
Nenue@0
|
858 for k,v in pairs(FlightMapFrame) do
|
Nenue@0
|
859 tinsert(res, tostring(k))
|
Nenue@0
|
860 end
|
Nenue@0
|
861
|
Nenue@0
|
862 table.sort(res)
|
Nenue@0
|
863 for i, k in ipairs(res) do
|
Nenue@0
|
864 print(k)
|
Nenue@0
|
865 end
|
Nenue@0
|
866 hooksecurefunc(FlightMapFrame, 'RefreshAll', function(self)
|
Nenue@0
|
867 print('|cFF0088FFWQDP RefreshAllData ', GetTime())
|
Nenue@0
|
868
|
Nenue@0
|
869 WorldPlan:GetPinsForMap(self:GetMapID())
|
Nenue@0
|
870
|
Nenue@0
|
871 for pin in self:EnumerateAllPins() do
|
Nenue@0
|
872 if pin.worldQuest then
|
Nenue@0
|
873 --print('got pin #', pin.questID)
|
Nenue@30
|
874 local wp = self.QuestsByID[pin.questID]
|
Nenue@0
|
875 if wp then
|
Nenue@0
|
876 wp:ClearAllPoints()
|
Nenue@0
|
877 wp:SetParent(FlightMapFrame.ScrollContainer)
|
Nenue@0
|
878 wp:SetFrameStrata('MEDIUM')
|
Nenue@0
|
879 wp:SetPoint('CENTER', pin, 'CENTER')
|
Nenue@0
|
880 wp:Show()
|
Nenue@0
|
881 end
|
Nenue@0
|
882 end
|
Nenue@0
|
883 end
|
Nenue@0
|
884 end)
|
Nenue@0
|
885 end
|
Nenue@0
|
886
|
Nenue@0
|
887
|
Nenue@0
|
888
|
Nenue@0
|
889 local throttle = 0
|
Nenue@0
|
890 local tooltip = CreateFrame ("GameTooltip", "VeneerWorldQuestsScanner", nil, "GameTooltipTemplate")
|
Nenue@0
|
891 local tooltipLine1 = _G['VeneerWorldQuestsScannerTextLeft1']
|
Nenue@0
|
892 local tooltipLine3 = _G['VeneerWorldQuestsScannerTextLeft3']
|
Nenue@0
|
893 local GetTime, mod = GetTime, mod
|
Nenue@0
|
894
|
Nenue@0
|
895
|
Nenue@0
|
896
|
Nenue@0
|
897
|
Nenue@9
|
898 function WorldQuests:FilterCheckByID(questID)
|
Nenue@9
|
899 local pin = WorldQuests:GetPinByQuestID(questID)
|
Nenue@9
|
900 return pin:IsShowable()
|
Nenue@0
|
901 end
|
Nenue@0
|
902
|
Nenue@0
|
903
|
Nenue@9
|
904 function QuestPOI:IsShowable ()
|
Nenue@9
|
905 local print = wqprint
|
Nenue@9
|
906 local db = WorldPlan.db
|
Nenue@0
|
907 local qType = self.worldQuestType
|
Nenue@0
|
908 local rType = self.rewardType
|
Nenue@0
|
909 self.filtered = nil
|
Nenue@9
|
910 self.used = true
|
Nenue@9
|
911
|
Nenue@14
|
912 print(' |cFFFF4400IsShowable()|r', self.title)
|
Nenue@14
|
913
|
Nenue@30
|
914 if not self.passesBlizzFilters then
|
Nenue@30
|
915 self.filtered = true
|
Nenue@0
|
916 end
|
Nenue@0
|
917 if not TQ_IsActive(self.questID) then
|
Nenue@9
|
918 self.used = nil
|
Nenue@30
|
919 elseif qType == LE_QUEST_TAG_TYPE_PROFESSION then
|
Nenue@9
|
920 if not (db.ShowAllProfessionQuests or (self.tradeskillLineIndex and GetProfessionInfo(self.tradeskillLineIndex))) then
|
Nenue@9
|
921 self.used = nil
|
Nenue@0
|
922 end
|
Nenue@0
|
923 end
|
Nenue@9
|
924 return self.used, self.filtered
|
Nenue@0
|
925 end
|
Nenue@0
|
926
|
Nenue@0
|
927 function QuestPOI:UpdateTimer (timeLeft, timeType)
|
Nenue@0
|
928 print('|cFF0088FFUpdatePinTimer()|r')
|
Nenue@0
|
929 end
|
Nenue@0
|
930
|
Nenue@9
|
931 --- Fixes icons upon size update
|
Nenue@9
|
932 function QuestPOI:UpdateSize (style, subStyle)
|
Nenue@27
|
933 style = style or self.style
|
Nenue@27
|
934 subStyle = subStyle or self.subStyle
|
Nenue@0
|
935
|
Nenue@30
|
936 --qprint('|cFF00FF88'..self:GetName()..'|r:UpdateSize()', style, subStyle)
|
Nenue@0
|
937
|
Nenue@0
|
938 self.currentWidth = subStyle.PinSize
|
Nenue@0
|
939 self.borderSize = subStyle.Border
|
Nenue@0
|
940 self.trackingBorderSize = subStyle.TrackingBorder
|
Nenue@0
|
941 self.tagSize = subStyle.TagSize
|
Nenue@0
|
942 self.TimeleftStage = subStyle.TimeleftStage
|
Nenue@0
|
943 self.NoIcon = subStyle.NoIcon
|
Nenue@0
|
944
|
Nenue@27
|
945
|
Nenue@0
|
946 self:SetSize(self.currentWidth, self.currentWidth)
|
Nenue@0
|
947
|
Nenue@27
|
948 local icon = self.icon
|
Nenue@0
|
949 local iconBorder = self.iconBorder
|
Nenue@0
|
950 local trackingBorder = self.supertrackBorder
|
Nenue@0
|
951 local tag = self.tagIcon
|
Nenue@27
|
952 local pinMask = style.pinMask
|
Nenue@27
|
953 local rewardMask = style.rewardMask
|
Nenue@0
|
954
|
Nenue@27
|
955 if self.NoIcon then
|
Nenue@27
|
956 self.icon:Hide()
|
Nenue@27
|
957 else
|
Nenue@27
|
958 self.icon:Show()
|
Nenue@27
|
959 icon:SetMask(nil)
|
Nenue@27
|
960 icon:SetMask(rewardMask)
|
Nenue@27
|
961 icon:SetTexture(self.icon:GetTexture())
|
Nenue@27
|
962 end
|
Nenue@27
|
963 iconBorder:SetMask(nil)
|
Nenue@27
|
964 trackingBorder:SetMask(nil)
|
Nenue@0
|
965
|
Nenue@0
|
966
|
Nenue@0
|
967 local borderWidth = self.borderSize
|
Nenue@0
|
968 local trackingWidth = self.trackingBorderSize
|
Nenue@0
|
969
|
Nenue@0
|
970 iconBorder:ClearAllPoints()
|
Nenue@0
|
971 iconBorder:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', -borderWidth + (style.x or 0), -borderWidth + (style.y or 0))
|
Nenue@0
|
972 iconBorder:SetPoint('TOPRIGHT', self, 'TOPRIGHT', borderWidth + (style.x or 0), borderWidth + (style.y or 0))
|
Nenue@0
|
973
|
Nenue@0
|
974 trackingBorder:ClearAllPoints()
|
Nenue@0
|
975 trackingBorder:SetPoint('BOTTOMLEFT', iconBorder, 'BOTTOMLEFT', -trackingWidth, -trackingWidth)
|
Nenue@0
|
976 trackingBorder:SetPoint('TOPRIGHT', iconBorder, 'TOPRIGHT', trackingWidth, trackingWidth)
|
Nenue@0
|
977
|
Nenue@0
|
978 if self.tagSize then
|
Nenue@0
|
979 tag:Show()
|
Nenue@0
|
980 tag:ClearAllPoints()
|
Nenue@0
|
981 tag:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', borderWidth, -borderWidth)
|
Nenue@0
|
982 else
|
Nenue@0
|
983 tag:Hide()
|
Nenue@0
|
984 end
|
Nenue@0
|
985
|
Nenue@9
|
986 --qprint('using mask:', mask, self.name )
|
Nenue@27
|
987 iconBorder:SetMask(pinMask)
|
Nenue@27
|
988 trackingBorder:SetMask(pinMask)
|
Nenue@0
|
989
|
Nenue@0
|
990
|
Nenue@0
|
991 end
|
Nenue@0
|
992
|
Nenue@0
|
993
|
Nenue@0
|
994
|
Nenue@0
|
995 --%debug%
|
Nenue@0
|
996 local SetTimedCallbackForAllPins = function(seconds, callback)
|
Nenue@0
|
997 C_Timer.After(seconds, function()
|
Nenue@30
|
998 for id, pin in pairs(WorldPlanQuests.QuestsByID) do
|
Nenue@0
|
999 callback(pin)
|
Nenue@0
|
1000 end
|
Nenue@0
|
1001 end)
|
Nenue@0
|
1002 end
|
Nenue@0
|
1003
|
Nenue@0
|
1004 SLASH_WORLDPLAN1 = "/worldplan"
|
Nenue@0
|
1005 SLASH_WORLDPLAN2 = "/wp"
|
Nenue@0
|
1006 SlashCmdList.WORLDPLAN = function()
|
Nenue@0
|
1007 print('command pop')
|
Nenue@0
|
1008 WorldPlan:GetPinsForMap()
|
Nenue@0
|
1009 WorldPlan:RefreshPins()
|
Nenue@0
|
1010
|
Nenue@0
|
1011 SetTimedCallbackForAllPins(0, function(self) self.FadeIn:Play() self.FlashIn:Play() end)
|
Nenue@0
|
1012 SetTimedCallbackForAllPins(5, function(self) self.PendingFade:Play() end)
|
Nenue@0
|
1013 SetTimedCallbackForAllPins(8, function(self) self.PendingFade:Stop() end)
|
Nenue@0
|
1014 end
|
Nenue@0
|
1015 --%end-debug%
|