Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Defaults/Layout_Defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -169,22 +169,26 @@ Cell.defaults.layout = {
["health1"] = {
["format"] = "effective_percent",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
},
["health2"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
["delimiter"] = " ",
},
["shields"] = {
["format"] = "none",
["color"] = {"custom_color", {0, 1, 0}},
["colorByHealth"] = false,
["delimiter"] = "+",
},
["healAbsorbs"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 0, 0}},
["colorByHealth"] = false,
["delimiter"] = "-",
},
},
Expand Down
8 changes: 6 additions & 2 deletions Defaults/Layout_Defaults_Cata_Wrath.lua
Original file line number Diff line number Diff line change
Expand Up @@ -157,22 +157,26 @@ Cell.defaults.layout = {
["health1"] = {
["format"] = "effective_percent",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
},
["health2"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
["delimiter"] = " ",
},
["shields"] = {
["format"] = "none",
["color"] = {"custom_color", {0, 1, 0}},
["colorByHealth"] = false,
["delimiter"] = "+",
},
["healAbsorbs"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 0, 0}},
["colorByHealth"] = false,
["delimiter"] = "-",
},
},
Expand Down
8 changes: 6 additions & 2 deletions Defaults/Layout_Defaults_Mists.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,22 +164,26 @@ Cell.defaults.layout = {
["health1"] = {
["format"] = "effective_percent",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
},
["health2"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
["delimiter"] = " ",
},
["shields"] = {
["format"] = "none",
["color"] = {"custom_color", {0, 1, 0}},
["colorByHealth"] = false,
["delimiter"] = "+",
},
["healAbsorbs"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 0, 0}},
["colorByHealth"] = false,
["delimiter"] = "-",
},
},
Expand Down
8 changes: 6 additions & 2 deletions Defaults/Layout_Defaults_TBC_Vanilla.lua
Original file line number Diff line number Diff line change
Expand Up @@ -155,22 +155,26 @@ Cell.defaults.layout = {
["health1"] = {
["format"] = "effective_percent",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
},
["health2"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 1, 1}},
["hideIfEmptyOrFull"] = false,
["colorByHealth"] = false,
["hideIfEmptyOrFull"] = true,
["delimiter"] = " ",
},
["shields"] = {
["format"] = "none",
["color"] = {"custom_color", {0, 1, 0}},
["colorByHealth"] = false,
["delimiter"] = "+",
},
["healAbsorbs"] = {
["format"] = "none",
["color"] = {"custom_color", {1, 0, 0}},
["colorByHealth"] = false,
["delimiter"] = "-",
},
},
Expand Down
96 changes: 84 additions & 12 deletions Indicators/Built-in.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1952,17 +1952,33 @@ local formatter = {
["health_short"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.FormatNumber(health))
end,
["health_short2"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.FormatNumber(health, 2))
end,
["health_percent"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.Round(health / maxHealth * 100))
end,
["deficit"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(health - maxHealth)
-- hideIfZero (the segment's "Hide if 0" setting): suppress the deficit text entirely
-- once a unit is topped off, instead of always showing "-0" / "0%".
["deficit"] = function(pattern, hideIfZero, health, maxHealth, absorbs, healAbsorbs)
local deficit = health - maxHealth
if hideIfZero and deficit == 0 then return "" end
return pattern:format(deficit)
end,
["deficit_short"] = function(pattern, hideIfZero, health, maxHealth, absorbs, healAbsorbs)
local deficit = health - maxHealth
if hideIfZero and deficit == 0 then return "" end
return pattern:format(F.FormatNumber(deficit))
end,
["deficit_short"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.FormatNumber(health - maxHealth))
["deficit_short2"] = function(pattern, hideIfZero, health, maxHealth, absorbs, healAbsorbs)
local deficit = health - maxHealth
if hideIfZero and deficit == 0 then return "" end
return pattern:format(F.FormatNumber(deficit, 2))
end,
["deficit_percent"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.Round((health - maxHealth) / maxHealth * 100))
["deficit_percent"] = function(pattern, hideIfZero, health, maxHealth, absorbs, healAbsorbs)
local deficit = health - maxHealth
if hideIfZero and deficit == 0 then return "" end
return pattern:format(F.Round(deficit / maxHealth * 100))
end,

-- effective health
Expand All @@ -1972,6 +1988,9 @@ local formatter = {
["effective_short"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.FormatNumber(health + absorbs - healAbsorbs))
end,
["effective_short2"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.FormatNumber(health + absorbs - healAbsorbs, 2))
end,
["effective_percent"] = function(pattern, _, health, maxHealth, absorbs, healAbsorbs)
return pattern:format(F.Round((health + absorbs - healAbsorbs) / maxHealth * 100))
end,
Expand All @@ -1985,6 +2004,10 @@ local formatter = {
if absorbs == 0 then return "" end
return pattern:format(F.FormatNumber(absorbs))
end,
["shields_short2"] = function(pattern, health, maxHealth, absorbs, healAbsorbs)
if absorbs == 0 then return "" end
return pattern:format(F.FormatNumber(absorbs, 2))
end,
["shields_percent"] = function(pattern, health, maxHealth, absorbs, healAbsorbs)
if absorbs == 0 then return "" end
return pattern:format(F.Round(absorbs / maxHealth * 100))
Expand All @@ -1999,6 +2022,10 @@ local formatter = {
if healAbsorbs == 0 then return "" end
return pattern:format(F.FormatNumber(healAbsorbs))
end,
["healabsorbs_short2"] = function(pattern, health, maxHealth, absorbs, healAbsorbs)
if healAbsorbs == 0 then return "" end
return pattern:format(F.FormatNumber(healAbsorbs, 2))
end,
["healabsorbs_percent"] = function(pattern, health, maxHealth, absorbs, healAbsorbs)
if healAbsorbs == 0 then return "" end
return pattern:format(F.Round(healAbsorbs / maxHealth * 100))
Expand All @@ -2019,7 +2046,8 @@ local function BuildPattern(config)

local suffix = config.format:find("percent$") and "%%" or ""

if config.color[1] == "class_color" then
-- colorByHealth: color is computed dynamically per update (see ApplyHealthGradientColor), so leave it unbaked here
if config.colorByHealth or config.color[1] == "class_color" then
return prefix .. "%s" .. suffix
else
return prefix .. "|cff" .. F.ConvertRGBToHEX(F.ConvertRGB_256(unpack(config.color[2]))) .. "%s" .. suffix .. "|r"
Expand All @@ -2043,6 +2071,9 @@ local function BuildSecretSegment(config)

local isPercent = config.format:find("percent$") and true or false

-- colorByHealth needs live (secret-safe) percent evaluation which isn't available at C-level
-- here, so secret segments just fall back to their static base color (no gradient),
-- same as when colorByHealth is off - class_color still relies on the fontstring's ambient tint.
local colorStart, colorEnd
if config.color[1] == "class_color" then
colorStart, colorEnd = "", ""
Expand Down Expand Up @@ -2095,6 +2126,18 @@ local function HealthText_SetFormat(self, format)
self.shields = BuildPattern(format.shields)
self.healAbsorbs = BuildPattern(format.healAbsorbs)

-- hideIfEmptyOrFull: for deficit formats, suppress the "-0"/"0%" text once a unit is topped off
self.health1HideIfZero = format.health1.hideIfEmptyOrFull and true or false
self.health2HideIfZero = format.health2.hideIfEmptyOrFull and true or false

-- colorByHealth: remember which segments need their color recomputed every update
-- (against the segment's own class/custom base color) instead of the baked-in one
self.health1GradientColor = format.health1.colorByHealth and format.health1.color or nil
self.health2GradientColor = format.health2.colorByHealth and format.health2.color or nil
self.shieldsGradientColor = format.shields.colorByHealth and format.shields.color or nil
self.healAbsorbsGradientColor = format.healAbsorbs.colorByHealth and format.healAbsorbs.color or nil

-- Pre-build C-level format segments for use when values are secret.
-- Each active component gets a segment with a %d/%s placeholder.
-- Stored individually so the render path can skip zero-value absorb components.
local segments = {}
Expand All @@ -2116,6 +2159,26 @@ local function HealthText_SetFormat(self, format)

end

-- Wraps an already-formatted segment string with a color computed from the current
-- health percent (ElvUI-style red -> yellow -> base color), when colorByHealth is enabled
-- for that segment. `colorConfig` is the segment's {mode, {r,g,b}} color table, or nil.
local function ApplyHealthGradientColor(text, colorConfig, percent, unit)
if text == "" or not colorConfig then
return text
end

local r, g, b
if colorConfig[1] == "class_color" then
-- no live unit in the settings preview (e.g. widget:SetValue with a fake sample) - fall back to the player's class
r, g, b = unit and F.GetUnitClassColor(unit) or F.GetClassColor(Cell.vars.playerClass)
else
r, g, b = colorConfig[2][1], colorConfig[2][2], colorConfig[2][3]
end
r, g, b = F.GetHealthTextColor(percent, r, g, b)

return "|cff" .. F.ConvertRGBToHEX(F.ConvertRGB_256(r, g, b)) .. text .. "|r"
end

local function HealthText_SetValue(self, health, maxHealth, shields, healAbsorbs, unit)
-- safety net for any remaining Lua arithmetic in the formatters below.
if not F.IsValueNonSecret(health) or not F.IsValueNonSecret(maxHealth)
Expand Down Expand Up @@ -2179,11 +2242,20 @@ local function HealthText_SetValue(self, health, maxHealth, shields, healAbsorbs
end
maxHealth = maxHealth == 0 and 1 or maxHealth

self.text:SetFormattedText("%s%s%s%s",
self.GetHealth1(self.health1, false, health, maxHealth, shields, healAbsorbs),
self.GetHealth2(self.health2, false, health, maxHealth, shields, healAbsorbs),
self.GetShields(self.shields, health, maxHealth, shields, healAbsorbs),
self.GetHealAbsorbs(self.healAbsorbs, health, maxHealth, shields, healAbsorbs))
if self.health1GradientColor or self.health2GradientColor or self.shieldsGradientColor or self.healAbsorbsGradientColor then
local percent = health / maxHealth
self.text:SetFormattedText("%s%s%s%s",
ApplyHealthGradientColor(self.GetHealth1(self.health1, self.health1HideIfZero, health, maxHealth, shields, healAbsorbs), self.health1GradientColor, percent, unit),
ApplyHealthGradientColor(self.GetHealth2(self.health2, self.health2HideIfZero, health, maxHealth, shields, healAbsorbs), self.health2GradientColor, percent, unit),
ApplyHealthGradientColor(self.GetShields(self.shields, health, maxHealth, shields, healAbsorbs), self.shieldsGradientColor, percent, unit),
ApplyHealthGradientColor(self.GetHealAbsorbs(self.healAbsorbs, health, maxHealth, shields, healAbsorbs), self.healAbsorbsGradientColor, percent, unit))
else
self.text:SetFormattedText("%s%s%s%s",
self.GetHealth1(self.health1, self.health1HideIfZero, health, maxHealth, shields, healAbsorbs),
self.GetHealth2(self.health2, self.health2HideIfZero, health, maxHealth, shields, healAbsorbs),
self.GetShields(self.shields, health, maxHealth, shields, healAbsorbs),
self.GetHealAbsorbs(self.healAbsorbs, health, maxHealth, shields, healAbsorbs))
end
self:SetWidth(self.text:GetStringWidth())
end

Expand Down
3 changes: 3 additions & 0 deletions Locales/enUS.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ select(2, ...).L = setmetatable({
["dispellableByMe"] = "Only show debuffs dispellable by me",
["nonPlayerAuras"] = "Only show non-player auras",
["nonPlayerAurasTip"] = "Hides lust aftereffects such as Exhaustion, Sated, Forbearance and Temporal Displacement. Encounter debuffs stay visible.",
["colorByHealthTip"] = "Blend this segment's color from red (low health) to yellow to its normal color as health rises, like ElvUI.",
["2 Decimals"] = "2 Decimals",
["Hide the deficit text once a unit is topped off"] = "Hide the deficit text once a unit is topped off",
["Private Dispel Overlay"] = "Private Dispel Overlay",
["Show private dispel overlay"] = "Show private dispel overlay",
["Only dispellable by me"] = "Only dispellable by me",
Expand Down
24 changes: 17 additions & 7 deletions Utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -454,23 +454,25 @@ end
local abs = math.abs

if Cell.isAsian then
function F.FormatNumber(n)
function F.FormatNumber(n, decimals)
decimals = decimals or 1
if abs(n) >= 100000000 then
return F.Round(n / 100000000, 2) .. symbol_1B
return F.Round(n / 100000000, decimals) .. symbol_1B
elseif abs(n) >= 10000 then
return F.Round(n / 10000, 1) .. symbol_10K
return F.Round(n / 10000, decimals) .. symbol_10K
else
return n
end
end
else
function F.FormatNumber(n)
function F.FormatNumber(n, decimals)
decimals = decimals or 1
if abs(n) >= 1000000000 then
return F.Round(n / 1000000000, 2) .. "B"
return F.Round(n / 1000000000, decimals) .. "B"
elseif abs(n) >= 1000000 then
return F.Round(n / 1000000, 2) .. "M"
return F.Round(n / 1000000, decimals) .. "M"
elseif abs(n) >= 1000 then
return F.Round(n / 1000, 1) .. "K"
return F.Round(n / 1000, decimals) .. "K"
else
return n
end
Expand Down Expand Up @@ -1435,6 +1437,14 @@ function F.GetHealthBarColor(percent, isDeadOrGhost, r, g, b)
return barR, barG, barB, lossR, lossG, lossB
end

-- ElvUI-style health text coloring: red at 0% health, yellow at 50%, original color (e.g. class color) at 100%
function F.GetHealthTextColor(percent, r, g, b)
if not Cell.loaded then
return r, g, b
end
return F.ColorGradient(percent or 1, {1, 0, 0}, {1, 1, 0}, {r, g, b})
end

-------------------------------------------------
-- units
-------------------------------------------------
Expand Down
Loading