Files
pfUI-CustomMedia/pfUI-CustomMedia-gryphons.lua
Mr_Rosh 29a8a624d1 Modernize Lua APIs and optimize updates
Replace deprecated Lua APIs, make event-handler arguments Classic 1.12-safe, and reduce repeated lookups and texture updates. Remove unused button translations and bump the addon version to 2.3.9.
2026-10-24 20:23:46 +03:00

241 lines
9.1 KiB
Lua

if not pfUI then return end
local addonpath
local tocs = { "", "-master", "-tbc", "-wotlk" }
for _, name in ipairs(tocs) do
local current = string.format("pfUI-CustomMedia%s", name)
local _, title = GetAddOnInfo(current)
if title then
addonpath = "Interface\\AddOns\\" .. current
break
end
end
if type(pfUI.gui) == "table" and type(pfUI.gui.dropdowns) == "table" and type(pfUI.gui.dropdowns.gryphons) ~= "table" then
pfUI.gui.dropdowns.gryphons = {}
end
-- Keep the familiar gryphons first, then list the remaining options alphabetically.
local gryphons = {
{name = "Gryphon Dragonflight", path = "GryphonDragonflight"},
{name = "Gryphon Forever", path = "GryphonForever"},
{name = "Gryphon Forever Mono", path = "GryphonForeverMono"},
{name = "Lion Dragonflight", path = "LionDragonflight"},
{name = "Lion Forever", path = "LionForever"},
{name = "Lion Forever Mono", path = "LionForeverMono"},
{name = "Winged Lion", path = "wingedlion"},
{name = "Dragon Dragonflight", path = "DragonDragonflight"},
{name = "Dragon Forever", path = "DragonForever"},
{name = "Dragon Forever Mono", path = "DragonForeverMono"},
{name = "Diablo 1", path = "diablo1"},
{name = "Diablo 2", path = "diablo2"},
{name = "Diablo 3", path = "diablo3"},
{name = "Diablo 4", path = "diablo4"},
{name = "Dwarf", path = "dwarf"},
{name = "Ghoul", path = "ghoul"},
{name = "Gnome", path = "gnome"},
{name = "Human", path = "human"},
{name = "Leaf", path = "Leaf"},
{name = "Murloc", path = "murloc"},
{name = "Murloc 2", path = "murloc2"},
{name = "Night Elf", path = "nightelf"},
{name = "Octopus", path = "octopus"},
{name = "Orc", path = "orc"},
{name = "Skull", path = "skull"},
{name = "Skull 2", path = "skull2"},
{name = "Squid", path = "SquidModDefault"},
{name = "Tauren", path = "tauren"},
{name = "Troll", path = "troll"},
{name = "Turtle", path = "turtle"},
}
-- Function to add custom textures
local function AddCustomGryphons()
if not addonpath or type(pfUI.gryphons) ~= "table" or type(pfUI.gryphons.textures) ~= "table" then return end
if type(pfUI.gui) ~= "table" or type(pfUI.gui.dropdowns) ~= "table" then return end
if type(pfUI.gui.dropdowns.gryphons) ~= "table" then pfUI.gui.dropdowns.gryphons = {} end
local dropdown = pfUI.gui.dropdowns.gryphons
local registered = {}
for _, entry in ipairs(dropdown) do registered[entry] = true end
for _, gryphon in ipairs(gryphons) do
local fullpath = addonpath .. "\\gryphons\\" .. gryphon.path .. ".tga"
pfUI.gryphons.textures[gryphon.name] = fullpath
local option = string.format("%s:%s", gryphon.name, gryphon.name)
if not registered[option] then
table.insert(dropdown, option)
registered[option] = true
end
end
-- Force update the gryphons if they're already configured
if type(pfUI.gryphons.UpdateConfig) == "function" then
pfUI.gryphons.UpdateConfig()
end
end
local moverNames = {
left = "pfUICustomMediaGryphonLeft",
right = "pfUICustomMediaGryphonRight",
}
local function HasSavedMoverPosition(name)
local positions = pfUI_config and pfUI_config.position
return type(positions) == "table" and type(positions[name]) == "table" and positions[name].xpos ~= nil
end
local function CopyFramePosition(source, target)
local point, relative, relativePoint, x, y = source:GetPoint()
target:ClearAllPoints()
local relativeIsTarget = relative == target or relative == target:GetName() or
(relative and type(relative) ~= "string" and type(relative) ~= "number" and
type(relative.GetName) == "function" and relative:GetName() == target:GetName())
if point and relative and not relativeIsTarget and relative ~= source then
target:SetPoint(point, relative, relativePoint or point, x or 0, y or 0)
elseif point then
-- A gryphon anchor can resolve to this named mover after a reload or
-- another addon has already reparented the frame. Never create a cycle.
target:SetPoint(point, UIParent, relativePoint or point, x or 0, y or 0)
else
target:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
end
end
local function InstallMovableGryphons()
if type(pfUI.gryphons) ~= "table" or type(pfUI.gryphons.frames) ~= "table" then return end
if type(pfUI.gryphons.UpdateConfig) ~= "function" or type(pfUI.api) ~= "table" or type(pfUI.api.UpdateMovable) ~= "function" then return end
if pfUI.gryphons.customMediaMoversInstalled then return end
local originalUpdate = pfUI.gryphons.UpdateConfig
local movers = {}
local environment = type(pfUI.GetEnvironment) == "function" and pfUI:GetEnvironment() or _G
local config = environment.C and environment.C.bars and environment.C.bars.gryphons
local lastAnchors = type(config) == "table" and {
left = config.anchor_left,
right = config.anchor_right,
} or {}
pfUI.gryphons.customMediaMovers = movers
pfUI.gryphons.customMediaMoversInstalled = true
local function ClearSavedMoverPosition(name)
local saved = pfUI_config and pfUI_config.position
if type(saved) == "table" then saved[name] = nil end
local configured = environment.C and environment.C.position
if type(configured) == "table" then configured[name] = nil end
end
local function UpdateMovers()
-- The core gryphon updater uses SetPoint without clearing prior anchors.
-- Remove the child-to-mover anchor first so it cannot be mistaken for
-- pfUI's configured default anchor when resetting or changing settings.
for _, frame in pairs(pfUI.gryphons.frames) do
if frame then frame:ClearAllPoints() end
end
-- pfUI's updater assumes that every anchor name resolves to a frame.
-- "None" (or an empty anchor) resolves to nil and SetParent(nil) crashes.
-- Use UIParent just for this update; keep the user's selected value intact.
local anchors = {}
if type(config) == "table" then
for position in pairs(moverNames) do
local key = "anchor_" .. position
anchors[key] = { value = config[key] }
if lastAnchors[position] ~= config[key] then
ClearSavedMoverPosition(moverNames[position])
local mover = movers[position]
if mover then mover:SetScale(1) end
end
if not config[key] or not _G[config[key]] then config[key] = "UIParent" end
end
end
originalUpdate()
if type(config) == "table" then
for position in pairs(moverNames) do
local key = "anchor_" .. position
config[key] = anchors[key].value
lastAnchors[position] = anchors[key].value
end
end
for position, name in pairs(moverNames) do
local frame = pfUI.gryphons.frames[position]
if frame then
local mover = movers[position]
if not mover then
mover = CreateFrame("Frame", name, UIParent)
mover:SetFrameStrata("MEDIUM")
CopyFramePosition(frame, mover)
pfUI.api.UpdateMovable(mover, true)
movers[position] = mover
elseif not HasSavedMoverPosition(name) then
CopyFramePosition(frame, mover)
end
-- pfUI clamps movable frames when its offscreen option is disabled.
-- Gryphon movers must remain freely draggable past the screen edges.
mover:SetClampedToScreen(false)
mover:SetWidth(frame:GetWidth())
mover:SetHeight(frame:GetHeight())
local point = frame:GetPoint()
point = point or "CENTER"
frame:SetParent(mover)
frame:SetFrameStrata("HIGH")
frame:SetFrameLevel(mover:GetFrameLevel() + 1)
frame:ClearAllPoints()
frame:SetPoint(point, mover, point, 0, 0)
end
end
end
pfUI.gryphons.UpdateConfig = UpdateMovers
UpdateMovers()
end
local function ResetGryphonPosition()
local positions = pfUI_config and pfUI_config.position
if type(positions) == "table" then
for _, name in pairs(moverNames) do positions[name] = nil end
end
if type(C.position) == "table" then
for _, name in pairs(moverNames) do C.position[name] = nil end
end
local movers = pfUI.gryphons and pfUI.gryphons.customMediaMovers
if type(movers) == "table" then
for _, mover in pairs(movers) do
if mover then mover:SetScale(1) end
end
end
if type(pfUI.gryphons.UpdateConfig) == "function" then
pfUI.gryphons.UpdateConfig()
end
end
-- C and pfUI_config are already available in this module's environment via
-- pfUI:GetEnvironment(), so no setfenv is needed here.
pfUI.customMedia = pfUI.customMedia or {}
pfUI.customMedia.ResetGryphonPosition = ResetGryphonPosition
local function InitializeCustomGryphons()
InstallMovableGryphons()
AddCustomGryphons()
end
-- Hook into pfUI's module registration system
if type(pfUI.RegisterModule) == "function" then
pfUI:RegisterModule("custom-gryphons", "vanilla:tbc", function()
InitializeCustomGryphons()
end)
else
-- Fallback: try to add immediately and on events
InitializeCustomGryphons()
local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function()
-- Capture event and arg1 into locals (Classic 1.12-safe).
local event, arg1 = event, arg1
if event == "ADDON_LOADED" and arg1 == "pfUI" then
InitializeCustomGryphons()
this:UnregisterEvent("ADDON_LOADED")
end
end)
end