aura_env.debug = true ---@class BaseCooldown ---@field name string ---@field filename string ---@field id number ---@field isOnCooldown boolean ---@field announced boolean ---@field remaining number aura_env.BaseCooldown = { ---@param id number ---@param name string ---@param playbackSpeed number? ---@return BaseCooldown new = function(id, name, playbackSpeed) local self = setmetatable({}, { __index = aura_env.BaseCooldown }) self.id = id self.name = name name = string.gsub(name, " ", "_") name = string.gsub(name, "'", "") name = string.lower(name) self.filename = name if playbackSpeed == nil then self.filename = string.format("1x\\%s", self.filename) else self.filename = string.format("%.1fx\\%s", playbackSpeed, self.filename) end if aura_env.debug then print(string.format("Created BaseCooldown with filename %s", self.filename)) end self.isOnCooldown = false self.announced = false self.remaining = 0 return self end, ---@param self BaseCooldown ---@param cooldownFunc fun(spellId: number): number, number Update = function(self, cooldownFunc) local start, duration = cooldownFunc(self.id) local isOnCooldown = start > 0 and duration > 3 local remaining = start + duration - GetTime() if not isOnCooldown and self.isOnCooldown then self:playComplete() self.announced = false end if not self.announced and isOnCooldown and remaining < 10 then self:playSoon() self.announced = true end self.isOnCooldown = isOnCooldown self.remaining = remaining end, ---@param self BaseCooldown playComplete = function(self) local soundFile = string.format("Interface\\Sounds\\alerts\\%s.ogg", self.filename) if aura_env.debug then print(string.format("%s is off cooldown, playing sound file at %s", self.filename, soundFile)) end WeakAuras.ScanEvents("PLAY_SOUND", soundFile) end, ---@param self BaseCooldown playSoon = function(self) local soundFile = string.format("Interface\\Sounds\\alerts\\%s_soon.ogg", self.filename) if aura_env.debug then print(string.format("%s is almost off cooldown, playing sound file at %s", self.filename, soundFile)) end WeakAuras.ScanEvents("PLAY_SOUND", soundFile) end } ---@class Spell:BaseCooldown aura_env.Spell = { ---@param id number ---@param name string ---@param playbackSpeed number? ---@return Spell new = function(id, name, playbackSpeed) local obj = aura_env.BaseCooldown.new(id, name, playbackSpeed) ---@cast obj Spell setmetatable(obj, { __index = aura_env.Spell }) return obj end, Update = function(self) aura_env.BaseCooldown.Update(self, GetSpellCooldown) end, playComplete = aura_env.BaseCooldown.playComplete, playSoon = aura_env.BaseCooldown.playSoon } ---@class Item:BaseCooldown aura_env.Item = { ---@param id number ---@param name string ---@param playbackSpeed number? ---@return Item new = function(id, name, playbackSpeed) local obj = aura_env.BaseCooldown.new(id, name, playbackSpeed) ---@cast obj Item setmetatable(obj, { __index = aura_env.Item }) return obj end, Update = function(self) aura_env.BaseCooldown.Update(self, GetItemCooldown) end, playComplete = aura_env.BaseCooldown.playComplete, playSoon = aura_env.BaseCooldown.playSoon } ---@class Buff:BaseCooldown ---@field isActive boolean aura_env.Buff = { ---@param id number ---@param name string ---@param playbackSpeed number? ---@return Buff new = function(id, name, playbackSpeed) local obj = aura_env.BaseCooldown.new(id, name, playbackSpeed) ---@cast obj Buff setmetatable(obj, { __index = aura_env.Buff }) obj.isActive = false return obj end, Update = function(self) local duration, expiry = select(6, UnitBuff("player", self.name)) local isActive = true if duration == nil or expiry == nil then isActive = false expiry = 0 end local remaining = expiry - GetTime() if not isActive and self.isActive then self:playComplete() -- More like "PlayExpired" self.announced = false end if not self.announced and isActive and remaining < 5 then self:playSoon() -- More like "PlayExpiring" self.announced = true end self.isActive = isActive self.remaining = remaining end, ---@param self Buff playComplete = function(self) local soundFile = string.format("Interface\\Sounds\\alerts\\%s_expired.ogg", self.filename) if aura_env.debug then print(string.format("%s expired, playing sound file at %s", self.filename, soundFile)) end WeakAuras.ScanEvents("PLAY_SOUND", soundFile) end, ---@param self Buff playSoon = function(self) local soundFile = string.format("Interface\\Sounds\\alerts\\%s_expiring.ogg", self.filename) if aura_env.debug then print(string.format("%s expiring, playing sound file at %s", self.filename, soundFile)) end WeakAuras.ScanEvents("PLAY_SOUND", soundFile) end } ---@type table|nil aura_env.ActiveSet = nil ---@type table> aura_env.Cooldowns = { ["Warrior"] = { aura_env.Spell.new(107574, "Avatar", 1.6), aura_env.Spell.new(1719, "Battle Cry", 1.6), aura_env.Spell.new(205545, "Odyns Fury", 1.6), aura_env.Spell.new(26297, "Berserking", 1.6), aura_env.Spell.new(12292, "Bloodbath", 1.6), }, ["Warlock"] = { aura_env.Spell.new(108416, "Dark Pact", 1.6), aura_env.Spell.new(104773, "Unending Resolve", 1.6), aura_env.Spell.new(196098, "Soul Harvest", 1.6), aura_env.Item.new(5512, "Healthstone", 1.6), aura_env.Buff.new(0, "Deadwind Harvester", 1.6), } }