view SkeletonUnit/UnitFrame.lua @ 3:07293831dd7b

- implement unit parameters table inheritance from a stock table - UnitFrames.unit() and UnitFrames.ui() methods
author Nenue
date Tue, 21 Jun 2016 08:14:22 -0400
parents cd7d06bcd98d
children a30285f8191e
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 rawget(t.player, k)
  end,
  __newindex = function(t, k, v)
    if type(v) == 'table' then
      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
            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},
  }
params.pet = {
  width = 180,
  height = 25
}
params.focus = params.pet

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)

  if not _G['KT'..unit..'Frame'] then
    CreateFrame('Frame', 'KT'.. unit .. 'Frame', uf)
  end

  local frame = _G['KT'..unit..'Frame']
  frame.unit = unit
  frame.anchorPoint = {frame:GetPoint(1)}
  frame.handler = prototypes[unit]

  buttons[unit] = {}
  units[unit] = frame

  local width = params.player.width
  local height = params.player.height

  if params[unit] then
    if params[unit].width then
      width = params[unit].width
    end
    if params[unit].height then
      height = params[unit].height
    end
  end

  frame:SetWidth(width)
  frame:SetHeight(height)

  return 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: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()
  prototypes.player.refresh(units.target)
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)
end


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

  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



  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(PLAYER_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(PLAYER_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