--Plater main software file --Calls with : are functions imported from the framework --whenever a variable or function has a --private comment attached to it, means scripts cannot access it (read, write, override), anything else can be overriden with scripts --with that, you can make your own version of Plater by modifying and overriding functions entirelly using a hooking script, them you can export the script and upload to wago.io (have fun :) --check the list of available functions and members to override at 'Plater.CanOverride_Functions' and 'Plater.CanOverride_Members' --Weakauras Scripters: if you need to attach something to Plater nameplates: -- local namePlate = C_NamePlate.GetNamePlateForUnit (unitID) -- local unitFrame = namePlate.unitFrame --unitFrame is the main frame where all things is attached, it has SetAllPoints() on the namePlate frame. -- local healthBar = unitFrame.healthBar -- local castBar = unitFrame.castBar -- navigate within the code using search tags: ~color ~border, etc... if (true) then --return --but not today end --> details! framework local DF = _G ["DetailsFramework"] if (not DF) then print ("|cFFFFAA00Plater: framework not found, if you just installed or updated the addon, please restart your client.|r") return end --/run UIErrorsFrame:HookScript ("OnEnter", function() UIErrorsFrame:EnableMouse (false);Plater:Msg("UIErrorsFrame had MouseEnabled, its disabled now.") end) --> some WA or addon are enabling the mouse on the error frame making nameplates unclickable if (UIErrorsFrame) then UIErrorsFrame:HookScript ("OnEnter", function() --safe disable the mouse on error frame avoiding mouse interactions and warn the user UIErrorsFrame:EnableMouse (false) Plater:Msg ("something enabled the mouse on UIErrorsFrame, Plater disabled.") end) UIErrorsFrame:EnableMouse (false) end --> blend nameplates with the worldframe local AlphaBlending = ALPHA_BLEND_AMOUNT + 0.0654785 --> locals local unpack = unpack local ipairs = ipairs --local rawset = rawset --200 locals limit local rawget = rawget local setfenv = setfenv --local pcall = pcall --200 locals limit local InCombatLockdown = InCombatLockdown local UnitIsPlayer = UnitIsPlayer local UnitClassification = UnitClassification local UnitDetailedThreatSituation = UnitDetailedThreatSituation local UnitCanAttack = UnitCanAttack local IsSpellInRange = IsSpellInRange local abs = math.abs local format = string.format local GetSpellInfo = GetSpellInfo local UnitIsUnit = UnitIsUnit local type = type local select = select local UnitGUID = UnitGUID local strsplit = strsplit local lower = string.lower local floor = floor local max = math.max local min = math.min local IS_WOW_PROJECT_MAINLINE = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE local IS_WOW_PROJECT_NOT_MAINLINE = WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE local IS_WOW_PROJECT_CLASSIC_ERA = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC local IS_WOW_PROJECT_CLASSIC_WRATH = IS_WOW_PROJECT_NOT_MAINLINE and ClassicExpansionAtLeast and LE_EXPANSION_WRATH_OF_THE_LICH_KING and ClassicExpansionAtLeast(LE_EXPANSION_WRATH_OF_THE_LICH_KING) local PixelUtil = PixelUtil or DFPixelUtil local LibSharedMedia = LibStub:GetLibrary ("LibSharedMedia-3.0") -- https://www.curseforge.com/wow/addons/libsharedmedia-3-0 local LCG = LibStub:GetLibrary("LibCustomGlow-1.0") -- https://github.com/Stanzilla/LibCustomGlow local LibRangeCheck = LibStub:GetLibrary ("LibRangeCheck-2.0") -- https://www.curseforge.com/wow/addons/librangecheck-2-0/ local LibTranslit = LibStub:GetLibrary ("LibTranslit-1.0") -- https://github.com/Vardex/LibTranslit local LDB = LibStub ("LibDataBroker-1.1", true) local LDBIcon = LDB and LibStub ("LibDBIcon-1.0", true) local addonId, platerInternal = ... _ = nil --localization local LOC = DF.Language.GetLanguageTable(addonId) local Plater = DF:CreateAddOn ("Plater", "PlaterDB", PLATER_DEFAULT_SETTINGS, InterfaceOptionsFrame and { --options table --TODO: DISABLED FOR DRAGONFLIGHT FOR NOW! name = "Plater Nameplates", type = "group", args = { openOptions = { name = "Open Plater Options", desc = "Opens the Plater Options Menu.", type = "execute", func = function() if InterfaceOptionsFrame then InterfaceOptionsFrame:Hide() elseif SettingsPanel then SettingsPanel:Hide() end HideUIPanel(GameMenuFrame) Plater.OpenOptionsPanel() end, }, } }) local GetAddOnMetadata = C_AddOns and C_AddOns.GetAddOnMetadata or GetAddOnMetadata Plater.versionString = GetAddOnMetadata("Plater", "Version") Plater.fullVersionInfo = Plater.versionString .. " - DF v" .. select(2,LibStub:GetLibrary("DetailsFramework-1.0")) .. " - " .. GetBuildInfo() function Plater.GetVersionInfo(printOut) -- update, just in case... Plater.versionString = GetAddOnMetadata("Plater", "Version") Plater.fullVersionInfo = Plater.versionString .. " - DF v" .. select(2,LibStub:GetLibrary("DetailsFramework-1.0")) .. " - " .. GetBuildInfo() if printOut then print("Plater version info:\n" .. Plater.fullVersionInfo) end return Plater.fullVersionInfo end --> when a hook script is compiled, it increases the build version, so the handler for running scripts will notice in the change and update the script in real time local PLATER_HOOK_BUILD = 1 function Plater.IncreaseHookBuildID() --private PLATER_HOOK_BUILD = PLATER_HOOK_BUILD + 1 end --> if a widget has a RefreshID lower than the addon, it needs to be updated local PLATER_REFRESH_ID = 1 function Plater.IncreaseRefreshID() --private PLATER_REFRESH_ID = PLATER_REFRESH_ID + 1 Plater.IncreaseRefreshID_Auras() end --script namespace platerInternal.Scripts = {} platerInternal.Mods = {} platerInternal.Events = {} platerInternal.Defaults = { dropdownStatusBarTexture = [[Interface\Tooltips\UI-Tooltip-Background]], dropdownStatusBarColor = {.1, .1, .1, .8}, } platerInternal.Comms = {} platerInternal.Frames = {} platerInternal.Data = {} --> namespaces: --resources Plater.Resources = {} Plater.Auras = {} --store npcIds for npcs which flood the screen with nameplates and can be quickly processed --search .isPerformanceUnit for locations where there code for improve performance --unitFrame.isPerformanceUnit healthBar.isPerformanceUnit Plater.PerformanceUnits = { --[189706] = true, --chaotic essence (shadowlands season 4 raid affixes) --this is only one single orb which casts. no need for performance [189707] = true, --chaotic essence (shadowlands season 4 raid affixes) --these are the multiple spawns from the above [167999] = true, --Echo of Sin (shadowlands, Castle Nathria, Sire Denathrius) [176920] = true, --Domination Arrow (shadowlands, Sanctum of Domination, Sylvanas) [196642] = true, --Hungry Lasher (dragonflight, Algeth'ar Academy, Overgrown Ancient) } --setter Plater.AddPerformanceUnits = function (npcID) if type(npcID) == "number" then Plater.PerformanceUnits[npcID] = true end end Plater.RemovePerformanceUnits = function (npcID) if type(npcID) == "number" then Plater.PerformanceUnits[npcID] = nil end end Plater.ForceBlizzardNameplateUnits = { -- } Plater.AddForceBlizzardNameplateUnits = function(npcID) if type(npcID) == "number" then Plater.ForceBlizzardNameplateUnits[npcID] = true end end Plater.RemoveForceBlizzardNameplateUnits = function(npcID) if type(npcID) == "number" then Plater.ForceBlizzardNameplateUnits[npcID] = nil end end --all functions below can be overridden by scripts, hooks or any external code --this allows the user to fully modify Plater at a high level --how to override a function: --create a script in the hooking tab, add a 'Constructor' and a 'Nameplate Created' --copy the entire function from this file and paste in the constructor, hit save. --then when the first nameplate appears in the screen the function get rewritten --for fast debugging is recomended to paste the function in a 'Nameplate Updated' hook so just by saving the script (SHIFT + ENTER) you get the function to update immediately. Plater.CanOverride_Functions = { RefreshDBUpvalues = true, --refresh cache RefreshDBLists = true, --refresh cache UpdateAuraCache = true, --refresh cache CreateShowAuraIconAnimation = true, --creates the animation for aura icons played when they are shown GetHealthCutoffValue = true, --check if the character has a execute range and enable or disable the health cut off indicators CheckRange = true, --check if the player is in range of the unit GetSpellForRangeCheck = true, --get a spell to be used in the range check SetFontOutlineAndShadow = true, --apply the outline and shadow of a text UpdatePersonalBar = true, --update the personal bar UpdateResourceFrame = true, --anchors the resource frame (soul shards, combo points, etc) UpdateCastbarTargetText = true, --update the settings of the cast target (font color, size, etc) UpdateSpellNameSize = true, --receive a fontString and set the length of the spell name size in the cast bar QuickHealthUpdate = true, --update the health bar during NAMEPLATE_ADDED OnUpdateHealth = true, --when the healthbar get a new health value OnUpdateHealthMax = true, --when the maxhealth of the healthbar get updated UpdateIconAspecRatio = true, --adjust the icon texcoords depending on its size FormatTime = true, --get a number and return it formated into time, e.g. 63 return "1m" 1 minute FormatTimeDecimal = true, --get a number and return it formated into time with decimals below 10sec, e.g. 9.5 return "9.5s" GetAuraIcon = true, --return an icon to be use to show an aura AddAura = true, --adds an aura into the nameplate, require all the aura data and an icon AddExtraIcon = true, --adds an aura into the extra buff row of icons, require the aura data HideNonUsedAuraIcons = true, --after an aura refresh, hide all non used icons in the aura container ResetAuraContainer = true, --reset the aura container to be ready to a refresh TrackSpecificAuras = true, --refresh the aura container using a list of auras to track UpdateAuras_Manual = true, --start an aura refresh for manual aura tracking UpdateAuras_Automatic = true, --start an aura refresh for automatic aura tracking UpdateAuras_Self_Automatic = true, --start an aura refresh on the personal bar nameplate ColorOverrider = true, --control which color que nameplate will have when the Override Default Colors are enabled FindAndSetNameplateColor = true, --Plater tries to find a color for the nameplate SetTextColorByClass = true, --adds the class color into a text with scape sequence UpdatePlateSize = true, --control the size of health, cast, power bars SetPlateBackground = true, --set the backdrop when showing the nameplate area UpdateNameplateThread = true, --change the nameplate color based on threat UpdateTargetHighlight = true, --adjust the highlight on the player target nameplate UpdateTargetIndicator = true, --adjust the target indicator on the player target nameplate UpdateLifePercentVisibility = true, --control when the life percent text is shown UpdateLifePercentText = true, --update the health shown in the nameplate AddGuildNameToPlayerName = true, --adds the guild name into the player name UpdateUnitName = true, --update the unit name UpdateUnitNameTextSize = true, --controls the length of the unit name text UpdateBorderColor = true, --update the color of the border UpdatePlateBorderThickness = true, --adjust how thick is the border around the health bar UpdatePlateRaidMarker = true, --update the raid marker in the nameplate UpdateIndicators = true, --check which indicators will be shown in the nameplate (rare, elite, etc) AddIndicator = true, --adds an indicator ClearIndicators = true, --clear all indicators in the nameplate GetPlateAlpha = true, --get the absolute alpha amount for the nameplate (when in range) CheckHighlight = true, --check if the mouse is over the nameplate and show the highlight EnableHighlight = true, --enable the highlight check DisableHighlight = true, --disable the highlight check GetUnitType = true, --return if an unit is a pet, minor or regular AnimateLeftWithAccel = true, --move the health bar to left when health animation is enabled AnimateRightWithAccel = true, --move the health bar to right when health animation is enabled IsQuestObjective = true, --check if the npc from the nameplate is a quest mob } --store functions and members which can be overridden by scripts Plater.CanOverride_Members = { TargetIndicators = true, --table with all options for target indicators TargetHighlights = true, --table with all options for target highlight SparkTextures = true, --table with all textures available for castbar sparks CooldownEdgeTextures = true, --table with all textures available for cooldown edges AurasHorizontalPadding = true, --space in pixels between each row of buffs WideIconCoords = true, --used on buff special icons, are the texcoordinates when using wide icons BorderLessIconCoords = true, --used on buff special icons, when not using wide icons PlayerIsTank = true, --for aggro checks, if true the function will consider the player as tank CombatTime = true, --GetTime() of when the player entered in combat, affect aggro animations CurrentEncounterID = true, --store the current encounter ID if in combat and fighiting a boss LatestEncounter = true, --store time() from the latest ENCOUNTER_END ZoneInstanceType = true, --from GetInstanceInfo zone type, can be party, raid, arena, pvp, none ZonePvpType = true, --from GetZonePVPInfo PlayerGuildName = true, --name of the player's guild SpellForRangeCheck = true, --spell name used for range check PlayerGUID = true, --store the GUID of the player PlayerClass = true, --store the name for the player (non localized) } --store npc names and spell names from the current/latest combat --used to sort data in the options panel: Spell List, Spell Colors and Npc Colors Plater.LastCombat = { npcNames = {}, spellNames = {}, } --store spell cache. spell cache is loaded when adding new auras to track Plater.SpellHashTable = {} Plater.SpellIndexTable = {} --> export strings identification Plater.Export_CastColors = "CastColor" Plater.Export_NpcColors = "NpcColor" --> types of codes for each script in the Scripting tab (do not change these inside scripts) Plater.CodeTypeNames = { --private [1] = "UpdateCode", [2] = "ConstructorCode", [3] = "OnHideCode", [4] = "OnShowCode", [5] = "Initialization", } --hook options --> types of codes available to add in a script in the Hooking tab Plater.HookScripts = { --private "Initialization", "Deinitialization", "Constructor", "Destructor", "Nameplate Created", "Nameplate Added", "Nameplate Removed", "Nameplate Updated", "Cast Start", "Cast Update", "Cast Stop", "Target Changed", "Raid Target", "Enter Combat", "Leave Combat", "Player Power Update", "Player Talent Update", "Health Update", "Zone Changed", "Name Updated", "Load Screen", "Player Logon", "Receive Comm Message", "Send Comm Message", } Plater.HookScriptsDesc = { --private ["Initialization"] = "Executed once for the mod every time it is loaded or compiled. Used to initialize the global mod environment 'modTable'.", ["Deinitialization"] = "Executed once for the mod every time it is unloaded. Used to de-initialize the global mod environment 'modTable' and the mod.", ["Constructor"] = "Executed once when the nameplate run the hook for the first time.\n\nUse to initialize configs in the environment.\n\nAlways receive unitFrame in 'self' parameter.", ["Destructor"] = "Run when the hook is Disabled or unloaded due to Load Conditions.\n\nUse to hide all frames created.\n\n|cFF44FF44Run on all nameplates shown in the screen|r.", ["Nameplate Created"] = "Executed when a nameplate is created.\n\nRequires a |cFFFFFF22/reload|r after changing the code.", ["Nameplate Added"] = "Run after a nameplate is added to the screen.", ["Nameplate Removed"] = "Run when the nameplate is removed from the screen.", ["Nameplate Updated"] = "Run after the nameplate gets an updated from Plater.\n\n|cFFFFFF22Important:|r doesn't run every frame.", ["Cast Start"] = "When the unit starts to cast a spell.\n\n|cFFFFFF22self|r is unitFrame.castBar", ["Cast Update"] = "When the cast bar receives an update from Plater.\n\n|cFFFFFF22Important:|r doesn't run every frame.\n\n|cFFFFFF22self|r is unitFrame.castBar", ["Cast Stop"] = "When the cast is finished for any reason or the nameplate has been removed from the screen.\n\n|cFFFFFF22self|r is unitFrame.castBar", ["Target Changed"] = "Run after the player selects a new target.\n\n|cFF44FF44Run on all nameplates shown in the screen|r.", ["Raid Target"] = "A raid target mark has added, modified or removed (skull, cross, etc).\n\n|cFF44FF44Run on all nameplates shown in the screen|r.", ["Enter Combat"] = "Executed shortly after the player enter combat.\n\n|cFF44FF44Run on all nameplates shown in the screen|r.", ["Leave Combat"] = "Executed shortly after the player leave combat.\n\n|cFF44FF44Run on all nameplates shown in the screen|r.", ["Player Power Update"] = "Run when the player power, such as combo points, gets an update.\n\n|cFF44FF44Run only on the nameplate of your current target|r.", ["Player Talent Update"] = "When the player changes a talent or specialization.\n\n|cFF44FF44Run on all nameplates shown in the screen|r.", ["Health Update"] = "When the health of the unit changes.", ["Zone Changed"] = "Run when the player enter into a new zone.\n\n|cFF44FF44Run on all nameplates already created, on screen or not|r.", ["Name Updated"] = "Executed when the name of the unit shown in the nameplate receives an update.", ["Load Screen"] = "Run when a load screen finishes.\n\nUse to change settings for a specific area or map.\n\n|cFF44FF44Do not run on nameplates|r.", ["Player Logon"] = "Run when the player login into the game.\n\nUse to register textures, indicators, etc.\n\n|cFF44FF44Do not run on nameplates,\nrun only once after login\nor /reload|r.", ["Receive Comm Message"] = "Executed when a comm is received, a comm can be sent using Plater.SendComm(payload) in 'Send Comm Message' hook.", ["Send Comm Message"] = "Executed on an internal timer for each mod. Used to send comm data via Plater.SendComm(payload).", } -- ~hook (hook scripts are cached in the indexed part of these tales, for performance the member ScriptAmount caches the amount of scripts inside the indexed table) local HOOK_NAMEPLATE_ADDED = {ScriptAmount = 0} local HOOK_NAMEPLATE_CREATED = {ScriptAmount = 0} local HOOK_NAMEPLATE_REMOVED = {ScriptAmount = 0} local HOOK_NAMEPLATE_UPDATED = {ScriptAmount = 0} local HOOK_TARGET_CHANGED = {ScriptAmount = 0} local HOOK_CAST_START = {ScriptAmount = 0} local HOOK_CAST_UPDATE = {ScriptAmount = 0} local HOOK_CAST_STOP = {ScriptAmount = 0} local HOOK_RAID_TARGET = {ScriptAmount = 0} local HOOK_COMBAT_ENTER = {ScriptAmount = 0} local HOOK_COMBAT_LEAVE = {ScriptAmount = 0} local HOOK_NAMEPLATE_CONSTRUCTOR = {ScriptAmount = 0} local HOOK_PLAYER_POWER_UPDATE = {ScriptAmount = 0} local HOOK_PLAYER_TALENT_UPDATE = {ScriptAmount = 0} local HOOK_HEALTH_UPDATE = {ScriptAmount = 0} local HOOK_ZONE_CHANGED = {ScriptAmount = 0} local HOOK_UNITNAME_UPDATE = {ScriptAmount = 0} local HOOK_LOAD_SCREEN = {ScriptAmount = 0} local HOOK_PLAYER_LOGON = {ScriptAmount = 0} local HOOK_MOD_INITIALIZATION = {ScriptAmount = 0} local HOOK_MOD_DEINITIALIZATION = {ScriptAmount = 0} local HOOK_COMM_RECEIVED_MESSAGE = {ScriptAmount = 0} local HOOK_COMM_SEND_MESSAGE = {ScriptAmount = 0} local HOOK_NAMEPLATE_DESTRUCTOR = {ScriptAmount = 0} local PLATER_GLOBAL_MOD_ENV = {} -- contains modEnv for each mod, identified by "" local PLATER_GLOBAL_SCRIPT_ENV = {} -- contains modEnv for each script, identified by "