1 local f = OmaRF.frames;
2 local majorFrames = OmaRF.majorFrames;
3 local positions = OmaRF.positions;
7 TOPRIGHT = {-pad, -pad},
9 BOTTOMLEFT = {pad, pad},
10 BOTTOMRIGHT = {-pad, pad}
15 local auraFilters = {"HELPFUL", "HARMFUL"};
16 local DEFAULT_ICON = "Interface\\AddOns\\OmaRF\\images\\rhomb";
19 -- global functions used every update
20 local C_TimerAfter = C_Timer.After;
21 local GetTime = GetTime;
22 local UnitAura = UnitAura;
23 local UnitIsPlayer = UnitIsPlayer;
24 local UnitIsConnected = UnitIsConnected;
25 local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
26 local CompactRaidFrameContainer_ApplyToFrames = CompactRaidFrameContainer_ApplyToFrames;
27 local format = string.format;
28 local unpack = unpack;
32 -- update current auras
33 hooksecurefunc("CompactUnitFrame_UpdateAuras", function(frame)
34 local frameName = frame:GetName();
36 for _, ind in pairs(f[frameName]) do ind.expires = nil end
37 for _, ind in ipairs(majorFrames[frameName]) do ind.expires = nil end
39 local name, icon, count, expires, caster, id;
40 local unit = frame.displayedUnit;
42 for _, filter in ipairs(auraFilters) do
45 name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
46 if not id then break end
47 local pos = watchedAuras[id] or watchedAuras[name];
49 local ind = f[frameName][pos];
50 local config = OmaRF.db.profile.indicators[pos];
51 if not config.mine or UnitIsPlayer(caster) then
52 if config.useDefaultIcon then
53 ind.icon:SetTexture(DEFAULT_ICON);
55 ind.icon:SetTexture(icon);
57 ind.expires = expires;
61 if (majorAuras[id] or majorAuras[name]) and majorI <= majorMax then
62 local ind = majorFrames[frameName][majorI];
63 ind.icon:SetTexture(icon);
64 ind.expires = expires;
66 ind.stackText:SetText(count);
76 local function configureIndicators(frame, name)
77 local frameName = name or frame:GetName();
78 if not f[frameName] then return end
80 local config = OmaRF.db.profile.indicators;
81 for pos, ind in pairs(f[frameName]) do
82 ind.text:SetFont(STANDARD_TEXT_FONT, config[pos]["textSize"]);
83 ind.text:SetTextColor(unpack(config[pos]["textColor"]));
84 ind.icon:SetWidth(config[pos]["iconSize"]);
85 ind.icon:SetHeight(config[pos]["iconSize"]);
86 ind.icon:SetTexture(DEFAULT_ICON);
87 ind.icon:SetVertexColor(unpack(config[pos]["iconColor"]));
90 config = OmaRF.db.profile.majorAuras;
91 for i, ind in ipairs(majorFrames[frameName]) do
93 ind.icon:ClearAllPoints();
94 ind.icon:SetPoint("CENTER", frame, "CENTER", -config.iconSize, 0);
96 ind.icon:SetWidth(config.iconSize);
97 ind.icon:SetHeight(config.iconSize);
98 ind.expireText:SetFont(STANDARD_TEXT_FONT, config["textSize"], "OUTLINE");
99 ind.stackText:SetFont(STANDARD_TEXT_FONT, config["textSize"], "OUTLINE");
103 -- Create the FontStrings used for indicators
104 local function setupCompactUnitFrame(frame, name)
106 for _, pos in ipairs(positions) do
108 f[name][pos].text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
109 f[name][pos].text:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
110 f[name][pos].icon = frame:CreateTexture(nil, "OVERLAY");
111 f[name][pos].icon:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
114 local config = OmaRF.db.profile.majorAuras;
115 majorFrames[name] = {};
116 for i = 1, config.max do
117 majorFrames[name][i] = {};
118 majorFrames[name][i].icon = frame:CreateTexture(nil, "OVERLAY");
120 majorFrames[name][i].icon:SetPoint("TOPLEFT", majorFrames[name][i-1].icon, "TOPRIGHT");
122 majorFrames[name][i].expireText = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
123 majorFrames[name][i].expireText:SetPoint("BOTTOMRIGHT", majorFrames[name][i].icon, "BOTTOMRIGHT");
124 majorFrames[name][i].stackText = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
125 majorFrames[name][i].stackText:SetPoint("TOPLEFT", majorFrames[name][i].icon, "TOPLEFT");
128 configureIndicators(frame, name);
131 local function remaining(expires, current)
132 if expires == 0 then return "" end
133 local remain = expires - current;
135 return format("%dm", ceil(remain/60));
137 return floor(remain+0.5);
140 local function hide(frameName)
141 for _, ind in pairs(f[frameName]) do
145 for _, ind in ipairs(majorFrames[frameName]) do
147 ind.expireText:Hide();
148 ind.stackText:Hide();
152 -- Check the indicators on a frame and update the times on them
153 local function updateIndicators(frame)
154 local frameName = frame:GetName();
155 local unit = frame.unit;
156 if not unit then return end -- possible if the frame is just being hidden
158 -- Create indicators if needed, out of combat if forbidden
159 if not f[frameName] then
160 if frame:IsForbidden() then
161 if not OmaRF.ooc_queue[frameName] then
162 OmaRF.ooc_queue[frameName] = {
163 func = setupCompactUnitFrame,
164 args = { frame, frameName }
169 setupCompactUnitFrame(frame, frameName);
174 -- Hide if unit is dead/disconnected
175 if (not UnitIsConnected(unit)) or UnitIsDeadOrGhost(frame.displayedUnit) then
179 local current = GetTime();
180 for pos, ind in pairs(f[frameName]) do
181 if ind.expires ~= nil then
182 local config = OmaRF.db.profile.indicators[pos];
183 if config.showIcon then
186 if config.showText then
187 ind.text:SetText(remaining(ind.expires, current));
192 for _, ind in ipairs(majorFrames[frameName]) do
193 if ind.expires ~= nil then
195 ind.expireText:SetText(remaining(ind.expires, current));
196 ind.expireText:Show();
197 ind.stackText:Show();
202 -- Update all indicators
203 function OmaRF:UpdateAllIndicators()
204 CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", updateIndicators);
205 if OmaRF.running then
206 C_TimerAfter(0.15, OmaRF.UpdateAllIndicators);
210 -- Used to update everything that is affected by the configuration
211 function OmaRF:RefreshConfig()
212 self:OnDisable(); -- clear everything
213 if self.db.profile.enabled then
214 CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", configureIndicators);
216 for _, pos in ipairs(positions) do
217 for _, aura in ipairs(self.db.profile.indicators[pos]["auras"]) do
218 watchedAuras[aura] = pos; -- TODO single aura only in one position
222 for _, aura in ipairs(self.db.profile.majorAuras["auras"]) do
223 majorAuras[aura] = true;
225 majorMax = OmaRF.db.profile.majorAuras["max"];
227 if next(watchedAuras) ~= nil or next(majorAuras) ~= nil then
229 C_TimerAfter(0.15, self.UpdateAllIndicators);