view Spirit.lua @ 4:8ace773d6bfc

suppress castbar latency logic on non-player units
author Nenue
date Tue, 15 Dec 2015 10:09:20 -0500
parents 766d8a40a1d6
children
line wrap: on
line source
-- User: Krakyn
-- Created: 12/8/2015 7:30 PM
local T = LibStub("AceAddon-3.0"):GetAddon("Turok")
local TL = 'Spirit'
local print = function(...) _G.print(TL, ...) end
local LSM = LibStub("LibSharedMedia-3.0")
local mod = T:NewModule("Spirit", "AceTimer-3.0")
local time = _G.ct
local auras = {
  168811, -- sniper training
  168809, -- sniper training: recently moved
  13159,           -- aspect of the pack,
  187615, -- Maalus
}
local spells = {
  3045, -- rapid fire,
  26297, -- berserking,
  121818, -- stampede,

}
local FRAME_PREFIX = 'TkSpirit'
local FADE_TIME = 0.5
-- local repetitive tasks
local function FindSpirit(id)
  local db = T.db
  local c = db.spirit
  local isIcon = false
  if db.spirit.progressbar[id] then
    c = db.spirit.progressbar[id]
  elseif db.spirit.icon[id] then
    c = db.spirit.icon[id]
    isIcon = true
  end
  local name, rank, icon, castingTime, minRange, maxRange, spellID = GetSpellInfo(id)
  local s = {
    name = name,
    rank = rank,
    icon = icon,
    castingTime = castingTime,
    minRange = minRange,
    maxRange = maxRange,
    spellID = spellID
  }

  return s, c, isIcon
end

function mod:OnEnable()
  local db = _G.TurokData
  self.aura_watch = {}
  self.cooldown_watch = {}
  self.item_watch = {}
  self.myGUID = UnitGUID('player')


  db.spirit = {
    foreground_color = {1, 1, 1, 0.7},
    foreground_texture = 'Cilo',
    foreground_blend = 'BLEND',
    foreground_inset = -1,
    background_color = {0, 0, 0, 0.7},
    background_blend = 'BLEND',
    background_texture = 'Cilo',
    icon_show = true,
    width = 250, height = 20,
    anchor = 'CENTER', parent = 'UIParent', anchorTo = 'CENTER',
    posX = 0, posY = -150,
    label_color = {1, 1, 1, 1},
    label_font = 'turok',
    label_size = 14,
    label_inset = -2,
    label_point = 'LEFT',
    label_outline = 'OUTLINE',
    label_string = '%n %p',
    label_strata = 'HIGH',
    expire_sound = LSM:Fetch('sound'),
    strata = 'LOW',
    icon = {
      [13159] = {  -- Aspect of the Pack
        posX = 20, posY = 20, width = 140, height = 140,
      },
      [3045] = {
        parent = 13159, anchor = 'RIGHT', anchorTo = 'LEFT',
        posx = 0, posY = 0, width = 64, height = 64,
      }
    },
    progressbar = {
      [168811] = { -- Sniper Training (duration)
        background_color = {0,0,0,0},
        foreground_color = {1,0,0,1},
        anchor = 'BOTTOMLEFT', parent = 'TkFocusBar', anchorTo = 'TOPLEFT',
        posX = 0, posY = 0, height = 16, width = 250,
        label_string = '',
        label_point = 'TOPLEFT',
        strata = 'LOW',
        attach = {{
          width_relative = 0.5,
          height_relative = 1,
          background_color = {1,0,0,1},
          foreground_color = {1,1,0.5, 1},
          background_blend = 'ADD',
          foreground_blend = 'ADD',

          anchor = 'LEFT',
          anchorTo = 'LEFT',
          strata = 'MEDIUM',
        }}
      },
      [168809] = { -- Sniper Training: Recently Moved
        background_color = {0,0,0,0 },
        foreground_color = {1,1,1,1},
        foreground_blend = 'ADD',
        anchor = 'BOTTOMLEFT', parent = 'TkFocusBar', anchorTo = 'TOPLEFT',
        strata = 'HIGH',
        posX = 0, posY = 0, height = 16, width = 125,
        icon_show = false,
        label_string = '',
        exceptions = {
          function(aura)
            return (mod.aura_watch[168811].expires < aura.expires)
          end
        },
      },
    },
  }

  for _, id in pairs(auras) do
    -- store spellinfo fetch
    self.aura_watch[id] = self:CreateSpiritFrame(id)
    self.aura_watch[id].count = 0
    self.aura_watch[id].duration = 0
    self.aura_watch[id].expires = 0
    self.aura_watch[id].caster = 0
    print('AURA', id, self.aura_watch[id].name)
  end

  for _, id in ipairs(spells) do
    self.cooldown_watch[id] = self:CreateSpiritFrame(id)
    print('COOLDOWN', id, self.cooldown_watch[id].name)
  end

  self:SpiritScan()
  self:RegisterEvent('UNIT_AURA')
  self:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
  self:RegisterEvent('PLAYER_REGEN_DISABLED')
  self:RegisterEvent('PLAYER_REGEN_ENABLED')
end

-- StatusBar factory
function mod:CreateSpiritFrame(id)
  local s, c, isIcon = FindSpirit(id)

  -- how much frame do we need?
  local f
  if isIcon then
    f = CreateFrame('Frame', FRAME_PREFIX..id, UIParent)
    f.db = c
    function f:Update() end
  else
    f = T:CreateBar('TkAuraBar'..id, c)
    f.isTimer = true
    if (c.label_string ~= '') then
      print('has label, add it', id)
      T:AddLabel(f, c)
      end
  end
  f:Hide()

  -- general display
  f:SetPoint(c.anchor, c.parent, c.anchorTo, c.posX, c.posY)
  f:SetSize(c.width, c.height)
  f:SetFrameStrata(c.strata)

  -- icon?
  f.icon = s.icon
  T:CreateStatusIcon(f)

  -- attachment frames?
  if c.attach then
    for i, e in ipairs(c.attach) do
      local ef = CreateFrame('Frame', 'TkExtra'..id, f)
      f[i] = ef
      ef:SetPoint(e.anchor, f, e.anchorTo)
      ef:SetSize(c.width * e.width_relative or e.width, c.height * e.height_relative or e.height)
      ef:SetFrameStrata(e.strata or c.strata)
      T:CreateStatusTextures(ef, e)
    end
  end

  -- setup suppression checking
  if c.exceptions then
    function s:ExceptionCheck ()
      for i, func in ipairs(c.exceptions) do
        if not func(self) then
          return false, i
        end
      end
      return true
    end
  else
    function s:ExceptionCheck () return true end
  end

  -- access linkage
  f.format = c.label_string
  f.spirit = s
  f.name = s.name
  s.frame = f
  return s
end

function mod:UNIT_AURA(e, unit)
  if unit == 'player' then
    self:SpiritScan()
  end
end

-- Updates aura watches
function mod:SpiritScan()
  local db = _G.TurokData
  for id, aura in pairs(self.aura_watch) do
    local c = aura.conf
    local f = aura.frame

    local name, _, _, count, _, duration, expires, caster = UnitAura('player', aura.name)

    if name then
      aura.duration = duration
      aura.expires = expires
      aura.caster = caster
      aura.count = count
      local test, i = aura:ExceptionCheck()
      print(name, duration, expires)
      if not test then
        print('suppressing '..aura.name..' (failed test #'..i..')')
      else
        f.name = name
        f:Update(nil, duration, expires)
        f:Show()
      end
    end
  end
end

function mod:PLAYER_REGEN_ENABLED()
  for id, aura in pairs(self.aura_watch) do
    print('non-combat alpha for #', id, aura.name, 'is', aura.frame.db.alpha_ooc)
    aura.frame.fadeTo = aura.frame.db.alpha_ooc
    aura.frame.fadeDuration = FADE_TIME
  end
end

function mod:PLAYER_REGEN_DISABLED()
  for id, aura in pairs(self.aura_watch) do
    print('combat alpha for #', id, aura.name, 'is', aura.frame.db.alpha)
    aura.frame.fadeTo = aura.frame.db.alpha
    aura.frame.fadeDuration = FADE_TIME
  end
end

-- This is the most reliable way of catching item and spell uses, other events are delayed or too vague to be useful
function mod:COMBAT_LOG_EVENT_UNFILTERED(e, ...)
  local timestamp, combatEvent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags =
  ...; -- Those arguments appear for all combat event variants.
  local eventPrefix, eventSuffix = combatEvent:match("^(.-)_?([^_]*)$");
  if eventPrefix ~= 'SPELL_' or sourceGUID ~= self.myGUID then
    return
  end

  local spellid, name, count, type = select(13, select('#', ...), ...)
  local kc = ''
  for i=1,4 do
    kc = kc .. string.format('%X',((string.byte(eventSuffix,i) % 8) + 8))
  end
  print('|cFFFF'..kc..eventSuffix..'|r', sourceName, destName, spellid, name)
end