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 indSize = Settings.IndSize;
12 local positions = nil;
13 local watchedAuras = nil;
17 local auraFilters = {"HELPFUL", "HARMFUL"};
22 function M.SetupIndicators(frame)
23 if not watchedAuras then
24 watchedAuras = Settings.Character["WatchedAuras"];
25 positions = Settings.Character.Positions;
28 frame.inds = CreateFrame("Frame", nil, frame);
29 frame.inds:SetAllPoints();
31 for _, pos in pairs(positions) do
32 frame.inds[pos] = frame.inds:CreateTexture(nil, "OVERLAY");
33 frame.inds[pos]:SetPoint(pos, frame.inds, pos);
34 frame.inds[pos]:SetWidth(indSize);
35 frame.inds[pos]:SetHeight(indSize);
36 frame.inds[pos]:SetTexture("Interface\\AddOns\\OmaRF\\images\\rhomb");
37 frame.inds[pos]:SetVertexColor(1, 0, 0);
38 frame.inds[pos]:Hide();
39 frame.inds[pos].text = frame.inds:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
40 frame.inds[pos].text:SetPoint("BOTTOMRIGHT", frame.inds[pos], "BOTTOMRIGHT");
41 frame.inds[pos].text:Hide();
43 frame.major = CreateFrame("Frame", nil, frame);
44 frame.major:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -indSize + 4);
45 frame.major:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT");
47 frame.major[i] = frame.major:CreateTexture(nil, "OVERLAY");
49 frame.major[i]:SetPoint("TOPLEFT", frame.major, "TOPLEFT");
51 frame.major[i]:SetPoint("TOPLEFT", frame.major[i-1], "TOPRIGHT");
53 frame.major[i]:SetWidth(indSize*2);
54 frame.major[i]:SetHeight(indSize*2);
55 frame.major[i]:Hide();
56 frame.major[i].text = frame.major:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
57 frame.major[i].text:SetPoint("BOTTOMRIGHT", frame.major[i], "BOTTOMRIGHT");
58 frame.major[i].text:Hide();
59 frame.major[i].stack = frame.major:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
60 frame.major[i].stack:SetPoint("TOPLEFT", frame.major[i], "TOPLEFT");
61 frame.major[i].stack:Hide();
65 local function remaining(text, expires, current)
70 local remain = expires - current;
74 text:SetText(floor(remain+0.5));
79 local function updateIndicators(frame, unit)
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 _, pos in pairs(positions) do
88 local ind = frame.inds[pos];
89 if ind.expires ~= nil then
90 needUpdate = remaining(ind.text, ind.expires, current) or needUpdate;
94 local ind = frame.major[i];
95 if ind.expires ~= nil then
96 needUpdate = remaining(ind.text, ind.expires, current) or needUpdate;
100 CTimerAfter(0.16, updaters[frame]);
102 updating[frame] = nil;
106 function M.CheckIndicators(frame, unit)
107 for _, pos in pairs(positions) do
108 frame.inds[pos].expires = nil;
109 frame.inds[pos]:Hide();
110 frame.inds[pos].text:Hide();
113 frame.major[i].expires = nil;
114 frame.major[i]:Hide();
115 frame.major[i].text:Hide();
116 frame.major[i].stack:Hide();
118 local name, icon, count, expires, caster, id;
119 local showInds, showMajors, needUpdate = false, false, false;
121 local alert = false; -- color the whole bar
122 local current = GetTime();
123 for _, filter in ipairs(auraFilters) do
126 name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
127 if not id then break end
128 local pos = watchedAuras[id] or watchedAuras[name];
129 if pos and caster == "player" then
130 needUpdate = remaining(frame.inds[pos].text, expires, current);
131 frame.inds[pos].expires = expires;
132 frame.inds[pos]:Show();
133 frame.inds[pos].text:Show();
136 local major = majorAuras[id] or majorAuras[name];
137 if major and majorPos <= 3 then
138 needUpdate = remaining(frame.major[majorPos].text, expires, current);
139 frame.major[majorPos].expires = expires;
140 frame.major[majorPos]:SetTexture(icon);
141 frame.major[majorPos]:Show();
142 frame.major[majorPos].text:Show();
144 frame.major[majorPos].stack:SetText(count);
145 frame.major[majorPos].stack:Show();
151 majorPos = majorPos + 1;
156 if showInds or showMajors then
159 if needUpdate and not updating[frame] then
160 updating[frame] = true; -- race?
161 -- create a function for updating the indicator
162 local func = updaters[frame];
164 func = function() updateIndicators(frame, unit) end;
165 updaters[frame] = func;
167 CTimerAfter(0.16, func);