# HG changeset patch # User Nenue # Date 1490809541 14400 # Node ID 02f1d3bce558744363cf91e37b2298c0d5e84d02 # Parent 876c3f0bfd0e1bc08121e3d728c99d46fe969824 Update for Legion Patch 7.2 - Massively improved performance footprint via 7.2 API changes and some major optimization of POI update triggers - Removed AP token caching until reliable mechanisms for detecting AK shifts can be resolved. diff -r 876c3f0bfd0e -r 02f1d3bce558 QuestPOI.lua --- a/QuestPOI.lua Thu Mar 23 05:26:51 2017 -0400 +++ b/QuestPOI.lua Wed Mar 29 13:45:41 2017 -0400 @@ -2,6 +2,8 @@ -- QuestPOI.lua -- Created: 10/1/2016 7:21 PM -- %file-revision% +-- Big TODOs: +-- -- generate frames using `WorldMap_GetOrCreateTaskPOI' to remove tainting issues -- local _, db = ... local TQ_GetQuestInfoByQuestID = C_TaskQuest.GetQuestInfoByQuestID @@ -21,6 +23,8 @@ local GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString = GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString local SpellCanTargetQuest, GetCVarBool = SpellCanTargetQuest, GetCVarBool local SetSuperTrackedQuestID = SetSuperTrackedQuestID +local HaveQuestRewardData = HaveQuestRewardData + local pairs, ipairs, tinsert, unpack, select = pairs, ipairs, tinsert, unpack, select local floor, mod, tostring, tonumber, GetSuperTrackedQuestID = floor, mod, tostring, tonumber, GetSuperTrackedQuestID @@ -54,6 +58,7 @@ local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS +local REWARD_HONOR = WORLD_QUEST_REWARD_TYPE_FLAG_HONOR local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE @@ -67,6 +72,9 @@ local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL +local LE_ITEM_CLASS_WEAPON, LE_ITEM_CLASS_ARMOR, LE_ITEM_CLASS_GEM, LE_ITEM_GEM_ARTIFACTRELIC, LE_ITEM_CLASS_TRADEGOODS = LE_ITEM_CLASS_WEAPON, LE_ITEM_CLASS_ARMOR, LE_ITEM_CLASS_GEM, LE_ITEM_GEM_ARTIFACTRELIC, LE_ITEM_CLASS_TRADEGOODS + + local STYLE_TYPE_PENDING = 768 @@ -265,7 +273,7 @@ end end end - WorldMap_AddQuestRewardsToTooltip(questID) + GameTooltip_AddQuestRewardsToTooltip(WorldMapTooltip, questID) WorldMapTooltip:Show() --WorldMapTooltip.recalculatePadding = true; @@ -292,18 +300,11 @@ local questTitle, factionID, capped = TQ_GetQuestInfoByQuestID(questID) -- if the title is nil, then wait and try later if not questTitle then - if not self.isPending then - C_TaskQuest.RequestPreloadRewardData(questID) - self.isPending = true - end - dprint('|cFFBB8844isPending=true|r|cFF00FFFF', self.questId) + dprint('|cFFBB8844dataLoaded|r = false|cFF00FFFF', self.questId) + return false else self.title, self.factionID, self.capped = questTitle, factionID, capped - dprint('|cFFBB8844 data|r|cFF00FFFF', (self.isPending and '|cFFFF4400delayed|r' or '|cFF00FF00success|r'), self.title, '|r', self.factionID) - if self.dataLoaded then - dprint(' |cFFFF4400overwriting data|r') - end - + dprint(questTitle, factionID, capped) -- set tag details local worldQuestType self.tagID, self.tagName, worldQuestType, self.rarity, self.isElite, self.tradeskillLineIndex = GetQuestTagInfo(questID); @@ -326,35 +327,163 @@ self.worldQuestType = worldQuestType self.tagAtlas = tagAtlas - self:SetRewardInfo() - - -- force throttle on success - --qprint(' |cFF00FFFF'..questID..'|r hasUpdate:', hasUpdate, 'isPending:', isPending, 'isShown', self:IsShown()) - --qprint(' ', 'rewardType:', self.rewardType, 'tag:', self.tagID) - qprint(' ', tostring(self.title), " |T"..tostring(self.itemTexture)..":12:12|t", tostring(self.itemName)) - - if self.itemTexture and self.itemName and self.title then + local dataLoaded, rewardType, itemName, itemTexture, itemNumber, quality = self:UpdateRewards() + dprint('|cFFBB8844 dataLoaded|r =', dataLoaded, rewardType, itemName, itemTexture, itemNumber, quality) + if dataLoaded then + self.rewardType = rewardType + self.itemName = itemName + self.itemTexture = itemTexture + self.itemNumber = itemNumber + self.itemQuality = quality self.dataLoaded = true - self.isPending = nil - self.throttle = 1 - self.updateRate = PIN_REFRESH_DELAY self.isStale = true end end self.isCriteria = WorldMapFrame.UIElementsFrame.BountyBoard:IsWorldQuestCriteriaForSelectedBounty(questID) - return self.isStale, self.isPending + return self.dataLoaded end -function QuestPOI:SetRewardInfo() +--- Returns true if data has changed (either from loading in or qualifications changed) +function QuestPOI:UpdateRewards() local questID = self.questID - if not HaveQuestData(questID) then - self.isPending = true + if not HaveQuestRewardData(questID) then + C_TaskQuest.RequestPreloadRewardData(questID); + return false; else + local rewardMoney, rewardAP, rewardHonor + local rewardItems, rewardCurrency = {}, {} + local rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality + local xpIcon, xpName, xpCount, xpType - local rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality - -- set reward category + if (GetNumQuestLogRewardCurrencies(questID) > 0 or GetNumQuestLogRewards(questID) > 0 or GetQuestLogRewardMoney(questID) > 0 or GetQuestLogRewardArtifactXP(questID) > 0 or GetQuestLogRewardHonor(questID)) then + local money = GetQuestLogRewardMoney(questID) + if money > 0 then + rewardMoney = money + rewardIcon = ICON_MONEY + rewardName = GetMoneyString(money) + rewardCount = floor(money/10000) + rewardType = REWARD_CASH + end + + local artifactXP = GetQuestLogRewardArtifactXP(questID); + if artifactXP > 0 then + rewardAP = artifactXP + rewardIcon = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" + rewardCount = artifactXP + rewardType = REWARD_ARTIFACT_POWER + qprint(' artifactXP', artifactXP) + end + + local numQuestCurrencies = GetNumQuestLogRewardCurrencies(questID); + for i = 1, numQuestCurrencies do + local name, texture, numItems = GetQuestLogRewardCurrencyInfo(i, questID); + local text = BONUS_OBJECTIVE_REWARD_WITH_COUNT_FORMAT:format(texture, numItems, name); + tinsert(rewardCurrency, { + name = name, + texture = texture, + numItems = numItems, + text = text + }) + qprint(' currency', i, name, " |T"..tostring(texture)..":12:12|t") + rewardIcon = texture + rewardCount = numItems + rewardName = name + rewardType = REWARD_CURRENCY + end + local honorAmount = GetQuestLogRewardHonor(questID); + if honorAmount > 0 then + xpIcon = "Interface\\ICONS\\Achievement_LegionPVPTier4" + xpCount = honorAmount + xpName = HONOR + xpType = HONOR_CURRENCY + end + + local numQuestRewards = GetNumQuestLogRewards(questID); + if numQuestRewards > 0 then + local foundPrimary + for i = 1, numQuestRewards do + local name, texture, numItems, quality, isUsable, itemID = GetQuestLogRewardInfo(i, questID) + + if itemID then + local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, sellPrice, classID, subclassID = GetItemInfo(itemID); + + + if ( classID == LE_ITEM_CLASS_WEAPON or classID == LE_ITEM_CLASS_ARMOR or (classID == LE_ITEM_CLASS_GEM and subclassID == LE_ITEM_GEM_ARTIFACTRELIC) ) then + rewardType = REWARD_GEAR + rewardIcon = texture + rewardName = name + rewardCount = numItems + foundPrimary = true + elseif IsArtifactPowerItem(itemID) then + rewardType = REWARD_ARTIFACT_POWER + rewardIcon = texture + rewardName = name + rewardCount = 1 + foundPrimary = true + + WorldPlanTooltip:SetOwner(self, 'ANCHOR_NONE') + WorldPlanTooltip:SetHyperlink(itemLink) + for i = 1, WorldPlanTooltip:NumLines() do + local line = _G['WorldPlanTooltipTextLeft' .. i] + local text = line and line:GetText() + local ap = text and text:gsub(',', ''):match('(%d+) '..ARTIFACT_POWER) + if ap then + rewardCount = tonumber(ap) + print(ap) + end + + end + + if WorldPlanTooltipTextLeft2 then + local text = WorldPlanTooltipTextLeft2:GetText() + end + + print('is an AP token') + elseif classID == LE_ITEM_CLASS_TRADEGOODS then + rewardType = REWARD_REAGENT + rewardIcon = texture + rewardName = name + rewardCount = numItems + foundPrimary = true + end + + + qprint(' reward', i, name, " |T"..tostring(texture)..":12:12|t", quality, isUsable, itemID) + tinsert(rewardItems, { + name = name, + texture = texture, + numItems = numItems, + quality = quality, + isUsable = isUsable + }) + if not foundPrimary then + rewardType = REWARD_GEAR + + rewardIcon = texture + rewardName = name + rewardCount = numItems + end + + end + + end + end + + qprint(' '..self.questID..':|cFFFFFF00SetRewardInfo():', numQuestRewards, rewardType) + qprint(' ', tostring(self.title), " |T"..tostring(self.itemTexture)..":12:12|t", tostring(self.itemName)) + + if (self.itemNumber ~= rewardCount) or (self.rewardType ~= rewardType) or (self.itemName ~= rewardName) or (self.itemTexture ~= rewardIcon) then + return true, rewardType, rewardName, rewardIcon, rewardCount, quality + else + return false + end + end + + + + --[[ set reward category local numRewards = GetNumQuestLogRewards(questID) local numCurrency = GetNumQuestLogRewardCurrencies(questID) local money = GetQuestLogRewardMoney(questID) @@ -364,31 +493,9 @@ rewardName, rewardIcon, rewardCount = GetQuestLogRewardCurrencyInfo(1, questID) rewardType = REWARD_CURRENCY elseif money >= 1 then - rewardIcon = ICON_MONEY rewardName = GetMoneyString(money) - rewardType = REWARD_CASH end - - qprint(' '..self.questID..':|cFFFFFF00SetRewardInfo():', numRewards, rewardType) - self.itemNumber = tonumber(rewardCount or self.itemNumber) - self.rewardType = rewardType - self.quality = quality - - self.itemTexture = rewardIcon or self.itemTexture - self.itemName = rewardName or self.itemName - - -- flag unresolved info - if not (rewardIcon and rewardName) then - self.isPending = true - self.isStale = nil - --WorldPlan:print('|cFFFFFF00'..tostring(self.title)..'|r waiting on texture info') - else - if (rewardIcon and rewardName) and self.isPending then - --WorldPlan:print('|cFF00FF00'..tostring(self.title)..'|r has info', rewardIcon, rewardName) - self.isStale = true - end - self.isPending = nil - end + --]] end end @@ -442,7 +549,7 @@ self.isAnimating = nil end --- different from owningFrame +-- Places the pin and triggers display function QuestPOI:SetAnchor(owner, dX, dY, mapWidth, mapHeight) wqprint(self:GetName()..':SetAnchor()', owner, dX, dY, self.filtered, self.used) if not self.used then @@ -460,13 +567,19 @@ if not (mapHeight and mapWidth) then mapWidth, mapHeight = owner:GetSize() end - local pX = (dX * mapWidth) - local pY = (-dY * mapHeight) - self.x = dX - self.y = dY - self:SetPoint('CENTER', owner, 'TOPLEFT', pX, pY) + if (self.x ~= dY) or (self.y ~= dY) then + self.x = dX + self.y = dY + local pX = (dX * mapWidth) + local pY = (-dY * mapHeight) + self:SetPoint('CENTER', owner, 'TOPLEFT', pX, pY) + end else - self:SetPoint('CENTER') + if self.x or self.y then + self.x = nil + self.y = nil + self:SetPoint('CENTER') + end end self:ShowFrames() @@ -499,7 +612,6 @@ function QuestPOI:OnLoad() qprint('|cFF00FF88'..self:GetName()..':OnLoad()|r',db.Config) - self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED') self.title = '|cFF0088FF' .. RETRIEVING_DATA..'|r' self.isPending = true @@ -522,12 +634,6 @@ end -function QuestPOI:OnEvent(event, ...) - if event == 'SUPER_TRACKED_QUEST_CHANGED' then - self.isStale = true - end -end - function QuestPOI:OnUpdate (sinceLast) -- control update check intervals self.throttle = (self.throttle or self.updateRate) + sinceLast @@ -548,7 +654,7 @@ -- query for reward data if it wasn't found in the original scan local questID = self.questID - if self.isPending then + if not self.dataLoaded then --print('|cFFFF4400'..self:GetID()..':|r polling reward info') if not (self.isAnimating) then self.PendingFade:Play() @@ -608,7 +714,7 @@ - local styleType = (self.isPending and STYLE_TYPE_PENDING) or self.rewardType + local styleType = (self.dataLoaded and self.rewardType) or STYLE_TYPE_PENDING local style,subStyle = self:GetTypeInfo(self.rewardType) if (self.filtered or (not self.dataLoaded)) and (self.questID ~= GetSuperTrackedQuestID()) then subStyle = style.minimized @@ -634,7 +740,11 @@ if self.itemNumber then local numberString = self.itemNumber - if self.itemNumber >= 1000 then + if self.itemNumber >= 1000000 then + numberString = (floor(self.itemNumber/100000)/10) .. 'M' + elseif self.itemNumber >= 10000 then + numberString = floor(self.itemNumber/1000) .. 'k' + elseif self.itemNumber >= 1000 then local numeral = floor(self.itemNumber/1000) local decimal = mod(self.itemNumber, 1000) numberString = numeral @@ -740,7 +850,6 @@ self.isStale = true print(' '..self.questID..':|cFFFFFF00CheckFilterRules()|r ', canShow, filtered, self.title) end - self.filtered = filtered end diff -r 876c3f0bfd0e -r 02f1d3bce558 WorldPlan.toc --- a/WorldPlan.toc Thu Mar 23 05:26:51 2017 -0400 +++ b/WorldPlan.toc Wed Mar 29 13:45:41 2017 -0400 @@ -1,4 +1,4 @@ -## Interface: 70100 +## Interface: 70200 ## Title: WorldPlan ## Notes: World Quest planning helper ## Author: Krakyn diff -r 876c3f0bfd0e -r 02f1d3bce558 WorldQuests.lua --- a/WorldQuests.lua Thu Mar 23 05:26:51 2017 -0400 +++ b/WorldQuests.lua Wed Mar 29 13:45:41 2017 -0400 @@ -35,7 +35,9 @@ local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS - +local numShown = 0 +local numLoaded = 0 +local isDataLoaded local numPins = 0 local NumPinFrames = 1 Module.TasksByID = {} @@ -72,6 +74,31 @@ hooksecurefunc("WorldMapFrame_UpdateMap", InternalDoRefresh) WorldMapFrame.UIElementsFrame.BountyBoard:SetSelectedBountyChangedCallback(InternalDoRefresh); WorldMapFrame.UIElementsFrame.ActionButton:SetOnCastChangedCallback(InternalDoRefresh); + + self.Status = CreateFrame('Frame', nil, self) + self.Status:SetPoint('TOPLEFT', WorldMapPOIFrame, 'TOPLEFT', 0, 0) + self.Status:SetPoint('BOTTOMRIGHT', WorldMapPOIFrame, 'TOPRIGHT', 0, -4) + self.Status.t = self.Status:CreateTexture(nil, 'OVERLAY') + self.Status.b = self.Status:CreateTexture(nil, 'BACKGROUND') + self.Status.b:SetColorTexture(0,0,0,.25) + self.Status.b:SetAllPoints(self.Status) + self.Status.t:SetColorTexture(1,1,1,.5) + self.Status.t:SetPoint('TOP') + self.Status.t:SetPoint('BOTTOM') + self.Status.t:SetPoint('LEFT') + local translationEnd, translationStart + self.Status:SetScript('OnUpdate', function(status) + local translateTo + if numLoaded < numShown then + translateTo = numLoaded/numShown * status:GetWidth() + status.t:SetWidth(translateTo) + else + translateTo = numShown * status:GetWidth() + status.t:SetWidth(translateTo) + end + + + end) end function Module:OnConfigUpdate() @@ -160,7 +187,7 @@ self.isStale = true end end - +local superTrackedQuestID function Module:OnEvent (event, ...) print('|cFFFFFF00'..self:GetName()..':OnEvent() '..event..'|r', GetTime(), ...) @@ -181,10 +208,7 @@ self:ReleasePin(db.QuestsByID[questID]) rprint('|cFFFF4400release|r', questID) end - elseif event == 'SKILL_LINES_CHANGED' then - self:Refresh() - elseif event == 'CURRENT_SPELL_CAST_CHANGED' then - + elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then self:Refresh() elseif event == 'ARTIFACT_UPDATE' then local ak = C_ArtifactUI.GetArtifactKnowledgeMultiplier() @@ -196,6 +220,14 @@ end self:Refresh() end + elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then + if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then + db.QuestsByID[superTrackedQuestID].isStale = true + end + local newID = GetSuperTrackedQuestID() + if newID and db.QuestsByID[newID] then + db.QuestsByID[newID].isStale = true + end end end @@ -253,14 +285,14 @@ end if (not pin.dataLoaded) then - pin:GetData() + local dataLoaded = pin:GetData() + isDataLoaded = (isDataLoaded and dataLoaded) WorldPlan.dataFlush = true end pin.isActive = TQ_IsActive(questID) pin:CheckFilterRules() - pin.isStale = true rprint(pin:GetID(), pin.filtered, pin.used) return pin @@ -475,6 +507,8 @@ print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') rprint('|cFFFFFF00'..self:GetName()..':Cleanup()|r') --local showQuestPOI = db.Config.EnablePins + numShown = 0 + numLoaded = 0 for questID, pin in pairs(db.QuestsByID) do local oV = pin:IsShown() if pin.used then @@ -483,6 +517,11 @@ print('|cFF00FF00cleanup +|r', questID, pin.title) end pin:SetShown(true) + numShown = numShown + 1 + if pin.dataLoaded then + numLoaded = numLoaded + 1 + end + else if oV == true then print('|cFFFF4400 -|r', questID, pin.title) @@ -491,6 +530,11 @@ end end + if numShown > numLoaded then + self.Status:Show() + end + + self.isStale = nil self.sizesDirty = nil end @@ -517,17 +561,13 @@ rprint('|cFF00FF00update|r', pin.questID, pin.title) if x and y then - pin.x = x - pin.y = y pin:SetFrameLevel(PinBaseIndex+pin:GetID()) pin.owningFrame = WorldMapFrame - pin:SetAnchor(WorldMapPOIFrame, pin.x, pin.y, self.hostWidth, self.hostHeight) + pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight) --tinsert(self.UsedPositions, pin) end - if self:IsVisible() then + if self:IsVisible() and pin.isStale then pin:Refresh() - else - pin.isStale = true end if mapID then if not db.QuestsByZone[mapID] then @@ -545,6 +585,7 @@ end function Module:UpdateAnchors () + wipe(self.UsedPositions) print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()') self.hostWidth, self.hostHeight = WorldMapPOIFrame:GetSize() @@ -556,7 +597,8 @@ if isMicroDungeon then return end - + -- starts as true + isDataLoaded = true numPins = 0 local taskInfo = TQ_GetQuestsForPlayerByMapID(self.currentMapID) @@ -575,4 +617,3 @@ end end -