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"},
138 auraFilter = "PLAYER HARMFUL",
146 auras = {"Power Word: Fortitude"},
147 auraFilter = "PLAYER HELPFUL",
157 totems = {1}, -- Efflorescence
167 auras = {"Tidal Waves"},
168 auraFilter = "PLAYER HELPFUL",
176 auras = {"Healing Rain"},
177 auraFilter = "PLAYER HELPFUL",
185 auras = {"Unleash Life"},
186 auraFilter = "PLAYER HELPFUL",
197 -- unit = unitID where to check auras, not required for totem checkers
198 -- spec = player spec index to show frame, if nil show always
199 -- auras = list of auras to track, in priority order
200 -- auraFilter = filter for UnitAura
201 -- totems = list of totem slots to track, in priority order, only checked if auras is nil
202 -- x = x position relative to UIParent bottom left
203 -- y = y position relative to UIParent bottom left
207 -- global frames' settings
211 auras = {"Innervate"},
212 auraFilter = "HELPFUL",
221 "Delusions", "Entropic Blast", "Necrotic Embrace", "Flametouched", "Shadowtouched",
222 "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul",
223 "Time Bomb", "Broken Shard", "Demolished", "Fetid Rot", "Roiling Deceit",
224 "Putrid Blood", "Endemic Virus", "Lingering Infection", "Gigavolt Charge",
225 "Crackling Lightning", "Storm's Wail", "Death's Door", "Deathly Withering",
226 "Chilling Touch", "Volatile Charge", "Liquid Gold", "Drained Soul"
228 auraFilter = "HARMFUL",
237 local units = {}; -- mapping from unitID to frames
238 local totems = {}; -- mapping to frames with totems
240 for i = 1, MAX_BOSS_FRAMES do
241 bosses[i] = "boss"..i;
243 local currentSpec = 0; -- 0 is invalid
245 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
247 local function updateAuraFrame(frame)
248 local unit = frame.unit;
249 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
250 local name, icon, count, duration, expires;
251 local auraFilter = frame.auraFilter;
254 name, icon, count, _, duration, expires = UnitAura(unit, i, auraFilter);
255 if not name then break end
256 -- possible improvement to add spellID as an option
257 if frame.auras[name] and not frame.invert then
259 frame.stack:SetText(count);
265 frame.cd:SetCooldown(expires - duration, duration);
270 frame.icon:SetTexture(icon);
273 elseif frame.auras[name] and frame.invert then
274 frame.icon:SetTexture(icon);
281 frame:Show(); -- not functional without first hiding once to get SetTexture
288 local function updateAuras(unit)
290 for _, i in pairs(units[unit]) do
291 updateAuraFrame(frames[i]);
296 local function updateTotemFrame(frame, slot)
297 local _, name, start, duration, icon = GetTotemInfo(slot);
299 frame.cd:SetCooldown(start, duration);
301 frame.icon:SetTexture(icon);
308 local function updateTotems(slot)
310 for _, i in pairs(totems[slot]) do
311 updateTotemFrame(frames[i], slot);
316 local function createTMW(name, config, parent)
317 local frame = CreateFrame("Frame", name, parent);
318 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
319 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
320 frame.unit = config.unit;
321 frame.spec = config.spec;
324 for _, v in pairs(config.auras) do
325 frame.auras[v] = true;
328 frame.auraFilter = config.auraFilter;
329 frame.totems = config.totems;
330 frame.invert = config.invert;
332 frame.base = frame:CreateTexture(nil, "BACKGROUND");
333 frame.base:SetAllPoints();
334 frame.base:SetColorTexture(0, 0, 0, 0.6);
335 frame.icon = frame:CreateTexture(nil, "ARTWORK");
336 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
337 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
338 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
339 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
340 frame.stack:SetPoint("TOPLEFT");
342 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
343 frame.cd:SetReverse(true);
344 frame.cd:SetAllPoints();
348 local function initialize()
349 Indicators:SetFrameStrata("LOW");
350 Indicators:SetPoint("BOTTOMLEFT");
351 Indicators:SetWidth(1);
352 Indicators:SetHeight(1);
353 currentSpec = GetSpecialization();
354 local name, realm = UnitFullName("player");
355 if chars[realm] and chars[realm][name] then
356 for _, config in pairs(chars[realm][name]) do
357 table.insert(settings, config)
360 for i, config in pairs(settings) do
362 if not units[config.unit] then units[config.unit] = {} end
363 table.insert(units[config.unit], i);
365 if config.totems then
366 for _, slot in pairs(config.totems) do
367 if not totems[slot] then totems[slot] = {} end
368 table.insert(totems[slot], i);
371 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
374 for _, frame in pairs(frames) do
375 if frame.auras then updateAuraFrame(frame) end
377 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
382 Indicators:RegisterEvent("UNIT_AURA");
383 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
384 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
385 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
386 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
387 Indicators:RegisterEvent("PLAYER_LOGIN");
388 Indicators:SetScript("OnEvent", function(self, event, arg1)
389 if event == "UNIT_AURA" then
391 elseif event == "PLAYER_TARGET_CHANGED" then
392 updateAuras("target");
393 elseif event == "PLAYER_TOTEM_UPDATE" then
395 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
396 for _, boss in pairs(bosses) do
399 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
400 currentSpec = GetSpecialization();
401 for _, frame in pairs(frames) do
402 if frame.auras then updateAuraFrame(frame) end
404 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
407 elseif event == "PLAYER_LOGIN" then