Files
ShaguTweaks-ClassicAPI/libs/libnameplate.lua
T

158 lines
5.0 KiB
Lua

local _G = ShaguTweaks.GetGlobalEnv()
local GetExpansion = ShaguTweaks.GetExpansion
local API = ShaguTweaks.API or {}
local NAMEPLATE_OBJECTORDER = { "border", "glow", "name", "level", "levelicon", "raidicon" }
local NAMEPLATE_TYPE = "Button"
if GetExpansion() == "tbc" then
NAMEPLATE_OBJECTORDER = { "border", "castborder", "casticon", "glow", "name", "level", "levelicon", "raidicon" }
NAMEPLATE_TYPE = "Frame"
end
local function IsNamePlate(frame)
if not frame or frame:GetObjectType() ~= NAMEPLATE_TYPE then return nil end
local regions = frame:GetRegions()
if not regions then return nil end
if not regions.GetObjectType then return nil end
if not regions.GetTexture then return nil end
if regions:GetObjectType() ~= "Texture" then return nil end
return regions:GetTexture() == "Interface\\Tooltips\\Nameplate-Border" or nil
end
local registry = {}
ShaguTweaks.libnameplate = CreateFrame("Frame", nil, UIParent)
ShaguTweaks.libnameplate.OnInit = {}
ShaguTweaks.libnameplate.OnShow = {}
ShaguTweaks.libnameplate.OnUpdate = {}
local function GetHealthBar(plate)
-- Other nameplate addons may already have attached the authoritative bar.
if plate.healthbar and plate.healthbar.GetStatusBarColor and
plate.healthbar.SetStatusBarColor then
return plate.healthbar
end
-- Once another addon has added children, the health bar is no longer
-- guaranteed to be the first value returned by GetChildren().
local children = { plate:GetChildren() }
for i = 1, table.getn(children) do
local child = children[i]
if child and child.GetStatusBarColor and child.SetStatusBarColor then
return child
end
end
return children[1]
end
local function SetupPlate(plate, unit)
if not plate or not IsNamePlate(plate) then return end
local healthbar = GetHealthBar(plate)
if not healthbar then return end
local registered = registry[healthbar]
if registered then
if unit then
registered.unit = unit
registered.guid = API.UnitGUID and API.UnitGUID(unit) or nil
end
return registered
end
plate.healthbar = healthbar
if unit then
plate.unit = unit
plate.guid = API.UnitGUID and API.UnitGUID(unit) or nil
end
for i, object in pairs({plate:GetRegions()}) do
if NAMEPLATE_OBJECTORDER[i] then
plate[NAMEPLATE_OBJECTORDER[i]] = object
end
end
-- run OnInit functions
for id, func in pairs(ShaguTweaks.libnameplate.OnInit) do
func(plate)
end
-- preserve the plate's existing scripts and append ShaguTweaks callbacks
local oldUpdate = plate:GetScript("OnUpdate")
plate:SetScript("OnUpdate", function(self, elapsed)
if oldUpdate then oldUpdate(self, elapsed) end
for id, func in pairs(ShaguTweaks.libnameplate.OnUpdate) do
func(self, elapsed)
end
end)
local oldShow = plate:GetScript("OnShow")
plate:SetScript("OnShow", function(self)
if oldShow then oldShow(self) end
for id, func in pairs(ShaguTweaks.libnameplate.OnShow) do
func(self)
end
end)
registry[healthbar] = plate
return plate
end
-- ClassicAPI exposes real nameplate lifecycle events and nameplateN unit
-- tokens. Prefer those so ShaguTweaks no longer scans every WorldFrame child
-- on every rendered frame. Keep the unit token/GUID on each plate so modules
-- can query precise unit data without identifying enemies by displayed name.
if API.nameplates and _G.C_NamePlate and _G.C_NamePlate.GetNamePlates then
ShaguTweaks.libnameplate:RegisterEvent("NAME_PLATE_CREATED")
ShaguTweaks.libnameplate:RegisterEvent("NAME_PLATE_UNIT_ADDED")
ShaguTweaks.libnameplate:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
ShaguTweaks.libnameplate:RegisterEvent("PLAYER_ENTERING_WORLD")
ShaguTweaks.libnameplate:SetScript("OnEvent", function()
if event == "NAME_PLATE_CREATED" then
SetupPlate(arg1)
elseif event == "NAME_PLATE_UNIT_ADDED" then
local unit = arg1
SetupPlate(API.GetNamePlateForUnit(unit), unit)
elseif event == "NAME_PLATE_UNIT_REMOVED" then
-- ClassicAPI resolves the leaving token during the removal handler,
-- before positional nameplateN indices shift.
local plate = API.GetNamePlateForUnit(arg1)
if plate then
plate.unit = nil
plate.guid = nil
end
elseif event == "PLAYER_ENTERING_WORLD" then
local plates = _G.C_NamePlate.GetNamePlates()
if plates then
for i = 1, table.getn(plates) do
local unit = "nameplate" .. i
local plate = API.GetNamePlateForUnit(unit)
if plate then SetupPlate(plate, unit) end
end
end
end
end)
else
-- Compatibility fallback for clients without the ClassicAPI nameplate API.
local initialized = 0
local parentcount, childs, plate
ShaguTweaks.libnameplate:SetScript("OnUpdate", function()
parentcount = WorldFrame:GetNumChildren()
if initialized < parentcount then
childs = { WorldFrame:GetChildren() }
for i = initialized + 1, parentcount do
plate = childs[i]
if IsNamePlate(plate) then SetupPlate(plate) end
end
initialized = parentcount
end
end)
end