3d7b873aa9
* HealComm - Absorb, HealAbsorb * HealComm - Unify all bars
419 lines
14 KiB
Lua
419 lines
14 KiB
Lua
local E, L, V, P, G = unpack(ElvUI)
|
|
local NP = E:GetModule('NamePlates')
|
|
local UF = E:GetModule('UnitFrames')
|
|
local LSM = E.Libs.LSM
|
|
|
|
local ipairs = ipairs
|
|
local unpack = unpack
|
|
local UnitPlayerControlled = UnitPlayerControlled
|
|
local UnitClass = UnitClass
|
|
local UnitReaction = UnitReaction
|
|
local UnitIsConnected = UnitIsConnected
|
|
local CreateFrame = CreateFrame
|
|
local UnitIsTapped = UnitIsTapped
|
|
local UnitIsTappedByPlayer = UnitIsTappedByPlayer
|
|
local UnitIsDeadOrGhost = UnitIsDeadOrGhost
|
|
local UnitIsPlayer = UnitIsPlayer
|
|
|
|
function NP:Health_UpdateColor(_, unit)
|
|
if not unit or self.unit ~= unit then return end
|
|
local element = self.Health
|
|
|
|
local r, g, b, t
|
|
if element.colorDisconnected and not UnitIsConnected(unit) then
|
|
t = self.colors.disconnected
|
|
elseif (element.colorClass and self.isPlayer) or (element.colorClassNPC and not self.isPlayer) or (element.colorClassPet and UnitPlayerControlled(unit) and not self.isPlayer) then
|
|
local _, class = UnitClass(unit)
|
|
t = self.colors.class[class]
|
|
elseif element.colorReaction and UnitReaction(unit, 'player') then
|
|
local reaction = UnitReaction(unit, 'player')
|
|
t = NP.db.colors.reactions[reaction == 4 and 'neutral' or reaction <= 3 and 'bad' or 'good']
|
|
elseif element.colorSmooth then
|
|
r, g, b = self:ColorGradient(element.cur or 1, element.max or 1, unpack(element.smoothGradient or self.colors.smooth))
|
|
elseif element.colorHealth then
|
|
t = NP.db.colors.health
|
|
end
|
|
|
|
if t then
|
|
r, g, b = t.r, t.g, t.b
|
|
element.r, element.g, element.b = r, g, b -- save these for the style filter to switch back
|
|
end
|
|
|
|
local db = NP:PlateDB(self)
|
|
if db.greyTappedTargets and UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) and not UnitIsPlayer(unit) and not UnitIsDeadOrGhost(unit) then
|
|
r, g, b = 0.5, 0.5, 0.5
|
|
element.r, element.g, element.b = r, g, b
|
|
end
|
|
|
|
local sf = NP:StyleFilterChanges(self)
|
|
if sf.HealthColor then
|
|
r, g, b = sf.HealthColor.r, sf.HealthColor.g, sf.HealthColor.b
|
|
end
|
|
|
|
if b then
|
|
element:SetStatusBarColor(r, g, b)
|
|
|
|
if element.bg then
|
|
element.bg:SetVertexColor(r * NP.multiplier, g * NP.multiplier, b * NP.multiplier)
|
|
end
|
|
end
|
|
|
|
if element.PostUpdateColor then
|
|
element:PostUpdateColor(unit, r, g, b)
|
|
end
|
|
end
|
|
|
|
function NP:Construct_Health(nameplate)
|
|
local Health = CreateFrame('StatusBar', nameplate:GetName()..'Health', nameplate)
|
|
Health:SetParent(nameplate)
|
|
Health:CreateBackdrop('Transparent', nil, nil, nil, nil, true, true)
|
|
Health:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
|
Health.considerSelectionInCombatHostile = true
|
|
Health.UpdateColor = NP.Health_UpdateColor
|
|
|
|
NP.StatusBars[Health] = true
|
|
|
|
local statusBarTexture = Health:GetStatusBarTexture()
|
|
local healthFlashTexture = Health:CreateTexture(nameplate:GetName()..'FlashTexture', 'OVERLAY')
|
|
healthFlashTexture:SetTexture(LSM:Fetch('background', 'ElvUI Blank'))
|
|
healthFlashTexture:Point('BOTTOMLEFT', statusBarTexture, 'BOTTOMLEFT')
|
|
healthFlashTexture:Point('TOPRIGHT', statusBarTexture, 'TOPRIGHT')
|
|
healthFlashTexture:Hide()
|
|
nameplate.HealthFlashTexture = healthFlashTexture
|
|
|
|
local clipFrame = CreateFrame("Frame", nil, Health)
|
|
clipFrame:SetScript("OnUpdate", UF.HealthClipFrame_OnUpdate)
|
|
clipFrame:SetAllPoints()
|
|
clipFrame:EnableMouse(false)
|
|
clipFrame.__frame = Health
|
|
Health.ClipFrame = clipFrame
|
|
|
|
return Health
|
|
end
|
|
|
|
function NP:Health_SetColors(nameplate, threatColors)
|
|
if threatColors then -- managed by ThreatIndicator_PostUpdate
|
|
nameplate.Health:SetColorTapping(nil)
|
|
nameplate.Health:SetColorSelection(nil)
|
|
nameplate.Health.colorReaction = nil
|
|
nameplate.Health.colorClass = nil
|
|
else
|
|
local db = NP:PlateDB(nameplate)
|
|
nameplate.Health:SetColorTapping(true)
|
|
nameplate.Health:SetColorSelection(true)
|
|
nameplate.Health.colorReaction = true
|
|
nameplate.Health.colorClass = db.health and db.health.useClassColor
|
|
end
|
|
end
|
|
|
|
function NP:Update_Health(nameplate, skipUpdate)
|
|
local db = NP:PlateDB(nameplate)
|
|
|
|
NP:Health_SetColors(nameplate)
|
|
|
|
if skipUpdate then return end
|
|
|
|
if db.health.enable then
|
|
if not nameplate:IsElementEnabled('Health') then
|
|
nameplate:EnableElement('Health')
|
|
end
|
|
|
|
nameplate.Health:Point('CENTER')
|
|
nameplate.Health:Point('LEFT')
|
|
nameplate.Health:Point('RIGHT')
|
|
|
|
E:SetSmoothing(nameplate.Health, NP.db.smoothbars)
|
|
elseif nameplate:IsElementEnabled('Health') then
|
|
nameplate:DisableElement('Health')
|
|
end
|
|
|
|
nameplate.Health.width = db.health.width
|
|
nameplate.Health.height = db.health.height
|
|
nameplate.Health:Height(db.health.height)
|
|
end
|
|
|
|
function NP:Update_HealComm(nameplate)
|
|
local db = NP:PlateDB(nameplate)
|
|
|
|
if db.health.enable and db.health.healPrediction then
|
|
if not nameplate:IsElementEnabled('HealCommBar') then
|
|
nameplate:EnableElement('HealCommBar')
|
|
end
|
|
|
|
local c = NP.db.colors.healPrediction
|
|
nameplate.HealCommBar.myBar:SetStatusBarColor(c.personal.r, c.personal.g, c.personal.b)
|
|
nameplate.HealCommBar.otherBar:SetStatusBarColor(c.others.r, c.others.g, c.others.b)
|
|
|
|
if nameplate.HealCommBar.absorbBar then
|
|
nameplate.HealCommBar.absorbBar:SetStatusBarColor(c.absorbs.r, c.absorbs.g, c.absorbs.b, c.absorbs.a)
|
|
end
|
|
|
|
if nameplate.HealCommBar.healAbsorbBar then
|
|
nameplate.HealCommBar.healAbsorbBar:SetStatusBarColor(c.healAbsorbs.r, c.healAbsorbs.g, c.healAbsorbs.b, c.healAbsorbs.a)
|
|
end
|
|
|
|
if nameplate.HealCommBar.overAbsorb then
|
|
nameplate.HealCommBar.overAbsorb:SetVertexColor(c.overAbsorbs.r, c.overAbsorbs.g, c.overAbsorbs.b, c.overAbsorbs.a)
|
|
end
|
|
|
|
if nameplate.HealCommBar.overHealAbsorb then
|
|
nameplate.HealCommBar.overHealAbsorb:SetVertexColor(c.overHealAbsorbs.r, c.overHealAbsorbs.g, c.overHealAbsorbs.b, c.overHealAbsorbs.a)
|
|
end
|
|
elseif nameplate:IsElementEnabled('HealCommBar') then
|
|
nameplate:DisableElement('HealCommBar')
|
|
end
|
|
end
|
|
|
|
function NP.HealthClipFrame_HealComm(frame)
|
|
local pred = frame.HealCommBar
|
|
if pred then
|
|
NP:SetAlpha_HealComm(pred, true)
|
|
NP:SetVisibility_HealComm(pred)
|
|
end
|
|
end
|
|
|
|
function NP:SetAlpha_HealComm(obj, show)
|
|
obj.myBar:SetAlpha(show and 1 or 0)
|
|
obj.otherBar:SetAlpha(show and 1 or 0)
|
|
if obj.absorbBar then
|
|
obj.absorbBar:SetAlpha(show and 1 or 0)
|
|
end
|
|
if obj.healAbsorbBar then
|
|
obj.healAbsorbBar:SetAlpha(show and 1 or 0)
|
|
end
|
|
end
|
|
|
|
function NP: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)
|
|
if obj.absorbBar then
|
|
obj.absorbBar:SetParent(obj.health)
|
|
end
|
|
if obj.healAbsorbBar then
|
|
obj.healAbsorbBar:SetParent(obj.health)
|
|
end
|
|
else
|
|
obj.myBar:SetParent(obj.parent)
|
|
obj.otherBar:SetParent(obj.parent)
|
|
if obj.absorbBar then
|
|
obj.absorbBar:SetParent(obj.parent)
|
|
end
|
|
if obj.healAbsorbBar then
|
|
obj.healAbsorbBar:SetParent(obj.parent)
|
|
end
|
|
end
|
|
end
|
|
|
|
function NP:Construct_HealComm(frame)
|
|
local health = frame.Health
|
|
local parent = health.ClipFrame
|
|
|
|
local myBar = E:CreateReversibleStatusBar(nil, parent)
|
|
local otherBar = E:CreateReversibleStatusBar(nil, parent)
|
|
local absorbBar = E:CreateReversibleStatusBar(nil, parent)
|
|
local healAbsorbBar = E:CreateReversibleStatusBar(nil, parent)
|
|
|
|
myBar:SetFrameLevel(health:GetFrameLevel()+2)
|
|
otherBar:SetFrameLevel(health:GetFrameLevel()+2)
|
|
absorbBar:SetFrameLevel(health:GetFrameLevel()+2)
|
|
healAbsorbBar:SetFrameLevel(health:GetFrameLevel()+2)
|
|
|
|
local texture = health:GetStatusBarTexture() or E.media.blankTex
|
|
myBar:SetStatusBarTexture(texture)
|
|
otherBar:SetStatusBarTexture(texture)
|
|
absorbBar:SetStatusBarTexture(texture)
|
|
healAbsorbBar:SetStatusBarTexture(texture)
|
|
|
|
local healPrediction = {
|
|
myBar = myBar,
|
|
otherBar = otherBar,
|
|
absorbBar = absorbBar,
|
|
healAbsorbBar = healAbsorbBar,
|
|
PostUpdate = NP.UpdateHealComm,
|
|
maxOverflow = 1,
|
|
health = health,
|
|
parent = parent,
|
|
frame = frame
|
|
}
|
|
|
|
NP:SetAlpha_HealComm(healPrediction)
|
|
|
|
return healPrediction
|
|
end
|
|
|
|
function NP:Configure_HealComm(frame)
|
|
local db = NP:PlateDB(frame)
|
|
|
|
if db.health.enable and db.health.healPrediction then
|
|
if not frame:IsElementEnabled('HealComm4') then
|
|
frame:EnableElement('HealComm4')
|
|
end
|
|
|
|
local healPrediction = frame.HealCommBar
|
|
local myBar = healPrediction.myBar
|
|
local otherBar = healPrediction.otherBar
|
|
local absorbBar = healPrediction.absorbBar
|
|
local healAbsorbBar = healPrediction.healAbsorbBar
|
|
local c = db.colors.healPrediction
|
|
|
|
healPrediction.maxOverflow = 1 + (c.maxOverflow or 0)
|
|
healPrediction.overflowHeals = c.overflowHeals
|
|
healPrediction.overflowAbsorbs = c.overflowAbsorbs
|
|
|
|
if healPrediction.allowClippingUpdate then
|
|
NP:SetVisibility_HealComm(healPrediction)
|
|
end
|
|
|
|
local health = frame.Health
|
|
local orientation = health:GetOrientation()
|
|
local healthTexture = health:GetStatusBarTexture()
|
|
local width = health:GetWidth()
|
|
width = (width > 0 and width) or health.WIDTH
|
|
local height = health:GetHeight()
|
|
height = (height > 0 and height) or health.HEIGHT
|
|
|
|
healPrediction.healthBarTexture = healthTexture
|
|
healPrediction.myBarTexture = myBar:GetStatusBarTexture()
|
|
healPrediction.otherBarTexture = otherBar:GetStatusBarTexture()
|
|
|
|
myBar:SetOrientation(orientation)
|
|
otherBar:SetOrientation(orientation)
|
|
absorbBar:SetOrientation(orientation)
|
|
healAbsorbBar:SetOrientation(orientation)
|
|
|
|
if orientation == "HORIZONTAL" then
|
|
local p1 = "LEFT"
|
|
local p2 = "RIGHT"
|
|
|
|
healPrediction.anchor1 = p1
|
|
healPrediction.anchor2 = p2
|
|
|
|
myBar:SetSize(width, height)
|
|
myBar:ClearAllPoints()
|
|
myBar:Point("TOP", health)
|
|
myBar:Point("BOTTOM", health)
|
|
myBar:Point(p1, healthTexture, p2)
|
|
myBar:SetReverseFill(false)
|
|
|
|
otherBar:SetSize(width, height)
|
|
otherBar:ClearAllPoints()
|
|
otherBar:Point("TOP", health)
|
|
otherBar:Point("BOTTOM", health)
|
|
otherBar:Point(p1, healPrediction.myBarTexture, p2)
|
|
otherBar:SetReverseFill(false)
|
|
|
|
absorbBar:SetSize(width, height)
|
|
absorbBar:ClearAllPoints()
|
|
absorbBar:Point("TOP", health)
|
|
absorbBar:Point("BOTTOM", health)
|
|
absorbBar:Point(p1, healthTexture, p2)
|
|
absorbBar:SetReverseFill(false)
|
|
|
|
healAbsorbBar:SetSize(width, height)
|
|
healAbsorbBar:ClearAllPoints()
|
|
healAbsorbBar:Point("TOP", health)
|
|
healAbsorbBar:Point("BOTTOM", health)
|
|
healAbsorbBar:Point(p2, healthTexture, p2)
|
|
healAbsorbBar:SetReverseFill(true)
|
|
else -- VERTICAL
|
|
local p1 = "BOTTOM"
|
|
local p2 = "TOP"
|
|
|
|
healPrediction.anchor1 = p1
|
|
healPrediction.anchor2 = p2
|
|
|
|
myBar:SetSize(width, height)
|
|
myBar:ClearAllPoints()
|
|
myBar:Point("LEFT", health)
|
|
myBar:Point("RIGHT", health)
|
|
myBar:Point(p1, healthTexture, p2)
|
|
myBar:SetReverseFill(false)
|
|
|
|
otherBar:SetSize(width, height)
|
|
otherBar:ClearAllPoints()
|
|
otherBar:Point("LEFT", health)
|
|
otherBar:Point("RIGHT", health)
|
|
otherBar:Point(p1, healPrediction.myBarTexture, p2)
|
|
otherBar:SetReverseFill(false)
|
|
|
|
absorbBar:SetSize(width, height)
|
|
absorbBar:ClearAllPoints()
|
|
absorbBar:Point("LEFT", health)
|
|
absorbBar:Point("RIGHT", health)
|
|
absorbBar:Point(p1, healthTexture, p2)
|
|
absorbBar:SetReverseFill(false)
|
|
|
|
healAbsorbBar:SetSize(width, height)
|
|
healAbsorbBar:ClearAllPoints()
|
|
healAbsorbBar:Point("LEFT", health)
|
|
healAbsorbBar:Point("RIGHT", health)
|
|
healAbsorbBar:Point(p2, healthTexture, p2)
|
|
healAbsorbBar:SetReverseFill(true)
|
|
end
|
|
|
|
local hpc = NP.db.colors.healPrediction
|
|
frame.HealCommBar.myBar:SetStatusBarColor(hpc.personal.r, hpc.personal.g, hpc.personal.b)
|
|
frame.HealCommBar.otherBar:SetStatusBarColor(hpc.others.r, hpc.others.g, hpc.others.b)
|
|
frame.HealCommBar.absorbBar:SetStatusBarColor(hpc.absorbs.r, hpc.absorbs.g, hpc.absorbs.b, hpc.absorbs.a)
|
|
frame.HealCommBar.healAbsorbBar:SetStatusBarColor(hpc.healAbsorbs.r, hpc.healAbsorbs.g, hpc.healAbsorbs.b, hpc.healAbsorbs.a)
|
|
elseif frame:IsElementEnabled('HealComm4') then
|
|
frame:DisableElement('HealComm4')
|
|
end
|
|
end
|
|
|
|
local function AnchorPredictionBar(bar, health, orientation, anchorTexture, hasEnoughSpace, overflowMode, p1, p2, reverseAnchorTexture)
|
|
bar:ClearAllPoints()
|
|
|
|
if orientation == "HORIZONTAL" then
|
|
bar:Point("TOP", health)
|
|
bar:Point("BOTTOM", health)
|
|
else -- VERTICAL
|
|
bar:Point("LEFT", health)
|
|
bar:Point("RIGHT", health)
|
|
end
|
|
|
|
if overflowMode then
|
|
bar:Point(p1, anchorTexture, p2)
|
|
bar:SetReverseFill(false)
|
|
elseif hasEnoughSpace then
|
|
bar:Point(p1, anchorTexture, p2)
|
|
bar:SetReverseFill(false)
|
|
else
|
|
local reverseAnchor = reverseAnchorTexture or health
|
|
bar:Point(p2, reverseAnchor, p2)
|
|
bar:SetReverseFill(true)
|
|
end
|
|
end
|
|
|
|
function NP:UpdateHealComm(unit, myIncomingHeal, allIncomingHeal, totalAbsorb, myCurrentHealAbsorb, allHealAbsorb)
|
|
if not self.frame or not self.health then return end
|
|
|
|
local health = self.health
|
|
local healthTexture = self.healthBarTexture or health:GetStatusBarTexture()
|
|
local orientation = health:GetOrientation()
|
|
|
|
local currentHealth = UnitHealth(unit) or 0
|
|
local maxHealth = UnitHealthMax(unit) or 1
|
|
local missingHealth = maxHealth - currentHealth
|
|
local otherIncomingHeal = allIncomingHeal - myIncomingHeal
|
|
local totalIncomingHeal = myIncomingHeal + otherIncomingHeal
|
|
|
|
local p1 = self.anchor1 or (orientation == "HORIZONTAL" and "LEFT" or "BOTTOM")
|
|
local p2 = self.anchor2 or (orientation == "HORIZONTAL" and "RIGHT" or "TOP")
|
|
|
|
local overflowHeals = self.overflowHeals or false
|
|
local overflowAbsorbs = self.overflowAbsorbs or false
|
|
|
|
AnchorPredictionBar(self.myBar, health, orientation, healthTexture, missingHealth >= myIncomingHeal, overflowHeals, p1, p2)
|
|
AnchorPredictionBar(self.otherBar, health, orientation, self.myBarTexture, missingHealth >= totalIncomingHeal, overflowHeals, p1, p2)
|
|
AnchorPredictionBar(self.absorbBar, health, orientation, healthTexture, missingHealth >= totalAbsorb, overflowAbsorbs, p1, p2)
|
|
AnchorPredictionBar(self.healAbsorbBar, health, orientation, healthTexture, false, false, p1, p2, healthTexture)
|
|
end |