b13d011 - Re-add basic indicators
[wowui.git] / OmaRF / NewIndicators.lua
index 01c1ae9..bcc4260 100644 (file)
@@ -2,7 +2,8 @@
 local unpack, ipairs, pairs, ceil, floor = unpack, ipairs, pairs, ceil, floor;
 local UnitIsConnected, UnitIsDeadOrGhost = UnitIsConnected, UnitIsDeadOrGhost;
 local UnitAura, UnitIsPlayer, GetTime = UnitAura, UnitIsPlayer, GetTime;
 local unpack, ipairs, pairs, ceil, floor = unpack, ipairs, pairs, ceil, floor;
 local UnitIsConnected, UnitIsDeadOrGhost = UnitIsConnected, UnitIsDeadOrGhost;
 local UnitAura, UnitIsPlayer, GetTime = UnitAura, UnitIsPlayer, GetTime;
-local C_TimerAfter = C_Timer.After;
+local UnitName, C_TimerAfter = UnitName, C_Timer.After;
+local IsInGroup, IsInRaid, GetNumGroupMembers = IsInGroup, IsInRaid, GetNumGroupMembers;
 local format = string.format;
 
 local positions = OmaRF.positions;
 local format = string.format;
 
 local positions = OmaRF.positions;
@@ -15,6 +16,8 @@ local frames = {};
 local watchedAuras = {};
 local majorAuras = {};
 local majorMax;
 local watchedAuras = {};
 local majorAuras = {};
 local majorMax;
+local partyState = "solo";
+local partyMembers = {"player", "party1", "party2", "party3", "party4"};
 
 local function remaining(expires, current)
     if expires == 0 then return "" end
 
 local function remaining(expires, current)
     if expires == 0 then return "" end
@@ -57,57 +60,56 @@ local function showMajorIndicator(ind, icon, count, expires, current)
     if not ind.expireText:IsShown() then ind.expireText:Show() end
 end
 
     if not ind.expireText:IsShown() then ind.expireText:Show() end
 end
 
--- update current auras
-hooksecurefunc("CompactUnitFrame_UpdateAuras", function(unitFrame)
-    local frameName = unitFrame:GetName();
-    if frames[frameName] then
-        local frame = frames[frameName];
-        for _, ind in pairs(frame.inds) do ind.expires = nil end
-        for _, ind in ipairs(frame.majorInds) do ind.expires = nil end
+-- update current auras TODO add bar coloring back with extra options
+local function updateAuras(frame, unit)
+    for _, ind in pairs(frame.inds) do ind.expires = nil end
+    for _, ind in ipairs(frame.majorInds) do ind.expires = nil end
 
 
-        local name, icon, count, expires, caster, id;
-        local unit = unitFrame.displayedUnit;
-        local majorPos = 1;
-        local current = GetTime();
-        for _, filter in ipairs(auraFilters) do
-            local i = 1;
-            while true do
-                name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
-                if not id then break end
-                local pos = watchedAuras[id] or watchedAuras[name];
-                if pos then
-                    showIndicator(
-                        frame.inds[pos], icon, caster, expires, current,
-                        OmaRF.db.profile.indicators[pos]
-                    );
-                end
-                if (majorAuras[id] or majorAuras[name]) and majorPos <= majorMax then
-                    showMajorIndicator(frame.majorInds[majorPos], icon, count, expires, current);
-                    majorPos = majorPos + 1;
-                end
-                i = i + 1;
+    local name, icon, count, expires, caster, id;
+    local majorPos = 1;
+    local current = GetTime();
+    for _, filter in ipairs(auraFilters) do
+        local i = 1;
+        while true do
+            name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
+            if not id then break end
+            local pos = watchedAuras[id] or watchedAuras[name];
+            if pos then
+                showIndicator(
+                    frame.inds[pos], icon, caster, expires, current,
+                    OmaRF.db.profile.indicators[pos]
+                );
             end
             end
+            if (majorAuras[id] or majorAuras[name]) and majorPos <= majorMax then
+                showMajorIndicator(frame.majorInds[majorPos], icon, count, expires, current);
+                majorPos = majorPos + 1;
+            end
+            i = i + 1;
         end
     end
         end
     end
-end);
+end
 
 -- Check the indicators on a frame and update the times on them
 
 -- Check the indicators on a frame and update the times on them
-local function updateIndicators(frame, name)
-    local unitFrame = _G[name]; -- has to always reference global
-    if unitFrame == nil then
-        return;
-    elseif not unitFrame:IsVisible() then
+local function updateIndicators(frame, i)
+    local unit = "player";
+    if partyState == "solo" then
         if frame:IsShown() then frame:Hide() end
         return;
         if frame:IsShown() then frame:Hide() end
         return;
+    elseif partyState == "raid" then
+        unit = partyState..i;
+    elseif i ~= 1 then
+        -- party frames have player separate
+        unit = partyState..(i-1);
     end
 
     end
 
-    local unit = unitFrame.unit;
-    local displayedUnit = unitFrame.displayedUnit;
-    if not unit or not UnitIsConnected(unit) or UnitIsDeadOrGhost(displayedUnit) then
+    if not UnitExists(unit) then
+        return;
+    elseif not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) then
         if frame:IsShown() then frame:Hide() end
         return;
         if frame:IsShown() then frame:Hide() end
         return;
+    elseif not frame:IsShown() then
+        frame:Show();
     end
     end
-    if not frame:IsShown() then frame:Show() end
 
     local current = GetTime();
     for pos, ind in pairs(frame.inds) do
 
     local current = GetTime();
     for pos, ind in pairs(frame.inds) do
@@ -185,7 +187,9 @@ end
 
 -- Update all indicators
 local function updateAllIndicators()
 
 -- Update all indicators
 local function updateAllIndicators()
-    for name, frame in pairs(frames) do updateIndicators(frame, name) end
+    for i, frame in ipairs(frames) do
+        updateIndicators(frame, i);
+    end
     if OmaRF.running then C_TimerAfter(0.15, updateAllIndicators) end
 end
 
     if OmaRF.running then C_TimerAfter(0.15, updateAllIndicators) end
 end
 
@@ -207,54 +211,168 @@ function OmaRF:RefreshConfig()
         end
 
         if next(watchedAuras) ~= nil or next(majorAuras) ~= nil then
         end
 
         if next(watchedAuras) ~= nil or next(majorAuras) ~= nil then
-            frameBase:Show();
+            if not frameBase:IsShown() then frameBase:Show() end
             self.running = true;
             C_TimerAfter(0.15, updateAllIndicators);
         end
     end
 end
 
             self.running = true;
             C_TimerAfter(0.15, updateAllIndicators);
         end
     end
 end
 
+local function updateStatusText(self, unit)
+    if not UnitIsConnected(unit) then
+        self.statusText:SetText("DC");
+    elseif UnitIsDeadOrGhost(unit) then
+        self.statusText:SetText("rip");
+    else
+        local healthLost = UnitHealthMax(unit) - UnitHealth(unit);
+        if healthLost <= 0 then 
+            self.statusText:SetText("");
+            return;
+        end
+
+        local prettyHealth;
+        if healthLost > 1200000000 then -- 1.2B
+            prettyHealth = format("-%.1fB", healthLost / 1000000000);
+        elseif healthLost > 1200000 then -- 1.2M
+            prettyHealth = format("-%.1fM", healthLost / 1000000);
+        elseif healthLost > 1000 then -- 1K
+            prettyHealth = format("-%dK", healthLost / 1000);
+        else
+            prettyHealth = format("-%d", healthLost)
+        end
+
+        self.statusText:SetText(prettyHealth);
+    end
+end
+
+local function frameEvent(self, event, ...)
+    local arg1, arg2, arg3, arg4 = ...;
+    if event == "UNIT_HEALTH" or event == "UNIT_HEALTH_FREQUENT" then
+        updateStatusText(self, arg1);
+    elseif event == "UNIT_AURA" then
+        updateAuras(self, arg1);
+    end
+end
+
+--[[ TODO powerBar display and bar coloring
+    if options.displayPowerBar and role ~= "HEALER" then
+        frame.healthBar:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1);
+        frame.powerBar:Hide();
+    end
+]]
+
+--local update_ooc = false;
 local function updateFrames()
 local function updateFrames()
-    for name, frame in pairs(frames) do
+    if not IsInGroup() or GetNumGroupMembers() == 1 then
+        -- solo
+        partyState = "solo";
+        local frame = frames[1];
+        frame:UnregisterAllEvents();
+        frame:RegisterUnitEvent("UNIT_AURA", "player");
+        frame:RegisterUnitEvent("UNIT_HEALTH", "player");
+        frame:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", "player");
+    else
+        if IsInRaid() then
+            partyState = "raid";
+            for i, frame in ipairs(frames) do
+                local name = partyState..i;
+                if not UnitExists(name) then break end
+                frame:UnregisterAllEvents();
+                frame:RegisterUnitEvent("UNIT_AURA", name);
+                frame:RegisterUnitEvent("UNIT_HEALTH", name);
+                frame:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", name);
+            end
+        else
+            partyState = "party";
+            for i, name in ipairs(partyMembers) do
+                local frame = frames[i];
+                if not UnitExists(name) then break end
+                frame:UnregisterAllEvents();
+                frame:RegisterUnitEvent("UNIT_AURA", name);
+                frame:RegisterUnitEvent("UNIT_HEALTH", name);
+                frame:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", name);
+            end
+        end
+    end
+    --[[for name, frame in pairs(frames) do
         local unitFrame = _G[name];
         if unitFrame then
         local unitFrame = _G[name];
         if unitFrame then
-            if not frame.pointsSet then
-                frame:SetAllPoints(unitFrame);
-                frame.pointsSet = true;
+            if not frame.unitFrameSetup then
+                if InCombatLockdown() then
+                    update_ooc = true;
+                else
+                    unitFrame.name:SetFont(STANDARD_TEXT_FONT, 12, "");
+                    unitFrame.optionTable.displayBuffs = false;
+                    unitFrame.optionTable.displayDebuffs = false;
+                    unitFrame.optionTable.displayDispelDebuffs = false;
+                    frame.unitFrameSetup = true;
+                end
+            end
+            local unit = unitFrame.unit;
+            if unit then
+                if InCombatLockdown() then
+                    update_ooc = true;
+                else
+                    local name = UnitName(unit);
+                    unitFrame.name:SetText(name);
+                end
             end
         end
             end
         end
-    end
+    end]]
+end
+
+local function createStatusText(frame)
+    frame.statusText = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
+    frame.statusText:SetPoint("CENTER", frame, "CENTER");
+    frame.statusText:SetFont(STANDARD_TEXT_FONT, 14, "");
 end
 
 local function initialize(frame)
 end
 
 local function initialize(frame)
-    local name = "CompactRaidFrame1";
-    frames[name] = CreateFrame("Frame", "OmaRF1", frameBase);
-    frames[name]:SetAllPoints(name);
-    frames[name]:Hide();
-    createIndicators(frames[name]);
+    frames[1] = CreateFrame("Frame", "OmaRF1", frameBase);
+    frames[1]:SetAllPoints("CompactRaidFrame1"); -- only connection to blizzard frames
+    frames[1]:SetScript("OnEvent", frameEvent);
+    frames[1]:Hide();
+    createStatusText(frames[1]);
+    createIndicators(frames[1]);
     local i = 2;
     local i = 2;
+    -- TODO size could change
+    local width, height = frames[1]:GetWidth(), frames[1]:GetHeight();
     for y = 2,5 do
     for y = 2,5 do
-        local name = "CompactRaidFrame"..i;
-        frames[name] = CreateFrame("Frame", "OmaRF"..i, frameBase);
-        frames[name]:Hide();
-        createIndicators(frames[name]);
+        frames[i] = CreateFrame("Frame", "OmaRF"..i, frameBase);
+        frames[i]:SetPoint("TOPLEFT", frames[i-1], "BOTTOMLEFT");
+        frames[i]:SetWidth(width);
+        frames[i]:SetHeight(height);
+        frames[i]:SetScript("OnEvent", frameEvent);
+        frames[i]:Hide();
+        createStatusText(frames[i]);
+        createIndicators(frames[i]);
         i = i + 1;
     end
         i = i + 1;
     end
-    for x = 1,7 do
+    for x = 0,6 do
         for y = 1,5 do
         for y = 1,5 do
-            local name = "CompactRaidFrame"..i;
-            frames[name] = CreateFrame("Frame", "OmaRF"..i, frameBase);
-            frames[name]:Hide();
-            createIndicators(frames[name]);
+            frames[i] = CreateFrame("Frame", "OmaRF"..i, frameBase);
+            frames[i]:SetPoint("TOPLEFT", frames[x*5+y], "TOPRIGHT");
+            frames[i]:SetWidth(width);
+            frames[i]:SetHeight(height);
+            frames[i]:SetScript("OnEvent", frameEvent);
+            frames[i]:Hide();
+            createStatusText(frames[i]);
+            createIndicators(frames[i]);
             i = i + 1;
         end
     end
             i = i + 1;
         end
     end
+    C_TimerAfter(0.01, updateFrames);
 end
 
 end
 
-local function onEvent(self, event, ...)
+local function baseEvent(self, event, ...)
     if event == "GROUP_ROSTER_UPDATE" then
         -- not sure if fired before LayoutFrames, wait a bit
         C_TimerAfter(0.01, updateFrames);
     if event == "GROUP_ROSTER_UPDATE" then
         -- not sure if fired before LayoutFrames, wait a bit
         C_TimerAfter(0.01, updateFrames);
+    --[[elseif event == "PLAYER_REGEN_ENABLED" then
+        if update_ooc then
+            updateFrames();
+            update_ooc = false;
+        end]]
     elseif event == "PLAYER_LOGIN" then
         initialize();
     end
     elseif event == "PLAYER_LOGIN" then
         initialize();
     end
@@ -263,6 +381,12 @@ end
 frameBase = CreateFrame("Frame", nil, UIParent);
 frameBase:SetFrameStrata("HIGH");
 frameBase:RegisterEvent("PLAYER_LOGIN");
 frameBase = CreateFrame("Frame", nil, UIParent);
 frameBase:SetFrameStrata("HIGH");
 frameBase:RegisterEvent("PLAYER_LOGIN");
+frameBase:RegisterEvent("PLAYER_REGEN_ENABLED");
 frameBase:RegisterEvent("GROUP_ROSTER_UPDATE");
 frameBase:RegisterEvent("GROUP_ROSTER_UPDATE");
-frameBase:SetScript("OnEvent", onEvent);
+frameBase:SetScript("OnEvent", baseEvent);
 OmaRF.frameBase = frameBase;
 OmaRF.frameBase = frameBase;
+
+-- hide buffs, debuffs from Blizzard frames
+--DefaultCompactUnitFrameOptions.displayBuffs = false;
+--DefaultCompactUnitFrameOptions.displayDebuffs = false;
+--DefaultCompactUnitFrameOptions.displayDispelDebuffs = false;