view SkeletonUnit/UnitFrame.lua @ 4:a30285f8191e

Units: make sure unit frames are SecureUnitButton derivatives remove of unnecessary target/focus events Stats: resolve GUID after event handlers have fired keep frame manipulation in uf.ui, get needed values from wrapper functions
author Nenue
date Tue, 21 Jun 2016 11:56:14 -0400
parents 07293831dd7b
children
line wrap: on
line source
--------------------------------------------
-- KrakTool
-- Nick
-- @project - r e v i s i o n @ @project-hash@
-- @file - r e v i s i o n @ @file-hash@
-- Created: 6/16/2016 3:46 AM
--------------------------------------------

local KT = LibKT.register(SkeletonUnits)
local db
local PLAYER_NAMEPLATE
local PLAYER_WIDTH = 220
local BUFF_SIZE = 24
local uf = SkeletonUnits
local prototypes = {}
local units = {}
local buttons = {}

local params = setmetatable({}, {
  __index = function(t, k)
    print('get', k)
    return t.player
  end,
  __newindex = function(t, k, v)
    if type(v) == 'table' then
      print('branch', k)
      v = setmetatable(v, {
        __index  = function(tt, kk)
          print('get', k, kk)
          return rawget(t.player, kk)
        end,
        __newindex = function(tt, kk, vv)
          if type(vv) == 'table' then
            print('_branch', k, kk)
            vv = setmetatable(vv, {
              __index = function(_tt, _kk)
                print('_get', k, kk, _kk)
                return rawget(t.player[kk], _kk)
              end
            })
          end
          rawset(tt, kk ,vv)
        end
      })
    end
      rawset(t,k,v)
  end
})

params.player = {
  width = 220,
  height = 30,
    health = { height = 24 },
    power = { height = 6},
  position = {'CENTER', nil, 'CENTER',0,-120 }
}
params.pet = {
  width = 180,
  height = 25,

  position = {'TOPLEFT', 'player', 'BOTTOMLEFT',0,-4}
}
params.target = {

  position = {'TOPLEFT', 'player', 'TOPRIGHT',4,0}
}
params.focus = {
  width = 180,
  height = 25,
  position = {'BOTTOMRIGHT', 'target', 'TOPRIGHT',0,4}
}

uf.handler = uf -- so uf.event can work


local UpdateUnitAnchor = function(self)
  self.nameplate = C_NamePlate.GetNamePlateForUnit(self.unit)
  if self.nameplate and self.nameplate.namePlateUnitToken then
    self:ClearAllPoints()
    self:SetPoint('TOP', self.nameplate, 'BOTTOM', 0, 0)
    print('snapping', self.unit, 'to', self.nameplate.namePlateUnitToken)
  else
    self:ClearAllPoints()
    self:SetPoint(unpack(self.anchorPoint))
  end
end

local SetupButton = function(self, unit, index)
  if not buttons[unit][index] then
    buttons[unit][index] = CreateFrame('Frame', 'KT'..unit..'Buff'..index, self, 'KTAuraButton')
    buttons[unit][index]:SetSize(BUFF_SIZE, BUFF_SIZE)
    buttons[unit][index].cooldown:SetHideCountdownNumbers(true)
  end
  return buttons[unit][index]
end

uf.unit = function(unit)
  if not prototypes[unit] then
    return
  end
  print('|cFFFFFF00unit|r:', unit)

  local c = params[unit]

  if not _G['KT'..unit..'Frame'] then
    local new = CreateFrame('Button', 'KT'.. unit .. 'Frame', uf, 'KTUnitFrameTemplate')
    new.unit = unit
    new.anchorPoint = {new:GetPoint(1)}
    new.handler = prototypes[unit]
    new.params = c

    --if not db.position[unit] then
      db.position[unit] = c.position
    --end
    new.position = db.position[unit]


    buttons[unit] = {}
    new.buttons = buttons[unit]
    new.refresh = prototypes[unit].refresh
    new.init = prototypes[unit].init

    new:EnableMouse(true)
    new:SetScript('OnMouseUp', prototypes[unit].OnMouseUp)

    new:SetAttribute("type", "target")
    new:SetAttribute("unit", unit)
    RegisterUnitWatch(new)
    units[unit] = new
  end

  return _G['KT'..unit..'Frame']
end

uf.ui = function ()
  for unit, frame in pairs(units) do
    frame.handler.refresh(frame)
  end
end

uf.init = function()
  uf:RegisterEvent('PLAYER_TARGET_CHANGED')
  uf:RegisterEvent('PLAYER_FOCUS_CHANGED')
  uf:RegisterUnitEvent("UNIT_AURA")
end

uf.variables = function()
  if not FossilDB then
    FossilDB = {
      units = {'player', 'target', 'focus', 'pet', 'targettarget' },
      position = {}
    }
  end
  db = FossilDB

  for i, unit in pairs(db.units) do
    print(unit)
    local frame = uf.unit(unit)
    if frame then
      frame.handler.init(frame)
    end
  end
  uf.ui()
end

uf.event = function(self, event, ...)
  if self.handler[event] then
    self.handler[event](self, event, ...)
  end
  return true
end

uf.PLAYER_TARGET_CHANGED = function()
  print('caught target change')
  units.target:refresh()
end

uf.PLAYER_FOCUS_CHANGED = function()
  units.focus:refresh()
end

prototypes.player = {}
local player = prototypes.player
player.init = function(self)
  self:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", self.unit)
  self:RegisterUnitEvent("UNIT_POWER_FREQUENT", self.unit)
  self:RegisterEvent("NAME_PLATE_UNIT_ADDED")
  self:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
  self:RegisterEvent("UNIT_TARGET")
  self:SetScript('OnEvent', uf.event)

  local anchor, parent, relative, x, y = unpack(self.position)
  if parent and units[parent] then
    parent = units[parent]
  else
    parent = UIParent
  end

  self:SetPoint(anchor, parent, relative, x, y)
  self:SetSize(self.params.width, self.params.height)

end


--- Runs when event handler decides so
player.refresh = function(self)
  print(self.unit, UnitExists(self.unit))
  if not UnitExists(self.unit) then
    print('hiding unit')
    self:Hide()
    return
  end

  self:Show()
  if UnitIsPlayer(self.unit) then
    local class, classFile = UnitClass(self.unit)
    if classFile then
      self.healthbar:SetColorTexture(RAID_CLASS_COLORS[classFile].r, RAID_CLASS_COLORS[classFile].g, RAID_CLASS_COLORS[classFile].b)
    end
  elseif UnitIsFriend('player', self.unit) then
    self.healthbar:SetColorTexture(0,.75,0,1)
  elseif UnitIsEnemy('player', self.unit) then
    self.healthbar:SetColorTexture(1,0,0,1)
  else
    self.healthbar:SetColorTexture(1,1,0,1)
  end
  self.powertype = UnitPowerType(self.unit)
  if self.powertype then
    self.powerbar:SetColorTexture(0,.3,1, 1)

    self.handler.UNIT_POWER_FREQUENT(self)
  else
    self.healthbar:SetHeight(params[self.unit].health.height + params[self.unit].power.height)
  end
  uf.UNIT_AURA(self, 'UNIT_AURA', self.unit)

  self.handler.UNIT_HEALTH_FREQUENT(self)
end


uf.UNIT_AURA = function(self, event, unit)
  if not units[unit] then return true end

  local buffOffset = 0
  local buttons = buttons[unit]
  for i = 1, 16 do

    local aura, _, texture, count, dispelType, duration, expires, caster = UnitAura(unit, i, 'HARMFUL')
    if aura then
      local button = SetupButton(units[unit], unit, i)

      button.icon:SetTexture(texture)
      button.cooldown:SetCooldown(expires - duration, duration)
      button.cooldown:Show()
      button.count:SetText(count > 0 and count or nil)
      button:SetPoint('BOTTOMLEFT', units[unit], 'TOPLEFT', buffOffset* BUFF_SIZE, 2)
      button:Show()
      buffOffset = buffOffset + 1
    else
      if buttons[i] then
        buttons[i]:Hide()
      end
    end
  end
  return true
end

player.NAME_PLATE_UNIT_ADDED = function(self, event, nameplate)
    --UpdateUnitAnchor(self)
end
player.NAME_PLATE_UNIT_REMOVED = function(self, event, nameplate)
    --UpdateUnitAnchor(self)
end

player.UNIT_HEALTH_FREQUENT = function(self, ...)
  if UnitHealthMax(self.unit) > 0 then
    self.healthbar:SetWidth(self.params.width * UnitHealth(self.unit) / UnitHealthMax(self.unit))
    self.healthtext:SetText(UnitHealth(self.unit))
  else
    self.healthbar:SetWidth(PLAYER_WIDTH)
    self.healthtext:SetText(nil)
  end
  return true
end

player.UNIT_POWER_FREQUENT = function(self)
  if UnitPowerMax(self.unit) > 0 then
    self.powerbar:SetWidth(self.params.width * UnitPower(self.unit) / UnitPowerMax(self.unit))
    self.powertext:SetText(UnitPower(self.unit))
  else
    self.powerbar:Hide()
    self.powertext:SetText(nil)
  end
  return true
end


player.UNIT_TARGET = function(self, ...)
  if not UnitExists(self.unit) then
    self:Hide()
  else
    self:Show()
    self.handler.refresh(self)
  end
end

prototypes.pet = player
prototypes.target = player
prototypes.focus = player