Author SHA1 Message Date
Andreas 5823bf839c Add a status bar for incoming heals
This shows a prediction of incoming direct heals.
2026-11-01 16:34:52 +01:00
Andreas 0569c100a1 Make status colors configurable
The aura based status colors can now be configured in frames.lua. This
is important in TBC where some healers don't care about e.g. magic
debuffs.
2026-10-31 11:59:51 +00:00
3 changed files with 116 additions and 24 deletions

No files matched your search

+47
View File
@@ -26,6 +26,8 @@ local colors = {
disease = { 0.4, 0.2, 0.0 },
poison = { 0.0, 0.7, 0.7 },
curse = { 0.7, 0.0, 0.7 },
immune = { 0.0, 0.2, 0.4 },
bomb = { 1.0, 0.7, 0.7 },
red = { 1, 0, 0 },
blue = { 0.4, 0.4, 1 },
light_blue = { 0.7, 0.7, 1 },
@@ -833,6 +835,51 @@ local function TriggerConfig()
return triggers
end
local function StatusColorClassConfig()
local _, class = UnitClass("player")
if class == "DRUID" then
return {
{ status = "Curse", color = colors.curse },
{ status = "Poison", color = colors.poison },
}
elseif class == "MAGE" then
return {
{ status = "Curse", color = colors.curse },
}
elseif class == "PALADIN" then
return {
{ status = "Magic", color = colors.magic },
{ status = "Poison", color = colors.poison },
{ status = "Disease", color = colors.disease },
}
elseif class == "PRIEST" then
return {
{ status = "Magic", color = colors.magic },
{ status = "Disease", color = colors.disease },
}
elseif class == "SHAMAN" then
return {
{ status = "Poison", color = colors.poison },
{ status = "Disease", color = colors.disease },
}
end
return {}
end
local function StatusColorConfig()
local statusColors = {
{ status = "Immune", color = colors.immune },
{ status = "Bomb", color = colors.bomb },
}
for _, entry in ipairs(StatusColorClassConfig()) do
table.insert(statusColors, entry)
end
return statusColors
end
local types = omif.GetModule("types")
local UnitFrame = types.UnitFrame
local UnitGroup = types.UnitGroup
+14
View File
@@ -90,3 +90,17 @@ function StatusBar:SetColor(r, g, b)
self.bg:SetVertexColor(0.2 * r, 0.2 * g, 0.2 * b)
end
end
function StatusBar:SetAlpha(alpha)
self.bar:SetAlpha(alpha)
end
function StatusBar:GetColor()
local r, g, b = self.bar:GetStatusBarColor()
return r, g, b
end
function StatusBar:AttachTo(statusBar, point, relativePoint)
self.bar:ClearAllPoints()
self.bar:SetPoint(point, statusBar.bar:GetStatusBarTexture(), relativePoint)
end
+55 -24
View File
@@ -50,12 +50,6 @@ local colors = {
low = { 1.0, 0.0, 0 },
offline = { 0.7, 0.7, 0.7 },
dead = { 0.7, 0.7, 0.7 },
magic = { 0.4, 0.4, 1.0 },
disease = { 0.4, 0.2, 0.0 },
poison = { 0.0, 0.7, 0.7 },
curse = { 0.7, 0.0, 0.7 },
immune = { 0.0, 0.2, 0.4 },
bomb = { 1.0, 0.7, 0.7 },
cyan = { 0.0, 0.8, 0.8 },
white = { 1.0, 1.0, 1.0 },
shield = { 0.85, 0.95, 1.0 },
@@ -90,6 +84,8 @@ function UnitFrame:Init(unit, config)
self.rangeEnemy = config.range.enemy
self.rangeFade = config.range.fade
self.statusColors = config.statusColors
local secure = self:CreateSecureFrame(width, height)
secure:Hide()
@@ -101,14 +97,18 @@ function UnitFrame:Init(unit, config)
self.hp = StatusBar:new(self, width, height, 0, true, texture, texture)
self.power = StatusBar:new(self, width, 6, 2, false, texture, texture)
self.power = StatusBar:new(self, width, 6, 3, false, texture, texture)
self.power:Hide()
self.absorb = StatusBar:new(self, width, height, 1, true, texture_top)
self.incomingHeals = StatusBar:new(self, width, height, 1, true, texture)
self.incomingHeals:AttachTo(self.hp, "TOPLEFT", "TOPRIGHT")
self.incomingHeals:Hide()
self.absorb = StatusBar:new(self, width, height, 2, true, texture_top)
self.absorb:SetColor(unpack(colors.absorb))
self.absorb:SetFillStyle(Enum.StatusBarFillStyle.Reverse)
self.shield = StatusBar:new(self, width, height, 1, true, texture_bot)
self.shield = StatusBar:new(self, width, height, 2, true, texture_bot)
self.shield:SetColor(unpack(colors.shield))
self.shield:SetRange(0, 1)
self.shield:SetValue(0.6)
@@ -448,6 +448,7 @@ function UnitFrame:RegisterEvents()
secure:RegisterUnitEvent("UNIT_NAME_UPDATE", unit)
secure:RegisterUnitEvent("UNIT_ABSORB_AMOUNT_CHANGED", unit)
secure:RegisterUnitEvent("UNIT_HEAL_ABSORB_AMOUNT_CHANGED", unit)
secure:RegisterUnitEvent("UNIT_HEAL_PREDICTION", unit)
end
-- returns whether or not the unit guid has changed since the last call to this
@@ -508,6 +509,7 @@ function UnitFrame:UNIT_HEALTH()
end
self:UpdateHealth()
self:UpdateHealthColor()
self:UpdateIncomingHeals()
end
function UnitFrame:UNIT_MAXHEALTH()
@@ -517,6 +519,15 @@ function UnitFrame:UNIT_MAXHEALTH()
end
self:UpdateHealth()
self:UpdateHealthColor()
self:UpdateIncomingHeals()
end
function UnitFrame:UNIT_HEAL_PREDICTION()
if self:HasUnitChanged() then
self:UpdateAll(true)
return
end
self:UpdateIncomingHeals()
end
function UnitFrame:UNIT_TARGET()
@@ -607,6 +618,7 @@ function UnitFrame:UpdateAll(unitChanged)
end
self:UpdateHealth()
self:UpdateHealthColor()
self:UpdateIncomingHeals()
self:UpdateAbsorb()
self:UpdateShield()
self:UpdateRange()
@@ -662,23 +674,24 @@ function UnitFrame:UpdateHealthColor()
if not isFriend then
self.hp:SetColor(unpack(colors.hostile))
elseif self.auras.statusCount["Immune"] then
self.hp:SetColor(unpack(colors.immune))
elseif self.auras.statusCount["Bomb"] then
self.hp:SetColor(unpack(colors.bomb))
elseif self.auras.statusCount["Magic"] then
self.hp:SetColor(unpack(colors.magic))
elseif self.auras.statusCount["Curse"] then
self.hp:SetColor(unpack(colors.curse))
elseif self.auras.statusCount["Poison"] then
self.hp:SetColor(unpack(colors.poison))
elseif self.auras.statusCount["Disease"] then
self.hp:SetColor(unpack(colors.disease))
elseif isFriend and UnitIsDead(unit) then
return
end
local statusColor = nil
for _, entry in ipairs(self.statusColors) do
if self.auras.statusCount[entry.status] then
statusColor = entry.color
break
end
end
if statusColor then
self.hp:SetColor(unpack(statusColor))
elseif UnitIsDead(unit) then
self.hp:SetColor(unpack(colors.dead))
elseif isFriend and pct >= 0.90 then
elseif pct >= 0.90 then
self.hp:SetColor(unpack(colors.healthy))
elseif isFriend and pct >= 0.75 then
elseif pct >= 0.75 then
local progress = (pct - 0.75) / (0.90 - 0.75)
self.hp:SetInterpolatedColor(colors.mid, colors.high, progress)
else
@@ -703,3 +716,21 @@ function UnitFrame:UpdateName()
end
self.name:SetText(utf8_truncate((UnitName(self.unit)), 5))
end
function UnitFrame:UpdateIncomingHeals()
local incoming = UnitGetIncomingHeals(self.unit) or 0
local health = UnitHealth(self.unit)
local maxHealth = UnitHealthMax(self.unit)
incoming = math.min(incoming, maxHealth - health)
if incoming <= 0 then
self.incomingHeals:Hide()
else
local r, g, b = self.hp:GetColor()
self.incomingHeals:SetColor(r, g, b)
self.incomingHeals:SetAlpha(0.4)
self.incomingHeals:SetRange(0, maxHealth)
self.incomingHeals:SetValue(incoming)
self.incomingHeals:Show()
end
end