local Details = _G.Details
local Loc = LibStub ( " AceLocale-3.0 " ) : GetLocale ( " Details " )
local _
local addonName , Details222 = ...
local detailsFramework = DetailsFramework
---return the current profile name
---@return string
function Details : GetCurrentProfileName ( )
if ( _detalhes_database.active_profile == " " ) then
local characterKey = UnitName ( " player " ) .. " - " .. GetRealmName ( )
_detalhes_database.active_profile = characterKey
end
return _detalhes_database.active_profile
end
---create a new profile
---@param profileName string
---@return boolean|table
function Details : CreateProfile ( profileName )
if ( not profileName or type ( profileName ) ~= " string " or profileName == " " ) then
return false
end
--check if already exists
if ( _detalhes_global.__profiles [ profileName ] ) then
return false
end
--copy the default table
local newProfile = Details.CopyTable ( Details.default_profile )
newProfile.instances = { }
--add to global container
_detalhes_global.__profiles [ profileName ] = newProfile
--end
return newProfile
end
---return the list os all profiles
---@return table
function Details : GetProfileList ( )
local profileList = { }
for profileName in pairs ( _detalhes_global.__profiles ) do
profileList [ # profileList + 1 ] = profileName
end
return profileList
end
---delete a profile
---@param profileName string|nil
---@return boolean
function Details : EraseProfile ( profileName )
if ( not profileName ) then
return false
end
--erase the profile from the profile container
_detalhes_global.__profiles [ profileName ] = nil
if ( _detalhes_database.active_profile == profileName ) then
local characterKey = UnitName ( " player " ) .. " - " .. GetRealmName ( )
local profile = Details : GetProfile ( characterKey )
if ( profile ) then
Details : ApplyProfile ( characterKey , true )
else
Details : CreateProfile ( characterKey )
Details : ApplyProfile ( characterKey , true )
end
end
return true
end
---return the profile table requested
---@param profileName string
---@param create boolean
---@return table|boolean
function Details : GetProfile ( profileName , create )
if ( not profileName ) then
profileName = Details : GetCurrentProfileName ( )
end
local profile = _detalhes_global.__profiles [ profileName ]
if ( not profile and not create ) then
return false
elseif ( not profile and create ) then
profile = Details : CreateProfile ( profileName )
end
return profile
end
function Details : SetProfileCProp ( name , cprop , value )
if ( not name ) then
name = Details : GetCurrentProfileName ( )
end
local profile = Details : GetProfile ( name , false )
if ( profile ) then
if ( type ( value ) == " table " ) then
rawset ( profile , cprop , Details.CopyTable ( value ) )
else
rawset ( profile , cprop , value )
end
else
return
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--Profiles:
--reset the profile
function Details : ResetProfile ( profile_name )
--get the profile
local profile = Details : GetProfile ( profile_name , true )
if ( not profile ) then
return false
end
--reset all already created instances
for index , instance in Details : ListInstances ( ) do
if ( not instance.baseframe ) then
instance : AtivarInstancia ( )
end
instance.skin = " "
instance : ChangeSkin ( Details.default_skin_to_use )
end
for index , instance in pairs ( Details.unused_instances ) do
if ( not instance.baseframe ) then
instance : AtivarInstancia ( )
end
instance.skin = " "
instance : ChangeSkin ( Details.default_skin_to_use )
end
--reset the profile
Details : Destroy ( profile.instances )
--export first instance
local instance = Details : GetInstance ( 1 )
local exported = instance : ExportSkin ( )
exported.__was_opened = instance : IsEnabled ( )
exported.__pos = Details.CopyTable ( instance : GetPosition ( ) )
exported.__locked = instance.isLocked
exported.__snap = { }
exported.__snapH = false
exported.__snapV = false
profile.instances [ 1 ] = exported
instance.horizontalSnap = false
instance.verticalSnap = false
instance.snap = { }
Details : ApplyProfile ( profile_name , true )
--end
return true
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--Profiles:
--return the profile table requested
function Details : CreatePanicWarning ( )
Details.instance_load_failed = CreateFrame ( " frame " , " DetailsPanicWarningFrame " , UIParent , " BackdropTemplate " )
Details.instance_load_failed : SetHeight ( 80 )
--tinsert(UISpecialFrames, "DetailsPanicWarningFrame")
Details.instance_load_failed . text = Details.instance_load_failed : CreateFontString ( nil , " overlay " , " GameFontNormal " )
Details.instance_load_failed . text : SetPoint ( " center " , Details.instance_load_failed , " center " )
Details.instance_load_failed . text : SetTextColor ( 1 , 0.6 , 0 )
Details.instance_load_failed : SetBackdrop ( { bgFile = [[Interface\Tooltips\UI-Tooltip-Background]] , tileSize = 64 , tile = true } )
Details.instance_load_failed : SetBackdropColor ( 1 , 0 , 0 , 0.2 )
Details.instance_load_failed : SetPoint ( " topleft " , UIParent , " topleft " , 0 , - 250 )
Details.instance_load_failed : SetPoint ( " topright " , UIParent , " topright " , 0 , - 250 )
end
local safe_load = function ( func , param1 , ... )
local okey , errortext = pcall ( func , param1 , ... )
if ( not okey ) then
if ( not Details.instance_load_failed ) then
Details : CreatePanicWarning ( )
end
Details.do_not_save_skins = true
Details.instance_load_failed . text : SetText ( " Failed to load a Details! window. \n /reload or reboot the game client may fix the problem. \n If the problem persist, try /details reinstall. \n Error: " .. errortext .. " " )
end
return okey
end
function Details : ApplyProfile ( profileName , bNoSave , bIsCopy )
--get the profile
local profile = Details : GetProfile ( profileName , true )
--if the profile doesn't exist, just quit
if ( not profile ) then
Details : Msg ( " Profile Not Found. " )
return false
end
profile.ocd_tracker = nil --moved to local character saved
--always save the previous profile, except if nosave flag is up
if ( not bNoSave ) then
--salva o profile ativo no momento
Details : SaveProfile ( )
end
--update profile keys before go
for key , value in pairs ( Details.default_profile ) do
--the entire key doesn't exist
if ( profile [ key ] == nil ) then
if ( type ( value ) == " table " ) then
profile [ key ] = Details.CopyTable ( Details.default_profile [ key ] )
else
profile [ key ] = value
end
--the key exist and is a table, check for missing values on sub tables
elseif ( type ( value ) == " table " ) then
--deploy only copy non existing data
Details.table . deploy ( profile [ key ] , value )
end
end
--apply the profile values
for key , _ in pairs ( Details.default_profile ) do
local value = profile [ key ]
if ( type ( value ) == " table " ) then
if ( key == " class_specs_coords " ) then
value = Details.CopyTable ( Details.default_profile . class_specs_coords )
end
local ctable = Details.CopyTable ( value )
Details [ key ] = ctable
else
Details [ key ] = value
end
end
--set the current profile
if ( not bIsCopy ) then
Details.active_profile = profileName
_detalhes_database.active_profile = profileName
end
--apply the skin
--first save the local instance configs
Details : SaveLocalInstanceConfig ( )
local saved_skins = profile.instances
local instance_limit = Details.instances_amount
--then close all opened instances
for index , instance in Details : ListInstances ( ) do
if ( not getmetatable ( instance ) ) then
instance.iniciada = false
setmetatable ( instance , Details )
end
if ( instance : IsStarted ( ) ) then
if ( instance : IsEnabled ( ) ) then
instance : ShutDown ( )
end
end
end
--check if there is a skin saved or this is a empty profile
if ( # saved_skins == 0 ) then
local instance1 = Details : GetInstance ( 1 )
if ( not instance1 ) then
instance1 = Details : CreateInstance ( 1 )
end
--apply default config on this instance (flat skin texture was 'ResetInstanceConfig' running).
instance1.modo = 2
instance1 : ResetInstanceConfig ( )
instance1.skin = " no skin "
instance1 : ChangeSkin ( Details.default_skin_to_use )
--release the snap and lock
instance1 : LoadLocalInstanceConfig ( )
instance1.snap = { }
instance1.horizontalSnap = nil
instance1.verticalSnap = nil
instance1 : LockInstance ( false )
if ( # Details.tabela_instancias > 1 ) then
for i = # Details.tabela_instancias , 2 , - 1 do
Details.tabela_instancias [ i ] . modo = 2
Details.unused_instances [ i ] = Details.tabela_instancias [ i ]
Details.tabela_instancias [ i ] = nil
end
end
else
--load skins
local instances_loaded = 0
for index , skin in ipairs ( saved_skins ) do
if ( instance_limit < index ) then
break
end
--get the instance
local instance = Details : GetInstance ( index )
if ( not instance ) then
--create a instance without creating its frames (not initializing)
instance = Details : CreateDisabledInstance ( index , skin )
end
--copy skin
for key , value in pairs ( skin ) do
if ( type ( value ) == " table " ) then
instance [ key ] = Details.CopyTable ( value )
else
instance [ key ] = value
end
end
--apply default values if some key is missing
instance : LoadInstanceConfig ( )
--reset basic config
instance.snap = { }
instance.horizontalSnap = nil
instance.verticalSnap = nil
instance : LockInstance ( false )
--load data saved for this character only
instance : LoadLocalInstanceConfig ( )
if ( skin.__was_opened ) then
if ( not safe_load ( Details.AtivarInstancia , instance , nil , true ) ) then
return
end
else
instance.ativa = false
end
instance.modo = instance.modo or 2
--load data saved again
instance : LoadLocalInstanceConfig ( )
--check window positioning
if ( Details.profile_save_pos ) then
--print("is profile save pos", skin.__pos.normal.x, skin.__pos.normal.y)
if ( skin.__pos ) then
instance.posicao = Details.CopyTable ( skin.__pos )
else
if ( not instance.posicao ) then
print ( " |cFFFF2222Details!: Position for a window wasn't found! Moving it to the center of the screen.|r \n Type '/details exitlog' to check for errors. " )
instance.posicao = { normal = { x = 1 , y = 1 , w = 300 , h = 200 } , solo = { } }
elseif ( not instance.posicao . normal ) then
print ( " |cFFFF2222Details!: Normal position for a window wasn't found! Moving it to the center of the screen.|r \n Type '/details exitlog' to check for errors. " )
instance.posicao . normal = { x = 1 , y = 1 , w = 300 , h = 200 }
end
end
instance.isLocked = skin.__locked
instance.snap = Details.CopyTable ( skin.__snap ) or { }
instance.horizontalSnap = skin.__snapH
instance.verticalSnap = skin.__snapV
else
if ( not instance.posicao ) then
instance.posicao = { normal = { x = 1 , y = 1 , w = 300 , h = 200 } , solo = { } }
elseif ( not instance.posicao . normal ) then
instance.posicao . normal = { x = 1 , y = 1 , w = 300 , h = 200 }
end
end
--open the instance
if ( instance : IsEnabled ( ) ) then
if ( not instance.baseframe ) then
instance : AtivarInstancia ( )
end
instance : LockInstance ( instance.isLocked )
--tinsert(Details.resize_debug, #Details.resize_debug+1, "libwindow X (427): " .. (instance.libwindow.x or 0))
instance : RestoreMainWindowPosition ( )
instance : ReajustaGump ( )
--instance:SaveMainWindowPosition()
--Load StatusBarSaved values and options.
instance.StatusBarSaved = skin.StatusBarSaved or { options = { } }
instance.StatusBar . options = instance.StatusBarSaved . options
Details.StatusBar : UpdateChilds ( instance )
instance : ChangeSkin ( )
else
instance.skin = skin.skin
end
instances_loaded = instances_loaded + 1
end
--move unused instances for unused container
if ( # Details.tabela_instancias > instances_loaded ) then
for i = # Details.tabela_instancias , instances_loaded + 1 , - 1 do
Details.unused_instances [ i ] = Details.tabela_instancias [ i ]
Details.tabela_instancias [ i ] = nil
end
end
--check all snaps for invalid entries
for i = 1 , instances_loaded do
local instance = Details : GetInstance ( i )
local previous_instance_id = Details : GetInstance ( i - 1 ) and Details : GetInstance ( i - 1 ) : GetId ( ) or 0
local next_instance_id = Details : GetInstance ( i + 1 ) and Details : GetInstance ( i + 1 ) : GetId ( ) or 0
for snap_side , instance_id in pairs ( instance.snap ) do
if ( instance_id < 1 ) then --invalid instance
instance.snap [ snap_side ] = nil
elseif ( instance_id ~= previous_instance_id and instance_id ~= next_instance_id ) then --no match
instance.snap [ snap_side ] = nil
end
end
end
--auto realign windows
if ( not Details.initializing ) then
for _ , instance in Details : ListInstances ( ) do
if ( instance : IsEnabled ( ) ) then
Details.move_janela_func ( instance.baseframe , true , instance )
Details.move_janela_func ( instance.baseframe , false , instance )
end
end
else
--is in startup
for _ , instance in Details : ListInstances ( ) do
for side , id in pairs ( instance.snap ) do
local window = Details.tabela_instancias [ id ]
if ( not window.ativa ) then
instance.snap [ side ] = nil
if ( ( side == 1 or side == 3 ) and ( not instance.snap [ 1 ] and not instance.snap [ 3 ] ) ) then
instance.horizontalSnap = false
elseif ( ( side == 2 or side == 4 ) and ( not instance.snap [ 2 ] and not instance.snap [ 4 ] ) ) then
instance.verticalSnap = false
end
end
end
if ( not instance : IsEnabled ( ) ) then
for side , id in pairs ( instance.snap ) do
instance.snap [ side ] = nil
end
instance.horizontalSnap = false
instance.verticalSnap = false
end
end
end
end
--check instance amount
Details.opened_windows = 0
for index = 1 , Details.instances_amount do
local instance = Details.tabela_instancias [ index ]
if ( instance and instance.ativa ) then
Details.opened_windows = Details.opened_windows + 1
end
end
--update tooltip settings
Details : SetTooltipBackdrop ( )
--update the numerical system
Details : SelectNumericalSystem ( )
--refresh the update interval
Details : RefreshUpdater ( )
--refresh animation functions
Details : RefreshAnimationFunctions ( )
--refresh broadcaster tools
Details : LoadFramesForBroadcastTools ( )
--change the rogue spec combat icon to outlaw depending on the game version
Details : HandleRogueCombatSpecIconByGameVersion ( )
if ( Details.initializing ) then
Details.profile_loaded = true
end
Details : SendEvent ( " DETAILS_PROFILE_APPLYED " , profileName )
--to be removed in the future (2023-08-13)
if ( Details.time_type == 3 or not Details.time_type ) then
Details.time_type = 2
end
--enable all captures, this is a fix for the old performance profiles which doesn't exiss anymore
Details.capture_real [ " damage " ] = true
Details.capture_real [ " heal " ] = true
Details.capture_real [ " energy " ] = true
Details.capture_real [ " miscdata " ] = true
Details.capture_real [ " aura " ] = true
Details.capture_real [ " spellcast " ] = true
return true
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--Profiles:
--return the profile table requested
function Details : SaveProfile ( saveas )
--get the current profile
local profile_name
if ( saveas ) then
profile_name = saveas
else
profile_name = Details : GetCurrentProfileName ( )
end
local profile = Details : GetProfile ( profile_name , true )
--save default keys
for key , _ in pairs ( Details.default_profile ) do
local current_value = Details [ key ]
if ( type ( current_value ) == " table " ) then
local ctable = Details.CopyTable ( current_value )
profile [ key ] = ctable
else
profile [ key ] = current_value
end
end
--save skins
if ( not Details.do_not_save_skins ) then
Details : Destroy ( profile.instances )
for index , instance in ipairs ( Details.tabela_instancias ) do
local exported = instance : ExportSkin ( )
exported.__was_opened = instance : IsEnabled ( )
exported.__pos = Details.CopyTable ( instance : GetPosition ( ) )
exported.__locked = instance.isLocked
exported.__snap = Details.CopyTable ( instance.snap )
exported.__snapH = instance.horizontalSnap
exported.__snapV = instance.verticalSnap
profile.instances [ index ] = exported
end
end
Details.do_not_save_skins = nil
Details : SaveLocalInstanceConfig ( )
return profile
end
local default_profile = {
--spec coords, reset with: /run Details.class_specs_coords = nil
class_specs_coords = {
[ 577 ] = { 128 / 512 , 192 / 512 , 256 / 512 , 320 / 512 } , --havoc demon hunter
[ 581 ] = { 192 / 512 , 256 / 512 , 256 / 512 , 320 / 512 } , --vengeance demon hunter
[ 250 ] = { 0 , 64 / 512 , 0 , 64 / 512 } , --blood dk
[ 251 ] = { 64 / 512 , 128 / 512 , 0 , 64 / 512 } , --frost dk
[ 252 ] = { 128 / 512 , 192 / 512 , 0 , 64 / 512 } , --unholy dk
[ 102 ] = { 192 / 512 , 256 / 512 , 0 , 64 / 512 } , -- druid balance
[ 103 ] = { 256 / 512 , 320 / 512 , 0 , 64 / 512 } , -- druid feral
[ 104 ] = { 320 / 512 , 384 / 512 , 0 , 64 / 512 } , -- druid guardian
[ 105 ] = { 384 / 512 , 448 / 512 , 0 , 64 / 512 } , -- druid resto
[ 253 ] = { 448 / 512 , 512 / 512 , 0 , 64 / 512 } , -- hunter bm
[ 254 ] = { 0 , 64 / 512 , 64 / 512 , 128 / 512 } , --hunter marks
[ 255 ] = { 64 / 512 , 128 / 512 , 64 / 512 , 128 / 512 } , --hunter survivor
[ 62 ] = { ( 128 / 512 ) + 0.001953125 , 192 / 512 , 64 / 512 , 128 / 512 } , --mage arcane
[ 63 ] = { 192 / 512 , 256 / 512 , 64 / 512 , 128 / 512 } , --mage fire
[ 64 ] = { 256 / 512 , 320 / 512 , 64 / 512 , 128 / 512 } , --mage frost
[ 268 ] = { 320 / 512 , 384 / 512 , 64 / 512 , 128 / 512 } , --monk bm
[ 269 ] = { 448 / 512 , 512 / 512 , 64 / 512 , 128 / 512 } , --monk ww
[ 270 ] = { 384 / 512 , 448 / 512 , 64 / 512 , 128 / 512 } , --monk mw
[ 65 ] = { 0 , 64 / 512 , 128 / 512 , 192 / 512 } , --paladin holy
[ 66 ] = { 64 / 512 , 128 / 512 , 128 / 512 , 192 / 512 } , --paladin protect
[ 70 ] = { ( 128 / 512 ) + 0.001953125 , 192 / 512 , 128 / 512 , 192 / 512 } , --paladin ret
[ 256 ] = { 192 / 512 , 256 / 512 , 128 / 512 , 192 / 512 } , --priest disc
[ 257 ] = { 256 / 512 , 320 / 512 , 128 / 512 , 192 / 512 } , --priest holy
[ 258 ] = { ( 320 / 512 ) + ( 0.001953125 * 4 ) , 384 / 512 , 128 / 512 , 192 / 512 } , --priest shadow
[ 259 ] = { 384 / 512 , 448 / 512 , 128 / 512 , 192 / 512 } , --rogue assassination
[ 260 ] = { 448 / 512 , 512 / 512 , 128 / 512 , 192 / 512 } , --rogue combat
[ 261 ] = { 0 , 64 / 512 , 192 / 512 , 256 / 512 } , --rogue sub
[ 262 ] = { 64 / 512 , 128 / 512 , 192 / 512 , 256 / 512 } , --shaman elemental
[ 263 ] = { 128 / 512 , 192 / 512 , 192 / 512 , 256 / 512 } , --shamel enhancement
[ 264 ] = { 192 / 512 , 256 / 512 , 192 / 512 , 256 / 512 } , --shaman resto
[ 265 ] = { 256 / 512 , 320 / 512 , 192 / 512 , 256 / 512 } , --warlock aff
[ 266 ] = { 320 / 512 , 384 / 512 , 192 / 512 , 256 / 512 } , --warlock demo
[ 267 ] = { 384 / 512 , 448 / 512 , 192 / 512 , 256 / 512 } , --warlock destro
[ 71 ] = { 448 / 512 , 512 / 512 , 192 / 512 , 256 / 512 } , --warrior arms
[ 72 ] = { 0 , 64 / 512 , 256 / 512 , 320 / 512 } , --warrior fury
[ 73 ] = { 64 / 512 , 128 / 512 , 256 / 512 , 320 / 512 } , --warrior protect
[ 1467 ] = { 256 / 512 , 320 / 512 , 256 / 512 , 320 / 512 } , -- Devastation
[ 1468 ] = { 320 / 512 , 384 / 512 , 256 / 512 , 320 / 512 } , -- Preservation
[ 1473 ] = { 384 / 512 , 448 / 512 , 256 / 512 , 320 / 512 } , -- Augmentation
} ,
--class icons and colors
class_icons_small = [[Interface\AddOns\Details\images\classes_small]] ,
class_coords = {
[ " DEMONHUNTER " ] = {
0.73828126 / 2 , -- [1]
1 / 2 , -- [2]
0.5 / 2 , -- [3]
0.75 / 2 , -- [4]
} ,
[ " HUNTER " ] = {
0 , -- [1]
0.25 / 2 , -- [2]
0.25 / 2 , -- [3]
0.5 / 2 , -- [4]
} ,
[ " WARRIOR " ] = {
0 , -- [1]
0.25 / 2 , -- [2]
0 , -- [3]
0.25 / 2 , -- [4]
} ,
[ " ROGUE " ] = {
0.49609375 / 2 , -- [1]
0.7421875 / 2 , -- [2]
0 , -- [3]
0.25 / 2 , -- [4]
} ,
[ " MAGE " ] = {
0.25 / 2 , -- [1]
0.49609375 / 2 , -- [2]
0 , -- [3]
0.25 / 2 , -- [4]
} ,
[ " PET " ] = {
0.25 / 2 , -- [1]
0.49609375 / 2 , -- [2]
0.75 / 2 , -- [3]
1 / 2 , -- [4]
} ,
[ " DRUID " ] = {
0.7421875 / 2 , -- [1]
0.98828125 / 2 , -- [2]
0 , -- [3]
0.25 / 2 , -- [4]
} ,
[ " MONK " ] = {
0.5 / 2 , -- [1]
0.73828125 / 2 , -- [2]
0.5 / 2 , -- [3]
0.75 / 2 , -- [4]
} ,
[ " DEATHKNIGHT " ] = {
0.25 / 2 , -- [1]
0.5 / 2 , -- [2]
0.5 / 2 , -- [3]
0.75 / 2 , -- [4]
} ,
[ " UNKNOW " ] = {
0.5 / 2 , -- [1]
0.75 / 2 , -- [2]
0.75 / 2 , -- [3]
1 / 2 , -- [4]
} ,
[ " PRIEST " ] = {
0.49609375 / 2 , -- [1]
0.7421875 / 2 , -- [2]
0.25 / 2 , -- [3]
0.5 / 2 , -- [4]
} ,
[ " UNGROUPPLAYER " ] = {
0.5 / 2 , -- [1]
0.75 / 2 , -- [2]
0.75 / 2 , -- [3]
1 / 2 , -- [4]
} ,
[ " Alliance " ] = {
0.49609375 / 2 , -- [1]
0.742187 / 25 , -- [2]
0.75 / 2 , -- [3]
1 / 2 , -- [4]
} ,
[ " WARLOCK " ] = {
0.7421875 / 2 , -- [1]
0.98828125 / 2 , -- [2]
0.25 / 2 , -- [3]
0.5 / 2 , -- [4]
} ,
[ " ENEMY " ] = {
0 , -- [1]
0.25 / 2 , -- [2]
0.75 / 2 , -- [3]
1 / 2 , -- [4]
} ,
[ " Horde " ] = {
0.7421875 / 2 , -- [1]
0.98828125 / 2 , -- [2]
0.75 / 2 , -- [3]
1 / 2 , -- [4]
} ,
[ " PALADIN " ] = {
0 , -- [1]
0.25 / 2 , -- [2]
0.5 / 2 , -- [3]
0.75 / 2 , -- [4]
} ,
[ " MONSTER " ] = {
0 , -- [1]
0.25 / 2 , -- [2]
0.75 / 2 , -- [3]
1 / 2 , -- [4]
} ,
[ " SHAMAN " ] = {
0.25 / 2 , -- [1]
0.49609375 / 2 , -- [2]
0.25 / 2 , -- [3]
0.5 / 2 , -- [4]
} ,
[ " EVOKER " ] = {
0.50390625 , -- [1]
0.625 , -- [2]
0 , -- [3]
0.125 , -- [4]
} ,
} ,
class_colors = {
[ " DEMONHUNTER " ] = {
0.64 ,
0.19 ,
0.79 ,
} ,
[ " HUNTER " ] = {
0.67 , -- [1]
0.83 , -- [2]
0.45 , -- [3]
} ,
[ " WARRIOR " ] = {
0.78 , -- [1]
0.61 , -- [2]
0.43 , -- [3]
} ,
[ " PALADIN " ] = {
0.96 , -- [1]
0.55 , -- [2]
0.73 , -- [3]
} ,
[ " SHAMAN " ] = {
0 , -- [1]
0.44 , -- [2]
0.87 , -- [3]
} ,
[ " MAGE " ] = {
0.41 , -- [1]
0.8 , -- [2]
0.94 , -- [3]
} ,
[ " ROGUE " ] = {
1 , -- [1]
0.96 , -- [2]
0.41 , -- [3]
} ,
[ " UNKNOW " ] = {
0.2 , -- [1]
0.2 , -- [2]
0.2 , -- [3]
} ,
[ " PRIEST " ] = {
1 , -- [1]
1 , -- [2]
1 , -- [3]
} ,
[ " WARLOCK " ] = {
0.58 , -- [1]
0.51 , -- [2]
0.79 , -- [3]
} ,
[ " UNGROUPPLAYER " ] = {
0.4 , -- [1]
0.4 , -- [2]
0.4 , -- [3]
} ,
[ " ENEMY " ] = {
0.94117 , -- [1]
0 , -- [2]
0.0196 , -- [3]
1 , -- [4]
} ,
[ " version " ] = 1 ,
[ " PET " ] = {
0.3 , -- [1]
0.4 , -- [2]
0.5 , -- [3]
} ,
[ " DRUID " ] = {
1 , -- [1]
0.49 , -- [2]
0.04 , -- [3]
} ,
[ " MONK " ] = {
0 , -- [1]
1 , -- [2]
0.59 , -- [3]
} ,
[ " DEATHKNIGHT " ] = {
0.77 , -- [1]
0.12 , -- [2]
0.23 , -- [3]
} ,
[ " ARENA_GREEN " ] = {
0.686 , -- [1]
0.372 , -- [2]
0.905 , -- [3]
} ,
[ " ARENA_YELLOW " ] = {
1 , -- [1]
1 , -- [2]
0.25 , -- [3]
} ,
[ " NEUTRAL " ] = {
1 , -- [1]
1 , -- [2]
0 , -- [3]
} ,
[ " SELF " ] = {
0.89019 , -- [1]
0.32156 , -- [2]
0.89019 , -- [3]
} ,
[ " EVOKER " ] = {
--0.2000,
--0.4980,
--0.5764,
0.2000 ,
0.5764 ,
0.4980 ,
} ,
} ,
death_log_colors = {
damage = " red " ,
heal = " green " ,
friendlyfire = " darkorange " ,
cooldown = " yellow " ,
debuff = " purple " ,
buff = " silver " ,
} ,
fade_speed = 0.15 ,
use_self_color = false ,
--minimap
minimap = { hide = false , radius = 160 , minimapPos = 220 , onclick_what_todo = 1 , text_type = 1 , text_format = 3 } ,
data_broker_text = " " ,
--hotcorner
hotcorner_topleft = { hide = false } ,
--PvP
only_pvp_frags = false ,
color_by_arena_team = true ,
show_arena_role_icon = false , --deprecated: this has been moved to instance settings 05.06.22 (tercio)
--window settings
max_window_size = { width = 480 , height = 450 } ,
new_window_size = { width = 310 , height = 158 } ,
window_clamp = { - 8 , 0 , 21 , - 14 } ,
grouping_horizontal_gap = 0 ,
disable_window_groups = false ,
disable_reset_button = false ,
disable_lock_ungroup_buttons = false ,
disable_stretch_from_toolbar = false ,
disable_stretch_button = false ,
disable_alldisplays_window = false ,
damage_taken_everything = false ,
--info window
player_details_window = {
skin = " ElvUI " ,
bar_texture = " Skyline " ,
scale = 1 ,
} ,
options_window = {
scale = 1 ,
} ,
--segments
segments_amount = 40 ,
segments_amount_to_save = 40 ,
segments_panic_mode = false ,
segments_auto_erase = 1 ,
--instances
instances_amount = 5 ,
instances_segments_locked = true ,
instances_disable_bar_highlight = false ,
instances_menu_click_to_open = false ,
instances_no_libwindow = false ,
instances_suppress_trash = 0 ,
--if clear ungroup characters when logout
clear_ungrouped = true ,
--if clear graphic data when logout
clear_graphic = true ,
--item level tracker
track_item_level = false ,
--text settings
font_sizes = { menus = 10 } ,
font_faces = { menus = " Friz Quadrata TT " } ,
ps_abbreviation = 3 ,
total_abbreviation = 2 ,
numerical_system = 1 ,
numerical_system_symbols = " auto " ,
--performance
use_row_animations = true ,
--default animation speed - % per second
animation_speed = 33 ,
--percent to trigger fast speed - if the percent is hiogher than this it will increase the speed
animation_speed_triggertravel = 5 ,
--minumim speed multiplication value
animation_speed_mintravel = 0.45 ,
--max speed multiplication value
animation_speed_maxtravel = 3 ,
animate_scroll = false ,
use_scroll = false ,
scroll_speed = 2 ,
update_speed = 0.20 ,
time_type = 2 ,
time_type_original = 2 ,
use_realtimedps = false ,
realtimedps_order_bars = false ,
realtimedps_always_arena = false ,
memory_threshold = 3 ,
memory_ram = 64 ,
remove_realm_from_name = true ,
trash_concatenate = false ,
trash_auto_remove = false ,
world_combat_is_trash = false ,
--death log
deadlog_limit = 16 ,
deadlog_events = 32 ,
--report
report_lines = 5 ,
report_to_who = " " ,
report_heal_links = false ,
report_schema = 1 ,
deny_score_messages = false ,
--colors
default_bg_color = 0.0941 ,
default_bg_alpha = 0.5 ,
--fades
row_fade_in = { " in " , 0.2 } ,
windows_fade_in = { " in " , 0.2 } ,
row_fade_out = { " out " , 0.2 } ,
windows_fade_out = { " out " , 0.2 } ,
--captures
capture_real = {
[ " damage " ] = true ,
[ " heal " ] = true ,
[ " energy " ] = true ,
[ " miscdata " ] = true ,
[ " aura " ] = true ,
[ " spellcast " ] = true ,
} ,
--bookmark
bookmark_text_size = 11 ,
--cloud capture
cloud_capture = true ,
--combat
minimum_combat_time = 5 , --combats with less then this in elapsed time is discarted
minimum_overall_combat_time = 10 , --minimum time the combat must have to be added into the overall data
overall_flag = 0x10 ,
overall_clear_newboss = true ,
overall_clear_newchallenge = true ,
overall_clear_newtorghast = true ,
overall_clear_logout = false ,
overall_clear_pvp = true ,
data_cleanup_logout = false ,
close_shields = false ,
pvp_as_group = true ,
use_battleground_server_parser = false ,
force_activity_time_pvp = true ,
death_tooltip_width = 350 ,
death_tooltip_spark = false ,
death_tooltip_texture = " Details Serenity " ,
override_spellids = true ,
all_players_are_group = false ,
--skins
standard_skin = false ,
skin = " Minimalistic " ,
profile_save_pos = true ,
options_group_edit = true ,
chat_tab_embed = {
enabled = false ,
tab_name = " " ,
single_window = false ,
x_offset = 0 ,
y_offset = 0 ,
} ,
--broadcaster options
broadcaster_enabled = false ,
--event tracker
event_tracker = {
frame = {
locked = false ,
width = 250 ,
height = 300 ,
backdrop_color = { 0.1921 , 0.1921 , 0.1921 , 0.3869 } ,
show_title = true ,
strata = " LOW " ,
} ,
options_frame = { } ,
enabled = false ,
font_size = 10 ,
font_color = { 1 , 1 , 1 , 1 } ,
font_shadow = " NONE " ,
font_face = " Friz Quadrata TT " ,
line_height = 16 ,
line_texture = " Details Serenity " ,
line_color = { .1 , .1 , .1 , 0.3 } ,
show_crowdcontrol_pvp = true ,
show_crowdcontrol_pvm = false ,
} ,
--current damage
realtime_dps_meter = {
frame_settings = {
locked = true ,
width = 300 ,
height = 23 ,
backdrop_color = { 0 , 0 , 0 , 0.2 } ,
show_title = true ,
strata = " LOW " ,
--libwindow
point = " TOP " ,
scale = 1 ,
y = - 110 ,
x = 0 ,
} ,
options_frame = { } ,
enabled = false ,
arena_enabled = true ,
mythic_dungeon_enabled = false ,
font_size = 18 ,
font_color = { 1 , 1 , 1 , 1 } ,
font_shadow = " NONE " ,
font_face = " Friz Quadrata TT " ,
text_offset = 2 ,
update_interval = 0.30 ,
sample_size = 3 , --in seconds
} ,
--streamer
-- Details.streamer_config.
streamer_config = {
reset_spec_cache = false ,
disable_mythic_dungeon = false ,
no_alerts = false ,
quick_detection = false ,
faster_updates = false ,
use_animation_accel = true ,
} ,
--tooltip
tooltip = {
fontface = " Friz Quadrata TT " ,
fontsize = 10 ,
fontsize_title = 10 ,
fontcolor = { 1 , 1 , 1 , 1 } ,
fontcolor_right = { 1 , 0.7 , 0 , 1 } , --{1, 0.9254, 0.6078, 1}
fontshadow = false ,
bar_color = { 0.3960 , 0.3960 , 0.3960 , 0.8700 } ,
background = { 0.0941 , 0.0941 , 0.0941 , 0.8 } ,
divisor_color = { 1 , 1 , 1 , 1 } ,
abbreviation = 2 , -- 2 = ToK I Upper 5 = ToK I Lower -- was 8
maximize_method = 1 ,
show_amount = false ,
commands = { } ,
header_text_color = { 1 , 0.9176 , 0 , 1 } , --{1, 0.7, 0, 1}
header_statusbar = { 0.3 , 0.3 , 0.3 , 0.8 , false , false , " WorldState Score " } ,
submenu_wallpaper = true ,
rounded_corner = true ,
anchored_to = 1 ,
anchor_screen_pos = { 507.700 , - 350.500 } ,
anchor_point = " bottom " ,
anchor_relative = " top " ,
anchor_offset = { 0 , 0 } ,
border_texture = " Details BarBorder 3 " ,
border_color = { 0 , 0 , 0 , 1 } ,
border_size = 14 ,
tooltip_max_abilities = 6 ,
tooltip_max_targets = 2 ,
tooltip_max_pets = 2 ,
--menus_bg_coords = {331/512, 63/512, 109/512, 143/512}, --with gradient on right side
menus_bg_coords = { 0.309777336120606 , 0.924000015258789 , 0.213000011444092 , 0.279000015258789 } ,
menus_bg_color = { .8 , .8 , .8 , 0.2 } ,
menus_bg_texture = [[Interface\SPELLBOOK\Spellbook-Page-1]] ,
icon_border_texcoord = { L = 5 / 64 , R = 59 / 64 , T = 5 / 64 , B = 59 / 64 } ,
icon_size = { W = 13 , H = 13 } ,
--height used on tooltips at displays such as damage taken by spell
line_height = 17 ,
} ,
--new window system
all_in_one_windows = { } ,
--auto show overall data in dynamic mode
auto_swap_to_dynamic_overall = false ,
}
Details.default_profile = default_profile
-- aqui fica as propriedades do jogador que n�o ser�o armazenadas no profile
local default_player_data = {
coach = {
enabled = false ,
welcome_panel_pos = { } ,
last_coach_name = false ,
} ,
player_stats = { } ,
combat_log = {
inverse_deathlog_raid = false ,
inverse_deathlog_mplus = false ,
inverse_deathlog_overalldata = false ,
track_hunter_frenzy = false ,
merge_gemstones_1007 = false ,
merge_critical_heals = false ,
calc_evoker_damage = true ,
evoker_show_realtimedps = false ,
} ,
--this is used by the new data capture for charts
data_harvest_for_charsts = {
players = {
--damage done by each player
{
name = " Damage of Each Individual Player " ,
combatObjectContainer = 1 ,
playerOnly = true ,
playerKey = " total " ,
} ,
} ,
totals = {
--total damage done by the raid group
{
name = " Damage of All Player Combined " ,
combatObjectSubTableName = " totals " ,
combatObjectSubTableKey = 1 ,
} ,
} ,
} ,
data_harvested_for_charts = { } ,
--ocd tracker test
ocd_tracker = {
enabled = false ,
cooldowns = { } ,
ignored_cooldowns = { } ,
frames = {
[ " defensive-raid " ] = { } ,
[ " defensive-target " ] = { } ,
[ " defensive-personal " ] = { } ,
[ " ofensive " ] = { } ,
[ " utility " ] = { } ,
[ " main " ] = { } , --any cooldown that does not have a frame is shown on main frame
} , --panels for each cooldown type
show_conditions = {
only_in_group = true ,
only_inside_instance = true ,
} ,
show_options = false ,
current_cooldowns = { } ,
framme_locked = false ,
filters = {
[ " defensive-raid " ] = false ,
[ " defensive-target " ] = false ,
[ " defensive-personal " ] = false ,
[ " ofensive " ] = true ,
[ " utility " ] = false ,
[ " itemheal " ] = false ,
[ " itempower " ] = false ,
[ " itemutil " ] = false ,
[ " crowdcontrol " ] = false ,
} , --when creating a filter, add it here and also add to 'own_frame'
own_frame = {
[ " defensive-raid " ] = false ,
[ " defensive-target " ] = false ,
[ " defensive-personal " ] = false ,
[ " ofensive " ] = false ,
[ " utility " ] = false ,
} ,
show_title = true ,
group_frames = true ,
width = 120 ,
height = 18 ,
lines_per_column = 12 ,
} ,
--mythic plus log
mythic_plus_log = { } ,
--force all fonts to have this outline
force_font_outline = " " ,
--current combat number
cached_specs = { } ,
cached_talents = { } ,
cached_roles = { } ,
last_day = date ( " %d " ) ,
combat_id = 0 ,
combat_counter = 0 ,
last_instance_id = 0 ,
last_instance_time = 0 ,
mythic_dungeon_id = 0 ,
mythic_dungeon_currentsaved = {
started = false ,
run_id = 0 ,
dungeon_name = " " ,
dungeon_zone_id = 0 ,
started_at = 0 ,
segment_id = 0 ,
level = 0 ,
ej_id = 0 ,
previous_boss_killed_at = 0 ,
} ,
--nicktag cache
nick_tag_cache = { } ,
ignore_nicktag = false ,
--plugin data
plugin_database = { } ,
--information about this character
character_data = { logons = 0 } ,
--version
last_realversion = Details.realversion ,
last_version = " v1.0.0 " ,
--profile
active_profile = " " ,
--plugins tables
SoloTablesSaved = { } ,
RaidTablesSaved = { } ,
--saved skins
savedStyles = { } ,
--instance config
local_instances_config = { } ,
--announcements
announce_deaths = {
enabled = false ,
only_first = 5 ,
last_hits = 1 ,
where = 1 ,
} ,
announce_cooldowns = {
enabled = false ,
channel = " RAID " ,
ignored_cooldowns = { } ,
custom = " " ,
} ,
announce_interrupts = {
enabled = false ,
channel = " SAY " ,
whisper = " " ,
next = " " ,
custom = " " ,
} ,
announce_prepots = {
enabled = true ,
reverse = false ,
channel = " SELF " ,
} ,
announce_firsthit = {
enabled = true ,
channel = " SELF " ,
} ,
announce_damagerecord = {
enabled = true ,
channel = " SELF " ,
} ,
--benchmark
benchmark_db = {
frame = { } ,
} ,
--rank
rank_window = {
last_difficulty = 15 ,
last_raid = " " ,
} ,
--death panel buttons
on_death_menu = false ,
}
Details.default_player_data = default_player_data
local default_global_data = {
--profile pool
__profiles = { } ,
latest_news_saw = " " ,
always_use_profile = false ,
always_use_profile_name = " " ,
always_use_profile_exception = { } ,
custom = { } ,
savedStyles = { } ,
savedCustomSpells = { } ,
userCustomSpells = { } , --spells modified by the user
savedTimeCaptures = { } ,
lastUpdateWarning = 0 ,
update_warning_timeout = 10 ,
report_where = " SAY " ,
realm_sync = true , --deprecated
spell_school_cache = { } ,
global_plugin_database = { } ,
last_changelog_size = 0 ,
auto_open_news_window = true ,
immersion_special_units = true , --show a special unit as member of your group
immersion_unit_special_icons = true , --custom icons for specific units
immersion_pets_on_solo_play = false , --pets showing when solo play
damage_scroll_auto_open = true ,
damage_scroll_position = {
scale = 1 ,
} ,
data_wipes_exp = {
[ " 9 " ] = false ,
[ " 10 " ] = false ,
[ " 11 " ] = false ,
[ " 12 " ] = false ,
[ " 13 " ] = false ,
[ " 14 " ] = false ,
} ,
current_exp_raid_encounters = { } ,
encounter_journal_cache = { } , --store a dump of the encounter journal
installed_skins_cache = { } ,
user_is_patreon_supporter = false ,
show_aug_predicted_spell_damage = false ,
show_warning_id1 = true ,
show_warning_id1_amount = 0 ,
combat_id_global = 0 ,
slash_me_used = false ,
trinket_data = { } ,
merge_pet_abilities = false ,
merge_player_abilities = false ,
played_class_time = true ,
check_stuttering = false ,
--[bossname] = texture
boss_icon_cache = { } ,
--spell category feedback
spell_category_savedtable = { } ,
spell_category_latest_query = 0 ,
spell_category_latest_save = 0 ,
spell_category_latest_sent = 0 ,
--class time played
class_time_played = { } ,
--keystone cache
keystone_cache = { } ,
--all switch settings (panel shown when right click the title bar)
all_switch_config = {
scale = 1 ,
font_size = 10 ,
} ,
--keystone window
keystone_frame = {
scale = 1 ,
position = { } ,
} ,
--ask to erase data frame
ask_to_erase_frame = {
scale = 1 ,
position = { } ,
} ,
--aura tracker panel
aura_tracker_frame = {
position = { } , --for libwindow
scaletable = {
scale = 1
} ,
} ,
breakdown_general = {
font_size = 11 ,
font_color = { 0.9 , 0.9 , 0.9 , 0.923 } ,
font_outline = " NONE " ,
font_face = " DEFAULT " ,
bar_texture = " Skyline " ,
} ,
frame_background_color = { 0.1215 , 0.1176 , 0.1294 , 0.8 } ,
--/run Details.breakdown_spell_tab.spellcontainer_height = 311 --352
--breakdown spell tab
breakdown_spell_tab = {
--player spells
nest_players_spells_with_same_name = true ,
--pet spells
nest_pet_spells_by_name = false ,
nest_pet_spells_by_caster = true ,
blockcontainer_width = 430 ,
blockcontainer_height = 270 ,
blockcontainer_islocked = true ,
statusbar_background_color = { .15 , .15 , .15 } ,
statusbar_background_alpha = 0.7 ,
statusbar_texture = [[Interface\AddOns\Details\images\bar_skyline]] ,
statusbar_alpha = 0.70 ,
blockspell_height = 67 ,
blockspell_padding = 5 ,
blockspell_color = { 0 , 0 , 0 , 0.7 } ,
blockspell_bordercolor = { 0 , 0 , 0 , 0.7 } ,
blockspell_backgroundcolor = { 0.1 , 0.1 , 0.1 , 0.4 } ,
blockspell_spark_offset = - 1 ,
blockspell_spark_width = 4 ,
blockspell_spark_show = true ,
blockspell_spark_color = { 1 , 1 , 1 , 0.7 } ,
spellcontainer_width = 429 ,
spellcontainer_height = 311 ,
spellcontainer_islocked = true ,
targetcontainer_width = 429 ,
targetcontainer_height = 140 ,
targetcontainer_islocked = true ,
phasecontainer_enabled = true ,
phasecontainer_width = 290 ,
phasecontainer_height = 140 ,
phasecontainer_islocked = true ,
genericcontainer_enabled = true ,
genericcontainer_width = 429 ,
genericcontainer_height = 311 + 140 + 30 ,
genericcontainer_islocked = true ,
genericcontainer_right_width = 403 ,
genericcontainer_right_height = 460 ,
spellbar_background_alpha = 0.92 ,
spellcontainer_headers = { } , --store information about active headers and their sizes (spells)
targetcontainer_headers = { } , --store information about active headers and their sizes (target)
phasecontainer_headers = { } , --store information about active headers and their sizes (phases)
genericcontainer_headers = { } , --store information about active headers and their sizes (generic left)
genericcontainer_headers_right = { } , --store information about active headers and their sizes (generic right)
spellcontainer_header_height = 20 ,
spellcontainer_header_fontsize = 10 ,
spellcontainer_header_fontcolor = { 1 , 1 , 1 , 1 } ,
} ,
--profile by spec
profile_by_spec = { } ,
--displays by spec
displays_by_spec = { } ,
--death log
show_totalhitdamage_on_overkill = false ,
--switch tables
switchSaved = { slots = 4 , table = {
{ [ " atributo " ] = 1 , [ " sub_atributo " ] = 1 } , --damage done
{ [ " atributo " ] = 2 , [ " sub_atributo " ] = 1 } , --healing done
{ [ " atributo " ] = 1 , [ " sub_atributo " ] = 6 } , --enemies
{ [ " atributo " ] = 4 , [ " sub_atributo " ] = 5 } , --deaths
} } ,
report_pos = { 1 , 1 } ,
--tutorial
tutorial = {
logons = 0 ,
unlock_button = 0 ,
version_announce = 0 ,
main_help_button = 0 ,
alert_frames = { false , false , false , false , false , false } ,
bookmark_tutorial = false ,
ctrl_click_close_tutorial = false ,
} ,
performance_profiles = { --deprecated
[ " RaidFinder " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
[ " Raid15 " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
[ " Raid30 " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
[ " Mythic " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
[ " Battleground15 " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
[ " Battleground40 " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
[ " Arena " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
[ " Dungeon " ] = { enabled = false , update_speed = 1 , use_row_animations = false , damage = true , heal = true , aura = true , energy = false , miscdata = true } ,
} ,
--auras (wa auras created from the aura panel)
details_auras = { } , --deprecated due to major security wa code revamp
--ilvl
item_level_pool = { } ,
--latest report
latest_report_table = { } ,
--death recap
death_recap = {
enabled = true ,
relevance_time = 7 ,
show_life_percent = false ,
show_segments = false ,
} ,
--spell caches
boss_mods_timers = {
encounter_timers_dbm = { } ,
encounter_timers_bw = { } ,
latest_boss_mods_access = time ( ) ,
} ,
spell_pool = { } ,
latest_spell_pool_access = time ( ) ,
npcid_pool = { } ,
latest_npcid_pool_access = time ( ) ,
encounter_spell_pool = { } ,
latest_encounter_spell_pool_access = time ( ) ,
--store spells that passed by the healing absorb event on the parser, this list will help counting the overhealing of shields
shield_spellid_cache = { } ,
latest_shield_spellid_cache_access = time ( ) ,
--parser options
parser_options = {
--compute the overheal of shields
shield_overheal = false ,
--compute the energy wasted by players when they current energy is equal to the maximum energy
energy_overflow = false ,
} ,
--aura creation frame libwindow
createauraframe = { } , --deprecated
--min health done on the death report
deathlog_healingdone_min = 1 ,
deathlog_healingdone_min_arena = 400 ,
deathlog_line_height = 16 ,
--mythic plus config
mythic_plus = {
merge_boss_trash = true ,
boss_dedicated_segment = true ,
make_overall_when_done = true ,
make_overall_boss_only = false ,
show_damage_graphic = true ,
reverse_death_log = false ,
delay_to_show_graphic = 1 ,
last_mythicrun_chart = { } ,
mythicrun_chart_frame = { } ,
mythicrun_chart_frame_minimized = { } ,
finished_run_frame = { } , --end of mythic+ panel
mythicrun_time_type = 1 , --1: combat time (the amount of time the player is in combat) 2: run time (the amount of time it took to finish the mythic+ run)
} , --implementar esse time_type quando estiver dando refresh na janela
--plugin window positions
plugin_window_pos = { } ,
--run code
run_code = {
[ " on_specchanged " ] = " \n -- run when the player changes its spec " ,
[ " on_zonechanged " ] = " \n -- when the player changes zone, this code will run " ,
[ " on_init " ] = " \n -- code to run when Details! initializes, put here code which only will run once \n -- this also will run then the profile is changed \n \n --size of the death log tooltip in the Deaths display (default 350) \n Details.death_tooltip_width = 350; \n \n --when in arena or battleground, details! silently switch to activity time (goes back to the old setting on leaving, default true) \n Details.force_activity_time_pvp = true; \n \n --speed of the bar animations (default 33) \n Details.animation_speed = 33; \n \n --threshold to trigger slow or fast speed (default 0.45) \n Details.animation_speed_mintravel = 0.45; \n \n --call to update animations \n Details:RefreshAnimationFunctions(); \n \n --max window size, does require a /reload to work (default 480 x 450) \n Details.max_window_size.width = 480; \n Details.max_window_size.height = 450; \n \n --use the arena team color as the class color (default true) \n Details.color_by_arena_team = true; \n \n --how much time the update warning is shown (default 10) \n Details.update_warning_timeout = 10; " ,
[ " on_leavecombat " ] = " \n -- this code runs when the player leave combat " ,
[ " on_entercombat " ] = " \n -- this code runs when the player enters in combat " ,
[ " on_groupchange " ] = " \n -- this code runs when the player enter or leave a group " ,
} ,
--plater integration
plater = {
realtime_dps_enabled = false ,
realtime_dps_size = 12 ,
realtime_dps_color = { 1 , 1 , 0 , 1 } ,
realtime_dps_shadow = true ,
realtime_dps_anchor = { side = 7 , x = 0 , y = 0 } ,
--
realtime_dps_player_enabled = false ,
realtime_dps_player_size = 12 ,
realtime_dps_player_color = { 1 , 1 , 0 , 1 } ,
realtime_dps_player_shadow = true ,
realtime_dps_player_anchor = { side = 7 , x = 0 , y = 0 } ,
--
damage_taken_enabled = false ,
damage_taken_size = 12 ,
damage_taken_color = { 1 , 1 , 0 , 1 } ,
damage_taken_shadow = true ,
damage_taken_anchor = { side = 7 , x = 0 , y = 0 } ,
} ,
--dungeon information - can be accessed by plugins and third party mods
dungeon_data = { } ,
--raid information - can be accessed by plugins and third party mods
raid_data = { } ,
--store all npcids blacklisted by the user
npcid_ignored = { } ,
--store all spellids blacklisted by the user
spellid_ignored = { } ,
--9.0 exp (store data only used for the 9.0 expansion)
exp90temp = {
delete_damage_TCOB = true , --delete damage on the concil of blood encounter
} ,
}
Details.default_global_data = default_global_data
function Details : GetTutorialCVar ( key , default )
--is disabling all popups from the streamer options
if ( Details.streamer_config . no_alerts ) then
return true
end
local value = Details.tutorial [ key ]
if ( value == nil and default ) then
Details.tutorial [ key ] = default
value = default
end
return value
end
function Details : SetTutorialCVar ( key , value )
Details.tutorial [ key ] = value
end
function Details : SaveProfileSpecial ( )
--get the current profile
local profile_name = Details : GetCurrentProfileName ( )
local profile = Details : GetProfile ( profile_name , true )
--save default keys
for key , _ in pairs ( Details.default_profile ) do
local current_value = _detalhes_database [ key ] or _detalhes_global [ key ] or Details.default_player_data [ key ] or Details.default_global_data [ key ]
if ( type ( current_value ) == " table " ) then
local ctable = Details.CopyTable ( current_value )
profile [ key ] = ctable
else
profile [ key ] = current_value
end
end
--save skins
Details : Destroy ( profile.instances )
if ( Details.tabela_instancias ) then
for index , instance in ipairs ( Details.tabela_instancias ) do
local exported = instance : ExportSkin ( )
profile.instances [ index ] = exported
end
end
--end
return profile
end
--save things for the mythic dungeon run
function Details : SaveState_CurrentMythicDungeonRun ( runID , zoneName , zoneID , startAt , segmentID , level , ejID , latestBossAt )
local zoneName , _ , _ , _ , _ , _ , _ , currentZoneID = GetInstanceInfo ( )
local savedTable = Details.mythic_dungeon_currentsaved
savedTable.started = true
savedTable.run_id = runID
savedTable.dungeon_name = zoneName
savedTable.dungeon_zone_id = currentZoneID
savedTable.started_at = startAt
savedTable.segment_id = segmentID
savedTable.level = level
savedTable.ej_id = ejID
savedTable.previous_boss_killed_at = latestBossAt
local playersOnTheRun = { }
for i = 1 , GetNumGroupMembers ( ) do
local unitGUID = UnitGUID ( " party " .. i )
if ( unitGUID ) then
playersOnTheRun [ # playersOnTheRun + 1 ] = unitGUID
end
end
savedTable.players = playersOnTheRun
end
function Details : UpdateState_CurrentMythicDungeonRun ( stillOngoing , segmentID , latestBossAt )
local savedTable = Details.mythic_dungeon_currentsaved
if ( not stillOngoing ) then
savedTable.started = false
end
if ( segmentID ) then
savedTable.segment_id = segmentID
end
if ( latestBossAt ) then
savedTable.previous_boss_killed_at = latestBossAt
end
end
function Details : RestoreState_CurrentMythicDungeonRun ( )
--no need to check for mythic+ if the user is playing on classic wow
if ( DetailsFramework.IsTimewalkWoW ( ) ) then
return
end
local savedTable = Details.mythic_dungeon_currentsaved
local mythicLevel = C_ChallengeMode.GetActiveKeystoneInfo ( )
local zoneName , _ , _ , _ , _ , _ , _ , currentZoneID = GetInstanceInfo ( )
local mapID = C_Map.GetBestMapForUnit ( " player " )
if ( not mapID ) then
--print("D! no mapID to restored mythic dungeon state.")
return
end
local ejID = 0
if ( mapID ) then
ejID = DetailsFramework.EncounterJournal . EJ_GetInstanceForMap ( mapID ) or 0
end
--is there a saved state for the dungeon?
if ( savedTable.started ) then
--player are within the same zone?
if ( zoneName == savedTable.dungeon_name and currentZoneID == savedTable.dungeon_zone_id ) then
--is there a mythic run ongoing and the level is the same as the saved state?
if ( mythicLevel and mythicLevel == savedTable.level ) then
--restore the state
Details.MythicPlus . Started = true
Details.MythicPlus . DungeonName = zoneName
Details.MythicPlus . DungeonID = currentZoneID
Details.MythicPlus . StartedAt = savedTable.started_at
Details.MythicPlus . SegmentID = savedTable.segment_id
Details.MythicPlus . Level = mythicLevel
Details.MythicPlus . ejID = ejID
Details.MythicPlus . PreviousBossKilledAt = savedTable.previous_boss_killed_at
Details.MythicPlus . IsRestoredState = true
DetailsMythicPlusFrame.IsDoingMythicDungeon = true
Details : Msg ( " D! (debug) mythic dungeon state restored. " )
C_Timer.After ( 2 , function ( )
Details : SendEvent ( " COMBAT_MYTHICDUNGEON_START " )
end )
return
else
print ( " D! (debug) mythic level isn't equal. " , mythicLevel , savedTable.level )
end
else
print ( " D! (debug) zone name or zone Id isn't the same: " , zoneName , savedTable.dungeon_name , currentZoneID , savedTable.dungeon_zone_id )
end
--mythic run is over
savedTable.started = false
else
--print("D! savedTable.stated isn't true.")
end
end
--------------------------------------------------------------------------------------------------------------------------------------------
--~export ~ import ~profile
local exportProfileBlacklist = {
custom = true ,
cached_specs = true ,
cached_talents = true ,
combat_id = true ,
combat_counter = true ,
mythic_dungeon_currentsaved = true ,
nick_tag_cache = true ,
plugin_database = true ,
character_data = true ,
active_profile = true ,
SoloTablesSaved = true ,
RaidTablesSaved = true ,
benchmark_db = true ,
rank_window = true ,
last_realversion = true ,
last_version = true ,
__profiles = true ,
latest_news_saw = true ,
always_use_profile = true ,
always_use_profile_name = true ,
always_use_profile_exception = true ,
savedStyles = true ,
savedTimeCaptures = true ,
lastUpdateWarning = true ,
spell_school_cache = true ,
global_plugin_database = true ,
details_auras = true ,
item_level_pool = true ,
latest_report_table = true ,
boss_mods_timers = true ,
spell_pool = true ,
encounter_spell_pool = true ,
npcid_pool = true ,
createauraframe = true ,
mythic_plus = true ,
plugin_window_pos = true ,
switchSaved = true ,
installed_skins_cache = true ,
trinket_data = true ,
keystone_cache = true ,
performance_profiles = true ,
}
--transform the current profile into a string which can be shared in the internet
function Details : ExportCurrentProfile ( )
--save the current profile
Details : SaveProfile ( )
--data saved inside the profile
local profileObject = Details : GetProfile ( Details : GetCurrentProfileName ( ) )
if ( not profileObject ) then
Details : Msg ( " fail to get the current profile. " )
return false
end
--data saved individual for each character
local defaultPlayerData = Details.default_player_data
local playerData = { }
--data saved for the account
local defaultGlobalData = Details.default_global_data
local globaData = { }
--fill player and global data tables
for key , _ in pairs ( defaultPlayerData ) do
if ( not exportProfileBlacklist [ key ] ) then
if ( type ( Details [ key ] ) == " table " ) then
playerData [ key ] = DetailsFramework.table . copy ( { } , Details [ key ] )
else
playerData [ key ] = Details [ key ]
end
end
end
for key , _ in pairs ( defaultGlobalData ) do
if ( not exportProfileBlacklist [ key ] ) then
if ( type ( Details [ key ] ) == " table " ) then
globaData [ key ] = DetailsFramework.table . copy ( { } , Details [ key ] )
else
globaData [ key ] = Details [ key ]
end
end
end
local exportedData = {
profile = profileObject ,
playerData = playerData ,
globaData = globaData ,
version = 1 ,
}
local compressedData = Details : CompressData ( exportedData , " print " )
return compressedData
end
---bIsFromImportPrompt is true when the import call is from the import window
---@param profileString string
---@param newProfileName string
---@param bImportAutoRunCode boolean
---@param bIsFromImportPrompt boolean
---@return boolean
function Details : ImportProfile ( profileString , newProfileName , bImportAutoRunCode , bIsFromImportPrompt )
if ( not newProfileName or type ( newProfileName ) ~= " string " or string.len ( newProfileName ) < 2 ) then
Details : Msg ( " invalid profile name or profile name is too short. " ) --localize-me
return false
end
profileString = DetailsFramework : Trim ( profileString )
local currentDataVersion = 1
local dataTable = Details : DecompressData ( profileString , " print " )
if ( dataTable ) then
local profileObject = Details : GetProfile ( newProfileName , false )
local nameWasDuplicate = false
while ( profileObject ) do
newProfileName = newProfileName .. ' 2 ' ;
profileObject = Details : GetProfile ( newProfileName , false )
nameWasDuplicate = true
end
if ( not profileObject ) then
--profile doesn't exists, create new
profileObject = Details : CreateProfile ( newProfileName )
if ( not profileObject ) then
Details : Msg ( " failed to create a new profile. " ) --localize-me
return
end
end
local profileData , playerData , globalData , version = dataTable.profile , dataTable.playerData , dataTable.globaData , dataTable.version
if ( version < currentDataVersion ) then
--perform update in the sereived settings
end
--character data defaults
local defaultPlayerData = Details.default_player_data
--global data defaults
local defaultGlobalData = Details.default_global_data
--profile defaults
local defaultProfileData = Details.default_profile
if ( not bImportAutoRunCode or not bIsFromImportPrompt ) then
globalData.run_code = nil
end
--transfer player and global data tables from the profile to details object
for key , _ in pairs ( defaultPlayerData ) do
local importedValue = playerData [ key ]
if ( importedValue ~= nil ) then
if ( type ( importedValue ) == " table " ) then
Details [ key ] = DetailsFramework.table . copy ( { } , importedValue )
else
Details [ key ] = importedValue
end
end
end
for key , _ in pairs ( defaultGlobalData ) do
local importedValue = globalData [ key ]
if ( importedValue ~= nil ) then
if ( type ( importedValue ) == " table " ) then
Details [ key ] = DetailsFramework.table . copy ( { } , importedValue )
else
Details [ key ] = importedValue
end
end
end
--transfer data from the imported profile to the new profile object
for key , _ in pairs ( defaultProfileData ) do
local importedValue = profileData [ key ]
if ( importedValue ~= nil ) then
if ( type ( importedValue ) == " table " ) then
profileObject [ key ] = DetailsFramework.table . copy ( { } , importedValue )
else
profileObject [ key ] = importedValue
end
end
end
--profile imported, set mythic dungeon to default settings
local mythicPlusSettings = Details.mythic_plus
mythicPlusSettings.merge_boss_trash = true
mythicPlusSettings.boss_dedicated_segment = true
mythicPlusSettings.make_overall_when_done = true
mythicPlusSettings.make_overall_boss_only = false
mythicPlusSettings.show_damage_graphic = true
mythicPlusSettings.reverse_death_log = false
mythicPlusSettings.delay_to_show_graphic = 1
mythicPlusSettings.last_mythicrun_chart = { }
mythicPlusSettings.mythicrun_chart_frame = { }
mythicPlusSettings.mythicrun_chart_frame_minimized = { }
mythicPlusSettings.finished_run_frame = { }
--make the max amount of segments be 30
Details.segments_amount = 40
Details.segments_amount_to_save = 40
--transfer instance data to the new created profile
profileObject.instances = DetailsFramework.table . copy ( { } , profileData.instances )
Details : ApplyProfile ( newProfileName )
--reset automation settings (due to user not knowing why some windows are disappearing)
for instanceId , instance in Details : ListInstances ( ) do
DetailsFramework.table . copy ( instance.hide_on_context , Details.instance_defaults . hide_on_context )
end
if ( nameWasDuplicate ) then
Details : Msg ( " profile name already exists and was imported as: " , newProfileName ) --localize-me
else
Details : Msg ( " profile successfully imported. " ) --localize-me
end
return true
else
Details : Msg ( " failed to decompress profile data. " ) --localize-me
return false
end
end
--create a import profile confirmation dialog with a text box to enter the profile name and a checkbox to select if should import auto run scripts
function Details . ShowImportProfileConfirmation ( message , callback )
if ( not Details.profileConfirmationDialog ) then
local promptFrame = CreateFrame ( " frame " , " DetailsImportProfileDialog " , UIParent , " BackdropTemplate " )
promptFrame : SetSize ( 400 , 170 )
promptFrame : SetFrameStrata ( " FULLSCREEN " )
promptFrame : SetPoint ( " center " , UIParent , " center " , 0 , 100 )
promptFrame : EnableMouse ( true )
promptFrame : SetMovable ( true )
promptFrame : RegisterForDrag ( " LeftButton " )
promptFrame : SetScript ( " OnDragStart " , function ( ) promptFrame : StartMoving ( ) end )
promptFrame : SetScript ( " OnDragStop " , function ( ) promptFrame : StopMovingOrSizing ( ) end )
promptFrame : SetScript ( " OnMouseDown " , function ( self , button ) if ( button == " RightButton " ) then promptFrame.EntryBox : ClearFocus ( ) promptFrame : Hide ( ) end end )
table.insert ( UISpecialFrames , " DetailsImportProfileDialog " )
detailsFramework : CreateTitleBar ( promptFrame , " Import Profile Confirmation " )
detailsFramework : ApplyStandardBackdrop ( promptFrame )
local prompt = promptFrame : CreateFontString ( nil , " overlay " , " GameFontNormal " )
prompt : SetPoint ( " top " , promptFrame , " top " , 0 , - 25 )
prompt : SetJustifyH ( " center " )
prompt : SetSize ( 360 , 36 )
promptFrame.prompt = prompt
local button_text_template = detailsFramework : GetTemplate ( " font " , " OPTIONS_FONT_TEMPLATE " )
local options_dropdown_template = detailsFramework : GetTemplate ( " dropdown " , " OPTIONS_DROPDOWN_TEMPLATE " )
local textbox = detailsFramework : CreateTextEntry ( promptFrame , function ( ) end , 380 , 20 , " textbox " , nil , nil , options_dropdown_template )
textbox : SetPoint ( " topleft " , promptFrame , " topleft " , 10 , - 60 )
promptFrame.EntryBox = textbox
--create a detailsframework checkbox to select if want to import the auto run scripts
local checkbox = detailsFramework : CreateSwitch ( promptFrame , function ( ) end , false , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , DetailsFramework : GetTemplate ( " switch " , " OPTIONS_CHECKBOX_BRIGHT_TEMPLATE " ) )
checkbox : SetPoint ( " topleft " , promptFrame , " topleft " , 10 , - 90 )
checkbox : SetAsCheckBox ( )
promptFrame.checkbox = checkbox
--create the checkbox label with the text: "Import Auto Run Scripts"
local checkboxLabel = promptFrame : CreateFontString ( nil , " overlay " , " GameFontNormal " )
checkboxLabel : SetPoint ( " left " , checkbox.widget , " right " , 2 , 0 )
checkboxLabel : SetText ( " Import Auto Run Scripts " )
checkboxLabel : SetJustifyH ( " left " )
promptFrame.checkboxLabel = checkboxLabel
local buttonTrue = detailsFramework : CreateButton ( promptFrame , nil , 60 , 20 , " Okey " , nil , nil , nil , nil , nil , nil , options_dropdown_template )
buttonTrue : SetPoint ( " bottomright " , promptFrame , " bottomright " , - 10 , 5 )
promptFrame.button_true = buttonTrue
local buttonFalse = detailsFramework : CreateButton ( promptFrame , function ( ) promptFrame.textbox : ClearFocus ( ) promptFrame : Hide ( ) end , 60 , 20 , " Cancel " , nil , nil , nil , nil , nil , nil , options_dropdown_template )
buttonFalse : SetPoint ( " bottomleft " , promptFrame , " bottomleft " , 10 , 5 )
promptFrame.button_false = buttonFalse
local executeCallback = function ( )
local bCanImportAutoRunCode = promptFrame.checkbox : GetValue ( )
local myFunc = buttonTrue.true_function
if ( myFunc ) then
local okey , errormessage = pcall ( myFunc , textbox : GetText ( ) , bCanImportAutoRunCode )
textbox : ClearFocus ( )
if ( not okey ) then
print ( " error: " , errormessage )
end
promptFrame : Hide ( )
end
end
buttonTrue : SetClickFunction ( function ( )
executeCallback ( )
end )
textbox : SetHook ( " OnEnterPressed " , function ( )
executeCallback ( )
end )
promptFrame : Hide ( )
Details.profileConfirmationDialog = promptFrame
end
Details.profileConfirmationDialog : Show ( )
Details.profileConfirmationDialog . EntryBox : SetText ( " " )
Details.profileConfirmationDialog . EntryBox : SetFocus ( false )
Details.profileConfirmationDialog . prompt : SetText ( message )
Details.profileConfirmationDialog . button_true.true_function = callback
Details.profileConfirmationDialog . textbox : SetFocus ( true )
end