Nenue@0: -------------------------------------------- Nenue@0: -- KrakTool Nenue@0: -- Nick Nenue@0: -- @project - r e v i s i o n @ @project-hash@ Nenue@0: -- @file - r e v i s i o n @ @file-hash@ Nenue@0: -- Created: 6/16/2016 3:46 AM Nenue@0: -------------------------------------------- Nenue@0: Nenue@1: local KT = LibKT.register(SkeletonUnits) Nenue@3: local db Nenue@0: local PLAYER_NAMEPLATE Nenue@0: local PLAYER_WIDTH = 220 Nenue@0: local BUFF_SIZE = 24 Nenue@3: local uf = SkeletonUnits Nenue@3: local prototypes = {} Nenue@1: local units = {} Nenue@1: local buttons = {} Nenue@3: Nenue@3: local params = setmetatable({}, { Nenue@3: __index = function(t, k) Nenue@3: print('get', k) Nenue@4: return t.player Nenue@3: end, Nenue@3: __newindex = function(t, k, v) Nenue@3: if type(v) == 'table' then Nenue@4: print('branch', k) Nenue@3: v = setmetatable(v, { Nenue@3: __index = function(tt, kk) Nenue@3: print('get', k, kk) Nenue@3: return rawget(t.player, kk) Nenue@3: end, Nenue@3: __newindex = function(tt, kk, vv) Nenue@3: if type(vv) == 'table' then Nenue@4: print('_branch', k, kk) Nenue@3: vv = setmetatable(vv, { Nenue@3: __index = function(_tt, _kk) Nenue@3: print('_get', k, kk, _kk) Nenue@3: return rawget(t.player[kk], _kk) Nenue@3: end Nenue@3: }) Nenue@3: end Nenue@3: rawset(tt, kk ,vv) Nenue@3: end Nenue@3: }) Nenue@3: end Nenue@3: rawset(t,k,v) Nenue@3: end Nenue@3: }) Nenue@3: Nenue@3: params.player = { Nenue@3: width = 220, Nenue@3: height = 30, Nenue@3: health = { height = 24 }, Nenue@3: power = { height = 6}, Nenue@4: position = {'CENTER', nil, 'CENTER',0,-120 } Nenue@4: } Nenue@3: params.pet = { Nenue@3: width = 180, Nenue@4: height = 25, Nenue@4: Nenue@4: position = {'TOPLEFT', 'player', 'BOTTOMLEFT',0,-4} Nenue@1: } Nenue@4: params.target = { Nenue@4: Nenue@4: position = {'TOPLEFT', 'player', 'TOPRIGHT',4,0} Nenue@4: } Nenue@4: params.focus = { Nenue@4: width = 180, Nenue@4: height = 25, Nenue@4: position = {'BOTTOMRIGHT', 'target', 'TOPRIGHT',0,4} Nenue@4: } Nenue@3: Nenue@3: uf.handler = uf -- so uf.event can work Nenue@0: Nenue@0: Nenue@1: local UpdateUnitAnchor = function(self) Nenue@1: self.nameplate = C_NamePlate.GetNamePlateForUnit(self.unit) Nenue@1: if self.nameplate and self.nameplate.namePlateUnitToken then Nenue@1: self:ClearAllPoints() Nenue@1: self:SetPoint('TOP', self.nameplate, 'BOTTOM', 0, 0) Nenue@1: print('snapping', self.unit, 'to', self.nameplate.namePlateUnitToken) Nenue@1: else Nenue@1: self:ClearAllPoints() Nenue@1: self:SetPoint(unpack(self.anchorPoint)) Nenue@1: end Nenue@0: end Nenue@0: Nenue@0: local SetupButton = function(self, unit, index) Nenue@1: if not buttons[unit][index] then Nenue@1: buttons[unit][index] = CreateFrame('Frame', 'KT'..unit..'Buff'..index, self, 'KTAuraButton') Nenue@1: buttons[unit][index]:SetSize(BUFF_SIZE, BUFF_SIZE) Nenue@1: buttons[unit][index].cooldown:SetHideCountdownNumbers(true) Nenue@0: end Nenue@1: return buttons[unit][index] Nenue@0: end Nenue@0: Nenue@3: uf.unit = function(unit) Nenue@3: if not prototypes[unit] then Nenue@3: return Nenue@3: end Nenue@3: print('|cFFFFFF00unit|r:', unit) Nenue@3: Nenue@4: local c = params[unit] Nenue@4: Nenue@3: if not _G['KT'..unit..'Frame'] then Nenue@4: local new = CreateFrame('Button', 'KT'.. unit .. 'Frame', uf, 'KTUnitFrameTemplate') Nenue@4: new.unit = unit Nenue@4: new.anchorPoint = {new:GetPoint(1)} Nenue@4: new.handler = prototypes[unit] Nenue@4: new.params = c Nenue@4: Nenue@4: --if not db.position[unit] then Nenue@4: db.position[unit] = c.position Nenue@4: --end Nenue@4: new.position = db.position[unit] Nenue@4: Nenue@4: Nenue@4: buttons[unit] = {} Nenue@4: new.buttons = buttons[unit] Nenue@4: new.refresh = prototypes[unit].refresh Nenue@4: new.init = prototypes[unit].init Nenue@4: Nenue@4: new:EnableMouse(true) Nenue@4: new:SetScript('OnMouseUp', prototypes[unit].OnMouseUp) Nenue@4: Nenue@4: new:SetAttribute("type", "target") Nenue@4: new:SetAttribute("unit", unit) Nenue@4: RegisterUnitWatch(new) Nenue@4: units[unit] = new Nenue@1: end Nenue@1: Nenue@4: return _G['KT'..unit..'Frame'] Nenue@1: end Nenue@3: Nenue@3: uf.ui = function () Nenue@1: for unit, frame in pairs(units) do Nenue@3: frame.handler.refresh(frame) Nenue@1: end Nenue@1: end Nenue@1: Nenue@3: uf.init = function() Nenue@3: uf:RegisterEvent('PLAYER_TARGET_CHANGED') Nenue@4: uf:RegisterEvent('PLAYER_FOCUS_CHANGED') Nenue@3: uf:RegisterUnitEvent("UNIT_AURA") Nenue@3: end Nenue@3: Nenue@3: uf.variables = function() Nenue@3: if not FossilDB then Nenue@3: FossilDB = { Nenue@3: units = {'player', 'target', 'focus', 'pet', 'targettarget' }, Nenue@3: position = {} Nenue@3: } Nenue@3: end Nenue@3: db = FossilDB Nenue@3: Nenue@3: for i, unit in pairs(db.units) do Nenue@3: print(unit) Nenue@3: local frame = uf.unit(unit) Nenue@3: if frame then Nenue@3: frame.handler.init(frame) Nenue@3: end Nenue@3: end Nenue@3: uf.ui() Nenue@3: end Nenue@3: Nenue@3: uf.event = function(self, event, ...) Nenue@1: if self.handler[event] then Nenue@1: self.handler[event](self, event, ...) Nenue@1: end Nenue@3: return true Nenue@1: end Nenue@1: Nenue@3: uf.PLAYER_TARGET_CHANGED = function() Nenue@4: print('caught target change') Nenue@4: units.target:refresh() Nenue@4: end Nenue@4: Nenue@4: uf.PLAYER_FOCUS_CHANGED = function() Nenue@4: units.focus:refresh() Nenue@1: end Nenue@1: Nenue@3: prototypes.player = {} Nenue@3: local player = prototypes.player Nenue@3: player.init = function(self) Nenue@1: self:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", self.unit) Nenue@1: self:RegisterUnitEvent("UNIT_POWER_FREQUENT", self.unit) Nenue@1: self:RegisterEvent("NAME_PLATE_UNIT_ADDED") Nenue@1: self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") Nenue@1: self:RegisterEvent("UNIT_TARGET") Nenue@3: self:SetScript('OnEvent', uf.event) Nenue@4: Nenue@4: local anchor, parent, relative, x, y = unpack(self.position) Nenue@4: if parent and units[parent] then Nenue@4: parent = units[parent] Nenue@4: else Nenue@4: parent = UIParent Nenue@4: end Nenue@4: Nenue@4: self:SetPoint(anchor, parent, relative, x, y) Nenue@4: self:SetSize(self.params.width, self.params.height) Nenue@4: Nenue@1: end Nenue@1: Nenue@1: Nenue@1: --- Runs when event handler decides so Nenue@3: player.refresh = function(self) Nenue@4: print(self.unit, UnitExists(self.unit)) Nenue@1: if not UnitExists(self.unit) then Nenue@4: print('hiding unit') Nenue@1: self:Hide() Nenue@1: return Nenue@1: end Nenue@1: Nenue@4: self:Show() Nenue@3: if UnitIsPlayer(self.unit) then Nenue@3: local class, classFile = UnitClass(self.unit) Nenue@3: if classFile then Nenue@3: self.healthbar:SetColorTexture(RAID_CLASS_COLORS[classFile].r, RAID_CLASS_COLORS[classFile].g, RAID_CLASS_COLORS[classFile].b) Nenue@3: end Nenue@3: elseif UnitIsFriend('player', self.unit) then Nenue@3: self.healthbar:SetColorTexture(0,.75,0,1) Nenue@3: elseif UnitIsEnemy('player', self.unit) then Nenue@3: self.healthbar:SetColorTexture(1,0,0,1) Nenue@3: else Nenue@3: self.healthbar:SetColorTexture(1,1,0,1) Nenue@3: end Nenue@3: self.powertype = UnitPowerType(self.unit) Nenue@3: if self.powertype then Nenue@3: self.powerbar:SetColorTexture(0,.3,1, 1) Nenue@3: Nenue@3: self.handler.UNIT_POWER_FREQUENT(self) Nenue@3: else Nenue@3: self.healthbar:SetHeight(params[self.unit].health.height + params[self.unit].power.height) Nenue@1: end Nenue@4: uf.UNIT_AURA(self, 'UNIT_AURA', self.unit) Nenue@3: Nenue@1: self.handler.UNIT_HEALTH_FREQUENT(self) Nenue@1: end Nenue@1: Nenue@4: Nenue@3: uf.UNIT_AURA = function(self, event, unit) Nenue@3: if not units[unit] then return true end Nenue@1: Nenue@0: local buffOffset = 0 Nenue@1: local buttons = buttons[unit] Nenue@0: for i = 1, 16 do Nenue@1: Nenue@1: local aura, _, texture, count, dispelType, duration, expires, caster = UnitAura(unit, i, 'HARMFUL') Nenue@0: if aura then Nenue@1: local button = SetupButton(units[unit], unit, i) Nenue@0: Nenue@0: button.icon:SetTexture(texture) Nenue@0: button.cooldown:SetCooldown(expires - duration, duration) Nenue@0: button.cooldown:Show() Nenue@0: button.count:SetText(count > 0 and count or nil) Nenue@1: button:SetPoint('BOTTOMLEFT', units[unit], 'TOPLEFT', buffOffset* BUFF_SIZE, 2) Nenue@0: button:Show() Nenue@0: buffOffset = buffOffset + 1 Nenue@0: else Nenue@0: if buttons[i] then Nenue@0: buttons[i]:Hide() Nenue@0: end Nenue@0: end Nenue@0: end Nenue@3: return true Nenue@0: end Nenue@0: Nenue@3: player.NAME_PLATE_UNIT_ADDED = function(self, event, nameplate) Nenue@3: --UpdateUnitAnchor(self) Nenue@1: end Nenue@3: player.NAME_PLATE_UNIT_REMOVED = function(self, event, nameplate) Nenue@3: --UpdateUnitAnchor(self) Nenue@1: end Nenue@1: Nenue@3: player.UNIT_HEALTH_FREQUENT = function(self, ...) Nenue@1: if UnitHealthMax(self.unit) > 0 then Nenue@4: self.healthbar:SetWidth(self.params.width * UnitHealth(self.unit) / UnitHealthMax(self.unit)) Nenue@1: self.healthtext:SetText(UnitHealth(self.unit)) Nenue@1: else Nenue@1: self.healthbar:SetWidth(PLAYER_WIDTH) Nenue@1: self.healthtext:SetText(nil) Nenue@0: end Nenue@1: return true Nenue@0: end Nenue@1: Nenue@3: player.UNIT_POWER_FREQUENT = function(self) Nenue@1: if UnitPowerMax(self.unit) > 0 then Nenue@4: self.powerbar:SetWidth(self.params.width * UnitPower(self.unit) / UnitPowerMax(self.unit)) Nenue@1: self.powertext:SetText(UnitPower(self.unit)) Nenue@1: else Nenue@1: self.powerbar:Hide() Nenue@1: self.powertext:SetText(nil) Nenue@1: end Nenue@1: return true Nenue@1: end Nenue@1: Nenue@1: Nenue@3: player.UNIT_TARGET = function(self, ...) Nenue@1: if not UnitExists(self.unit) then Nenue@1: self:Hide() Nenue@1: else Nenue@1: self:Show() Nenue@1: self.handler.refresh(self) Nenue@0: end Nenue@0: end Nenue@0: Nenue@3: prototypes.pet = player Nenue@4: prototypes.target = player Nenue@4: prototypes.focus = player