2 local pairs, ipairs = pairs, ipairs;
3 local floor = math.floor;
4 local GetTime = GetTime;
5 local UnitExists = UnitExists;
6 local UnitAura = UnitAura;
7 local CreateFrame = CreateFrame;
8 local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected;
9 local CTimerAfter = C_Timer.After;
11 local Settings = OmaRFSettings;
12 local majorAuras = Settings.MajorAuras;
14 local watchedAuras = {};
23 function M.SetupIndicators(frame, class)
24 frame.indBase = CreateFrame("Frame", nil, frame);
25 frame.indBase:SetAllPoints();
27 if M.Class[class] then
28 watchedAuras = M.Class[class].Auras;
29 frame.inds = M.Class[class].Setup(frame.indBase);
34 frame.majorBase = CreateFrame("Frame", nil, frame);
35 frame.majorBase:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -10);
36 frame.majorBase:SetPoint("BOTTOMRIGHT");
39 local tex = frame.majorBase:CreateTexture(nil, "OVERLAY");
40 tex = frame.majorBase:CreateTexture(nil, "OVERLAY");
41 if i == 1 then tex:SetPoint("TOPLEFT", frame.majorBase, "TOPLEFT");
42 else tex:SetPoint("TOPLEFT", frame.majors[i-1], "TOPRIGHT"); end
46 tex.text = frame.majorBase:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
47 tex.text:SetPoint("CENTER", tex, "BOTTOMRIGHT", -2, 2);
49 tex.stack = frame.majorBase:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
50 tex.stack:SetPoint("CENTER", tex, "TOPLEFT", 1, 0);
53 frame.majors[i] = tex;
56 frame.throttle = function()
57 frame.throttled = nil;
58 if UnitExists(frame.displayed) then
59 return updateAuras(frame, frame.displayed);
64 local function remaining(text, expires, current)
69 local remain = expires - current;
73 text:SetText(floor(remain+0.5));
78 local function updateIndicators(frame)
79 local unit = frame.displayed;
80 if not frame:IsShown() or not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) then
81 updating[frame] = nil;
85 local needUpdate = false;
86 local current = GetTime();
87 for _, ind in pairs(frame.inds) do
88 if ind.text and ind.text.expires ~= nil then
89 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
92 for _, ind in pairs(frame.majors) do
93 if ind.text and ind.text.expires ~= nil then
94 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
98 CTimerAfter(0.20, updaters[frame]);
100 updating[frame] = nil;
104 local function showInd(ind, expires, current, count, icon)
105 local needUpdate = false;
107 ind:SetTexture(icon);
110 needUpdate = remaining(ind.text, expires, current);
111 ind.text.expires = expires;
114 if ind.stack and count > 1 then
115 ind.stack:SetText(count);
122 local function hideInd(ind)
124 ind.text.expires = nil;
127 if ind.stack then ind.stack:Hide() end
131 function M.UpdateAuras(frame, unit)
132 local current = GetTime();
133 if frame.throttled then
135 elseif frame.prevUpdate and current - frame.prevUpdate < 0.2 then
136 frame.throttled = true;
137 return CTimerAfter(0.2, frame.throttle);
140 frame.prevUpdate = current;
141 for _, ind in pairs(frame.inds) do
144 local icon, count, expires, id;
145 local showInds, needUpdate = false, false;
148 _, _, icon, count, _, _, expires, _, _, _, id = UnitAura(unit, i, "PLAYER HELPFUL");
149 if not id then break end
150 local pos = watchedAuras[id];
152 needUpdate = showInd(frame.inds[pos], expires, current, count, icon) or needUpdate;
159 frame.indBase:Show();
160 if needUpdate and not updating[frame] then
161 updating[frame] = true; -- race?
162 -- create a function for updating the indicator
163 local func = updaters[frame];
165 func = function() updateIndicators(frame) end;
166 updaters[frame] = func;
168 CTimerAfter(0.20, func);
171 frame.indBase:Hide();
174 updateAuras = M.UpdateAuras;
176 function M.UpdateMajorAuras(frame, unit)
177 for _, ind in pairs(frame.majors) do
180 local icon, count, expires, id;
181 local showMajors, needUpdate = false, false;
183 local alert = false; -- color the whole bar
184 local current = GetTime();
187 _, _, icon, count, _, _, expires, _, _, _, id = UnitAura(unit, i, "HARMFUL");
188 if not id or majorPos > 3 then break end
189 local major = majorAuras[id];
191 needUpdate = showInd(frame.majors[majorPos], expires, current, count, icon) or needUpdate;
192 if major.bar then alert = true end
194 majorPos = majorPos + 1;
200 frame.majorBase:Show();
201 if needUpdate and not updating[frame] then
202 updating[frame] = true; -- race?
203 -- create a function for updating the indicator
204 local func = updaters[frame];
206 func = function() updateIndicators(frame) end;
207 updaters[frame] = func;
209 CTimerAfter(0.20, func);
212 frame.majorBase:Hide();