2 local pairs, ipairs = pairs, ipairs;
3 local floor = math.floor;
4 local GetTime = GetTime;
5 local UnitAura = UnitAura;
6 local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected;
7 local CTimerAfter = C_Timer.After;
9 local Settings = OmaRFSettings;
10 local majorAuras = Settings.MajorAuras;
11 local watchedAuras = {};
15 local auraFilters = {"HELPFUL", "HARMFUL"};
21 function M.SetupIndicators(frame, class)
22 frame.indBase = CreateFrame("Frame", nil, frame);
23 frame.indBase:SetAllPoints();
25 if M.Class[class] then
26 watchedAuras = M.Class[class].Auras;
27 frame.inds = M.Class[class].Setup(frame.indBase);
32 frame.majorBase = CreateFrame("Frame", nil, frame);
33 frame.majorBase:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -10);
34 frame.majorBase:SetPoint("BOTTOMRIGHT");
37 local tex = frame.majorBase:CreateTexture(nil, "OVERLAY");
38 tex = frame.majorBase:CreateTexture(nil, "OVERLAY");
39 if i == 1 then tex:SetPoint("TOPLEFT", frame.majorBase, "TOPLEFT");
40 else tex:SetPoint("TOPLEFT", frame.majors[i-1], "TOPRIGHT"); end
44 tex.text = frame.majorBase:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
45 tex.text:SetPoint("CENTER", tex, "BOTTOMRIGHT", -2, 2);
47 tex.stack = frame.majorBase:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
48 tex.stack:SetPoint("CENTER", tex, "TOPLEFT", 1, 0);
51 frame.majors[i] = tex;
55 local function remaining(text, expires, current)
60 local remain = expires - current;
64 text:SetText(floor(remain+0.5));
69 local function updateIndicators(frame)
70 local unit = frame.displayed;
71 if not frame:IsShown() or not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) then
72 updating[frame] = nil;
76 local needUpdate = false;
77 local current = GetTime();
78 for _, ind in pairs(frame.inds) do
79 if ind.text and ind.text.expires ~= nil then
80 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
83 for _, ind in pairs(frame.majors) do
84 if ind.text and ind.text.expires ~= nil then
85 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
89 CTimerAfter(0.16, updaters[frame]);
91 updating[frame] = nil;
95 local function showInd(ind, expires, current, count, icon)
96 local needUpdate = false;
101 needUpdate = remaining(ind.text, expires, current);
102 ind.text.expires = expires;
105 if ind.stack and count > 1 then
106 ind.stack:SetText(count);
113 local function hideInd(ind)
115 ind.text.expires = nil;
118 if ind.stack then ind.stack:Hide() end
122 function M.CheckIndicators(frame, unit)
123 for _, ind in pairs(frame.inds) do
126 for _, ind in pairs(frame.majors) do
129 local name, icon, count, expires, caster, id;
130 local showInds, showMajors, needUpdate = false, false, false;
132 local alert = false; -- color the whole bar
133 local current = GetTime();
134 for _, filter in ipairs(auraFilters) do
137 name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
138 if not id then break end
139 local pos = watchedAuras[id] or watchedAuras[name];
140 if pos and caster == "player" then
141 needUpdate = showInd(frame.inds[pos], expires, current, count, icon) or needUpdate;
144 local major = majorAuras[id] or majorAuras[name];
145 if major and majorPos <= 3 then
146 needUpdate = showInd(frame.majors[majorPos], expires, current, count, icon) or needUpdate;
147 if major.bar then alert = true end
149 majorPos = majorPos + 1;
154 if showInds or showMajors then
155 frame.indBase:Show();
156 frame.majorBase:Show();
157 if needUpdate and not updating[frame] then
158 updating[frame] = true; -- race?
159 -- create a function for updating the indicator
160 local func = updaters[frame];
162 func = function() updateIndicators(frame) end;
163 updaters[frame] = func;
165 CTimerAfter(0.16, func);
168 frame.indBase:Hide();
169 frame.majorBase:Hide();