2 Commits

Author SHA1 Message Date
Dusk 2505bb1c6e Update README with commands and fork change 2026-08-30 07:17:11 +00:00
Dusk 1ca9de3d9d Fix nil LowHealth thresholds on startup 2026-08-30 07:09:49 +00:00
2 changed files with 42 additions and 3 deletions
+25 -1
View File
@@ -64,6 +64,11 @@ end
function LifeSafer_LowHealth_ApplySettings()
-- restore defaults if saved variables are missing
if (not LifeSafer_LowHealth_Thresholds) then
LifeSafer_LowHealth_Thresholds = LifeSafer_LowHealth_Default_Thresholds
end
-- for compatibility with older versions of saved variables
if (not LifeSafer_LowHealth_Thresholds["SOUND"]) then
LifeSafer_LowHealth_Thresholds["SOUND"] = { [1] = 30 }
@@ -78,9 +83,11 @@ function LifeSafer_LowHealth_ApplySettings()
if (LifeSafer_LowHealth_Enabled) then
LifeSafer_LowHealth_HealthFrame = LifeSafer_LowHealth_UseAltTextures and LowHealthWarningFrameAltTexture1 or LowHealthFrame
frame:RegisterEvent("UNIT_DISPLAYPOWER")
if (LifeSafer_LowHealth_HealthEnabled or LifeSafer_LowHealth_SoundEnabled) then
frame:RegisterEvent("UNIT_HEALTH")
end
LifeSafer_LowHealth_ManaCheck()
LifeSafer_LowHealth_ManaFrame = LifeSafer_LowHealth_UseAltTextures and LowHealthWarningFrameAltTexture2 or OutOfControlFrame
else
@@ -101,6 +108,7 @@ function LifeSafer_LowHealth_FlashFrame(value, regular, critical, frame, state)
if (UIFrameIsFlashing(frame) or UIFrameIsFading(frame)) then
LifeSafer_LowHealth_FlashFrameStop(frame, state)
end
-- regular flash
elseif (value > critical) then
if (not (LowHealthWarningFrame.states[state] == REGULAR_FLASH)) then
@@ -114,11 +122,13 @@ function LifeSafer_LowHealth_FlashFrame(value, regular, critical, frame, state)
end
LowHealthWarningFrame.states[state] = REGULAR_FLASH
end
-- critical flash
else
if (not (LowHealthWarningFrame.states[state] == CRITICAL_FLASH)) then
if (LifeSafer_LowHealth_HealthEmote and state == "UNIT_HEALTH") then DoEmote("healme") end
if (LifeSafer_LowHealth_ManaEmote and state == "UNIT_MANA") then DoEmote("oom") end
if (UIFrameIsFlashing(frame)) then
--frame.flashDuration = frame.flashDuration + 10
frame.fadeInTime = 0.2
@@ -127,23 +137,28 @@ function LifeSafer_LowHealth_FlashFrame(value, regular, critical, frame, state)
else
UIFrameFlash(frame, 0.2, 0.8, -1, nil, 0, 0)
end
LowHealthWarningFrame.states[state] = CRITICAL_FLASH
end
end
end
function LifeSafer_LowHealth_SmoothFlashFrame(value, threshold, frame, state)
-- disable
if (value > threshold or LifeSafer_LowHealth_CombatCheck(state) or UnitIsDeadOrGhost("player")) then
LifeSafer_LowHealth_FlashFrameStop(frame, state)
-- smooth flash
else
local rate = LifeSafer_LowHealth_GetHeartRate(state)
local flashIn, flashOut = rate * 0.1, rate * 0.4
if (UIFrameIsFlashing(frame)) then
frame.flashDuration = frame.flashDuration + rate + 1
if (rate < 1) then
frame.fadeInTime = rate * 0.15
frame.fadeOutTime = rate * 0.85
@@ -173,7 +188,7 @@ end
function LifeSafer_LowHealth_OnEvent()
if (event == "UNIT_DISPLAYPOWER") then
if (event == "UNIT_DISPLAYPOWER") then
LifeSafer_LowHealth_ManaCheck()
return
end
@@ -185,9 +200,11 @@ function LifeSafer_LowHealth_OnEvent()
if (event == "UNIT_HEALTH") then
value = UnitHealth("player") / UnitHealthMax("player")
LifeSafer_LowHealth_SoundCheck(this, value * 100, unpack(LifeSafer_LowHealth_Thresholds["SOUND"]))
if (not LifeSafer_LowHealth_HealthEnabled) then
return -- this hack is because both sound and health flash need this event
end
frame = LifeSafer_LowHealth_HealthFrame
smooth = LifeSafer_LowHealth_HealthSync
elseif (event == "UNIT_MANA") then
@@ -208,6 +225,7 @@ end
function LifeSafer_LowHealth_CombatCheck(state)
local combat = UnitAffectingCombat("player")
if (not state or state == "UNIT_HEALTH") then
return LifeSafer_LowHealth_HealthCombatOnly and not combat
elseif (state == "UNIT_MANA") then
@@ -227,18 +245,21 @@ function LifeSafer_LowHealth_SoundCheck(frame, value, threshold)
frame:SetScript("OnUpdate", nil)
frame.heartRate = nil
end
-- regular
elseif (not frame.heartRate) then
frame:SetScript("OnUpdate", LifeSafer_LowHealth_OnUpdate)
frame.timer = 1
frame.heartRate = 0
end
end
function LifeSafer_LowHealth_ManaCheck()
local mana, frame = "UNIT_MANA", getglobal("LowHealthWarningFrame")
if (LifeSafer_LowHealth_ManaEnabled and UnitPowerType("player") == 0) then
-- player is using mana
frame:RegisterEvent(mana)
@@ -246,6 +267,7 @@ function LifeSafer_LowHealth_ManaCheck()
frame:UnregisterEvent(mana)
LifeSafer_LowHealth_FlashFrameStop(LifeSafer_LowHealth_ManaFrame, mana)
end
end
@@ -263,11 +285,13 @@ end
function LifeSafer_LowHealth_GetHeartRate(state)
if (state and state == "UNIT_MANA") then
return 0.5 + 2.0 * UnitMana("player") / UnitManaMax("player")
else
return 0.5 + 2.0 * UnitHealth("player") / UnitHealthMax("player")
end
end
+17 -2
View File
@@ -1,8 +1,23 @@
# LifeSafer🦇🦇🦇
Enables a flashing red effect when you are low on life (with sounds), and a flasing blue effect when you're low on mana. This warning system was implemented by Blizzard but is not in use. Enables a flashing purple effect when you gain Shadow Trance.
Enables a flashing red effect when you are low on life (with sounds), and a flashing blue effect when you're low on mana. This warning system was implemented by Blizzard but is not in use. Enables a flashing purple effect when you gain Shadow Trance.
---
## Commands
- `/lowhealth`
- `/lowhealthwarning`
- `/lhw`
These commands open the LifeSafer settings.
---
## OctoWoW fork
This is an OctoWoW-hosted fork of [RavenOfSeven/LifeSafer_LowHealthWarning](https://github.com/RavenOfSeven/LifeSafer_LowHealthWarning) (rebuild by tamara09). The **only** change from upstream is in `LifeSafer_LowHealthWarning.toc`: the `## Title` color escapes were lowercased (`|C…`/`|R``|c…`/`|r`) so the OctoLauncher addon browser renders the gradient name instead of printing the raw escape codes. The addon code is unchanged. All credit for the addon goes to the original author.
This is an OctoWoW-hosted fork of [RavenOfSeven/LifeSafer_LowHealthWarning](https://github.com/RavenOfSeven/LifeSafer_LowHealthWarning) (rebuild by tamara09).
Changes:
- Fix an error on startup when low-health threshold SavedVariables are missing.
All credit for the original addon goes to the original author.