Nenue@6: -- User: Krakyn Nenue@6: -- Created: 12/15/2015 7:31 PM Nenue@6: --[[ Nenue@6: -- Turok by @project-author@ Nenue@6: -- @file-author@ Nenue@6: -- @file-revision@:@project-revision@ Nenue@6: -- @file-date-iso@ Nenue@6: -- Nenue@6: -- Visible element operations begin here Nenue@6: --]] Nenue@6: local _G = _G Nenue@6: local T, pairs, select, setmetatable, type, tinsert = _G.Turok, pairs, select, setmetatable, type, tinsert Nenue@6: local mod = T:NewModule("PowerBar") Nenue@6: local UnitPower, UnitPowerMax, GetTalentInfoByID, GetTalentInfo, CreateFrame = UnitPower, UnitPowerMax, GetTalentInfoByID, GetTalentInfo, CreateFrame Nenue@6: local bar, db, prototype -- convenience upvalues Nenue@6: local cType, cText, cNum, cWord, cKey, cPink, cBool = cText, cNum, cWord, cKey, cPink, cBool Nenue@6: --@debug Nenue@6: local cType, cText, cNum, cWord, cKey, cPink, cBool = cText, cNum, cWord, cKey, cPink, cBool Nenue@6: local print = function(...) Nenue@6: if _G.Devian and _G.DevianDB.workspace ~= 1 then Nenue@6: _G.print('PowerBar', ...) Nenue@6: end Nenue@6: end Nenue@9: local uprint = function(...) Nenue@9: if _G.Devian and _G.DevianDB.workspace ~= 1 then Nenue@9: _G.print('Update', ...) Nenue@9: end Nenue@9: end Nenue@6: local addon, tg = ... Nenue@6: tg.what = tostring(tg.what)..'more' Nenue@6: print(tg.what) Nenue@6: --@end-debug@ Nenue@6: mod.OnInitialize = function(self) Nenue@6: self.UNIT_SPELLCAST_START = self.SpellCastEvent Nenue@6: self.UNIT_SPELLCAST_STOP = self.SpellCastEvent Nenue@6: self.UNIT_SPELLCAST_SUCCEEDED = self.SpellCastEvent Nenue@6: self.UNIT_SPELLCAST_CHANNEL_START = self.SpellCastEvent Nenue@6: self.UNIT_SPELLCAST_CHANNEL_STOP = self.SpellCastEvent Nenue@6: self.SPELL_UPDATE_COOLDOWN = self.SpellCooldownEvent Nenue@6: self.PLAYER_REGEN_DISABLED = self.CombatStart Nenue@6: self.PLAYER_REGEN_ENABLED = self.CombatEnd Nenue@6: self.focusbar = {} Nenue@6: self.parserLog = {} Nenue@6: self.currentParse = {} Nenue@6: end Nenue@6: local SPELL_POWER_MANA, SPELL_POWER_ENERGY, SPELL_POWER_RAGE, SPELL_POWER_FOCUS = SPELL_POWER_MANA, SPELL_POWER_ENERGY, SPELL_POWER_RAGE, SPELL_POWER_FOCUS Nenue@6: local SPELL_POWER_SHADOW_ORBS = SPELL_POWER_SHADOW_ORBS Nenue@6: local SPELL_POWER_SOUL_SHARDS, SPELL_POWER_BURNING_EMBERS, SPELL_POWER_DEMONIC_FURY = SPELL_POWER_SOUL_SHARDS, SPELL_POWER_BURNING_EMBERS, SPELL_POWER_DEMONIC_FURY Nenue@6: local SPELL_POWER_HOLY_POWER = SPELL_POWER_HOLY_POWER Nenue@6: local SPELL_POWER_CHI = SPELL_POWER_CHI Nenue@6: local SPELL_POWER_COMBO_POINTS = SPELL_POWER_COMBO_POINTS Nenue@6: Nenue@6: -- indexes for talent_update cleanup Nenue@6: mod.secondary_rows = {} Nenue@6: mod.disabled_frames = {} Nenue@6: Nenue@6: --[[ Nenue@6: -- Prototype list naming all the data sources and events that need to be handled for the logged in character Nenue@6: -- .power_type {[bliz const] = event token} list of resources represented by global SPELL_POWER_* constants in the blizzard ui and the UNIT_POWER* token argument representing it Nenue@6: -- .frame string frameXML template Nenue@6: -- .spells {[spell name/id] = {events}} list of spells tracked by the updater Nenue@6: -- .secondary {[aura name] = {}} list of auras tracked as secondary resources such as Thrill of Hunt, Anticipatin, Evangelism, etc. Nenue@6: --]] Nenue@6: mod.prototype = { Nenue@6: ['HUNTER'] = { Nenue@6: primary = { Nenue@6: [1] = {"FOCUS", SPELL_POWER_FOCUS}, -- array of power type constants associated to event strings Nenue@6: }, Nenue@6: frame = 'TkThinComboTemplate', ---------------------- desired frame template Nenue@6: spells = { Nenue@6: ["Steady Shot"] = {'UNIT_SPELL_CAST_SUCCEEDED', 'UNIT_SPELLCAST_STOP', 'UNIT_SPELLCAST_START'} -- spell events that this frame should listen to Nenue@6: }, Nenue@6: secondary = {}, Nenue@6: spec = { Nenue@6: [1] = { Nenue@6: secondary = { Nenue@6: ['Frenzy'] = { Nenue@6: type = 'aura', Nenue@6: order = 1, Nenue@6: scale = 5, Nenue@6: filters = 'HELPFUL', Nenue@6: max = 5, Nenue@6: specPage = 1, Nenue@6: unit = 'player', Nenue@6: spellID = 19623, Nenue@6: }, Nenue@6: ['Focus Fire'] = { Nenue@6: type = 'aura', Nenue@6: max = 40, Nenue@6: order = 2, Nenue@6: scale = 5, Nenue@6: line = 3, --------------- use this subtext value instead of count field Nenue@6: filters = 'HELPFUL', Nenue@6: specPage = 1, Nenue@6: unit = 'player', Nenue@6: spellID = 19623, Nenue@6: } Nenue@6: } Nenue@6: }, Nenue@6: [2] = { Nenue@6: secondary = { ------------------------ list of buffs that act as a secondary resource Nenue@6: ['Thrill of the Hunt'] = { Nenue@6: order = 1, Nenue@6: unit = 'player', Nenue@6: type = 'aura', Nenue@6: max = 3, Nenue@6: scale = 5, Nenue@6: filters = 'HELPFUL', Nenue@6: talent = {4,3}, Nenue@6: display = 'progressbar' Nenue@6: }, Nenue@6: }, Nenue@6: }, Nenue@6: }, Nenue@6: }, Nenue@6: ['PRIEST'] = { Nenue@6: primary = { Nenue@6: [1] = {'MANA', SPELL_POWER_MANA} Nenue@6: }, Nenue@6: frame = 'TkThinComboTemplate', Nenue@6: secondary = {}, Nenue@6: spec = { Nenue@6: [1] = { Nenue@6: secondary = { Nenue@6: ['Evangelism'] = { Nenue@6: order = 1, Nenue@6: max = 5, Nenue@6: scale = 5, Nenue@6: type='aura', Nenue@6: unit = 'player', Nenue@6: filters = 'HELPFUL|PLAYER', Nenue@6: spellID = 81662, Nenue@6: } Nenue@6: } Nenue@6: }, Nenue@6: [3] = { Nenue@6: primary = { Nenue@6: [1] = {'SHADOW_ORBS', SPELL_POWER_SHADOW_ORBS}, Nenue@6: }, Nenue@6: secondary = { Nenue@6: ["Surge of Darkness"] = { Nenue@6: order = 2, Nenue@6: type = 'aura', Nenue@6: filters = 'HELPFUL|PLAYER', Nenue@6: spellID = 87160, Nenue@6: talentID = 21751, Nenue@6: max = 3, Nenue@6: scale = 5, Nenue@6: unit = 'player', Nenue@6: }, Nenue@6: ["Insanity"] = { Nenue@6: order = 2, Nenue@6: type = 'aura', Nenue@6: binary = true, Nenue@6: regress = true, Nenue@6: size = 1, scale = 1, max = 1, Nenue@6: filters = 'HELPFUL|PLAYER', Nenue@6: spellID = 132573, Nenue@6: unit = 'player', Nenue@6: talentID = 21753}, Nenue@6: } Nenue@6: }, Nenue@6: }, Nenue@6: }, Nenue@6: ['ROGUE'] = { Nenue@6: primary = { Nenue@6: [1] = {'ENERGY', SPELL_POWER_ENERGY}, Nenue@6: [2] = {'COMBO_POINTS', SPELL_POWER_COMBO_POINTS} Nenue@6: }, Nenue@6: frame = 'TkThinComboTemplate', Nenue@6: secondary = { Nenue@6: ['Anticipation'] = { Nenue@6: type = 'aura', Nenue@6: order = 1, Nenue@6: max = 5, Nenue@6: scale = 5, Nenue@6: unit = 'player', Nenue@6: talentID = 19250, Nenue@6: }, Nenue@6: }, Nenue@6: spec = {}, Nenue@6: }, Nenue@6: ['MAGE'] = { Nenue@6: primary = { Nenue@6: [1] = {'MANA', SPELL_POWER_MANA}, Nenue@6: }, Nenue@6: frame = 'TkThinComboTemplate', Nenue@6: secondary = { Nenue@6: Nenue@6: ["Incanter's Flow"] = { Nenue@6: type = 'aura', Nenue@6: unit = 'player', Nenue@6: filters = 'HELPFUL|PLAYER', Nenue@6: spellID = 1463, Nenue@6: max = 5, Nenue@6: scale = 5, Nenue@6: order = 2, Nenue@6: talentID = 16033, Nenue@6: }, Nenue@6: ["Rune of Power"] = { Nenue@6: type = 'aura', Nenue@6: unit = 'player', Nenue@6: filters = 'HELPFUL|PLAYER', Nenue@6: binary = true, Nenue@6: max = 1, Nenue@6: scale = 1, Nenue@6: order = 2, Nenue@6: talentID = 16032, Nenue@6: } Nenue@6: }, Nenue@6: spec = { Nenue@6: [1] = { Nenue@6: secondary = { Nenue@6: ['Arcane Charge'] = { Nenue@6: type ='aura', Nenue@6: unit = 'player', Nenue@6: filters = 'HARMFUL|PLAYER', Nenue@6: spellID = 114664, Nenue@6: scale = 4, Nenue@6: max = 4, Nenue@6: order = 1, Nenue@6: }, Nenue@6: } Nenue@6: }, Nenue@6: [3] = { Nenue@6: secondary = { Nenue@6: ['Fingers of Frost'] = { Nenue@6: type = 'aura', Nenue@6: unit = 'player', Nenue@6: filters = '', Nenue@6: spellID = 112965, Nenue@6: max = 2, Nenue@6: scale = 4, Nenue@6: order = 1, Nenue@6: }, Nenue@6: ['Brain Freeze'] = { Nenue@6: type = 'aura', Nenue@6: unit = 'player', Nenue@6: filters = '', Nenue@6: spellID = 44549, Nenue@6: scale = 4, Nenue@6: max = 2, Nenue@6: order = 1, Nenue@6: mirror = true, Nenue@6: } Nenue@6: } Nenue@6: }, Nenue@6: } Nenue@6: } Nenue@6: } Nenue@6: local P = mod.prototype Nenue@6: Nenue@6: function mod:OnEnable() Nenue@6: self.disabled_freams = { Nenue@6: [T.playerClass] = { Nenue@6: [T.specPage] = {} Nenue@6: } Nenue@6: } Nenue@6: self.watched_units = {} Nenue@6: self.watched_auras = {} Nenue@6: self.watched_spells = {} Nenue@6: self.db = TurokData.powerbar Nenue@6: db = self.db Nenue@6: Nenue@6: self:Prototype_Init() Nenue@6: end Nenue@6: function mod:Prototype_Init() Nenue@6: -- consult prototype vars Nenue@6: prototype = {} Nenue@6: mod.dcopy = function(t1, t2, d) Nenue@6: d = d or '' Nenue@6: for k,v in pairs(t2) do Nenue@6: if type(v) == 'table' then Nenue@6: if type(t1[k]) ~= 'table' then Nenue@6: t1[k] = {} Nenue@6: print(d, 'adding table', cKey(k)) Nenue@6: else Nenue@6: print(d, 'merging tables', cKey(k)) Nenue@6: end Nenue@6: mod.dcopy(t1[k], v, d..' ') Nenue@6: else Nenue@6: if t1[k] then Nenue@6: print(d, 'clobbered', k) Nenue@6: else Nenue@6: print(d, k, '=', cType(v)) Nenue@6: end Nenue@6: t1[k] = v Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: mod.dcopy(prototype, mod.prototype[T.playerClass]) Nenue@6: if mod.prototype[T.playerClass].spec[T.specPage] then Nenue@6: mod.dcopy(prototype, mod.prototype[T.playerClass].spec[T.specPage]) Nenue@6: end Nenue@6: Nenue@6: mod.thisproto = prototype Nenue@6: Nenue@6: print('|cFFFF0088Template:|r', 'Frame', 'TkPowerBarFrame', UIParent, prototype.frame) Nenue@6: db = self.db Nenue@6: Nenue@6: if bar and bar.GetObjectType then Nenue@6: bar:Hide() Nenue@6: mod.disabled_frames[bar.specPage] = bar Nenue@6: print('putting away old frame') Nenue@6: end Nenue@6: Nenue@6: if not bar then Nenue@6: bar = CreateFrame('Frame', 'TkPowerBar', UIParent, prototype.frame) Nenue@6: end Nenue@6: bar.specPage = T.specPage Nenue@6: bar.specID = T.specID Nenue@6: bar.primary = {} -- {current, max, token} Nenue@6: bar.secondary = {} -- {current, max, token} Nenue@6: bar.aura = {} -- {name, duration, expires, unit, flags} Nenue@6: bar.spell = {} -- copy of the last T.spellevent match Nenue@6: print(' setting layout', db) Nenue@6: print(bar:GetName()) Nenue@6: T.SetFrameLayout(bar, prototype.cvars and db[prototype.cvars] or db) Nenue@6: T.SetStatusTextures(bar, db) Nenue@6: Nenue@6: print(' setting methods') Nenue@6: bar.Init = mod.Bar_Init Nenue@6: bar.Event = mod.Bar_Event Nenue@6: bar.Update = mod.Bar_Update Nenue@6: Nenue@6: Nenue@6: --- loop through aura definitions and flag accordingly Nenue@6: print('Primary power types:') Nenue@6: for order, power_data in pairs(prototype.primary) do Nenue@6: print( order, unpack(power_data)) Nenue@6: local token, power_type = unpack(power_data) Nenue@6: local power, max = UnitPower('player', power_type), UnitPowerMax('player', power_type) Nenue@6: bar.primary[token] = {power, max, power_type, order} Nenue@6: print(' ', cKey(token), '= {', power, max, power_type, order, '}') Nenue@6: end Nenue@6: Nenue@6: --- go through secondary data args and assign the appropriate source functions Nenue@6: local useAura, useCooldown Nenue@6: local used_rows = {} Nenue@6: if prototype.secondary then Nenue@6: mod.secondary = {} Nenue@6: for name, c in pairs(prototype.secondary) do Nenue@6: local isActive = true Nenue@6: print('parsing extra handler', name) Nenue@6: if c.talentID then Nenue@6: print(c.talentID, T.specPage) Nenue@6: isActive = (type(c.talentID) == 'table') and select(4, GetTalentInfo(unpack(c.talentID), T.specGroup)) or Nenue@6: select(4, GetTalentInfoByID(c.talentID, T.specGroup)) Nenue@6: print(' talentID:', cNum(isActive)) Nenue@6: end Nenue@6: if isActive then Nenue@6: local sc = {} Nenue@6: Nenue@6: sc = c Nenue@6: print(' enable:', cNum(isActive), cWord(c.type)) Nenue@6: if c.type == 'aura' then Nenue@6: sc.spellName = name Nenue@6: if c.binary then Nenue@6: sc.Get = function(self) Nenue@6: print('get: UnitAura', self.unit, self.spellName, c.filters) Nenue@6: local exists = UnitAura(self.unit, self.spellName, nil, self.filters) Nenue@6: return (exists) and 1 or 0 Nenue@6: end Nenue@6: else Nenue@6: sc.Get = function(self) Nenue@6: print('get: UnitAura', self.unit, self.spellName, c.filters) Nenue@6: local _,_,_, count = UnitAura(self.unit, self.spellName, nil, self.filters) Nenue@6: return count or 0 Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: useAura = true Nenue@6: elseif c.type == 'cooldown' then Nenue@6: if c.inverse then Nenue@6: sc.Get = function(self) Nenue@6: local start, duration, enabled = GetSpellCooldown(c.spellID) Nenue@6: sc[1] = (duration > 0) and (GetTime() - start) or c.max Nenue@6: print('get: GetSpellCooldown (inverse)', c.spellID, '=', sc[1]) Nenue@6: end Nenue@6: else Nenue@6: sc.Get = function(self) Nenue@6: local start, duration, enabled = GetSpellCooldown(c.spellID) Nenue@6: sc[1] = (duration > 0) and (start + duration - GetTime()) or 0 Nenue@6: print('get: GetSpellCooldown', c.spellID, '=', sc[1]) Nenue@6: end Nenue@6: end Nenue@6: useCooldown = true Nenue@6: end Nenue@6: print(' committing', name, 'to row', sc.order) Nenue@6: bar.secondary[name] = sc Nenue@6: used_rows[sc.order] = true -- index the drawn rows for talent_update Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: Nenue@6: if useAura then bar:RegisterEvent('UNIT_AURA') end Nenue@6: if useCooldown then bar:RegisterEvent('UNIT_SPELLCAST_SUCCEEDED') end Nenue@6: Nenue@6: bar:SetScript('OnUpdate', nil) -- make sure any xml embeds are cleaned out Nenue@6: bar:SetScript('OnEvent', mod.Bar_Event) Nenue@6: bar:RegisterEvent('UNIT_POWER_FREQUENT') Nenue@6: Nenue@6: bar:Init() Nenue@6: bar:Show() Nenue@6: Nenue@6: -- metrics used by data plots Nenue@6: bar.width = db.width Nenue@6: bar.foreground_inset = db.foreground_inset Nenue@6: bar.right_edge = bar:GetRight() Nenue@6: bar.fill_limit = bar.right_edge Nenue@6: bar.foreground.width = bar.width + (bar.foreground_inset) Nenue@6: bar.spacing = 1 Nenue@6: Nenue@6: mod.powerbar = bar Nenue@6: end Nenue@6: Nenue@6: mod.Bar_Init = function(self) Nenue@6: local mainPower, comboPower Nenue@6: for token, power in pairs(self.primary) do Nenue@6: if power[4] == 1 then Nenue@6: mainPower = power Nenue@6: elseif power[4] == 2 then Nenue@6: comboPower = power Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: if mainPower then Nenue@6: local power, max, type, token = unpack(mainPower) Nenue@6: if power and max then Nenue@6: self.powerText:SetText(power) Nenue@6: self:SetProgress(power/max) Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: if comboPower then Nenue@6: local power, max, type, token = unpack(comboPower) Nenue@6: local px = (self.width-db.secondary.spacing* (max -1)-db.secondary.padding*2) / max Nenue@6: self.combo = {} Nenue@6: for i = 1, max do Nenue@6: if not self.combo[i] then Nenue@6: self.combo[i] = self:CreateTexture('TkPrimaryResourcePellet'..i, 'OVERLAY') Nenue@6: end Nenue@6: Nenue@6: local k = i - 1 Nenue@6: local cx = db.secondary.padding + px * k + db.secondary.spacing * k Nenue@6: local cy = db.secondary.padding Nenue@6: self.combo[i]:ClearAllPoints() Nenue@6: self.combo[i]:SetSize(px, db.secondary.height) Nenue@6: self.combo[i]:SetPoint(db.secondary.anchor, self, db.secondary.anchorTo, cx, cy) Nenue@6: --print(' ', self.combo[i]:GetName(), self.pointsize1, cx, cy, self.combo[i]:GetDrawLayer()) Nenue@6: Nenue@6: self.combo[i]:Show() Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: Nenue@6: if self.secondary then Nenue@6: if not self.resources then Nenue@6: print('|cFFFF0000creating resources block') Nenue@6: self.resources = {} Nenue@6: else Nenue@6: local hidecount = 0 Nenue@6: for i, row in pairs(self.resources) do Nenue@6: for j, col in pairs(row) do Nenue@6: col:Hide() Nenue@6: hidecount = hidecount + 1 Nenue@6: end Nenue@6: end Nenue@6: print('hiding', hidecount, 'regions') Nenue@6: end Nenue@6: for name, secondary in pairs(self.secondary) do Nenue@6: local n = secondary.order Nenue@6: local sid = 'secondary'..n Nenue@6: local c = db[sid] or db Nenue@6: if not self.resources[n] then Nenue@6: print(' |cFFFF8800creating resource row') Nenue@6: self.resources[n] = {} Nenue@6: end Nenue@6: local row = self.resources[n] Nenue@6: Nenue@6: print('secondary resource', cText(name), 'max= '..cNum(secondary.max), 'scale= '..cNum(secondary.scale)) Nenue@6: local px = c.padding Nenue@6: local pw = (self.width - c.padding*2 - c.spacing * (secondary.scale - 1)) / secondary.scale Nenue@6: for i = 1, (secondary.max or 1) do Nenue@6: if not row[i] then Nenue@6: row[i] = bar:CreateTexture('TkResourcePellet.'..tostring(secondary.order)..'.'..tostring(i)) Nenue@6: end Nenue@6: row[i]:Show() Nenue@6: row[i]:SetDrawLayer('OVERLAY', sid) Nenue@6: row[i]:SetPoint('BOTTOMLEFT', self, 'TOPLEFT', px, c.y) Nenue@6: row[i]:SetSize(pw, db[sid].height or db.height) Nenue@6: Nenue@6: print(' *', cNum(i), cKey(sid), cNum(px), cNum(c.padding)) Nenue@6: px = px + pw + c.spacing Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: mod.Bar_Event(self, nil, 'player') Nenue@6: end Nenue@6: Nenue@6: -- we only want to update at specific points Nenue@6: mod.Bar_Event = function(self, event, ...) Nenue@6: local unit, token = ... Nenue@9: uprint( event, unit, token) Nenue@6: if token and unit == 'player' then Nenue@6: mod.Bar_Power(self, token) Nenue@6: end Nenue@6: --print(unit, token, ...) Nenue@6: mod.Bar_Aura(bar, event, unit, token, ...) Nenue@6: end Nenue@6: Nenue@6: mod.Bar_Aura = function (self, event, unit) Nenue@9: uprint('bar updating function called', event, unit) Nenue@6: Nenue@6: Nenue@6: if event == 'UNIT_AURA' or event == nil then Nenue@6: for token, info in pairs(self.secondary) do Nenue@6: local row = self.resources[info.order] Nenue@6: if info.unit == unit then Nenue@6: local count = info.Get(info) Nenue@6: local db = db['secondary'..info.order] or db Nenue@6: for i = 1, info.max do Nenue@6: local palette = (i > count) and ('background_color') or ('foreground_color') Nenue@6: Nenue@6: print(token, i, count, (i > count), palette, unpack(db[palette])) Nenue@6: row[i]:SetTexture(unpack(db[palette])) Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: function mod:Bar_Power(token) Nenue@6: if not self.primary[token] then Nenue@6: return Nenue@6: end Nenue@6: Nenue@6: local p = self.primary[token] Nenue@6: -- 1=cur, 2=max, 3=type, 4=token Nenue@6: p[1] = UnitPower('player', p[3]) Nenue@6: p[2] = UnitPowerMax('player', p[3]) Nenue@9: uprint(' ', table.concat(self.primary[token],', ')) Nenue@6: Nenue@6: if p[4] == 1 then Nenue@9: uprint( 'progress:', p[1]/p[2]) Nenue@6: --print(unpack(p)) Nenue@6: self.powerText:SetText(p[1]) Nenue@6: self:SetProgress(p[1]/p[2]) Nenue@6: elseif p[4] == 2 then Nenue@6: --print('update on', token, 'c:', p[1], 'm:', p[2]) Nenue@6: self.secondaryText:SetText(p[1]) Nenue@6: for i = 1, p[2] do Nenue@6: local palette = (i > p[1]) and 'background_color' or 'foreground_color' Nenue@6: self.combo[i]:SetTexture(unpack(db.secondary[palette])) Nenue@6: Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: --- Spell parsing Nenue@6: function mod:SpellCastEvent(e, u, spellName, rank, castID, spellID) Nenue@6: if u ~= 'player' then Nenue@6: return true Nenue@6: end Nenue@6: if e == 'UNIT_SPELLCAST_DELAYED' then Nenue@6: elseif e == 'UNIT_SPELLCAST_START' then Nenue@6: bar.casting = true Nenue@6: bar.spellevent = T.spellevent[u] Nenue@6: bar.spell = T.casting[u] Nenue@6: elseif e == 'UNIT_SPELLCAST_CHANNEL_START' then Nenue@6: bar.channeling = true Nenue@6: bar.spellevent = T.spellevent[u] Nenue@6: bar.spell = T.channeling[u] Nenue@6: elseif e == 'UNIT_SPELLCAST_SUCCEEDED' then Nenue@6: elseif e == 'UNIT_SPELLCAST_STOP' then Nenue@6: bar.casting = nil Nenue@6: bar.casting = nil Nenue@6: elseif e == 'UNIT_SPELLCAST_CHANNEL_STOP' then Nenue@6: bar.channeling = nil Nenue@6: bar.channeling = nil Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: function mod:PLAYER_TALENT_UPDATE(event, unit) Nenue@6: print(cText('*** Talent Update'), cKey('Spec:'), cWord(T.specName), cNum(T.specPage)) Nenue@6: mod:Prototype_Init() Nenue@6: end