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",
136 totems = {1}, -- Efflorescence
146 auras = {"Tidal Waves"},
147 auraFilter = "PLAYER HELPFUL",
155 auras = {"Healing Rain"},
156 auraFilter = "PLAYER HELPFUL",
167 -- unit = unitID where to check auras, not required for totem checkers
168 -- spec = player spec index to show frame, if nil show always
169 -- auras = list of auras to track, in priority order
170 -- auraFilter = filter for UnitAura
171 -- totems = list of totem slots to track, in priority order, only checked if auras is nil
172 -- x = x position relative to UIParent bottom left
173 -- y = y position relative to UIParent bottom left
177 -- global frames' settings
181 auras = {"Innervate"},
182 auraFilter = "HELPFUL",
191 "Delusions", "Entropic Blast", "Necrotic Embrace", "Flametouched", "Shadowtouched",
192 "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul",
193 "Time Bomb", "Broken Shard", "Demolished", "Fetid Rot", "Roiling Deceit",
194 "Putrid Blood", "Endemic Virus", "Lingering Infection", "Gigavolt Charge",
195 "Crackling Lightning", "Storm's Wail", "Death's Door", "Deathly Withering",
196 "Chilling Touch", "Volatile Charge", "Liquid Gold", "Drained Soul"
198 auraFilter = "HARMFUL",
207 local units = {}; -- mapping from unitID to frames
208 local totems = {}; -- mapping to frames with totems
210 for i = 1, MAX_BOSS_FRAMES do
211 bosses[i] = "boss"..i;
213 local currentSpec = 0; -- 0 is invalid
215 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
217 local function updateAuraFrame(frame)
218 local unit = frame.unit;
219 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
220 local name, icon, count, duration, expires;
221 local auraFilter = frame.auraFilter;
224 name, icon, count, _, duration, expires = UnitAura(unit, i, auraFilter);
225 if not name then break end
226 -- possible improvement to add spellID as an option
227 if frame.auras[name] then
229 frame.stack:SetText(count);
235 frame.cd:SetCooldown(expires - duration, duration);
240 frame.icon:SetTexture(icon);
250 local function updateAuras(unit)
252 for _, i in pairs(units[unit]) do
253 updateAuraFrame(frames[i]);
258 local function updateTotemFrame(frame, slot)
259 local _, name, start, duration, icon = GetTotemInfo(slot);
261 frame.cd:SetCooldown(start, duration);
263 frame.icon:SetTexture(icon);
270 local function updateTotems(slot)
272 for _, i in pairs(totems[slot]) do
273 updateTotemFrame(frames[i], slot);
278 local function createTMW(name, config, parent)
279 local frame = CreateFrame("Frame", name, parent);
280 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
281 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
282 frame.unit = config.unit;
283 frame.spec = config.spec;
286 for _, v in pairs(config.auras) do
287 frame.auras[v] = true;
290 frame.auraFilter = config.auraFilter;
291 frame.totems = config.totems;
293 frame.base = frame:CreateTexture(nil, "BACKGROUND");
294 frame.base:SetAllPoints();
295 frame.base:SetColorTexture(0, 0, 0, 0.6);
296 frame.icon = frame:CreateTexture(nil, "ARTWORK");
297 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
298 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
299 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
300 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
301 frame.stack:SetPoint("TOPLEFT");
303 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
304 frame.cd:SetReverse(true);
305 frame.cd:SetAllPoints();
309 local function initialize()
310 Indicators:SetFrameStrata("LOW");
311 Indicators:SetPoint("BOTTOMLEFT");
312 Indicators:SetWidth(1);
313 Indicators:SetHeight(1);
314 currentSpec = GetSpecialization();
315 local name, realm = UnitFullName("player");
316 if chars[realm] and chars[realm][name] then
317 for _, config in pairs(chars[realm][name]) do
318 table.insert(settings, config)
321 for i, config in pairs(settings) do
323 if not units[config.unit] then units[config.unit] = {} end
324 table.insert(units[config.unit], i);
326 if config.totems then
327 for _, slot in pairs(config.totems) do
328 if not totems[slot] then totems[slot] = {} end
329 table.insert(totems[slot], i);
332 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
335 for _, frame in pairs(frames) do
336 if frame.auras then updateAuraFrame(frame) end
338 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
343 Indicators:RegisterEvent("UNIT_AURA");
344 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
345 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
346 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
347 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
348 Indicators:RegisterEvent("PLAYER_LOGIN");
349 Indicators:SetScript("OnEvent", function(self, event, arg1)
350 if event == "UNIT_AURA" then
352 elseif event == "PLAYER_TARGET_CHANGED" then
353 updateAuras("target");
354 elseif event == "PLAYER_TOTEM_UPDATE" then
356 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
357 for _, boss in pairs(bosses) do
360 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
361 currentSpec = GetSpecialization();
362 for _, frame in pairs(frames) do
363 if frame.auras then updateAuraFrame(frame) end
365 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
368 elseif event == "PLAYER_LOGIN" then