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