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",
196 auraFilter = "HARMFUL",
205 local units = {}; -- mapping from unitID to frames
206 local totems = {}; -- mapping to frames with totems
208 for i = 1, MAX_BOSS_FRAMES do
209 bosses[i] = "boss"..i;
211 local currentSpec = 0; -- 0 is invalid
213 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
215 local function updateAuraFrame(frame)
216 local unit = frame.unit;
217 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
218 local name, icon, count, duration, expires;
219 local auraFilter = frame.auraFilter;
222 name, icon, count, _, duration, expires = UnitAura(unit, i, auraFilter);
223 if not name then break end
224 -- possible improvement to add spellID as an option
225 if frame.auras[name] then
227 frame.stack:SetText(count);
233 frame.cd:SetCooldown(expires - duration, duration);
238 frame.icon:SetTexture(icon);
248 local function updateAuras(unit)
250 for _, i in pairs(units[unit]) do
251 updateAuraFrame(frames[i]);
256 local function updateTotemFrame(frame, slot)
257 local _, name, start, duration, icon = GetTotemInfo(slot);
259 frame.cd:SetCooldown(start, duration);
261 frame.icon:SetTexture(icon);
268 local function updateTotems(slot)
270 for _, i in pairs(totems[slot]) do
271 updateTotemFrame(frames[i], slot);
276 local function createTMW(name, config, parent)
277 local frame = CreateFrame("Frame", name, parent);
278 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
279 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
280 frame.unit = config.unit;
281 frame.spec = config.spec;
284 for _, v in pairs(config.auras) do
285 frame.auras[v] = true;
288 frame.auraFilter = config.auraFilter;
289 frame.totems = config.totems;
291 frame.base = frame:CreateTexture(nil, "BACKGROUND");
292 frame.base:SetAllPoints();
293 frame.base:SetColorTexture(0, 0, 0, 0.6);
294 frame.icon = frame:CreateTexture(nil, "ARTWORK");
295 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
296 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
297 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
298 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
299 frame.stack:SetPoint("TOPLEFT");
301 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
302 frame.cd:SetReverse(true);
303 frame.cd:SetAllPoints();
307 local function initialize()
308 Indicators:SetFrameStrata("LOW");
309 Indicators:SetPoint("BOTTOMLEFT");
310 Indicators:SetWidth(1);
311 Indicators:SetHeight(1);
312 currentSpec = GetSpecialization();
313 local name, realm = UnitFullName("player");
314 if chars[realm] and chars[realm][name] then
315 for _, config in pairs(chars[realm][name]) do
316 table.insert(settings, config)
319 for i, config in pairs(settings) do
321 if not units[config.unit] then units[config.unit] = {} end
322 table.insert(units[config.unit], i);
324 if config.totems then
325 for _, slot in pairs(config.totems) do
326 if not totems[slot] then totems[slot] = {} end
327 table.insert(totems[slot], i);
330 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
333 for _, frame in pairs(frames) do
334 if frame.auras then updateAuraFrame(frame) end
336 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
341 Indicators:RegisterEvent("UNIT_AURA");
342 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
343 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
344 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
345 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
346 Indicators:RegisterEvent("PLAYER_LOGIN");
347 Indicators:SetScript("OnEvent", function(self, event, arg1)
348 if event == "UNIT_AURA" then
350 elseif event == "PLAYER_TARGET_CHANGED" then
351 updateAuras("target");
352 elseif event == "PLAYER_TOTEM_UPDATE" then
354 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
355 for _, boss in pairs(bosses) do
358 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
359 currentSpec = GetSpecialization();
360 for _, frame in pairs(frames) do
361 if frame.auras then updateAuraFrame(frame) end
363 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
366 elseif event == "PLAYER_LOGIN" then