view RaidBuffTray.lua @ 25:4b3da1b221de v1.0-beta

- distinction between all possible types of values for the 'isComplete' field - style polish applied to title headers - clickable regions altered to somewhat match those of the blizzard objectives tracker, for more world frame space and quicker user familiarity
author Nenue
date Wed, 13 Apr 2016 11:20:09 -0400
parents 3dbcad2b387d
children
line wrap: on
line source
--- ${PACKAGE_NAME}
-- @file-author@
-- @project-revision@ @project-hash@
-- @file-revision@ @file-hash@
-- Created: 3/20/2016 10:00 PM

local _, A = ...
local B = A.frame
local MODULE = 'BuffFrame'
local M = B:RegisterModule(MODULE)
local displays = B.displays

local parentAnchor, parentFrame, raidbuffsFrame
local band, lshift, CreateFrame = bit.band, bit.lshift, CreateFrame
local raidBuffs = {}
local raidBuffSymbols = {'St', 'HP', 'AP', 'Ha', 'SP', 'Cr', 'Ma', 'MS', 'V' }
local missingBuffs = {}
local playerBuffing, playerCurrentBuff
local playerBuffs = {}
local c, ac, frameSize, frameSpacing, framePosition
local fprint = B.fprint
local NUM_LE_MISSING_RAID_BUFFS = 0
local missingBuffsAnchor


--- Takes a given icon texture and calls the pre-defined function set
M.UpdateBuffStyle = function(buff, style, path)
  local print = fprint()
  local icon = buff.icon
  local symbol = buff.symbol
  path = path or icon.iconPath
  --print(style,  icon.iconStyle)

  if style ~= buff.iconStyle or path ~= buff.iconPath then
    print('|cFF0088FFUpdateBuffStyle(|r',  icon:GetName(), style, path)
    icon.iconStyle = style
    icon.iconPath = path
  else
    --print('|cFF00FF88UpdateBuffStyle(|r',  icon:GetName(), style, path, ') same values, ignore')
    return
  end
  local styleset = B.BuffStyles[style]
  if not path or path == '' then
    print('path is nil/empty')
    icon:SetTexture(1, 1, 1, 1)
    icon:SetVertexColor(unpack(styleset.Color))
  else
    icon:SetTexture(path or icon:GetTexture())
    icon:SetVertexColor(unpack(styleset.Color))
  end

  if symbol and symbol.GetText then
    symbol:SetTextColor(unpack(styleset.TextColor))
    symbol:SetText(buff.symbolName or 'NaW')
  end

  icon:SetBlendMode(styleset.SetBlendMode)
  icon:SetDesaturated(styleset.SetDesaturated)
end

--- Populates a list of targets needing a buff, fired by a handler
local PlayerBuffTodo ={}
M.UpdateBuffStatus = function(aura, filters)
  if not PlayerBuffStatus[aura] then
    PlayerBuffStatus[aura] = {}
  end


  print(UnitClass('player'))
  if IsInGroup() then
    local numBuffed = 0
    local partySize = GetNumGroupMembers()
    local missing = {}
    for i = 1, partySize do
      local unit = 'raid'..i
      if UnitAura(unit, aura, nil, filters) then
        numBuffed = numBuffed + 1
      else
        tinsert(missing, unit)
      end
    end

    PlayerBuffTodo[aura] = missing

  end
end

--- Evaluates buff availability criteria
-- Uses hard returns to avoid over-iterating conditionals, particularly pet family
local function IsBuffAvailable(criteria)
  local available, active = false, false
  local result
  for _, test in ipairs(criteria) do
    if test == true then
      -- it's a passive effect that is always on
      return true, true
    else
      if c.spec then
        if not (result and c.spec == B.PlayerSpec) then
          return false
        end
      end

      if c.talent then
        local talentID, name, texture, selected, available = GetTalentInfoByID(c.talent, GetActiveSpecGroup())
        if not (result and selected) then
          return false
        end
      end

      if c.petFamily then
        local lim = min(5, NUM_PET_STABLE_SLOTS) -- to avoid volatile loop condition
        for p = 1, lim do
          local hasPet = false
          local icon, name, level, family, talent = GetStablePetInfo(p)
          if family == c.petFamily then
            hasPet = true
          end
          if not (result and hasPet) then
            return false
          end
        end
      end

    end
  end
  return true, false
end

--- events: PLAYER_SPECIALIZATION_CHANGED
function M:UpdateBuffsTodo (unit)
  -- buffs vs. auras
  if unit ~= 'player' then
    -- look for changes in the GIST manifest and sort them out
    return
  end

  local class = UnitClass('player')
  local spec = GetSpecialization()
  if not class or
      not spec or
      not IsInGroup() or
      not B.PlayerBuffStatus[class] then
    -- if just logging in, info won't be available for several seconds
    -- if not grouped, don't calc
    -- hide frame
      B.PlayerBuffsActive = function() return false end
    return
  end

  -- verify change
  if B.PlayerCurrentSpec == spec or B.PlayerClass == class then
    return
  end
  B.PlayerCurrentSpec = spec
  B.PlayerClass = class

  local test = B.ClassRaidBuffs
  local buffTypes = {}
  local auraTypes = {}
  for i = 1, NUM_LE_RAID_BUFF_TYPES do
    local name, filters
    if test[i] and test[i][class] then
      playerBuffs[i], name, filters = IsBuffAvailable(test[i][class])
    else
      playerBuffs[i] = nil
    end

    if name then
      B.UpdateBuffStatus(name, filters)
    end
  end
end

-- Called once to setup the ConsolidatedBuffs stencil
local consolidatedBuffsLoaded
M.SetConsolidatedBuffs = function()
  local print = fprint()
  c = displays.ConsolidatedBuff.conf
  parentFrame = B.guides[c.Parent][c.Position]
  raidbuffsFrame = B.anchor.ConsolidatedBuff

  B.SetConfigLayers(raidbuffsFrame)
  consolidatedBuffsLoaded = true
  ConsolidatedBuffs:ClearAllPoints()
  ConsolidatedBuffs:SetAllPoints(parentFrame.icon)
  if c.Icon then
    ConsolidatedBuffsIcon:SetAllPoints(parentFrame.icon)
    ConsolidatedBuffsIcon:SetTexCoord(0.609,0.89,0.215,0.78)
  else
    ConsolidatedBuffsIcon:Hide()
  end

  ConsolidatedBuffsCount:Hide()
end

local missingTypes = {}
local raidBuffsInitialized
M.UpdateRaidBuffs = function()
  local print = fprint()
  if not consolidatedBuffsLoaded then
    M.SetConsolidatedBuffs()
  end

  if not M.ShowConsolidated or not parentFrame.contains then
    print('  hiding raid buffs square')
    if raidBuffsInitialized then
      for i = 1, 9 do
        if raidBuffs[i] then
          raidBuffs[i]:Hide()
        end
      end
      raidBuffsInitialized = nil
    end
    if parentFrame then
      print(c.Parent, c.Position)
      print('de-flagging parent')
      parentFrame.contains = nil
    end
    raidbuffsFrame:Hide()
    return
  end

  local c = B.displays.ConsolidatedBuff.conf
  if parentFrame and not parentFrame.contains then
    raidBuffsInitialized = true
    print('re-flagging parent', parentFrame:GetName())
    parentFrame.contains = parentFrame
    B.decors[c.Parent][c.Position]:Hide()
    raidbuffsFrame:Show()

    -- make sure parent icon is updated
    local w = c.Size*c.PerRow+c.Spacing*(c.PerRow-1)+c.Border*2
    parentFrame:SetSize(w, w)
    parentFrame.icon:SetSize(w - c.Border*2, w - c.Border*2)
    parentFrame.contains = raidbuffsFrame

    M.UpdateBuffs(c.Parent)
  end

  -- have to loop again due to tainting restrictions
  -- could compare the tooltip font object pointers, but that may change
  local buffStack = GetRaidBuffInfo()
  print(GetRaidBuffInfo())
  local guides = B.guides.ConsolidatedBuff
  local numBuffs = 0
  local numAvailable = 0
  local mask = 1
  if buffStack == nil then
    return -- discard
  end


  for i = 1, NUM_LE_RAID_BUFF_TYPES do
    local available = (band(buffStack, mask) > 0)
    local name, _, icon, start, duration, spellID, slot = GetRaidBuffTrayAuraInfo(i)
    print(i, name, icon, available)

    raidBuffs[i] = raidBuffs[i] or CreateFrame('Frame', 'VeneerRaidBuff' .. i, raidbuffsFrame, 'VeneerRaidBuffTemplate')
    local buff = raidBuffs[i]
    if not raidBuffs[i].stylized then
      print('  setting style', i)
      buff.stylized = true
      buff.symbol:SetText(raidBuffSymbols[i])
      buff.symbol:SetFont("Fonts\\FRIZQT__.TTF", 10, 'OUTLINE')
      buff:SetSize(parentFrame.icon:GetWidth()/c.PerRow,parentFrame.icon:GetWidth()/c.PerRow)
      buff.symbolName = raidBuffSymbols[i]

      buff.icon:SetAllPoints(guides[i].icon)
      buff:SetAllPoints(guides[i])
      raidbuffsFrame.Zoom(buff.icon)
    end

    buff:Show()
    local buffStyle = 'missing'
    if name then
      buff:Show()
      buff.symbol:Hide()
      missingTypes[i] = nil
      numBuffs = numBuffs + 1
      numAvailable = numAvailable + 1
      buffStyle = 'active'
    else
      buff.symbol:Show()
      if band(buffStack, mask) > 0 then
        buffStyle = 'available'
        numAvailable = numAvailable + 1
      else
        buffStyle = 'missing'
        icon = ''
      end
    end
    mask = lshift(mask, 1)

    M.UpdateBuffStyle(buff, buffStyle, icon)
  end

  -- todo: filter by castable and suppress for non-overlapping auras

  raidbuffsFrame.label:SetText(numBuffs..'/'..numAvailable)
  print(parentFrame:GetName(), parentFrame:GetSize())

  if B.ShowMissingBuffs then
      B.UpdateMissingBuffs()
  elseif missingBuffsAnchor and missingBuffsAnchor:IsVisible() then
    for i = 1, NUM_LE_MISSING_RAID_BUFFS do
      missingBuffs[i]:Hide()
    end
  end
end

B.UpdateMissingBuffs = function()
  local print = B.fprint()
  local numMissing = 0

  local firstMissing, lastMissing
  for i = 1, NUM_LE_RAID_BUFF_TYPES do
    local name, _, icon, start, duration, spellID, slot = GetRaidBuffTrayAuraInfo(i)

    if not name then
      numMissing = numMissing + 1

      print('missing buff', i, numMissing)
      B.UpdateBuffStyle(raidBuffs[i].icon, 'missing', "")

      missingBuffs[numMissing] = missingBuffs[numMissing] or CreateFrame('Button', 'VeneerMissingBuff' .. numMissing, raidbuffsFrame, 'VeneerMissingBuffTemplate')

      local missing = missingBuffs[numMissing]

      missing:Show()
      missing:SetSize(c.Size*c.PerRow, c.Size)
      if numMissing == 1 then
        firstMissing = missing
      else
        missing:SetPoint('TOP', lastMissing, 'BOTTOM', 0, -c.Spacing)
      end

      missing.label:SetText(_G['RAID_BUFF_'.. i])
      lastMissing = missing

    end
  end

  if firstMissing then
    print(firstMissing:GetName(), raidbuffsFrame)
    firstMissing:SetPoint('TOPRIGHT', raidbuffsFrame.label, 'BOTTOMRIGHT', 0, c.Spacing)
    missingBuffsAnchor = firstMissing
  end

  for i = numMissing +1, NUM_LE_MISSING_RAID_BUFFS do
    missingBuffs[i]:Hide()
  end
  NUM_LE_MISSING_RAID_BUFFS = numMissing
end