-- Auras.lua
local _;
local CreateFrame = CreateFrame;
+local UnitAura = UnitAura;
+local GameTooltip = GameTooltip;
+local GetTime = GetTime;
+local CTimerAfter = C_Timer.After;
+
+local auraFilters = {"HELPFUL", "HARMFUL"};
+local updateAuras;
local M = {};
OmaUFAuras = M;
-function M.CreateAuraFrame(parent)
- parent.auras = CreateFrame("Frame", nil, parent);
- parent.auras:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 0, -2);
+local function updateTooltip(frame)
+ if GameTooltip:IsOwned(frame) then
+ GameTooltip:SetUnitAura(frame.unit, frame.index, frame.filter);
+ else
+ frame:SetScript("OnUpdate", nil);
+ end
+end
+
+local function showTooltip(frame)
+ -- tooltip handling from FrameXML/TargetFrame.xml
+ GameTooltip:SetOwner(frame, "ANCHOR_BOTTOMRIGHT", 15, -25);
+ GameTooltip:SetUnitAura(frame.unit, frame.index, frame.filter);
+ frame:SetScript("OnUpdate", updateTooltip);
+end
+
+local function hideTooltip(frame)
+ GameTooltip:Hide();
+ frame:SetScript("OnUpdate", nil);
+end
+
+local function createAura(parent, prev, anchor, name, unit)
+ local aura = CreateFrame("Frame", name, parent);
+ aura:SetPoint("TOPLEFT", prev, anchor);
+ aura:SetWidth(20);
+ aura:SetHeight(20);
+ aura.icon = aura:CreateTexture(nil, "ARTWORK");
+ aura.icon:SetAllPoints();
+ aura.stack = aura:CreateFontString(nil, "OVERLAY", "NumberFontNormalSmall");
+ aura.stack:SetPoint("BOTTOMRIGHT");
+ aura.cd = CreateFrame("Cooldown", name.."CD", aura, "CooldownFrameTemplate");
+ aura.cd:SetReverse(true);
+ aura.cd:SetHideCountdownNumbers(true);
+ aura.cd:SetAllPoints();
+ aura.unit = unit;
+ aura:SetScript("OnEnter", showTooltip);
+ aura:SetScript("OnLeave", hideTooltip);
+ aura:Hide();
+ return aura;
+end
+
+function M.CreateAuraFrame(parent, unit)
+ local name = parent:GetName().."Auras";
+ parent.auras = CreateFrame("Frame", name, parent);
+ parent.auras:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 0, -8);
+ parent.auras:SetWidth(10);
+ parent.auras:SetHeight(10);
+ local i = 1;
+ -- max auras per row
+ for x=1,10 do
+ local auraName = name..i;
+ if i == 1 then
+ parent.auras[i] = createAura(parent.auras, parent.auras, "TOPLEFT", auraName, unit);
+ else
+ parent.auras[i] = createAura(parent.auras, parent.auras[i-1], "TOPRIGHT", auraName, unit);
+ end
+ i = i + 1;
+ end
+ -- max rows
+ for y=0,0 do
+ for x=1,10 do
+ local auraName = name..i;
+ parent.auras[i] = createAura(parent.auras, parent.auras[y*10+x], "BOTTOMLEFT", auraName, unit);
+ i = i + 1;
+ end
+ end
+
+ parent.throttle = function()
+ parent.throttled = nil;
+ if UnitExists(unit) then
+ return updateAuras(parent, unit);
+ end
+ end;
end
function M.UpdateAuras(frame, unit)
+ local current = GetTime();
+ if frame.throttled then
+ return;
+ elseif frame.prevUpdate and current - frame.prevUpdate < 0.2 then
+ frame.throttled = true;
+ return CTimerAfter(0.1, frame.throttle); -- faster timer here to reduce the delay, gets called twice
+ end
+
+ frame.prevUpdate = current;
local auras = frame.auras;
+ local icon, count, duration, expires, caster, id;
+ local pos = 1;
+ for _, filter in ipairs(auraFilters) do
+ local i = 1;
+ while true do
+ _, icon, count, _, duration, expires, caster, _, _, id = UnitAura(unit, i, filter);
+ if not id or not auras[pos] then break end
+ local aura = auras[pos];
+ aura.icon:SetTexture(icon);
+ aura.index = i;
+ aura.filter = filter;
+ if count > 1 then
+ aura.stack:SetText(count);
+ aura.stack:Show();
+ else
+ aura.stack:Hide();
+ end
+ if expires > 0 then
+ aura.cd:SetCooldown(expires - duration, duration);
+ else
+ aura.cd:Hide();
+ end
+ aura:Show();
+ pos = pos + 1;
+ i = i + 1;
+ end
+ end
+
+ while auras[pos] do
+ if not auras[pos]:IsShown() then return end
+ auras[pos]:Hide();
+ pos = pos + 1;
+ end
end
+updateAuras = M.UpdateAuras;