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",
195 auraFilter = "HARMFUL",
204 local units = {}; -- mapping from unitID to frames
205 local totems = {}; -- mapping to frames with totems
207 for i = 1, MAX_BOSS_FRAMES do
208 bosses[i] = "boss"..i;
210 local currentSpec = 0; -- 0 is invalid
212 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
214 local function updateAuraFrame(frame)
215 local unit = frame.unit;
216 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
217 local name, icon, count, duration, expires;
218 local auraFilter = frame.auraFilter;
221 name, icon, count, _, duration, expires = UnitAura(unit, i, auraFilter);
222 if not name then break end
223 -- possible improvement to add spellID as an option
224 if frame.auras[name] then
226 frame.stack:SetText(count);
232 frame.cd:SetCooldown(expires - duration, duration);
237 frame.icon:SetTexture(icon);
247 local function updateAuras(unit)
249 for _, i in pairs(units[unit]) do
250 updateAuraFrame(frames[i]);
255 local function updateTotemFrame(frame, slot)
256 local _, name, start, duration, icon = GetTotemInfo(slot);
258 frame.cd:SetCooldown(start, duration);
260 frame.icon:SetTexture(icon);
267 local function updateTotems(slot)
269 for _, i in pairs(totems[slot]) do
270 updateTotemFrame(frames[i], slot);
275 local function createTMW(name, config, parent)
276 local frame = CreateFrame("Frame", name, parent);
277 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
278 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
279 frame.unit = config.unit;
280 frame.spec = config.spec;
283 for _, v in pairs(config.auras) do
284 frame.auras[v] = true;
287 frame.auraFilter = config.auraFilter;
288 frame.totems = config.totems;
290 frame.base = frame:CreateTexture(nil, "BACKGROUND");
291 frame.base:SetAllPoints();
292 frame.base:SetColorTexture(0, 0, 0, 0.6);
293 frame.icon = frame:CreateTexture(nil, "ARTWORK");
294 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
295 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
296 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
297 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
298 frame.stack:SetPoint("TOPLEFT");
300 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
301 frame.cd:SetReverse(true);
302 frame.cd:SetAllPoints();
306 local function initialize()
307 Indicators:SetFrameStrata("LOW");
308 Indicators:SetPoint("BOTTOMLEFT");
309 Indicators:SetWidth(1);
310 Indicators:SetHeight(1);
311 currentSpec = GetSpecialization();
312 local name, realm = UnitFullName("player");
313 if chars[realm] and chars[realm][name] then
314 for _, config in pairs(chars[realm][name]) do
315 table.insert(settings, config)
318 for i, config in pairs(settings) do
320 if not units[config.unit] then units[config.unit] = {} end
321 table.insert(units[config.unit], i);
323 if config.totems then
324 for _, slot in pairs(config.totems) do
325 if not totems[slot] then totems[slot] = {} end
326 table.insert(totems[slot], i);
329 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
332 for _, frame in pairs(frames) do
333 if frame.auras then updateAuraFrame(frame) end
335 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
340 Indicators:RegisterEvent("UNIT_AURA");
341 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
342 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
343 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
344 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
345 Indicators:RegisterEvent("PLAYER_LOGIN");
346 Indicators:SetScript("OnEvent", function(self, event, arg1)
347 if event == "UNIT_AURA" then
349 elseif event == "PLAYER_TARGET_CHANGED" then
350 updateAuras("target");
351 elseif event == "PLAYER_TOTEM_UPDATE" then
353 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
354 for _, boss in pairs(bosses) do
357 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
358 currentSpec = GetSpecialization();
359 for _, frame in pairs(frames) do
360 if frame.auras then updateAuraFrame(frame) end
362 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
365 elseif event == "PLAYER_LOGIN" then