diff Modules/ArtifactPower.lua @ 99:74d6d97a2d24 v7.1.5-r100

- artifact progress visualizations, green for current, blue for attainable - force fishing artifact to list last - support for fishing artifact power
author Nenue
date Fri, 20 Jan 2017 19:40:55 -0500
parents dadddb8a551f
children f32b63c93275
line wrap: on
line diff
--- a/Modules/ArtifactPower.lua	Tue Jan 17 09:49:15 2017 -0500
+++ b/Modules/ArtifactPower.lua	Fri Jan 20 19:40:55 2017 -0500
@@ -6,7 +6,9 @@
 
 local print = DEVIAN_WORKSPACE and function(...) print('VnAP', ...) end or nop
 VeneerArtifactPowerMixin = {
-
+  numItems = 0,
+  Tokens = {},
+  ItemButtons = {},
   anchorPoint = 'TOP',
   anchorFrom = 'TOP',
 }
@@ -27,6 +29,10 @@
   3975000, 4175000, 4385000, 4605000
 }
 
+local FRAME_LIST = {'ContainerFrame1', 'BankFrame'}
+local BAG_FRAMES = {'ContainerFrame1'}
+local BANK_FRAMES = {'BankFrame'}
+
 function ap:OnLoad()
   self:RegisterEvent('BAG_UPDATE') -- use to obtain bag IDs to scan
   self:RegisterEvent('BAG_UPDATE_DELAYED') -- use to trigger actual scan activity
@@ -34,9 +40,9 @@
   self:RegisterEvent('BANKFRAME_CLOSED')  -- " " "
   self:RegisterEvent('ARTIFACT_UPDATE')    -- when artifact data has changed
   self:RegisterEvent('ARTIFACT_XP_UPDATE') -- when artifact xp has changed (but not necessarily data)
-  self:RegisterEvent('MODIFIER_STATE_CHANGED')
   self:RegisterEvent('PLAYER_REGEN_ENABLED')
   self:RegisterEvent('PLAYER_REGEN_DISABLED')
+  self:RegisterEvent('PLAYER_ENTERING_WORLD')
   Veneer:AddHandler(self, self.anchorPoint, true)
   SLASH_VENEER_AP1 = "/vap"
   SLASH_VENEER_AP2 = "/veneerap"
@@ -56,12 +62,22 @@
   end
 
   self.tooltip = CreateFrame('GameTooltip', TOOLTIP_NAME, self, 'GameTooltipTemplate')
+  tinsert(UISpecialFrames, self:GetName())
+
 
 end
 
-local defaultSettings = {
+local addonCompatibility = {
+  ['Bagnon'] = {
+    BagFrames = {'BagnonFrameinventory'},
+    BankFrames = {'BagnonFramebank'},
+    PostHooks = {'ToggleAllBags', 'ToggleBackpack' },
+    MethodClass = 'Bagnon',
+    MethodHooks = {'BANK_OPENED', 'BANKFRAME_CLOSED'}
+  }
 }
 
+
 function ap:Setup()
   print(self:GetName()..':Setup()')
   local guid = UnitGUID('player')
@@ -72,32 +88,42 @@
   self.profile.artifacts = self.profile.artifacts or {}
   self.updateSummary = true
 
+  local DoTryToShow = function()
+    self:TryToShow()
+  end
+  hooksecurefunc("OpenBackpack", DoTryToShow)
+  hooksecurefunc("CloseBackpack", DoTryToShow)
+
   -- Bagnon compatibility
   -- todo: ArkInventory, Elv, etc
-  if IsAddOnLoaded('Bagnon') then
-    local oToggleAllBags = ToggleAllBags
-    ToggleAllBags =  function()
-      print('|cFFFF0088ToggleAllBags')
-      oToggleAllBags()
-      if BagnonFrameinventory:IsShown() then
-        self:Show()
-      else
-        self.enabled = nil
-        self:Hide()
+  for addon, args in pairs(addonCompatibility) do
+    if IsAddOnLoaded(addon) then
+      for _, name in ipairs(args.BagFrames) do
+        tinsert(FRAME_LIST, name)
+        tinsert(BAG_FRAMES, name)
+      end
+      for _, name in ipairs(args.BankFrames) do
+        tinsert(FRAME_LIST, name)
+        tinsert(BAG_FRAMES, name)
+      end
+      for _, name in ipairs(args.PostHooks) do
+        local oFunc = _G[name]
+        _G[name] = function(...)
+          print('|cFFFF0088' .. name .. '|r', ...)
+          oFunc(...)
+          self:TryToShow()
+        end
+      end
+      local frame = _G[args.MethodClass]
+      if frame then
+        for _, name in ipairs(args.MethodHooks) do
+          hooksecurefunc(frame, name, DoTryToShow)
+        end
       end
     end
-  else
-    hooksecurefunc("OpenBackpack", function()
-      self:Show()
-    end)
-    hooksecurefunc("CloseBackpack", function()
-      self.enabled = nil
-      self:Hide()
-    end)
   end
+end
 
-
-end
 local UNDERLIGHT_ANGLER_ID = 133755
 function ap:SetArtifact(itemID, name, texture, currentXP, pointsSpent)
   print('|cFF00FF00SetArtifact()|r')
@@ -108,6 +134,9 @@
 
 
   if itemID then
+
+    self.currentEquipped = itemID
+
     artifacts[itemID] = artifacts[itemID] or {}
     table.wipe(artifacts[itemID])
     local artifact = artifacts[itemID]
@@ -147,39 +176,79 @@
   end
 end
 
+function ap:Reanchor()
+  if Veneer then
+    Veneer:DynamicReanchor()
+  end
+end
+
 function ap:OnShow()
+  print('|cFFFFFF00OnShow()|r')
   self.enabled = true
-  self:Update()
-  Veneer:DynamicReanchor()
+  self:ScanAllBags()
+  self:Reanchor()
+  if not self.postShowSetup then
+    self.postShowSetup = true
+    hooksecurefunc("HideUIPanel", function() self:TryToShow() end)
+  end
 end
 function ap:OnHide()
-  Veneer:DynamicReanchor()
+  print('|cFF88FF00OnHide()|r')
+  self:Reanchor()
 end
-
 function ap:OnEnter()
 
   GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
 
+
   GameTooltip:AddLine(self.bagAP)
   GameTooltip:AddLine(self.bankAP)
 
 end
 
+function ap:TryToShow()
+
+  print('|cFFFFFF00TryToShow()')
+
+  if not InCombatLockdown() then
+    for _, name in ipairs(FRAME_LIST) do
+      --print(name, (_G[name] and _G[name]:IsShown()))
+      if _G[name] and _G[name]:IsShown() then
+        if self:IsShown() then
+          self:Update()
+        else
+          self:Show()
+        end
+        return
+      end
+    end
+  end
+
+
+  self:Hide()
+end
+
+
 function ap:OnEvent(event, ...)
-  print(self:GetName()..':OnEvent()', event, ...)
-  if event == 'BAG_UPDATE' then
+  print('|cFF00FF88OnEvent()', event, ...)
+  if event == 'PLAYER_ENTERING_WORLD' then
+    self:TryToShow()
+  elseif event == 'BAG_UPDATE' then
     local containerID = ...
     self:QueueBag(containerID)
   elseif event == 'PLAYER_BANKSLOTS_CHANGED' then
-    self:ScanAllBags(true)
-    self:Update()
+    self:ScanAllBags()
   elseif event == 'BAG_UPDATE_DELAYED' then
-    self:ScanAllBags(self.bankAccess)
+    if not self.firstHit then
+      self.firstHit = true
+    else
+      self:ScanAllBags()
+    end
   elseif event == 'BANKFRAME_OPENED' then
     self.bankAccess = true
-    self:ScanAllBags(true)
+    self:ScanAllBags()
   elseif event == 'BANKFRAME_CLOSED' then
-    self.bankAccess = false
+    self.bankAccess = nil
   elseif event == 'ARTIFACT_UPDATE' then
     local newItem = ...
     if newItem then
@@ -193,7 +262,11 @@
     self:ScanAllBags(self.bankAccess)
   elseif event == 'PLAYER_REGEN_ENABLED' then
     if self.enabled then
-      self:Show()
+      if self.queuedScan then
+        self:ScanAllBags(self.backAccess)
+      else
+        self:TryToShow()
+      end
     end
 
   elseif event == 'PLAYER_REGEN_DISABLED' then
@@ -208,6 +281,7 @@
 
 function ap:Update()
   if not self:IsShown() then
+    print('|cFFFF4400Update()|r')
     return
   end
   print('|cFF00FFFFUpdate()|r')
@@ -217,7 +291,7 @@
     bankText = '|cFFFF0000Open bank frame to count all AP|r '
   else
     if (self.bagAP + self.bankAP) == 0 then
-      bankText = '|cFF00FFFFNo Items|r'
+      bankText = '|cFFFF4400No Artifact Power tokens on hand|r'
     else
       if self.bagAP and (self.bagAP > 0) then
         bankText = '|cFFFFFFFF' .. tostring(self.bagAP) .. '|r'
@@ -227,17 +301,20 @@
       end
     end
   end
+  if self.fishingAP and self.fishingAP >= 1 then
+    bankText = (bankText and (bankText .. ' ') or '') .. '|cFF0088FF' .. tostring(self.fishingAP) .. ' fishing AP|r'
+  end
+
   self.SummaryHeader:SetText(bankText)
 
   -- Artifact icons, in no particular order
-  local equippedID = C_ArtifactUI.GetEquippedArtifactInfo()
+  self.equippedID = C_ArtifactUI.GetEquippedArtifactInfo()
   local numButtons = 0
-  local lastFrame
-  local fishingRod, fishingID, fishingData
+  local lastFrame = self
+  local fishingID, fishingData
   local index, button
   for itemID, artifact in pairs(self.profile.artifacts) do
-    local isFishingRod = (itemID == UNDERLIGHT_ANGLER_ID)
-    if isFishingRod  then
+    if (itemID == UNDERLIGHT_ANGLER_ID)  then
       if VeneerData.ArtifactPower.EnableFishing then
         fishingID = itemID
         fishingData = artifact
@@ -246,22 +323,25 @@
     else
       numButtons = numButtons + 1
       button = self.Artifact[numButtons]
-      lastFrame = button:SetButton(itemID, artifact, lastFrame)
+      button.relativeFrame = lastFrame
+      lastFrame = button:SetButton(itemID, artifact, numButtons, (self.equippedID == itemID))
     end
 
   end
 
   if fishingData then
     numButtons = numButtons + 1
-    local button = self.Artifact[GetNumSpecializations()+1]
-    button:SetButton(fishingID, fishingData, lastFrame)
+    local button = self.Artifact[numButtons]
+    button.relativeFrame = lastFrame
+    button:SetButton(fishingID, fishingData, numButtons, self.equippedID == fishingID)
   end
 
-  for i = numButtons+ (fishingRod and 2 or 1), #self.Artifact do
+  for i = numButtons+ 1, #self.Artifact do
     print('hide', i)
     self.Artifact[i]:Hide()
   end
 
+  self:UpdateItemButtons()
 
 
   self:SetWidth(64*numButtons + 4 * (numButtons+1))
@@ -270,6 +350,75 @@
 
 end
 
+
+function ap:UpdateItemButtons()
+  print('|cFF00FFFFUpdateItemButtons()|r')
+  local lastFrame, upFrame
+  local numButtons = 0
+  for index, button in ipairs(self.Tokens) do
+    if button.numItems >= 1 then
+      if button.itemName then
+        self:SetItemAction(button)
+      end
+
+      button:ClearAllPoints()
+      numButtons = numButtons + 1
+      print(index, button:GetID(), button.Icon:GetTexture())
+      if numButtons == 1 then
+        button:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', 0, -2)
+        upFrame = button
+      elseif mod(numButtons,8) == 1 then
+        button:SetPoint('TOPLEFT', upFrame, 'BOTTOMLEFT', 0, -2)
+        upFrame = button
+      else
+        button:SetPoint('TOPLEFT', lastFrame, 'TOPRIGHT', 2, 0)
+      end
+      button.Count:SetText(button.numItems)
+      lastFrame = button
+      button:Show()
+    else
+
+      button:Hide()
+    end
+
+  end
+
+end
+
+function ap:SetItemAction(button, name)
+  name = name or self.itemName
+  if InCombatLockdown() then
+    self.itemName = name
+    return
+  else
+      button:SetAttribute('*type*','item')
+    button:SetAttribute('*item*', name)
+  end
+end
+
+function ap:GetItemButton(itemID, texture, itemAP)
+  print('|cFF00FFFFGetItemButton()|r', itemID, texture, itemAP)
+  local button = self.ItemButtons[itemID]
+  if not button then
+    button = CreateFrame('Button', 'VeneerAPToken'..itemID, self, 'VeneerItemButton')
+    button:SetPushedTexture([[Interface\Buttons\UI-Quickslot-Depress]])
+    button:SetHighlightTexture([[Interface\Buttons\ButtonHilight-Square]],"ADD")
+    button:SetID(itemID)
+    button.numItems = 0
+    button.Icon:SetTexture(texture)
+    button.Label:SetText(itemAP)
+    button:RegisterForClicks("AnyUp")
+    self:SetItemAction(button, GetItemInfo(itemID))
+
+    print('  created')
+    self.ItemButtons[itemID] = button
+    self.numItems = self.numItems +  1
+  end
+
+  button.numItems = button.numItems + 1
+  return button
+end
+
 function ap:ScanBag(id)
   print('|cFF00FFFFScanBag()|r', id, IsBagOpen(id), GetContainerNumSlots(id))
   local numSlots = GetContainerNumSlots(id)
@@ -283,6 +432,10 @@
   table.wipe(self.profile.bagslots[id])
   local bagData = self.profile.bagslots[id]
   bagData.totalAP = 0
+  bagData.fishingAP = 0
+  bagData.items = bagData.items or {}
+  table.wipe(bagData.items)
+
   for slotID = 1, numSlots do
     local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(id, slotID)
     local itemID = GetContainerItemID(id, slotID)
@@ -305,15 +458,28 @@
                 requiresUpdate = true
                 bagData.numItems = (bagData.numItems or 0) + 1
                 bagData.totalAP = (bagData.totalAP or 0) + itemAP
-                bagData.items = bagData.items or {}
-                if not bagData.items[itemID] then
-                  bagData.numUnique = (bagData.numUnique or 0) + 1
-                end
-                bagData.items[itemID] = (bagData.items[itemAP] or 0) + 1
+                bagData.items[itemID] = (bagData.items[itemID] or 0) + 1
+
+
+                local itemButton = self:GetItemButton(itemID, texture, itemAP)
               end
             end
           end
         end
+        local fishingText = _G[TOOLTIP_NAME .. 'TextLeft3']:GetText()
+        if fishingText and fishingText:match('fishing artifact') then
+          local fishingAP = fishingText:match("%d+")
+          fishingAP = tonumber(fishingAP)
+          if fishingAP then
+            bagData.fishingItems = (bagData.fishingItems or 0) + 1
+            bagData.fishingAP = (bagData.fishingAP or 0) + fishingAP
+            bagData.items[itemID] = (bagData.items[itemID] or 0) + 1
+            local itemButton = self:GetItemButton(itemID, texture, fishingAP)
+            print(fishingAP, bagData.fishingAP)
+          end
+
+        end
+
       end
     end
 
@@ -329,15 +495,26 @@
 
 local BAG_SLOTS = {0, 1, 2, 3, 4 }
 local BANK_SLOTS = {-1, 5, 6,7, 8, 9, 10, 11, 12}
+local ItemCounts = {}
+function ap:ScanAllBags()
+  if InCombatLockdown() then
+    self.queuedScan = true
+    return
+  end
+  self.queuedScan = nil
 
-function ap:ScanAllBags(checkBank)
   print('|cFFFF0088ScanAllBags()|r')
 
+  for _, button in ipairs(self.Tokens) do
+    button.numItems = 0
+  end
+
+
   for _, bagID in ipairs(BAG_SLOTS) do
     self:ScanBag(bagID)
   end
 
-  if checkBank then
+  if self.bankAccess then
     for _, bagID in ipairs(BANK_SLOTS) do
       self:ScanBag(bagID)
     end
@@ -345,6 +522,9 @@
 
   self.bankAP = 0
   self.bagAP = 0
+  self.fishingAP = 0
+
+  table.wipe(ItemCounts)
   for id, bagData in pairs(self.profile.bagslots) do
     print(id, GetBagName(id), bagData.totalAP)
     id = tonumber(id)
@@ -355,16 +535,19 @@
         self.bagAP = self.bagAP + bagData.totalAP
       end
     end
+    if bagData.fishingAP then
+      self.fishingAP = self.fishingAP + bagData.fishingAP
+    end
 
   end
   self.lastUpdate = GetTime()
-  self:Update()
-  self.updateSummary = nil
+  self:TryToShow()
 end
 
 VeneerArtifactButtonMixin = {}
 
-function VeneerArtifactButtonMixin:SetButton(itemID, artifact, lastFrame)
+function VeneerArtifactButtonMixin:SetButton(itemID, artifact, index, equipped)
+  print(itemID, index)
   print(artifact.name, artifact.texture, artifact.currentXP)
   self:SetID(itemID)
   for k,v in pairs(artifact) do
@@ -374,8 +557,10 @@
 
   -- this can change between artifact parses
   local potentialPoints = self.actualLevel
-  local totalAP = (itemID == UNDERLIGHT_ANGLER_ID) and ((self:GetParent().bankAP or 0) + (self:GetParent().bagAP or 0)) or (self.fishingAP or 0)
+  local totalAP = (itemID ~= UNDERLIGHT_ANGLER_ID) and ((self:GetParent().bankAP or 0) + (self:GetParent().bagAP or 0)) or (self:GetParent().fishingAP or 0)
+  print(totalAP)
   local potentialXP = self.actualXP + totalAP
+
   self.potentialXP = potentialXP
   local potentialCost = C_ArtifactUI.GetCostForPointAtRank(potentialPoints)
   while potentialXP >= potentialCost do
@@ -389,9 +574,15 @@
   self.potentialAdjustedXP = potentialXP
 
 
+  if index ~= 1 then
+    self:ClearAllPoints()
+    self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPRIGHT', 4, 0)
+  else
+    self:ClearAllPoints()
+    self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPLEFT', 4, -4)
+  end
 
-  self.isEquipped = (equippedID == itemID)
-  self.relativeFrame = lastFrame
+  self.isEquipped = equipped
   self:Update()
   self:Show()
   return self
@@ -399,18 +590,37 @@
 
 function VeneerArtifactButtonMixin:Update()
 
+  local r, g, b = 1, 1, 1
+  local lR, lG, lB = 1, 1, 0
+  local levelText = self.level
+  local xpValue = self.currentXP
+  local costValue = self.cost
   if self.actualLevel ~= self.level then
-    self.Level:SetText(self.actualLevel)
-    self.Level:SetTextColor(0,1,0)
-    self.CurrentXP:SetText(self.adjustedXP)
-    self.CurrentXP:SetTextColor(0,1,0)
-  else
-    self.Level:SetText(self.level, 1, 1, 1)
-    self.Level:SetTextColor(1,1,1)
-    self.CurrentXP:SetText(self.currentXP)
-    self.CurrentXP:SetTextColor(1,1,0)
+    levelText, r,g,b = self.actualLevel, 0,1,0
+    xpValue, costValue, lR, lG, lB = self.actualXP, self.actualCost, 0, 1, 0
+  elseif self.potentialLevel ~= self.level then
+    levelText, r, g, b = self.potentialLevel, 0,1,1
+    xpValue, costValue, lR, lG, lB = self.potentialAdjustedXP, self.potentialCost, 0,1,0
+
   end
 
+  if xpValue >= 100000 then
+    xpValue = tostring(floor(xpValue/1000))..'k'
+  elseif xpValue > 1000 then
+    xpValue = tostring(floor(xpValue/100)/10)..'k'
+  end
+  if costValue >= 100000 then
+    costValue = tostring(floor(costValue/1000))..'k'
+  elseif costValue >= 1000 then
+    costValue = tostring(floor(costValue/100)/10)..'k'
+  end
+
+
+  self.Level:SetText(levelText)
+  self.Level:SetTextColor(r, g, b)
+  self.CurrentXP:SetText(xpValue)
+  self.CurrentXP:SetTextColor(lR, lG, lB)
+
   if self.isEquipped then
     self:SetNormalTexture([[Interface\Buttons\ButtonHilight-Square]])
     self:GetNormalTexture():SetBlendMode('ADD')
@@ -419,31 +629,27 @@
     self:SetNormalTexture(nil, 'ADD')
   end
 
-  self:ClearAllPoints()
-  if self.relativeFrame then
-    self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPRIGHT', 4, 0)
-  else
-    self:SetPoint('TOPLEFT', 4, -4)
-  end
   local currentProgress = (self.currentXP < self.cost) and (self.currentXP / self.cost) or 1
   if self.level <= 53 then
+
     self.CurrentProgress.animateFrom = self.CurrentProgress:GetHeight() or 1
     self.CurrentProgress.animateTo = currentProgress * self:GetHeight()
     self.CurrentProgress:Show()
   else
     self.CurrentProgress:Hide()
   end
-  print(currentProgress)
+
   if self.potentialXP > self.currentXP then
-    local projectedProgress = (self.potentialAdjustedXP < self.potentialCost) and (self.potentialAdjustedXP / self.potentialCost) or 1
-    print(projectedProgress)
+    local projectedProgress = (self.potentialAdjustedXP < self.potentialCost) and (self.potentialXP / self.potentialCost) or 1
+
     if (projectedProgress > currentProgress) then
       self.AdjustedProgress:SetPoint('BOTTOM', self.CurrentProgress, 'TOP')
       projectedProgress = projectedProgress - currentProgress
-      print(projectedProgress)
+
     else
       self.AdjustedProgress:SetPoint('BOTTOM', self, 'BOTTOM')
     end
+    print('show potential', currentProgress, projectedProgress)
     self.AdjustedProgress.animateFrom = self.AdjustedProgress:GetHeight() or 1
     self.AdjustedProgress.animateTo = projectedProgress * self:GetHeight()
 
@@ -452,8 +658,8 @@
     self.AdjustedProgress:Hide()
   end
 
+
   self.Icon:SetTexture(self.texture)
-  self.Name:SetText(self.name)
   self:SetSize(64,64)
 end
 
@@ -495,10 +701,14 @@
   GameTooltip:AddLine(tostring(self.currentXP) .. ' / '..tostring(self.cost), 1, 1, 0)
   if self.potentialXP > self.currentXP then
     GameTooltip:AddLine(tostring(self.potentialXP) .. ' potential XP', 0, 1, 1)
-    if self.adjustedXP ~= self.potentialXP then
-      GameTooltip:AddLine(tostring(self.potentialAdjustedXP) .. ' / ' .. tostring(self.potentialAdjustedCost).. ' after spending', 0, 1, 0)
+    if self.potentialAdjustedXP ~= self.potentialXP then
+      GameTooltip:AddLine(tostring(self.potentialAdjustedXP) .. ' / ' .. tostring(self.potentialCost).. ' after', 0, 1, 0)
     end
   end
+  if self.actualLevel ~= self.level then
+    GameTooltip:AddLine(tostring(self.actualLevel - self.level) .. ' points unlocked', 0, 1, 1)
+  end
+
   GameTooltip:Show()
 end
 function VeneerArtifactButtonMixin:OnLeave()