Files
coa-elvui/ElvUI/Libraries/oUF_Plugins/oUF_HealComm4/oUF_HealComm4.lua
T
scorpzor 3d456d036a Add absorbs, heal absorbs (#90)
* HealComm - Absorb, HealAbsorb

* HealComm - Unify all bars
2025-12-24 16:09:40 -07:00

249 lines
7.0 KiB
Lua

--[[
# Element: Health Prediction Bars
Handles the visibility and updating of incoming heals and heal/damage absorbs.
## Widget
HealthPrediction - A `table` containing references to sub-widgets and options.
## Sub-Widgets
myBar - A `StatusBar` used to represent incoming heals from the player.
otherBar - A `StatusBar` used to represent incoming heals from others.
## Notes
A default texture will be applied to the StatusBar widgets if they don't have a texture set.
A default texture will be applied to the Texture widgets if they don't have a texture or a color set.
## Options
.maxOverflow - The maximum amount of overflow past the end of the health bar. Set this to 1 to disable the overflow.
Defaults to 1.05 (number)
## Examples
-- Position and size
local myBar = CreateFrame('StatusBar', nil, self.Health)
myBar:SetPoint('TOP')
myBar:SetPoint('BOTTOM')
myBar:SetPoint('LEFT', self.Health:GetStatusBarTexture(), 'RIGHT')
myBar:SetWidth(200)
local otherBar = CreateFrame('StatusBar', nil, self.Health)
otherBar:SetPoint('TOP')
otherBar:SetPoint('BOTTOM')
otherBar:SetPoint('LEFT', myBar:GetStatusBarTexture(), 'RIGHT')
otherBar:SetWidth(200)
-- Register with oUF
self.HealthPrediction = {
myBar = myBar,
otherBar = otherBar,
maxOverflow = 1.05
}
--]]
local _, ns = ...
local oUF = ns.oUF or oUF
assert(oUF, "oUF_HealComm4 was unable to locate oUF install")
local UnitHealth = UnitHealth
local UnitHealthMax = UnitHealthMax
local UnitName = UnitName
local UnitGetIncomingHeals = UnitGetIncomingHeals
local UnitGetTotalAbsorbs = UnitGetTotalAbsorbs
local UnitGetTotalHealAbsorbs = UnitGetTotalHealAbsorbs
local enabledUF, enabled = {}, nil
local function Update(self)
local unit = self.unit
local element = self.HealCommBar
--[[ Callback: HealthPrediction:PreUpdate(unit)
Called before the element has been updated.
* self - the HealthPrediction element
* unit - the unit for which the update has been triggered (string)
--]]
if element.PreUpdate then
element:PreUpdate(unit)
end
local myIncomingHeal = UnitGetIncomingHeals(unit, UnitName("player")) or 0
local allIncomingHeal = UnitGetIncomingHeals(unit) or 0
local absorb = UnitGetTotalAbsorbs and UnitGetTotalAbsorbs(unit) or 0
local healAbsorb = UnitGetTotalHealAbsorbs and UnitGetTotalHealAbsorbs(unit) or 0
local health = UnitHealth(unit)
local maxHealth = UnitHealthMax(unit)
local maxOverflowHP = maxHealth * element.maxOverflow
local otherIncomingHeal = 0
if healAbsorb > allIncomingHeal then
healAbsorb = healAbsorb - allIncomingHeal
allIncomingHeal = 0
myIncomingHeal = 0
else
allIncomingHeal = allIncomingHeal - healAbsorb
healAbsorb = 0
if element.overflowHeals then
if health + allIncomingHeal > maxOverflowHP then
allIncomingHeal = maxOverflowHP - health
end
end
if allIncomingHeal < myIncomingHeal then
myIncomingHeal = allIncomingHeal
else
otherIncomingHeal = allIncomingHeal - myIncomingHeal
end
end
if element.overflowAbsorbs then
local maxAbsorb = maxOverflowHP - health
if absorb > maxAbsorb then
absorb = maxAbsorb > 0 and maxAbsorb or 0
end
end
if element.myBar then
element.myBar:SetMinMaxValues(0, maxHealth)
element.myBar:SetValue(myIncomingHeal)
element.myBar:Show()
end
if element.otherBar then
element.otherBar:SetMinMaxValues(0, maxHealth)
element.otherBar:SetValue(otherIncomingHeal)
element.otherBar:Show()
end
if element.absorbBar then
element.absorbBar:SetMinMaxValues(0, maxHealth)
element.absorbBar:SetValue(absorb)
if absorb > 0 then
element.absorbBar:Show()
else
element.absorbBar:Hide()
end
end
if element.healAbsorbBar then
element.healAbsorbBar:SetMinMaxValues(0, maxHealth)
element.healAbsorbBar:SetValue(healAbsorb)
if healAbsorb > 0 then
element.healAbsorbBar:Show()
else
element.healAbsorbBar:Hide()
end
end
--[[ Callback: HealthPrediction:PostUpdate(unit, myIncomingHeal, otherIncomingHeal, absorb, healAbsorb)
Called after the element has been updated.
* self - the HealthPrediction element
* unit - the unit for which the update has been triggered (string)
* myIncomingHeal - the amount of incoming healing done by the player (number)
* otherIncomingHeal - the amount of incoming healing done by others (number)
* absorb - the amount of damage the unit can absorb without losing health (number)
* healAbsorb - the amount of healing the unit can absorb without gaining health (number)
--]]
if element.PostUpdate then
return element:PostUpdate(unit, myIncomingHeal, otherIncomingHeal, absorb, healAbsorb)
end
end
local function Path(self, ...)
--[[ Override: HealthPrediction.Override(self, event, unit)
Used to completely override the internal update function.
* self - the parent object
* event - the event triggering the update (string)
* unit - the unit accompanying the event
--]]
return (self.HealCommBar.Override or Update) (self, ...)
end
local function ForceUpdate(element)
return Path(element.__owner, "ForceUpdate", element.__owner.unit)
end
local function UpdateAllUnits(...)
local all_units = {...}
local units = { }
for _, unit in pairs(all_units) do
units[unit] = true
end
for j = 1, #enabledUF do
local frame = enabledUF[j]
if units[UnitName(frame.unit)] and frame:IsVisible() then
Path(frame)
end
end
end
local function Enable(self)
local element = self.HealCommBar
if element then
element.__owner = self
element.ForceUpdate = ForceUpdate
self:RegisterEvent("UNIT_HEALTH", Path)
self:RegisterEvent("UNIT_MAXHEALTH", Path)
self:RegisterEvent("UNIT_HEAL_PREDICTION", Path)
self:RegisterEvent("UNIT_ABSORB_AMOUNT_CHANGED", Path)
self:RegisterEvent("UNIT_HEAL_ABSORB_AMOUNT_CHANGED", Path)
if not element.maxOverflow then
element.maxOverflow = 1.05
end
if element.absorbBar and element.absorbBar:IsObjectType("StatusBar") and not element.absorbBar:GetStatusBarTexture() then
element.absorbBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
end
if element.healAbsorbBar and element.healAbsorbBar:IsObjectType("StatusBar") and not element.healAbsorbBar:GetStatusBarTexture() then
element.healAbsorbBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
end
enabledUF[#enabledUF + 1] = self
return true
end
end
local function Disable(self)
local element = self.HealCommBar
if element then
if element.myBar then
element.myBar:Hide()
end
if element.otherBar then
element.otherBar:Hide()
end
if element.absorbBar then
element.absorbBar:Hide()
end
if element.healAbsorbBar then
element.healAbsorbBar:Hide()
end
self:UnregisterEvent("UNIT_HEALTH", Path)
self:UnregisterEvent("UNIT_MAXHEALTH", Path)
self:UnregisterEvent("UNIT_HEAL_PREDICTION", Path)
self:UnregisterEvent("UNIT_ABSORB_AMOUNT_CHANGED", Path)
self:UnregisterEvent("UNIT_HEAL_ABSORB_AMOUNT_CHANGED", Path)
end
end
oUF:AddElement("HealComm4", Path, Enable, Disable)