annotate 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
rev   line source
Nenue@0 1 --------------------------------------------
Nenue@0 2 -- KrakTool
Nenue@0 3 -- Nick
Nenue@0 4 -- @project - r e v i s i o n @ @project-hash@
Nenue@0 5 -- @file - r e v i s i o n @ @file-hash@
Nenue@0 6 -- Created: 6/16/2016 3:46 AM
Nenue@0 7 --------------------------------------------
Nenue@0 8
Nenue@1 9 local KT = LibKT.register(SkeletonUnits)
Nenue@3 10 local db
Nenue@0 11 local PLAYER_NAMEPLATE
Nenue@0 12 local PLAYER_WIDTH = 220
Nenue@0 13 local BUFF_SIZE = 24
Nenue@3 14 local uf = SkeletonUnits
Nenue@3 15 local prototypes = {}
Nenue@1 16 local units = {}
Nenue@1 17 local buttons = {}
Nenue@3 18
Nenue@3 19 local params = setmetatable({}, {
Nenue@3 20 __index = function(t, k)
Nenue@3 21 print('get', k)
Nenue@3 22 return rawget(t.player, k)
Nenue@3 23 end,
Nenue@3 24 __newindex = function(t, k, v)
Nenue@3 25 if type(v) == 'table' then
Nenue@3 26 v = setmetatable(v, {
Nenue@3 27 __index = function(tt, kk)
Nenue@3 28 print('get', k, kk)
Nenue@3 29 return rawget(t.player, kk)
Nenue@3 30 end,
Nenue@3 31 __newindex = function(tt, kk, vv)
Nenue@3 32 if type(vv) == 'table' then
Nenue@3 33 vv = setmetatable(vv, {
Nenue@3 34 __index = function(_tt, _kk)
Nenue@3 35 print('_get', k, kk, _kk)
Nenue@3 36 return rawget(t.player[kk], _kk)
Nenue@3 37 end
Nenue@3 38 })
Nenue@3 39 end
Nenue@3 40 rawset(tt, kk ,vv)
Nenue@3 41 end
Nenue@3 42 })
Nenue@3 43 end
Nenue@3 44 rawset(t,k,v)
Nenue@3 45 end
Nenue@3 46 })
Nenue@3 47
Nenue@3 48 params.player = {
Nenue@3 49 width = 220,
Nenue@3 50 height = 30,
Nenue@3 51 health = { height = 24 },
Nenue@3 52 power = { height = 6},
Nenue@3 53 }
Nenue@3 54 params.pet = {
Nenue@3 55 width = 180,
Nenue@3 56 height = 25
Nenue@1 57 }
Nenue@3 58 params.focus = params.pet
Nenue@3 59
Nenue@3 60 uf.handler = uf -- so uf.event can work
Nenue@0 61
Nenue@0 62
Nenue@1 63 local UpdateUnitAnchor = function(self)
Nenue@1 64 self.nameplate = C_NamePlate.GetNamePlateForUnit(self.unit)
Nenue@1 65 if self.nameplate and self.nameplate.namePlateUnitToken then
Nenue@1 66 self:ClearAllPoints()
Nenue@1 67 self:SetPoint('TOP', self.nameplate, 'BOTTOM', 0, 0)
Nenue@1 68 print('snapping', self.unit, 'to', self.nameplate.namePlateUnitToken)
Nenue@1 69 else
Nenue@1 70 self:ClearAllPoints()
Nenue@1 71 self:SetPoint(unpack(self.anchorPoint))
Nenue@1 72 end
Nenue@0 73 end
Nenue@0 74
Nenue@0 75 local SetupButton = function(self, unit, index)
Nenue@1 76 if not buttons[unit][index] then
Nenue@1 77 buttons[unit][index] = CreateFrame('Frame', 'KT'..unit..'Buff'..index, self, 'KTAuraButton')
Nenue@1 78 buttons[unit][index]:SetSize(BUFF_SIZE, BUFF_SIZE)
Nenue@1 79 buttons[unit][index].cooldown:SetHideCountdownNumbers(true)
Nenue@0 80
Nenue@0 81 end
Nenue@1 82 return buttons[unit][index]
Nenue@0 83 end
Nenue@0 84
Nenue@3 85 uf.unit = function(unit)
Nenue@3 86 if not prototypes[unit] then
Nenue@3 87 return
Nenue@3 88 end
Nenue@3 89 print('|cFFFFFF00unit|r:', unit)
Nenue@3 90
Nenue@3 91 if not _G['KT'..unit..'Frame'] then
Nenue@3 92 CreateFrame('Frame', 'KT'.. unit .. 'Frame', uf)
Nenue@1 93 end
Nenue@1 94
Nenue@3 95 local frame = _G['KT'..unit..'Frame']
Nenue@3 96 frame.unit = unit
Nenue@3 97 frame.anchorPoint = {frame:GetPoint(1)}
Nenue@3 98 frame.handler = prototypes[unit]
Nenue@3 99
Nenue@3 100 buttons[unit] = {}
Nenue@3 101 units[unit] = frame
Nenue@3 102
Nenue@3 103 local width = params.player.width
Nenue@3 104 local height = params.player.height
Nenue@3 105
Nenue@3 106 if params[unit] then
Nenue@3 107 if params[unit].width then
Nenue@3 108 width = params[unit].width
Nenue@3 109 end
Nenue@3 110 if params[unit].height then
Nenue@3 111 height = params[unit].height
Nenue@3 112 end
Nenue@3 113 end
Nenue@3 114
Nenue@3 115 frame:SetWidth(width)
Nenue@3 116 frame:SetHeight(height)
Nenue@3 117
Nenue@3 118 return frame
Nenue@1 119 end
Nenue@3 120
Nenue@3 121 uf.ui = function ()
Nenue@1 122 for unit, frame in pairs(units) do
Nenue@3 123 frame.handler.refresh(frame)
Nenue@1 124 end
Nenue@1 125 end
Nenue@1 126
Nenue@3 127 uf.init = function()
Nenue@3 128 uf:RegisterEvent('PLAYER_TARGET_CHANGED')
Nenue@3 129 uf:RegisterUnitEvent("UNIT_AURA")
Nenue@3 130 end
Nenue@3 131
Nenue@3 132 uf.variables = function()
Nenue@3 133 if not FossilDB then
Nenue@3 134 FossilDB = {
Nenue@3 135 units = {'player', 'target', 'focus', 'pet', 'targettarget' },
Nenue@3 136 position = {}
Nenue@3 137 }
Nenue@3 138 end
Nenue@3 139 db = FossilDB
Nenue@3 140
Nenue@3 141 for i, unit in pairs(db.units) do
Nenue@3 142 print(unit)
Nenue@3 143 local frame = uf.unit(unit)
Nenue@3 144 if frame then
Nenue@3 145 frame.handler.init(frame)
Nenue@3 146 end
Nenue@3 147 end
Nenue@3 148 uf.ui()
Nenue@3 149 end
Nenue@3 150
Nenue@3 151 uf.event = function(self, event, ...)
Nenue@1 152 if self.handler[event] then
Nenue@1 153 self.handler[event](self, event, ...)
Nenue@1 154 end
Nenue@3 155 return true
Nenue@1 156 end
Nenue@1 157
Nenue@3 158 uf.PLAYER_TARGET_CHANGED = function()
Nenue@1 159 prototypes.player.refresh(units.target)
Nenue@1 160 end
Nenue@1 161
Nenue@3 162 prototypes.player = {}
Nenue@3 163 local player = prototypes.player
Nenue@3 164 player.init = function(self)
Nenue@1 165 self:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", self.unit)
Nenue@1 166 self:RegisterUnitEvent("UNIT_POWER_FREQUENT", self.unit)
Nenue@1 167 self:RegisterEvent("NAME_PLATE_UNIT_ADDED")
Nenue@1 168 self:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
Nenue@1 169 self:RegisterEvent("UNIT_TARGET")
Nenue@3 170 self:SetScript('OnEvent', uf.event)
Nenue@1 171 end
Nenue@1 172
Nenue@1 173
Nenue@1 174 --- Runs when event handler decides so
Nenue@3 175 player.refresh = function(self)
Nenue@1 176 if not UnitExists(self.unit) then
Nenue@1 177 self:Hide()
Nenue@1 178 return
Nenue@1 179 end
Nenue@1 180
Nenue@3 181 if UnitIsPlayer(self.unit) then
Nenue@3 182 local class, classFile = UnitClass(self.unit)
Nenue@3 183 if classFile then
Nenue@3 184 self.healthbar:SetColorTexture(RAID_CLASS_COLORS[classFile].r, RAID_CLASS_COLORS[classFile].g, RAID_CLASS_COLORS[classFile].b)
Nenue@3 185 end
Nenue@3 186 elseif UnitIsFriend('player', self.unit) then
Nenue@3 187 self.healthbar:SetColorTexture(0,.75,0,1)
Nenue@3 188 elseif UnitIsEnemy('player', self.unit) then
Nenue@3 189 self.healthbar:SetColorTexture(1,0,0,1)
Nenue@3 190 else
Nenue@3 191 self.healthbar:SetColorTexture(1,1,0,1)
Nenue@3 192 end
Nenue@3 193 self.powertype = UnitPowerType(self.unit)
Nenue@3 194 if self.powertype then
Nenue@3 195 self.powerbar:SetColorTexture(0,.3,1, 1)
Nenue@3 196
Nenue@3 197 self.handler.UNIT_POWER_FREQUENT(self)
Nenue@3 198 else
Nenue@3 199 self.healthbar:SetHeight(params[self.unit].health.height + params[self.unit].power.height)
Nenue@1 200 end
Nenue@1 201
Nenue@3 202
Nenue@3 203
Nenue@1 204 self.handler.UNIT_HEALTH_FREQUENT(self)
Nenue@1 205 end
Nenue@1 206
Nenue@3 207 uf.UNIT_AURA = function(self, event, unit)
Nenue@3 208 if not units[unit] then return true end
Nenue@1 209
Nenue@0 210 local buffOffset = 0
Nenue@1 211 local buttons = buttons[unit]
Nenue@0 212 for i = 1, 16 do
Nenue@1 213
Nenue@1 214 local aura, _, texture, count, dispelType, duration, expires, caster = UnitAura(unit, i, 'HARMFUL')
Nenue@0 215 if aura then
Nenue@1 216 local button = SetupButton(units[unit], unit, i)
Nenue@0 217
Nenue@0 218 button.icon:SetTexture(texture)
Nenue@0 219 button.cooldown:SetCooldown(expires - duration, duration)
Nenue@0 220 button.cooldown:Show()
Nenue@0 221 button.count:SetText(count > 0 and count or nil)
Nenue@1 222 button:SetPoint('BOTTOMLEFT', units[unit], 'TOPLEFT', buffOffset* BUFF_SIZE, 2)
Nenue@0 223 button:Show()
Nenue@0 224 buffOffset = buffOffset + 1
Nenue@0 225 else
Nenue@0 226 if buttons[i] then
Nenue@0 227 buttons[i]:Hide()
Nenue@0 228 end
Nenue@0 229 end
Nenue@0 230 end
Nenue@3 231 return true
Nenue@0 232 end
Nenue@0 233
Nenue@3 234 player.NAME_PLATE_UNIT_ADDED = function(self, event, nameplate)
Nenue@3 235 --UpdateUnitAnchor(self)
Nenue@1 236 end
Nenue@3 237 player.NAME_PLATE_UNIT_REMOVED = function(self, event, nameplate)
Nenue@3 238 --UpdateUnitAnchor(self)
Nenue@1 239 end
Nenue@1 240
Nenue@3 241 player.UNIT_HEALTH_FREQUENT = function(self, ...)
Nenue@1 242 if UnitHealthMax(self.unit) > 0 then
Nenue@1 243 self.healthbar:SetWidth(PLAYER_WIDTH * UnitHealth(self.unit) / UnitHealthMax(self.unit))
Nenue@1 244 self.healthtext:SetText(UnitHealth(self.unit))
Nenue@1 245 else
Nenue@1 246 self.healthbar:SetWidth(PLAYER_WIDTH)
Nenue@1 247 self.healthtext:SetText(nil)
Nenue@0 248 end
Nenue@1 249 return true
Nenue@0 250 end
Nenue@1 251
Nenue@3 252 player.UNIT_POWER_FREQUENT = function(self)
Nenue@1 253 if UnitPowerMax(self.unit) > 0 then
Nenue@1 254 self.powerbar:SetWidth(PLAYER_WIDTH * UnitPower(self.unit) / UnitPowerMax(self.unit))
Nenue@1 255 self.powertext:SetText(UnitPower(self.unit))
Nenue@1 256 else
Nenue@1 257 self.powerbar:Hide()
Nenue@1 258 self.powertext:SetText(nil)
Nenue@1 259 end
Nenue@1 260 return true
Nenue@1 261 end
Nenue@1 262
Nenue@1 263
Nenue@3 264 player.UNIT_TARGET = function(self, ...)
Nenue@1 265 if not UnitExists(self.unit) then
Nenue@1 266 self:Hide()
Nenue@1 267 else
Nenue@1 268 self:Show()
Nenue@1 269 self.handler.refresh(self)
Nenue@0 270 end
Nenue@0 271 end
Nenue@0 272
Nenue@3 273 prototypes.pet = player
Nenue@3 274 prototypes.target = player