Mercurial > wow > worldplan
comparison WorldPlan.lua @ 33:be4db60219ca
WorldPlan:
- Toggling a reward filter cancels out other types by default. Use right mouse to clear.
- Fixed filter bar info falling out of sync after player-triggered world map updates.
ClassPlan:
- Available missions are now recorded; the mission list can be toggled between in-progress and available by clicking the heading.
| author | Nenue |
|---|---|
| date | Wed, 02 Nov 2016 17:25:07 -0400 |
| parents | e8679ecb48d8 |
| children | 0100d923d8c3 |
comparison
equal
deleted
inserted
replaced
| 32:e8679ecb48d8 | 33:be4db60219ca |
|---|---|
| 1 -- WorldPlan.lua | 1 -- WorldPlan.lua |
| 2 -- Created: 8/16/2016 8:19 AM | 2 -- Created: 8/16/2016 8:19 AM |
| 3 -- %file-revision% | 3 -- %file-revision% |
| 4 | 4 |
| 5 local addonName, db = ... | |
| 6 | |
| 7 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" | |
| 8 local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" | |
| 9 | |
| 10 local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background" | |
| 11 local POI_BORDER_FILL = "Interface\\BUTTONS\\YELLOWORANGE64" | |
| 12 local POI_BORDER_BLUE = "Interface\\BUTTONS\\GRADBLUE" | |
| 13 local POI_BORDER_RED = "Interface\\BUTTONS\\RedGrad64" | |
| 14 local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64" | |
| 15 local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64" | |
| 16 | |
| 17 WorldPlanCore = { | 5 WorldPlanCore = { |
| 18 defaults = {}, | 6 defaults = {}, |
| 19 modules = {}, | 7 modules = {}, |
| 20 } | 8 FilterOptions = {}, |
| 21 WorldPlanQuestsMixin = { | 9 UsedFilters = {}, |
| 22 QuestsByZone = {}, | 10 QuestsByZone = {}, |
| 23 QuestsByID = {}, | 11 QuestsByID = {}, |
| 24 freePins = {}, | 12 TaskQueue = {}, |
| 25 } | 13 } |
| 26 WorldPlanPOIMixin = {} | |
| 27 WorldPlanFilterPinMixin = setmetatable({ QuestsByID = {}, freePins = {} }, {__tostring = function() return 'QuestHandler' end}) | |
| 28 local WorldPlanFlightMapMixin = setmetatable({}, {__tostring = function() return 'FlightMapHandler' end}) | |
| 29 local WorldQuests = WorldPlanQuestsMixin | |
| 30 | |
| 31 | |
| 32 local WorldPlan = WorldPlanCore | 14 local WorldPlan = WorldPlanCore |
| 33 local QuestPOI = WorldPlanPOIMixin | 15 |
| 34 local FilterPin = WorldPlanFilterPinMixin | 16 local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end |
| 35 local WP_VERSION = "1.0" | 17 local WP_VERSION = "1.0" |
| 36 | 18 local tinsert, pairs, floor = table.insert, pairs, floor |
| 37 local db | |
| 38 local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end | |
| 39 local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end | |
| 40 local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end | |
| 41 local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end | |
| 42 local fbprint = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or function() end | |
| 43 | |
| 44 local wipe, tremove, tinsert, pairs, floor, tContains = table.wipe, table.remove, table.insert, pairs, floor, tContains | |
| 45 local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented | |
| 46 local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID | |
| 47 local TQ_IsActive = C_TaskQuest.IsActive | |
| 48 local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS | 19 local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS |
| 49 local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters | 20 local BROKEN_ISLES_ID = 1007 |
| 50 local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest | |
| 51 local GameTooltip = GameTooltip | |
| 52 local GetItemIcon = GetItemIcon | |
| 53 | |
| 54 | |
| 55 local GetMapInfo, QuestPOIGetIconInfo = GetMapInfo, QuestPOIGetIconInfo | |
| 56 local GetQuestTagInfo, HaveQuestData = GetQuestTagInfo, HaveQuestData | |
| 57 local GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, GetQuestLogRewardMoney = GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, GetQuestLogRewardMoney | |
| 58 local GetQuestLogRewardInfo, GetQuestLogRewardCurrencyInfo, GetMoneyString = GetQuestLogRewardInfo, GetQuestLogRewardCurrencyInfo, GetMoneyString | |
| 59 | |
| 60 local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID | 21 local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID |
| 61 local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo | |
| 62 | |
| 63 | 22 |
| 64 -- default color templates | 23 -- default color templates |
| 65 local ARTIFACT_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT] | |
| 66 local MONEY_COLOR = {hex ='|cFFFFFF00', r=1, g=1, b=0} | |
| 67 local COMMON_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON] | |
| 68 local DEFAULT_TYPE = { | 24 local DEFAULT_TYPE = { |
| 69 a = 1, | 25 a = 1, |
| 70 r = 1, g = 1, b = 1, | 26 r = 1, g = 1, b = 1, |
| 71 x = 0, y = 0, | 27 x = 0, y = 0, |
| 72 desaturated = true, | 28 desaturated = true, |
| 73 pinMask = POI_BORDER_MASK, | 29 pinMask = "Interface\\Minimap\\UI-Minimap-Background", |
| 74 rewardMask = POI_BORDER_MASK, | 30 rewardMask = "Interface\\Minimap\\UI-Minimap-Background", |
| 75 texture = POI_BORDER_FILL, | 31 texture = "Interface\\BUTTONS\\YELLOWORANGE64", |
| 76 continent = { | 32 continent = { |
| 77 PinSize = 14, | 33 PinSize = 14, |
| 78 Border = 2, | 34 Border = 2, |
| 79 TrackingBorder = 1, | 35 TrackingBorder = 1, |
| 80 TagSize = 6, | 36 TagSize = 6, |
| 111 NotifyWhenNewQuests = true, | 67 NotifyWhenNewQuests = true, |
| 112 EnablePins = true, | 68 EnablePins = true, |
| 113 FadeWhileGrouped = true, | 69 FadeWhileGrouped = true, |
| 114 } | 70 } |
| 115 | 71 |
| 116 -- Summary header structure | |
| 117 | |
| 118 local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD | |
| 119 local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER | |
| 120 local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT | |
| 121 local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES | |
| 122 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS | |
| 123 | |
| 124 | |
| 125 local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP | |
| 126 local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE | |
| 127 local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON | |
| 128 local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION | |
| 129 local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL | |
| 130 WorldPlanCore.BrokenIsleID = BROKEN_ISLES_ID | |
| 131 WorldPlanCore.FilterStyle = POI_FILTER_STYLE | |
| 132 | |
| 133 WorldPlanCore.FilterOptions = {} | |
| 134 WorldPlanCore.UsedFilters = {} | |
| 135 | |
| 136 | |
| 137 -- operating flags | 72 -- operating flags |
| 138 local superTrackedID | 73 local superTrackedID |
| 139 local currentMapName | 74 local currentMapName |
| 140 local hasNewQuestPins | 75 local hasNewQuestPins |
| 141 local isContinentMap | 76 local isContinentMap |
| 142 local numPins = 0 | |
| 143 local FilterInclusions = {rewardType = {}, worldQuestType = {}, factionID = {}} | |
| 144 local NotificationTypes = {} | |
| 145 local ZoneInfo = {} | |
| 146 local SummaryHeaders = {} | |
| 147 | |
| 148 local FreePins = {} | |
| 149 local NumPinFrames = 1 | |
| 150 | |
| 151 local hasPendingQuestData | 77 local hasPendingQuestData |
| 152 local notifyPlayed | 78 local notifyPlayed |
| 153 local scanner, wmtt, WorldMapPOIFrame | 79 local scanner, wmtt, WorldMapPOIFrame |
| 154 | 80 |
| 155 | |
| 156 local tasksQueue = {} | |
| 157 local function OnNext (func) | |
| 158 if #tasksQueue == 0 then | |
| 159 _G.WorldPlan:SetScript('OnUpdate', function() | |
| 160 local func = tremove(tasksQueue, 1) | |
| 161 if func then | |
| 162 func() | |
| 163 end | |
| 164 if #tasksQueue == 0 then | |
| 165 _G.WorldPlan:SetScript('OnUpdate', nil) | |
| 166 end | |
| 167 end) | |
| 168 end | |
| 169 print('inserting task #', #tasksQueue+1, func) | |
| 170 tinsert(tasksQueue, func) | |
| 171 end | |
| 172 | |
| 173 -- update a masked texture without messing up its blending mask | |
| 174 local SetMaskedTexture = function(region, file, mask) | |
| 175 mask = mask or POI_BORDER_MASK | |
| 176 region:SetMask(nil) | |
| 177 region:SetTexture(file) | |
| 178 region:SetMask(mask) | |
| 179 end | |
| 180 | 81 |
| 181 -- tracking menu toggler | 82 -- tracking menu toggler |
| 182 local DropDown_OnClick = function(self) | 83 local DropDown_OnClick = function(self) |
| 183 local key = self.value | 84 local key = self.value |
| 184 if key then | 85 if key then |
| 186 WorldPlanData[key] = nil | 87 WorldPlanData[key] = nil |
| 187 else | 88 else |
| 188 WorldPlanData[key] = true | 89 WorldPlanData[key] = true |
| 189 end | 90 end |
| 190 end | 91 end |
| 191 WorldPlan:Refresh() | 92 _G.WorldPlan:Refresh() |
| 192 end | 93 end |
| 193 | 94 |
| 194 function WorldPlan:print(...) | 95 function WorldPlan:print(...) |
| 195 local msg | 96 local msg |
| 196 for i = 1, select('#', ...) do | 97 for i = 1, select('#', ...) do |
| 236 for index, color in pairs(ITEM_QUALITY_COLORS) do | 137 for index, color in pairs(ITEM_QUALITY_COLORS) do |
| 237 self:AddTypeInfo(self, index, { r = color.r, g = color.g, b = color.b, hex = color.hex, }) | 138 self:AddTypeInfo(self, index, { r = color.r, g = color.g, b = color.b, hex = color.hex, }) |
| 238 end | 139 end |
| 239 | 140 |
| 240 WorldPlan = self | 141 WorldPlan = self |
| 241 scanner = _G.WorldPlanTooltip | |
| 242 wmtt = _G.WorldMapTooltip | |
| 243 WorldMapPOIFrame = _G.WorldMapPOIFrame | |
| 244 | 142 |
| 245 WorldPlan:print('v'..WP_VERSION) | 143 WorldPlan:print('v'..WP_VERSION) |
| 246 | 144 |
| 247 self:RegisterEvent("QUESTLINE_UPDATE") | 145 self:RegisterEvent("QUESTLINE_UPDATE") |
| 248 self:RegisterEvent("QUEST_LOG_UPDATE") | 146 self:RegisterEvent("QUEST_LOG_UPDATE") |
| 258 function WorldPlan:OnShow() | 156 function WorldPlan:OnShow() |
| 259 print(self:GetName()..':OnShow()') | 157 print(self:GetName()..':OnShow()') |
| 260 if self.isStale then | 158 if self.isStale then |
| 261 self:Refresh() | 159 self:Refresh() |
| 262 end | 160 end |
| 263 | |
| 264 end | 161 end |
| 265 | 162 |
| 266 function WorldPlan:OnEvent (event, ...) | 163 function WorldPlan:OnEvent (event, ...) |
| 267 print() | 164 print() |
| 268 print(event, self.initialized) | 165 print(event, 'init:', self.initialized) |
| 269 if event == 'ADDON_LOADED' then | 166 if event == 'ADDON_LOADED' then |
| 270 local addon = ... | 167 local addon = ... |
| 271 if addon == "Blizzard_FlightMap" then | 168 if addon == "Blizzard_FlightMap" then |
| 272 print('do mixin junk') | 169 print('do mixin junk') |
| 273 self.OnFlightMapLoaded() | 170 self.OnFlightMapLoaded() |
| 274 | 171 |
| 275 end | 172 end |
| 276 if IsLoggedIn() and not self.initialized then | 173 if IsLoggedIn() and not self.initialized then |
| 277 self:Setup() | 174 self:Setup() |
| 278 end | 175 end |
| 279 elseif event == 'WORLD_MAP_UPDATE' then | 176 else |
| 280 self.currentMapID = GetCurrentMapAreaID() | 177 if event == 'WORLD_MAP_UPDATE' then |
| 281 print('|cFFFF4400currentMapID =', self.currentMapID) | 178 self.currentMapID = GetCurrentMapAreaID() |
| 179 self.isContinentMap = (self.currentMapID == BROKEN_ISLES_ID) | |
| 180 print('|cFFFF4400currentMapID =', self.currentMapID) | |
| 181 --self.isStale = true | |
| 182 end | |
| 183 | |
| 184 for i, module in ipairs(self.modules) do | |
| 185 if module.OnEvent then | |
| 186 print(' |cFF0088FF'..module:GetName() .. ':OnEvent()|r') | |
| 187 module:OnEvent(event, ...) | |
| 188 end | |
| 189 end | |
| 190 end | |
| 191 end | |
| 192 | |
| 193 function WorldPlanCore:OnNext(func) | |
| 194 tinsert(self.TaskQueue, func) | |
| 195 end | |
| 196 | |
| 197 function WorldPlanCore:OnUpdate() | |
| 198 if #self.TaskQueue >= 1 then | |
| 199 local func = tremove(self.TaskQueue, 1) | |
| 200 if func then | |
| 201 func() | |
| 202 end | |
| 203 | |
| 204 end | |
| 205 | |
| 206 if self.isStale then | |
| 207 print('|cFF00FF00pushing global update') | |
| 208 self.isStale = nil | |
| 282 self:Refresh() | 209 self:Refresh() |
| 283 else | 210 else |
| 284 for i, module in ipairs(self.modules) do | 211 for i, module in ipairs(self.modules) do |
| 285 if module.OnEvent then | 212 if module.isStale then |
| 286 print('forwarding to', tostring(module)) | 213 print('|cFF00FF00internal '..module:GetName()..':Refresh()|r') |
| 287 module:OnEvent(event, ...) | 214 module:Refresh() |
| 288 end | 215 end |
| 289 end | 216 end |
| 290 end | 217 end |
| 291 end | 218 end |
| 292 | |
| 293 | 219 |
| 294 function WorldPlan:Setup () | 220 function WorldPlan:Setup () |
| 295 if not WorldPlanData then | 221 if not WorldPlanData then |
| 296 WorldPlanData = {key = 0 } | 222 WorldPlanData = {key = 0 } |
| 297 end | 223 end |
| 321 end | 247 end |
| 322 end | 248 end |
| 323 self.initialized = true | 249 self.initialized = true |
| 324 | 250 |
| 325 hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize) | 251 hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize) |
| 252 | |
| 253 hooksecurefunc("WorldMapTrackingOptionsDropDown_OnClick", function(button) | |
| 254 print("|cFF0088FFWorldMapTrackingOptionsDropDown_OnClick|r") | |
| 255 local value = button.value | |
| 256 if (value == "worldQuestFilterOrderResources" or value == "worldQuestFilterArtifactPower" or | |
| 257 value == "worldQuestFilterProfessionMaterials" or value == "worldQuestFilterGold" or | |
| 258 value == "worldQuestFilterEquipment") then | |
| 259 self:Refresh(true) | |
| 260 end | |
| 261 end) | |
| 326 end | 262 end |
| 327 | 263 |
| 328 function WorldPlan:AddTypeInfo(owner, id, info) | 264 function WorldPlan:AddTypeInfo(owner, id, info) |
| 329 self.Types[owner] = self.Types[owner] or {} | 265 self.Types[owner] = self.Types[owner] or {} |
| 330 self.Types[owner][id] = info | 266 self.Types[owner][id] = info |
| 396 if not self.initialized then | 332 if not self.initialized then |
| 397 return | 333 return |
| 398 end | 334 end |
| 399 | 335 |
| 400 for i, module in ipairs(self.modules) do | 336 for i, module in ipairs(self.modules) do |
| 401 if module.Reset then | |
| 402 print(module, 'Reset()') | |
| 403 module:Reset() | |
| 404 end | |
| 405 end | |
| 406 | |
| 407 for i, module in ipairs(self.modules) do | |
| 408 if module.Refresh then | 337 if module.Refresh then |
| 409 print(module, 'Refresh()') | 338 print('|cFF00FF00external '..module:GetName()..':Refresh()|r') |
| 410 module:Refresh() | 339 module:Refresh(forced) |
| 411 end | |
| 412 end | |
| 413 | |
| 414 for i, module in ipairs(self.modules) do | |
| 415 if module.Cleanup then | |
| 416 print(module, 'Cleanup()') | |
| 417 module:Cleanup() | |
| 418 end | |
| 419 end | |
| 420 end | |
| 421 function WorldPlan:UpdateAnchors () | |
| 422 for i, module in ipairs(self.modules) do | |
| 423 if module.UpdateAnchors then | |
| 424 module:UpdateAnchors() | |
| 425 end | 340 end |
| 426 end | 341 end |
| 427 end | 342 end |
| 428 | 343 |
| 429 -- insert visual options into the tracking button menu | 344 -- insert visual options into the tracking button menu |
| 492 end | 407 end |
| 493 | 408 |
| 494 -------------------------------------------------------------------------------------------------------------------- | 409 -------------------------------------------------------------------------------------------------------------------- |
| 495 -------------------------------------------------------------------------------------------------------------------- | 410 -------------------------------------------------------------------------------------------------------------------- |
| 496 | 411 |
| 497 local PinBaseIndex = 1600 | |
| 498 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 | |
| 499 | |
| 500 -- maps where we do our own anchors | |
| 501 local CONTINENT_MAPS = { [BROKEN_ISLES_ID] = BROKEN_ISLES_ID, } | |
| 502 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah", | |
| 503 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', } | |
| 504 | |
| 505 function WorldQuests:Setup() | |
| 506 | |
| 507 | |
| 508 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do | |
| 509 self.QuestsByZone[mapID] = {} | |
| 510 end | |
| 511 | |
| 512 | |
| 513 -- refresh positions any time blizzard does so (i.e. mousewheel zoom) | |
| 514 hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() | |
| 515 self:Refresh(true) | |
| 516 end) | |
| 517 | |
| 518 -- hide the original world quest POIs | |
| 519 hooksecurefunc("WorldMap_UpdateQuestBonusObjectives", function() | |
| 520 for i = 1, NUM_WORLDMAP_TASK_POIS do | |
| 521 local button = _G['WorldMapFrameTaskPOI'..i] | |
| 522 if button and button.worldQuest then | |
| 523 button:Hide() | |
| 524 end | |
| 525 end | |
| 526 end) | |
| 527 | |
| 528 hooksecurefunc("WorldMapTrackingOptionsDropDown_OnClick", function(button) | |
| 529 print("|cFF0088FFWorldMapTrackingOptionsDropDown_OnClick|r") | |
| 530 local value = button.value | |
| 531 if (value == "worldQuestFilterOrderResources" or value == "worldQuestFilterArtifactPower" or | |
| 532 value == "worldQuestFilterProfessionMaterials" or value == "worldQuestFilterGold" or | |
| 533 value == "worldQuestFilterEquipment") then | |
| 534 self:Refresh(true) | |
| 535 end | |
| 536 end) | |
| 537 end | |
| 538 | |
| 539 local defaults = {} | |
| 540 function WorldQuests:OnLoad() | |
| 541 print('|cFF00FF88'..self:GetName()..':OnLoad') | |
| 542 | |
| 543 WorldPlan:AddHandler(self, defaults) | |
| 544 | |
| 545 local rgbWhite = {1, 1, 1} | |
| 546 WorldPlan:AddTypeInfo(self, REWARD_REAGENT, { r = 0, g = 1, b = 1 }) | |
| 547 WorldPlan:AddTypeInfo(self, REWARD_ARTIFACT_POWER, { r = 1, g = .25, b = .5, hasNumeric = true, numberRGB = rgbWhite }) | |
| 548 WorldPlan:AddTypeInfo(self, REWARD_GEAR, { r = .1, g = .2, b = 1 }) | |
| 549 WorldPlan:AddTypeInfo(self, REWARD_CURRENCY, { r = 1, g = 1, b = 0, hasNumeric = true, numberRGB = {1,1,0}, }) | |
| 550 WorldPlan:AddTypeInfo(self, REWARD_CASH, { r = 0, g = 0, b = 0, }) | |
| 551 | |
| 552 for areaID, fileName in pairs(WORLD_QUEST_MAPS) do | |
| 553 self.QuestsByZone[areaID] = {} | |
| 554 end | |
| 555 | |
| 556 self:RegisterEvent('QUEST_LOG_UPDATE') | |
| 557 self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') | |
| 558 self:RegisterEvent('SKILL_LINES_CHANGED') | |
| 559 | |
| 560 | |
| 561 end | |
| 562 | |
| 563 function WorldQuests:OnEvent (event, ...) | |
| 564 local print = wqprint | |
| 565 print('|cFFFFFF00'..self:GetName()..':OnEvent()'..event..'|r', GetTime(), ...) | |
| 566 if event == 'QUEST_LOG_UPDATE' then | |
| 567 local questID, added = ... | |
| 568 if questID and added then | |
| 569 local questPOI = self:AcquirePin(questID) | |
| 570 self.hasUpdate, self.isPending = questPOI:RefreshData() | |
| 571 else | |
| 572 self:RefreshData() | |
| 573 end | |
| 574 print('WorldMapFrame', WorldMapFrame:IsVisible(), 'hasUpdates:', self.hasUpdate) | |
| 575 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then | |
| 576 local questID = ... | |
| 577 if questID and self.QuestsByID[questID] then | |
| 578 self:ReleasePin(self.QuestsByID[questID]) | |
| 579 end | |
| 580 elseif event == 'SKILL_LINES_CHANGED' then | |
| 581 self.hasUpdate = true | |
| 582 end | |
| 583 end | |
| 584 | |
| 585 function WorldQuests:OnUpdate() | |
| 586 if self.hasUpdate then | |
| 587 wqprint('|cFF00FF00pushing update') | |
| 588 self:Refresh(true) | |
| 589 end | |
| 590 end | |
| 591 | |
| 592 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation | |
| 593 function WorldQuests:AcquirePin (questID, mapID) | |
| 594 local pin = self.QuestsByID[questID] | |
| 595 local isNew = false | |
| 596 if not pin then | |
| 597 isNew = true | |
| 598 local numFree = #self.freePins | |
| 599 if numFree >= 1 then | |
| 600 pin = tremove(self.freePins, numFree) | |
| 601 --print('|cFF00FF00Re-using', pin:GetName()) | |
| 602 else | |
| 603 local name = 'WorldPlanQuestMarker' .. NumPinFrames | |
| 604 --print('|cFF00FF00Creating', name) | |
| 605 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') | |
| 606 | |
| 607 pin:SetFrameStrata('HIGH') | |
| 608 pin.GetTypeInfo = function(frame, typeID) | |
| 609 return self:GetTypeInfo(typeID) | |
| 610 end | |
| 611 NumPinFrames = NumPinFrames + 1 | |
| 612 --pin.iconBorder:SetVertexColor(0,0,0,1) | |
| 613 end | |
| 614 pin:SetID(questID) | |
| 615 pin.isNew = true | |
| 616 pin.currentWidth = nil | |
| 617 | |
| 618 -- used by TaskPOI_x scripts | |
| 619 pin.questID = questID | |
| 620 pin.worldQuest = true | |
| 621 | |
| 622 self.QuestsByID[questID] = pin | |
| 623 else | |
| 624 --print('|cFF00FF00Using', pin:GetName()) | |
| 625 end | |
| 626 mapID = mapID or TQ_GetQuestZoneID(questID) | |
| 627 self.QuestsByZone[mapID][questID] = pin | |
| 628 | |
| 629 return pin, isNew | |
| 630 end | |
| 631 | |
| 632 -- remove from index and add it to the recycling heap | |
| 633 function WorldQuests:ReleasePin (pin) | |
| 634 | |
| 635 local id = pin.questId | |
| 636 if id then | |
| 637 self.QuestsByID[id] = nil | |
| 638 for i, zone in pairs(self.QuestsByZone) do | |
| 639 print('-', i, zone[i]) | |
| 640 zone[id] = nil | |
| 641 end | |
| 642 end | |
| 643 pin:Hide() | |
| 644 pin:ClearAllPoints() | |
| 645 tinsert(self.freePins, pin) | |
| 646 print('|cFFFF4400Clearing out', pin:GetName(),id) | |
| 647 end | |
| 648 | |
| 649 -- create of update quest pins for a map and its underlying zones | |
| 650 function WorldQuests:RefreshData (mapID) | |
| 651 local print = wqprint | |
| 652 mapID = mapID or GetCurrentMapAreaID() | |
| 653 superTrackedID = GetSuperTrackedQuestID() | |
| 654 if not mapID then | |
| 655 -- info not available yet | |
| 656 return | |
| 657 end | |
| 658 | |
| 659 print('|cFF00FF88'..self:GetName()..':RefreshData()|r', 'map:', mapID, 'realMap:', GetCurrentMapAreaID()) | |
| 660 | |
| 661 if mapID == BROKEN_ISLES_ID then | |
| 662 self.hasUpdate = false | |
| 663 print('|cFF00FFFFContinent:|r', mapID, GetMapNameByID(mapID), superTrackedID) | |
| 664 self.fullSearch = true | |
| 665 for i = 1, MC_GetNumZones(mapID) do | |
| 666 local submapID, name, depth = MC_GetZoneInfo(mapID, i) | |
| 667 self:RefreshData(submapID) | |
| 668 end | |
| 669 self.fullSearch = nil | |
| 670 elseif self.QuestsByZone[mapID] then | |
| 671 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID) | |
| 672 local numQuests = 0 | |
| 673 if taskInfo and #taskInfo >= 1 then | |
| 674 print('|cFF00FFFF Zone:|r', mapID, GetMapNameByID(mapID), #taskInfo) | |
| 675 wipe(self.QuestsByZone[mapID]) | |
| 676 ZoneInfo[mapID] = taskInfo | |
| 677 qprint('|cFFFF4400START of', GetMapNameByID(mapID)) | |
| 678 for taskID, info in pairs(taskInfo) do | |
| 679 local questID = info.questId | |
| 680 info.mapID = mapID | |
| 681 local questPOI = self:AcquirePin(questID, mapID) | |
| 682 local hasUpdate, isPending = questPOI:RefreshData(info) | |
| 683 self.hasUpdate = (self.hasUpdate or hasUpdate) | |
| 684 self.isPending = (self.isPending or isPending) | |
| 685 numQuests = numQuests + 1 | |
| 686 end | |
| 687 qprint('|cFFFF4400END of', GetMapNameByID(mapID)) | |
| 688 end | |
| 689 end | |
| 690 | |
| 691 if not self.fullSearch then | |
| 692 print(' hasUpdate:', self.hasUpdate, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or '')) | |
| 693 | |
| 694 end | |
| 695 | |
| 696 end | |
| 697 | |
| 698 function WorldQuests:Refresh(forced) | |
| 699 local print = wqprint | |
| 700 print('|cFF00FF88'..self:GetName()..':Refresh()|r') | |
| 701 if not WorldMapPOIFrame:IsVisible() then | |
| 702 return | |
| 703 end | |
| 704 if forced then | |
| 705 self:Reset() | |
| 706 end | |
| 707 self:UpdateAnchors() | |
| 708 | |
| 709 if forced then | |
| 710 self:Cleanup () | |
| 711 end | |
| 712 end | |
| 713 | |
| 714 -- prepares elements for a map update | |
| 715 function WorldQuests:Reset () | |
| 716 local print = wqprint | |
| 717 print('|cFF00FF88'..self:GetName()..':Reset()|r') | |
| 718 for questID, pin in pairs(self.QuestsByID) do | |
| 719 pin.used = nil | |
| 720 end | |
| 721 end | |
| 722 | |
| 723 -- update visibility states of all pins | |
| 724 function WorldQuests:UpdateAnchors (submapID) | |
| 725 local print = wqprint | |
| 726 local db = WorldPlan.db | |
| 727 local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() | |
| 728 if isMicroDungeon then | |
| 729 return | |
| 730 end | |
| 731 | |
| 732 local currentMap = GetCurrentMapAreaID() | |
| 733 local submapID = submapID or currentMap | |
| 734 | |
| 735 if submapID == BROKEN_ISLES_ID and (not db.DisplayContinentPins) then | |
| 736 print('not updating map for reasons') | |
| 737 return | |
| 738 end | |
| 739 print('|cFF88FF00'..self:GetName()..':UpdateAnchors|r', submapID, GetMapNameByID(submapID), 'pin count:', numPins) | |
| 740 local numZones = MC_GetNumZones(submapID) | |
| 741 if numZones then | |
| 742 for i = 1, numZones do | |
| 743 local subMapID = MC_GetZoneInfo(submapID, i) | |
| 744 self:UpdateAnchors(subMapID) | |
| 745 end | |
| 746 end | |
| 747 local pins = self.QuestsByZone[submapID] | |
| 748 | |
| 749 if pins then | |
| 750 local hostFrame = WorldMapPOIFrame | |
| 751 local mapWidth, mapHeight = hostFrame:GetSize() | |
| 752 for questID, pin in pairs(pins) do | |
| 753 pin:IsShowable() | |
| 754 if pin.used then | |
| 755 pin.hasUpdate = true | |
| 756 pin:SetFrameLevel(PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins) | |
| 757 print('level', PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins) | |
| 758 pin:SetAnchor(WorldMapPOIFrame, currentMap, mapWidth, mapHeight) | |
| 759 numPins = numPins + 1 | |
| 760 end | |
| 761 end | |
| 762 end | |
| 763 end | |
| 764 | |
| 765 -- shows, animates, or hides pins based on their current visibility flags | |
| 766 local debug_show = {} | |
| 767 local debug_animate = {} | |
| 768 local debug_hide = {} | |
| 769 function WorldQuests:Cleanup () | |
| 770 local print = wqprint | |
| 771 local showQuestPOI = db.EnablePins | |
| 772 print('|cFFFFFF00'..tostring(self)..':Cleanup()|r') | |
| 773 local mapID = GetCurrentMapAreaID() | |
| 774 isContinentMap = (mapID == BROKEN_ISLES_ID) | |
| 775 | |
| 776 wipe(debug_show) | |
| 777 wipe(debug_animate) | |
| 778 wipe(debug_hide) | |
| 779 -- continent or zone sizing | |
| 780 local fadeGrouped = (db.FadeWhileGrouped and IsInGroup()) | |
| 781 | |
| 782 numPins = 0 | |
| 783 for questID, pin in pairs(self.QuestsByID) do | |
| 784 -- can we show it? | |
| 785 if showQuestPOI and (pin.used) then | |
| 786 | |
| 787 pin.hasUpdate = true | |
| 788 if fadeGrouped then | |
| 789 pin:SetAlpha(0.25) | |
| 790 else | |
| 791 pin:SetAlpha(1) | |
| 792 end | |
| 793 -- is it a new quest? | |
| 794 if pin.isNew then | |
| 795 if not pin.isAnimating then | |
| 796 pin.isAnimating = true | |
| 797 OnNext(function() | |
| 798 pin:ShowNew() | |
| 799 end) | |
| 800 if not notifyPlayed then | |
| 801 for k,v in pairs(NotificationTypes) do | |
| 802 if v[pin[k]] then | |
| 803 notifyPlayed = true | |
| 804 PlaySoundKitID(23404) | |
| 805 end | |
| 806 end | |
| 807 end | |
| 808 tinsert(debug_animate,questID) | |
| 809 else | |
| 810 | |
| 811 print('animating? ', questID, 'filtered:', pin.filtered) | |
| 812 end | |
| 813 -- trap new but animating pins here | |
| 814 else | |
| 815 -- hard show existing pin | |
| 816 print('refresh #', questID, 'filtered:', pin.filtered, 'hasUpdate', pin.hasUpdate) | |
| 817 pin:Show() | |
| 818 tinsert(debug_show,questID) | |
| 819 end | |
| 820 else | |
| 821 if pin:IsShown() then | |
| 822 tinsert(debug_hide,questID) | |
| 823 end | |
| 824 pin.isAnimating = nil | |
| 825 pin.FadeIn:Stop() | |
| 826 pin:Hide() | |
| 827 end | |
| 828 end | |
| 829 print(' adding:', table.concat(debug_animate, ',' )) | |
| 830 print(' refresh:', table.concat(debug_show, ',' )) | |
| 831 print(' hiding:', table.concat(debug_hide, ',' )) | |
| 832 hasNewQuestPins = nil | |
| 833 notifyPlayed = nil | |
| 834 self.hasUpdate = nil | |
| 835 end | |
| 836 | 412 |
| 837 -- data provider manipulations for the taxi map | 413 -- data provider manipulations for the taxi map |
| 838 WorldPlan.OnFlightMapLoaded = function() | 414 WorldPlan.OnFlightMapLoaded = function() |
| 839 if true then return end | 415 if true then return end |
| 840 -- todo: figure out how to layer inside the map canvas | 416 -- todo: figure out how to layer inside the map canvas |
| 869 end) | 445 end) |
| 870 end | 446 end |
| 871 | 447 |
| 872 | 448 |
| 873 | 449 |
| 874 local throttle = 0 | 450 |
| 875 local tooltip = CreateFrame ("GameTooltip", "VeneerWorldQuestsScanner", nil, "GameTooltipTemplate") | 451 |
| 876 local tooltipLine1 = _G['VeneerWorldQuestsScannerTextLeft1'] | 452 |
| 877 local tooltipLine3 = _G['VeneerWorldQuestsScannerTextLeft3'] | |
| 878 local GetTime, mod = GetTime, mod | |
| 879 | |
| 880 | |
| 881 | |
| 882 | |
| 883 function WorldQuests:FilterCheckByID(questID) | |
| 884 local pin = WorldQuests:GetPinByQuestID(questID) | |
| 885 return pin:IsShowable() | |
| 886 end | |
| 887 | |
| 888 | |
| 889 function QuestPOI:IsShowable () | |
| 890 local print = wqprint | |
| 891 local db = WorldPlan.db | |
| 892 local qType = self.worldQuestType | |
| 893 local rType = self.rewardType | |
| 894 self.filtered = nil | |
| 895 self.used = true | |
| 896 | |
| 897 print(' |cFFFF4400IsShowable()|r', self.title) | |
| 898 | |
| 899 self.questId = self:GetID() | |
| 900 if not (WorldMap_DoesWorldQuestInfoPassFilters(self, false, true)) then | |
| 901 self.filtered = true | |
| 902 end | |
| 903 | |
| 904 for filterKey, value in pairs(WorldPlan.UsedFilters) do | |
| 905 if self[filterKey] ~= value then | |
| 906 self.filtered = true | |
| 907 end | |
| 908 end | |
| 909 | |
| 910 if not TQ_IsActive(self.questID) then | |
| 911 self.used = nil | |
| 912 elseif qType == LE_QUEST_TAG_TYPE_PROFESSION then | |
| 913 if not (db.ShowAllProfessionQuests or (self.tradeskillLineIndex and GetProfessionInfo(self.tradeskillLineIndex))) then | |
| 914 self.used = nil | |
| 915 end | |
| 916 end | |
| 917 return self.used, self.filtered | |
| 918 end | |
| 919 | |
| 920 function QuestPOI:UpdateTimer (timeLeft, timeType) | |
| 921 print('|cFF0088FFUpdatePinTimer()|r') | |
| 922 end | |
| 923 | |
| 924 --- Fixes icons upon size update | |
| 925 function QuestPOI:UpdateSize (style, subStyle) | |
| 926 style = style or self.style | |
| 927 subStyle = subStyle or self.subStyle | |
| 928 | |
| 929 --qprint('|cFF00FF88'..self:GetName()..'|r:UpdateSize()', style, subStyle) | |
| 930 | |
| 931 self.currentWidth = subStyle.PinSize | |
| 932 self.borderSize = subStyle.Border | |
| 933 self.trackingBorderSize = subStyle.TrackingBorder | |
| 934 self.tagSize = subStyle.TagSize | |
| 935 self.TimeleftStage = subStyle.TimeleftStage | |
| 936 self.NoIcon = subStyle.NoIcon | |
| 937 | |
| 938 | |
| 939 self:SetSize(self.currentWidth, self.currentWidth) | |
| 940 | |
| 941 local icon = self.icon | |
| 942 local iconBorder = self.iconBorder | |
| 943 local trackingBorder = self.supertrackBorder | |
| 944 local tag = self.tagIcon | |
| 945 local pinMask = style.pinMask | |
| 946 local rewardMask = style.rewardMask | |
| 947 | |
| 948 if self.NoIcon then | |
| 949 self.icon:Hide() | |
| 950 else | |
| 951 self.icon:Show() | |
| 952 icon:SetMask(nil) | |
| 953 icon:SetMask(rewardMask) | |
| 954 icon:SetTexture(self.icon:GetTexture()) | |
| 955 end | |
| 956 iconBorder:SetMask(nil) | |
| 957 trackingBorder:SetMask(nil) | |
| 958 | |
| 959 | |
| 960 local borderWidth = self.borderSize | |
| 961 local trackingWidth = self.trackingBorderSize | |
| 962 | |
| 963 iconBorder:ClearAllPoints() | |
| 964 iconBorder:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', -borderWidth + (style.x or 0), -borderWidth + (style.y or 0)) | |
| 965 iconBorder:SetPoint('TOPRIGHT', self, 'TOPRIGHT', borderWidth + (style.x or 0), borderWidth + (style.y or 0)) | |
| 966 | |
| 967 trackingBorder:ClearAllPoints() | |
| 968 trackingBorder:SetPoint('BOTTOMLEFT', iconBorder, 'BOTTOMLEFT', -trackingWidth, -trackingWidth) | |
| 969 trackingBorder:SetPoint('TOPRIGHT', iconBorder, 'TOPRIGHT', trackingWidth, trackingWidth) | |
| 970 | |
| 971 if self.tagSize then | |
| 972 tag:Show() | |
| 973 tag:ClearAllPoints() | |
| 974 tag:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', borderWidth, -borderWidth) | |
| 975 else | |
| 976 tag:Hide() | |
| 977 end | |
| 978 | |
| 979 --qprint('using mask:', mask, self.name ) | |
| 980 iconBorder:SetMask(pinMask) | |
| 981 trackingBorder:SetMask(pinMask) | |
| 982 | |
| 983 | |
| 984 end | |
| 985 | |
| 986 | |
| 987 | |
| 988 --%debug% | |
| 989 local SetTimedCallbackForAllPins = function(seconds, callback) | |
| 990 C_Timer.After(seconds, function() | |
| 991 for id, pin in pairs(WorldPlanQuests.QuestsByID) do | |
| 992 callback(pin) | |
| 993 end | |
| 994 end) | |
| 995 end | |
| 996 | 453 |
| 997 SLASH_WORLDPLAN1 = "/worldplan" | 454 SLASH_WORLDPLAN1 = "/worldplan" |
| 998 SLASH_WORLDPLAN2 = "/wp" | 455 SLASH_WORLDPLAN2 = "/wp" |
| 999 SlashCmdList.WORLDPLAN = function() | 456 SlashCmdList.WORLDPLAN = function() |
| 1000 print('command pop') | 457 print('command pop') |
