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",
206 -- unit = unitID where to check auras, not required for totem checkers
207 -- spec = player spec index to show frame, if nil show always
208 -- auras = list of auras to track, in priority order
209 -- auraFilter = filter for UnitAura
210 -- totems = list of totem slots to track, in priority order, only checked if auras is nil
211 -- x = x position relative to UIParent bottom left
212 -- y = y position relative to UIParent bottom left
216 -- global frames' settings
220 auras = {"Innervate", "Gift of the Titans"},
221 auraFilter = "HELPFUL",
230 "Delusions", "Entropic Blast", "Necrotic Embrace", "Flametouched", "Shadowtouched",
231 "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul",
232 "Time Bomb", "Broken Shard", "Demolished", "Fetid Rot", "Roiling Deceit",
233 "Putrid Blood", "Endemic Virus", "Lingering Infection", "Gigavolt Charge",
234 "Crackling Lightning", "Storm's Wail", "Death's Door", "Deathly Withering",
235 "Chilling Touch", "Volatile Charge", "Liquid Gold", "Drained Soul", "Evoke Anguish",
236 "Ancient Curse", "Corrosion", "Debilitating Spit", "Tasty Morsel", "Encroaching Shadows"
238 auraFilter = "HARMFUL",
247 local units = {}; -- mapping from unitID to frames
248 local totems = {}; -- mapping to frames with totems
250 for i = 1, MAX_BOSS_FRAMES do
251 bosses[i] = "boss"..i;
253 local currentSpec = 0; -- 0 is invalid
255 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
257 local function updateAuraFrame(frame)
258 local unit = frame.unit;
259 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
260 local name, icon, count, duration, expires;
261 local auraFilter = frame.auraFilter;
264 name, icon, count, _, duration, expires = UnitAura(unit, i, auraFilter);
265 if not name then break end
266 -- possible improvement to add spellID as an option
267 if frame.auras[name] and not frame.invert then
269 frame.stack:SetText(count);
275 frame.cd:SetCooldown(expires - duration, duration);
280 frame.icon:SetTexture(icon);
283 elseif frame.auras[name] and frame.invert then
284 frame.icon:SetTexture(icon);
291 frame:Show(); -- not functional without first hiding once to get SetTexture
298 local function updateAuras(unit)
300 for _, i in pairs(units[unit]) do
301 updateAuraFrame(frames[i]);
306 local function updateTotemFrame(frame, slot)
307 local _, name, start, duration, icon = GetTotemInfo(slot);
309 frame.cd:SetCooldown(start, duration);
311 frame.icon:SetTexture(icon);
318 local function updateTotems(slot)
320 for _, i in pairs(totems[slot]) do
321 updateTotemFrame(frames[i], slot);
326 local function createTMW(name, config, parent)
327 local frame = CreateFrame("Frame", name, parent);
328 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
329 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
330 frame.unit = config.unit;
331 frame.spec = config.spec;
334 for _, v in pairs(config.auras) do
335 frame.auras[v] = true;
338 frame.auraFilter = config.auraFilter;
339 frame.totems = config.totems;
340 frame.invert = config.invert;
342 frame.base = frame:CreateTexture(nil, "BACKGROUND");
343 frame.base:SetAllPoints();
344 frame.base:SetColorTexture(0, 0, 0, 0.6);
345 frame.icon = frame:CreateTexture(nil, "ARTWORK");
346 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
347 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
348 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
349 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
350 frame.stack:SetPoint("TOPLEFT");
352 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
353 frame.cd:SetReverse(true);
354 frame.cd:SetAllPoints();
358 local function initialize()
359 Indicators:SetFrameStrata("LOW");
360 Indicators:SetPoint("BOTTOMLEFT");
361 Indicators:SetWidth(1);
362 Indicators:SetHeight(1);
363 currentSpec = GetSpecialization();
364 local name, realm = UnitFullName("player");
365 if chars[realm] and chars[realm][name] then
366 for _, config in pairs(chars[realm][name]) do
367 table.insert(settings, config)
370 for i, config in pairs(settings) do
372 if not units[config.unit] then units[config.unit] = {} end
373 table.insert(units[config.unit], i);
375 if config.totems then
376 for _, slot in pairs(config.totems) do
377 if not totems[slot] then totems[slot] = {} end
378 table.insert(totems[slot], i);
381 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
384 for _, frame in pairs(frames) do
385 if frame.auras then updateAuraFrame(frame) end
387 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
392 Indicators:RegisterEvent("UNIT_AURA");
393 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
394 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
395 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
396 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
397 Indicators:RegisterEvent("PLAYER_LOGIN");
398 Indicators:SetScript("OnEvent", function(self, event, arg1)
399 if event == "UNIT_AURA" then
401 elseif event == "PLAYER_TARGET_CHANGED" then
402 updateAuras("target");
403 elseif event == "PLAYER_TOTEM_UPDATE" then
405 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
406 for _, boss in pairs(bosses) do
409 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
410 currentSpec = GetSpecialization();
411 for _, frame in pairs(frames) do
412 if frame.auras then updateAuraFrame(frame) end
414 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
417 elseif event == "PLAYER_LOGIN" then