3 local unpack, pairs, ipairs = unpack, pairs, ipairs;
4 local ssub = string.sub;
6 local UnitName, UnitClass = UnitName, UnitClass;
7 local UnitDebuff, UnitIsCharmed = UnitDebuff, UnitIsCharmed;
8 local UnitPower, UnitPowerMax, UnitPowerType = UnitPower, UnitPowerMax, UnitPowerType;
9 local UnitHealth, UnitHealthMax = UnitHealth, UnitHealthMax;
10 local UnitInParty, UnitInRaid = UnitInParty, UnitInRaid;
11 local UnitGetIncomingHeals, UnitGetTotalAbsorbs = UnitGetIncomingHeals, UnitGetTotalAbsorbs;
12 local UnitThreatSituation, GetThreatStatusColor = UnitThreatSituation, GetThreatStatusColor;
13 local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected;
14 local UnitHasIncomingResurrection = UnitHasIncomingResurrection;
15 local UnitGetTotalHealAbsorbs = UnitGetTotalHealAbsorbs;
16 local IsInGroup, IsInRaid = IsInGroup, IsInRaid;
17 local CTimerAfter = C_Timer.After;
18 local RAID_CLASS_COLORS = RAID_CLASS_COLORS;
20 local Frames = OmaFrames;
21 local Indicators = OmaIndicators;
22 local checkIndicators = Indicators.CheckIndicators;
24 local CFrame = CreateFrame("Frame", "OmaCFrame", UIParent);
29 local width, height = Frames.Width, Frames.Height;
30 local anchorX, anchorY = Frames.AnchorX, Frames.AnchorY;
31 local baseColor = Frames.BaseColor;
32 local overlayColorDispel = Frames.OverlayColorDispel;
33 local overlayColorCharm = Frames.OverlayColorCharm;
34 local overlayColorAlert = Frames.OverlayColorAlert;
35 local powerColors = Frames.PowerColors;
37 local function updateHealth(frame, unit)
38 local current, max = UnitHealth(unit), frame.health.max;
39 local healthLost = max - current;
41 -- sanity check, occasionally UnitHealthMax gives zero
43 -- somehow current health has gone over the maximum (missed maxhealth event)
44 frame.health.max = UnitHealthMax(unit);
45 max = frame.health.max;
47 -- error state, still over maximum
48 frame.health:SetWidth(width);
53 frame.health:SetWidth(current/frame.health.max*width);
55 frame.health:SetWidth(width);
60 if UnitIsDeadOrGhost(unit) then
62 if UnitHasIncomingResurrection(unit) then
63 frame.text:SetText("Rez");
65 frame.text:SetText("Dead");
67 elseif not UnitIsConnected(unit) then
69 frame.text:SetText("DC");
70 elseif healthLost > 0 then
71 if healthLost > 1200000000 then -- 1.2B
72 frame.text:SetFormattedText("-%.1fB", healthLost / 1000000000);
73 elseif healthLost > 1200000 then -- 1.2M
74 frame.text:SetFormattedText("-%.1fM", healthLost / 1000000);
75 elseif healthLost > 1000 then -- 1K
76 frame.text:SetFormattedText("-%dK", healthLost / 1000);
78 frame.text:SetFormattedText("-%d", healthLost)
86 local function updateMaxHealth(frame, unit)
87 frame.health.max = UnitHealthMax(unit);
88 updateHealth(frame, unit);
91 local function updatePower(frame, unit)
92 local current, max = UnitPower(unit), frame.mana.max;
93 -- sanity check, occasionally UnitPowerMax gives zero
95 frame.mana.max = UnitPowerMax(unit);
99 frame.mana:SetWidth(width);
103 frame.mana:SetWidth(UnitPower(unit)/max*width);
105 frame.mana:SetWidth(width);
109 local function updateMaxPower(frame, unit)
110 frame.mana.max = UnitPowerMax(unit);
111 updatePower(frame, unit);
114 local function updatePowerColor(frame, unit)
115 frame.mana:SetVertexColor(unpack(powerColors[UnitPowerType(unit)]));
118 local function updateName(frame, unit)
119 local name = UnitName(unit);
120 if not name then return end
121 frame.name:SetText(ssub(name, 1, 6));
123 local _, class = UnitClass(unit);
124 local color = RAID_CLASS_COLORS[class];
125 if color then frame.name:SetVertexColor(color.r, color.g, color.b) end
128 local function updateHealPred(frame, unit)
129 local incoming = UnitGetIncomingHeals(unit) or 0;
131 local max = frame.health.max;
132 local space = width - frame.health:GetWidth() + 1;
133 local pred = (incoming / max) * width;
134 frame.healpred:SetWidth(min(space, pred));
135 frame.healpred:Show();
137 frame.healpred:Hide();
141 local function updateShield(frame, unit)
142 local shield = UnitGetTotalAbsorbs(unit) or 0;
144 local max = frame.health.max;
145 local space = width - frame.health:GetWidth();
146 shield = (shield / max) * width;
147 if space < shield then
148 frame.shield:SetWidth(space);
149 frame.shieldhl:Show();
151 frame.shield:SetWidth(shield);
152 frame.shieldhl:Hide();
157 frame.shieldhl:Hide();
161 local function updateHealAbsorb(frame, unit)
162 local absorb = UnitGetTotalHealAbsorbs(unit) or 0;
164 local max = frame.health.max;
165 local space = frame.health:GetWidth();
166 absorb = (absorb / max) * width;
167 frame.healabsorb:SetWidth(min(space, absorb));
168 frame.healabsorb:Show();
170 frame.healabsorb:Hide();
174 local function updateAuras(frame, unit)
175 checkIndicators(frame, unit);
176 if UnitDebuff(unit, 1, "RAID") ~= nil then
177 -- something dispellable
178 if frame.overlay.color ~= overlayColorDispel then
179 frame.overlay:SetVertexColor(unpack(overlayColorDispel));
180 frame.overlay:Show();
181 frame.overlay.color = overlayColorDispel;
183 elseif UnitIsCharmed(unit) then
184 if frame.overlay.color ~= overlayColorCharm then
185 frame.overlay:SetVertexColor(unpack(overlayColorCharm));
186 frame.overlay:Show();
187 frame.overlay.color = overlayColorCharm;
190 if frame.overlay.color ~= nil then
191 frame.overlay:Hide();
192 frame.overlay.color = nil;
197 local function updateAggro(frame, unit)
198 local status = UnitThreatSituation(unit);
199 if status and status > 0 then
200 frame.base:SetVertexColor(GetThreatStatusColor(status));
202 frame.base:SetVertexColor(unpack(baseColor));
207 ["UNIT_HEALTH"] = function(frame, unit)
208 updateHealth(frame, unit);
209 updateShield(frame, unit);
210 updateHealAbsorb(frame, unit);
211 -- no heal prediction update, that doesn't overflow too much
213 ["UNIT_POWER"] = function(frame, unit)
214 updatePower(frame, unit);
216 ["UNIT_AURA"] = function(frame, unit)
217 updateAuras(frame, unit);
219 ["UNIT_HEAL_PREDICTION"] = function(frame, unit)
220 updateHealPred(frame, unit);
222 ["UNIT_ABSORB_AMOUNT_CHANGED"] = function(frame, unit)
223 updateShield(frame, unit);
225 ["UNIT_HEAL_ABSORB_AMOUNT_CHANGED"] = function(frame, unit)
226 updateHealAbsorb(frame, unit);
228 ["UNIT_THREAT_SITUATION_UPDATE"] = function(frame, unit)
229 updateAggro(frame, unit);
231 ["UNIT_MAXHEALTH"] = function(frame, unit)
232 updateMaxHealth(frame, unit);
234 ["UNIT_MAXPOWER"] = function(frame, unit)
235 updateMaxPower(frame, unit);
237 ["UNIT_DISPLAYPOWER"] = function(frame, unit)
238 updatePowerColor(frame, unit);
240 ["UNIT_NAME_UPDATE"] = function(frame, unit)
241 updateName(frame, unit);
243 ["UNIT_CONNECTION"] = function(frame, unit)
244 updateHealth(frame, unit);
246 ["INCOMING_RESURRECT_CHANGED"] = function(frame, unit)
248 updateHealth(frame, unit);
250 ["PARTY_MEMBER_ENABLE"] = function(frame)
251 -- new power info possibly (FrameXML/CompactUnitFrame.lua)
252 updateMaxPower(frame, frame.unit);
253 updatePowerColor(frame, frame.unit);
255 ["UPDATE_ALL_BARS"] = function(frame, unit)
256 updateMaxHealth(frame, unit);
257 updateMaxPower(frame, unit);
258 --updateHealth(frame, unit); -- MaxHealth covers this
259 --updatePower(frame, unit); -- MaxPower covers this
260 updateAuras(frame, unit);
261 updateShield(frame, unit);
262 updateHealPred(frame, unit);
263 updateHealAbsorb(frame, unit);
264 updatePowerColor(frame, unit);
265 updateAggro(frame, unit);
266 updateName(frame, unit);
269 eventFuncs["UNIT_HEALTH_FREQUENT"] = eventFuncs["UNIT_HEALTH"];
270 eventFuncs["PARTY_MEMBER_DISABLE"] = eventFuncs["PARTY_MEMBER_ENABLE"];
271 local function unitEvent(self, event, ...)
272 local arg1, arg2, arg3, arg4 = ...;
273 eventFuncs[event](self, arg1);
276 local function initialize()
277 CFrame:SetPoint("CENTER", nil, "CENTER", anchorX, anchorY);
278 CFrame:SetHeight((height+2)*8);
279 CFrame:SetWidth((width+2)*5+1); -- extra pixel for shield overflow
280 Frames.InitializeParty(CFrame, party, unitEvent);
281 Frames.InitializeRaid(CFrame, raid, unitEvent);
284 CFrame:RegisterEvent("ADDON_LOADED");
285 CFrame:RegisterEvent("PLAYER_LOGIN");
286 CFrame:RegisterEvent("PLAYER_ENTERING_WORLD");
287 CFrame:RegisterEvent("GROUP_ROSTER_UPDATE");
288 CFrame:RegisterEvent("PLAYER_REGEN_ENABLED");
289 CFrame:SetScript("OnEvent", function(self, event, ...)
290 if event == "GROUP_ROSTER_UPDATE" or event == "PLAYER_REGEN_ENABLED" or
291 event == "PLAYER_ENTERING_WORLD" then
293 elseif event == "PLAYER_LOGIN" then
295 elseif event == "ADDON_LOADED" then