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;
13 local watchedAuras = {};
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;
55 frame.throttle = function()
56 frame.throttled = nil;
57 updateAuras(frame, frame.displayed);
61 local function remaining(text, expires, current)
66 local remain = expires - current;
70 text:SetText(floor(remain+0.5));
75 local function updateIndicators(frame)
76 local unit = frame.displayed;
77 if not frame:IsShown() or not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) then
78 updating[frame] = nil;
82 local needUpdate = false;
83 local current = GetTime();
84 for _, ind in pairs(frame.inds) do
85 if ind.text and ind.text.expires ~= nil then
86 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
89 for _, ind in pairs(frame.majors) do
90 if ind.text and ind.text.expires ~= nil then
91 needUpdate = remaining(ind.text, ind.text.expires, current) or needUpdate;
95 CTimerAfter(0.20, updaters[frame]);
97 updating[frame] = nil;
101 local function showInd(ind, expires, current, count, icon)
102 local needUpdate = false;
104 ind:SetTexture(icon);
107 needUpdate = remaining(ind.text, expires, current);
108 ind.text.expires = expires;
111 if ind.stack and count > 1 then
112 ind.stack:SetText(count);
119 local function hideInd(ind)
121 ind.text.expires = nil;
124 if ind.stack then ind.stack:Hide() end
128 function M.UpdateAuras(frame, unit)
129 local current = GetTime();
130 if frame.throttled then
131 print("updateAuras throttled for ", unit); -- TODO debug print
133 elseif frame.prevUpdate - current < 0.1 then
134 frame.throttled = true;
135 return CTimerAfter(0.1, frame.throttle);
138 for _, ind in pairs(frame.inds) do
141 local icon, count, expires, id;
142 local showInds, needUpdate = false, false;
145 _, _, icon, count, _, _, expires, _, _, _, id = UnitAura(unit, i, "PLAYER HELPFUL");
146 if not id then break end
147 local pos = watchedAuras[id];
149 needUpdate = showInd(frame.inds[pos], expires, current, count, icon) or needUpdate;
156 frame.indBase: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.20, func);
168 frame.indBase:Hide();
171 updateAuras = M.UpdateAuras;
173 function M.UpdateMajorAuras(frame, unit)
174 for _, ind in pairs(frame.majors) do
177 local icon, count, expires, id;
178 local showMajors, needUpdate = false, false;
180 local alert = false; -- color the whole bar
181 local current = GetTime();
184 _, _, icon, count, _, _, expires, _, _, _, id = UnitAura(unit, i, "HARMFUL");
185 if not id or majorPos > 3 then break end
186 local major = majorAuras[id];
188 needUpdate = showInd(frame.majors[majorPos], expires, current, count, icon) or needUpdate;
189 if major.bar then alert = true end
191 majorPos = majorPos + 1;
197 frame.majorBase:Show();
198 if needUpdate and not updating[frame] then
199 updating[frame] = true; -- race?
200 -- create a function for updating the indicator
201 local func = updaters[frame];
203 func = function() updateIndicators(frame) end;
204 updaters[frame] = func;
206 CTimerAfter(0.20, func);
209 frame.majorBase:Hide();