1 local media = LibStub:GetLibrary("LibSharedMedia-3.0");
2 local f = RaidFrameCustomization.frames;
3 local positions = RaidFrameCustomization.positions;
7 TOPRIGHT = {-pad, -pad},
9 BOTTOMLEFT = {pad, pad},
10 BOTTOMRIGHT = {-pad, pad}
12 local watchedAuras; -- all watched auras
13 local indicatorAuras; -- watched auras per indicator
14 local auraFilters = {"HELPFUL", "HARMFUL"};
15 local DEFAULT_ICON = "Interface\\AddOns\\RaidFrameCustomization\\images\\rhomb";
18 -- global functions used every update
19 local GetTime = GetTime;
20 local UnitAura = UnitAura;
21 local UnitIsUnit = UnitIsUnit;
22 local UnitIsConnected = UnitIsConnected;
23 local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
24 local CompactRaidFrameContainer_ApplyToFrames = CompactRaidFrameContainer_ApplyToFrames;
26 -- list of important auras TODO try to use spellIDs
31 local function dPrint(s)
32 DEFAULT_CHAT_FRAME:AddMessage("Indicators: ".. tostring(s));
35 local function configureIndicators(frame)
36 local frameName = frame:GetName();
37 if not f[frameName] then return end
39 local config = RaidFrameCustomization.db.profile;
40 local font = media and media:Fetch('font', config.indicatorFont) or STANDARD_TEXT_FONT;
41 for pos, ind in pairs(f[frameName]) do
42 ind.text:SetFont(font, config[pos]["textSize"]);
43 ind.text:SetTextColor(unpack(config[pos]["color"]));
44 ind.icon:SetWidth(config[pos]["iconSize"]);
45 ind.icon:SetHeight(config[pos]["iconSize"]);
46 ind.icon:SetTexture(DEFAULT_ICON);
47 if config[pos]["showIcon"] then
55 -- Create the FontStrings used for indicators
56 local function setupCompactUnitFrame(frame)
57 local name = frame:GetName();
59 for _, pos in ipairs(positions) do
61 f[name][pos].text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
62 f[name][pos].text:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
63 f[name][pos].icon = frame:CreateTexture(nil, "OVERLAY");
64 f[name][pos].icon:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
66 configureIndicators(frame);
69 -- Get all unit auras TODO change to event driven, only remaining updating with timer
70 local function getAuras(unit)
72 local auraName, icon, count, expires, caster, debuffType, spellId;
75 for _, filter in ipairs(auraFilters) do
78 auraName, _, icon, count, debuffType, _, expires, caster, _, _, spellId = UnitAura(unit, i, filter);
79 if not spellId then break end
80 if watchedAuras[auraName] or watchedAuras[spellId] or watchedAuras[debuffType] then
82 aura.auraName = auraName;
83 aura.spellId = spellId;
85 aura.expires = expires;
86 aura.mine = UnitIsUnit(caster, "player");
88 aura.debuffType = debuffType;
89 table.insert(unitAuras, aura);
97 -- Check the indicators on a frame and update the times on them
98 local function updateIndicators(frame)
99 if not frame.unit then return end
100 local unit = frame.unit;
101 local frameName = frame:GetName();
103 -- Check if the indicator object exists, else create it
104 if not f[frameName] then setupCompactUnitFrame(frame) end
105 -- Hide if unit is dead/disconnected
106 if (not UnitIsConnected(unit)) or UnitIsDeadOrGhost(frame.displayedUnit) then
107 for _, ind in pairs(f[frameName]) do
108 ind.text:SetText("");
109 ind.icon:SetTexture("");
114 local unitAuras = getAuras(unit);
115 for pos, ind in pairs(f[frameName]) do
116 -- try to find matching aura
118 for _, aura in pairs(unitAuras) do
119 if indicatorAuras[pos][aura.auraName] or indicatorAuras[pos][aura.spellId] or
120 indicatorAuras[pos][aura.debuffType] then
122 -- break on first matching buff/debuff cast by me
123 -- otherwise continue through
124 if aura.mine then break end
128 local config = RaidFrameCustomization.db.profile[pos];
130 if config.mine and not found.mine then
132 ind.icon:SetTexture("");
133 ind.text:SetText("");
135 if config.showIcon and not config.useDefaultIcon then
136 -- show icon TODO coloring
137 ind.icon:SetTexture(found.icon);
139 -- TODO make show text into general setting
140 -- under which you can select what text to show
141 if config.showText then
144 local remaining = found.expires - GetTime();
145 if remaining > 60 then
146 text = string.format("%dm", ceil(remaining/60));
148 text = string.format("%d", floor(remaining+0.5));
151 if config.stack and found.count > 0 then
153 text = found.count.."-"..text;
159 ind.text:SetText(text);
163 -- not found, show nothing
164 ind.icon:SetTexture("");
165 ind.text:SetText("");
170 -- Update all indicators
171 function RaidFrameCustomization:UpdateAllIndicators()
172 CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", updateIndicators);
175 -- Used to update everything that is affected by the configuration
176 function RaidFrameCustomization:RefreshConfig()
177 self:OnDisable(); -- clear everything
178 if self.db.profile.enabled then
179 CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", configureIndicators);
180 -- Format aura strings
183 for _, pos in ipairs(positions) do
184 indicatorAuras[pos] = {};
185 for _, aura in ipairs(self.db.profile[pos]["auras"]) do
186 watchedAuras[aura] = true;
187 indicatorAuras[pos][aura] = true;
191 if next(watchedAuras) ~= nil then
192 self.updateTimer = self:ScheduleRepeatingTimer("UpdateAllIndicators", 0.15);