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 spec = 3, -- Retribution
98 auraFilter = "PLAYER HARMFUL",
99 x = 570, -- placed over Innervate frame
106 spec = 3, -- Retribution
107 auras = {"Divine Purpose"},
108 auraFilter = "PLAYER HELPFUL",
116 spec = 2, -- Protection
117 auras = {"Shield of the Righteous"},
118 auraFilter = "PLAYER HELPFUL",
126 auras = {"Divine Shield"},
127 auraFilter = "PLAYER HELPFUL",
137 auras = {"Shadow Word: Pain", "Purge the Wicked"},
138 auraFilter = "PLAYER HARMFUL",
146 auras = {"Power Word: Fortitude"},
147 auraFilter = "HELPFUL",
156 auras = {"Overcharge Mana"},
157 auraFilter = "PLAYER HELPFUL",
166 totems = {1}, -- Efflorescence
176 auras = {"Tidal Waves"},
177 auraFilter = "PLAYER HELPFUL",
185 auras = {"Healing Rain"},
186 auraFilter = "PLAYER HELPFUL",
194 auras = {"Unleash Life"},
195 auraFilter = "PLAYER HELPFUL",
205 auras = {"Tidal Waves"},
206 auraFilter = "PLAYER HELPFUL",
214 auras = {"Healing Rain"},
215 auraFilter = "PLAYER HELPFUL",
223 auras = {"Unleash Life"},
224 auraFilter = "PLAYER HELPFUL",
235 auraFilter = "HELPFUL",
246 -- unit = unitID where to check auras, not required for totem checkers
247 -- spec = player spec index to show frame, if nil show always
248 -- auras = list of auras to track, in priority order
249 -- auraFilter = filter for UnitAura
250 -- totems = list of totem slots to track, in priority order, only checked if auras is nil
251 -- x = x position relative to UIParent bottom left
252 -- y = y position relative to UIParent bottom left
256 -- global frames' settings
260 auras = {"Innervate", "Gift of the Titans"},
261 auraFilter = "HELPFUL",
269 auras = {"Ineffable Truth"},
270 auraFilter = "HELPFUL",
279 "Delusions", "Entropic Blast", "Necrotic Embrace", "Flametouched", "Shadowtouched",
280 "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul",
281 "Time Bomb", "Broken Shard", "Demolished", "Fetid Rot", "Roiling Deceit",
282 "Putrid Blood", "Endemic Virus", "Lingering Infection", "Gigavolt Charge",
283 "Crackling Lightning", "Storm's Wail", "Death's Door", "Deathly Withering",
284 "Chilling Touch", "Volatile Charge", "Liquid Gold", "Drained Soul", "Evoke Anguish",
285 "Ancient Curse", "Corrosion", "Debilitating Spit", "Tasty Morsel", "Encroaching Shadows",
286 "Corrupted Existence", "Madness Bomb"
288 auraFilter = "HARMFUL",
299 auraFilter = "HARMFUL",
308 local units = {}; -- mapping from unitID to frames
309 local totems = {}; -- mapping to frames with totems
311 for i = 1, MAX_BOSS_FRAMES do
312 bosses[i] = "boss"..i;
314 local currentSpec = 0; -- 0 is invalid
316 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
318 local function updateAuraFrame(frame)
319 local unit = frame.unit;
320 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
321 local name, icon, count, duration, expires;
322 local auraFilter = frame.auraFilter;
325 name, icon, count, _, duration, expires = UnitAura(unit, i, auraFilter);
326 if not name then break end
327 -- possible improvement to add spellID as an option
328 if frame.auras[name] and not frame.invert then
330 frame.stack:SetText(count);
336 frame.cd:SetCooldown(expires - duration, duration);
341 frame.icon:SetTexture(icon);
344 elseif frame.auras[name] and frame.invert then
345 frame.icon:SetTexture(icon);
352 frame:Show(); -- not functional without first hiding once to get SetTexture
359 local function updateAuras(unit)
361 for _, i in pairs(units[unit]) do
362 updateAuraFrame(frames[i]);
367 local function updateTotemFrame(frame, slot)
368 local _, name, start, duration, icon = GetTotemInfo(slot);
370 frame.cd:SetCooldown(start, duration);
372 frame.icon:SetTexture(icon);
379 local function updateTotems(slot)
381 for _, i in pairs(totems[slot]) do
382 updateTotemFrame(frames[i], slot);
387 local function createTMW(name, config, parent)
388 local frame = CreateFrame("Frame", name, parent);
389 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
390 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
391 frame.unit = config.unit;
392 frame.spec = config.spec;
395 for _, v in pairs(config.auras) do
396 frame.auras[v] = true;
399 frame.auraFilter = config.auraFilter;
400 frame.totems = config.totems;
401 frame.invert = config.invert;
403 frame.base = frame:CreateTexture(nil, "BACKGROUND");
404 frame.base:SetAllPoints();
405 frame.base:SetColorTexture(0, 0, 0, 0.6);
406 frame.icon = frame:CreateTexture(nil, "ARTWORK");
407 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
408 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
409 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
410 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
411 frame.stack:SetPoint("TOPLEFT");
413 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
414 frame.cd:SetReverse(true);
415 frame.cd:SetAllPoints();
419 local function initialize()
420 Indicators:SetFrameStrata("LOW");
421 Indicators:SetPoint("BOTTOMLEFT");
422 Indicators:SetWidth(1);
423 Indicators:SetHeight(1);
424 currentSpec = GetSpecialization();
425 local name, realm = UnitFullName("player");
426 if chars[realm] and chars[realm][name] then
427 for _, config in pairs(chars[realm][name]) do
428 table.insert(settings, config)
431 for i, config in pairs(settings) do
433 if not units[config.unit] then units[config.unit] = {} end
434 table.insert(units[config.unit], i);
436 if config.totems then
437 for _, slot in pairs(config.totems) do
438 if not totems[slot] then totems[slot] = {} end
439 table.insert(totems[slot], i);
442 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
445 for _, frame in pairs(frames) do
446 if frame.auras then updateAuraFrame(frame) end
448 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
453 Indicators:RegisterEvent("UNIT_AURA");
454 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
455 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
456 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
457 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
458 Indicators:RegisterEvent("PLAYER_LOGIN");
459 Indicators:SetScript("OnEvent", function(self, event, arg1)
460 if event == "UNIT_AURA" then
462 elseif event == "PLAYER_TARGET_CHANGED" then
463 updateAuras("target");
464 elseif event == "PLAYER_TOTEM_UPDATE" then
466 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
467 for _, boss in pairs(bosses) do
470 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
471 currentSpec = GetSpecialization();
472 for _, frame in pairs(frames) do
473 if frame.auras then updateAuraFrame(frame) end
475 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
478 elseif event == "PLAYER_LOGIN" then