3d456d036a
* HealComm - Absorb, HealAbsorb * HealComm - Unify all bars
249 lines
7.0 KiB
Lua
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) |