view Modules/PaperDoll.lua @ 115:8c94bee4fdfc

- AddHandler simplified - Centralized combat start/stop hooks - WorldState removed
author Nenue
date Tue, 28 Mar 2017 07:02:26 -0400
parents 3992b41c637e
children ddfe19d70a34
line wrap: on
line source
-- Veneer
-- PaperDoll.lua
-- Created: 8/16/2016 8:18 AM
-- %file-revision%
-- Displays the item level and modifications of character sheet equipment, including artifact power
local print = DEVIAN_WORKSPACE and function(...) print('PaperDoll', ...) end or nop
local artifactSlot
local slot_overlays = {}
VeneerPaperDollMixin = {
  anchorFrame = 'CharacterFrame',
  anchorPoint = 'TOPLEFT',
  KnownRelics = {},
}

local relic_slot_paths = {
  Arcane = {"Relic-Arcane-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.849609375, 0.919921875, 0.1181640625, 0.1884765625, false, false},
  Blood = {"Relic-Blood-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.921875, 0.9921875, 0.1181640625, 0.1884765625, false, false},
  Fel = {"Relic-Fel-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.572265625, 0.642578125, false, false},
  Fire = {"Relic-Fire-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.669921875, 0.740234375, 0.572265625, 0.642578125, false, false},
  Frost = {"Relic-Frost-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.7421875, 0.8125, 0.572265625, 0.642578125, false, false},
  Holy = {"Relic-Holy-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.814453125, 0.884765625, 0.572265625, 0.642578125, false, false},
  Iron = {"Relic-Iron-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.88671875, 0.95703125, 0.572265625, 0.642578125, false, false},
  Life = {"Relic-Life-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.64453125, 0.71484375, false, false},
  Shadow = {"Relic-Shadow-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.716796875, 0.787109375, false, false},
  Water = {"Relic-Water-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.7890625, 0.859375, false, false},
  Wind = {"Relic-Wind-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.861328125, 0.931640625, false, false},
}

local slots_left = {'TOPLEFT', 'TOPRIGHT', 1, 0, 'TOPLEFT', 'BOTTOMLEFT', 0, -1}
local slots_right = {'TOPRIGHT', 'TOPLEFT', -1, 0, 'TOPRIGHT', 'BOTTOMRIGHT', 0, -1}
local slots_bottomleft = {'BOTTOMRIGHT', 'TOPRIGHT', 0, 1, 'BOTTOMRIGHT', 'TOPRIGHT', 0, 1 }
local slots_bottomright = {'BOTTOMLEFT', 'TOPLEFT', 0, -1, 'BOTTOMLEFT', 'TOPLEFT', 0, 1}

local slot_anchors = {
  [1] = slots_left,
  [2] = slots_left,
  [3] = slots_left,
  [15] = slots_left,
  [5] = slots_left,
  [9] = slots_left,

  [10] = slots_right,
  [6] = slots_right,
  [7] = slots_right,
  [8] = slots_right,
  [11] = slots_right,
  [12] = slots_right,
  [13] = slots_right,
  [14] = slots_right,
  
  [16] = slots_bottomleft,
  [17] = slots_bottomright,
}


function VeneerPaperDollMixin:OnLoad()
  hooksecurefunc("PaperDollItemSlotButton_Update", function(...)
    self:GetSlotButton(PaperDollItemsFrame, ...)
  end)

  hooksecurefunc("PaperDollFrame_UpdateStats", function(...)
    self:GetStats(PaperDollItemsFrame, ...)
  end)

  self:RegisterEvent('INSPECT_READY')
  Veneer:AddHandler(self)
end

function VeneerPaperDollMixin:SetupInspectFrame()
  hooksecurefunc("InspectPaperDollItemSlotButton_Update", function(...)
    self:GetSlotButton(InspectFrame, ...)
  end)
  self:RegisterEvent('INSPECT_READY')
end
function VeneerPaperDollMixin:SetupArtifactUI()
end

function VeneerPaperDollMixin:Setup()
  VeneerData.PaperDoll = VeneerData.PaperDoll or {}
  VeneerData.PaperDoll.KnownRelics = VeneerData.PaperDoll.KnownRelics or {}
  self.KnownRelics = VeneerData.PaperDoll.KnownRelics

  self:RegisterEvent('UNIT_INVENTORY_CHANGED')
  self:RegisterEvent('PLAYER_EQUIPMENT_CHANGED')
  self:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED')
  self:RegisterEvent('ARTIFACT_UPDATE')

  self:MarkForUpdate()
end

function VeneerPaperDollMixin:MarkForUpdate()
  for frame, overlays in pairs(slot_overlays) do
    for slot, overlay in pairs(overlays) do
      if overlay:IsVisible() then
        overlay:Update()
      else
        overlay.isDirty = true
      end
    end
  end
end

function VeneerPaperDollMixin:GetStats()
end
function VeneerPaperDollMixin:GetSlotButton(panel, frame)
  print('|cFF00FF88'..self:GetName()..':GetSlotButton()', frame:GetName(), frame:GetID())
  local slot = frame:GetID()
  local unit = panel.unit or 'player'
  if slot_anchors[slot] then
    slot_overlays[panel] = slot_overlays[panel] or {}
    local overlay = slot_overlays[panel][slot]
    if not overlay then
      print('creating slot overlay', slot)
      overlay = CreateFrame('Frame', 'VeneerPaperDollSlot' .. unit .. slot, frame, 'VeneerPaperDollSlotInfoTemplate')
      overlay:SetID(slot)
      slot_overlays[panel][slot] = overlay
      overlay.checkRelic = frame.checkRelic

      local anchorPoint, relativePoint, dX, dY, statPoint, statRelative, statdX, statdY = unpack(slot_anchors[slot])
      local offset = 7
      overlay:SetPoint(anchorPoint, frame, relativePoint, dX * offset, dY * offset)
      overlay:SetSize(frame:GetWidth()*3, frame:GetHeight())

      local relativeFrame = overlay
      for i, region in ipairs(overlay.StatsLeft) do
        region:ClearAllPoints()
        print(statPoint, relativeFrame, (i == 1) and statPoint or statRelative)
        region:SetPoint(statPoint, relativeFrame, (i == 1) and statPoint or statRelative, 0, 0)
        relativeFrame = region
      end
      if slot == 16 then
        overlay.Sockets:ClearAllPoints()
        overlay.Sockets:SetPoint('BOTTOM', CharacterFrameInsetBg, 'BOTTOM', 0, frame:GetHeight() + 14)
        overlay.ItemLevel:SetFontObject(VeneerNumberFontLarge)
        overlay.ItemLevel:ClearAllPoints()
        overlay.ItemLevel:SetPoint('BOTTOM', overlay.Sockets, 'TOP', 0, 4)
        if unit == 'player' then
          artifactSlot = overlay
        end

      end

      print(overlay.Sockets:GetPoint(1))
      overlay.anchors = slot_anchors[slot]
    end

    overlay.unit = unit
    overlay.checkRelic = (unit == 'player' and slot == 16)


    if frame.hasItem then
      overlay.isDirty = true
      overlay:Show()
    else
      overlay:Hide()
    end
  end
end



function VeneerPaperDollMixin:OnEvent(event, arg)
  print(event, arg)
  if event == 'ADDON_LOADED' then
    if arg == 'Blizzard_InspectUI' then
      self:SetupInspectFrame()
    end
    if arg == 'Blizzard_ArtifactUI' then
      self:SetupArtifactUI()
      self:MarkForUpdate()
    end
  elseif event == 'ARTIFACT_UPDATE' then
    if artifactSlot then
      print('just udpate artifact slot')
      artifactSlot:Update(true)
    end
  else
    if (event == 'PLAYER_SPECIALIZATION_CHANGED' or event == 'UNIT_INVENTORY_CHANGED') then
      if arg ~= 'player' then
        return
      end
    end
    self:MarkForUpdate()
  end
end


VeneerPaperDollSlotMixin = {}

function VeneerPaperDollSlotMixin:OnLoad()
  self.SocketText = {}
  self.SocketType = {}
  self.SocketLink = {}
end
function VeneerPaperDollSlotMixin:OnShow()
  if self.isDirty then
    self:Update()
  end
end
function VeneerPaperDollSlotMixin:OnUpdate()
  if self.isDirty then
    --print('|cFF00FF00pushing update for', self:GetID())
    self:Update()
  end

  if self.checkRelic then
    self.tooltipLink = nil
    for i = 1, 3 do
      if self.SocketLink[i] and self.Sockets.SocketIcon[i]:IsMouseOver() then
        self.tooltipLink = self.SocketLink[i]
      end
    end

    if self.tooltipLink then
      if not GameTooltip:IsOwned(self) then
        GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
        GameTooltip:SetHyperlink(self.tooltipLink)

        GameTooltip:Show()
      end
    else
      if GameTooltip:IsOwned(self) then
        GameTooltip:Hide()
      end
    end
  end
end

function VeneerPaperDollSlotMixin:UpdateRelicInfo()


  local itemID =  GetInventoryItemID(self.unit, 16)
  if not itemID then
    return
  end
  print('|cFF00FFFFRelic Sweep:', itemID)


  local guid = UnitGUID(self.unit or 'player')
  local relicCache = VeneerPaperDoll.KnownRelics[guid] and VeneerPaperDoll.KnownRelics[guid][itemID]
  if VeneerPaperDoll.KnownRelics[guid] then
    for k, v in pairs(VeneerPaperDoll.KnownRelics[guid]) do
      if tonumber(k) and tonumber(k) < 72 then
        VeneerPaperDoll.KnownRelics[guid][k] = nil
      end
    end
  end


  if not relicCache then
    relicCache = {}
    VeneerPaperDoll.KnownRelics[guid] = VeneerPaperDoll.KnownRelics[guid] or {}
    VeneerPaperDoll.KnownRelics[guid][itemID] = relicCache
  end

  local numRelics = C_ArtifactUI.GetNumRelicSlots()
  local isEquipped = C_ArtifactUI.IsViewedArtifactEquipped()
  local tooltip = VeneerPaperDollTooltip
  tooltip:SetOwner(self, 'ANCHOR_NONE')
  self.hasRelicSlots = true
  if numRelics and isEquipped then
    print('Relic Query:', itemID, numRelics)
    for i = 1, numRelics do
      local lockedReason, relicName, relicIcon, relicLink = C_ArtifactUI.GetRelicInfo(i);
      local relicType = C_ArtifactUI.GetRelicSlotType(i);
      print(relicType)
      if relicType then
        if relicLink then
        tooltip:SetHyperlink(relicLink)
          print(tooltip:NumLines())

          local line1 = _G['VeneerPaperDollTooltipTextLeft2']
          local line2 = _G['VeneerPaperDollTooltipTextLeft3']
          local text1 = line1 and line1:GetText()
          local text2 = line2 and line2:GetText()
          if text1 or text2 then
            self.SocketText[i] = text1:match('Item Level (%d+)') or text2:match('Item Level (%d+)')
          end
        end

        self.SocketInfo[i] = relicIcon or 0
        self.SocketType[i] = relicType
        self.SocketLink[i] = relicLink
        print('storing', i, self.SocketInfo[i], self.SocketText[i], self.SocketType[i], self.SocketLink[i])
      else


        self.SocketInfo[i] = "Interface\\CharacterFrame\\TempPortraitAlphaMask"
        self.SocketType[i] = nil
        self.SocketLink[i] = nil
      end

      relicCache[i] = {self.SocketInfo[i], self.SocketText[i], self.SocketType[i], self.SocketLink[i]}
    end
  else

    for i = 1, 3 do
      if relicCache[i] then
        local relicIcon, relicText, relicType, relicLink = unpack(relicCache[i])

        print('loading', i, relicIcon, relicText, relicType, relicLink)
        self.SocketInfo[i] = relicIcon
        self.SocketText[i] = relicText
        self.SocketType[i] = relicType
        self.SocketLink[i] = relicLink
      end
    end
  end
end

function VeneerPaperDollSlotMixin:Update(forced)
  local id = self:GetID()

  self.SocketInfo = self.SocketInfo or {}
  table.wipe(self.SocketInfo)
  self.ItemLevel:SetText(nil)

  local tooltip = VeneerPaperDollTooltip
  tooltip:SetOwner(self, 'ANCHOR_NONE')
  if forced then
    print('refresh', self.unit, id)
  end

  tooltip:SetInventoryItem(self.unit or 'player', id)
  tooltip:Show()

  local numLines = tooltip:NumLines()
  local numTextures = 0
  local itemLevel
  local itemLevelLine
    --print('|cFFFFFF00Sockets scan:', numLines)
    for i = 1, numLines do
      local line = _G['VeneerPaperDollTooltipTextLeft'..i]
      local text = line and line:GetText()
      if text then
        itemLevel = text:match('Item Level (%d+)')
        if itemLevel then
          self.ItemLevel:SetText(itemLevel)
          break
        end
      end

      local texture = _G['VeneerPaperDollTooltipTexture'..i]
      if texture and texture:IsShown() then
        numTextures = numTextures + 1
        --print('picked up socket', numTextures, texture:GetTexture())
        self.SocketInfo[numTextures] = texture:GetTexture()
      end
    end
  if self.checkRelic then
    self:UpdateRelicInfo()
  end


  local relativeIcon
  local socketsWidth = 0
  local socketsHeight = 24
  for index, icon in ipairs(self.Sockets.SocketIcon) do
    if self.SocketInfo[index] then
      --print('|cFF0088FFsocketInfo|r', index, self.SocketInfo[index])
      icon:ClearAllPoints()

      icon:SetTexture(self.SocketInfo[index])
      icon:SetSize(16, 16)
      icon:Show()
      if index == 1 then
        icon:SetPoint('LEFT', self.Sockets, 'LEFT', 0, 0)
        socketsWidth = socketsWidth + icon:GetWidth()
        socketsHeight = icon:GetHeight()
      else
        if id == 16 then
          icon:SetPoint('LEFT', relativeIcon, 'RIGHT', 14, 0)
          socketsWidth = socketsWidth + 14
        else
          icon:SetPoint('LEFT', relativeIcon, 'RIGHT', 2, 0)
          socketsWidth = socketsWidth + 2
        end
        socketsWidth = socketsWidth + icon:GetWidth()
      end
      print( '|cFFFF4400', icon:GetPoint(1))

      local label = self.Sockets.SocketLabel[index]
      label:ClearAllPoints()
      label:SetPoint('BOTTOM', icon, 'TOP',0, 2)
      label:SetFontObject(VeneerNumberFont)
      label:SetText(self.SocketText[index])

      if self.checkRelic and self.SocketType[index] then
        print(self.SocketType[index])
        local relicAtlasName = ("Relic-%s-Slot"):format(self.SocketType[index]);
        self.Sockets.SocketBg = self.Sockets.SocketBg or {}
        self.Sockets.SocketBg[index] = self.Sockets.SocketBg[index] or self.Sockets:CreateTexture()
        self.Sockets.SocketBg[index]:SetAtlas(relicAtlasName)
        self.Sockets.SocketBg[index]:SetPoint('TOPRIGHT', icon, 'TOPRIGHT', 12, 12)
        self.Sockets.SocketBg[index]:SetPoint('BOTTOMLEFT', icon, 'BOTTOMLEFT', -12,-12)
        --print('', self.SocketType[index], relicAtlasName)
        if self.SocketInfo[index] == 0 then
          icon:SetAtlas("Relic-SlotBG")
        end

        socketsHeight = self.Sockets.SocketBg[index]:GetHeight()
        print(socketsWidth, socketsHeight)
      end


      relativeIcon = icon
    else
      if self.checkRelic and self.Sockets.SocketBg and self.Sockets.SocketBg[index] then
        self.Sockets.SocketBg[index]:SetTexture(nil)
        self.Sockets.SocketLabel[index]:SetText(nil)
      end

      icon:Hide()
    end


  end
  self.Sockets:SetWidth(socketsWidth)
  self.Sockets:SetHeight(socketsHeight)





  self.isDirty = nil
end