2 local pairs, ipairs = pairs, ipairs;
3 local floor = math.floor;
4 local GetTime = GetTime;
5 local UnitAura = UnitAura;
6 local CreateFrame = CreateFrame;
7 local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected;
8 local CTimerAfter = C_Timer.After;
10 local Settings = OmaRFSettings;
11 local majorAuras = Settings.MajorAuras;
12 local watchedAuras = {};
16 local auraFilters = {"HELPFUL", "HARMFUL"};
22 function M.SetupIndicators(frame, class)
23 frame.indBase = CreateFrame("Frame", nil, frame);
24 frame.indBase:SetAllPoints();
26 if M.Class[class] then
27 watchedAuras = M.Class[class].Auras;
28 frame.inds = M.Class[class].Setup(frame.indBase);
33 frame.majorBase = CreateFrame("Frame", nil, frame);
34 frame.majorBase:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -10);
35 frame.majorBase:SetPoint("BOTTOMRIGHT");
38 local tex = frame.majorBase:CreateTexture(nil, "OVERLAY");
39 tex = frame.majorBase:CreateTexture(nil, "OVERLAY");
40 if i == 1 then tex:SetPoint("TOPLEFT", frame.majorBase, "TOPLEFT");
41 else tex:SetPoint("TOPLEFT", frame.majors[i-1], "TOPRIGHT"); end
45 tex.text = frame.majorBase:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
46 tex.text:SetPoint("CENTER", tex, "BOTTOMRIGHT", -2, 2);
48 tex.stack = frame.majorBase:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
49 tex.stack:SetPoint("CENTER", tex, "TOPLEFT", 1, 0);
52 frame.majors[i] = tex;
56 local function remaining(text, expires, current)
61 local remain = expires - current;
65 text:SetText(floor(remain+0.5));
70 local function updateIndicators(frame)
71 local unit = frame.displayed;
72 if not frame:IsShown() or not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) then
73 updating[frame] = nil;
77 local needUpdate = false;
78 local current = GetTime();
79 for _, ind in pairs(frame.inds) do
80 if ind.text and ind.text.expires ~= nil then
81 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
84 for _, ind in pairs(frame.majors) do
85 if ind.text and ind.text.expires ~= nil then
86 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
90 CTimerAfter(0.16, updaters[frame]);
92 updating[frame] = nil;
96 local function showInd(ind, expires, current, count, icon)
97 local needUpdate = false;
102 needUpdate = remaining(ind.text, expires, current);
103 ind.text.expires = expires;
106 if ind.stack and count > 1 then
107 ind.stack:SetText(count);
114 local function hideInd(ind)
116 ind.text.expires = nil;
119 if ind.stack then ind.stack:Hide() end
123 function M.CheckIndicators(frame, unit)
124 for _, ind in pairs(frame.inds) do
127 for _, ind in pairs(frame.majors) do
130 local name, icon, count, expires, caster, id;
131 local showInds, showMajors, needUpdate = false, false, false;
133 local alert = false; -- color the whole bar
134 local current = GetTime();
135 for _, filter in ipairs(auraFilters) do
138 name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
139 if not id then break end
140 local pos = watchedAuras[id] or watchedAuras[name];
141 if pos and caster == "player" then
142 needUpdate = showInd(frame.inds[pos], expires, current, count, icon) or needUpdate;
145 local major = majorAuras[id] or majorAuras[name];
146 if major and majorPos <= 3 then
147 needUpdate = showInd(frame.majors[majorPos], expires, current, count, icon) or needUpdate;
148 if major.bar then alert = true end
150 majorPos = majorPos + 1;
155 if showInds or showMajors then
156 frame.indBase:Show();
157 frame.majorBase:Show();
158 if needUpdate and not updating[frame] then
159 updating[frame] = true; -- race?
160 -- create a function for updating the indicator
161 local func = updaters[frame];
163 func = function() updateIndicators(frame) end;
164 updaters[frame] = func;
166 CTimerAfter(0.16, func);
169 frame.indBase:Hide();
170 frame.majorBase:Hide();