Files
RelationshipsThreatPlates/RelationshipsThreatPlates_Core.lua
2026-07-25 14:46:01 +00:00

224 lines
7.6 KiB
Lua

----------------------------------------------------------------------
-- RelationshipsThreatPlates_Core.lua
-- Core addon initialization, saved variables, slash commands
-- Compatible with WoW 1.12 (Vanilla / Turtle WoW / Octo WoW)
----------------------------------------------------------------------
-- Create the global addon object
RelationshipsThreatPlates = CreateFrame("Frame")
local addon = RelationshipsThreatPlates
addon.MAJOR = 1
addon.MINOR = 1
-- Version string
TP_VERSION = "2.6.1"
TP_ADDON_NAME = "RelationshipsThreatPlates"
-- ==================================================================
-- Default configuration
-- ==================================================================
local DEFAULT_CONFIG = {
enabled = true,
showText = true,
tankMode = false,
targetSnap100 = true,
barHeight = 6,
barAlpha = 0.5,
barOffsetY = 24,
barOffsetX = -17.8,
barWidthScale = 0.8,
fontSize = 9,
fontOutline = true,
smoothColors = true,
showOnFriendly = false,
showOnNeutral = true,
showOnHostile = true,
showSpark = false,
showFillBG = true,
fillAlpha = 0.1,
glowEnabled = false,
glowSize = 3,
glowAsShadow = true,
-- New in 2.6
combatOnly = false,
hideBelowPct = 0,
warningSound = false,
warningSoundName = "RaidWarning",
warningThreshold = 80,
flashOnAggro = false,
flashSpeed = 4,
textFormat = "percent", -- percent | tank | status | combo
colorPreset = "kui", -- kui | cool | mono | warband
lockGUI = false,
guiPos = {
point = "CENTER",
relPoint = "CENTER",
x = 0,
y = 0,
},
}
-- ==================================================================
-- Safe UnitGUID wrapper - UnitGUID does not exist in Vanilla 1.12
-- Returns nil on vanilla clients, falls back to unit name
-- ==================================================================
function addon:SafeGUID(unit)
if UnitGUID then
local ok, guid = pcall(UnitGUID, unit)
if ok and guid then return guid end
end
return nil
end
-- ==================================================================
-- Get a unique identifier for a unit (GUID or name)
-- In vanilla 1.12, UnitGUID does not exist, so we use unit name
-- ==================================================================
function addon:GetUnitID(unit)
if not unit then return nil end
local guid = addon:SafeGUID(unit)
if guid then return guid end
local ok, name = pcall(UnitName, unit)
if ok and name then return name end
return nil
end
-- ==================================================================
-- Print helper
-- ==================================================================
function addon:ui_print(msg)
if DEFAULT_CHAT_FRAME then
DEFAULT_CHAT_FRAME:AddMessage("|cffbb99ffRelationshipsThreatPlates|r " .. tostring(msg))
end
end
-- ==================================================================
-- Deep copy utility
-- ==================================================================
local function DeepCopy(src)
if type(src) ~= "table" then return src end
local dst = {}
for k, v in pairs(src) do
if type(v) == "table" then
dst[k] = DeepCopy(v)
else
dst[k] = v
end
end
return dst
end
-- ==================================================================
-- Ensure SavedVariable table exists and has all default keys.
-- Safe to call multiple times.
-- ==================================================================
local function EnsureDB()
if not RelationshipsThreatPlatesDB then
RelationshipsThreatPlatesDB = DeepCopy(DEFAULT_CONFIG)
else
for k, v in pairs(DEFAULT_CONFIG) do
if RelationshipsThreatPlatesDB[k] == nil then
RelationshipsThreatPlatesDB[k] = DeepCopy(v)
end
end
end
end
addon.EnsureDB = EnsureDB
-- In WoW 1.12, SavedVariables are loaded BEFORE the addon's Lua files
-- execute, so it is safe to initialize the DB at file load. Doing this
-- here (in addition to ADDON_LOADED) protects against cases where the
-- installed folder name doesn't match TP_ADDON_NAME exactly
-- (e.g. "RelationshipsThreatPlates-main" from a GitHub zip), which
-- would otherwise cause the ADDON_LOADED arg1 check to fail and leave
-- RelationshipsThreatPlatesDB nil - the root cause of
-- "attempt to index global 'RelationshipsThreatPlatesDB' a nil value"
-- reported at RelationshipsThreatPlates_GUI.lua:320.
EnsureDB()
-- ==================================================================
-- Event handling
-- ==================================================================
addon:RegisterEvent("ADDON_LOADED")
addon:RegisterEvent("PLAYER_ENTERING_WORLD")
local modulesInitialized = false
local function InitializeModules()
if modulesInitialized then return end
modulesInitialized = true
EnsureDB()
-- Ensure media textures
addon.Media.EnsureTextures()
-- Initialize modules
addon.ThreatEngine:Initialize()
addon.Threat:Initialize()
addon.Nameplates:Initialize()
addon.GUI:Initialize()
addon:ui_print("v" .. TP_VERSION .. " loaded! Type /tp for options.")
end
addon:SetScript("OnEvent", function()
if event == "ADDON_LOADED" then
-- Accept any ADDON_LOADED: this script only runs when our addon
-- is loaded, so the first ADDON_LOADED we see is safe to act on.
-- This avoids folder-rename issues where arg1 ~= TP_ADDON_NAME.
InitializeModules()
elseif event == "PLAYER_ENTERING_WORLD" then
-- Safety net: if ADDON_LOADED was somehow missed, initialize now.
InitializeModules()
if RelationshipsThreatPlatesDB and RelationshipsThreatPlatesDB.enabled then
addon.Nameplates:UpdateAll()
end
end
end)
-- ==================================================================
-- Slash commands
-- ==================================================================
SLASH_THREATPLATES1 = "/threatplates"
SLASH_THREATPLATES2 = "/tp"
SlashCmdList["THREATPLATES"] = function(msg)
-- Trim whitespace and lowercase (vanilla-safe)
msg = msg or ""
msg = string.lower(msg)
-- Trim leading/trailing spaces
msg = string.gsub(msg, "^%s*(.-)%s*$", "%1")
if msg == "reset" then
RelationshipsThreatPlatesDB = DeepCopy(DEFAULT_CONFIG)
addon:ui_print("Settings reset to defaults.")
addon.GUI:Refresh()
elseif msg == "toggle" then
RelationshipsThreatPlatesDB.enabled = not RelationshipsThreatPlatesDB.enabled
local state = RelationshipsThreatPlatesDB.enabled and "|cff33ff99ON|r" or "|cffff3333OFF|r"
addon:ui_print("Threat bars " .. state)
addon.Nameplates:UpdateAll()
elseif msg == "threat" then
addon.ThreatEngine:DumpThreat()
elseif msg == "help" then
addon:ui_print("Commands:")
DEFAULT_CHAT_FRAME:AddMessage(" |cffbb99ff/tp|r - Open GUI")
DEFAULT_CHAT_FRAME:AddMessage(" |cffbb99ff/tp toggle|r - Toggle threat bars on/off")
DEFAULT_CHAT_FRAME:AddMessage(" |cffbb99ff/tp reset|r - Reset to defaults")
DEFAULT_CHAT_FRAME:AddMessage(" |cffbb99ff/tp threat|r - Dump threat table (debug)")
DEFAULT_CHAT_FRAME:AddMessage(" |cffbb99ff/tp help|r - Show this help")
else
addon.GUI:Toggle()
end
end
-- ==================================================================
-- Expose DeepCopy on addon for other modules
-- ==================================================================
addon.DeepCopy = DeepCopy