Files
Nanami-Plates/Healthbar.lua
2026-03-20 10:20:05 +08:00

154 lines
5.3 KiB
Lua

NanamiPlates_Healthbar = {}
local NP = NanamiPlates
local NEUTRAL_COLOR = {0.9, 0.7, 0.0, 1}
local HOSTILE_THRESHOLD = {r_min = 0.9, g_max = 0.2, b_max = 0.2}
local NEUTRAL_THRESHOLD = {r_min = 0.9, g_min = 0.9, b_max = 0.2}
function NanamiPlates_Healthbar.ResetCache(nameplate)
if not nameplate then return end
nameplate.cachedIsFriendly = nil
nameplate.cachedIsHostile = nil
nameplate.cachedIsNeutral = nil
nameplate.wasNeutral = nil
nameplate.lastPlateName = nil
nameplate.lastColorR = nil
nameplate.lastColorG = nil
nameplate.lastColorB = nil
end
function NanamiPlates_Healthbar.DetectUnitType(nameplate, original)
if not nameplate or not original or not original.healthbar then
return false, false, true, 0, 1, 0
end
local r, g, b = original.healthbar:GetStatusBarColor()
-- Guard: if color is (0,0,0) the engine hasn't set it yet, use previous cache or default hostile
if r == 0 and g == 0 and b == 0 then
if nameplate.cachedIsHostile ~= nil then
return nameplate.cachedIsHostile, nameplate.cachedIsNeutral, nameplate.cachedIsFriendly, r, g, b
end
return true, false, false, 1, 0, 0
end
local isHostile, isNeutral, isFriendly
local lastR, lastG, lastB = nameplate.lastColorR, nameplate.lastColorG, nameplate.lastColorB
if r == lastR and g == lastG and b == lastB then
isHostile = nameplate.cachedIsHostile
isNeutral = nameplate.cachedIsNeutral
isFriendly = nameplate.cachedIsFriendly
else
isHostile = r > HOSTILE_THRESHOLD.r_min and g < HOSTILE_THRESHOLD.g_max and b < HOSTILE_THRESHOLD.b_max
isNeutral = r > NEUTRAL_THRESHOLD.r_min and g > NEUTRAL_THRESHOLD.g_min and b < NEUTRAL_THRESHOLD.b_max
isFriendly = not isHostile and not isNeutral
nameplate.lastColorR = r
nameplate.lastColorG = g
nameplate.lastColorB = b
nameplate.cachedIsHostile = isHostile
nameplate.cachedIsNeutral = isNeutral
nameplate.cachedIsFriendly = isFriendly
if nameplate.wasNeutral == nil then
nameplate.wasNeutral = isNeutral
end
end
return isHostile, isNeutral, isFriendly, r, g, b
end
function NanamiPlates_Healthbar.CheckUnitChange(nameplate, plateName, isNeutral)
if not nameplate then return end
if plateName and plateName ~= nameplate.lastPlateName then
nameplate.lastPlateName = plateName
nameplate.wasNeutral = isNeutral
end
end
function NanamiPlates_Healthbar.IsNeutral(nameplate)
if not nameplate then return false end
return nameplate.cachedIsNeutral or nameplate.wasNeutral or false
end
function NanamiPlates_Healthbar.WasNeutral(nameplate)
if not nameplate then return false end
return nameplate.wasNeutral or false
end
function NanamiPlates_Healthbar.IsFriendly(nameplate)
if not nameplate then return false end
return nameplate.cachedIsFriendly or false
end
function NanamiPlates_Healthbar.IsHostile(nameplate)
if not nameplate then return false end
return nameplate.cachedIsHostile or false
end
function NanamiPlates_Healthbar.GetNeutralColor()
return NEUTRAL_COLOR[1], NEUTRAL_COLOR[2], NEUTRAL_COLOR[3], NEUTRAL_COLOR[4]
end
function NanamiPlates_Healthbar.ApplyNeutralColor(nameplate)
if not nameplate or not nameplate.health then return end
nameplate.health:SetStatusBarColor(NEUTRAL_COLOR[1], NEUTRAL_COLOR[2], NEUTRAL_COLOR[3], NEUTRAL_COLOR[4])
end
function NanamiPlates_Healthbar.ShouldShowNeutral(nameplate, isNeutral, isAttackingPlayer)
if not nameplate then return false end
return (isNeutral or nameplate.wasNeutral) and not isAttackingPlayer
end
function NanamiPlates_Healthbar.IsCritter(frame, nameplate, original, unitstr)
if unitstr and UnitCreatureType then
local creatureType = UnitCreatureType(unitstr)
if creatureType == "Critter" then return true end
end
if NP and NP.Critters then
local plateName = nil
if original and original.name and original.name.GetText then
plateName = original.name:GetText()
end
if not plateName and nameplate and nameplate.name and nameplate.name.GetText then
plateName = nameplate.name:GetText()
end
if plateName and NP.Critters[string.lower(plateName)] then
return true
end
end
if not unitstr and original and original.healthbar then
local r, g, b = original.healthbar:GetStatusBarColor()
local isNeutralColor = r > 0.9 and g > 0.9 and b < 0.2
if isNeutralColor then
local levelText = nil
if original.level and original.level.GetText then
levelText = original.level:GetText()
end
local _, hpmax = original.healthbar:GetMinMaxValues()
if levelText == "1" and hpmax and hpmax > 0 and hpmax < 100 then
return true
end
end
end
return false
end
function NanamiPlates_Healthbar.ShouldSkipNameplate(frame, nameplate, original, Settings)
if not Settings or Settings.showCritterNameplates then
return false
end
local unitstr = nil
if NP and NP.superwow_active and frame and frame.GetName then
unitstr = frame:GetName(1)
end
return NanamiPlates_Healthbar.IsCritter(frame, nameplate, original, unitstr)
end
NanamiPlates.Healthbar = NanamiPlates_Healthbar