local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB local UF = E:GetModule('UnitFrames'); local CreateFrame = CreateFrame function UF.HealthClipFrame_HealComm(frame) if frame.HealthPrediction then UF:SetAlpha_HealComm(frame.HealthPrediction, 1) UF:SetVisibility_HealComm(frame.HealthPrediction) end end function UF:SetAlpha_HealComm(obj, alpha) obj.myBar:SetAlpha(alpha) obj.otherBar:SetAlpha(alpha) obj.absorbBar:SetAlpha(alpha) obj.healAbsorbBar:SetAlpha(alpha) end function UF:SetTexture_HealComm(obj, texture) obj.myBar:SetStatusBarTexture(texture) obj.otherBar:SetStatusBarTexture(texture) obj.absorbBar:SetStatusBarTexture(texture) obj.healAbsorbBar:SetStatusBarTexture(texture) end function UF:SetVisibility_HealComm(obj) -- the first update is from `HealthClipFrame_HealComm` -- we set this variable to allow `Configure_HealComm` to -- update the elements overflow lock later on by option if not obj.allowClippingUpdate then obj.allowClippingUpdate = true end if obj.maxOverflow > 1 then obj.myBar:SetParent(obj.health) obj.otherBar:SetParent(obj.health) obj.healAbsorbBar:SetParent(obj.health) else obj.myBar:SetParent(obj.parent) obj.otherBar:SetParent(obj.parent) obj.healAbsorbBar:SetParent(obj.parent) end end function UF:Construct_HealComm(frame) local health = frame.Health local parent = health.ClipFrame local myBar = CreateFrame('StatusBar', nil, parent) local otherBar = CreateFrame('StatusBar', nil, parent) local absorbBar = CreateFrame('StatusBar', nil, parent) local healAbsorbBar = CreateFrame('StatusBar', nil, parent) myBar:SetFrameLevel(11) otherBar:SetFrameLevel(11) absorbBar:SetFrameLevel(11) healAbsorbBar:SetFrameLevel(11) local prediction = { myBar = myBar, otherBar = otherBar, absorbBar = absorbBar, healAbsorbBar = healAbsorbBar, PostUpdate = UF.UpdateHealComm, maxOverflow = 1, health = health, parent = parent, frame = frame } UF:SetAlpha_HealComm(prediction, 0) UF:SetTexture_HealComm(prediction, E.media.blankTex) return prediction end function UF:SetSize_HealComm(frame) local health = frame.Health local pred = frame.HealthPrediction local orientation = health:GetOrientation() local db = frame.db.healPrediction local width, height = health:GetSize() if orientation == 'HORIZONTAL' then local barHeight = db.height if barHeight == -1 or barHeight > height then barHeight = height end pred.myBar:Size(width, barHeight) pred.otherBar:Size(width, barHeight) pred.healAbsorbBar:Size(width, barHeight) pred.absorbBar:Size(width, barHeight) else local barWidth = db.height -- this is really width now not height if barWidth == -1 or barWidth > width then barWidth = width end pred.myBar:Size(barWidth, height) pred.otherBar:Size(barWidth, height) pred.healAbsorbBar:Size(barWidth, height) pred.absorbBar:Size(barWidth, height) end end function UF:Configure_HealComm(frame) local db = frame.db.healPrediction if db and db.enable then local pred = frame.HealthPrediction local myBar = pred.myBar local otherBar = pred.otherBar local absorbBar = pred.absorbBar local healAbsorbBar = pred.healAbsorbBar pred.needsSizeUpdated = true local colors = self.db.colors.healPrediction pred.maxOverflow = 1 + (colors.maxOverflow or 0) if pred.allowClippingUpdate then UF:SetVisibility_HealComm(pred) end if not frame:IsElementEnabled('HealthPrediction') then frame:EnableElement('HealthPrediction') end local health = frame.Health local orientation = health:GetOrientation() local reverseFill = health:GetReverseFill() local healthBarTexture = health:GetStatusBarTexture() pred.reverseFill = reverseFill pred.healthBarTexture = healthBarTexture pred.myBarTexture = myBar:GetStatusBarTexture() pred.otherBarTexture = otherBar:GetStatusBarTexture() UF:SetTexture_HealComm(pred, UF.db.colors.transparentHealth and E.media.blankTex or healthBarTexture:GetTexture()) myBar:SetReverseFill(reverseFill) otherBar:SetReverseFill(reverseFill) healAbsorbBar:SetReverseFill(not reverseFill) if db.absorbStyle == 'REVERSED' then absorbBar:SetReverseFill(not reverseFill) else absorbBar:SetReverseFill(reverseFill) end myBar:SetStatusBarColor(colors.personal.r, colors.personal.g, colors.personal.b, colors.personal.a) otherBar:SetStatusBarColor(colors.others.r, colors.others.g, colors.others.b, colors.others.a) absorbBar:SetStatusBarColor(colors.absorbs.r, colors.absorbs.g, colors.absorbs.b, colors.absorbs.a) healAbsorbBar:SetStatusBarColor(colors.healAbsorbs.r, colors.healAbsorbs.g, colors.healAbsorbs.b, colors.healAbsorbs.a) myBar:SetOrientation(orientation) otherBar:SetOrientation(orientation) absorbBar:SetOrientation(orientation) healAbsorbBar:SetOrientation(orientation) if orientation == 'HORIZONTAL' then local p1 = reverseFill and 'RIGHT' or 'LEFT' local p2 = reverseFill and 'LEFT' or 'RIGHT' local anchor = db.anchorPoint pred.anchor, pred.anchor1, pred.anchor2 = anchor, p1, p2 myBar:ClearAllPoints() myBar:Point(anchor, health) myBar:Point(p1, healthBarTexture, p2) otherBar:ClearAllPoints() otherBar:Point(anchor, health) otherBar:Point(p1, pred.myBarTexture, p2) healAbsorbBar:ClearAllPoints() healAbsorbBar:Point(anchor, health) absorbBar:ClearAllPoints() absorbBar:Point(anchor, health) if db.absorbStyle == 'REVERSED' then absorbBar:Point(p2, health, p2) else absorbBar:Point(p1, pred.otherBarTexture, p2) end else local p1 = reverseFill and 'TOP' or 'BOTTOM' local p2 = reverseFill and 'BOTTOM' or 'TOP' local anchor = (db.anchorPoint == 'BOTTOM' and 'RIGHT') or (db.anchorPoint == 'TOP' and 'LEFT') or db.anchorPoint -- convert this for vertical too pred.anchor, pred.anchor1, pred.anchor2 = anchor, p1, p2 myBar:ClearAllPoints() myBar:Point(anchor, health) myBar:Point(p1, healthBarTexture, p2) otherBar:ClearAllPoints() otherBar:Point(anchor, health) otherBar:Point(p1, pred.myBarTexture, p2) healAbsorbBar:ClearAllPoints() healAbsorbBar:Point(anchor, health) absorbBar:ClearAllPoints() absorbBar:Point(anchor, health) if db.absorbStyle == 'REVERSED' then absorbBar:Point(p2, health, p2) else absorbBar:Point(p1, pred.otherBarTexture, p2) end end elseif frame:IsElementEnabled('HealthPrediction') then frame:DisableElement('HealthPrediction') end end function UF:UpdateHealComm(_, _, _, absorb, _, hasOverAbsorb, hasOverHealAbsorb, health, maxHealth) local frame = self.frame local db = frame and frame.db and frame.db.healPrediction if not db or not db.absorbStyle then return end local pred = frame.HealthPrediction local healAbsorbBar = pred.healAbsorbBar local absorbBar = pred.absorbBar if pred.needsSizeUpdated then UF:SetSize_HealComm(frame) pred.needsSizeUpdated = nil end -- absorbs is set to none so hide both and kill code execution if db.absorbStyle == 'NONE' then healAbsorbBar:Hide() absorbBar:Hide() return end local colors = UF.db.colors.healPrediction local maxOverflow = colors.maxOverflow or 0 -- handle over heal absorbs healAbsorbBar:ClearAllPoints() healAbsorbBar:Point(pred.anchor, frame.Health) if hasOverHealAbsorb then -- forward fill it when its greater than health so that you can still see this is being stolen healAbsorbBar:SetReverseFill(pred.reverseFill) healAbsorbBar:Point(pred.anchor1, pred.healthBarTexture, pred.anchor2) healAbsorbBar:SetStatusBarColor(colors.overhealabsorbs.r, colors.overhealabsorbs.g, colors.overhealabsorbs.b, colors.overhealabsorbs.a) else -- otherwise just let it backfill so that we know how much is being stolen healAbsorbBar:SetReverseFill(not pred.reverseFill) healAbsorbBar:Point(pred.anchor2, pred.healthBarTexture, pred.anchor2) healAbsorbBar:SetStatusBarColor(colors.healAbsorbs.r, colors.healAbsorbs.g, colors.healAbsorbs.b, colors.healAbsorbs.a) end -- color absorb bar if in over state if hasOverAbsorb then absorbBar:SetStatusBarColor(colors.overabsorbs.r, colors.overabsorbs.g, colors.overabsorbs.b, colors.overabsorbs.a) else absorbBar:SetStatusBarColor(colors.absorbs.r, colors.absorbs.g, colors.absorbs.b, colors.absorbs.a) end -- if we are in normal mode and overflowing happens we should let a bit show, like blizzard does if db.absorbStyle == 'NORMAL' then if hasOverAbsorb and health == maxHealth then absorbBar:SetValue(1.5) absorbBar:SetMinMaxValues(0, 100) absorbBar:SetParent(pred.health) -- lets overflow happen else absorbBar:SetParent(pred.parent) -- prevents overflow end else if maxOverflow > 0 then absorbBar:SetParent(pred.health) else absorbBar:SetParent(pred.parent) end if hasOverAbsorb then -- non normal mode overflowing if db.absorbStyle == 'WRAPPED' then -- engage backfilling absorbBar:SetReverseFill(not pred.reverseFill) absorbBar:ClearAllPoints() absorbBar:Point(pred.anchor, pred.health) absorbBar:Point(pred.anchor2, pred.health, pred.anchor2) elseif db.absorbStyle == 'OVERFLOW' then -- we need to display the overflow but adjusting the values local overflowAbsorb = absorb * maxOverflow if health == maxHealth then absorbBar:SetValue(overflowAbsorb) else -- fill the inner part along with the overflow amount so it smoothly transitions absorbBar:SetValue((maxHealth - health) + overflowAbsorb) end end elseif db.absorbStyle == 'WRAPPED' then -- restore wrapped to its forward filling state absorbBar:SetReverseFill(pred.reverseFill) absorbBar:ClearAllPoints() absorbBar:Point(pred.anchor, pred.health) absorbBar:Point(pred.anchor1, pred.otherBarTexture, pred.anchor2) end end end