c33600a - Reorganise hook scripts to single function/file
[wowui.git] / RaidFrameIndicators.lua
index 782e5bd..8bb26ef 100644 (file)
@@ -1,29 +1,28 @@
--- ----------------------------------------------------------------------------
--- Raid Frame Indicators by Szandos, schyrio
--- ----------------------------------------------------------------------------
-Indicators = LibStub( "AceAddon-3.0" ):NewAddon( "Indicators", "AceTimer-3.0");
+Indicators = LibStub("AceAddon-3.0"):NewAddon( "Indicators", "AceTimer-3.0");
 local media = LibStub:GetLibrary("LibSharedMedia-3.0");
 local f = {}; -- Indicator objects
 local pad = 2;
 local _;
 local watchedAuras; -- all watched auras
 local indicatorAuras; -- watched auras per indicator
+local auraFilters = {"HELPFUL", "HARMFUL"};
 local DEFAULT_ICON = "Interface\\AddOns\\RaidFrameCustomization\\images\\rhomb";
 
--- Hide buff/debuff icons
-local function hideBlizzardBuffs(frame)
-    -- used in CompactUnitFrame_UpdateAuras (Buffs, Debuffs, DispellableDebuffs)
-    if frame.optionTable.displayBuffs then
-        frame.optionTable.displayBuffs = false
-        -- used in CompactUnitFrame_UpdateHealthColor, might not be set prior
-        frame.optionTable.healthBarColorOverride = CreateColor(0.4, 0.4, 0.4);
-    end
-    if frame.optionTable.displayDebuffs then frame.optionTable.displayDebuffs = false end
-    -- TODO
-    if frame.optionTable.displayDispelDebuffs then frame.optionTable.displayDispelDebuffs = true end
+-- global functions used every update
+local GetTime = GetTime;
+local UnitAura = UnitAura;
+local UnitIsUnit = UnitIsUnit;
+local UnitIsConnected = UnitIsConnected;
+local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
+
+-- list of important auras TODO try to use spellIDs
+local centerAuras = {
+    "Power Word: Shield"
+};
 
+local function dPrint(s)
+    DEFAULT_CHAT_FRAME:AddMessage("Indicators: ".. tostring(s));
 end
-hooksecurefunc("CompactUnitFrame_SetOptionTable", hideBlizzardBuffs);
 
 -- Set the appearance of the FontStrings
 local function setupIndicatorAppearance(frame)
@@ -31,15 +30,15 @@ local function setupIndicatorAppearance(frame)
     if not f[frameName] then return end
     local font = media and media:Fetch('font', Indicators.db.profile.indicatorFont) or STANDARD_TEXT_FONT;
 
-    local i;
-    for i = 1, 5 do
-        f[frameName][i].text:SetFont(font, Indicators.db.profile["textSize"..i], "");
-        f[frameName][i].icon:SetWidth(Indicators.db.profile["iconSize"..i]);
-        f[frameName][i].icon:SetHeight(Indicators.db.profile["iconSize"..i]);
+    local i, ind;
+    for i, ind in ipairs(f[frameName]) do
+        ind.text:SetFont(font, Indicators.db.profile["textSize"..i], "");
+        ind.icon:SetWidth(Indicators.db.profile["iconSize"..i]);
+        ind.icon:SetHeight(Indicators.db.profile["iconSize"..i]);
         if Indicators.db.profile["showIcon"..i] then
-            f[frameName][i].icon:Show();
+            ind.icon:Show();
         else
-            f[frameName][i].icon:Hide();
+            ind.icon:Hide();
         end
     end
 end
@@ -69,48 +68,32 @@ end
 
 -- Get all unit auras
 local function getAuras(unit)
-    local unitBuffs = {};
-    local unitDebuffs = {};
+    local unitAuras = {};
     local auraName, icon, count, expires, caster, debuffType, spellId;
-    local i = 1;
-
-    -- Get all unit buffs
-    while true do
-        auraName, _, icon, count, _, _, expires, caster, _, _, spellId = UnitBuff(unit, i);
-        if not spellId then break end
-        if watchedAuras[auraName] or watchedAuras[spellId] then
-            -- possibly non-contiguous indexes, doesn't matter
-            unitBuffs[i] = {};
-            unitBuffs[i].auraName = auraName;
-            unitBuffs[i].spellId = spellId;
-            unitBuffs[i].count = count;
-            unitBuffs[i].expires = expires;
-            unitBuffs[i].mine = UnitIsUnit(caster, "player");
-            unitBuffs[i].icon = icon;
-        end
-        i = i + 1;
-    end
-
-    -- Get all unit debuffs
-    i = 1;
-    while true do
-        auraName, _, icon, count, debuffType, _, expires, caster, _, _, spellId  = UnitDebuff(unit, i);
-        if not spellId then break end
-        -- TODO debuffType check better
-        if watchedAuras[auraName] or watchedAuras[spellId] or watchedAuras[debuffType] then
-            unitDebuffs[i] = {};
-            unitDebuffs[i].auraName = auraName;
-            unitDebuffs[i].spellId = spellId;
-            unitDebuffs[i].count = count;
-            unitDebuffs[i].expires = expires;
-            unitDebuffs[i].mine = UnitIsUnit(caster, "player");
-            unitDebuffs[i].icon = icon;
-            unitDebuffs[i].debuffType = debuffType;
+    local filter;
+
+    -- Get all unit auras
+
+    for _, filter in ipairs(auraFilters) do
+        local i = 1;
+        while true do
+            auraName, _, icon, count, debuffType, _, expires, caster, _, _, spellId = UnitAura(unit, i, filter);
+            if not spellId then break end
+            if watchedAuras[auraName] or watchedAuras[spellId] or watchedAuras[debuffType] then
+                local aura = {};
+                aura.auraName = auraName;
+                aura.spellId = spellId;
+                aura.count = count;
+                aura.expires = expires;
+                aura.mine = UnitIsUnit(caster, "player");
+                aura.icon = icon;
+                aura.debuffType = debuffType;
+                table.insert(unitAuras, aura);
+            end
+            i = i + 1;
         end
-        i = i + 1;
     end
-
-    return unitBuffs, unitDebuffs;
+    return unitAuras;
 end
 
 -- Check the indicators on a frame and update the times on them
@@ -118,57 +101,45 @@ local function updateIndicator(frame)
     if not frame.unit then return end
     local unit = frame.unit;
     local frameName = frame:GetName();
-    local currentTime = GetTime();
-    local i;
+    local i, ind;
 
     -- Check if the indicator object exists, else create it
     if not f[frameName] then setupCompactUnitFrame(frame) end
     -- Hide if unit is dead/disconnected
     if (not UnitIsConnected(unit)) or UnitIsDeadOrGhost(frame.displayedUnit) then
-        for i = 1, 5 do
-            f[frameName][i].text:SetText("");
-            f[frameName][i].icon:SetTexture("");
+        for _, ind in pairs(f[frameName]) do
+            ind.text:SetText("");
+            ind.icon:SetTexture("");
         end
         return;
     end
 
-    local unitBuffs, unitDebuffs = getAuras(unit);
-    for i = 1, 5 do
+    local unitAuras = getAuras(unit);
+    for i, ind in ipairs(f[frameName]) do
         -- try to find matching aura
         local found, aura;
-        for _, aura in pairs(unitBuffs) do
-            if indicatorAuras[i][aura.auraName] or indicatorAuras[i][aura.spellId] then
+        for _, aura in pairs(unitAuras) do
+            if indicatorAuras[i][aura.auraName] or indicatorAuras[i][aura.spellId] or
+               indicatorAuras[i][aura.debuffType] then
                 found = aura;
-                -- break on first matching buff cast by me
+                -- break on first matching buff/debuff cast by me
                 -- otherwise continue through
                 if aura.mine then break end
             end
         end
-        if not found then
-            -- search debuffs if buff was not found
-            for _, aura in pairs(unitDebuffs) do
-                if indicatorAuras[i][aura.auraName] or indicatorAuras[i][aura.spellId] or
-                   indicatorAuras[i][aura.debuffType] then
-                    found = aura;
-                    -- break on first matching debuff cast by me
-                    -- otherwise continue through
-                    if aura.mine then break end
-                end
-            end
-        end
 
         if found then
             if Indicators.db.profile["mine"..i] and not found.mine then
                 -- don't show
-                f[frameName][i].icon:SetTexture("");
-                f[frameName][i].text:SetText("");
+                ind.icon:SetTexture("");
+                ind.text:SetText("");
             else
                 if Indicators.db.profile["showIcon"..i] then
                     -- show icon TODO coloring
                     if Indicators.db.profile["useDefaultIcon"..i] then
-                        f[frameName][i].icon:SetTexture(DEFAULT_ICON);
+                        ind.icon:SetTexture(DEFAULT_ICON);
                     else
-                        f[frameName][i].icon:SetTexture(found.icon);
+                        ind.icon:SetTexture(found.icon);
                     end
                 end
                 -- TODO make show text into general setting
@@ -176,7 +147,7 @@ local function updateIndicator(frame)
                 if Indicators.db.profile["showText"..i] then
                     -- show text
                     local text;
-                    local remaining = found.expires - currentTime;
+                    local remaining = found.expires - GetTime();
                     if remaining > 60 then
                         text = string.format("%dm", ceil(remaining/60));
                     else
@@ -192,7 +163,7 @@ local function updateIndicator(frame)
                     end
 
                     -- colors
-                    f[frameName][i].text:SetTextColor(
+                    ind.text:SetTextColor(
                         Indicators.db.profile["color"..i].r,
                         Indicators.db.profile["color"..i].g,
                         Indicators.db.profile["color"..i].b,
@@ -201,24 +172,24 @@ local function updateIndicator(frame)
                     if Indicators.db.profile["debuffColor"..i] then
                         if found.debuffType then
                             if found.debuffType == "Curse" then
-                                f[frameName][i].text:SetTextColor(0.6,0,1,1);
+                                ind.text:SetTextColor(0.6,0,1,1);
                             elseif found.debuffType == "Disease" then
-                                f[frameName][i].text:SetTextColor(0.6,0.4,0,1);
+                                ind.text:SetTextColor(0.6,0.4,0,1);
                             elseif found.debuffType == "Magic" then
-                                f[frameName][i].text:SetTextColor(0.2,0.6,1,1);
+                                ind.text:SetTextColor(0.2,0.6,1,1);
                             elseif found.debuffType == "Poison" then
-                                f[frameName][i].text:SetTextColor(0,0.6,0,1);
+                                ind.text:SetTextColor(0,0.6,0,1);
                             end
                         end
                     end
 
-                    f[frameName][i].text:SetText(text);
+                    ind.text:SetText(text);
                 end
             end
         else
             -- not found, show nothing
-            f[frameName][i].icon:SetTexture("");
-            f[frameName][i].text:SetText("");
+            ind.icon:SetTexture("");
+            ind.text:SetText("");
         end
     end
 end
@@ -230,13 +201,11 @@ end
 
 -- Used to update everything that is affected by the configuration
 function Indicators:RefreshConfig()
-    local i;
     CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", setupIndicatorAppearance);
-
     -- Format aura strings
     watchedAuras = {};
     indicatorAuras = {};
-    local auraName, i
+    local auraName, i;
     for i = 1, 5 do
         indicatorAuras[i] = {};
         for auraName in string.gmatch(Indicators.db.profile["auras"..i], "[^\n]+") do -- Grab each line
@@ -253,15 +222,12 @@ function Indicators:RefreshConfig()
 
     self:CancelAllTimers();
     if next(watchedAuras) ~= nil then
-        self.updateTimer = self:ScheduleRepeatingTimer("UpdateAllIndicators", 0.11);
+        self.updateTimer = self:ScheduleRepeatingTimer("UpdateAllIndicators", 0.15);
     end
 end
 
 function Indicators:OnInitialize()
-    -- Set up config pane
     self:SetupOptions();
-
-    -- Register callbacks for profile switching
     self.db.RegisterCallback(self, "OnProfileChanged", "RefreshConfig");
     self.db.RegisterCallback(self, "OnProfileCopied", "RefreshConfig");
     self.db.RegisterCallback(self, "OnProfileReset", "RefreshConfig");
@@ -274,18 +240,12 @@ function Indicators:OnEnable()
 end
 
 function Indicators:OnDisable()
-    local i;
-    -- Stop update
+    local frame, ind;
     self:CancelAllTimers();
-    -- Hide all indicators
-    for frameName, _ in pairs(f) do
-        for i = 1, 5 do
-            f[frameName][i].text:SetText("");
-            f[frameName][i].icon:SetTexture("");
+    for _, frame in pairs(f) do
+        for _, ind in pairs(frame) do
+            ind.text:SetText("");
+            ind.icon:SetTexture("");
         end
     end
 end
-
-function dPrint(s)
-    DEFAULT_CHAT_FRAME:AddMessage("Indicators: ".. tostring(s));
-end