4 local GetSpecialization = GetSpecialization;
5 local UnitExists = UnitExists;
6 local UnitAura = UnitAura;
7 local GetTotemInfo = GetTotemInfo;
9 -- character specific frames
10 -- TODO try with auraFilter, remove characters, change to classes
13 ["PLAYER HELPFUL"] = {
16 auras = {["Divine Shield"]=1, ""},
31 ["PLAYER HELPFUL"] = {
34 auras = {["Judgment"]=1},
41 ["PLAYER HARMFUL"] = {
53 spec = 3, -- Retribution
55 auraFilter = "PLAYER HARMFUL",
56 x = 570, -- placed over Innervate frame
63 spec = 3, -- Retribution
64 auras = {"Divine Purpose"},
65 auraFilter = "PLAYER HELPFUL",
73 spec = 2, -- Protection
74 auras = {"Shield of the Righteous"},
75 auraFilter = "PLAYER HELPFUL",
83 auras = {"Divine Shield"},
84 auraFilter = "PLAYER HELPFUL",
96 auras = {"Bursting With Pride"},
97 auraFilter = "HELPFUL",
98 x = 570, -- placed over Innervate frame
105 auras = {"Divine Purpose"},
106 auraFilter = "PLAYER HELPFUL",
114 spec = 2, -- Protection
115 auras = {"Shield of the Righteous"},
116 auraFilter = "PLAYER HELPFUL",
124 spec = 2, -- Protection
125 auras = {"Shining Light"},
126 auraFilter = "PLAYER HELPFUL",
134 auras = {"Seraphim", "Righteous Verdict"},
135 auraFilter = "PLAYER HELPFUL",
143 auras = {"Divine Shield"},
144 auraFilter = "PLAYER HELPFUL",
152 auras = {"Devotion Aura"},
153 auraFilter = "HELPFUL",
164 auras = {"Shadow Word: Pain", "Purge the Wicked"},
165 auraFilter = "PLAYER HARMFUL",
173 auras = {"Power Word: Fortitude"},
174 auraFilter = "HELPFUL",
183 auras = {"Overcharge Mana"},
184 auraFilter = "PLAYER HELPFUL",
193 totems = {1}, -- Efflorescence
203 auras = {"Tidal Waves"},
204 auraFilter = "PLAYER HELPFUL",
212 auras = {"Healing Rain"},
213 auraFilter = "PLAYER HELPFUL",
221 auras = {"Unleash Life"},
222 auraFilter = "PLAYER HELPFUL",
232 auras = {"Tidal Waves"},
233 auraFilter = "PLAYER HELPFUL",
241 auras = {"Healing Rain"},
242 auraFilter = "PLAYER HELPFUL",
250 auras = {"Unleash Life"},
251 auraFilter = "PLAYER HELPFUL",
262 auraFilter = "HELPFUL",
273 auras = {"Sun King's Blessing"},
274 auraFilter = "PLAYER HELPFUL",
283 auras = {"Infernal Cascade"},
284 auraFilter = "PLAYER HELPFUL",
293 auras = {"Combustion"},
294 auraFilter = "PLAYER HELPFUL",
303 auras = {"Arcane Intellect"},
304 auraFilter = "HELPFUL",
314 auras = {"Winter's Chill"},
315 auraFilter = "PLAYER HARMFUL",
324 auras = {"Icy Veins"},
325 auraFilter = "PLAYER HELPFUL",
333 auras = {"Alter Time"},
334 auraFilter = "PLAYER HELPFUL",
345 -- unit = unitID where to check auras, not required for totem checkers
346 -- spec = player spec index to show frame, if nil show always
347 -- auras = list of auras to track, in priority order
348 -- auraFilter = filter for UnitAura
349 -- totems = list of totem slots to track, in priority order, only checked if auras is nil
350 -- x = x position relative to UIParent bottom left
351 -- y = y position relative to UIParent bottom left
355 -- global frames' settings
359 auras = {"Innervate", "Gift of the Titans", "Power Infusion"},
360 auraFilter = "HELPFUL",
368 auras = {"Ineffable Truth"},
369 auraFilter = "HELPFUL",
378 "Delusions", "Entropic Blast", "Necrotic Embrace", "Flametouched", "Shadowtouched",
379 "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul",
380 "Time Bomb", "Broken Shard", "Demolished", "Fetid Rot", "Roiling Deceit",
381 "Putrid Blood", "Endemic Virus", "Lingering Infection", "Gigavolt Charge",
382 "Crackling Lightning", "Storm's Wail", "Death's Door", "Deathly Withering",
383 "Chilling Touch", "Volatile Charge", "Liquid Gold", "Drained Soul", "Evoke Anguish",
384 "Ancient Curse", "Corrosion", "Debilitating Spit", "Tasty Morsel", "Encroaching Shadows",
385 "Corrupted Existence", "Madness Bomb", "Crimson Chorus", "Essence Sap", "Bloodlight",
386 "Arcane Vulnerability", "Wicked Laceration", "Withering Touch", "Fragment of Destiny",
387 "Flameclasp Eruption", "Wailing Arrow", "Frozen Destruction",
388 "Remnant: Mort'regar's Echoes", "Barbed Arrow", "Scorn", "Ire", "Song of Dissolution",
389 "Grim Portent", "Exposed Threads of Fate", "Despair", "Shadowsteel Chains", "Ignite Soul"
391 auraFilter = "HARMFUL",
400 "Adaptive Membrane", "Gluttonous Miasma", "Remnant: Soulforge Heat"
402 auraFilter = "HARMFUL",
411 local units = {}; -- mapping from unitID to frames
412 local totems = {}; -- mapping to frames with totems
414 for i = 1, MAX_BOSS_FRAMES do
415 bosses[i] = "boss"..i;
417 local currentSpec = 0; -- 0 is invalid
419 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
421 local function updateAuraFrame(frame)
422 local unit = frame.unit;
423 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
424 local name, icon, count, duration, expires, id;
425 local auraFilter = frame.auraFilter;
428 name, icon, count, _, duration, expires, _, _, _, id = UnitAura(unit, i, auraFilter);
429 if not name then break end
430 -- possible improvement to add spellID as an option
431 if frame.auras[name] and not frame.invert then
433 frame.stack:SetText(count);
439 frame.cd:SetCooldown(expires - duration, duration);
444 frame.icon:SetTexture(icon);
447 elseif frame.auras[name] and frame.invert then
448 frame.icon:SetTexture(icon);
455 frame:Show(); -- not functional without first hiding once to get SetTexture
462 local function updateAuras(unit)
464 for _, i in pairs(units[unit]) do
465 updateAuraFrame(frames[i]);
470 local function updateTotemFrame(frame, slot)
471 local _, name, start, duration, icon = GetTotemInfo(slot);
473 frame.cd:SetCooldown(start, duration);
475 frame.icon:SetTexture(icon);
482 local function updateTotems(slot)
484 for _, i in pairs(totems[slot]) do
485 updateTotemFrame(frames[i], slot);
490 local function createTMW(name, config, parent)
491 local frame = CreateFrame("Frame", name, parent);
492 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
493 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
494 frame.unit = config.unit;
495 frame.spec = config.spec;
498 for _, v in pairs(config.auras) do
499 frame.auras[v] = true;
502 frame.auraFilter = config.auraFilter;
503 frame.totems = config.totems;
504 frame.invert = config.invert;
506 frame.base = frame:CreateTexture(nil, "BACKGROUND");
507 frame.base:SetAllPoints();
508 frame.base:SetColorTexture(0, 0, 0, 0.6);
509 frame.icon = frame:CreateTexture(nil, "ARTWORK");
510 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
511 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
512 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
513 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
514 frame.stack:SetFont(STANDARD_TEXT_FONT, 26, "OUTLINE");
515 frame.stack:SetPoint("TOPLEFT");
517 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
518 frame.cd:SetReverse(true);
519 frame.cd:SetAllPoints();
523 local function initialize()
524 Indicators:SetFrameStrata("LOW");
525 Indicators:SetPoint("BOTTOMLEFT");
526 Indicators:SetWidth(1);
527 Indicators:SetHeight(1);
528 currentSpec = GetSpecialization();
529 local name, realm = UnitFullName("player");
530 if chars[realm] and chars[realm][name] then
531 for _, config in pairs(chars[realm][name]) do
532 table.insert(settings, config)
535 for i, config in pairs(settings) do
537 if not units[config.unit] then units[config.unit] = {} end
538 table.insert(units[config.unit], i);
540 if config.totems then
541 for _, slot in pairs(config.totems) do
542 if not totems[slot] then totems[slot] = {} end
543 table.insert(totems[slot], i);
546 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
549 for _, frame in pairs(frames) do
550 if frame.auras then updateAuraFrame(frame) end
552 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
557 Indicators:RegisterEvent("UNIT_AURA");
558 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
559 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
560 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
561 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
562 Indicators:RegisterEvent("PLAYER_LOGIN");
563 Indicators:SetScript("OnEvent", function(self, event, arg1)
564 if event == "UNIT_AURA" then
566 elseif event == "PLAYER_TARGET_CHANGED" then
567 updateAuras("target");
568 elseif event == "PLAYER_TOTEM_UPDATE" then
570 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
571 for _, boss in pairs(bosses) do
574 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
575 currentSpec = GetSpecialization();
576 for _, frame in pairs(frames) do
577 if frame.auras then updateAuraFrame(frame) end
579 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
582 elseif event == "PLAYER_LOGIN" then