local _, addon = ...;
local unpack = unpack;
local min = math.min;
+local format = string.format;
local UnitDebuff, UnitIsCharmed = UnitDebuff, UnitIsCharmed;
local UnitHealth, UnitHealthMax = UnitHealth, UnitHealthMax;
+local UnitPower, UnitPowerMax = UnitPower, UnitPowerMax;
local UnitIsAFK, UnitIsDND = UnitIsAFK, UnitIsDND;
local UnitGetIncomingHeals, UnitGetTotalAbsorbs = UnitGetIncomingHeals, UnitGetTotalAbsorbs;
local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected;
local UnitGetTotalHealAbsorbs = UnitGetTotalHealAbsorbs;
+local InCombatLockdown, IsResting = InCombatLockdown, IsResting;
+local UnitInRange, UnitInPhase = UnitInRange, UnitInPhase;
local dispelcolor = addon.Colors.OverlayColorDispel;
local charmcolor = addon.Colors.OverlayColorCharm;
local majorcolor = addon.Colors.OverlayColorAlert;
local healcolor = addon.Colors.OverlayColorHeal;
+local ignoredAuras = {
+ [315176] = true, -- Grasping Tendrils
+ [313759] = true, -- Cursed Blood (Il'gynoth)
+ [312486] = true, -- Recurring Nightmare (Il'gynoth)
+};
+
+local powerColors = {
+ [Enum.PowerType.Mana] = {0.1, 0.5, 0.9},
+ [Enum.PowerType.Rage] = {1, 0, 0},
+ [Enum.PowerType.Pain] = {1, 0, 0},
+ [Enum.PowerType.Focus] = {1, 0.5, 0},
+ [Enum.PowerType.Energy] = {1, 0.8, 0},
+ [Enum.PowerType.Fury] = {0.8, 0.3, 0.9},
+ [Enum.PowerType.RunicPower] = {0.8, 0, 0.2},
+ [Enum.PowerType.LunarPower] = {0.3, 0.5, 0.9},
+ [Enum.PowerType.Maelstrom] = {0, 0.5, 1},
+ [Enum.PowerType.Insanity] = {0.4, 0, 0.8},
+};
+
function addon.FrameUpdate(frame)
assert(type(frame) == "table", "FrameUpdate received invalid frame parameter!");
local unit = frame.displayed;
local width = frame.barwidth;
- -- range check (doesn't have an event)
- local inrange, checked = UnitInRange(unit);
- if checked and not inrange then
- frame:SetAlpha(0.55);
- else
- frame:SetAlpha(1);
+ -- range check (doesn't have an event) frames can be marked constantly visible
+ if not frame.constant then
+ local inrange, checked = UnitInRange(unit);
+ local inphase = UnitPhaseReason(unit);
+ if (checked and not inrange) or inphase then
+ frame:SetAlpha(0.55);
+ else
+ frame:SetAlpha(1);
+ end
end
-- states
if UnitIsDeadOrGhost(unit) then
frame.prev.hmax = nil;
else
if UnitIsAFK(unit) then
+ frame.text.status = true;
+ frame.prev.htext = nil;
frame.text:SetText("afk");
if not frame.text:IsShown() then frame.text:Show() end
elseif UnitIsDND(unit) then
+ frame.text.status = true;
+ frame.prev.htext = nil;
frame.text:SetText("dnd");
if not frame.text:IsShown() then frame.text:Show() end
else
- if frame.text:IsShown() then frame.text:Hide() end
+ frame.text.status = false;
+ if frame.raid and frame.text:IsShown() then
+ frame.text:Hide();
+ end
+ end
+ if not frame.raid and frame.unit == "player" then
+ if InCombatLockdown() then
+ frame.status:SetTexCoord(0.5, 1, 0, 0.484375);
+ frame.status:Show();
+ elseif IsResting() then
+ frame.status:SetTexCoord(0, 0.5, 0, 0.421875);
+ frame.status:Show();
+ elseif frame.status:IsShown() then
+ frame.status:Hide();
+ end
end
-- health
local current, hmax = UnitHealth(unit), UnitHealthMax(unit);
if not frame.health:IsShown() then frame.health:Show() end
end
end
+ -- health text
+ if not frame.raid and not frame.text.status and frame.prev.htext ~= current then
+ frame.prev.htext = current;
+ if frame.boss then
+ if hmax < current or hmax <= 1 then
+ frame.text:SetText("100");
+ if not frame.text:IsShown() then frame.text:Show() end
+ elseif current <= 0 then
+ if frame.text:IsShown() then frame.text:Hide() end
+ else
+ frame.text:SetFormattedText("%.1f", current/hmax*100);
+ if not frame.text:IsShown() then frame.text:Show() end
+ end
+ else
+ if current > 1000000000 then -- 1.0B
+ frame.text:SetFormattedText("%.2fB", current / 1000000000);
+ elseif current > 1000000 then -- 1.0M
+ frame.text:SetFormattedText("%.2fM", current / 1000000);
+ elseif current > 1000 then -- 1.0K
+ frame.text:SetFormattedText("%.1fK", current / 1000);
+ else
+ frame.text:SetFormattedText("%i", current);
+ end
+ if not frame.text:IsShown() then frame.text:Show() end
+ end
+ end
-- shield
local hwidth = frame.health.width;
current = UnitGetTotalAbsorbs(unit) or 0;
elseif frame.healpred:IsShown() then
frame.healpred:Hide();
end
- -- tank CD marker
- if next(frame.tankcd) then
- if not frame.defensive:IsShown() then frame.defensive:Show() end
- elseif frame.defensive:IsShown() then
- frame.defensive:Hide();
+ -- mana, if present
+ if frame.mana ~= nil then
+ local current, max = UnitPower(unit), UnitPowerMax(unit);
+ local ptype = UnitPowerType(unit);
+ if frame.mana.ptype ~= ptype then
+ frame.mana.ptype = ptype;
+ frame.mana:SetVertexColor(unpack(powerColors[ptype]));
+ end
+ if frame.prev.mana ~= current or frame.prev.mmax ~= max then
+ frame.prev.mana = current;
+ frame.prev.mmax = max;
+ if max < 1 then
+ if frame.mana:IsShown() then frame.mana:Hide() end
+ if frame.manatext:IsShown() then frame.manatext:Hide() end
+ elseif max < current then
+ frame.mana:SetWidth(width);
+ frame.manatext:SetText("100");
+ if not frame.mana:IsShown() then frame.mana:Show() end
+ if not frame.manatext:IsShown() then frame.manatext:Show() end
+ elseif current <= 0 then
+ if frame.mana:IsShown() then frame.mana:Hide() end
+ if frame.manatext:IsShown() then frame.manatext:Hide() end
+ else
+ local percent = current/max;
+ frame.mana:SetWidth(percent*width);
+ frame.manatext:SetText(format("%d", percent*100+0.5));
+ if not frame.mana:IsShown() then frame.mana:Show() end
+ if not frame.manatext:IsShown() then frame.manatext:Show() end
+ end
+ end
end
- -- aura stacks
- if next(frame.stacks) then
- frame.stack:SetText(next(frame.stacks));
- if not frame.stack:IsShown() then frame.stack:Show() end
- elseif frame.stack:IsShown() then
- frame.stack:Hide();
+ -- forced aura updates
+ if frame.rounds ~= nil then
+ frame.rounds = frame.rounds + 1;
+ if (frame.rounds > 7) then
+ frame.tankcd = {};
+ frame.alert = {};
+ frame.stacks = {};
+ frame.heal = {};
+ frame.buff1 = {};
+ frame.buff2 = {};
+ frame.stagger = {};
+ addon.SetAuras(frame.unit, frame.guid);
+ frame.rounds = 0;
+ end
end
- -- overlays
- if next(frame.alert) then
- -- major
- if frame.overlay.color ~= majorcolor then
- frame.overlay:SetVertexColor(unpack(majorcolor));
- frame.overlay.color = majorcolor;
- if not frame.overlay:IsShown() then frame.overlay:Show() end
+ if frame.raid then
+ -- tank CD marker
+ if next(frame.tankcd) then
+ if not frame.defensive:IsShown() then frame.defensive:Show() end
+ elseif frame.defensive:IsShown() then
+ frame.defensive:Hide();
end
- elseif next(frame.heal) then
- -- major heals needed
- if frame.overlay.color ~= healcolor then
- frame.overlay:SetVertexColor(unpack(healcolor));
- frame.overlay.color = healcolor;
- if not frame.overlay:IsShown() then frame.overlay:Show() end
+ -- aura stacks
+ if next(frame.stacks) then
+ local _, amount = next(frame.stacks);
+ frame.stack:SetText(amount);
+ if not frame.stack:IsShown() then frame.stack:Show() end
+ elseif next(frame.hits) then
+ local _, amount = next(frame.hits);
+ frame.stack:SetText(amount);
+ if not frame.stack:IsShown() then frame.stack:Show() end
+ elseif frame.stack:IsShown() then
+ frame.stack:Hide();
end
- elseif UnitIsCharmed(unit) and frame.unit == frame.displayed then
- -- charmed
- if frame.overlay.color ~= charmcolor then
- frame.overlay:SetVertexColor(unpack(charmcolor));
- frame.overlay.color = charmcolor;
- if not frame.overlay:IsShown() then frame.overlay:Show() end
+ -- custom buff indicator 1
+ if next(frame.buff1) then
+ if not frame.buffind1:IsShown() then frame.buffind1:Show() end
+ elseif frame.buffind1:IsShown() then
+ frame.buffind1:Hide();
end
- elseif UnitDebuff(unit, 1, "RAID") ~= nil then
- -- dispellable
- if frame.overlay.color ~= dispelcolor then
- frame.overlay:SetVertexColor(unpack(dispelcolor));
- frame.overlay.color = dispelcolor;
- if not frame.overlay:IsShown() then frame.overlay:Show() end
+ -- custom buff indicator 2
+ if next(frame.buff2) then
+ if not frame.buffind2:IsShown() then frame.buffind2:Show() end
+ elseif frame.buffind2:IsShown() then
+ frame.buffind2:Hide();
end
- else
- if frame.overlay.color ~= nil then
- frame.overlay.color = nil;
- if frame.overlay:IsShown() then frame.overlay:Hide() end
+ -- incoming ability
+ if next(frame.incoming) then
+ if not frame.glow:IsShown() then frame.glow:Show() end
+ elseif frame.glow:IsShown() then
+ frame.glow:Hide();
+ end
+ -- DK Death Strike and Monk Stagger tracking
+ if frame.rolename == "TANK" then
+ if frame.classname == "DEATHKNIGHT" then
+ local power = UnitPower(unit);
+ if power < 45 then
+ if not frame.bottomwarn:IsShown() then frame.bottomwarn:Show() end
+ elseif frame.bottomwarn:IsShown() then
+ frame.bottomwarn:Hide();
+ end
+ elseif frame.classname == "MONK" then
+ if next(frame.stagger) then -- Heavy Stagger
+ if not frame.bottomwarn:IsShown() then frame.bottomwarn:Show() end
+ elseif frame.bottomwarn:IsShown() then
+ frame.bottomwarn:Hide();
+ end
+ end
+ elseif frame.bottomwarn:IsShown() then
+ frame.bottomwarn:Hide();
+ end
+ -- overlays
+ if next(frame.alert) then
+ -- major
+ if frame.overlay.color ~= majorcolor then
+ frame.overlay:SetVertexColor(unpack(majorcolor));
+ frame.overlay.color = majorcolor;
+ if not frame.overlay:IsShown() then frame.overlay:Show() end
+ end
+ else
+ local _, _, _, _, _, _, _, _, _, spellid = UnitDebuff(unit, 1, "RAID");
+ if UnitIsCharmed(unit) and frame.unit == frame.displayed then
+ -- charmed
+ if frame.overlay.color ~= charmcolor then
+ frame.overlay:SetVertexColor(unpack(charmcolor));
+ frame.overlay.color = charmcolor;
+ if not frame.overlay:IsShown() then frame.overlay:Show() end
+ end
+ elseif spellid ~= nil and not ignoredAuras[spellid] then
+ -- dispellable
+ if frame.overlay.color ~= dispelcolor then
+ frame.overlay:SetVertexColor(unpack(dispelcolor));
+ frame.overlay.color = dispelcolor;
+ if not frame.overlay:IsShown() then frame.overlay:Show() end
+ end
+ elseif next(frame.heal) then
+ -- major heals needed
+ if frame.overlay.color ~= healcolor then
+ frame.overlay:SetVertexColor(unpack(healcolor));
+ frame.overlay.color = healcolor;
+ if not frame.overlay:IsShown() then frame.overlay:Show() end
+ end
+ else
+ if frame.overlay.color ~= nil then
+ frame.overlay.color = nil;
+ if frame.overlay:IsShown() then frame.overlay:Hide() end
+ end
+ end
end
end
end