4 local GetSpecialization = GetSpecialization;
5 local UnitExists = UnitExists;
6 local UnitAura = UnitAura;
7 local GetTotemInfo = GetTotemInfo;
9 -- character specific frames
15 spec = 3, -- Retribution
17 auraFilter = "PLAYER HARMFUL",
18 x = 570, -- placed over Innervate frame
25 spec = 3, -- Retribution
26 auras = {"Divine Purpose"},
27 auraFilter = "PLAYER HELPFUL",
35 spec = 2, -- Protection
36 auras = {"Shield of the Righteous"},
37 auraFilter = "PLAYER HELPFUL",
45 auras = {"Divine Shield"},
46 auraFilter = "PLAYER HELPFUL",
55 totems = {1}, -- Efflorescence
65 auras = {"Tidal Waves"},
66 auraFilter = "PLAYER HELPFUL",
74 auras = {"Healing Rain"},
75 auraFilter = "PLAYER HELPFUL",
86 -- unit = unitID where to check auras, not required for totem checkers
87 -- spec = player spec index to show frame, if nil show always
88 -- auras = list of auras to track, in priority order
89 -- iterateAuras = iterate over UnitAura() instead of auras list
90 -- auraFilter = filter for UnitAura
91 -- totems = list of totem slots to track, in priority order, only checked if auras is nil
92 -- x = x position relative to UIParent bottom left
93 -- y = y position relative to UIParent bottom left
97 -- global frames' settings
101 auras = {"Innervate"},
102 auraFilter = "HELPFUL",
111 "Delusions", "Entropic Blast", "Necrotic Embrace", "Flametouched", "Shadowtouched",
112 "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul",
113 "Time Bomb", "Broken Shard", "Demolished", "Fetid Rot",
115 iterateAuras = true, -- typically fewer debuffs on player than this list
116 auraFilter = "HARMFUL",
125 local units = {}; -- mapping from unitID to frames
126 local totems = {}; -- mapping to frames with totems
128 for i = 1, MAX_BOSS_FRAMES do
129 bosses[i] = "boss"..i;
131 local currentSpec = 0; -- 0 is invalid
133 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
135 local function updateAuraFrame(frame)
136 local unit = frame.unit;
137 if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
138 local name, icon, count, duration, expires;
139 local auraFilter = frame.auraFilter;
140 if frame.iterateAuras then
143 name, _, icon, count, _, duration, expires = UnitAura(unit, i, auraFilter);
144 if not name then break end
145 -- possible improvement to add spellID as an option
146 if frame.auras[name] then
148 frame.stack:SetText(count);
154 frame.cd:SetCooldown(expires - duration, duration);
159 frame.icon:SetTexture(icon);
166 for _, aura in pairs(frame.auras) do
167 name, _, icon, count, _, duration, expires = UnitAura(unit, aura, nil, auraFilter);
170 frame.stack:SetText(count);
176 frame.cd:SetCooldown(expires - duration, duration);
181 frame.icon:SetTexture(icon);
191 local function updateAuras(unit)
193 for _, i in pairs(units[unit]) do
194 updateAuraFrame(frames[i]);
199 local function updateTotemFrame(frame, slot)
200 local _, name, start, duration, icon = GetTotemInfo(slot);
202 frame.cd:SetCooldown(start, duration);
204 frame.icon:SetTexture(icon);
211 local function updateTotems(slot)
213 for _, i in pairs(totems[slot]) do
214 updateTotemFrame(frames[i], slot);
219 local function createTMW(name, config, parent)
220 local frame = CreateFrame("Frame", name, parent);
221 frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
222 frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
223 frame.unit = config.unit;
224 frame.spec = config.spec;
225 frame.iterateAuras = config.iterateAuras;
226 if frame.iterateAuras then
228 for _, v in pairs(config.auras) do
229 frame.auras[v] = true;
232 frame.auras = config.auras;
234 frame.auraFilter = config.auraFilter;
235 frame.totems = config.totems;
237 frame.base = frame:CreateTexture(nil, "BACKGROUND");
238 frame.base:SetAllPoints();
239 frame.base:SetColorTexture(0, 0, 0, 0.6);
240 frame.icon = frame:CreateTexture(nil, "ARTWORK");
241 frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
242 frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
243 frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
244 frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
245 frame.stack:SetPoint("TOPLEFT");
247 frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
248 frame.cd:SetReverse(true);
249 frame.cd:SetAllPoints();
253 local function initialize()
254 Indicators:SetFrameStrata("LOW");
255 Indicators:SetPoint("BOTTOMLEFT");
256 Indicators:SetWidth(1);
257 Indicators:SetHeight(1);
258 currentSpec = GetSpecialization();
259 local name, realm = UnitFullName("player");
260 if chars[realm] and chars[realm][name] then
261 for _, config in pairs(chars[realm][name]) do
262 table.insert(settings, config)
265 for i, config in pairs(settings) do
267 if not units[config.unit] then units[config.unit] = {} end
268 table.insert(units[config.unit], i);
270 if config.totems then
271 for _, slot in pairs(config.totems) do
272 if not totems[slot] then totems[slot] = {} end
273 table.insert(totems[slot], i);
276 frames[i] = createTMW("OmaTMW"..i, config, Indicators);
279 for _, frame in pairs(frames) do
280 if frame.auras then updateAuraFrame(frame) end
282 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
287 Indicators:RegisterEvent("UNIT_AURA");
288 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
289 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
290 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
291 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
292 Indicators:RegisterEvent("PLAYER_LOGIN");
293 Indicators:SetScript("OnEvent", function(self, event, arg1)
294 if event == "UNIT_AURA" then
296 elseif event == "PLAYER_TARGET_CHANGED" then
297 updateAuras("target");
298 elseif event == "PLAYER_TOTEM_UPDATE" then
300 elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
301 for _, boss in pairs(bosses) do
304 elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
305 currentSpec = GetSpecialization();
306 for _, frame in pairs(frames) do
307 if frame.auras then updateAuraFrame(frame) end
309 for _, slot in pairs(frame.totems) do updateTotemFrame(frame, slot) end
312 elseif event == "PLAYER_LOGIN" then