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 |
