Nenue@97: -- Veneer Nenue@97: -- ArtifactPower.lua Nenue@97: -- Created: 1/15/2017 11:44 PM Nenue@97: -- %file-revision% Nenue@97: -- Nenue@97: Nenue@97: local print = DEVIAN_WORKSPACE and function(...) print('VnAP', ...) end or nop Nenue@97: VeneerArtifactPowerMixin = { Nenue@97: Nenue@97: anchorPoint = 'TOP', Nenue@97: anchorFrom = 'TOP', Nenue@97: } Nenue@97: local ap = VeneerArtifactPowerMixin Nenue@97: local BAGS_TO_SCAN = {BACKPACK_CONTAINER } Nenue@97: local TOOLTIP_NAME = 'VeneerAPScanner' Nenue@97: Nenue@97: function ap:OnLoad() Nenue@97: self:RegisterEvent('BAG_UPDATE') -- use to obtain bag IDs to scan Nenue@97: self:RegisterEvent('BAG_UPDATE_DELAYED') -- use to trigger actual scan activity Nenue@97: self:RegisterEvent('BANKFRAME_OPENED') -- determine when bank info is available Nenue@97: self:RegisterEvent('BANKFRAME_CLOSED') -- " " " Nenue@97: self:RegisterEvent('ARTIFACT_UPDATE') -- when artifact data has changed Nenue@97: self:RegisterEvent('ARTIFACT_UPDATE_XP') -- when artifact xp has changed (but not necessarily data) Nenue@97: self:RegisterEvent('MODIFIER_STATE_CHANGED') Nenue@97: self:RegisterEvent('PLAYER_REGEN_ENABLED') Nenue@97: self:RegisterEvent('PLAYER_REGEN_DISABLED') Nenue@97: Veneer:AddHandler(self, self.anchorPoint, true) Nenue@97: SLASH_VENEER_AP1 = "/vap" Nenue@97: SLASH_VENEER_AP2 = "/veneerap" Nenue@97: SlashCmdList.VENEER_AP = function() Nenue@97: self:Show() Nenue@97: end Nenue@97: Nenue@97: self.tooltip = CreateFrame('GameTooltip', TOOLTIP_NAME, self, 'GameTooltipTemplate') Nenue@97: Nenue@97: end Nenue@97: Nenue@97: local defaultSettings = { Nenue@97: } Nenue@97: Nenue@97: function ap:Setup() Nenue@97: print(self:GetName()..':Setup()') Nenue@97: local guid = UnitGUID('player') Nenue@97: VeneerData.ArtifactPower = VeneerData.ArtifactPower or defaultSettings Nenue@97: VeneerData.ArtifactPower[guid] = VeneerData.ArtifactPower[guid] or {} Nenue@97: self.profile = VeneerData.ArtifactPower[guid] Nenue@97: self.profile.bagslots = self.profile.bagslots or {} Nenue@97: self.profile.artifacts = self.profile.artifacts or {} Nenue@97: self:GetCurrentArtifact(true) Nenue@97: self.updateSummary = true Nenue@97: Nenue@97: -- Bagnon compatibility Nenue@97: -- todo: ArkInventory, Elv, etc Nenue@97: if IsAddOnLoaded('Bagnon') then Nenue@97: local oToggleAllBags = ToggleAllBags Nenue@97: ToggleAllBags = function() Nenue@97: print('|cFFFF0088ToggleAllBags') Nenue@97: oToggleAllBags() Nenue@97: if BagnonFrameinventory:IsShown() then Nenue@97: self:Show() Nenue@97: else Nenue@97: self.enabled = nil Nenue@97: self:Hide() Nenue@97: end Nenue@97: end Nenue@97: else Nenue@97: hooksecurefunc("OpenBackpack", function() Nenue@97: self:Show() Nenue@97: end) Nenue@97: hooksecurefunc("CloseBackpack", function() Nenue@97: self.enabled = nil Nenue@97: self:Hide() Nenue@97: end) Nenue@97: end Nenue@97: Nenue@97: Nenue@97: end Nenue@97: local UNDERLIGHT_ANGLER_ID = 133755 Nenue@97: function ap:GetCurrentArtifact(newItem) Nenue@97: if not self.profile then Nenue@97: return Nenue@97: end Nenue@97: local artifacts = self.profile.artifacts Nenue@97: local itemID, altItemID, name, texture, currentXP, pointsSpent, _, _, artifactAppearanceID, appearanceModID, itemAppearanceID, altItemAppearanceID, altOnTop = C_ArtifactUI:GetArtifactInfo() Nenue@97: Nenue@97: Nenue@97: if itemID then Nenue@97: Nenue@97: Nenue@97: Nenue@97: Nenue@97: print('updating', itemID, name, currentXP, pointsSpent, pointsAvailable, adjustedXP) Nenue@97: table.wipe(artifacts[itemID]) Nenue@97: artifacts[itemID] = artifacts[itemID] or {} Nenue@97: artifacts[itemID].name = name Nenue@97: artifacts[itemID].texture = texture Nenue@97: artifacts[itemID].currentXP = currentXP Nenue@97: artifacts[itemID].level = pointsSpent Nenue@97: end Nenue@97: Nenue@97: Nenue@97: self:Update() Nenue@97: end Nenue@97: function ap:QueueBag(containerID) Nenue@97: containerID = tonumber(containerID) Nenue@97: if not containerID then Nenue@97: return Nenue@97: end Nenue@97: Nenue@97: if not tContains(BAGS_TO_SCAN, containerID) then Nenue@97: print(' queueing', containerID, type(containerID), #BAGS_TO_SCAN , 'in line') Nenue@97: BAGS_TO_SCAN[#BAGS_TO_SCAN + 1] = containerID Nenue@97: end Nenue@97: end Nenue@97: Nenue@97: function ap:OnShow() Nenue@97: self.enabled = true Nenue@97: self:Update() Nenue@97: Veneer:DynamicReanchor() Nenue@97: end Nenue@97: function ap:OnHide() Nenue@97: Veneer:DynamicReanchor() Nenue@97: end Nenue@97: Nenue@97: function ap:OnEnter() Nenue@97: Nenue@97: GameTooltip:SetOwner(self, 'ANCHOR_CURSOR') Nenue@97: Nenue@97: GameTooltip:AddLine(self.bagAP) Nenue@97: GameTooltip:AddLine(self.bankAP) Nenue@97: Nenue@97: end Nenue@97: Nenue@97: function ap:OnEvent(event, ...) Nenue@97: print(self:GetName()..':OnEvent()', event, ...) Nenue@97: if event == 'BAG_UPDATE' then Nenue@97: local containerID = ... Nenue@97: self:QueueBag(containerID) Nenue@97: elseif event == 'PLAYER_BANKSLOTS_CHANGED' then Nenue@97: self:QueueBag(BANK_CONTAINER) Nenue@97: elseif event == 'BAG_UPDATE_DELAYED' then Nenue@97: self:ScanAllBags() Nenue@97: elseif event == 'BANKFRAME_OPENED' then Nenue@97: self.bankAccess = true Nenue@97: self:QueueBag(BANK_CONTAINER) Nenue@97: for i = 1, GetNumBankSlots() do Nenue@97: self:QueueBag(i+NUM_BAG_SLOTS) Nenue@97: end Nenue@97: self:ScanAllBags() Nenue@97: elseif event == 'BANKFRAME_CLOSED' then Nenue@97: self.bankAccess = false Nenue@97: self:Update() Nenue@97: elseif event == 'ARTIFACT_UPDATE' then Nenue@97: self:GetCurrentArtifact(...) Nenue@97: elseif event == 'ARTIFACT_UPDATE_XP' then Nenue@97: self:GetCurrentArtifact(...) Nenue@97: self:Update() Nenue@97: elseif event == 'MODIFIER_STATE_CHANGED' then Nenue@97: self:Update() Nenue@97: elseif event == 'PLAYER_REGEN_ENABLED' then Nenue@97: if self.enabled then Nenue@97: self:Show() Nenue@97: end Nenue@97: Nenue@97: elseif event == 'PLAYER_REGEN_DISABLED' then Nenue@97: self:Hide() Nenue@97: end Nenue@97: end Nenue@97: Nenue@97: function ap:OnMouseDown() Nenue@97: self.enabled = nil Nenue@97: self:Hide() Nenue@97: end Nenue@97: Nenue@97: function ap:Update() Nenue@97: if not self:IsShown() then Nenue@97: return Nenue@97: end Nenue@97: print('|cFF00FFFFUpdate()|r') Nenue@97: Nenue@97: local bankText, bagText Nenue@97: if not (self.bankAP and self.bagAP) then Nenue@97: bankText = '|cFFFF0000Open bank frame to count all AP|r ' Nenue@97: else Nenue@97: bankText = '|cFFFFFFFFAP:|r' .. tostring(self.bagAP + self.bankAP) .. ' |cFFFFFF00('..tostring(self.bankAP)..' banked)|r' Nenue@97: end Nenue@97: self.SummaryHeader:SetText(bankText) Nenue@97: Nenue@97: -- Artifact icons, in no particular order Nenue@97: local equippedID = C_ArtifactUI.GetEquippedArtifactInfo() Nenue@97: local numButtons = 0 Nenue@97: local lastFrame Nenue@97: for itemID, artifact in pairs(self.profile.artifacts) do Nenue@97: print(artifact.name, artifact.texture, artifact.currentXP) Nenue@97: numButtons = numButtons + 1 Nenue@97: local button = self.Artifact[numButtons] Nenue@97: Nenue@97: button:SetID(itemID) Nenue@97: for k,v in pairs(artifact) do Nenue@97: --print('::',k,v) Nenue@97: button[k] = v Nenue@97: end Nenue@97: Nenue@97: Nenue@97: local pointsAvailable = button.level Nenue@97: local cost = C_ArtifactUI.GetCostForPointAtRank(pointsAvailable) Nenue@97: local adjustedXP = button.currentXP Nenue@97: if itemID ~= UNDERLIGHT_ANGLER_ID then Nenue@97: adjustedXP = adjustedXP + (self.bankAP or 0) + (self.bagAP or 0) Nenue@97: print('not UL angler', adjustedXP) Nenue@97: else Nenue@97: print('UL angler', adjustedXP) Nenue@97: end Nenue@97: Nenue@97: while adjustedXP >= cost do Nenue@97: pointsAvailable = pointsAvailable + 1 Nenue@97: adjustedXP = adjustedXP - cost Nenue@97: print(pointsAvailable, '-', cost, '=', adjustedXP) Nenue@97: cost = C_ArtifactUI.GetCostForPointAtRank(pointsAvailable) Nenue@97: end Nenue@97: button.adjustedXP = adjustedXP Nenue@97: button.actualLevel = pointsAvailable Nenue@97: Nenue@97: button.isEquipped = (equippedID == itemID) Nenue@97: button.relativeFrame = lastFrame Nenue@97: button:Update() Nenue@97: lastFrame = button Nenue@97: button:Show() Nenue@97: end Nenue@97: for i = numButtons+1, #self.Artifact do Nenue@97: print('hide', i) Nenue@97: self.Artifact[i]:Hide() Nenue@97: end Nenue@97: Nenue@97: Nenue@97: Nenue@97: self:SetWidth(64*3+ 16) Nenue@97: self:SetHeight(8 + self.SummaryHeader:GetHeight() + 64) Nenue@97: self:Reanchor() Nenue@97: Nenue@97: end Nenue@97: Nenue@97: function ap:ScanBag(id) Nenue@97: print('|cFF00FFFFScanBag()|r', id, IsBagOpen(id), GetContainerNumSlots(id)) Nenue@97: local numSlots = GetContainerNumSlots(id) Nenue@97: local requiresUpdate Nenue@97: if numSlots == 0 then Nenue@97: return nil Nenue@97: end Nenue@97: Nenue@97: Nenue@97: self.profile.bagslots[id] = self.profile.bagslots[id] or {} Nenue@97: table.wipe(self.profile.bagslots[id]) Nenue@97: local bagData = self.profile.bagslots[id] Nenue@97: bagData.totalAP = 0 Nenue@97: for slotID = 1, numSlots do Nenue@97: local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(id, slotID) Nenue@97: local itemID = GetContainerItemID(id, slotID) Nenue@97: Nenue@97: if link then Nenue@97: self.tooltip:SetOwner(self, 'ANCHOR_NONE') Nenue@97: self.tooltip:SetHyperlink(link) Nenue@97: self.tooltip:Show() Nenue@97: local numLines = self.tooltip:NumLines() Nenue@97: if numLines >= 3 then Nenue@97: local subText = _G[TOOLTIP_NAME .. 'TextLeft2']:GetText() Nenue@97: if subText and subText:match(ARTIFACT_POWER) then Nenue@97: for i = 3, numLines do Nenue@97: local text = _G[TOOLTIP_NAME .. 'TextLeft'.. i]:GetText() Nenue@97: if text and text:match(ARTIFACT_POWER) then Nenue@97: text = text:gsub('[,%D]', '') Nenue@97: print(link, '-', tonumber(text)) Nenue@97: local itemAP = tonumber(text) Nenue@97: if itemAP then Nenue@97: bagData.numItems = (bagData.numItems or 0) + 1 Nenue@97: bagData.totalAP = (bagData.totalAP or 0) + itemAP Nenue@97: bagData.items = bagData.items or {} Nenue@97: if not bagData.items[itemID] then Nenue@97: requiresUpdate = true Nenue@97: bagData.numUnique = (bagData.numUnique or 0) + 1 Nenue@97: end Nenue@97: bagData.items[itemID] = (bagData.items[itemAP] or 0) + 1 Nenue@97: end Nenue@97: end Nenue@97: end Nenue@97: end Nenue@97: end Nenue@97: end Nenue@97: Nenue@97: if self.profile.artifacts[itemID] then Nenue@97: print('artfiact weapon', itemID, link, id, slotID) Nenue@97: self.profile.artifacts[itemID].containerID = id Nenue@97: self.profile.artifacts[itemID].slotID = slotID Nenue@97: end Nenue@97: Nenue@97: end Nenue@97: Nenue@97: return requiresUpdate Nenue@97: end Nenue@97: Nenue@97: function ap:ScanAllBags() Nenue@97: print('|cFFFF0088ScanAllBags()|r') Nenue@97: Nenue@97: local bagID = tremove(BAGS_TO_SCAN, 1) Nenue@97: while bagID do Nenue@97: self.updateSummary = self:ScanBag(bagID) or self.updateSummary Nenue@97: bagID = tremove(BAGS_TO_SCAN, 1) Nenue@97: end Nenue@97: Nenue@97: if self.updateSummary then Nenue@97: print('tripped updater') Nenue@97: self.bankAP = 0 Nenue@97: self.bagAP = 0 Nenue@97: for id, bagData in pairs(self.profile.bagslots) do Nenue@97: print(id, GetBagName(id), bagData.totalAP) Nenue@97: id = tonumber(id) Nenue@97: if bagData.totalAP then Nenue@97: if (id == BANK_CONTAINER) or (id >= 5) then Nenue@97: self.bankAP = self.bankAP + bagData.totalAP Nenue@97: else Nenue@97: self.bagAP = self.bagAP + bagData.totalAP Nenue@97: end Nenue@97: end Nenue@97: Nenue@97: end Nenue@97: self.lastUpdate = GetTime() Nenue@97: self:Update() Nenue@97: end Nenue@97: self.updateSummary = nil Nenue@97: end Nenue@97: Nenue@97: VeneerArtifactButtonMixin = {} Nenue@97: function VeneerArtifactButtonMixin:Update() Nenue@97: Nenue@97: if self.actualLevel ~= self.level then Nenue@97: self.Level:SetText(self.actualLevel) Nenue@97: self.Level:SetTextColor(0,1,0) Nenue@97: self.CurrentXP:SetText(self.adjustedXP) Nenue@97: self.CurrentXP:SetTextColor(0,1,0) Nenue@97: else Nenue@97: self.Level:SetText(self.level, 1, 1, 1) Nenue@97: self.Level:SetTextColor(1,1,1) Nenue@97: self.CurrentXP:SetText(self.currentXP) Nenue@97: self.CurrentXP:SetTextColor(1,1,0) Nenue@97: end Nenue@97: Nenue@97: if self.isEquipped then Nenue@97: self:SetNormalTexture([[Interface\Buttons\ButtonHilight-Square]]) Nenue@97: self:GetNormalTexture():SetBlendMode('ADD') Nenue@97: self:GetNormalTexture():SetVertexColor(0,1,0) Nenue@97: else Nenue@97: self:SetNormalTexture(nil, 'ADD') Nenue@97: end Nenue@97: Nenue@97: self:ClearAllPoints() Nenue@97: if self.relativeFrame then Nenue@97: self:SetPoint('BOTTOMLEFT', self.relativeFrame, 'BOTTOMRIGHT', 4, 0) Nenue@97: else Nenue@97: self:SetPoint('BOTTOMLEFT', 4, 4) Nenue@97: end Nenue@97: Nenue@97: Nenue@97: Nenue@97: self.Icon:SetTexture(self.texture) Nenue@97: self.Name:SetText(self.name) Nenue@97: self:SetSize(64,64) Nenue@97: end Nenue@97: Nenue@97: function VeneerArtifactButtonMixin:OnEnter() Nenue@97: GameTooltip:SetOwner(self, 'ANCHOR_CURSOR') Nenue@97: GameTooltip:SetText(self.name) Nenue@97: GameTooltip:AddLine(self.currentXP, 1, 1, 0) Nenue@97: if self.adjustedXP ~= self.currentXP then Nenue@97: GameTooltip:AddLine(self.adjustedXP, 0, 1, 1) Nenue@97: end Nenue@97: Nenue@97: Nenue@97: GameTooltip:Show() Nenue@97: end Nenue@97: function VeneerArtifactButtonMixin:OnLeave() Nenue@97: if GameTooltip:IsOwned(self) then Nenue@97: GameTooltip:Hide() Nenue@97: end Nenue@97: end Nenue@97: Nenue@97: function VeneerArtifactButtonMixin:OnClick(button, down) Nenue@97: if self.isEquipped then Nenue@97: SocketInventoryItem(16) Nenue@97: else Nenue@97: SocketContainerItem(self.containerID, self.slotID) Nenue@97: end Nenue@97: end