fbf981791768ecc90b649b9b02b91aa843ea5f1e
[wowui.git] / OmaRF / Indicators.lua
1 -- Indicators.lua
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;
8
9 local Settings = OmaRFSettings;
10 local positions = Settings.Positions;
11 local watchedAuras = Settings.Character["WatchedAuras"];
12 local majorAuras = Settings.MajorAuras;
13
14 local updaters = {};
15 local updating = {};
16 local auraFilters = {"HELPFUL", "HARMFUL"};
17
18 local M = {};
19 OmaRFIndicators = M;
20
21 local function remaining(text, expires, current)
22     if expires == 0 then
23         text:SetText("");
24         return false;
25     end
26     local remain = expires - current;
27     if remain > 8 then
28         text:SetText("");
29     else
30         text:SetText(floor(remain+0.5));
31     end
32     return true;
33 end
34
35 local function updateIndicators(frame, unit)
36     if not frame:IsShown() or not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) then
37         updating[frame] = nil;
38         return;
39     end
40
41     local needUpdate = false;
42     local current = GetTime();
43     for _, pos in pairs(positions) do
44         local ind = frame.inds[pos];
45         if ind.expires ~= nil then
46             needUpdate = remaining(ind.text, ind.expires, current) or needUpdate;
47         end
48     end
49     for i = 1,3 do
50         local ind = frame.major[i];
51         if ind.expires ~= nil then
52             needUpdate = remaining(ind.text, ind.expires, current) or needUpdate;
53         end
54     end
55     if needUpdate then
56         CTimerAfter(0.16, updaters[frame]);
57     else
58         updating[frame] = nil;
59     end
60 end
61
62 function M.CheckIndicators(frame, unit)
63     for _, pos in pairs(positions) do
64         frame.inds[pos].expires = nil;
65         frame.inds[pos]:Hide();
66         frame.inds[pos].text:Hide();
67     end
68     for i = 1,3 do
69         frame.major[i].expires = nil;
70         frame.major[i]:Hide();
71         frame.major[i].text:Hide();
72         frame.major[i].stack:Hide();
73     end
74     local name, icon, count, expires, caster, id;
75     local showInds, showMajors, needUpdate = false, false, false;
76     local majorPos = 1;
77     local current = GetTime();
78     for _, filter in ipairs(auraFilters) do
79         local i = 1;
80         while true do
81             name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
82             if not id then break end
83             local pos = watchedAuras[id] or watchedAuras[name];
84             if pos and caster == "player" then
85                 needUpdate = remaining(frame.inds[pos].text, expires, current);
86                 frame.inds[pos].expires = expires;
87                 frame.inds[pos]:Show();
88                 frame.inds[pos].text:Show();
89                 showInds = true;
90             end
91             if (majorAuras[id] or majorAuras[name]) and majorPos <= 3 then
92                 needUpdate = remaining(frame.major[majorPos].text, expires, current);
93                 frame.major[majorPos].expires = expires;
94                 frame.major[majorPos]:SetTexture(icon);
95                 frame.major[majorPos]:Show();
96                 frame.major[majorPos].text:Show();
97                 if count > 1 then
98                     frame.major[majorPos].stack:SetText(count);
99                     frame.major[majorPos].stack:Show();
100                 end
101                 showMajors = true;
102                 majorPos = majorPos + 1;
103             end
104             i = i + 1;
105         end
106     end
107     if showInds or showMajors then
108         frame.inds:Show();
109         frame.major:Show();
110         if needUpdate and not updating[frame] then
111             updating[frame] = true; -- race?
112             -- create a function for updating the indicator
113             local func = updaters[frame];
114             if not func then
115                 func = function() updateIndicators(frame, unit) end;
116                 updaters[frame] = func;
117             end
118             CTimerAfter(0.16, func);
119         end
120     else
121         frame.inds:Hide();
122         frame.major:Hide();
123     end
124 end