X-Git-Url: https://www.aleksib.fi/git/wowui.git/blobdiff_plain/ac5ca8a9cb3cd9c2a6f5850ba5774bd81307fb51..0453a59cf1f5c15fa46a1460dd12d372475b10f1:/OmaUF/Auras.lua?ds=sidebyside diff --git a/OmaUF/Auras.lua b/OmaUF/Auras.lua index deb62fa..f3da677 100644 --- a/OmaUF/Auras.lua +++ b/OmaUF/Auras.lua @@ -1,15 +1,134 @@ -- 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;