bf7bbcc - Create own frames
authorAleksi Blinnikka <aleksi.blinnikka@gmail.com>
Sun, 14 Jan 2018 20:56:07 +0000
committerAleksi Blinnikka <aleksi.blinnikka@gmail.com>
Sun, 14 Jan 2018 20:56:07 +0000
Attaching to blizzard frames just caused taints in combat if people
joined.

OmaRF/CFrame.lua [new file with mode: 0644]
OmaRF/LayoutFramesHook.lua [deleted file]
OmaRF/NewIndicators.lua
OmaRF/OmaRF.toc
OmaRF/UnitFrameSetupHook.lua [deleted file]
OmaRF/UpdateAuras.lua [deleted file]
OmaRF/UpdateNameHook.lua [deleted file]
OmaRF/UpdateStatusTextHook.lua [deleted file]

diff --git a/OmaRF/CFrame.lua b/OmaRF/CFrame.lua
new file mode 100644 (file)
index 0000000..5049497
--- /dev/null
@@ -0,0 +1,458 @@
+-- CFrame.lua
+local _;
+local unpack, pairs, ipairs = unpack, pairs, ipairs;
+local ssub = string.sub;
+local min = math.min;
+local UnitName, UnitInRange, UnitDebuff = UnitName, UnitInRange, UnitDebuff;
+local UnitPower, UnitPowerMax, UnitPowerType = UnitPower, UnitPowerMax, UnitPowerType;
+local UnitHealth, UnitHealthMax = UnitHealth, UnitHealthMax;
+local UnitInParty, UnitInRaid = UnitInParty, UnitInRaid;
+local UnitGetIncomingHeals, UnitGetTotalAbsorbs = UnitGetIncomingHeals, UnitGetTotalAbsorbs;
+local UnitGetTotalHealAbsorbs = UnitGetTotalHealAbsorbs;
+local IsInGroup, IsInRaid = IsInGroup, IsInRaid;
+local UnitIsCharmed = UnitIsCharmed;
+local CreateFrame, RegisterStateDriver, RegisterUnitWatch = CreateFrame, RegisterStateDriver, RegisterUnitWatch;
+local SPELL_POWER_MANA = SPELL_POWER_MANA;
+
+local CFrame = CreateFrame("Frame", "OmaCFrame", UIParent);
+local party = {};
+local raid = {};
+local positions = {"TOPRIGHT", "BOTTOMLEFT"};
+
+-- configurable settings
+local width, height = 80, 40;
+local anchorX, anchorY = 0, -200;
+local indSize = 14;
+local bgColor = {0.7, 0.7, 0.7};
+local bgColorDispel = {1, 0.5, 0};
+local healthColor = {0.3, 0.3, 0.3};
+local healthColorDispel = {0.8, 0.4, 0};
+local shieldColor = {0, 0.7, 1};
+local shieldhlColor = {0.5, 0.8, 1};
+local healpredColor = {0.5, 0.6, 0.5};
+local healabsorbColor = {0.1, 0.1, 0.1};
+local powerColors = {
+    [SPELL_POWER_MANA] = {0, 0.5, 1},
+    [SPELL_POWER_RAGE] = {1, 0.2, 0},
+    [SPELL_POWER_FOCUS] = {1, 0.5, 0},
+    [SPELL_POWER_ENERGY] = {1, 0.8, 0},
+    [SPELL_POWER_RUNIC_POWER] = {0.9, 0, 0.1},
+};
+-- watch to not remove mana entry
+setmetatable(powerColors, {__index = function(t) return t[SPELL_POWER_MANA] end});
+
+local function updateHealth(frame, unit)
+    local current = UnitHealth(unit);
+    local _, max = frame.health:GetMinMaxValues();
+    local healthLost = max - current;
+    frame.health:SetValue(current);
+    if healthLost > 0 then
+        if healthLost > 1200000000 then -- 1.2B
+            frame.text:SetFormattedText("-%.1fB", healthLost / 1000000000);
+        elseif healthLost > 1200000 then -- 1.2M
+            frame.text:SetFormattedText("-%.1fM", healthLost / 1000000);
+        elseif healthLost > 1000 then -- 1K
+            frame.text:SetFormattedText("-%dK", healthLost / 1000);
+        else
+            frame.text:SetFormattedText("-%d", healthLost)
+        end
+        if not frame.text:IsShown() then frame.text:Show() end
+    else
+        if frame.text:IsShown() then frame.text:Hide() end
+    end
+end
+
+local function updateMaxHealth(frame, unit)
+    frame.health:SetMinMaxValues(0, UnitHealthMax(unit));
+end
+
+local function updatePower(frame, unit)
+    frame.mana:SetValue(UnitPower(unit));
+end
+
+local function updateMaxPower(frame, unit)
+    frame.mana:SetMinMaxValues(0, UnitPowerMax(unit));
+end
+
+local function updatePowerColor(frame, unit)
+    frame.mana:SetStatusBarColor(unpack(powerColors[UnitPowerType(unit)]));
+end
+
+local function updateName(frame, unit)
+    frame.name:SetText(ssub(UnitName(unit), 1, 6));
+end
+
+local function updateHealPred(frame, unit)
+    local incoming = UnitGetIncomingHeals(unit) or 0;
+    if incoming > 0 then
+        local _, max = frame.health:GetMinMaxValues();
+        local space = width - frame.health.bar:GetWidth() + 1;
+        local pred = (incoming / max) * width;
+        frame.healpred:SetWidth(min(space, pred));
+        if not frame.healpred:IsShown() then frame.healpred:Show() end
+    else
+        if frame.healpred:IsShown() then frame.healpred:Hide() end
+    end
+end
+
+local function updateShield(frame, unit)
+    local shield = UnitGetTotalAbsorbs(unit) or 0;
+    if shield > 0 then
+        local _, max = frame.health:GetMinMaxValues();
+        local space = width - frame.health.bar:GetWidth();
+        shield = (shield / max) * width;
+        frame.shield:SetWidth(min(space, shield));
+        if not frame.shield:IsShown() then
+            frame.shield:Show();
+            frame.shieldhl:Show();
+        end
+    else
+        if frame.shield:IsShown() then
+            frame.shield:Hide();
+            frame.shieldhl:Hide();
+        end
+    end
+end
+
+local function updateHealAbsorb(frame, unit)
+    local absorb = UnitGetTotalHealAbsorbs(unit) or 0;
+    if absorb > 0 then
+        local _, max = frame.health:GetMinMaxValues();
+        local space = frame.health.bar:GetWidth();
+        absorb = (absorb / max) * width;
+        frame.healabsorb:SetWidth(min(space, absorb));
+        if not frame.healabsorb:IsShown() then frame.healabsorb:Show() end
+    else
+        if frame.healabsorb:IsShown() then frame.healabsorb:Hide() end
+    end
+end
+
+local function updateAuras(frame, unit)
+    if UnitDebuff(unit, 1, "RAID") ~= nil then
+        -- something dispellable
+        if frame.health.color ~= healthColorDispel then
+            -- TODO change to a texture layered on top tinting whole bar
+            frame.health:SetStatusBarColor(unpack(healthColorDispel));
+            frame.background:SetColorTexture(unpack(bgColorDispel));
+            frame.health.color = healthColorDispel;
+        end
+    elseif UnitIsCharmed(unit) then
+        -- TODO purple
+    else
+        if frame.health.color ~= healthColor then
+            frame.health:SetStatusBarColor(unpack(healthColor));
+            frame.background:SetColorTexture(unpack(bgColor));
+            frame.health.color = healthColor;
+        end
+    end
+end
+
+local function unitEvent(self, event, ...)
+    local arg1, arg2, arg3, arg4 = ...;
+    if event == "UNIT_HEALTH" or event == "UNIT_HEALTH_FREQUENT" then
+        updateHealth(self, arg1);
+    elseif event == "UNIT_POWER" then
+        updatePower(self, arg1);
+    elseif event == "UNIT_AURA" then
+        updateAuras(self, arg1);
+    elseif event == "UNIT_ABSORB_AMOUNT_CHANGED" then
+        updateShield(self, arg1);
+    elseif event == "UNIT_HEAL_PREDICTION" then
+        updateHealPred(self, arg1);
+    elseif event == "UNIT_HEAL_ABSORB_AMOUNT_CHANGED" then
+        updateHealAbsorb(self, arg1);
+    elseif event == "UNIT_MAXHEALTH" then
+        updateMaxHealth(self, arg1);
+    elseif event == "UNIT_MAXPOWER" then
+        updateMaxPower(self, arg1);
+    elseif event == "UNIT_DISPLAYPOWER" then
+        updatePowerColor(self, arg1);
+    elseif event == "UNIT_NAME_UPDATE" then
+        updateName(self, arg1);
+    elseif event == "UPDATE_ALL_BARS" then
+        updateHealth(self, arg1);
+        updatePower(self, arg1);
+        updateAuras(self, arg1);
+        updateShield(self, arg1);
+        updateHealPred(self, arg1);
+        updateMaxHealth(self, arg1);
+        updateMaxPower(self, arg1);
+        updatePowerColor(self, arg1);
+        updateName(self, arg1);
+    end
+end
+
+local function unitUpdate(self, elapsed)
+    -- there's no in/out of range event, have to check each frame
+    -- indicator update here?
+    local inRange, checked = UnitInRange(self.unit);
+    if checked and not inRange then
+        self:SetAlpha(0.55);
+    else
+        self:SetAlpha(1);
+    end
+end
+
+local function registerEvents(frame, unit)
+    frame:RegisterUnitEvent("UNIT_HEALTH", unit);
+    frame:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", unit);
+    frame:RegisterUnitEvent("UNIT_MAXHEALTH", unit);
+    frame:RegisterUnitEvent("UNIT_POWER", unit);
+    frame:RegisterUnitEvent("UNIT_MAXPOWER", unit);
+    frame:RegisterUnitEvent("UNIT_DISPLAYPOWER", unit);
+    frame:RegisterUnitEvent("UNIT_NAME_UPDATE", unit);
+    frame:RegisterUnitEvent("UNIT_AURA", unit);
+    frame:RegisterUnitEvent("UNIT_HEAL_PREDICTION", unit);
+    frame:RegisterUnitEvent("UNIT_ABSORB_AMOUNT_CHANGED", unit);
+    frame:RegisterUnitEvent("UNIT_HEAL_ABSORB_AMOUNT_CHANGED", unit);
+end
+
+local function vis(frame, vis)
+    if vis then
+        frame:Show();
+        frame:SetScript("OnUpdate", unitUpdate);
+        frame:UnregisterAllEvents();
+        registerEvents(frame, frame.unit);
+        unitEvent(frame, "UPDATE_ALL_BARS", frame.unit);
+    else
+        frame:Hide();
+        frame:SetScript("OnUpdate", nil);
+        frame:UnregisterAllEvents();
+    end;
+end
+
+local function updateGroup()
+    if IsInGroup() then
+        if IsInRaid() then
+            -- show raid
+            for _, val in ipairs(raid) do
+                if UnitInRaid(val.frame.unit) then
+                    if not val.frame:IsShown() then vis(val.frame, true) end
+                elseif val.frame:IsShown() then
+                    vis(val.frame, false);
+                end
+            end
+            -- hide player + party (use pairs, not ipairs)
+            for _, val in pairs(party) do
+                if val.frame:IsShown() then vis(val.frame, false) end
+            end
+        else
+            -- show player + party
+            for _, val in pairs(party) do
+                if UnitInParty(val.frame.unit) then
+                    if not val.frame:IsShown() then vis(val.frame, true) end
+                elseif val.frame:IsShown() then
+                    vis(val.frame, false);
+                end
+            end
+            -- hide raid
+            for _, val in ipairs(raid) do
+                if val.frame:IsShown() then vis(val.frame, false) end
+            end
+        end
+    else
+        -- show player
+        if not party[0].frame:IsShown() then vis(party[0].frame, true) end
+        -- hide all other frames
+        for _, val in ipairs(party) do
+            if val.frame:IsShown() then vis(val.frame, false) end
+        end
+        for _, val in ipairs(raid) do
+            if val.frame:IsShown() then vis(val.frame, false) end
+        end
+    end
+end
+
+local function setupIndicators(frame)
+    frame.inds = CreateFrame("Frame", nil, frame);
+    frame.inds:SetAllPoints();
+    for _, pos in pairs(positions) do
+        frame.inds[pos] = frame.inds:CreateTexture(nil, "OVERLAY");
+        frame.inds[pos]:SetPoint(pos, frame.inds, pos);
+        frame.inds[pos]:SetWidth(indSize);
+        frame.inds[pos]:SetHeight(indSize);
+        frame.inds[pos]:SetTexture("Interface\\AddOns\\OmaRF\\images\\rhomb");
+    end
+end
+
+local function setupFrame(frame, secure, unit)
+    -- create visuals
+    secure:SetWidth(width+2);
+    frame:SetWidth(width+2);
+    frame.base = frame:CreateTexture(nil, "BACKGROUND");
+    frame.base:SetAllPoints();
+    frame.base:SetColorTexture(0, 0, 0);
+    frame.background = frame:CreateTexture(nil, "BACKGROUND", nil, 1);
+    frame.background:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1);
+    frame.background:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1);
+    frame.background:SetColorTexture(unpack(bgColor));
+    frame.health = CreateFrame("StatusBar", nil, frame);
+    frame.health:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
+    frame.health:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", 0, 2);
+    frame.health.bar = frame.health:CreateTexture(nil, "ARTWORK");
+    frame.health.bar:SetTexture("Interface\\RaidFrame\\Raid-Bar-Hp-Fill");
+    frame.health:SetStatusBarTexture(frame.health.bar);
+    frame.health:SetStatusBarColor(unpack(healthColor));
+    frame.health.color = healthColor;
+    frame.shield = frame.health:CreateTexture(nil, "ARTWORK");
+    frame.shield:SetPoint("TOPLEFT", frame.health.bar, "TOPRIGHT");
+    frame.shield:SetPoint("BOTTOMLEFT", frame.health.bar, "BOTTOMRIGHT");
+    frame.shield:SetColorTexture(unpack(shieldColor));
+    frame.shield:Hide();
+    frame.shieldhl = frame:CreateTexture(nil, "ARTWORK");
+    frame.shieldhl:SetPoint("TOPLEFT", frame.shield, "TOPRIGHT", -1, 0);
+    frame.shieldhl:SetPoint("BOTTOMRIGHT", frame.shield, "BOTTOMRIGHT", 1, 0);
+    frame.shieldhl:SetColorTexture(unpack(shieldhlColor));
+    frame.shieldhl:Hide();
+    frame.healpred = frame.health:CreateTexture(nil, "ARTWORK", nil, 1);
+    frame.healpred:SetPoint("TOPLEFT", frame.health.bar, "TOPRIGHT");
+    frame.healpred:SetPoint("BOTTOMLEFT", frame.health.bar, "BOTTOMRIGHT");
+    frame.healpred:SetColorTexture(unpack(healpredColor));
+    frame.healpred:Hide();
+    frame.healabsorb = frame.health:CreateTexture(nil, "ARTWORK", nil, 1);
+    frame.healabsorb:SetPoint("TOPRIGHT", frame.health.bar, "TOPRIGHT");
+    frame.healabsorb:SetPoint("BOTTOMRIGHT", frame.health.bar, "BOTTOMRIGHT");
+    frame.healabsorb:SetColorTexture(unpack(healabsorbColor));
+    frame.healabsorb:Hide();
+    frame.mana = CreateFrame("StatusBar", nil, frame);
+    frame.mana:SetPoint("TOPLEFT", frame.background, "BOTTOMLEFT", 0, 2);
+    frame.mana:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT");
+    frame.mana.bar = frame.mana:CreateTexture(nil, "ARTWORK");
+    frame.mana.bar:SetColorTexture(1, 1, 1);
+    frame.mana:SetStatusBarTexture(frame.mana.bar);
+    frame.name = frame.health:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
+    frame.name:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
+    local name = UnitName(unit);
+    frame.name:SetText(name and ssub(name, 1, 6) or "");
+    frame.text = frame.health:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
+    frame.text:SetFont(STANDARD_TEXT_FONT, 13);
+    frame.text:SetPoint("CENTER", frame.background, "CENTER");
+    frame.text:Hide();
+    setupIndicators(frame);
+    -- set attributes
+    secure:RegisterForClicks("AnyDown");
+    secure:SetAttribute("type1", "spell"); -- left click
+    secure:SetAttribute("type2", "spell"); -- right click
+    secure:SetAttribute("shift-type1", "spell"); -- shift left click
+    secure:SetAttribute("shift-type2", "spell"); -- shift right click
+    secure:SetAttribute("ctrl-type1", "spell"); -- ctrl left click
+    secure:SetAttribute("alt-type2", "spell"); -- alt right click
+    secure:SetAttribute("alt-shift-type1", "spell"); -- alt+shift left click
+    secure:SetAttribute("alt-shift-type2", "spell"); -- alt+shift right click
+    secure:SetAttribute("spell1", "Holy Light");
+    secure:SetAttribute("spell2", "Bestow Faith");
+    secure:SetAttribute("shift-spell1", "Flash of Light");
+    secure:SetAttribute("shift-spell2", "Light of the Martyr");
+    secure:SetAttribute("ctrl-spell1", "Cleanse");
+    secure:SetAttribute("alt-spell2", "Lay on Hands");
+    secure:SetAttribute("alt-shift-spell1", "Beacon of Light");
+    secure:SetAttribute("alt-shift-spell2", "Beacon of Faith");
+    -- rest give target and menu
+    secure:SetAttribute("*type1", "target");
+    secure:SetAttribute("*type2", "togglemenu");
+end
+
+local function initializeParty()
+    local secure = CreateFrame("Button", "OmaPartySecure0", CFrame, "SecureUnitButtonTemplate");
+    local frame = CreateFrame("Frame", "OmaParty0", CFrame);
+    local unit = "player";
+    secure:SetAttribute("unit", unit);
+    secure:SetPoint("TOPLEFT", CFrame, "TOPLEFT");
+    secure:SetHeight(height+2);
+    frame.unit = unit;
+    frame:SetPoint("TOPLEFT", CFrame, "TOPLEFT");
+    frame:SetHeight(height+2);
+    frame:SetScript("OnEvent", unitEvent);
+    frame:Hide();
+    setupFrame(frame, secure, unit);
+    RegisterStateDriver(secure, "visibility", "[@player,group:raid] hide; show");
+    party[0] = {secure=secure, frame=frame};
+    for i = 1,4 do
+        local secure = CreateFrame("Button", "OmaPartySecure"..i, CFrame, "SecureUnitButtonTemplate");
+        local frame = CreateFrame("Frame", "OmaParty"..i, CFrame);
+        local unit = "party"..i;
+        secure:SetAttribute("unit", unit);
+        secure:SetPoint("TOPLEFT", party[i-1].secure, "TOPRIGHT");
+        secure:SetPoint("BOTTOMLEFT", party[i-1].secure, "BOTTOMRIGHT");
+        frame.unit = unit;
+        frame:SetPoint("TOPLEFT", party[i-1].frame, "TOPRIGHT");
+        frame:SetPoint("BOTTOMLEFT", party[i-1].frame, "BOTTOMRIGHT");
+        frame:SetScript("OnEvent", unitEvent);
+        frame:Hide();
+        setupFrame(frame, secure, unit);
+        RegisterUnitWatch(secure);
+        party[i] = {secure=secure, frame=frame};
+    end
+end
+
+local function initializeRaid()
+    local secure = CreateFrame("Button", "OmaRaidSecure1", CFrame, "SecureUnitButtonTemplate");
+    local frame = CreateFrame("Frame", "OmaRaid1", CFrame);
+    local unit = "raid1";
+    secure:SetAttribute("unit", unit);
+    secure:SetPoint("TOPLEFT", CFrame, "TOPLEFT");
+    secure:SetHeight(height+2);
+    frame.unit = unit;
+    frame:SetPoint("TOPLEFT", CFrame, "TOPLEFT");
+    frame:SetHeight(height+2);
+    frame:SetScript("OnEvent", unitEvent);
+    frame:Hide();
+    setupFrame(frame, secure, unit);
+    RegisterUnitWatch(secure);
+    raid[1] = {secure=secure, frame=frame};
+    for y = 1,7 do
+        local i = y*5+1;
+        local secure = CreateFrame("Button", "OmaRaidSecure"..i, CFrame, "SecureUnitButtonTemplate");
+        local frame = CreateFrame("Frame", "OmaRaid"..i, CFrame);
+        local unit = "raid"..i;
+        secure:SetAttribute("unit", unit);
+        secure:SetPoint("TOPLEFT", raid[i-5].secure, "BOTTOMLEFT");
+        secure:SetHeight(height+2);
+        frame.unit = unit;
+        frame:SetPoint("TOPLEFT", raid[i-5].frame, "BOTTOMLEFT");
+        frame:SetHeight(height+2);
+        frame:SetScript("OnEvent", unitEvent);
+        frame:Hide();
+        setupFrame(frame, secure, unit);
+        RegisterUnitWatch(secure);
+        raid[i] = {secure=secure, frame=frame};
+    end
+    for y = 0,7 do
+        for x = 1,4 do
+            local i = y*5+x+1;
+            local secure = CreateFrame("Button", "OmaRaidSecure"..i, CFrame, "SecureUnitButtonTemplate");
+            local frame = CreateFrame("Frame", "OmaRaid"..i, CFrame);
+            local unit = "raid"..i;
+            secure:SetAttribute("unit", unit);
+            secure:SetPoint("TOPLEFT", raid[i-1].secure, "TOPRIGHT");
+            secure:SetPoint("BOTTOMLEFT", raid[i-1].secure, "BOTTOMRIGHT");
+            frame.unit = unit;
+            frame:SetPoint("TOPLEFT", raid[i-1].frame, "TOPRIGHT");
+            frame:SetPoint("BOTTOMLEFT", raid[i-1].frame, "BOTTOMRIGHT");
+            frame:SetScript("OnEvent", unitEvent);
+            frame:Hide();
+            setupFrame(frame, secure, unit);
+            RegisterUnitWatch(secure);
+            raid[i] = {secure=secure, frame=frame};
+        end
+    end
+end
+
+local function initialize()
+    CFrame:SetPoint("CENTER", nil, "CENTER", anchorX, anchorY);
+    CFrame:SetHeight((height+2)*8);
+    CFrame:SetWidth((width+2)*5+1); -- extra pixel for shield overflow
+    initializeParty();
+    initializeRaid();
+    updateGroup();
+end
+
+CFrame:RegisterEvent("PLAYER_LOGIN");
+CFrame:RegisterEvent("GROUP_ROSTER_UPDATE");
+CFrame:SetScript("OnEvent", function(self, event, ...)
+    if event == "GROUP_ROSTER_UPDATE" then
+        updateGroup();
+    elseif event == "PLAYER_LOGIN" then
+        initialize();
+    end
+end);
diff --git a/OmaRF/LayoutFramesHook.lua b/OmaRF/LayoutFramesHook.lua
deleted file mode 100644 (file)
index 168891c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-local normalBarColor = OmaRF.normalBarColor;
-local normalBackColor = OmaRF.normalBackColor;
-local UnitGroupRolesAssigned = UnitGroupRolesAssigned;
-local CompactUnitFrame_UpdateHealthColor = CompactUnitFrame_UpdateHealthColor;
-local CompactRaidFrameContainer_ApplyToFrames = CompactRaidFrameContainer_ApplyToFrames;
-local unpack = unpack;
-
--- TODO remove 1px border
-local function layoutHook(frame)
-    if InCombatLockdown() then
-        OmaRF.ooc_queue["layoutHook"] = {func = layoutHook, args = {frame}};
-        return;
-    end
-    CompactRaidFrameContainer_ApplyToFrames(frame, "normal", function(frame)
-        -- Health bar color --
-        -- used in CompactUnitFrame_UpdateHealthColor, might not be set prior
-        frame.optionTable.healthBarColorOverride = normalBarColor;
-        frame.background:SetColorTexture(unpack(normalBackColor));
-        -- Power bar display --
-        local role = UnitGroupRolesAssigned(frame.unit);
-        local options = DefaultCompactUnitFrameSetupOptions;
-        if options.displayPowerBar and role ~= "HEALER" then
-            frame.healthBar:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1);
-            frame.powerBar:Hide();
-        end
-    end);
-end
-hooksecurefunc("CompactRaidFrameContainer_LayoutFrames", layoutHook);
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 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;
@@ -15,6 +16,8 @@ local frames = {};
 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
@@ -57,57 +60,56 @@ local function showMajorIndicator(ind, icon, count, expires, current)
     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
+            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
 
 -- 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;
+    elseif partyState == "raid" then
+        unit = partyState..i;
+    elseif i ~= 1 then
+        -- party frames have player separate
+        unit = partyState..(i-1);
     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;
+    elseif not frame:IsShown() then
+        frame:Show();
     end
-    if not frame:IsShown() then frame:Show() end
 
     local current = GetTime();
     for pos, ind in pairs(frame.inds) do
@@ -185,7 +187,9 @@ end
 
 -- 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
 
@@ -207,54 +211,168 @@ function OmaRF:RefreshConfig()
         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
 
+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()
-    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
-            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
+
+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)
-    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;
+    -- TODO size could change
+    local width, height = frames[1]:GetWidth(), frames[1]:GetHeight();
     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
-    for x = 1,7 do
+    for x = 0,6 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
+    C_TimerAfter(0.01, updateFrames);
 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);
+    --[[elseif event == "PLAYER_REGEN_ENABLED" then
+        if update_ooc then
+            updateFrames();
+            update_ooc = false;
+        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:RegisterEvent("PLAYER_REGEN_ENABLED");
 frameBase:RegisterEvent("GROUP_ROSTER_UPDATE");
-frameBase:SetScript("OnEvent", onEvent);
+frameBase:SetScript("OnEvent", baseEvent);
 OmaRF.frameBase = frameBase;
+
+-- hide buffs, debuffs from Blizzard frames
+--DefaultCompactUnitFrameOptions.displayBuffs = false;
+--DefaultCompactUnitFrameOptions.displayDebuffs = false;
+--DefaultCompactUnitFrameOptions.displayDispelDebuffs = false;
index 9e4a6aa..15d4244 100644 (file)
@@ -7,11 +7,5 @@
 
 embeds.xml
 
-Core.lua
-NewIndicators.lua
-UnitFrameSetupHook.lua
-UpdateNameHook.lua
-UpdateStatusTextHook.lua
-UpdateAuras.lua
-LayoutFramesHook.lua
+CFrame.lua
 PlayerFrameHooks.lua
diff --git a/OmaRF/UnitFrameSetupHook.lua b/OmaRF/UnitFrameSetupHook.lua
deleted file mode 100644 (file)
index 9a29992..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-hooksecurefunc("DefaultCompactUnitFrameSetup", function(frame)
-    -- used in CompactUnitFrame_UpdateAuras (Buffs, Debuffs, DispellableDebuffs)
-    frame.optionTable.displayBuffs = false;
-    frame.optionTable.displayDebuffs = false;
-    frame.optionTable.displayDispelDebuffs = false;
-end);
diff --git a/OmaRF/UpdateAuras.lua b/OmaRF/UpdateAuras.lua
deleted file mode 100644 (file)
index e6d82f0..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-local normalBarColor = OmaRF.normalBarColor;
-local dispelBarColor = OmaRF.dispelBarColor;
-local normalBackColor = OmaRF.normalBackColor;
-local dispelBackColor = OmaRF.dispelBackColor;
-
-local UnitDebuff = UnitDebuff;
-local CompactUnitFrame_UpdateHealthColor = CompactUnitFrame_UpdateHealthColor;
-local unpack = unpack;
-
-hooksecurefunc("CompactUnitFrame_UpdateAuras", function(frame)
-    -- allowClassColorsForNPCs only in regular raid frames
-    if frame.optionTable.allowClassColorsForNPCs ~= nil then
-        -- try to find dispellable debuff
-        if UnitDebuff(frame.displayedUnit, 1, "RAID") ~= nil then
-            frame.optionTable.healthBarColorOverride = dispelBarColor;
-            frame.background:SetColorTexture(unpack(dispelBackColor));
-        else
-            frame.optionTable.healthBarColorOverride = normalBarColor;
-            frame.background:SetColorTexture(unpack(normalBackColor));
-        end
-        CompactUnitFrame_UpdateHealthColor(frame);
-    end
-end);
diff --git a/OmaRF/UpdateNameHook.lua b/OmaRF/UpdateNameHook.lua
deleted file mode 100644 (file)
index 8165c7d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-local UnitName = UnitName;
-
-local function nameHook(frame)
-    if InCombatLockdown() then
-        table.insert(OmaRF.ooc_queue, {func = nameHook, args = {frame}});
-        return;
-    end
-    -- allowClassColorsForNPCs only in regular raid frames,
-    -- match only to them
-    if frame.optionTable.allowClassColorsForNPCs ~= nil then
-        local name, _;
-        name, _ = UnitName(frame.unit);
-        if name then
-            frame.name:SetFont(STANDARD_TEXT_FONT, 12, "");
-            frame.name:SetText(name);
-        end
-    end
-end
-hooksecurefunc("CompactUnitFrame_UpdateName", nameHook);
diff --git a/OmaRF/UpdateStatusTextHook.lua b/OmaRF/UpdateStatusTextHook.lua
deleted file mode 100644 (file)
index 76a677e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-local UnitIsConnected = UnitIsConnected;
-local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
-local UnitHealthMax = UnitHealthMax;
-local UnitHealth = UnitHealth;
-local format = string.format
-
-hooksecurefunc("CompactUnitFrame_UpdateStatusText", function(frame)
-    -- allowClassColorsForNPCs only in regular raid frames,
-    -- match only to them
-    if frame.optionTable.allowClassColorsForNPCs ~= nil then
-        -- conditions taken from CompactUnitFrame.lua
-        if not UnitIsConnected(frame.unit) or UnitIsDeadOrGhost(frame.displayedUnit) then
-            return;
-        elseif (frame.optionTable.healthText == "losthealth") then
-            -- only losthealth option is condensed
-            local healthLost = UnitHealthMax(frame.displayedUnit) - UnitHealth(frame.displayedUnit);
-            if healthLost <= 0 then 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
-
-            frame.statusText:SetText(prettyHealth);
-        end
-    end
-end);