-- TellMeWhen.lua local _; local pairs = pairs; local GetSpecialization = GetSpecialization; local UnitExists = UnitExists; local UnitAura = UnitAura; -- character specific frames local chars = { ["Stormreaver"] = { ["Vildan"] = { { unit = "target", spec = 3, -- Retribution auras = {"Judgment"}, auraFilter = "PLAYER HARMFUL", x = 570, -- placed over Innervate frame y = 440, width = 80, height = 80, }, { unit = "player", spec = 3, -- Retribution auras = {"Divine Purpose"}, auraFilter = "PLAYER HELPFUL", x = 570, y = 530, width = 80, height = 80, }, { unit = "player", spec = 2, -- Protection auras = {"Shield of the Righteous"}, auraFilter = "PLAYER HELPFUL", x = 570, y = 440, width = 80, height = 80, }, { unit = "player", auras = {"Divine Shield"}, auraFilter = "PLAYER HELPFUL", x = 660, y = 440, width = 80, height = 80, }, }, }, }; -- settings entry: -- unit = unitID where to check auras, not required for totem checkers -- spec = player spec index to show frame, if nil show always -- auras = list of auras to track, in priority order -- auraFilter = filter for UnitAura -- totems = list of totem slots to track, in priority order, only checked if auras is nil -- x = x position relative to UIParent bottom left -- y = y position relative to UIParent bottom left -- width = width -- height = height -- global frames' settings local settings = { { unit = "player", auras = {"Innervate"}, auraFilter = "HELPFUL", x = 570, y = 440, width = 80, height = 80, }, { unit = "player", auras = { "Necrotic Embrace", "Flametouched", "Shadowtouched", "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul", "Time Bomb", "Broken Shard", }, auraFilter = "HARMFUL", x = 660, y = 530, width = 80, height = 80, }, }; local frames = {}; local units = {}; -- mapping from unitID to frames local totems = {}; -- mapping to frames with totems local bosses = {}; for i = 1, MAX_BOSS_FRAMES do bosses[i] = "boss"..i; end local currentSpec = 0; -- 0 is invalid local Indicators = CreateFrame("Frame", "OmaTMW", UIParent); local function updateAuraFrame(frame) local unit = frame.unit; if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then local name, icon, count, duration, expires; for _, aura in pairs(frame.auras) do name, _, icon, count, _, duration, expires = UnitAura(unit, aura, nil, frame.auraFilter); if name then if expires > 0 then frame.cd:SetCooldown(expires - duration, duration); frame.cd:Show(); else frame.cd:Hide(); end frame.icon:SetTexture(icon); frame:Show(); return; end end end frame:Hide(); end local function updateAuras(unit) if units[unit] then for _, i in pairs(units[unit]) do updateAuraFrame(frames[i]); end end end local function updateTotemFrame(frame) print("totem frame not implemented"); end local function updateTotems(slot) if totems[slot] then for _, i in pairs(totems[slot]) do updateTotemFrame(frames[i]); end end end local function createTMW(name, config, parent) local frame = CreateFrame("Frame", name, parent); frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height); frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y); frame.unit = config.unit; frame.spec = config.spec; frame.auras = config.auras; frame.auraFilter = config.auraFilter; frame.totems = config.totems; frame:Hide(); -- TODO a background, like Masque, stack count frame.icon = frame:CreateTexture(nil, "ARTWORK"); frame.icon:SetAllPoints(); frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93); frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate"); frame.cd:SetReverse(true); frame.cd:SetAllPoints(); return frame; end local function initialize() Indicators:SetFrameStrata("LOW"); Indicators:SetPoint("BOTTOMLEFT"); Indicators:SetWidth(1); Indicators:SetHeight(1); currentSpec = GetSpecialization(); local name, realm = UnitFullName("player"); if chars[realm] and chars[realm][name] then for _, config in pairs(chars[realm][name]) do table.insert(settings, config) end end for i, config in pairs(settings) do if config.unit then if not units[config.unit] then units[config.unit] = {} end table.insert(units[config.unit], i); end if config.totems then for _, slot in pairs(config.totems) do if not totems[slot] then totems[slot] = {} end table.insert(totems[slot], i); end end frames[i] = createTMW("OmaTMW"..i, config, Indicators); end for _, frame in pairs(frames) do if frame.auras then updateAuraFrame(frame) end if frame.totems then updateTotemFrame(frame) end end end -- TODO have healthstone icon for player separate from this Indicators:RegisterEvent("UNIT_AURA"); Indicators:RegisterEvent("PLAYER_TARGET_CHANGED"); Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE"); Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT"); Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED"); Indicators:RegisterEvent("PLAYER_LOGIN"); Indicators:SetScript("OnEvent", function(self, event, arg1) if event == "UNIT_AURA" then updateAuras(arg1); elseif event == "PLAYER_TARGET_CHANGED" then updateAuras("target"); elseif event == "PLAYER_TOTEM_UPDATE" then updateTotems(arg1); elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then for _, boss in pairs(bosses) do updateAuras(boss); end elseif event == "PLAYER_SPECIALIZATION_CHANGED" then currentSpec = GetSpecialization(); for _, frame in pairs(frames) do if frame.auras then updateAuraFrame(frame) end if frame.totems then updateTotemFrame(frame) end end elseif event == "PLAYER_LOGIN" then initialize(); end end);