+-- updater.lua
+-- 2019 Aleksi Blinnikka
+--
+-- Main update function for all frames. Gets around issues with events.
+local _, addon = ...;
+local unpack = unpack;
+local min = math.min;
+local UnitDebuff, UnitIsCharmed = UnitDebuff, UnitIsCharmed;
+local UnitHealth, UnitHealthMax = UnitHealth, UnitHealthMax;
+local UnitIsAFK, UnitIsDND = UnitIsAFK, UnitIsDND;
+local UnitGetIncomingHeals, UnitGetTotalAbsorbs = UnitGetIncomingHeals, UnitGetTotalAbsorbs;
+local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected;
+local UnitGetTotalHealAbsorbs = UnitGetTotalHealAbsorbs;
+
+local dispelcolor = addon.Colors.OverlayColorDispel;
+local charmcolor = addon.Colors.OverlayColorCharm;
+local majorcolor = addon.Colors.OverlayColorAlert;
+
+local function updateAuras()
+ -- TODO
+ return false;
+end
+
+function addon.FrameUpdate(frame)
+ assert(type(frame) == "table", "FrameUpdate received invalid frame parameter!");
+
+ local unit = frame.displayed;
+ local width = frame.barwidth;
+ -- range check (doesn't have an event)
+ local inrange, checked = UnitInRange(unit);
+ if checked and not inrange then
+ frame:SetAlpha(0.55);
+ else
+ frame:SetAlpha(1);
+ end
+ -- states
+ if UnitIsDeadOrGhost(unit) then
+ frame.text:SetText("Dead");
+ if not frame.text:IsShown() then frame.text:Show() end
+ if frame.health:IsShown() then frame.health:Hide() end
+ if frame.shield:IsShown() then frame.shield:Hide() end
+ if frame.healpred:IsShown() then frame.healpred:Hide() end
+ if frame.healabsorb:IsShown() then frame.healabsorb:Hide() end
+ --if frame.auras:IsShown() then frame.auras:Hide() end
+ elseif not UnitIsConnected(unit) then
+ frame.text:SetText("DC");
+ if not frame.text:IsShown() then frame.text:Show() end
+ if frame.health:IsShown() then frame.health:Hide() end
+ if frame.shield:IsShown() then frame.shield:Hide() end
+ if frame.healpred:IsShown() then frame.healpred:Hide() end
+ if frame.healabsorb:IsShown() then frame.healabsorb:Hide() end
+ --if frame.auras:IsShown() then frame.auras:Hide() end
+ else
+ if UnitIsAFK(unit) then
+ frame.text:SetText("afk");
+ if not frame.text:IsShown() then frame.text:Show() end
+ elseif UnitIsDND(unit) then
+ frame.text:SetText("dnd");
+ if not frame.text:IsShown() then frame.text:Show() end
+ else
+ if frame.text:IsShown() then frame.text:Hide() end
+ end
+ -- health
+ local current, hmax = UnitHealth(unit), UnitHealthMax(unit);
+ if frame.prev.health ~= current or frame.prev.hmax ~= hmax then
+ frame.prev.health = current;
+ frame.prev.hmax = hmax;
+ if hmax < current or hmax <= 1 then
+ frame.health:SetWidth(width);
+ frame.health.width = width;
+ if not frame.health:IsShown() then frame.health:Show() end
+ elseif current <= 0 then
+ if frame.health:IsShown() then frame.health:Hide() end
+ else
+ local w = current/hmax*width;
+ frame.health:SetWidth(w);
+ frame.health.width = w;
+ if not frame.health:IsShown() then frame.health:Show() end
+ end
+ end
+ -- shield
+ local hwidth = frame.health.width;
+ current = UnitGetTotalAbsorbs(unit) or 0;
+ if current > 0 then
+ local space = width - hwidth;
+ current = (current / hmax) * width;
+ if space == 0 then
+ if frame.shield:IsShown() then frame.shield:Hide() end
+ if not frame.shieldhl:IsShown() then frame.shieldhl:Show() end
+ elseif space < current then
+ frame.shield:SetWidth(space);
+ if not frame.shield:IsShown() then frame.shield:Show() end
+ if not frame.shieldhl:IsShown() then frame.shieldhl:Show() end
+ else
+ frame.shield:SetWidth(current);
+ if not frame.shield:IsShown() then frame.shield:Show() end
+ if frame.shieldhl:IsShown() then frame.shieldhl:Hide() end
+ end
+ else
+ if frame.shield:IsShown() then frame.shield:Hide() end
+ if frame.shieldhl:IsShown() then frame.shieldhl:Hide() end
+ end
+ -- heal absorb
+ current = UnitGetTotalHealAbsorbs(unit) or 0;
+ if current > 0 then
+ current = (current / hmax) * width;
+ frame.healabsorb:SetWidth(min(hwidth, current));
+ if not frame.healabsorb:IsShown() then frame.healabsorb:Show() end
+ elseif frame.healabsorb:IsShown() then
+ frame.healabsorb:Hide();
+ end
+ -- heal prediction
+ current = UnitGetIncomingHeals(unit) or 0;
+ if current > 0 then
+ current = (current / hmax) * width;
+ -- at least 1 pixel prediction shown
+ frame.healpred:SetWidth(min(width - hwidth + 1, current));
+ if not frame.healpred:IsShown() then frame.healpred:Show() end
+ elseif frame.healpred:IsShown() then
+ frame.healpred:Hide();
+ end
+ -- auras
+ if updateAuras(frame, unit) then
+ -- major
+ if frame.overlay.color ~= majorcolor then
+ frame.overlay:SetVertexColor(unpack(majorcolor));
+ frame.overlay.color = majorcolor;
+ if not frame.overlay:IsShown() then frame.overlay:Show() end
+ end
+ elseif UnitIsCharmed(unit) and frame.unit == frame.displayed then
+ -- charmed
+ if frame.overlay.color ~= charmcolor then
+ frame.overlay:SetVertexColor(unpack(charmcolor));
+ frame.overlay.color = charmcolor;
+ if not frame.overlay:IsShown() then frame.overlay:Show() end
+ end
+ elseif UnitDebuff(unit, 1, "RAID") ~= nil then
+ -- dispellable
+ if frame.overlay.color ~= dispelcolor then
+ frame.overlay:SetVertexColor(unpack(dispelcolor));
+ frame.overlay.color = dispelcolor;
+ if not frame.overlay:IsShown() then frame.overlay:Show() end
+ end
+ else
+ if frame.overlay.color ~= nil then
+ frame.overlay.color = nil;
+ if frame.overlay:IsShown() then frame.overlay:Hide() end
+ end
+ end
+ end
+end