328ab5f - Autolog all dungeons during beta
[wowui.git] / OmaUF / Auras.lua
1 -- Auras.lua
2 local _;
3 local CreateFrame = CreateFrame;
4 local UnitAura = UnitAura;
5 local GameTooltip = GameTooltip;
6 local GetTime = GetTime;
7 local CTimerAfter = C_Timer.After;
8
9 local auraFilters = {"HELPFUL", "HARMFUL"};
10 local updateAuras;
11
12 local M = {};
13 OmaUFAuras = M;
14
15 local function updateTooltip(frame)
16     if GameTooltip:IsOwned(frame) then
17         GameTooltip:SetUnitAura(frame.unit, frame.index, frame.filter);
18     else
19         frame:SetScript("OnUpdate", nil);
20     end
21 end
22
23 local function showTooltip(frame)
24     -- tooltip handling from FrameXML/TargetFrame.xml
25     GameTooltip:SetOwner(frame, "ANCHOR_BOTTOMRIGHT", 15, -25);
26     GameTooltip:SetUnitAura(frame.unit, frame.index, frame.filter);
27     frame:SetScript("OnUpdate", updateTooltip);
28 end
29
30 local function hideTooltip(frame)
31     GameTooltip:Hide();
32     frame:SetScript("OnUpdate", nil);
33 end
34
35 local function createAura(parent, prev, anchor, name, unit)
36     local aura = CreateFrame("Frame", name, parent);
37     aura:SetPoint("TOPLEFT", prev, anchor);
38     aura:SetWidth(20);
39     aura:SetHeight(20);
40     aura.icon = aura:CreateTexture(nil, "ARTWORK");
41     aura.icon:SetAllPoints();
42     aura.stack = aura:CreateFontString(nil, "OVERLAY", "NumberFontNormalSmall");
43     aura.stack:SetPoint("BOTTOMRIGHT");
44     aura.cd = CreateFrame("Cooldown", name.."CD", aura, "CooldownFrameTemplate");
45     aura.cd:SetReverse(true);
46     aura.cd:SetHideCountdownNumbers(true);
47     aura.cd:SetAllPoints();
48     aura.unit = unit;
49     aura:SetScript("OnEnter", showTooltip);
50     aura:SetScript("OnLeave", hideTooltip);
51     aura:Hide();
52     return aura;
53 end
54
55 function M.CreateAuraFrame(parent, unit)
56     local name = parent:GetName().."Auras";
57     parent.auras = CreateFrame("Frame", name, parent);
58     parent.auras:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 0, -8);
59     parent.auras:SetWidth(10);
60     parent.auras:SetHeight(10);
61     local i = 1;
62     -- max auras per row
63     for x=1,10 do
64         local auraName = name..i;
65         if i == 1 then
66             parent.auras[i] = createAura(parent.auras, parent.auras, "TOPLEFT", auraName, unit);
67         else
68             parent.auras[i] = createAura(parent.auras, parent.auras[i-1], "TOPRIGHT", auraName, unit);
69         end
70         i = i + 1;
71     end
72     -- max rows
73     for y=0,0 do
74         for x=1,10 do
75             local auraName = name..i;
76             parent.auras[i] = createAura(parent.auras, parent.auras[y*10+x], "BOTTOMLEFT", auraName, unit);
77             i = i + 1;
78         end
79     end
80
81     parent.throttle = function()
82         parent.throttled = nil;
83         if UnitExists(unit) then
84             return updateAuras(parent, unit);
85         end
86     end;
87 end
88
89 function M.UpdateAuras(frame, unit)
90     local current = GetTime();
91     if frame.throttled then
92         return;
93     elseif frame.prevUpdate and current - frame.prevUpdate < 0.2 then
94         frame.throttled = true;
95         return CTimerAfter(0.1, frame.throttle); -- faster timer here to reduce the delay, gets called twice
96     end
97
98     frame.prevUpdate = current;
99     local auras = frame.auras;
100     local icon, count, duration, expires, caster, id;
101     local pos = 1;
102     for _, filter in ipairs(auraFilters) do
103         local i = 1;
104         while true do
105             _, icon, count, _, duration, expires, caster, _, _, id = UnitAura(unit, i, filter);
106             if not id or not auras[pos] then break end
107             local aura = auras[pos];
108             aura.icon:SetTexture(icon);
109             aura.index = i;
110             aura.filter = filter;
111             if count > 1 then
112                 aura.stack:SetText(count);
113                 aura.stack:Show();
114             else
115                 aura.stack:Hide();
116             end
117             if expires > 0 then
118                 aura.cd:SetCooldown(expires - duration, duration);
119             else
120                 aura.cd:Hide();
121             end
122             aura:Show();
123             pos = pos + 1;
124             i = i + 1;
125         end
126     end
127
128     while auras[pos] do
129         if not auras[pos]:IsShown() then return end
130         auras[pos]:Hide();
131         pos = pos + 1;
132     end
133 end
134 updateAuras = M.UpdateAuras;