2 -- 2019 Aleksi Blinnikka
4 -- Main update function for all frames. Gets around issues with events.
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;
15 local dispelcolor = addon.Colors.OverlayColorDispel;
16 local charmcolor = addon.Colors.OverlayColorCharm;
17 local majorcolor = addon.Colors.OverlayColorAlert;
18 local healcolor = addon.Colors.OverlayColorHeal;
20 function addon.FrameUpdate(frame)
21 assert(type(frame) == "table", "FrameUpdate received invalid frame parameter!");
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
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;
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
61 if frame.text:IsShown() then frame.text:Hide() end
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
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
82 local hwidth = frame.health.width;
83 current = UnitGetTotalAbsorbs(unit) or 0;
85 local space = width - hwidth;
86 current = (current / hmax) * width;
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
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
100 if frame.shield:IsShown() then frame.shield:Hide() end
101 if frame.shieldhl:IsShown() then frame.shieldhl:Hide() end
104 current = UnitGetTotalHealAbsorbs(unit) or 0;
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();
113 current = UnitGetIncomingHeals(unit) or 0;
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();
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();
129 if next(frame.stacks) then
130 local _, amount = next(frame.stacks);
131 frame.stack:SetText(amount);
132 if not frame.stack:IsShown() then frame.stack:Show() end
133 elseif frame.stack:IsShown() then
137 if next(frame.alert) then
139 if frame.overlay.color ~= majorcolor then
140 frame.overlay:SetVertexColor(unpack(majorcolor));
141 frame.overlay.color = majorcolor;
142 if not frame.overlay:IsShown() then frame.overlay:Show() end
144 elseif UnitDebuff(unit, 1, "RAID") ~= nil then
146 if frame.overlay.color ~= dispelcolor then
147 frame.overlay:SetVertexColor(unpack(dispelcolor));
148 frame.overlay.color = dispelcolor;
149 if not frame.overlay:IsShown() then frame.overlay:Show() end
151 elseif UnitIsCharmed(unit) and frame.unit == frame.displayed then
153 if frame.overlay.color ~= charmcolor then
154 frame.overlay:SetVertexColor(unpack(charmcolor));
155 frame.overlay.color = charmcolor;
156 if not frame.overlay:IsShown() then frame.overlay:Show() end
158 elseif next(frame.heal) then
159 -- major heals needed
160 if frame.overlay.color ~= healcolor then
161 frame.overlay:SetVertexColor(unpack(healcolor));
162 frame.overlay.color = healcolor;
163 if not frame.overlay:IsShown() then frame.overlay:Show() end
166 if frame.overlay.color ~= nil then
167 frame.overlay.color = nil;
168 if frame.overlay:IsShown() then frame.overlay:Hide() end