local function StrSplit(inputString, separator) local outputTable = {} for str in string.gmatch(inputString, "([^" .. separator .. "]+)") do outputTable[#outputTable + 1] = str end return outputTable end local function PrintTable(table) for k, v in pairs(table) do print(k .. " " .. v) end end aura_env.GetClassColor = function(class) if class == "Death Knight" then return "\124cFFC41E3A" elseif class == "Druid" then return "\124cFFFF7C0A" elseif class == "Hunter" then return "\124cFFAAD372" elseif class == "Mage" then return "\124cFF3FC7EB" elseif class == "Paladin" then return "\124cFFF48CBA" elseif class == "Priest" then return "\124cFFFFFFFF" elseif class == "Rogue" then return "\124cFFFFF468" elseif class == "Shaman" then return "\124cFF0070DD" elseif class == "Warlock" then return "\124cFF8788EE" elseif class == "Warrior" then return "\124cFFC69B6D" end end local Unit = { New = function(self, unit) o = { ["unit"] = unit, } setmetatable(o, self) self.__index = self return o end, GetAuras = function(self, auraFunc, name, type) return nil end, } local BasicUnit = Unit:New("player") function BasicUnit:GetAuras(auraFunc, name) local aura, _, _, stacks, _, duration, expirationTime, _, _, _, spellID = auraFunc(self.unit, name) if aura ~= nil then return { [UnitName(self.unit)] = { ["duration"] = duration, ["expirationTime"] = expirationTime, ["spellID"] = spellID, ["stacks"] = stacks or 1, }, } else return {} end end -- Maybe implement some sort of throttle to group unit? local GroupUnit = Unit:New("group") function GroupUnit:GetAuras(auraFunc, name) local raidMem = GetNumRaidMembers() local num = GetNumPartyMembers() local unitPrefix = "party" if raidMem > num then unitPrefix = "raid" num = raidMem end auras = {} for i = 1, num do local aura, _, _, stacks, _, duration, expirationTime, _, _, _, spellID = auraFunc(unitPrefix .. i, name) if aura ~= nil then auras[UnitName(unitPrefix .. i)] = { ["duration"] = duration, ["expirationTime"] = expirationTime, ["spellID"] = spellID, ["class"] = UnitClass(unitPrefix .. i) or "Paladin", ["stacks"] = stacks or 1, } end end if unitPrefix == "party" then local aura, _, _, stacks, _, duration, expirationTime, _, _, _, spellID = auraFunc("player", name) if aura ~= nil then auras[UnitName("player")] = { ["duration"] = duration, ["expirationTime"] = expirationTime, ["spellID"] = spellID, ["class"] = UnitClass(unitPrefix .. i) or "Paladin", ["stacks"] = stacks or 1, } end end return auras end -- Nameplate does not work, find out why? local NameplateUnit = Unit:New("nameplate") function NameplateUnit:GetAuras(auraFunc, name) local unitPrefix = "nameplate" auras = {} for i = 1, 40 do local aura, _, _, stacks, _, duration, expirationTime, _, _, _, spellID = auraFunc(auraPrefix .. i, name) if aura ~= nil then auras[UnitName(unitPrefix .. i)] = { ["duration"] = duration, ["expirationTime"] = expirationTime, ["spellID"] = spellID, ["stacks"] = stacks or 1, } end end return auras end local UnitFactory = { New = function(self) o = {} setmetatable(o, self) self.__index = self return o end, CreateUnit = function(self, target) target = string.lower(target) if target == "player" or target == "target" or target == "focus" then return BasicUnit:New(target) elseif target == "group" then return GroupUnit:New(target) elseif target == "nameplate" then return NameplateUnit:New(target) end end, } local unitFactory = UnitFactory:New() local Aura = { New = function(self, entry, index) o = { ["name"] = entry.auraName, ["unit"] = entry.target, ["hasCooldown"] = entry.hasCooldown, ["index"] = index, ["GetAura"] = entry.GetAura, } setmetatable(o, self) self.__index = self return o end, IsActive = function(self) for k, v in pairs(self.unit:GetAuras(self.GetAura, self.name)) do for k2, v2 in pairs(v) do end return true end return false end, IsOnCooldown = function(self) if not self.hasCooldown then return false end return GetSpellCooldown(self.name) > 0 end, AddAsAura = function(self, allstates) local auras = self.unit:GetAuras(self.GetAura, self.name) for k, v in pairs(auras) do duration = v.duration expirationTime = v.expirationTime icon = self:GetAuraIcon(v.spellID) allstates[self.name .. k] = { changed = true, show = true, resort = true, progressType = "timed", duration = duration, expirationTime = expirationTime, index = self.index, icon = icon, pname = k, stacks = v.stacks, pclass = v.class, IsOnCooldown = true, IsActive = true, IsBad = self.GetAura == UnitDebuff, } end end, AddAsCooldown = function(self, allstates) if not self.hasCooldown then return false end startTime, duration = GetSpellCooldown(self.name) icon = self:GetSpellIcon() allstates[self.name] = { changed = true, show = true, resort = true, progressType = "timed", duration = duration, expirationTime = startTime + duration, index = self.index, icon = icon, IsOnCooldown = true, IsActive = false, IsBad = self.GetAura == UnitDebuff, } end, AddAsIcon = function(self, allstates) if not self.hasCooldown then return false end icon = self:GetSpellIcon() allstates[self.name] = { changed = true, show = true, resort = true, progressType = "static", value = 1, total = 1, index = self.index, icon = icon, IsOnCooldown = false, IsActive = false, IsBad = self.GetAura == UnitDebuff, } end, GetSpellIcon = function(self) return select(3, GetSpellInfo(self.name)) end, GetAuraIcon = function(self, spellID) return select(3, GetSpellInfo(spellID)) end, } local Entry = { New = function(self, entry) entry = self:TrimWhitespace(entry) local entryData = StrSplit(entry, ",") local name = self:ReadEntryData(entryData, 1) local type = self:ReadEntryData(entryData, 2) or "Buff" local target = unitFactory:CreateUnit(self:ReadEntryData(entryData, 3) or "Player") local cooldown = (self:ReadEntryData(entryData, 4) == "0") or false cooldown = not cooldown local GetAura = UnitBuff if type == "Debuff" then GetAura = UnitDebuff end o = { ["entry"] = entry, ["auraName"] = name, ["GetAura"] = GetAura, ["target"] = target, ["hasCooldown"] = cooldown, } setmetatable(o, self) self.__index = self return o end, ReadEntryData = function(self, entryData, index) local str = entryData[index] if str == nil then return nil end str = self:TrimWhitespace(str) return str end, TrimWhitespace = function(self, str) str = str:gsub("^[ ]+", "") str = str:gsub("\n$", "") str = str:gsub("[ ]+$", "") return str end, } aura_env.auras = {} for entry in string.gmatch(aura_env.config.spellList, "([a-zA-Z,0-9 ]+)") do entry = Entry:New(entry) auraObj = Aura:New(entry, #aura_env.auras + 1) aura_env.auras[#aura_env.auras + 1] = auraObj end aura_env.HandleEvent = function(allstates) for k, v in ipairs(aura_env.auras) do if v:IsActive() then v:AddAsAura(allstates) elseif v:IsOnCooldown() and not v:IsActive() then v:AddAsCooldown(allstates) elseif not v:IsOnCooldown() and not v:IsActive() then v:AddAsIcon(allstates) end end end