fb13e34 - Add 2 new aura types
[wowui.git] / kehys / updater.lua
1 -- updater.lua
2 -- 2019 Aleksi Blinnikka
3 --
4 -- Main update function for all frames. Gets around issues with events.
5 local _, addon = ...;
6 local unpack = unpack;
7 local min = math.min;
8 local UnitDebuff, UnitIsCharmed = UnitDebuff, UnitIsCharmed;
9 local UnitHealth, UnitHealthMax = UnitHealth, UnitHealthMax;
10 local UnitIsAFK, UnitIsDND = UnitIsAFK, UnitIsDND;
11 local UnitGetIncomingHeals, UnitGetTotalAbsorbs = UnitGetIncomingHeals, UnitGetTotalAbsorbs;
12 local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected;
13 local UnitGetTotalHealAbsorbs = UnitGetTotalHealAbsorbs;
14
15 local dispelcolor = addon.Colors.OverlayColorDispel;
16 local charmcolor = addon.Colors.OverlayColorCharm;
17 local majorcolor = addon.Colors.OverlayColorAlert;
18 local healcolor = addon.Colors.OverlayColorHeal;
19
20 function addon.FrameUpdate(frame)
21     assert(type(frame) == "table", "FrameUpdate received invalid frame parameter!");
22
23     local unit = frame.displayed;
24     local width = frame.barwidth;
25     -- range check (doesn't have an event)
26     local inrange, checked = UnitInRange(unit);
27     if checked and not inrange then
28         frame:SetAlpha(0.55);
29     else
30         frame:SetAlpha(1);
31     end
32     -- states
33     if UnitIsDeadOrGhost(unit) then
34         frame.text:SetText("Dead");
35         if not frame.text:IsShown() then frame.text:Show() end
36         if frame.health:IsShown() then frame.health:Hide() end
37         if frame.shield:IsShown() then frame.shield:Hide() end
38         if frame.shieldhl:IsShown() then frame.shieldhl:Hide() end
39         if frame.healpred:IsShown() then frame.healpred:Hide() end
40         if frame.healabsorb:IsShown() then frame.healabsorb:Hide() end
41         frame.prev.health = nil;
42         frame.prev.hmax = nil;
43     elseif not UnitIsConnected(unit) then
44         frame.text:SetText("DC");
45         if not frame.text:IsShown() then frame.text:Show() end
46         if frame.health:IsShown() then frame.health:Hide() end
47         if frame.shield:IsShown() then frame.shield:Hide() end
48         if frame.shieldhl:IsShown() then frame.shieldhl:Hide() end
49         if frame.healpred:IsShown() then frame.healpred:Hide() end
50         if frame.healabsorb:IsShown() then frame.healabsorb:Hide() end
51         frame.prev.health = nil;
52         frame.prev.hmax = nil;
53     else
54         if UnitIsAFK(unit) then
55             frame.text:SetText("afk");
56             if not frame.text:IsShown() then frame.text:Show() end
57         elseif UnitIsDND(unit) then
58             frame.text:SetText("dnd");
59             if not frame.text:IsShown() then frame.text:Show() end
60         else
61             if frame.text:IsShown() then frame.text:Hide() end
62         end
63         -- health
64         local current, hmax = UnitHealth(unit), UnitHealthMax(unit);
65         if frame.prev.health ~= current or frame.prev.hmax ~= hmax then
66             frame.prev.health = current;
67             frame.prev.hmax = hmax;
68             if hmax < current or hmax <= 1 then
69                 frame.health:SetWidth(width);
70                 frame.health.width = width;
71                 if not frame.health:IsShown() then frame.health:Show() end
72             elseif current <= 0 then
73                 if frame.health:IsShown() then frame.health:Hide() end
74             else
75                 local w = current/hmax*width;
76                 frame.health:SetWidth(w);
77                 frame.health.width = w;
78                 if not frame.health:IsShown() then frame.health:Show() end
79             end
80         end
81         -- shield
82         local hwidth = frame.health.width;
83         current = UnitGetTotalAbsorbs(unit) or 0;
84         if current > 0 then
85             local space = width - hwidth;
86             current = (current / hmax) * width;
87             if space == 0 then
88                 if frame.shield:IsShown() then frame.shield:Hide() end
89                 if not frame.shieldhl:IsShown() then frame.shieldhl:Show() end
90             elseif space < current then
91                 frame.shield:SetWidth(space);
92                 if not frame.shield:IsShown() then frame.shield:Show() end
93                 if not frame.shieldhl:IsShown() then frame.shieldhl:Show() end
94             else
95                 frame.shield:SetWidth(current);
96                 if not frame.shield:IsShown() then frame.shield:Show() end
97                 if frame.shieldhl:IsShown() then frame.shieldhl:Hide() end
98             end
99         else
100             if frame.shield:IsShown() then frame.shield:Hide() end
101             if frame.shieldhl:IsShown() then frame.shieldhl:Hide() end
102         end
103         -- heal absorb
104         current = UnitGetTotalHealAbsorbs(unit) or 0;
105         if current > 0 then
106             current = (current / hmax) * width;
107             frame.healabsorb:SetWidth(min(hwidth, current));
108             if not frame.healabsorb:IsShown() then frame.healabsorb:Show() end
109         elseif frame.healabsorb:IsShown() then
110             frame.healabsorb:Hide();
111         end
112         -- heal prediction
113         current = UnitGetIncomingHeals(unit) or 0;
114         if current > 0 then
115             current = (current / hmax) * width;
116             -- at least 1 pixel prediction shown
117             frame.healpred:SetWidth(min(width - hwidth + 1, current));
118             if not frame.healpred:IsShown() then frame.healpred:Show() end
119         elseif frame.healpred:IsShown() then
120             frame.healpred:Hide();
121         end
122         -- tank CD marker
123         if next(frame.tankcd) then
124             if not frame.defensive:IsShown() then frame.defensive:Show() end
125         elseif frame.defensive:IsShown() then
126             frame.defensive:Hide();
127         end
128         -- aura stacks
129         if next(frame.stacks) then
130             frame.stack:SetText(next(frame.stacks));
131             if not frame.stack:IsShown() then frame.stack:Show() end
132         elseif frame.stack:IsShown() then
133             frame.stack:Hide();
134         end
135         -- overlays
136         if next(frame.alert) then
137             -- major
138             if frame.overlay.color ~= majorcolor then
139                 frame.overlay:SetVertexColor(unpack(majorcolor));
140                 frame.overlay.color = majorcolor;
141                 if not frame.overlay:IsShown() then frame.overlay:Show() end
142             end
143         elseif next(frame.heal) then
144             -- major heals needed
145             if frame.overlay.color ~= healcolor then
146                 frame.overlay:SetVertexColor(unpack(healcolor));
147                 frame.overlay.color = healcolor;
148                 if not frame.overlay:IsShown() then frame.overlay:Show() end
149             end
150         elseif UnitIsCharmed(unit) and frame.unit == frame.displayed then
151             -- charmed
152             if frame.overlay.color ~= charmcolor then
153                 frame.overlay:SetVertexColor(unpack(charmcolor));
154                 frame.overlay.color = charmcolor;
155                 if not frame.overlay:IsShown() then frame.overlay:Show() end
156             end
157         elseif UnitDebuff(unit, 1, "RAID") ~= nil then
158             -- dispellable
159             if frame.overlay.color ~= dispelcolor then
160                 frame.overlay:SetVertexColor(unpack(dispelcolor));
161                 frame.overlay.color = dispelcolor;
162                 if not frame.overlay:IsShown() then frame.overlay:Show() end
163             end
164         else
165             if frame.overlay.color ~= nil then
166                 frame.overlay.color = nil;
167                 if frame.overlay:IsShown() then frame.overlay:Hide() end
168             end
169         end
170     end
171 end