--Damage Class
--a damage object is created inside an actor container
--an actor container is created inside a combat object
--combat objects has 4 actor containers: damage, healing, energy, utility
--these containers are indexed within the combat object table: combatObject[1] = damage container, combatObject[2] = healing container, combatObject[3] = energy container, combatObject[4] = utility container
--damage object
local Details = _G.Details
local Loc = LibStub ( " AceLocale-3.0 " ) : GetLocale ( " Details " )
local Translit = LibStub ( " LibTranslit-1.0 " )
local gump = Details.gump
local _ = nil
local detailsFramework = DetailsFramework
local addonName , Details222 = ...
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--local pointers
local format = string.format --lua local
local _math_floor = math.floor --lua local
local _table_sort = table.sort --lua local
local tinsert = table.insert --lua local
local setmetatable = setmetatable --lua local
local _getmetatable = getmetatable --lua local
local ipairs = ipairs --lua local
local pairs = pairs --lua local
local _math_min = math.min --lua local
local _math_max = math.max --lua local
local abs = math.abs --lua local
local bitBand = bit.band --lua local
local unpack = unpack --lua local
local type = type --lua local
local GameTooltip = GameTooltip --api local
local IsInRaid = IsInRaid --api local
local IsInGroup = IsInGroup --api local
local GetSpellInfo = GetSpellInfo --api local
local _GetSpellInfo = Details.getspellinfo --details api
local stringReplace = Details.string . replace --details api
--show more information about spells
local debugmode = false
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--constants
local spellContainerClass = Details.container_habilidades
local damageClass = Details.atributo_damage
local atributo_misc = Details.atributo_misc
local container_damage = Details.container_type . CONTAINER_DAMAGE_CLASS
local modo_GROUP = Details.modos . group
local modo_ALL = Details.modos . all
local class_type = Details.atributos . dano
local ToKFunctions = Details.ToKFunctions
local SelectedToKFunction = ToKFunctions [ 1 ]
local UsingCustomLeftText = false
local UsingCustomRightText = false
local FormatTooltipNumber = ToKFunctions [ 8 ]
local TooltipMaximizedMethod = 1
--local CLASS_ICON_TCOORDS = _G.CLASS_ICON_TCOORDS
local is_player_class = Details.player_class
Details.tooltip_key_overlay1 = { 1 , 1 , 1 , .2 }
Details.tooltip_key_overlay2 = { 1 , 1 , 1 , .5 }
Details.tooltip_key_size_width = 24
Details.tooltip_key_size_height = 10
local enemies_background = { value = 100 , color = { 0.1960 , 0.1960 , 0.1960 , 0.8697 } , texture = " Interface \\ AddOns \\ Details \\ images \\ bar_background2 " }
local headerColor = { 1 , 0.9 , 0.0 , 1 }
local breakdownWindowFrame = Details.BreakdownWindowFrame
local keyName
local OBJECT_TYPE_PLAYER = 0x00000400
local ntable = { } --temp
local vtable = { } --temp
local tooltip_void_zone_temp = { } --temp
local bs_table = { } --temp
local bs_index_table = { } --temp
local bs_tooltip_table
local frags_tooltip_table
local tooltip_temp_table = { }
local OBJECT_TYPE_FRIENDLY_NPC = 0x00000A18
local ignoredEnemyNpcsTable = Details.IgnoredEnemyNpcsTable
--damage mixin
local damageClassMixin = { }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--exported functions
function Details : CreateActorLastEventTable ( ) --[[exported]]
local t = { { } , { } , { } , { } , { } , { } , { } , { } }
t.n = 1
return t
end
function damageClass : CreateFFTable ( targetName ) --[[exported]]
local newTable = { total = 0 , spells = { } }
self.friendlyfire [ targetName ] = newTable
return newTable
end
function Details : CreateActorAvoidanceTable ( noOverall ) --[[exported]]
if ( noOverall ) then
local avoidanceTable = { [ " ALL " ] = 0 , [ " DODGE " ] = 0 , [ " PARRY " ] = 0 , [ " HITS " ] = 0 , [ " ABSORB " ] = 0 , --quantas vezes foi dodge, parry, quandos hits tomou, quantos absorbs teve
[ " FULL_HIT " ] = 0 , [ " FULL_ABSORBED " ] = 0 , [ " PARTIAL_ABSORBED " ] = 0 , --full hit full absorbed and partial absortion
[ " FULL_HIT_AMT " ] = 0 , [ " PARTIAL_ABSORB_AMT " ] = 0 , [ " ABSORB_AMT " ] = 0 , [ " FULL_ABSORB_AMT " ] = 0 , --amounts
[ " BLOCKED_HITS " ] = 0 , [ " BLOCKED_AMT " ] = 0 , --amount of hits blocked - amout of damage mitigated
}
return avoidanceTable
else
local avoidanceTable = {
overall = { [ " ALL " ] = 0 , [ " DODGE " ] = 0 , [ " PARRY " ] = 0 , [ " HITS " ] = 0 , [ " ABSORB " ] = 0 , --quantas vezes foi dodge, parry, quandos hits tomou, quantos absorbs teve
[ " FULL_HIT " ] = 0 , [ " FULL_ABSORBED " ] = 0 , [ " PARTIAL_ABSORBED " ] = 0 , --full hit full absorbed and partial absortion
[ " FULL_HIT_AMT " ] = 0 , [ " PARTIAL_ABSORB_AMT " ] = 0 , [ " ABSORB_AMT " ] = 0 , [ " FULL_ABSORB_AMT " ] = 0 , --amounts
[ " BLOCKED_HITS " ] = 0 , [ " BLOCKED_AMT " ] = 0 , --amount of hits blocked - amout of damage mitigated
}
}
return avoidanceTable
end
end
function Details . SortGroup ( container , keyName2 ) --[[exported]]
keyName = keyName2
return _table_sort ( container , Details.SortKeyGroup )
end
function Details . SortKeyGroup ( table1 , table2 ) --[[exported]]
if ( table1.grupo and table2.grupo ) then
return table1 [ keyName ] > table2 [ keyName ]
elseif ( table1.grupo and not table2.grupo ) then
return true
elseif ( not table1.grupo and table2.grupo ) then
return false
else
return table1 [ keyName ] > table2 [ keyName ]
end
end
function Details . SortKeySimple ( table1 , table2 ) --[[exported]]
return table1 [ keyName ] > table2 [ keyName ]
end
---sort by real time dps
---@param actor1 actor
---@param actor2 actor
---@return boolean
function Details . SortByRealTimeDps ( actor1 , actor2 )
return ( actor1.last_dps_realtime or 0 ) > ( actor2.last_dps_realtime or 0 )
end
function Details : ContainerSort ( container , amount , keyName2 ) --[[exported]]
keyName = keyName2
_table_sort ( container , Details.SortKeySimple )
if ( amount ) then
for i = amount , 1 , - 1 do --de tr�s pra frente
if ( container [ i ] [ keyName ] < 1 ) then
amount = amount - 1
else
break
end
end
return amount
end
end
---return true if the actor is a friendly npc
---@return boolean
function Details : IsFriendlyNpc ( ) --[[exported]]
local flag = self.flag_original
if ( flag ) then
if ( bitBand ( flag , 0x00000008 ) ~= 0 ) then
if ( bitBand ( flag , 0x00000010 ) ~= 0 ) then
if ( bitBand ( flag , 0x00000800 ) ~= 0 ) then
return true
end
end
end
end
return false
end
function Details : IsEnemy ( ) --[[exported]]
if ( self.flag_original ) then
if ( bitBand ( self.flag_original , 0x00000060 ) ~= 0 ) then
local npcId = Details : GetNpcIdFromGuid ( self.serial )
if ( ignoredEnemyNpcsTable [ npcId ] ) then
return false
end
return true
end
end
return false
end
function Details : GetSpellList ( ) --[[exported]]
return self.spells . _ActorTable
end
function Details : GetTimeInCombat ( petOwner ) --[[exported]]
if ( petOwner ) then
if ( Details.time_type == 1 or not petOwner.grupo ) then
return self : Tempo ( )
elseif ( Details.time_type == 2 or Details.use_realtimedps ) then
return self : GetCombatTime ( )
end
else
if ( Details.time_type == 1 ) then
return self : Tempo ( )
elseif ( Details.time_type == 2 or Details.use_realtimedps ) then
return self : GetCombatTime ( )
end
end
end
--enemies(sort function)
local sortEnemies = function ( t1 , t2 )
local a = bitBand ( t1.flag_original , 0x00000060 )
local b = bitBand ( t2.flag_original , 0x00000060 )
if ( a ~= 0 and b ~= 0 ) then
local npcid1 = Details : GetNpcIdFromGuid ( t1.serial )
local npcid2 = Details : GetNpcIdFromGuid ( t2.serial )
if ( not ignoredEnemyNpcsTable [ npcid1 ] and not ignoredEnemyNpcsTable [ npcid2 ] ) then
return t1.damage_taken > t2.damage_taken
elseif ( ignoredEnemyNpcsTable [ npcid1 ] and not ignoredEnemyNpcsTable [ npcid2 ] ) then
return false
elseif ( not ignoredEnemyNpcsTable [ npcid1 ] and ignoredEnemyNpcsTable [ npcid2 ] ) then
return true
else
return t1.damage_taken > t2.damage_taken
end
elseif ( a ~= 0 and b == 0 ) then
return true
elseif ( a == 0 and b ~= 0 ) then
return false
end
return false
end
function Details : ContainerSortEnemies ( container , amount , keyName2 ) --[[exported]]
keyName = keyName2
_table_sort ( container , sortEnemies )
local total = 0
for index , player in ipairs ( container ) do
local npcid1 = Details : GetNpcIdFromGuid ( player.serial )
--p rint (player.nome, npcid1, ignored_enemy_npcs [npcid1])
if ( bitBand ( player.flag_original , 0x00000060 ) ~= 0 and not ignoredEnemyNpcsTable [ npcid1 ] ) then --� um inimigo
total = total + player [ keyName ]
else
amount = index - 1
break
end
end
return amount , total
end
function Details : TooltipForCustom ( barra ) --[[exported]]
GameCooltip : AddLine ( Loc [ " STRING_LEFT_CLICK_SHARE " ] )
return true
end
--[[ Void Zone Sort]]
local void_zone_sort = function ( t1 , t2 )
if ( t1.damage == t2.damage ) then
return t1.nome <= t2.nome
else
return t1.damage > t2.damage
end
end
function Details . Sort1 ( table1 , table2 ) --[[exported]]
return table1 [ 1 ] > table2 [ 1 ]
end
function Details . Sort2 ( table1 , table2 ) --[[exported]]
return table1 [ 2 ] > table2 [ 2 ]
end
function Details . Sort3 ( table1 , table2 ) --[[exported]]
return table1 [ 3 ] > table2 [ 3 ]
end
function Details . Sort4 ( table1 , table2 ) --[[exported]]
return table1 [ 4 ] > table2 [ 4 ]
end
function Details . Sort4Reverse ( table1 , table2 ) --[[exported]]
if ( not table2 ) then
return true
end
return table1 [ 4 ] < table2 [ 4 ]
end
function Details : GetBarColor ( actor ) --[[exported]]
actor = actor or self
if ( actor.monster ) then
return unpack ( Details.class_colors . ENEMY )
elseif ( actor.customColor ) then
return unpack ( actor.customColor )
elseif ( actor.spellicon ) then
return 0.729 , 0.917 , 1
elseif ( actor.owner ) then
return unpack ( Details.class_colors [ actor.owner . classe or " UNKNOW " ] )
elseif ( actor.arena_team and Details.color_by_arena_team ) then
if ( actor.arena_team == 0 ) then
return unpack ( Details.class_colors . ARENA_GREEN )
else
return unpack ( Details.class_colors . ARENA_YELLOW )
end
else
if ( not is_player_class [ actor.classe ] and actor.flag_original and bitBand ( actor.flag_original , 0x00000020 ) ~= 0 ) then --neutral
return unpack ( Details.class_colors . NEUTRAL )
elseif ( actor.color ) then
return unpack ( actor.color )
else
return unpack ( Details.class_colors [ actor.classe or " UNKNOW " ] )
end
end
end
function Details : GetSpellLink ( spellid ) --[[exported]]
if ( type ( spellid ) ~= " number " ) then
return spellid
end
if ( spellid == 1 ) then --melee
return GetSpellLink ( 6603 )
elseif ( spellid == 2 ) then --autoshot
return GetSpellLink ( 75 )
elseif ( spellid > 10 ) then
return GetSpellLink ( spellid )
else
local spellname = _GetSpellInfo ( spellid )
return spellname
end
end
function Details : GameTooltipSetSpellByID ( spellId ) --[[exported]]
if ( spellId == 1 ) then
GameTooltip : SetSpellByID ( 6603 )
elseif ( spellId == 2 ) then
GameTooltip : SetSpellByID ( 75 )
elseif ( spellId > 10 ) then
GameTooltip : SetSpellByID ( spellId )
else
GameTooltip : SetSpellByID ( spellId )
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--class ~constructor
---create a new actorObject and set the metatable to the actor prototype
---this function is called from within an actorContainer when it needs to create a new actorObject for a new actor
---actorObject is a ordinary table with the actor attributes and a metatable to inherit the functions from Details object
---@return table
function damageClass : NovaTabela ( ) --create new actorObject
local alphabetical = Details : GetOrderNumber ( )
--constructor: creates a table with the actor attributes and then set the metatable to the actor prototype
local newDamageActor = {
--type of the actor
tipo = class_type ,
--total: amount of damage done
total = alphabetical ,
total_extra = 0 ,
--totalabsorbed: amount of damage done absorbed by shields
totalabsorbed = alphabetical ,
--total_without_pet: amount of damage done without pet damage
total_without_pet = alphabetical ,
--custom: used by custom scripts, works more like a cache
custom = 0 ,
--damage_taken: amount of damage the actor took during the combat
damage_taken = alphabetical ,
--damage_from: table with actor names as keys and boolean true as value
damage_from = { } ,
--dps_started: is false until this actor does damage
dps_started = false ,
--last_event: the time when the actor as last edited by a damage effect: suffered damage, did damage
last_event = 0 ,
--on_hold: if the actor is idle, doing nothing during combat, on_hold is true
on_hold = false ,
--delay: the time when the actor went idle
delay = 0 ,
--caches
last_value = nil ,
last_dps = 0 , --cache of the latest dps value calculated for this actor
last_dps_realtime = 0 , --cache of the latest real time dps value calculated for this actor
--start_time: the time when the actor started to do damage
start_time = 0 ,
--end_time: the time when the actor stopped to do damage
end_time = nil ,
--table indexed with pet names
pets = { } ,
--table where key is the raid target flags and the value is the damage done to that target
raid_targets = { } ,
--friendlyfire_total: amount of damage done to friendly players
friendlyfire_total = 0 ,
--friendlyfire: table where key is a player name and value is a table with .total: damage inflicted and .spells a table with spell names as keys and damage done as value
friendlyfire = { } ,
--targets: table where key is the target name (actor name) and the value is the amount of damage done to that target
targets = { } ,
--spells: spell container
spells = spellContainerClass : NovoContainer ( container_damage )
}
setmetatable ( newDamageActor , damageClass )
detailsFramework : Mixin ( newDamageActor , Details222.Mixins . ActorMixin )
detailsFramework : Mixin ( newDamageActor , damageClassMixin )
return newDamageActor
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--special cases
---calculate real time dps for each actor within the passed table
---@param tableWithActors actor[]
---@return number
function damageClass : RefreshDpsRealTime ( tableWithActors )
local totalRealTime = 0
local timeSample = Details222.CurrentDPS . GetTimeSample ( )
for _ , actorObject in ipairs ( tableWithActors ) do
---@cast actorObject actordamage
---@type details_currentdps_actorcache
local realTimeDPS = Details222.CurrentDPS . Cache [ actorObject.serial ]
if ( realTimeDPS ) then
realTimeDPS = realTimeDPS.totalDamage / timeSample
actorObject.last_dps_realtime = realTimeDPS
totalRealTime = totalRealTime + realTimeDPS
end
end
return totalRealTime
end
--dps (calculate dps for actors)
---@param tableWithActors table
---@param combatTime combattime
---@return number, number
function damageClass : ContainerRefreshDps ( tableWithActors , combatTime )
local total = 0
local totalRealTime = 0
local bIsEffectiveTime = Details.time_type == 2
local bOrderDpsByRealTime = Details.CurrentDps . CanSortByRealTimeDps ( )
local timeSample = Details222.CurrentDPS . GetTimeSample ( )
if ( bIsEffectiveTime or not Details : CaptureGet ( " damage " ) ) then
for _ , actorObject in ipairs ( tableWithActors ) do
---@cast actorObject actordamage
if ( actorObject.grupo ) then
actorObject.last_dps = actorObject.total / combatTime
else
actorObject.last_dps = actorObject.total / actorObject : Tempo ( )
end
if ( bOrderDpsByRealTime ) then
---@type details_currentdps_actorcache
local realTimeDPS = Details222.CurrentDPS . Cache [ actorObject.serial ]
if ( realTimeDPS ) then
realTimeDPS = realTimeDPS.totalDamage / timeSample
actorObject.last_dps_realtime = realTimeDPS
totalRealTime = totalRealTime + realTimeDPS
end
end
total = total + actorObject.last_dps
end
else
for _ , actorObject in ipairs ( tableWithActors ) do
actorObject.last_dps = actorObject.total / actorObject : Tempo ( )
total = total + actorObject.last_dps
if ( bOrderDpsByRealTime ) then
local realTimeDPS = Details222.CurrentDPS . Cache [ actorObject.serial ] or 0
actorObject.last_dps_realtime = realTimeDPS
totalRealTime = totalRealTime + realTimeDPS
end
end
end
return total , totalRealTime
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--damage taken by spell
local byspell_tooltip_background = { value = 100 , color = { 0.1960 , 0.1960 , 0.1960 , 0.9097 } , texture = [[Interface\AddOns\Details\images\bar_background_dark]] }
function Details : ToolTipBySpell ( instance , tabela , thisLine , keydown )
local GameCooltip = GameCooltip
local combat = instance.showing
local from_spell = tabela [ 1 ] --spellid
local from_spellname
if ( from_spell ) then
from_spellname = select ( 1 , GetSpellInfo ( from_spell ) )
end
--get a list of all damage actors
local AllDamageCharacters = combat : GetActorList ( DETAILS_ATTRIBUTE_DAMAGE )
--hold the targets
local Targets = { }
local total = 0
local top = 0
local is_custom_spell = false
for _ , spellcustom in ipairs ( Details.savedCustomSpells ) do
if ( spellcustom [ 1 ] == from_spell ) then
is_custom_spell = true
end
end
for index , character in ipairs ( AllDamageCharacters ) do
if ( is_custom_spell ) then
for playername , ff_table in pairs ( character.friendlyfire ) do
if ( ff_table.spells [ from_spell ] ) then
local damage_actor = combat ( 1 , playername )
local heal_actor = combat ( 2 , playername )
if ( ( damage_actor or heal_actor ) and ( ( damage_actor and damage_actor : IsPlayer ( ) ) or ( heal_actor and heal_actor : IsPlayer ( ) ) ) ) then
local got
for index , t in ipairs ( Targets ) do
if ( t [ 1 ] == playername ) then
t [ 2 ] = t [ 2 ] + ff_table.spells [ from_spell ]
total = total + ff_table.spells [ from_spell ]
if ( t [ 2 ] > top ) then
top = t [ 2 ]
end
got = true
break
end
end
if ( not got ) then
Targets [ # Targets + 1 ] = { playername , ff_table.spells [ from_spell ] }
total = total + ff_table.spells [ from_spell ]
if ( ff_table.spells [ from_spell ] > top ) then
top = ff_table.spells [ from_spell ]
end
end
end
end
end
else
for playername , ff_table in pairs ( character.friendlyfire ) do
for spellid , amount in pairs ( ff_table.spells ) do
local spellname = select ( 1 , GetSpellInfo ( spellid ) )
if ( spellname == from_spellname ) then
local damage_actor = combat ( 1 , playername )
local heal_actor = combat ( 2 , playername )
if ( ( damage_actor or heal_actor ) and ( ( damage_actor and damage_actor : IsPlayer ( ) ) or ( heal_actor and heal_actor : IsPlayer ( ) ) ) ) then
local got
for index , t in ipairs ( Targets ) do
if ( t [ 1 ] == playername ) then
t [ 2 ] = t [ 2 ] + amount
total = total + amount
if ( t [ 2 ] > top ) then
top = t [ 2 ]
end
got = true
break
end
end
if ( not got ) then
Targets [ # Targets + 1 ] = { playername , amount }
total = total + amount
if ( amount > top ) then
top = amount
end
end
end
end
end
end
end
--search actors which used the spell shown in the bar
local spell = character.spells . _ActorTable [ from_spell ]
if ( spell ) then
for targetname , amount in pairs ( spell.targets ) do
local got = false
local damage_actor = combat ( 1 , targetname )
local heal_actor = combat ( 2 , targetname )
if ( ( damage_actor or heal_actor ) and ( ( damage_actor and damage_actor : IsPlayer ( ) ) or ( heal_actor and heal_actor : IsPlayer ( ) ) ) ) then
for index , t in ipairs ( Targets ) do
if ( t [ 1 ] == targetname ) then
t [ 2 ] = t [ 2 ] + amount
total = total + amount
if ( t [ 2 ] > top ) then
top = t [ 2 ]
end
got = true
break
end
end
if ( not got ) then
Targets [ # Targets + 1 ] = { targetname , amount }
total = total + amount
if ( amount > top ) then
top = amount
end
end
end
end
end
if ( not is_custom_spell ) then
for spellid , spell in pairs ( character.spells . _ActorTable ) do
if ( spellid ~= from_spell ) then
local spellname = select ( 1 , GetSpellInfo ( spellid ) )
if ( spellname == from_spellname ) then
for targetname , amount in pairs ( spell.targets ) do
local got = false
local damage_actor = combat ( 1 , targetname )
local heal_actor = combat ( 2 , targetname )
if ( ( damage_actor or heal_actor ) and ( ( damage_actor and damage_actor : IsPlayer ( ) ) or ( heal_actor and heal_actor : IsPlayer ( ) ) ) ) then
for index , t in ipairs ( Targets ) do
if ( t [ 1 ] == targetname ) then
t [ 2 ] = t [ 2 ] + amount
total = total + amount
if ( t [ 2 ] > top ) then
top = t [ 2 ]
end
got = true
break
end
end
if ( not got ) then
Targets [ # Targets + 1 ] = { targetname , amount }
total = total + amount
if ( amount > top ) then
top = amount
end
end
end
end
end
end
end
end
end
table.sort ( Targets , Details.Sort2 )
bs_tooltip_table = Targets
bs_tooltip_table.damage_total = total
GameCooltip : SetOption ( " StatusBarTexture " , " Interface \\ AddOns \\ Details \\ images \\ bar_serenity " )
local spellname , _ , spellicon = select ( 1 , _GetSpellInfo ( from_spell ) )
GameCooltip : AddLine ( spellname .. " " .. Loc [ " STRING_CUSTOM_ATTRIBUTE_DAMAGE " ] , nil , nil , headerColor , nil , 10 )
GameCooltip : AddIcon ( spellicon , 1 , 1 , 14 , 14 , 0.078125 , 0.921875 , 0.078125 , 0.921875 )
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
Details : AddTooltipHeaderStatusbar ( 1 , 1 , 1 , 0.5 )
local top = Targets [ 1 ] and Targets [ 1 ] [ 2 ]
local lineHeight = Details.tooltip . line_height
for index , t in ipairs ( Targets ) do
GameCooltip : AddLine ( Details : GetOnlyName ( t [ 1 ] ) , Details : ToK ( t [ 2 ] ) .. " ( " .. format ( " %.1f " , t [ 2 ] / total * 100 ) .. " %) " )
local class , _ , _ , _ , _ , r , g , b = Details : GetClass ( t [ 1 ] )
GameCooltip : AddStatusBar ( t [ 2 ] / top * 100 , 1 , r , g , b , 0.8 , false , byspell_tooltip_background )
if ( class ) then
local specID = Details : GetSpec ( t [ 1 ] )
if ( specID ) then
local texture , l , r , t , b = Details : GetSpecIcon ( specID , false )
GameCooltip : AddIcon ( texture , 1 , 1 , lineHeight , lineHeight , l , r , t , b )
else
local texture , l , r , t , b = Details : GetClassIcon ( class )
GameCooltip : AddIcon ( " Interface \\ AddOns \\ Details \\ images \\ classes_small_alpha " , 1 , 1 , lineHeight , lineHeight , l , r , t , b )
end
elseif ( t [ 1 ] == Loc [ " STRING_TARGETS_OTHER1 " ] ) then
GameCooltip : AddIcon ( " Interface \\ AddOns \\ Details \\ images \\ classes_small_alpha " , 1 , 1 , lineHeight , lineHeight , 0.25 , 0.49609375 , 0.75 , 1 )
end
end
GameCooltip : AddLine ( " " )
Details : AddTooltipReportLineText ( )
GameCooltip : SetOption ( " YSpacingMod " , 0 )
GameCooltip : SetOwner ( thisLine )
GameCooltip : Show ( )
end
local function RefreshBarraBySpell ( tabela , barra , instancia )
damageClass : AtualizarBySpell ( tabela , tabela.minha_barra , barra.colocacao , instancia )
end
local on_switch_DTBS_show = function ( instance )
instance : TrocaTabela ( instance , true , 1 , 8 )
return true
end
local DTBS_search_code = [ [
---@type combat, table, instance
local combatObject , instanceContainer , instanceObject = ...
--declade the values to return
local totalDamage , topDamage , amount = 0 , 0 , 0
---@type {key1: actorname, key2: number, key3: actor}[]
local damageTakenFrom = { }
local spellId = @ SPELLID @
local spellName
if ( spellId ) then
spellName = select ( 1 , GetSpellInfo ( spellId ) )
end
---@type actorcontainer
local damageContainer = combatObject : GetContainer ( DETAILS_ATTRIBUTE_DAMAGE )
---@type actorcontainer
local healContainer = combatObject : GetContainer ( DETAILS_ATTRIBUTE_HEAL )
local bIsCustomSpell = false
for _ , customSpellObject in ipairs ( Details.savedCustomSpells ) do
if ( customSpellObject [ 1 ] == spellId ) then
bIsCustomSpell = true
end
end
for index , actorObject in damageContainer : ListActors ( ) do
---@cast actorObject actordamage
--> handle friendly fire spell damage taken
if ( actorObject : IsPlayer ( ) ) then
if ( bIsCustomSpell ) then --if the spell has been modified, check only by its spellId, as it can't get other spells with the same name
for playerName , friendlyFireTable in pairs ( actorObject.friendlyfire ) do
---@cast friendlyFireTable friendlyfiretable
if ( friendlyFireTable.spells [ spellId ] ) then
---@type actordamage
local damageActor = damageContainer : GetActor ( playerName )
---@type actorheal
local healingActor = healContainer : GetActor ( playerName )
if ( ( damageActor and damageActor : IsPlayer ( ) ) or ( healingActor and healingActor : IsPlayer ( ) ) ) then
local got
for index , damageTakenTable in ipairs ( damageTakenFrom ) do
if ( damageTakenTable [ 1 ] == playerName ) then
damageTakenTable [ 2 ] = damageTakenTable [ 2 ] + friendlyFireTable.spells [ spellId ]
if ( damageTakenTable [ 2 ] > topDamage ) then
topDamage = damageTakenTable [ 2 ]
end
got = true
break
end
end
if ( not got ) then
---@type {key1: actorname, key2: number, key3: actor}
local damageTakenTable = { playerName , friendlyFireTable.spells [ spellId ] , damageActor or healingActor }
damageTakenFrom [ # damageTakenFrom + 1 ] = damageTakenTable
if ( friendlyFireTable.spells [ spellId ] > topDamage ) then
topDamage = friendlyFireTable.spells [ spellId ]
end
end
end
end
end
else
for playerName , friendlyFireTable in pairs ( actorObject.friendlyfire ) do
---@cast friendlyFireTable friendlyfiretable
for ffSpellId , damageAmount in pairs ( friendlyFireTable.spells ) do
local ffSpellName = select ( 1 , GetSpellInfo ( ffSpellId ) )
if ( ffSpellName == spellName ) then
---@type actordamage
local damageActor = damageContainer : GetActor ( playerName )
---@type actorheal
local healingActor = healContainer : GetActor ( playerName )
if ( ( damageActor and damageActor : IsPlayer ( ) ) or ( healingActor and healingActor : IsPlayer ( ) ) ) then
local got
for index , damageTakenTable in ipairs ( damageTakenFrom ) do
if ( damageTakenTable [ 1 ] == playerName ) then
damageTakenTable [ 2 ] = damageTakenTable [ 2 ] + damageAmount
if ( damageTakenTable [ 2 ] > topDamage ) then
topDamage = damageTakenTable [ 2 ]
end
got = true
break
end
end
if ( not got ) then
---@type {key1: actorname, key2: number, key3: actor}
local damageTakenTable = { playerName , damageAmount , damageActor or healingActor }
damageTakenFrom [ # damageTakenFrom + 1 ] = damageTakenTable
if ( damageAmount > topDamage ) then
topDamage = damageAmount
end
end
end
end
end
end
end
end
--> handle regular damage taken from spells
---@type spelltable
local spellTable = actorObject : GetSpell ( spellId )
if ( spellTable ) then
for targetName , damageAmount in pairs ( spellTable.targets ) do
local got = false
---@type actordamage
local damageActor = damageContainer : GetActor ( targetName )
---@type actorheal
local healingActor = healContainer : GetActor ( targetName )
if ( ( damageActor and damageActor : IsPlayer ( ) ) or ( healingActor and healingActor : IsPlayer ( ) ) ) then
for index , damageTakenTable in ipairs ( damageTakenFrom ) do
if ( damageTakenTable [ 1 ] == targetName ) then
damageTakenTable [ 2 ] = damageTakenTable [ 2 ] + damageAmount
if ( damageTakenTable [ 2 ] > topDamage ) then
topDamage = damageTakenTable [ 2 ]
end
got = true
break
end
end
if ( not got ) then
---@type {key1: actorname, key2: number, key3: actor}
local damageTakenTable = { targetName , damageAmount , damageActor or healingActor }
damageTakenFrom [ # damageTakenFrom + 1 ] = damageTakenTable
if ( damageAmount > topDamage ) then
topDamage = damageAmount
end
end
end
end
end
if ( not bIsCustomSpell ) then
for thisSpellId , spellTable in pairs ( actorObject.spells . _ActorTable ) do
if ( thisSpellId ~= spellId ) then --this is invalid
local spellname = select ( 1 , GetSpellInfo ( thisSpellId ) )
if ( spellname == spellName ) then
for targetName , damageAmount in pairs ( spellTable.targets ) do
local got = false
---@type actordamage
local damageActor = damageContainer : GetActor ( targetName )
---@type actorheal
local healingActor = healContainer : GetActor ( targetName )
if ( ( damageActor and damageActor : IsPlayer ( ) ) or ( healingActor and healingActor : IsPlayer ( ) ) ) then
for index , damageTakenTable in ipairs ( damageTakenFrom ) do
if ( damageTakenTable [ 1 ] == targetName ) then
damageTakenTable [ 2 ] = damageTakenTable [ 2 ] + damageAmount
if ( damageTakenTable [ 2 ] > topDamage ) then
topDamage = damageTakenTable [ 2 ]
end
got = true
break
end
end
if ( not got ) then
---@type {key1: actorname, key2: number, key3: actor}
local damageTakenTable = { targetName , damageAmount , damageActor or healingActor }
damageTakenFrom [ # damageTakenFrom + 1 ] = damageTakenTable
if ( damageAmount > topDamage ) then
topDamage = damageAmount
end
end
end
end
end
end
end
end
end
table.sort ( damageTakenFrom , Details.Sort2 )
for index , damageTakenTable in ipairs ( damageTakenFrom ) do
instanceContainer : AddValue ( damageTakenTable [ 3 ] , damageTakenTable [ 2 ] ) --actorObject, amountDamage
totalDamage = totalDamage + damageTakenTable [ 2 ] --amountDamage
amount = amount + 1
end
return totalDamage , topDamage , amount
] ]
local function ShowDTBSInWindow ( spell , instance ) --for hold shift key and click, show players which took damage from this spell
local spellname , _ , icon = _GetSpellInfo ( spell [ 1 ] )
local custom_name = spellname .. " - " .. Loc [ " STRING_CUSTOM_DTBS " ] .. " "
--check if already exists
for index , CustomObject in ipairs ( Details.custom ) do
if ( CustomObject : GetName ( ) == custom_name ) then
--fix for not saving funcs on logout
if ( not CustomObject.OnSwitchShow ) then
CustomObject.OnSwitchShow = on_switch_DTBS_show
end
return instance : TrocaTabela ( instance.segmento , 5 , index )
end
end
--create a custom for this spell
local new_custom_object = {
name = custom_name ,
icon = icon ,
attribute = false ,
author = Details.playername ,
desc = spellname .. " " .. Loc [ " STRING_CUSTOM_DTBS " ] ,
source = false ,
target = false ,
script = false ,
tooltip = false ,
temp = true ,
notooltip = true ,
OnSwitchShow = on_switch_DTBS_show ,
}
local new_code = DTBS_search_code
new_code = new_code : gsub ( " @SPELLID@ " , spell [ 1 ] )
new_custom_object.script = new_code
tinsert ( Details.custom , new_custom_object )
setmetatable ( new_custom_object , Details.atributo_custom )
new_custom_object.__index = Details.atributo_custom
return instance : TrocaTabela ( instance.segmento , 5 , # Details.custom )
end
local DTBS_format_name = function ( player_name ) return Details : GetOnlyName ( player_name ) end
local DTBS_format_amount = function ( amount ) return Details : ToK ( amount ) .. " ( " .. format ( " %.1f " , amount / bs_tooltip_table.damage_total * 100 ) .. " %) " end
function damageClass : ReportSingleDTBSLine ( spell , instance , ShiftKeyDown , ControlKeyDown )
if ( ControlKeyDown ) then
local spellname , _ , spellicon = _GetSpellInfo ( spell [ 1 ] )
return Details : OpenAuraPanel ( spell [ 1 ] , spellname , spellicon )
elseif ( ShiftKeyDown ) then
return ShowDTBSInWindow ( spell , instance )
end
local spelllink = Details : GetSpellLink ( spell [ 1 ] )
local report_table = { " Details!: " .. Loc [ " STRING_CUSTOM_DTBS " ] .. " " .. spelllink }
Details : FormatReportLines ( report_table , bs_tooltip_table , DTBS_format_name , DTBS_format_amount )
return Details : Reportar ( report_table , { _no_current = true , _no_inverse = true , _custom = true } )
end
function damageClass : AtualizarBySpell ( tabela , whichRowLine , colocacao , instance )
tabela [ " byspell " ] = true --marca que esta tabela � uma tabela de frags, usado no controla na hora de montar o tooltip
local thisLine = instance.barras [ whichRowLine ] --pega a refer�ncia da barra na janela
if ( not thisLine ) then
print ( " DEBUG: problema com <instance.thisLine> " .. whichRowLine .. " " .. colocacao )
return
end
thisLine.minha_tabela = tabela
local spellName , _ , spellIcon = _GetSpellInfo ( tabela [ 1 ] )
tabela.nome = spellName --evita dar erro ao redimencionar a janela
tabela.minha_barra = whichRowLine
thisLine.colocacao = colocacao
if ( not _getmetatable ( tabela ) ) then
setmetatable ( tabela , { __call = RefreshBarraBySpell } )
tabela._custom = true
end
local total = instance.showing . totals.by_spell
local porcentagem
if ( instance.row_info . percent_type == 1 ) then
porcentagem = format ( " %.1f " , tabela [ 2 ] / total * 100 )
elseif ( instance.row_info . percent_type == 2 ) then
porcentagem = format ( " %.1f " , tabela [ 2 ] / instance.top * 100 )
end
thisLine.lineText1 : SetText ( colocacao .. " . " .. spellName )
local bars_show_data = instance.row_info . textR_show_data
local spell_damage = tabela [ 2 ] -- spell_damage passar por uma ToK function, precisa ser number
if ( not bars_show_data [ 1 ] ) then
spell_damage = tabela [ 2 ] --damage taken by spell n�o tem PS, ent�o � obrigado a passar o dano total
end
if ( not bars_show_data [ 3 ] ) then
porcentagem = " "
else
porcentagem = porcentagem .. " % "
end
local bars_brackets = instance : GetBarBracket ( )
if ( instance.use_multi_fontstrings ) then
instance : SetInLineTexts ( thisLine , " " , ( spell_damage and SelectedToKFunction ( _ , spell_damage ) or " " ) , porcentagem )
else
thisLine.lineText4 : SetText ( ( spell_damage and SelectedToKFunction ( _ , spell_damage ) or " " ) .. bars_brackets [ 1 ] .. porcentagem .. bars_brackets [ 2 ] )
end
thisLine.lineText1 : SetTextColor ( 1 , 1 , 1 , 1 )
thisLine.lineText2 : SetTextColor ( 1 , 1 , 1 , 1 )
thisLine.lineText3 : SetTextColor ( 1 , 1 , 1 , 1 )
thisLine.lineText4 : SetTextColor ( 1 , 1 , 1 , 1 )
thisLine.lineText1 : SetSize ( thisLine : GetWidth ( ) - thisLine.lineText4 : GetStringWidth ( ) - 20 , 15 )
if ( colocacao == 1 ) then
thisLine : SetValue ( 100 )
else
thisLine : SetValue ( tabela [ 2 ] / instance.top * 100 )
end
if ( thisLine.hidden or thisLine.fading_in or thisLine.faded ) then
Details.FadeHandler . Fader ( thisLine , " out " )
end
if ( instance.row_info . texture_class_colors ) then
if ( tabela [ 3 ] > 1 ) then
local r , g , b = Details : GetSpellSchoolColor ( tabela [ 3 ] )
thisLine.textura : SetVertexColor ( r , g , b )
else
local r , g , b = Details : GetSpellSchoolColor ( 0 )
thisLine.textura : SetVertexColor ( r , g , b )
end
end
thisLine.icone_classe : SetTexture ( spellIcon )
thisLine.icone_classe : SetTexCoord ( 0.078125 , 0.921875 , 0.078125 , 0.921875 )
thisLine.icone_classe : SetVertexColor ( 1 , 1 , 1 )
if ( thisLine.mouse_over and not instance.baseframe . isMoving ) then
local classIcon = thisLine : GetClassIcon ( )
thisLine.iconHighlight : SetTexture ( classIcon : GetTexture ( ) )
thisLine.iconHighlight : SetTexCoord ( classIcon : GetTexCoord ( ) )
thisLine.iconHighlight : SetVertexColor ( classIcon : GetVertexColor ( ) )
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--frags
function Details : ToolTipFrags ( instancia , frag , thisLine , keydown )
local name = frag [ 1 ]
local GameCooltip = GameCooltip
--mantendo a fun��o o mais low level poss�vel
local damage_container = instancia.showing [ 1 ]
local frag_actor = damage_container._ActorTable [ damage_container._NameIndexTable [ name ] ]
if ( frag_actor ) then
local damage_taken_table = { }
local took_damage_from = frag_actor.damage_from
local total_damage_taken = frag_actor.damage_taken
local total = 0
for aggressor , _ in pairs ( took_damage_from ) do
local damager_actor = damage_container._ActorTable [ damage_container._NameIndexTable [ aggressor ] ]
if ( damager_actor and not damager_actor.owner ) then --checagem por causa do total e do garbage collector que n�o limpa os names que deram dano
local target_amount = damager_actor.targets [ name ]
if ( target_amount ) then
damage_taken_table [ # damage_taken_table + 1 ] = { aggressor , target_amount , damager_actor.classe }
total = total + target_amount
end
end
end
_table_sort ( damage_taken_table , Details.Sort2 )
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_DAMAGE_FROM " ] , headerColor , # damage_taken_table , [[Interface\Addons\Details\images\icons]] , 0.126953125 , 0.1796875 , 0 , 0.0546875 )
Details : AddTooltipHeaderStatusbar ( 1 , 1 , 1 , 0.5 )
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
local min = 6
local ismaximized = false
--always maximized
if ( true or keydown == " shift " or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3 ) then
min = 99
ismaximized = true
end
if ( ismaximized ) then
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay1 )
end
local top = damage_taken_table [ 1 ] and damage_taken_table [ 1 ] [ 2 ]
frags_tooltip_table = damage_taken_table
frags_tooltip_table.damage_total = total
local lineHeight = Details.tooltip . line_height
if ( # damage_taken_table > 0 ) then
for i = 1 , math.min ( min , # damage_taken_table ) do
local t = damage_taken_table [ i ]
GameCooltip : AddLine ( Details : GetOnlyName ( t [ 1 ] ) , FormatTooltipNumber ( _ , t [ 2 ] ) .. " ( " .. format ( " %.1f " , t [ 2 ] / total * 100 ) .. " %) " )
local classe = t [ 3 ]
if ( not classe ) then
classe = " UNKNOW "
end
if ( classe == " UNKNOW " ) then
GameCooltip : AddIcon ( " Interface \\ LFGFRAME \\ LFGROLE_BW " , nil , nil , lineHeight , lineHeight , .25 , .5 , 0 , 1 )
else
local specID = Details : GetSpec ( t [ 1 ] )
if ( specID ) then
local texture , l , r , t , b = Details : GetSpecIcon ( specID , false )
GameCooltip : AddIcon ( texture , 1 , 1 , lineHeight , lineHeight , l , r , t , b )
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\classes_small_alpha]] , nil , nil , lineHeight , lineHeight , unpack ( Details.class_coords [ classe ] ) )
end
end
local _ , _ , _ , _ , _ , r , g , b = Details : GetClass ( t [ 1 ] )
GameCooltip : AddStatusBar ( t [ 2 ] / top * 100 , 1 , r , g , b , 1 , false , enemies_background )
end
else
GameCooltip : AddLine ( Loc [ " STRING_NO_DATA " ] , nil , 1 , " white " )
GameCooltip : AddIcon ( instancia.row_info . icon_file , nil , nil , 14 , 14 , unpack ( Details.class_coords [ " UNKNOW " ] ) )
end
GameCooltip : AddLine ( " " )
Details : AddTooltipReportLineText ( )
GameCooltip : SetOption ( " StatusBarTexture " , " Interface \\ AddOns \\ Details \\ images \\ bar_serenity " )
GameCooltip : ShowCooltip ( )
end
end
local function RefreshBarraFrags ( tabela , barra , instancia )
damageClass : AtualizarFrags ( tabela , tabela.minha_barra , barra.colocacao , instancia )
end
function damageClass : AtualizarFrags ( tabela , whichRowLine , colocacao , instancia )
tabela [ " frags " ] = true --marca que esta tabela � uma tabela de frags, usado no controla na hora de montar o tooltip
local thisLine = instancia.barras [ whichRowLine ] --pega a refer�ncia da barra na janela
if ( not thisLine ) then
print ( " DEBUG: problema com <instancia.thisLine> " .. whichRowLine .. " " .. rank )
return
end
local previousData = thisLine.minha_tabela
thisLine.minha_tabela = tabela
tabela.nome = tabela [ 1 ] --evita dar erro ao redimencionar a janela
tabela.minha_barra = whichRowLine
thisLine.colocacao = colocacao
if ( not _getmetatable ( tabela ) ) then
setmetatable ( tabela , { __call = RefreshBarraFrags } )
tabela._custom = true
end
local total = instancia.showing . totals.frags_total
local porcentagem
if ( instancia.row_info . percent_type == 1 ) then
porcentagem = format ( " %.1f " , tabela [ 2 ] / total * 100 )
elseif ( instancia.row_info . percent_type == 2 ) then
porcentagem = format ( " %.1f " , tabela [ 2 ] / instancia.top * 100 )
end
thisLine.lineText1 : SetText ( colocacao .. " . " .. tabela [ 1 ] )
local bars_show_data = instancia.row_info . textR_show_data
local bars_brackets = instancia : GetBarBracket ( )
local total_frags = tabela [ 2 ]
if ( not bars_show_data [ 1 ] ) then
total_frags = " "
end
if ( not bars_show_data [ 3 ] ) then
porcentagem = " "
else
porcentagem = porcentagem .. " % "
end
--
if ( instancia.use_multi_fontstrings ) then
instancia : SetInLineTexts ( thisLine , " " , total_frags , porcentagem )
else
thisLine.lineText4 : SetText ( total_frags .. bars_brackets [ 1 ] .. porcentagem .. bars_brackets [ 2 ] )
end
thisLine.lineText1 : SetSize ( thisLine : GetWidth ( ) - thisLine.lineText4 : GetStringWidth ( ) - 20 , 15 )
if ( colocacao == 1 ) then
thisLine : SetValue ( 100 )
else
thisLine : SetValue ( tabela [ 2 ] / instancia.top * 100 )
end
thisLine.lineText1 : SetTextColor ( 1 , 1 , 1 , 1 )
thisLine.lineText4 : SetTextColor ( 1 , 1 , 1 , 1 )
if ( thisLine.hidden or thisLine.fading_in or thisLine.faded ) then
Details.FadeHandler . Fader ( thisLine , " out " )
end
Details : SetBarColors ( thisLine , instancia , unpack ( Details.class_colors [ tabela [ 3 ] ] ) )
if ( tabela [ 3 ] == " UNKNOW " or tabela [ 3 ] == " UNGROUPPLAYER " or tabela [ 3 ] == " ENEMY " ) then
thisLine.icone_classe : SetTexture ( [[Interface\AddOns\Details\images\classes_plus]] )
thisLine.icone_classe : SetTexCoord ( 0.50390625 , 0.62890625 , 0 , 0.125 )
thisLine.icone_classe : SetVertexColor ( 1 , 1 , 1 )
else
thisLine.icone_classe : SetTexture ( instancia.row_info . icon_file )
thisLine.icone_classe : SetTexCoord ( unpack ( Details.class_coords [ tabela [ 3 ] ] ) )
thisLine.icone_classe : SetVertexColor ( 1 , 1 , 1 )
end
if ( thisLine.mouse_over and not instancia.baseframe . isMoving ) then --precisa atualizar o tooltip
--gump:UpdateTooltip(whichRowLine, thisLine, instancia)if(thisLine.mouse_over and not instancia.baseframe.isMoving) then
local classIcon = thisLine : GetClassIcon ( )
thisLine.iconHighlight : SetTexture ( classIcon : GetTexture ( ) )
thisLine.iconHighlight : SetTexCoord ( classIcon : GetTexCoord ( ) )
thisLine.iconHighlight : SetVertexColor ( classIcon : GetVertexColor ( ) )
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--void zones
local on_switch_AVZ_show = function ( instance )
instance : TrocaTabela ( instance , true , 1 , 7 )
return true
end
local AVZ_search_code = [ [
--get the parameters passed
local combat , instance_container , instance = ...
--declade the values to return
local total , top , amount = 0 , 0 , 0
local actor_name = " @ACTORNAME@ "
local actor = combat ( 4 , actor_name )
if ( not actor ) then
return 0 , 0 , 0
end
local damage_actor = combat ( 1 , actor.damage_twin )
local habilidade
local alvos
if ( damage_actor ) then
habilidade = damage_actor.spells . _ActorTable [ actor.damage_spellid ]
end
if ( habilidade ) then
alvos = habilidade.targets
end
local container = actor.debuff_uptime_targets
local tooltip_void_zone_temp = { }
for target_name , debuff_table in pairs ( container ) do
if ( alvos ) then
local damage_alvo = alvos [ target_name ]
if ( damage_alvo ) then
debuff_table.damage = damage_alvo
else
debuff_table.damage = 0
end
else
debuff_table.damage = 0
end
end
local i = 1
for target_name , debuff_table in pairs ( container ) do
local t = tooltip_void_zone_temp [ i ]
if ( not t ) then
t = { }
tinsert ( tooltip_void_zone_temp , t )
end
local target_actor = combat ( 1 , target_name ) or combat ( 2 , target_name ) or combat ( 4 , target_name )
t [ 1 ] = target_name
t [ 2 ] = debuff_table.damage
t [ 3 ] = debuff_table
t [ 4 ] = target_actor
i = i + 1
end
--sort no container:
table.sort ( tooltip_void_zone_temp , Details.sort_tooltip_void_zones )
for index , t in ipairs ( tooltip_void_zone_temp ) do
instance_container : AddValue ( t [ 4 ] , t [ 2 ] )
local custom_actor = instance_container : GetActorTable ( t [ 4 ] )
custom_actor.uptime = t [ 3 ] . uptime
total = total + t [ 2 ]
amount = amount + 1
if ( t [ 2 ] > top ) then
top = t [ 2 ]
end
end
return total , top , amount
] ]
local AVZ_total_code = [ [
local value , top , total , combat , instance , custom_actor = ...
local uptime = custom_actor.uptime or 0
local minutos , segundos = floor ( uptime / 60 ) , floor ( uptime % 60 )
if ( minutos > 0 ) then
uptime = " " .. minutos .. " m " .. segundos .. " s " .. " "
else
uptime = " " .. segundos .. " s " .. " "
end
return Details : ToK2 ( value ) .. " - " .. uptime .. " "
] ]
local function ShowVoidZonesInWindow ( actor , instance )
local spellid = tooltip_void_zone_temp.spellid
local spellname , _ , icon = _GetSpellInfo ( spellid )
local custom_name = spellname .. " - " .. Loc [ " STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT " ] .. " "
--check if already exists
for index , CustomObject in ipairs ( Details.custom ) do
if ( CustomObject : GetName ( ) == custom_name ) then
--fix for not saving funcs on logout
if ( not CustomObject.OnSwitchShow ) then
CustomObject.OnSwitchShow = on_switch_AVZ_show
end
return instance : TrocaTabela ( instance.segmento , 5 , index )
end
end
--create a custom for this spell
local new_custom_object = {
name = custom_name ,
icon = icon ,
attribute = false ,
author = Details.playername ,
desc = spellname .. " " .. Loc [ " STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT " ] ,
source = false ,
target = false ,
script = false ,
tooltip = false ,
temp = true ,
notooltip = true ,
OnSwitchShow = on_switch_AVZ_show ,
}
local new_code = AVZ_search_code
new_code = new_code : gsub ( " @ACTORNAME@ " , actor.nome )
new_custom_object.script = new_code
local new_total_code = AVZ_total_code
new_total_code = new_total_code : gsub ( " @ACTORNAME@ " , actor.nome )
new_total_code = new_total_code : gsub ( " @SPELLID@ " , spellid )
new_custom_object.total_script = new_total_code
tinsert ( Details.custom , new_custom_object )
setmetatable ( new_custom_object , Details.atributo_custom )
new_custom_object.__index = Details.atributo_custom
return instance : TrocaTabela ( instance.segmento , 5 , # Details.custom )
end
function damageClass : ReportSingleVoidZoneLine ( actor , instance , ShiftKeyDown , ControlKeyDown )
local spellid = tooltip_void_zone_temp.spellid
if ( ControlKeyDown ) then
local spellname , _ , spellicon = _GetSpellInfo ( spellid )
return Details : OpenAuraPanel ( spellid , spellname , spellicon )
elseif ( ShiftKeyDown ) then
return ShowVoidZonesInWindow ( actor , instance )
end
local spelllink = Details : GetSpellLink ( spellid )
local report_table = { " Details!: " .. spelllink .. " " .. Loc [ " STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT " ] }
local t = { }
for index , void_table in ipairs ( tooltip_void_zone_temp ) do
--ir� reportar dano zero tamb�m
if ( void_table [ 1 ] and type ( void_table [ 1 ] ) == " string " and void_table [ 2 ] and void_table [ 3 ] and type ( void_table [ 3 ] ) == " table " ) then
local actor_table = { Details : GetOnlyName ( void_table [ 1 ] ) }
local m , s = _math_floor ( void_table [ 3 ] . uptime / 60 ) , _math_floor ( void_table [ 3 ] . uptime % 60 )
if ( m > 0 ) then
actor_table [ 2 ] = FormatTooltipNumber ( _ , void_table [ 3 ] . damage ) .. " ( " .. m .. " m " .. s .. " s " .. " ) "
else
actor_table [ 2 ] = FormatTooltipNumber ( _ , void_table [ 3 ] . damage ) .. " ( " .. s .. " s " .. " ) "
end
t [ # t + 1 ] = actor_table
end
end
Details : FormatReportLines ( report_table , t )
return Details : Reportar ( report_table , { _no_current = true , _no_inverse = true , _custom = true } )
end
local sort_tooltip_void_zones = function ( tabela1 , tabela2 )
if ( tabela1 [ 2 ] > tabela2 [ 2 ] ) then
return true
elseif ( tabela1 [ 2 ] == tabela2 [ 2 ] ) then
if ( tabela1 [ 1 ] ~= " " and tabela2 [ 1 ] ~= " " ) then
return tabela1 [ 3 ] . uptime > tabela2 [ 3 ] . uptime
elseif ( tabela1 [ 1 ] ~= " " ) then
return true
elseif ( tabela2 [ 1 ] ~= " " ) then
return false
end
else
return false
end
end
Details.sort_tooltip_void_zones = sort_tooltip_void_zones
function Details : ToolTipVoidZones ( instancia , actor , barra , keydown )
local damage_actor = instancia.showing [ 1 ] : PegarCombatente ( _ , actor.damage_twin )
local habilidade
local alvos
if ( damage_actor ) then
habilidade = damage_actor.spells . _ActorTable [ actor.damage_spellid ]
end
if ( habilidade ) then
alvos = habilidade.targets
end
local container = actor.debuff_uptime_targets
for target_name , debuff_table in pairs ( container ) do
if ( alvos ) then
local damage_alvo = alvos [ target_name ]
if ( damage_alvo ) then
debuff_table.damage = damage_alvo
else
debuff_table.damage = 0
end
else
debuff_table.damage = 0
end
end
for i = 1 , # tooltip_void_zone_temp do
local t = tooltip_void_zone_temp [ i ]
t [ 1 ] = " "
t [ 2 ] = 0
t [ 3 ] = 0
end
local i = 1
for target_name , debuff_table in pairs ( container ) do
local t = tooltip_void_zone_temp [ i ]
if ( not t ) then
t = { }
tinsert ( tooltip_void_zone_temp , t )
end
t [ 1 ] = target_name
t [ 2 ] = debuff_table.damage
t [ 3 ] = debuff_table
i = i + 1
end
--sort no container:
_table_sort ( tooltip_void_zone_temp , sort_tooltip_void_zones )
--monta o cooltip
local GameCooltip = GameCooltip
local spellname , _ , spellicon = _GetSpellInfo ( actor.damage_spellid )
Details : AddTooltipSpellHeaderText ( spellname .. " " .. Loc [ " STRING_VOIDZONE_TOOLTIP " ] , headerColor , # tooltip_void_zone_temp , spellicon , 0.078125 , 0.921875 , 0.078125 , 0.921875 )
Details : AddTooltipHeaderStatusbar ( 1 , 1 , 1 , 0.5 )
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
--for target_name, debuff_table in pairs(container) do
local first = tooltip_void_zone_temp [ 1 ] and tooltip_void_zone_temp [ 1 ] [ 3 ]
if ( type ( first ) == " table " ) then
first = first.damage
end
tooltip_void_zone_temp.spellid = actor.damage_spellid
tooltip_void_zone_temp.current_actor = actor
local lineHeight = Details.tooltip . line_height
for index , t in ipairs ( tooltip_void_zone_temp ) do
if ( t [ 3 ] == 0 ) then
break
end
local debuff_table = t [ 3 ]
local minutos , segundos = _math_floor ( debuff_table.uptime / 60 ) , _math_floor ( debuff_table.uptime % 60 )
if ( minutos > 0 ) then
GameCooltip : AddLine ( Details : GetOnlyName ( t [ 1 ] ) , FormatTooltipNumber ( _ , debuff_table.damage ) .. " ( " .. minutos .. " m " .. segundos .. " s " .. " ) " )
else
GameCooltip : AddLine ( Details : GetOnlyName ( t [ 1 ] ) , FormatTooltipNumber ( _ , debuff_table.damage ) .. " ( " .. segundos .. " s " .. " ) " )
end
local classe = Details : GetClass ( t [ 1 ] )
if ( classe ) then
local specID = Details : GetSpec ( t [ 1 ] )
if ( specID ) then
local texture , l , r , t , b = Details : GetSpecIcon ( specID , false )
GameCooltip : AddIcon ( texture , 1 , 1 , lineHeight , lineHeight , l , r , t , b )
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\classes_small_alpha]] , nil , nil , lineHeight , lineHeight , unpack ( Details.class_coords [ classe ] ) )
end
else
GameCooltip : AddIcon ( " Interface \\ LFGFRAME \\ LFGROLE_BW " , nil , nil , lineHeight , lineHeight , .25 , .5 , 0 , 1 )
end
local _ , _ , _ , _ , _ , r , g , b = Details : GetClass ( t [ 1 ] )
if ( first == 0 ) then
first = 0.0000000001
end
GameCooltip : AddStatusBar ( debuff_table.damage / first * 100 , 1 , r , g , b , 1 , false , enemies_background )
--Details:AddTooltipBackgroundStatusbar()
end
GameCooltip : AddLine ( " " )
Details : AddTooltipReportLineText ( )
GameCooltip : SetOption ( " StatusBarTexture " , " Interface \\ AddOns \\ Details \\ images \\ bar_serenity " )
GameCooltip : ShowCooltip ( )
end
local function RefreshBarraVoidZone ( tabela , barra , instancia )
tabela : AtualizarVoidZone ( tabela.minha_barra , barra.colocacao , instancia )
end
function atributo_misc : AtualizarVoidZone ( whichRowLine , colocacao , instancia )
--pega a refer�ncia da barra na janela
local thisLine = instancia.barras [ whichRowLine ]
if ( not thisLine ) then
print ( " DEBUG: problema com <instancia.thisLine> " .. whichRowLine .. " " .. rank )
return
end
self._refresh_window = RefreshBarraVoidZone
local previousData = thisLine.minha_tabela
thisLine.minha_tabela = self
self.minha_barra = whichRowLine
thisLine.colocacao = colocacao
local total = instancia.showing . totals.voidzone_damage
local combat_time = instancia.showing : GetCombatTime ( )
local dps = _math_floor ( self.damage / combat_time )
local formated_damage = SelectedToKFunction ( _ , self.damage )
local formated_dps = SelectedToKFunction ( _ , dps )
local porcentagem
if ( instancia.row_info . percent_type == 1 ) then
total = max ( total , 0.0001 )
porcentagem = format ( " %.1f " , self.damage / total * 100 )
elseif ( instancia.row_info . percent_type == 2 ) then
local top = max ( instancia.top , 0.0001 )
porcentagem = format ( " %.1f " , self.damage / top * 100 )
end
local bars_show_data = instancia.row_info . textR_show_data
local bars_brackets = instancia : GetBarBracket ( )
local bars_separator = instancia : GetBarSeparator ( )
if ( not bars_show_data [ 1 ] ) then
formated_damage = " "
end
if ( not bars_show_data [ 2 ] ) then
formated_dps = " "
end
if ( not bars_show_data [ 3 ] ) then
porcentagem = " "
else
porcentagem = porcentagem .. " % "
end
local rightText = formated_damage .. bars_brackets [ 1 ] .. formated_dps .. bars_separator .. porcentagem .. bars_brackets [ 2 ]
if ( UsingCustomRightText ) then
thisLine.lineText4 : SetText ( stringReplace ( instancia.row_info . textR_custom_text , formated_damage , formated_dps , porcentagem , self , instancia.showing , instancia , rightText ) )
else
if ( instancia.use_multi_fontstrings ) then
instancia : SetInLineTexts ( thisLine , formated_damage , formated_dps , porcentagem )
else
thisLine.lineText4 : SetText ( rightText )
end
end
thisLine.lineText1 : SetText ( colocacao .. " . " .. self.nome )
thisLine.lineText1 : SetSize ( thisLine : GetWidth ( ) - thisLine.lineText4 : GetStringWidth ( ) - 20 , 15 )
thisLine.lineText1 : SetTextColor ( 1 , 1 , 1 , 1 )
thisLine.lineText4 : SetTextColor ( 1 , 1 , 1 , 1 )
thisLine : SetValue ( 100 )
if ( thisLine.hidden or thisLine.fading_in or thisLine.faded ) then
Details.FadeHandler . Fader ( thisLine , " out " )
end
local _ , _ , icon = GetSpellInfo ( self.damage_spellid )
local spellSchoolColor = Details.spells_school [ self.spellschool ] and Details.spells_school [ self.spellschool ] . decimals
if ( not spellSchoolColor ) then
spellSchoolColor = Details.spells_school [ 1 ]
end
Details : SetBarColors ( thisLine , instancia , unpack ( spellSchoolColor ) )
thisLine.icone_classe : SetTexture ( icon )
thisLine.icone_classe : SetTexCoord ( 0.078125 , 0.921875 , 0.078125 , 0.921875 )
thisLine.icone_classe : SetVertexColor ( 1 , 1 , 1 )
if ( thisLine.mouse_over and not instancia.baseframe . isMoving ) then
local classIcon = thisLine : GetClassIcon ( )
thisLine.iconHighlight : SetTexture ( classIcon : GetTexture ( ) )
thisLine.iconHighlight : SetTexCoord ( classIcon : GetTexCoord ( ) )
thisLine.iconHighlight : SetVertexColor ( classIcon : GetVertexColor ( ) )
--need call a refresh function
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--main refresh function
---@param instanceObject instance
---@param combatObject combat
---@param bForceUpdate boolean
---@param bExportData boolean
function damageClass : RefreshWindow ( instanceObject , combatObject , bForceUpdate , bExportData )
---@type actorcontainer
local damageContainer = combatObject [ class_type ] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable
--not have something to show
if ( # damageContainer._ActorTable < 1 ) then
if ( Details.debug and false ) then
Details.showing_ActorTable_Timer = Details.showing_ActorTable_Timer or 0
if ( time ( ) > Details.showing_ActorTable_Timer ) then
Details : Msg ( " (debug) nothing to show -> #showing._ActorTable < 1 " )
Details.showing_ActorTable_Timer = time ( ) + 5
end
end
--colocado isso recentemente para fazer as barras de dano sumirem na troca de atributo
return Details : HideBarsNotInUse ( instanceObject , damageContainer ) , " " , 0 , 0
end
--total
local total = 0
--top actor #1
instanceObject.top = 0
local isUsingCache = false
local subAttribute = instanceObject.sub_atributo
local actorTableContent = damageContainer._ActorTable
local amount = # actorTableContent
local windowMode = instanceObject.modo
--pega qual a sub key que ser� usada --sub keys
if ( bExportData ) then
if ( type ( bExportData ) == " boolean " ) then
if ( subAttribute == 1 ) then --DAMAGE DONE
keyName = " total "
elseif ( subAttribute == 2 ) then --DPS
keyName = " last_dps "
elseif ( subAttribute == 3 ) then --DAMAGE TAKEN
keyName = " damage_taken "
if ( Details.damage_taken_everything ) then
windowMode = modo_ALL
end
elseif ( subAttribute == 4 ) then --FRIENDLY FIRE
keyName = " friendlyfire_total "
elseif ( subAttribute == 5 ) then --FRAGS
keyName = " frags "
elseif ( subAttribute == 6 ) then --ENEMIES
keyName = " enemies "
elseif ( subAttribute == 7 ) then --AURAS VOIDZONES
keyName = " voidzones "
elseif ( subAttribute == 8 ) then --BY SPELL
keyName = " damage_taken_by_spells "
end
else
keyName = bExportData.key
windowMode = bExportData.modo
end
elseif ( instanceObject.atributo == 5 ) then --custom
keyName = " custom "
total = combatObject.totals [ instanceObject.customName ]
else
if ( subAttribute == 1 ) then --DAMAGE DONE
keyName = " total "
elseif ( subAttribute == 2 ) then --DPS
keyName = " last_dps "
elseif ( subAttribute == 3 ) then --DAMAGE TAKEN
keyName = " damage_taken "
if ( Details.damage_taken_everything ) then
windowMode = modo_ALL
end
elseif ( subAttribute == 4 ) then --FRIENDLY FIRE
keyName = " friendlyfire_total "
elseif ( subAttribute == 5 ) then --FRAGS
keyName = " frags "
elseif ( subAttribute == 6 ) then --ENEMIES
keyName = " enemies "
elseif ( subAttribute == 7 ) then --AURAS VOIDZONES
keyName = " voidzones "
elseif ( subAttribute == 8 ) then --BY SPELL
keyName = " damage_taken_by_spells "
end
end
if ( keyName == " frags " ) then
local frags = instanceObject.showing . frags
local frags_total_kills = 0
local index = 0
for fragName , fragAmount in pairs ( frags ) do
local fragged_actor = damageContainer._NameIndexTable [ fragName ] --get index
if ( fragged_actor ) then
fragged_actor = damageContainer._ActorTable [ fragged_actor ] --get object
if ( fragged_actor ) then
index = index + 1
local actor_classe = fragged_actor.classe
if ( fragged_actor and fragged_actor.monster ) then
actor_classe = " ENEMY "
elseif ( not actor_classe ) then
actor_classe = " UNGROUPPLAYER "
end
if ( ntable [ index ] ) then
ntable [ index ] [ 1 ] = fragName
ntable [ index ] [ 2 ] = fragAmount
ntable [ index ] [ 3 ] = actor_classe
else
ntable [ index ] = { fragName , fragAmount , actor_classe }
end
frags_total_kills = frags_total_kills + fragAmount
end
end
end
local tsize = # ntable
if ( index < tsize ) then
for i = index + 1 , tsize do
ntable [ i ] [ 2 ] = 0
end
end
instanceObject.top = 0
if ( tsize > 0 ) then
_table_sort ( ntable , Details.Sort2 )
instanceObject.top = ntable [ 1 ] [ 2 ]
end
total = index
if ( bExportData ) then
local export = { }
for i = 1 , index do
export [ i ] = { ntable [ i ] [ 1 ] , ntable [ i ] [ 2 ] , ntable [ i ] [ 3 ] }
end
return export
end
if ( total < 1 ) then
instanceObject : EsconderScrollBar ( )
return Details : EndRefresh ( instanceObject , total , combatObject , damageContainer ) --retorna a tabela que precisa ganhar o refresh
end
combatObject.totals . frags_total = frags_total_kills
instanceObject : RefreshScrollBar ( total )
local whichRowLine = 1
local lineContainer = instanceObject.barras
for i = instanceObject.barraS [ 1 ] , instanceObject.barraS [ 2 ] , 1 do
damageClass : AtualizarFrags ( ntable [ i ] , whichRowLine , i , instanceObject )
whichRowLine = whichRowLine + 1
end
return Details : EndRefresh ( instanceObject , total , combatObject , damageContainer ) --retorna a tabela que precisa ganhar o refresh
elseif ( keyName == " damage_taken_by_spells " ) then
local bs_index , total = 0 , 0
Details : Destroy ( bs_index_table )
local combat = combatObject
local AllDamageCharacters = combat : GetActorList ( DETAILS_ATTRIBUTE_DAMAGE )
--do a loop amoung the actors
for index , character in ipairs ( AllDamageCharacters ) do
--is the actor a player?
if ( character : IsPlayer ( ) ) then
for source_name , _ in pairs ( character.damage_from ) do
local source = combat ( 1 , source_name )
if ( source ) then
--came from an enemy
if ( not source : IsPlayer ( ) ) then
local AllSpells = source : GetSpellList ( )
for spellid , spell in pairs ( AllSpells ) do
local on_player = spell.targets [ character.nome ]
if ( on_player and on_player >= 1 ) then
local spellname = _GetSpellInfo ( spellid )
if ( spellname ) then
local has_index = bs_index_table [ spellname ]
local this_spell
if ( has_index ) then
this_spell = bs_table [ has_index ]
else
bs_index = bs_index + 1
this_spell = bs_table [ bs_index ]
if ( this_spell ) then
this_spell [ 1 ] = spellid
this_spell [ 2 ] = 0
this_spell [ 3 ] = spell.spellschool or Details.spell_school_cache [ select ( 1 , GetSpellInfo ( spellid ) ) ] or 1
bs_index_table [ spellname ] = bs_index
else
this_spell = { spellid , 0 , spell.spellschool or Details.spell_school_cache [ select ( 1 , GetSpellInfo ( spellid ) ) ] or 1 }
bs_table [ bs_index ] = this_spell
bs_index_table [ spellname ] = bs_index
end
end
this_spell [ 2 ] = this_spell [ 2 ] + on_player
total = total + on_player
else
error ( " error - no spell id for DTBS " .. spellid )
end
end
end
elseif ( source : IsGroupPlayer ( ) ) then -- friendly fire
local AllSpells = source.friendlyfire [ character.nome ] and source.friendlyfire [ character.nome ] . spells
if ( AllSpells ) then -- se n�o existir pode ter vindo de um pet, talvez
for spellid , on_player in pairs ( AllSpells ) do
if ( on_player and on_player >= 1 ) then
local spellname = _GetSpellInfo ( spellid )
if ( spellname ) then
local has_index = bs_index_table [ spellname ]
local this_spell
if ( has_index ) then
this_spell = bs_table [ has_index ]
else
bs_index = bs_index + 1
this_spell = bs_table [ bs_index ]
if ( this_spell ) then
this_spell [ 1 ] = spellid
this_spell [ 2 ] = 0
this_spell [ 3 ] = Details.spell_school_cache [ select ( 1 , GetSpellInfo ( spellid ) ) ] or 1
bs_index_table [ spellname ] = bs_index
else
this_spell = { spellid , 0 , Details.spell_school_cache [ select ( 1 , GetSpellInfo ( spellid ) ) ] or 1 }
bs_table [ bs_index ] = this_spell
bs_index_table [ spellname ] = bs_index
end
end
this_spell [ 2 ] = this_spell [ 2 ] + on_player
total = total + on_player
else
error ( " error - no spell id for DTBS friendly fire " .. spellid )
end
end
end
end
end
end
end
end
end
local tsize = # bs_table
if ( bs_index < tsize ) then
for i = bs_index + 1 , tsize do
bs_table [ i ] [ 2 ] = 0
end
end
instanceObject.top = 0
if ( tsize > 0 ) then
_table_sort ( bs_table , Details.Sort2 )
instanceObject.top = bs_table [ 1 ] [ 2 ]
end
local total2 = bs_index
if ( bExportData ) then
local export = { }
for i = 1 , bs_index do
-- spellid, total, spellschool
export [ i ] = { spellid = bs_table [ i ] [ 1 ] , damage = bs_table [ i ] [ 2 ] , spellschool = bs_table [ i ] [ 3 ] }
end
return total , " damage " , instanceObject.top , bs_index , export
end
if ( bs_index < 1 ) then
instanceObject : EsconderScrollBar ( )
return Details : EndRefresh ( instanceObject , bs_index , combatObject , damageContainer ) --retorna a tabela que precisa ganhar o refresh
end
combatObject.totals . by_spell = total
instanceObject : RefreshScrollBar ( bs_index )
local whichRowLine = 1
local lineContainer = instanceObject.barras
for i = instanceObject.barraS [ 1 ] , instanceObject.barraS [ 2 ] , 1 do
damageClass : AtualizarBySpell ( bs_table [ i ] , whichRowLine , i , instanceObject )
whichRowLine = whichRowLine + 1
end
return Details : EndRefresh ( instanceObject , bs_index , combatObject , damageContainer )
elseif ( keyName == " voidzones " ) then
local index = 0
local misc_container = combatObject [ 4 ]
local voidzone_damage_total = 0
for _ , actor in ipairs ( misc_container._ActorTable ) do
if ( actor.boss_debuff ) then
index = index + 1
--pega no container de dano o actor respons�vel por aplicar o debuff
local twin_damage_actor = damageContainer._NameIndexTable [ actor.damage_twin ] or damageContainer._NameIndexTable [ " [*] " .. actor.damage_twin ]
if ( twin_damage_actor ) then
local index = twin_damage_actor
twin_damage_actor = damageContainer._ActorTable [ twin_damage_actor ]
local spell = twin_damage_actor.spells . _ActorTable [ actor.damage_spellid ]
if ( spell ) then
--fix spell, sometimes there is two spells with the same name, one is the cast and other is the debuff
if ( spell.total == 0 and not actor.damage_spellid_fixed ) then
local curname = _GetSpellInfo ( actor.damage_spellid )
for spellid , spelltable in pairs ( twin_damage_actor.spells . _ActorTable ) do
if ( spelltable.total > spell.total ) then
local name = _GetSpellInfo ( spellid )
if ( name == curname ) then
actor.damage_spellid = spellid
spell = spelltable
end
end
end
actor.damage_spellid_fixed = true
end
actor.damage = spell.total
voidzone_damage_total = voidzone_damage_total + spell.total
elseif ( not actor.damage_spellid_fixed ) then --not
--fix spell, if the spellid passed for debuff uptime is actully the spell id of a ability and not if the aura it self
actor.damage_spellid_fixed = true
local found = false
for spellid , spelltable in pairs ( twin_damage_actor.spells . _ActorTable ) do
local name = _GetSpellInfo ( spellid )
if ( actor.damage_twin : find ( name ) ) then
actor.damage = spelltable.total
voidzone_damage_total = voidzone_damage_total + spelltable.total
actor.damage_spellid = spellid
found = true
break
end
end
if ( not found ) then
actor.damage = 0
end
else
actor.damage = 0
end
else
actor.damage = 0
end
vtable [ index ] = actor
end
end
local tsize = # vtable
if ( index < tsize ) then
for i = index + 1 , tsize do
vtable [ i ] = nil
end
end
if ( tsize > 0 and vtable [ 1 ] ) then
_table_sort ( vtable , void_zone_sort )
instanceObject.top = vtable [ 1 ] . damage
end
total = index
if ( bExportData ) then
for _ , t in ipairs ( vtable ) do
t.report_name = Details : GetSpellLink ( t.damage_spellid )
end
return voidzone_damage_total , " damage " , instanceObject.top , total , vtable , " report_name "
end
if ( total < 1 ) then
instanceObject : EsconderScrollBar ( )
return Details : EndRefresh ( instanceObject , total , combatObject , damageContainer ) --retorna a tabela que precisa ganhar o refresh
end
combatObject.totals . voidzone_damage = voidzone_damage_total
instanceObject : RefreshScrollBar ( total )
local whichRowLine = 1
local lineContainer = instanceObject.barras
for i = instanceObject.barraS [ 1 ] , instanceObject.barraS [ 2 ] , 1 do
vtable [ i ] : AtualizarVoidZone ( whichRowLine , i , instanceObject )
whichRowLine = whichRowLine + 1
end
return Details : EndRefresh ( instanceObject , total , combatObject , damageContainer ) --retorna a tabela que precisa ganhar o refresh
else
--/run Details:Dump(Details:GetCurrentCombat():GetActor(1, "Injured Steelspine 1"))
if ( keyName == " enemies " ) then
amount , total = Details : ContainerSortEnemies ( actorTableContent , amount , " damage_taken " )
--remove actors with zero damage taken
local newAmount = 0
for i = 1 , # actorTableContent do
if ( actorTableContent [ i ] . damage_taken < 1 ) then
newAmount = i - 1
break
end
end
--if all units shown are enemies and all have damage taken, check if newAmount is zero and #conteudo has value bigger than 0
if ( newAmount == 0 and # actorTableContent > 0 ) then
amount = amount
else
amount = newAmount
end
--keyName = "damage_taken"
--result of the first actor
instanceObject.top = actorTableContent [ 1 ] and actorTableContent [ 1 ] [ keyName ]
elseif ( windowMode == DETAILS_MODE_ALL ) then --mostrando ALL
--faz o sort da categoria e retorna o amount corrigido
if ( subAttribute == 2 ) then
local combat_time = instanceObject.showing : GetCombatTime ( )
total = damageClass : ContainerRefreshDps ( actorTableContent , combat_time )
else
--pega o total ja aplicado na tabela do combate
total = combatObject.totals [ class_type ]
end
amount = Details : ContainerSort ( actorTableContent , amount , keyName )
--grava o total
instanceObject.top = actorTableContent [ 1 ] [ keyName ]
elseif ( windowMode == DETAILS_MODE_GROUP ) then --mostrando GROUP
if ( Details.in_combat and instanceObject.segmento == 0 and not bExportData ) then
isUsingCache = true
end
if ( isUsingCache ) then
actorTableContent = Details.cache_damage_group
if ( # actorTableContent < 1 ) then
if ( Details.debug and false ) then
Details.showing_ActorTable_Timer2 = Details.showing_ActorTable_Timer2 or 0
if ( time ( ) > Details.showing_ActorTable_Timer2 ) then
Details : Msg ( " (debug) nothing to show -> #conteudo < 1 (using cache) " )
Details.showing_ActorTable_Timer2 = time ( ) + 5
end
end
return Details : HideBarsNotInUse ( instanceObject , damageContainer ) , " " , 0 , 0
end
local bOrderDpsByRealTime = Details.CurrentDps . CanSortByRealTimeDps ( )
if ( subAttribute == 2 ) then --dps
local combatTime = combatObject : GetCombatTime ( )
local realTimeTotal = 0
total , realTimeTotal = damageClass : ContainerRefreshDps ( actorTableContent , combatTime )
if ( bOrderDpsByRealTime ) then
total = realTimeTotal
end
elseif ( subAttribute == 1 ) then --damage done
if ( bOrderDpsByRealTime ) then
total = damageClass : RefreshDpsRealTime ( actorTableContent )
end
end
if ( bOrderDpsByRealTime ) then
_table_sort ( actorTableContent , Details.SortByRealTimeDps )
if ( actorTableContent [ 1 ] [ " last_dps_realtime " ] < 1 ) then
amount = 0
else
instanceObject.top = actorTableContent [ 1 ] . last_dps_realtime
amount = # actorTableContent
end
else
_table_sort ( actorTableContent , Details.SortKeySimple )
if ( actorTableContent [ 1 ] [ keyName ] < 1 ) then
amount = 0
else
instanceObject.top = actorTableContent [ 1 ] [ keyName ]
amount = # actorTableContent
end
if ( subAttribute ~= 2 ) then --other than dps because dps already did the iteration and the total is already calculated
for i = 1 , amount do
total = total + actorTableContent [ i ] [ keyName ]
end
end
end
else
if ( subAttribute == 2 ) then --dps
local combatTime = combatObject : GetCombatTime ( )
damageClass : ContainerRefreshDps ( actorTableContent , combatTime )
end
_table_sort ( actorTableContent , Details.SortKeyGroup )
end
--
if ( not isUsingCache ) then
for index , player in ipairs ( actorTableContent ) do
if ( player.grupo ) then --� um player e esta em grupo
if ( player [ keyName ] < 1 ) then --dano menor que 1, interromper o loop
amount = index - 1
break
end
total = total + player [ keyName ]
else
amount = index - 1
break
end
end
instanceObject.top = actorTableContent [ 1 ] and actorTableContent [ 1 ] [ keyName ]
end
end
end
--refaz o mapa do container
if ( not isUsingCache ) then
damageContainer : remapear ( )
end
if ( bExportData ) then
return total , keyName , instanceObject.top , amount
end
if ( amount < 1 ) then --n�o h� barras para mostrar
if ( bForceUpdate ) then
if ( instanceObject.modo == 2 ) then --group
for i = 1 , instanceObject.rows_fit_in_window do
Details.FadeHandler . Fader ( instanceObject.barras [ i ] , " in " , Details.fade_speed )
end
end
end
instanceObject : EsconderScrollBar ( ) --precisaria esconder a scroll bar
if ( Details.debug and false ) then
Details.showing_ActorTable_Timer2 = Details.showing_ActorTable_Timer2 or 0
if ( time ( ) > Details.showing_ActorTable_Timer2 ) then
Details : Msg ( " (debug) nothing to show -> amount < 1 " )
Details.showing_ActorTable_Timer2 = time ( ) + 5
end
end
return Details : EndRefresh ( instanceObject , total , combatObject , damageContainer ) --retorna a tabela que precisa ganhar o refresh
end
instanceObject : RefreshScrollBar ( amount )
local whichRowLine = 1
local lineContainer = instanceObject.barras
local percentageType = instanceObject.row_info . percent_type
local barsShowData = instanceObject.row_info . textR_show_data
local barsBrackets = instanceObject : GetBarBracket ( )
local barsSeparator = instanceObject : GetBarSeparator ( )
local baseframe = instanceObject.baseframe
local useAnimations = Details.is_using_row_animations and ( not baseframe.isStretching and not bForceUpdate and not baseframe.isResizing )
if ( total == 0 ) then
total = 0.00000001
end
local myPos
local following = instanceObject.following . enabled and subAttribute ~= 6
if ( following ) then
if ( isUsingCache ) then
local pname = Details.playername
for i , actor in ipairs ( actorTableContent ) do
if ( actor.nome == pname ) then
myPos = i
break
end
end
else
myPos = damageContainer._NameIndexTable [ Details.playername ]
end
end
local combatTime = instanceObject.showing : GetCombatTime ( )
UsingCustomLeftText = instanceObject.row_info . textL_enable_custom_text
UsingCustomRightText = instanceObject.row_info . textR_enable_custom_text
local useTotalBar = false
if ( instanceObject.total_bar . enabled ) then
useTotalBar = true
if ( instanceObject.total_bar . only_in_group and ( not IsInGroup ( ) and not IsInRaid ( ) ) ) then
useTotalBar = false
end
if ( subAttribute > 4 ) then --enemies, frags, void zones
useTotalBar = false
end
end
if ( subAttribute == 2 ) then --dps
instanceObject.player_top_dps = actorTableContent [ 1 ] . last_dps
instanceObject.player_top_dps_threshold = instanceObject.player_top_dps - ( instanceObject.player_top_dps * 0.65 )
end
local totalBarIsShown
if ( instanceObject.bars_sort_direction == 1 ) then --top to bottom
if ( useTotalBar and instanceObject.barraS [ 1 ] == 1 ) then
whichRowLine = 2
local iterLast = instanceObject.barraS [ 2 ]
if ( iterLast == instanceObject.rows_fit_in_window ) then
iterLast = iterLast - 1
end
local row1 = lineContainer [ 1 ]
row1.minha_tabela = nil
row1.lineText1 : SetText ( Loc [ " STRING_TOTAL " ] )
if ( instanceObject.use_multi_fontstrings ) then
row1.lineText2 : SetText ( " " )
row1.lineText3 : SetText ( Details : ToK2 ( total ) )
row1.lineText4 : SetText ( Details : ToK ( total / combatTime ) )
else
row1.lineText4 : SetText ( Details : ToK2 ( total ) .. " ( " .. Details : ToK ( total / combatTime ) .. " ) " )
end
row1 : SetValue ( 100 )
local r , g , b = unpack ( instanceObject.total_bar . color )
row1.textura : SetVertexColor ( r , g , b )
row1.icone_classe : SetTexture ( instanceObject.total_bar . icon )
row1.icone_classe : SetTexCoord ( 0.0625 , 0.9375 , 0.0625 , 0.9375 )
Details.FadeHandler . Fader ( row1 , " out " )
totalBarIsShown = true
if ( following and myPos and myPos + 1 > instanceObject.rows_fit_in_window and instanceObject.barraS [ 2 ] < myPos + 1 ) then
for i = instanceObject.barraS [ 1 ] , iterLast - 1 , 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
actorTableContent [ myPos ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , myPos , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
else
for i = instanceObject.barraS [ 1 ] , iterLast , 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
end
else
if ( following and myPos and myPos > instanceObject.rows_fit_in_window and instanceObject.barraS [ 2 ] < myPos ) then
for i = instanceObject.barraS [ 1 ] , instanceObject.barraS [ 2 ] - 1 , 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
actorTableContent [ myPos ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , myPos , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
else
for i = instanceObject.barraS [ 1 ] , instanceObject.barraS [ 2 ] , 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
end
end
elseif ( instanceObject.bars_sort_direction == 2 ) then --bottom to top
if ( useTotalBar and instanceObject.barraS [ 1 ] == 1 ) then
whichRowLine = 2
local iter_last = instanceObject.barraS [ 2 ]
if ( iter_last == instanceObject.rows_fit_in_window ) then
iter_last = iter_last - 1
end
local row1 = lineContainer [ 1 ]
row1.minha_tabela = nil
row1.lineText1 : SetText ( Loc [ " STRING_TOTAL " ] )
if ( instanceObject.use_multi_fontstrings ) then
row1.lineText2 : SetText ( " " )
row1.lineText3 : SetText ( Details : ToK2 ( total ) )
row1.lineText4 : SetText ( Details : ToK ( total / combatTime ) )
else
row1.lineText4 : SetText ( Details : ToK2 ( total ) .. " ( " .. Details : ToK ( total / combatTime ) .. " ) " )
end
row1 : SetValue ( 100 )
local r , g , b = unpack ( instanceObject.total_bar . color )
row1.textura : SetVertexColor ( r , g , b )
row1.icone_classe : SetTexture ( instanceObject.total_bar . icon )
row1.icone_classe : SetTexCoord ( 0.0625 , 0.9375 , 0.0625 , 0.9375 )
Details.FadeHandler . Fader ( row1 , " out " )
totalBarIsShown = true
if ( following and myPos and myPos + 1 > instanceObject.rows_fit_in_window and instanceObject.barraS [ 2 ] < myPos + 1 ) then
actorTableContent [ myPos ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , myPos , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
for i = iter_last - 1 , instanceObject.barraS [ 1 ] , - 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
else
for i = iter_last , instanceObject.barraS [ 1 ] , - 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
end
else
if ( following and myPos and myPos > instanceObject.rows_fit_in_window and instanceObject.barraS [ 2 ] < myPos ) then
actorTableContent [ myPos ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , myPos , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
for i = instanceObject.barraS [ 2 ] - 1 , instanceObject.barraS [ 1 ] , - 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
else
for i = instanceObject.barraS [ 2 ] , instanceObject.barraS [ 1 ] , - 1 do
if ( actorTableContent [ i ] ) then
actorTableContent [ i ] : RefreshLine ( instanceObject , lineContainer , whichRowLine , i , total , subAttribute , bForceUpdate , keyName , combatTime , percentageType , useAnimations , barsShowData , barsBrackets , barsSeparator )
whichRowLine = whichRowLine + 1
end
end
end
end
end
if ( totalBarIsShown ) then
instanceObject : RefreshScrollBar ( amount + 1 )
else
instanceObject : RefreshScrollBar ( amount )
end
if ( useAnimations ) then
instanceObject : PerformAnimations ( whichRowLine - 1 )
end
--beta, hidar barras n�o usadas durante um refresh for�ado
if ( bForceUpdate ) then
if ( instanceObject.modo == 2 ) then --group
for i = whichRowLine , instanceObject.rows_fit_in_window do
Details.FadeHandler . Fader ( instanceObject.barras [ i ] , " in " , Details.fade_speed )
end
end
end
Details.LastFullDamageUpdate = Details._tempo
instanceObject : AutoAlignInLineFontStrings ( )
return Details : EndRefresh ( instanceObject , total , combatObject , damageContainer ) --retorna a tabela que precisa ganhar o refresh
end
--[[exported]] function Details : AutoAlignInLineFontStrings ( )
--if this instance is using in line texts, check the min distance and the length of strings to make them more spread appart
if ( self.use_multi_fontstrings and self.use_auto_align_multi_fontstrings ) then
local maxStringLength_StringFour = 0
local maxStringLength_StringThree = 0
local profileOffsetString3 = self.fontstrings_text3_anchor
local profileOffsetString2 = self.fontstrings_text2_anchor
local profileYOffset = self.row_info . text_yoffset
Details.CacheInLineMaxDistance = Details.CacheInLineMaxDistance or { }
Details.CacheInLineMaxDistance [ self : GetId ( ) ] = Details.CacheInLineMaxDistance [ self : GetId ( ) ] or { [ 2 ] = profileOffsetString2 , [ 3 ] = profileOffsetString3 }
--space between string4 and string3 (usually dps is 4 and total value is 3)
for lineId = 1 , self : GetNumLinesShown ( ) do
local thisLine = self : GetLine ( lineId )
--check strings 3 and 4
if ( thisLine.lineText4 : GetText ( ) ~= " " and thisLine.lineText3 : GetText ( ) ~= " " ) then
--the length of the far right string determines the space between it and the next string in the left
local stringLength = thisLine.lineText4 : GetStringWidth ( )
maxStringLength_StringFour = stringLength > maxStringLength_StringFour and stringLength or maxStringLength_StringFour
end
--check strings 2 and 3
if ( thisLine.lineText2 : GetText ( ) ~= " " and thisLine.lineText3 : GetText ( ) ~= " " ) then
--the length of the middle string determines the space between it and the next string in the left
local stringLength = thisLine.lineText3 : GetStringWidth ( )
maxStringLength_StringThree = stringLength > maxStringLength_StringThree and stringLength or maxStringLength_StringThree
end
end
--if the length bigger than the min distance? calculate for string4 to string3 distance
if ( ( maxStringLength_StringFour > 0 ) and ( maxStringLength_StringFour + 5 > profileOffsetString3 ) ) then
local newOffset = maxStringLength_StringFour + 5
--check if the current needed min distance is bigger than the distance stored in the cache
local currentCacheMaxValue = Details.CacheInLineMaxDistance [ self : GetId ( ) ] [ 3 ]
if ( currentCacheMaxValue < newOffset ) then
currentCacheMaxValue = newOffset
Details.CacheInLineMaxDistance [ self : GetId ( ) ] [ 3 ] = currentCacheMaxValue
else
--if not, use the distance value cached to avoid jittering in the string
newOffset = currentCacheMaxValue
end
--update the lines
for lineId = 1 , self : GetNumLinesShown ( ) do
local thisLine = self : GetLine ( lineId )
thisLine.lineText3 : SetPoint ( " right " , thisLine.statusbar , " right " , - newOffset , profileYOffset )
end
end
--check if there's length in the third string, also the third string cannot have a length if the second string is empty
if ( maxStringLength_StringThree > 0 ) then
local newOffset = maxStringLength_StringThree + maxStringLength_StringFour + 14
if ( newOffset >= profileOffsetString2 ) then
--check if the current needed min distance is bigger than the distance stored in the cache
local currentCacheMaxValue = Details.CacheInLineMaxDistance [ self : GetId ( ) ] [ 2 ]
if ( currentCacheMaxValue < newOffset ) then
currentCacheMaxValue = newOffset
Details.CacheInLineMaxDistance [ self : GetId ( ) ] [ 2 ] = currentCacheMaxValue
else
--if not, use the distance value cached to avoid jittering in the string
newOffset = currentCacheMaxValue
end
--update the lines
for lineId = 1 , self : GetNumLinesShown ( ) do
local thisLine = self : GetLine ( lineId )
thisLine.lineText2 : SetPoint ( " right " , thisLine.statusbar , " right " , - newOffset , profileYOffset )
end
end
end
--reduce the size of the actor name string based on the total size of all strings in the right side
for lineId = 1 , self : GetNumLinesShown ( ) do
local thisLine = self : GetLine ( lineId )
--check if there's something showing in this line
--check if the line is shown and if the text exists for sanitization
if ( thisLine.minha_tabela and thisLine : IsShown ( ) and thisLine.lineText1 : GetText ( ) ) then
local playerNameFontString = thisLine.lineText1
local text2 = thisLine.lineText2
local text3 = thisLine.lineText3
local text4 = thisLine.lineText4
local totalWidth = text2 : GetStringWidth ( ) + text3 : GetStringWidth ( ) + text4 : GetStringWidth ( )
totalWidth = totalWidth + 40 - self.fontstrings_text_limit_offset
DetailsFramework : TruncateTextSafe ( playerNameFontString , self.cached_bar_width - totalWidth ) --this avoid truncated strings with ...
--these commented lines are for to create a cache and store the name already truncated there to safe performance
--local truncatedName = playerNameFontString:GetText()
--local actorObject = thisLine.minha_tabela
--actorObject.name_cached = truncatedName
--actorObject.name_cached_time = GetTime()
end
end
end
end
--handle internal details! events
local eventListener = Details : CreateEventListener ( )
eventListener : RegisterEvent ( " COMBAT_PLAYER_ENTER " , function ( )
if ( Details.CacheInLineMaxDistance ) then
Details : Destroy ( Details.CacheInLineMaxDistance )
for i = 1 , 10 do
C_Timer.After ( i , function ( )
Details : Destroy ( Details.CacheInLineMaxDistance )
end )
end
end
end )
local actor_class_color_r , actor_class_color_g , actor_class_color_b
-- ~texts
--[[exported]] function Details : SetInLineTexts ( thisLine , valueText , perSecondText , percentText )
--set defaults
local instance = self
valueText = valueText or " "
perSecondText = perSecondText or " "
percentText = percentText or " "
if ( ( Details.use_realtimedps or ( Details.combat_log . evoker_show_realtimedps and Details.playerspecid == 1473 ) ) and Details.in_combat ) then --real time
if ( thisLine : GetActor ( ) ) then
local actorSerial = thisLine : GetActor ( ) . serial
local currentDps = Details.CurrentDps . GetCurrentDps ( actorSerial )
if ( currentDps and currentDps > 0 ) then
currentDps = Details : ToK2 ( currentDps )
end
perSecondText = currentDps
end
end
--check if the instance is showing total, dps and percent
local instanceSettings = instance.row_info
if ( not instanceSettings.textR_show_data [ 3 ] ) then --percent text disabled on options panel
local attributeId = instance : GetDisplay ( )
if ( attributeId ~= 5 ) then --not custom
percentText = " "
end
end
--parse information
if ( percentText ~= " " ) then --has percent text
thisLine.lineText4 : SetText ( percentText )
if ( perSecondText ~= " " ) then --has dps?
thisLine.lineText3 : SetText ( perSecondText ) --set dps
thisLine.lineText2 : SetText ( valueText ) --set amount
else
thisLine.lineText3 : SetText ( valueText ) --set amount
thisLine.lineText2 : SetText ( " " ) --clear
end
else --no percent text
if ( perSecondText ~= " " ) then --has dps and no percent
thisLine.lineText4 : SetText ( perSecondText ) --set dps
thisLine.lineText3 : SetText ( valueText ) --set amount
thisLine.lineText2 : SetText ( " " ) --clear
else --no dps and not percent
thisLine.lineText4 : SetText ( valueText ) --set dps
thisLine.lineText3 : SetText ( " " ) --clear
thisLine.lineText2 : SetText ( " " ) --clear
end
end
end
-- ~atualizar ~barra ~update
function damageClass : RefreshLine ( instanceObject , lineContainer , whichRowLine , rank , total , subAttribute , bForceRefresh , keyName , combatTime , percentageType , bUseAnimations , bars_show_data , bars_brackets , bars_separator )
local thisLine = lineContainer [ whichRowLine ]
if ( not thisLine ) then
print ( " DEBUG: problema com <instance.thisLine> " .. whichRowLine .. " " .. rank )
return
end
local previousData = thisLine.minha_tabela
thisLine.minha_tabela = self --store references
self.minha_barra = thisLine --store references
thisLine.colocacao = rank
self.colocacao = rank
local damageTotal = self.total --total damage of this actor
local dps
local percentString
local percentNumber
--calc the percent amount base on the percent type
if ( percentageType == 1 ) then
percentString = format ( " %.1f " , self [ keyName ] / total * 100 )
elseif ( percentageType == 2 ) then
percentString = format ( " %.1f " , self [ keyName ] / instanceObject.top * 100 )
end
local currentCombat = Details : GetCurrentCombat ( )
--calculate the actor dps
if ( ( Details.time_type == 2 and self.grupo ) or not Details : CaptureGet ( " damage " ) or instanceObject.segmento == - 1 or Details.use_realtimedps ) then
if ( Details.use_realtimedps and Details.in_combat ) then
local currentDps = self.last_dps_realtime
if ( currentDps ) then
dps = currentDps
end
end
if ( not dps ) then
if ( instanceObject.segmento == - 1 and combatTime == 0 ) then
local actor = currentCombat ( 1 , self.nome )
if ( actor ) then
local combatTime = actor : Tempo ( )
dps = damageTotal / combatTime
self.last_dps = dps
else
dps = damageTotal / combatTime
self.last_dps = dps
end
else
dps = damageTotal / combatTime
self.last_dps = dps
end
end
else
if ( not self.on_hold ) then
dps = damageTotal / self : Tempo ( ) --calcula o dps deste objeto
self.last_dps = dps --salva o dps dele
else
if ( self.last_dps == 0 ) then --n�o calculou o dps dele ainda mas entrou em standby
dps = damageTotal / self : Tempo ( )
self.last_dps = dps
else
dps = self.last_dps
end
end
end
--right text
if ( subAttribute == 1 ) then --damage done
dps = _math_floor ( dps )
local formatedDamage = SelectedToKFunction ( _ , damageTotal )
local formatedDps = SelectedToKFunction ( _ , dps )
thisLine.ps_text = formatedDps
if ( not bars_show_data [ 1 ] ) then
formatedDamage = " "
end
if ( not bars_show_data [ 2 ] ) then
formatedDps = " "
end
if ( not bars_show_data [ 3 ] ) then
percentString = " "
else
percentString = percentString .. " % "
end
local rightText = formatedDamage .. bars_brackets [ 1 ] .. formatedDps .. bars_separator .. percentString .. bars_brackets [ 2 ]
if ( UsingCustomRightText ) then
thisLine.lineText4 : SetText ( stringReplace ( instanceObject.row_info . textR_custom_text , formatedDamage , formatedDps , percentString , self , instanceObject.showing , instanceObject , rightText ) )
else
if ( instanceObject.use_multi_fontstrings ) then
instanceObject : SetInLineTexts ( thisLine , formatedDamage , formatedDps , percentString )
else
thisLine.lineText4 : SetText ( rightText )
end
end
if ( Details.CurrentDps . CanSortByRealTimeDps ( ) ) then
percentNumber = _math_floor ( ( self.last_dps_realtime / instanceObject.top ) * 100 )
else
percentNumber = _math_floor ( ( damageTotal / instanceObject.top ) * 100 )
end
elseif ( subAttribute == 2 ) then --dps
local raw_dps = dps
dps = _math_floor ( dps )
local formated_damage = SelectedToKFunction ( _ , damageTotal )
local formated_dps = SelectedToKFunction ( _ , dps )
thisLine.ps_text = formated_dps
local diff_from_topdps
if ( rank > 1 ) then
diff_from_topdps = instanceObject.player_top_dps - raw_dps
end
local rightText
if ( diff_from_topdps ) then
local threshold = diff_from_topdps / instanceObject.player_top_dps_threshold * 100
if ( threshold < 100 ) then
threshold = abs ( threshold - 100 )
else
threshold = 5
end
local rr , gg , bb = Details : percent_color ( threshold )
rr , gg , bb = Details : hex ( _math_floor ( rr * 255 ) ) , Details : hex ( _math_floor ( gg * 255 ) ) , " 28 "
local color_percent = " " .. rr .. gg .. bb .. " "
if ( not bars_show_data [ 1 ] ) then
formated_dps = " "
end
if ( not bars_show_data [ 2 ] ) then
color_percent = " "
else
color_percent = bars_brackets [ 1 ] .. " |cFFFF4444-|r|cFF " .. color_percent .. SelectedToKFunction ( _ , _math_floor ( diff_from_topdps ) ) .. " |r " .. bars_brackets [ 2 ]
end
rightText = formated_dps .. color_percent
else
local icon = " |TInterface \\ GROUPFRAME \\ UI-Group-LeaderIcon:14:14:0:0:16:16:0:16:0:16|t "
if ( not bars_show_data [ 1 ] ) then
formated_dps = " "
end
if ( not bars_show_data [ 2 ] ) then
icon = " "
end
rightText = formated_dps .. icon
end
if ( UsingCustomRightText ) then
thisLine.lineText4 : SetText ( stringReplace ( instanceObject.row_info . textR_custom_text , formated_dps , formated_damage , percentString , self , instanceObject.showing , instanceObject , rightText ) )
else
if ( instanceObject.use_multi_fontstrings ) then
--instance:SetInLineTexts(thisLine, formated_damage, formated_dps, porcentagem)
instanceObject : SetInLineTexts ( thisLine , rightText )
else
thisLine.lineText4 : SetText ( rightText )
end
end
percentNumber = _math_floor ( ( dps / instanceObject.top ) * 100 )
elseif ( subAttribute == 3 ) then --damage taken
local dtps = self.damage_taken / combatTime
local formated_damage_taken = SelectedToKFunction ( _ , self.damage_taken )
local formated_dtps = SelectedToKFunction ( _ , dtps )
thisLine.ps_text = formated_dtps
if ( not bars_show_data [ 1 ] ) then
formated_damage_taken = " "
end
if ( not bars_show_data [ 2 ] ) then
formated_dtps = " "
end
if ( not bars_show_data [ 3 ] ) then
percentString = " "
else
percentString = percentString .. " % "
end
local rightText = formated_damage_taken .. bars_brackets [ 1 ] .. formated_dtps .. bars_separator .. percentString .. bars_brackets [ 2 ]
if ( UsingCustomRightText ) then
thisLine.lineText4 : SetText ( stringReplace ( instanceObject.row_info . textR_custom_text , formated_damage_taken , formated_dtps , percentString , self , instanceObject.showing , instanceObject , rightText ) )
else
if ( instanceObject.use_multi_fontstrings ) then
instanceObject : SetInLineTexts ( thisLine , formated_damage_taken , formated_dtps , percentString )
else
thisLine.lineText4 : SetText ( rightText )
end
end
percentNumber = _math_floor ( ( self.damage_taken / instanceObject.top ) * 100 )
elseif ( subAttribute == 4 ) then --friendly fire
local formated_friendly_fire = SelectedToKFunction ( _ , self.friendlyfire_total )
if ( not bars_show_data [ 1 ] ) then
formated_friendly_fire = " "
end
if ( not bars_show_data [ 3 ] ) then
percentString = " "
else
percentString = percentString .. " % "
end
local rightText = formated_friendly_fire .. bars_brackets [ 1 ] .. percentString .. bars_brackets [ 2 ]
if ( UsingCustomRightText ) then
thisLine.lineText4 : SetText ( stringReplace ( instanceObject.row_info . textR_custom_text , formated_friendly_fire , " " , percentString , self , instanceObject.showing , instanceObject , rightText ) )
else
if ( instanceObject.use_multi_fontstrings ) then
instanceObject : SetInLineTexts ( thisLine , " " , formated_friendly_fire , percentString )
else
thisLine.lineText4 : SetText ( rightText )
end
end
percentNumber = _math_floor ( ( self.friendlyfire_total / instanceObject.top ) * 100 )
elseif ( subAttribute == 6 ) then --enemies
local dtps = self.damage_taken / combatTime
local formatedDamageTaken = SelectedToKFunction ( _ , self.damage_taken )
local formatedDtps = SelectedToKFunction ( _ , dtps )
thisLine.ps_text = formatedDtps
if ( not bars_show_data [ 1 ] ) then
formatedDamageTaken = " "
end
if ( not bars_show_data [ 2 ] ) then
formatedDtps = " "
end
if ( not bars_show_data [ 3 ] ) then
percentString = " "
else
percentString = percentString .. " % "
end
local rightText = formatedDamageTaken .. bars_brackets [ 1 ] .. formatedDtps .. bars_separator .. percentString .. bars_brackets [ 2 ]
if ( UsingCustomRightText ) then
thisLine.lineText4 : SetText ( stringReplace ( instanceObject.row_info . textR_custom_text , formatedDamageTaken , formatedDtps , percentString , self , instanceObject.showing , instanceObject , rightText ) )
else
if ( instanceObject.use_multi_fontstrings ) then
instanceObject : SetInLineTexts ( thisLine , formatedDamageTaken , formatedDtps , percentString )
else
thisLine.lineText4 : SetText ( rightText )
end
end
percentNumber = _math_floor ( ( self.damage_taken / instanceObject.top ) * 100 )
end
--need tooltip update?
if ( thisLine.mouse_over and not instanceObject.baseframe . isMoving ) then
gump : UpdateTooltip ( whichRowLine , thisLine , instanceObject )
end
if ( self.need_refresh ) then
self.need_refresh = false
bForceRefresh = true
end
actor_class_color_r , actor_class_color_g , actor_class_color_b = self : GetBarColor ( )
return self : RefreshLineValue ( thisLine , instanceObject , previousData , bForceRefresh , percentNumber , bUseAnimations , total , instanceObject.top )
end
---show an extra statusbar on the line, after the main statusbar
---@param thisLine table
---@param amount valueamount
---@param extraAmount valueamount
---@param totalAmount valueamount
---@param topAmount valueamount
---@param instanceObject instance
---@param onEnterFunc function?
---@param onLeaveFunc function?
function Details : ShowExtraStatusbar ( thisLine , amount , extraAmount , totalAmount , topAmount , instanceObject , onEnterFunc , onLeaveFunc )
local extraStatusbar = thisLine.extraStatusbar
if ( extraAmount and extraAmount > 0 and instanceObject.atributo == 1 and instanceObject.sub_atributo == 1 ) then
local initialOffset = 0
local icon_offset_x , icon_offset_y = unpack ( instanceObject.row_info . icon_offset )
local bIsUsingBarStartAfterIcon = instanceObject.row_info . start_after_icon
if ( bIsUsingBarStartAfterIcon ) then
initialOffset = thisLine.icone_classe : GetWidth ( ) + icon_offset_x
end
local statusBarWidth = thisLine.statusbar : GetWidth ( )
local percent = amount / topAmount
local fillTheGapWidth = percent * 4
local startExtraStatusbarOffset = percent * statusBarWidth
local extraStatusbarWidth = statusBarWidth * ( extraAmount / topAmount )
extraStatusbar : ClearAllPoints ( )
extraStatusbar : SetHeight ( thisLine : GetHeight ( ) )
if ( bIsUsingBarStartAfterIcon ) then
extraStatusbar : SetPoint ( " topleft " , thisLine.icone_classe , " topright " , startExtraStatusbarOffset - fillTheGapWidth , 0 )
else
extraStatusbar : SetPoint ( " topleft " , thisLine , " topleft " , ( statusBarWidth * percent ) - fillTheGapWidth , 0 )
end
extraStatusbar : SetWidth ( extraStatusbarWidth )
extraStatusbar : SetFrameLevel ( thisLine : GetFrameLevel ( ) + 1 )
extraStatusbar.OnEnterCallback = onEnterFunc
extraStatusbar.OnLeaveCallback = onLeaveFunc
if ( Details.combat_log . evoker_calc_damage ) then
extraStatusbar : SetAlpha ( 0.8 )
extraStatusbar.defaultAlpha = 0.8
else
extraStatusbar : SetAlpha ( 0.1 )
extraStatusbar.defaultAlpha = 0.1
end
extraStatusbar : Show ( )
else
extraStatusbar : Hide ( )
end
end
--when the script detect the extrastatusbar need to be show, it will call this function
local handleShowExtraStatusbar = function ( thisLine , self , instance , previousData , isForceRefresh , percent , bUseAnimations , totalValue , topValue )
if ( self.spec == 1473 and self.augmentedSpellsContainer ) then
--prepare the extra bar to show the damage prediction to augmented evoker
local onEnterFunc = damageClass.PredictedAugSpellsOnEnter
local onLeaveFunc = damageClass.PredictedAugSpellsOnLeave
Details : ShowExtraStatusbar ( thisLine , self.total , self.total_extra , totalValue , topValue , instance , onEnterFunc , onLeaveFunc )
thisLine.extraStatusbar . augmentedSpellsContainer = self.augmentedSpellsContainer
thisLine.extraStatusbar . actorName = self : Name ( )
---@cast instance instance
thisLine.extraStatusbar . instanceId = instance : GetId ( )
else
Details : ShowExtraStatusbar ( thisLine , self.total , self.total_extra , totalValue , topValue , instance )
end
end
function Details : RefreshLineValue ( thisLine , instance , previousData , isForceRefresh , percent , bUseAnimations , totalValue , topValue ) --[[exported]]
thisLine.extraStatusbar : Hide ( )
if ( thisLine.colocacao == 1 ) then
thisLine.animacao_ignorar = true
if ( not previousData or previousData ~= thisLine.minha_tabela or isForceRefresh ) then
thisLine : SetValue ( 100 )
if ( thisLine.hidden or thisLine.fading_in or thisLine.faded ) then
Details.FadeHandler . Fader ( thisLine , " out " )
end
return self : RefreshBarra ( thisLine , instance )
else
return
end
else
if ( thisLine.hidden or thisLine.fading_in or thisLine.faded ) then
--setando o valor mesmo com anima��es pq o barra esta hidada com o value do �ltimo actor que ela mostrou
if ( bUseAnimations and self.spec ~= 1473 ) then
thisLine.animacao_fim = percent
thisLine : SetValue ( percent )
else
thisLine : SetValue ( percent )
thisLine.animacao_ignorar = true
end
Details.FadeHandler . Fader ( thisLine , " out " )
if ( self.total_extra and self.total_extra > 0 ) then
handleShowExtraStatusbar ( thisLine , self , instance , previousData , isForceRefresh , percent , bUseAnimations , totalValue , topValue )
end
return self : RefreshBarra ( thisLine , instance )
else
--agora esta comparando se a tabela da barra � diferente da tabela na atualiza��o anterior
if ( not previousData or previousData ~= thisLine.minha_tabela or isForceRefresh ) then --aqui diz se a barra do jogador mudou de posi��o ou se ela apenas ser� atualizada
if ( bUseAnimations and self.spec ~= 1473 ) then
thisLine.animacao_fim = percent
else
thisLine : SetValue ( percent )
thisLine.animacao_ignorar = true
end
thisLine.last_value = percent --reseta o ultimo valor da barra
if ( self.total_extra and self.total_extra > 0 ) then
handleShowExtraStatusbar ( thisLine , self , instance , previousData , isForceRefresh , percent , bUseAnimations , totalValue , topValue )
end
return self : RefreshBarra ( thisLine , instance )
elseif ( percent ~= thisLine.last_value ) then --continua mostrando a mesma tabela ent�o compara a porcentagem
--apenas atualizar
if ( bUseAnimations and self.spec ~= 1473 ) then
thisLine.animacao_fim = percent
else
thisLine : SetValue ( percent )
end
thisLine.last_value = percent
if ( self.total_extra and self.total_extra > 0 ) then
Details : ShowExtraStatusbar ( thisLine , self.total , self.total_extra , totalValue , topValue , instance )
end
return self : RefreshBarra ( thisLine , instance )
else
if ( self.total_extra and self.total_extra > 0 ) then
handleShowExtraStatusbar ( thisLine , self , instance , previousData , isForceRefresh , percent , bUseAnimations , totalValue , topValue )
end
end
end
end
end
local setLineTextSize = function ( line , instance )
if ( instance.bars_inverted ) then
line.lineText4 : SetSize ( instance.cached_bar_width - line.lineText1 : GetStringWidth ( ) - 20 , 15 )
else
line.lineText1 : SetSize ( instance.cached_bar_width - line.lineText4 : GetStringWidth ( ) - 20 , 15 )
end
end
function Details : SetBarLeftText ( bar , instance , enemy , arenaEnemy , arenaAlly , usingCustomLeftText ) --[[exported]]
local barNumber = " "
if ( instance.row_info . textL_show_number ) then
barNumber = bar.colocacao .. " . "
end
--translate cyrillic alphabet to western alphabet by Vardex (https://github.com/Vardex May 22, 2019)
if ( instance.row_info . textL_translit_text ) then
self.displayName = Translit : Transliterate ( self.displayName , " ! " )
end
if ( enemy ) then
if ( arenaEnemy ) then
if ( instance.row_info . show_arena_role_icon ) then
--show arena role icon
local sizeOffset = instance.row_info . arena_role_icon_size_offset
local leftText = barNumber .. " |TInterface \\ LFGFRAME \\ UI-LFG-ICON-ROLES: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:256: " .. Details.role_texcoord [ self.role or " NONE " ] .. " |t " .. self.displayName
if ( usingCustomLeftText ) then
bar.lineText1 : SetText ( stringReplace ( instance.row_info . textL_custom_text , bar.colocacao , self.displayName , " |TInterface \\ LFGFRAME \\ UI-LFG-ICON-ROLES: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:256: " .. Details.role_texcoord [ self.role or " NONE " ] .. " |t " , self , instance.showing , instance , leftText ) )
else
bar.lineText1 : SetText ( leftText )
end
else
--don't show arena role icon
local leftText = barNumber .. self.displayName
if ( usingCustomLeftText ) then
bar.lineText1 : SetText ( stringReplace ( instance.row_info . textL_custom_text , bar.colocacao , self.displayName , " " , self , instance.showing , instance , leftText ) )
else
bar.lineText1 : SetText ( leftText )
end
end
else
if ( instance.row_info . show_faction_icon ) then
local sizeOffset = instance.row_info . faction_icon_size_offset
if ( Details.faction_against == " Horde " ) then
local leftText = barNumber .. " |TInterface \\ AddOns \\ Details \\ images \\ icones_barra: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:32:0:32:0:32|t " .. self.displayName
if ( usingCustomLeftText ) then
bar.lineText1 : SetText ( stringReplace ( instance.row_info . textL_custom_text , bar.colocacao , self.displayName , " |TInterface \\ AddOns \\ Details \\ images \\ icones_barra: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:32:0:32:0:32|t " , self , instance.showing , instance , leftText ) )
else
bar.lineText1 : SetText ( leftText ) --seta o texto da esqueda -- HORDA
end
else --alliance
local leftText = barNumber .. " |TInterface \\ AddOns \\ Details \\ images \\ icones_barra: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:32:32:64:0:32|t " .. self.displayName
if ( usingCustomLeftText ) then
bar.lineText1 : SetText ( stringReplace ( instance.row_info . textL_custom_text , bar.colocacao , self.displayName , " |TInterface \\ AddOns \\ Details \\ images \\ icones_barra: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:32:32:64:0:32|t " , self , instance.showing , instance , leftText ) )
else
bar.lineText1 : SetText ( leftText ) --seta o texto da esqueda -- ALLY
end
end
else
--don't show faction icon
local leftText = barNumber .. self.displayName
if ( usingCustomLeftText ) then
bar.lineText1 : SetText ( stringReplace ( instance.row_info . textL_custom_text , bar.colocacao , self.displayName , " " , self , instance.showing , instance , leftText ) )
else
bar.lineText1 : SetText ( leftText )
end
end
end
else
if ( arenaAlly and instance.row_info . show_arena_role_icon ) then
local sizeOffset = instance.row_info . arena_role_icon_size_offset
local leftText = barNumber .. " |TInterface \\ LFGFRAME \\ UI-LFG-ICON-ROLES: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:256: " .. Details.role_texcoord [ self.role or " NONE " ] .. " |t " .. self.displayName
if ( usingCustomLeftText ) then
bar.lineText1 : SetText ( stringReplace ( instance.row_info . textL_custom_text , bar.colocacao , self.displayName , " |TInterface \\ LFGFRAME \\ UI-LFG-ICON-ROLES: " .. ( instance.row_info . height + sizeOffset ) .. " : " .. ( instance.row_info . height + sizeOffset ) .. " :0:0:256:256: " .. Details.role_texcoord [ self.role or " NONE " ] .. " |t " , self , instance.showing , instance , leftText ) )
else
bar.lineText1 : SetText ( leftText )
end
else
local leftText = barNumber .. self.displayName
if ( usingCustomLeftText ) then
bar.lineText1 : SetText ( stringReplace ( instance.row_info . textL_custom_text , bar.colocacao , self.displayName , " " , self , instance.showing , instance , leftText ) )
else
bar.lineText1 : SetText ( leftText ) --seta o texto da esqueda
end
end
end
setLineTextSize ( bar , instance )
end
function Details : SetBarColors ( bar , instance , r , g , b , a ) --[[exported]] --~colors
a = a or 1
if ( instance.row_info . texture_class_colors ) then
if ( self.classe == " UNGROUPPLAYER " ) then
if ( self.spec ) then
local specId , specName , specDescription , specIcon , specRole , specClass = DetailsFramework.GetSpecializationInfoByID ( self.spec )
if ( specClass ) then
self.classe = specClass
end
end
end
bar.textura : SetVertexColor ( r , g , b , a )
end
if ( instance.row_info . texture_background_class_color ) then
bar.background : SetVertexColor ( r , g , b , a )
end
if ( instance.row_info . textL_class_colors ) then
bar.lineText1 : SetTextColor ( r , g , b , a )
end
if ( instance.row_info . textR_class_colors ) then
bar.lineText2 : SetTextColor ( r , g , b , a )
bar.lineText3 : SetTextColor ( r , g , b , a )
bar.lineText4 : SetTextColor ( r , g , b , a )
end
if ( instance.row_info . backdrop.use_class_colors ) then
--get the alpha from the border color
local alpha = instance.row_info . backdrop.color [ 4 ]
bar.lineBorder : SetVertexColor ( r , g , b , alpha )
end
end
---set the icon of the actor spec, class, pet, enemy, custom icom, spellicon, etc.
---@param self actor
---@param texture texture
---@param instance instance
---@param class string
function Details : SetClassIcon ( texture , instance , class ) --[[exported]] --~icons
local customIcon
if ( Details.immersion_unit_special_icons ) then
customIcon = Details.Immersion . GetIcon ( self.aID )
end
--set the size offset of the icon
local iconSizeOffset = instance.row_info . icon_size_offset
local iconSize = instance.row_info . height
local newIconSize = iconSize + iconSizeOffset
texture : SetSize ( newIconSize , newIconSize )
if ( customIcon ) then
texture : SetTexture ( customIcon [ 1 ] )
texture : SetTexCoord ( unpack ( customIcon [ 2 ] ) )
texture : SetVertexColor ( 1 , 1 , 1 )
elseif ( self.spellicon ) then
texture : SetTexture ( self.spellicon )
texture : SetTexCoord ( 0.078125 , 0.921875 , 0.078125 , 0.921875 )
elseif ( class == " UNKNOW " ) then
texture : SetTexture ( [[Interface\AddOns\Details\images\classes_plus]] )
texture : SetTexCoord ( 0.50390625 , 0.62890625 , 0 , 0.125 )
texture : SetVertexColor ( 1 , 1 , 1 )
elseif ( class == " UNGROUPPLAYER " ) then
if ( self.spec ) then
if ( instance and instance.row_info . use_spec_icons ) then
if ( self.spec and Details.class_specs_coords [ self.spec ] ) then
texture : SetTexture ( instance.row_info . spec_file )
texture : SetTexCoord ( unpack ( Details.class_specs_coords [ self.spec ] ) )
texture : SetVertexColor ( 1 , 1 , 1 )
return
end
end
end
local localizedClass , englishClass
if ( self.serial ~= " " ) then
localizedClass , englishClass = GetPlayerInfoByGUID ( self.serial )
end
if ( englishClass ) then
texture : SetTexture ( instance.row_info . icon_file or [[Interface\AddOns\Details\images\classes_small]] )
texture : SetTexCoord ( unpack ( Details.class_coords [ englishClass ] ) )
texture : SetVertexColor ( 1 , 1 , 1 )
return
end
if ( self.enemy ) then
if ( Details.faction_against == " Horde " ) then
texture : SetTexture ( " Interface \\ ICONS \\ Achievement_Character_Troll_Male " )
texture : SetTexCoord ( 0.05 , 0.95 , 0.05 , 0.95 )
else
texture : SetTexture ( " Interface \\ ICONS \\ Achievement_Character_Nightelf_Female " )
texture : SetTexCoord ( 0.05 , 0.95 , 0.05 , 0.95 )
end
else
if ( Details.faction_against == " Horde " ) then
texture : SetTexture ( " Interface \\ ICONS \\ Achievement_Character_Nightelf_Female " )
texture : SetTexCoord ( 0.05 , 0.95 , 0.05 , 0.95 )
else
texture : SetTexture ( " Interface \\ ICONS \\ Achievement_Character_Troll_Male " )
texture : SetTexCoord ( 0.05 , 0.95 , 0.05 , 0.95 )
end
end
texture : SetVertexColor ( 1 , 1 , 1 )
elseif ( class == " PET " ) then
texture : SetTexture ( instance and instance.row_info . icon_file or [[Interface\AddOns\Details\images\classes_small]] )
texture : SetTexCoord ( 0.25 , 0.49609375 , 0.75 , 1 )
actor_class_color_r , actor_class_color_g , actor_class_color_b = DetailsFramework : ParseColors ( actor_class_color_r , actor_class_color_g , actor_class_color_b )
texture : SetVertexColor ( actor_class_color_r , actor_class_color_g , actor_class_color_b )
else
if ( instance and instance.row_info . use_spec_icons ) then
if ( self.spec and Details.class_specs_coords [ self.spec ] ) then
texture : SetTexture ( instance.row_info . spec_file )
texture : SetTexCoord ( unpack ( Details.class_specs_coords [ self.spec ] ) )
texture : SetVertexColor ( 1 , 1 , 1 )
else
texture : SetTexture ( instance.row_info . icon_file or [[Interface\AddOns\Details\images\classes_small]] )
texture : SetTexCoord ( unpack ( Details.class_coords [ class ] ) )
texture : SetVertexColor ( 1 , 1 , 1 )
end
else
texture : SetTexture ( instance and instance.row_info . icon_file or [[Interface\AddOns\Details\images\classes_small]] )
texture : SetTexCoord ( unpack ( Details.class_coords [ class ] ) )
texture : SetVertexColor ( 1 , 1 , 1 )
end
end
end
function Details : RefreshBarra ( thisLine , instance , fromResize ) --[[exported]]
local class , enemy , arenaEnemy , arenaAlly = self.classe , self.enemy , self.arena_enemy , self.arena_ally
if ( not class ) then
Details : Msg ( " Warning, actor without a class: " , self.nome , self.flag_original , self.serial )
self.classe = " UNKNOW "
class = " UNKNOW "
end
if ( fromResize ) then
actor_class_color_r , actor_class_color_g , actor_class_color_b = self : GetBarColor ( )
end
--icon
self : SetClassIcon ( thisLine.icone_classe , instance , class )
if ( thisLine.mouse_over ) then
local classIcon = thisLine : GetClassIcon ( )
thisLine.iconHighlight : SetTexture ( classIcon : GetTexture ( ) )
thisLine.iconHighlight : SetTexCoord ( classIcon : GetTexCoord ( ) )
thisLine.iconHighlight : SetVertexColor ( classIcon : GetVertexColor ( ) )
end
--texture color
self : SetBarColors ( thisLine , instance , actor_class_color_r , actor_class_color_g , actor_class_color_b )
--left text
self : SetBarLeftText ( thisLine , instance , enemy , arenaEnemy , arenaAlly , UsingCustomLeftText )
end
---comment
---@param self table extraStatusbar frame
function damageClass . PredictedAugSpellsOnEnter ( self )
if ( Details.show_aug_predicted_spell_damage ) then
---@type spellcontainer
local spellContainer = self.augmentedSpellsContainer
GameCooltip : Preset ( 2 )
---@type instance
local instanceObject = Details : GetInstance ( self.instanceId )
---@type combat
local combatObject = instanceObject : GetCombat ( )
for spellId , spellTable in spellContainer : ListSpells ( ) do
local spellName , _ , spellTexture = GetSpellInfo ( spellId )
if ( spellName ) then
GameCooltip : AddLine ( spellName , Details : Format ( spellTable.total ) )
GameCooltip : AddIcon ( spellTexture , 1 , 1 , 14 , 14 )
local spellsAugmented = { }
--the damage sources are added into the targets table for recycling
---@type table<actorname, valueamount>
local sources = spellTable.targets
for sourceName , sourceAmount in pairs ( sources ) do
spellsAugmented [ # spellsAugmented + 1 ] = { sourceName , sourceAmount }
end
table.sort ( spellsAugmented , Details.Sort2 )
for i = 1 , math.min ( # spellsAugmented , 5 ) do
local sourceName , sourceAmount = unpack ( spellsAugmented [ i ] )
GameCooltip : AddLine ( sourceName , Details : Format ( sourceAmount ) , 1 , " yellow " , " yellow " , 10 )
local actorObject = combatObject : GetActor ( 1 , sourceName )
if ( actorObject ) then
local actorIcon = Details : GetActorIcon ( actorObject )
if ( actorIcon ) then
GameCooltip : AddIcon ( actorIcon.texture , 1 , 1 , 14 , 14 , actorIcon.coords . left , actorIcon.coords . right , actorIcon.coords . top , actorIcon.coords . bottom )
else
GameCooltip : AddIcon ( [[Interface\COMMON\Indicator-Gray]] , 1 , 1 , 14 , 14 )
end
end
end
end
end
else
---@type instance
local instanceObject = Details : GetInstance ( self.instanceId )
---@type combat
local combatObject = instanceObject : GetCombat ( )
local combatTime = combatObject : GetCombatTime ( )
---@type actorname
local actorName = self.actorName
---@type actorcontainer
local utilityContainer = combatObject : GetContainer ( DETAILS_ATTRIBUTE_MISC )
local buffUptimeTable = { }
--for each actor in the container
for _ , actorObject in utilityContainer : ListActors ( ) do
---@type spellcontainer
local receivedBuffs = actorObject.received_buffs_spells
if ( receivedBuffs and actorObject : IsPlayer ( ) and actorObject : IsGroupPlayer ( ) ) then
for sourceNameSpellId , spellTable in receivedBuffs : ListSpells ( ) do
local sourceName , spellId = strsplit ( " @ " , sourceNameSpellId )
if ( sourceName == actorName ) then
spellId = tonumber ( spellId )
local spellName , _ , spellIcon = Details.GetSpellInfo ( spellId )
if ( spellName ) then
sourceName = detailsFramework : RemoveRealmName ( sourceName )
local targetName = actorObject : Name ( )
targetName = detailsFramework : RemoveRealmName ( targetName )
local uptime = spellTable.uptime or 0
buffUptimeTable [ # buffUptimeTable + 1 ] = { spellId , uptime , sourceName , targetName , actorObject : Class ( ) }
end
end
end
end
end
table.sort ( buffUptimeTable , Details.Sort2 )
Details : FormatCooltipForSpells ( )
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_SPELLS " ] , headerColor , # buffUptimeTable , Details.tooltip_spell_icon . file , unpack ( Details.tooltip_spell_icon . coords ) )
Details : AddTooltipHeaderStatusbar ( .1 , .1 , .1 , 0.834 )
local iconSize = 22
local iconBorderInfo = Details.tooltip . icon_border_texcoord
local combatTimeMinutes , combatTimeSeconds = math.floor ( combatTime / 60 ) , math.floor ( combatTime % 60 )
GameCooltip : AddLine ( " Combat Time " , combatTimeMinutes .. " m " .. combatTimeSeconds .. " s " .. " ( " .. format ( " %.1f " , 100 ) .. " %) " )
GameCooltip : AddIcon ( [[Interface\TARGETINGFRAME\UnitFrameIcons]] , nil , nil , iconSize , iconSize , iconBorderInfo.L , iconBorderInfo.R , iconBorderInfo.T , iconBorderInfo.B )
Details : AddTooltipBackgroundStatusbar ( false , 100 , true , " green " )
if ( # buffUptimeTable > 0 ) then
for i = 1 , min ( 30 , # buffUptimeTable ) do
local uptimeTable = buffUptimeTable [ i ]
local spellId = uptimeTable [ 1 ]
local uptime = uptimeTable [ 2 ]
local sourceName = uptimeTable [ 3 ]
local targetName = uptimeTable [ 4 ]
local targetClass = uptimeTable [ 5 ]
local uptimePercent = uptime / combatTime * 100
if ( uptime > 0 and uptimePercent < 99.5 ) then
local spellName , _ , spellIcon = _GetSpellInfo ( spellId )
if ( sourceName ) then
targetName = detailsFramework : AddClassColorToText ( targetName , targetClass )
targetName = detailsFramework : AddClassIconToText ( targetName , targetName , targetClass )
spellName = spellName .. " [ " .. targetName .. " ] "
end
if ( uptime <= combatTime ) then
local minutes , seconds = math.floor ( uptime / 60 ) , math.floor ( uptime % 60 )
if ( minutes > 0 ) then
GameCooltip : AddLine ( spellName , minutes .. " m " .. seconds .. " s " .. " ( " .. format ( " %.1f " , uptimePercent ) .. " %) " )
Details : AddTooltipBackgroundStatusbar ( false , uptimePercent , true , sourceName and " green " )
else
GameCooltip : AddLine ( spellName , seconds .. " s " .. " ( " .. format ( " %.1f " , uptimePercent ) .. " %) " )
Details : AddTooltipBackgroundStatusbar ( false , uptimePercent , true , sourceName and " green " )
end
GameCooltip : AddIcon ( spellIcon , nil , nil , iconSize , iconSize , iconBorderInfo.L , iconBorderInfo.R , iconBorderInfo.T , iconBorderInfo.B )
end
end
end
else
GameCooltip : AddLine ( Loc [ " STRING_NO_SPELL " ] )
end
end
GameCooltip : AddLine ( " feature under test, can't disable atm " )
GameCooltip : AddIcon ( [[Interface\BUTTONS\UI-GROUPLOOT-PASS-DOWN]] , nil , nil , 16 , 16 )
--GameCooltip:SetOption("LeftBorderSize", -5)
--GameCooltip:SetOption("RightBorderSize", 5)
--GameCooltip:SetOption("RightTextMargin", 0)
GameCooltip : SetOption ( " VerticalOffset " , 0 )
--GameCooltip:SetOption("AlignAsBlizzTooltip", true)
GameCooltip : SetOption ( " AlignAsBlizzTooltipFrameHeightOffset " , 0 )
GameCooltip : SetOption ( " LineHeightSizeOffset " , 0 )
GameCooltip : SetOption ( " VerticalPadding " , 0 )
GameCooltip : ShowCooltip ( self , " tooltip " )
end
function damageClass . PredictedAugSpellsOnLeave ( self )
GameCooltip : Hide ( )
--extraStatusbar.defaultAlpha
end
--------------------------------------------- // TOOLTIPS // ---------------------------------------------
---------TOOLTIPS BIFURCA��O
-- ~tooltip
function damageClass : ToolTip ( instance , numero , barra , keydown )
--seria possivel aqui colocar o icone da classe dele?
if ( instance.atributo == 5 ) then --custom
return self : TooltipForCustom ( barra )
else
if ( instance.sub_atributo == 1 or instance.sub_atributo == 2 ) then --damage done or Dps or enemy
return self : ToolTip_DamageDone ( instance , numero , barra , keydown )
elseif ( instance.sub_atributo == 3 ) then --damage taken
return self : ToolTip_DamageTaken ( instance , numero , barra , keydown )
elseif ( instance.sub_atributo == 6 ) then --enemies
return self : ToolTip_Enemies ( instance , numero , barra , keydown )
elseif ( instance.sub_atributo == 4 ) then --friendly fire
return self : ToolTip_FriendlyFire ( instance , numero , barra , keydown )
end
end
end
--tooltip locals
local r , g , b
local barAlha = .6
---------DAMAGE DONE & DPS
function damageClass : ToolTip_DamageDone ( instancia , numero , barra , keydown )
local owner = self.owner
if ( owner and owner.classe ) then
r , g , b = unpack ( Details.class_colors [ owner.classe ] )
else
if ( not Details.class_colors [ self.classe ] ) then
return print ( " Details!: error class not found: " , self.classe , " for " , self.nome )
end
r , g , b = unpack ( Details.class_colors [ self.classe ] )
end
local combatObject = instancia : GetShowingCombat ( )
--habilidades
local icon_size = Details.tooltip . icon_size
local icon_border = Details.tooltip . icon_border_texcoord
do
--TOP HABILIDADES
--get variables
--local ActorDamage = self.total_without_pet --mostrando os pets no tooltip
local ActorDamage = self.total
local ActorDamageWithPet = self.total
if ( ActorDamage == 0 ) then
ActorDamage = 0.00000001
end
local ActorSkillsContainer = self.spells . _ActorTable
local ActorSkillsSortTable = { }
local reflectionSpells = { }
--get time type
local meu_tempo
if ( Details.time_type == 1 or not self.grupo ) then
meu_tempo = self : Tempo ( )
elseif ( Details.time_type == 2 or Details.use_realtimedps ) then
meu_tempo = instancia.showing : GetCombatTime ( )
end
--add actor spells
for _spellid , _skill in pairs ( ActorSkillsContainer ) do
ActorSkillsSortTable [ # ActorSkillsSortTable + 1 ] = { _spellid , _skill.total , _skill.total / meu_tempo }
if ( _skill.isReflection ) then
reflectionSpells [ # reflectionSpells + 1 ] = _skill
end
end
--add actor pets
for petIndex , petName in ipairs ( self : Pets ( ) ) do
local petActor = instancia.showing [ class_type ] : PegarCombatente ( nil , petName )
if ( petActor ) then
for _spellid , _skill in pairs ( petActor : GetActorSpells ( ) ) do
ActorSkillsSortTable [ # ActorSkillsSortTable + 1 ] = { _spellid , _skill.total , _skill.total / meu_tempo , petName : gsub ( ( " <.* " ) , " " ) }
end
end
end
--sort
table.sort ( ActorSkillsSortTable , Details.Sort2 )
--TOP INIMIGOS
--get variables
local ActorTargetsSortTable = { }
--add
for targetName , amount in pairs ( self.targets ) do
local targetActorObject = combatObject ( DETAILS_ATTRIBUTE_DAMAGE , targetName )
local npcId = targetActorObject and targetActorObject.aID
npcId = tonumber ( npcId or 0 )
ActorTargetsSortTable [ # ActorTargetsSortTable + 1 ] = { targetName , amount , npcId }
end
--sort
table.sort ( ActorTargetsSortTable , Details.Sort2 )
--tooltip stuff
local tooltip_max_abilities = Details.tooltip . tooltip_max_abilities
local is_maximized = false
if ( keydown == " shift " or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3 ) then
tooltip_max_abilities = 99
is_maximized = true
end
--MOSTRA HABILIDADES
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_SPELLS " ] , headerColor , # ActorSkillsSortTable , Details.tooltip_spell_icon . file , unpack ( Details.tooltip_spell_icon . coords ) )
if ( is_maximized ) then
--highlight shift key
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
Details : AddTooltipHeaderStatusbar ( r , g , b , 1 )
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay1 )
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
end
local topAbility = ActorSkillsSortTable [ 1 ] and ActorSkillsSortTable [ 1 ] [ 2 ] or 0.0001
if ( # ActorSkillsSortTable > 0 ) then
for i = 1 , _math_min ( tooltip_max_abilities , # ActorSkillsSortTable ) do
local SkillTable = ActorSkillsSortTable [ i ]
local spellID = SkillTable [ 1 ]
local totalDamage = SkillTable [ 2 ]
local totalDPS = SkillTable [ 3 ]
local petName = SkillTable [ 4 ]
local nome_magia , _ , icone_magia = _GetSpellInfo ( spellID )
if ( petName ) then
if ( not nome_magia ) then
spellID = spellID or " spellId? "
nome_magia = " |cffffaa00 " .. spellID .. " " .. " (|cFFCCBBBB " .. petName .. " |r) "
else
nome_magia = nome_magia .. " (|cFFCCBBBB " .. petName .. " |r) "
end
end
local percent = format ( " %.1f " , totalDamage / ActorDamage * 100 )
if ( string.len ( percent ) < 4 ) then
percent = percent .. " 0 "
end
if ( instancia.sub_atributo == 1 or instancia.sub_atributo == 6 ) then
GameCooltip : AddLine ( nome_magia , FormatTooltipNumber ( _ , totalDamage ) .. " ( " .. percent .. " %) " )
else
GameCooltip : AddLine ( nome_magia , FormatTooltipNumber ( _ , _math_floor ( totalDPS ) ) .. " ( " .. percent .. " %) " )
end
GameCooltip : AddIcon ( icone_magia , nil , nil , icon_size.W + 4 , icon_size.H + 4 , icon_border.L , icon_border.R , icon_border.T , icon_border.B )
Details : AddTooltipBackgroundStatusbar ( false , totalDamage / topAbility * 100 )
end
else
GameCooltip : AddLine ( Loc [ " STRING_NO_SPELL " ] )
end
--spell reflected
if ( # reflectionSpells > 0 ) then
--small blank space
Details : AddTooltipSpellHeaderText ( " " , headerColor , 1 , false , 0.1 , 0.9 , 0.1 , 0.9 , true ) --add a space
Details : AddTooltipSpellHeaderText ( " Spells Reflected " , headerColor , 1 , select ( 3 , _GetSpellInfo ( reflectionSpells [ 1 ] . id ) ) , 0.1 , 0.9 , 0.1 , 0.9 ) --localize-me
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
for i = 1 , # reflectionSpells do
local _spell = reflectionSpells [ i ]
local extraInfo = _spell.extra
for spellId , damageDone in pairs ( extraInfo ) do
local spellName , _ , spellIcon = _GetSpellInfo ( spellId )
if ( spellName ) then
GameCooltip : AddLine ( spellName , FormatTooltipNumber ( _ , damageDone ) .. " ( " .. _math_floor ( damageDone / self.total * 100 ) .. " %) " )
Details : AddTooltipBackgroundStatusbar ( false , damageDone / self.total * 100 )
GameCooltip : AddIcon ( spellIcon , 1 , 1 , icon_size.W , icon_size.H , 0.1 , 0.9 , 0.1 , 0.9 )
end
end
end
end
--targets (enemies)
local topEnemy = ActorTargetsSortTable [ 1 ] and ActorTargetsSortTable [ 1 ] [ 2 ] or 0
if ( instancia.sub_atributo == 1 or instancia.sub_atributo == 6 ) then
--small blank space
Details : AddTooltipSpellHeaderText ( " " , headerColor , 1 , false , 0.1 , 0.9 , 0.1 , 0.9 , true )
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_TARGETS " ] , headerColor , # ActorTargetsSortTable , [[Interface\Addons\Details\images\icons]] , 0 , 0.03125 , 0.126953125 , 0.15625 )
local max_targets = Details.tooltip . tooltip_max_targets
local is_maximized = false
if ( keydown == " ctrl " or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 4 ) then
max_targets = 99
is_maximized = true
end
if ( is_maximized ) then
--highlight
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_ctrl]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
Details : AddTooltipHeaderStatusbar ( r , g , b , 1 )
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_ctrl]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay1 )
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
end
for i = 1 , math.min ( max_targets , # ActorTargetsSortTable ) do
local enemyTable = ActorTargetsSortTable [ i ]
GameCooltip : AddLine ( enemyTable [ 1 ] , FormatTooltipNumber ( _ , enemyTable [ 2 ] ) .. " ( " .. format ( " %.1f " , enemyTable [ 2 ] / ActorDamageWithPet * 100 ) .. " %) " )
local portraitTexture -- = Details222.Textures.GetPortraitTextureForNpcID(enemyTable[3]) --disabled atm
if ( portraitTexture ) then
GameCooltip : AddIcon ( portraitTexture , 1 , 1 , icon_size.W , icon_size.H )
else
GameCooltip : AddIcon ( [[Interface\PetBattles\PetBattle-StatIcons]] , nil , nil , icon_size.W , icon_size.H , 0 , 0.5 , 0 , 0.5 , { .7 , .7 , .7 , 1 } , nil , true )
end
Details : AddTooltipBackgroundStatusbar ( false , enemyTable [ 2 ] / topEnemy * 100 )
end
end
end
--PETS
local instance = instancia
local combatObject = instance : GetShowingCombat ( )
local myPets = self.pets
if ( # myPets > 0 ) then --teve ajudantes
local petAmountWithSameName = { } --armazena a quantidade de pets iguais
local petDamageTable = { } --armazena o dano total de cada objeto
--small blank space
Details : AddTooltipSpellHeaderText ( " " , headerColor , 1 , false , 0.1 , 0.9 , 0.1 , 0.9 , true )
for index , petName in ipairs ( myPets ) do
if ( not petAmountWithSameName [ petName ] ) then
petAmountWithSameName [ petName ] = 1
local damageContainer = combatObject : GetContainer ( DETAILS_ATTRIBUTE_DAMAGE )
local petActorObject = damageContainer : GetActor ( petName )
if ( petActorObject ) then
local petDamageDone = petActorObject.total_without_pet
local petSpells = petActorObject : GetSpellList ( )
local petSpellsSorted = { }
--local timeInCombat = petActorObject:GetTimeInCombat(self)
local timeInCombat = 0
if ( Details.time_type == 1 or not self.grupo ) then
timeInCombat = petActorObject : Tempo ( )
elseif ( Details.time_type == 2 or Details.use_realtimedps ) then
timeInCombat = petActorObject : GetCombatTime ( )
end
petDamageTable [ # petDamageTable + 1 ] = { petName , petActorObject.total_without_pet , petActorObject.total_without_pet / timeInCombat }
for spellId , spellTable in pairs ( petSpells ) do
local spellName , rank , spellIcon = _GetSpellInfo ( spellId )
tinsert ( petSpellsSorted , { spellId , spellTable.total , spellTable.total / petDamageDone * 100 , { spellName , rank , spellIcon } } )
end
table.sort ( petSpellsSorted , Details.Sort2 )
local petTargets = { }
petSpells = petActorObject.targets
for targetName , spellDamageDone in pairs ( petSpells ) do
tinsert ( petTargets , { targetName , spellDamageDone , spellDamageDone / petDamageDone * 100 } )
end
table.sort ( petTargets , Details.Sort2 )
end
else
petAmountWithSameName [ petName ] = petAmountWithSameName [ petName ] + 1
end
end
local petHeaderAdded = false
table.sort ( petDamageTable , Details.Sort2 )
local ismaximized = false
if ( keydown == " alt " or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 5 ) then
ismaximized = true
end
local topPetDamageDone = petDamageTable [ 1 ] and petDamageTable [ 1 ] [ 2 ] or 0
for index , damageTable in ipairs ( petDamageTable ) do
if ( damageTable [ 2 ] > 0 and ( index <= Details.tooltip . tooltip_max_pets or ismaximized ) ) then
if ( not petHeaderAdded ) then
petHeaderAdded = true
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_PETS " ] , headerColor , # petDamageTable , [[Interface\COMMON\friendship-heart]] , 0.21875 , 0.78125 , 0.09375 , 0.6875 )
if ( ismaximized ) then
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_alt]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
Details : AddTooltipHeaderStatusbar ( r , g , b , 1 )
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_alt]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay1 )
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
end
end
local petName = damageTable [ 1 ]
local petDamageDone = damageTable [ 2 ]
local petDPS = damageTable [ 3 ]
petName = damageTable [ 1 ] : gsub ( ( " %s%<.* " ) , " " )
if ( instancia.sub_atributo == 1 ) then
GameCooltip : AddLine ( petName , FormatTooltipNumber ( _ , petDamageDone ) .. " ( " .. math.floor ( petDamageDone / self.total * 100 ) .. " %) " )
else
GameCooltip : AddLine ( petName , FormatTooltipNumber ( _ , math.floor ( petDPS ) ) .. " ( " .. math.floor ( petDamageDone / self.total * 100 ) .. " %) " )
end
Details : AddTooltipBackgroundStatusbar ( false , petDamageDone / topPetDamageDone * 100 )
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\classes_small_alpha]] , 1 , 1 , icon_size.W , icon_size.H , 0.25 / 2 , 0.49609375 / 2 , 0.75 / 2 , 1 / 2 )
end
end
end
--~Phases
local segment = instancia : GetShowingCombat ( )
if ( segment and self.grupo ) then
local bossInfo = segment : GetBossInfo ( )
local phasesInfo = segment : GetPhases ( )
if ( bossInfo and phasesInfo ) then
if ( # phasesInfo > 1 ) then
--small blank space
Details : AddTooltipSpellHeaderText ( " " , headerColor , 1 , false , 0.1 , 0.9 , 0.1 , 0.9 , true )
Details : AddTooltipSpellHeaderText ( " Damage by Encounter Phase " , headerColor , 1 , [[Interface\Garrison\orderhall-missions-mechanic8]] , 11 / 64 , 53 / 64 , 11 / 64 , 53 / 64 ) --localize-me
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
local playerPhases = { }
local totalDamage = 0
for phase , playersTable in pairs ( phasesInfo.damage ) do --each phase
local allPlayers = { } --all players for this phase
for playerName , amount in pairs ( playersTable ) do
tinsert ( allPlayers , { playerName , amount } )
totalDamage = totalDamage + amount
end
table.sort ( allPlayers , function ( a , b ) return a [ 2 ] > b [ 2 ] end )
local myRank = 0
for i = 1 , # allPlayers do
if ( allPlayers [ i ] [ 1 ] == self.nome ) then
myRank = i
break
end
end
tinsert ( playerPhases , { phase , playersTable [ self.nome ] or 0 , myRank , ( playersTable [ self.nome ] or 0 ) / totalDamage * 100 } )
end
table.sort ( playerPhases , function ( a , b ) return a [ 1 ] < b [ 1 ] end )
for i = 1 , # playerPhases do
--[1] Phase Number [2] Amount Done [3] Rank [4] Percent
GameCooltip : AddLine ( " |cFFF0F0F0Phase|r " .. playerPhases [ i ] [ 1 ] , FormatTooltipNumber ( _ , playerPhases [ i ] [ 2 ] ) .. " (|cFFFFFF00# " .. playerPhases [ i ] [ 3 ] .. " |r, " .. format ( " %.1f " , playerPhases [ i ] [ 4 ] ) .. " %) " )
GameCooltip : AddIcon ( [[Interface\Garrison\orderhall-missions-mechanic9]] , 1 , 1 , 14 , 14 , 11 / 64 , 53 / 64 , 11 / 64 , 53 / 64 )
Details : AddTooltipBackgroundStatusbar ( )
end
end
end
end
return true
end
local on_switch_show_enemies = function ( instance )
instance : TrocaTabela ( instance , true , 1 , 6 )
return true
end
local on_switch_show_frags = function ( instance )
instance : TrocaTabela ( instance , true , 1 , 5 )
return true
end
local ENEMIES_format_name = function ( player ) if ( player == 0 ) then return false end return Details : GetOnlyName ( player.nome ) end
local ENEMIES_format_amount = function ( amount ) if ( amount <= 0 ) then return false end return Details : ToK ( amount ) .. " ( " .. format ( " %.1f " , amount / tooltip_temp_table.damage_total * 100 ) .. " %) " end
function damageClass : ReportEnemyDamageTaken ( actor , instance , ShiftKeyDown , ControlKeyDown , fromFrags )
--can open the breakdown window now
--this function is deprecated
if ( ShiftKeyDown ) then
local inimigo = actor.nome
local custom_name = inimigo .. " - " .. Loc [ " STRING_CUSTOM_ENEMY_DT " ]
--procura se j� tem um custom:
for index , CustomObject in ipairs ( Details.custom ) do
if ( CustomObject : GetName ( ) == custom_name ) then
--fix for not saving funcs on logout
if ( not CustomObject.OnSwitchShow ) then
CustomObject.OnSwitchShow = fromFrags and on_switch_show_frags or on_switch_show_enemies
end
return instance : TrocaTabela ( instance.segmento , 5 , index )
end
end
--criar um custom para este actor.
local new_custom_object = {
name = custom_name ,
icon = [[Interface\ICONS\Pet_Type_Undead]] ,
attribute = " damagedone " ,
author = Details.playername ,
desc = inimigo .. " Damage Taken " ,
source = " [raid] " ,
target = inimigo ,
script = false ,
tooltip = false ,
temp = true ,
OnSwitchShow = fromFrags and on_switch_show_frags or on_switch_show_enemies ,
}
tinsert ( Details.custom , new_custom_object )
setmetatable ( new_custom_object , Details.atributo_custom )
new_custom_object.__index = Details.atributo_custom
return instance : TrocaTabela ( instance.segmento , 5 , # Details.custom )
end
if ( true ) then return end
local report_table = { " Details!: " .. actor.nome .. " - " .. Loc [ " STRING_ATTRIBUTE_DAMAGE_TAKEN " ] }
Details : FormatReportLines ( report_table , tooltip_temp_table , ENEMIES_format_name , ENEMIES_format_amount )
return Details : Reportar ( report_table , { _no_current = true , _no_inverse = true , _custom = true } )
end
local FRAGS_format_name = function ( player_name ) return Details : GetOnlyName ( player_name ) end
local FRAGS_format_amount = function ( amount ) return Details : ToK ( amount ) .. " ( " .. format ( " %.1f " , amount / frags_tooltip_table.damage_total * 100 ) .. " %) " end
function damageClass : ReportSingleFragsLine ( frag , instance , ShiftKeyDown , ControlKeyDown )
if ( not frags_tooltip_table ) then --some cases a friendly object is getting threat as neutral, example is Druid's Efflorescense
return
end
if ( ShiftKeyDown ) then
return damageClass : ReportEnemyDamageTaken ( frag , instance , ShiftKeyDown , ControlKeyDown , true )
end
local report_table = { " Details!: " .. frag [ 1 ] .. " - " .. Loc [ " STRING_ATTRIBUTE_DAMAGE_TAKEN " ] }
Details : FormatReportLines ( report_table , frags_tooltip_table , FRAGS_format_name , FRAGS_format_amount )
return Details : Reportar ( report_table , { _no_current = true , _no_inverse = true , _custom = true } )
end
function damageClass : ToolTip_Enemies ( instancia , numero , barra , keydown )
local owner = self.owner
if ( owner and owner.classe ) then
r , g , b = unpack ( Details.class_colors [ owner.classe ] )
else
r , g , b = unpack ( Details.class_colors [ self.classe ] )
end
local combat = instancia : GetShowingCombat ( )
local enemy_name = self : name ( )
Details : Destroy ( tooltip_temp_table ) --fix for translit bug report, 'player' is nil
--enemy damage taken
local i = 1
local damage_taken = 0
for _ , actor in ipairs ( combat [ 1 ] . _ActorTable ) do
if ( actor.grupo and actor.targets [ self.nome ] ) then
local t = tooltip_temp_table [ i ]
if ( not t ) then
tooltip_temp_table [ i ] = { }
t = tooltip_temp_table [ i ]
end
t [ 1 ] = actor
t [ 2 ] = actor.targets [ enemy_name ] or 0
damage_taken = damage_taken + t [ 2 ]
i = i + 1
end
end
for o = i , # tooltip_temp_table do
local t = tooltip_temp_table [ o ]
t [ 2 ] = 0
t [ 1 ] = 0
end
_table_sort ( tooltip_temp_table , Details.Sort2 )
-- enemy damage taken
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_DAMAGE_TAKEN_FROM " ] , headerColor , i - 1 , [[Interface\Buttons\UI-MicroStream-Red]] , 0.1875 , 0.8125 , 0.15625 , 0.78125 )
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
Details : AddTooltipHeaderStatusbar ( 1 , 1 , 1 , 0.5 )
--build the tooltip
local top = ( tooltip_temp_table [ 1 ] and tooltip_temp_table [ 1 ] [ 2 ] ) or 0
tooltip_temp_table.damage_total = damage_taken
local lineHeight = Details.tooltip . line_height
for o = 1 , i - 1 do
local player = tooltip_temp_table [ o ] [ 1 ]
local total = tooltip_temp_table [ o ] [ 2 ]
local player_name = Details : GetOnlyName ( player : name ( ) )
GameCooltip : AddLine ( player_name .. " " , FormatTooltipNumber ( _ , total ) .. " ( " .. format ( " %.1f " , ( total / damage_taken ) * 100 ) .. " %) " )
local classe = player : class ( )
if ( not classe ) then
classe = " UNKNOW "
end
if ( classe == " UNKNOW " ) then
GameCooltip : AddIcon ( " Interface \\ LFGFRAME \\ LFGROLE_BW " , nil , nil , lineHeight , lineHeight , .25 , .5 , 0 , 1 )
else
local specID = player.spec
if ( specID ) then
local texture , l , r , t , b = Details : GetSpecIcon ( specID , false )
GameCooltip : AddIcon ( texture , 1 , 1 , lineHeight , lineHeight , l , r , t , b )
else
GameCooltip : AddIcon ( instancia.row_info . icon_file , nil , nil , lineHeight , lineHeight , unpack ( Details.class_coords [ classe ] ) )
end
end
local r , g , b = unpack ( Details.class_colors [ classe ] )
GameCooltip : AddStatusBar ( total / top * 100 , 1 , r , g , b , 1 , false , enemies_background )
end
GameCooltip : SetOption ( " StatusBarTexture " , " Interface \\ AddOns \\ Details \\ images \\ bar_serenity " )
--damage done and heal
GameCooltip : AddLine ( " " )
GameCooltip : AddLine ( Loc [ " STRING_ATTRIBUTE_DAMAGE_ENEMIES_DONE " ] , FormatTooltipNumber ( _ , _math_floor ( self.total ) ) )
local half = 0.00048828125
GameCooltip : AddIcon ( instancia : GetSkinTexture ( ) , 1 , 1 , 14 , 14 , 0.005859375 + half , 0.025390625 - half , 0.3623046875 , 0.3818359375 )
GameCooltip : AddStatusBar ( 0 , 1 , r , g , b , 1 , false , enemies_background )
local heal_actor = instancia.showing ( 2 , self.nome )
if ( heal_actor ) then
GameCooltip : AddLine ( Loc [ " STRING_ATTRIBUTE_HEAL_ENEMY " ] , FormatTooltipNumber ( _ , _math_floor ( heal_actor.heal_enemy_amt ) ) )
else
GameCooltip : AddLine ( Loc [ " STRING_ATTRIBUTE_HEAL_ENEMY " ] , 0 )
end
GameCooltip : AddIcon ( instancia : GetSkinTexture ( ) , 1 , 1 , 14 , 14 , 0.037109375 + half , 0.056640625 - half , 0.3623046875 , 0.3818359375 )
GameCooltip : AddStatusBar ( 0 , 1 , r , g , b , 1 , false , enemies_background )
GameCooltip : AddLine ( " " )
Details : AddTooltipReportLineText ( )
GameCooltip : SetOption ( " YSpacingMod " , 0 )
return true
end
---------DAMAGE TAKEN
function damageClass : ToolTip_DamageTaken ( instance , numero , barra , keydown )
--if the object has a owner, it's a pet
local owner = self.owner
if ( owner and owner.classe ) then
r , g , b = unpack ( Details.class_colors [ owner.classe ] )
else
r , g , b = unpack ( Details.class_colors [ self.classe ] )
end
local damageTakenFrom = self.damage_from
local totalDamageTaken = self.damage_taken
local actorName = self : Name ( )
local combatObject = instance : GetShowingCombat ( )
local damageContainer = combatObject : GetContainer ( DETAILS_ATTRIBUTE_DAMAGE )
---@type {key1:actorname, key2:valueamount, key3:class, key4:actor}
local damageTakenDataSorted = { }
local mainAttribute , subAttribute = instance : GetDisplay ( )
if ( subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES ) then
for _ , actorObject in damageContainer : ListActors ( ) do
if ( actorObject : IsGroupPlayer ( ) and actorObject.targets [ actorName ] ) then
damageTakenDataSorted [ # damageTakenDataSorted + 1 ] = {
actorName ,
actorObject.targets [ actorName ] ,
actorObject : Class ( ) ,
actorObject
}
end
end
else
for enemyName , _ in pairs ( damageTakenFrom ) do --who damaged the player
--get the aggressor
local enemyActorObject = damageContainer : GetActor ( enemyName )
if ( enemyActorObject ) then
---@type {key1:actorname, key2:valueamount, key3:class, key4:actor}
local damageTakenTable
local damageInflictedByThisEnemy = enemyActorObject.targets [ actorName ]
if ( damageInflictedByThisEnemy ) then
if ( enemyActorObject : IsPlayer ( ) or enemyActorObject : IsNeutralOrEnemy ( ) ) then
damageTakenTable = { enemyName , damageInflictedByThisEnemy , enemyActorObject : Class ( ) , enemyActorObject }
damageTakenDataSorted [ # damageTakenDataSorted + 1 ] = damageTakenTable
end
end
--special cases - monk stagger
if ( enemyName == actorName and self : Class ( ) == " MONK " ) then
local friendlyFire = enemyActorObject.friendlyfire [ enemyName ]
if ( friendlyFire and friendlyFire.total > 0 ) then
local staggerDamage = friendlyFire.spells [ 124255 ] or 0
if ( staggerDamage > 0 ) then
if ( damageTakenTable ) then
damageTakenTable [ 2 ] = damageTakenTable [ 2 ] + staggerDamage
else
damageTakenDataSorted [ # damageTakenDataSorted + 1 ] = { enemyName , staggerDamage , " MONK " , enemyActorObject }
end
end
end
end
end
end
end
local maxDataAllowed = # damageTakenDataSorted
if ( maxDataAllowed > 10 ) then
maxDataAllowed = 10
end
local bIsMaximized = false
if ( keydown == " shift " or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3 or instance.sub_atributo == 6 or Details.damage_taken_everything ) then
maxDataAllowed = # damageTakenDataSorted
bIsMaximized = true
end
if ( subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES ) then
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_DAMAGE_TAKEN_FROM " ] , headerColor , # damageTakenDataSorted , [[Interface\Buttons\UI-MicroStream-Red]] , 0.1875 , 0.8125 , 0.15625 , 0.78125 )
else
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_FROM " ] , headerColor , # damageTakenDataSorted , [[Interface\Addons\Details\images\icons]] , 0.126953125 , 0.1796875 , 0 , 0.0546875 )
end
if ( bIsMaximized ) then
--highlight
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
if ( subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES ) then
GameCooltip : AddStatusBar ( 100 , 1 , 0.7 , g , b , 1 )
else
Details : AddTooltipHeaderStatusbar ( r , g , b , 1 )
end
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay1 )
if ( subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES ) then
GameCooltip : AddStatusBar ( 100 , 1 , 0.7 , 0 , 0 , barAlha )
else
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
end
end
local iconSize = Details.tooltip . icon_size
local iconBorderTexCoord = Details.tooltip . icon_border_texcoord
-- create a full list of incoming damage, before adding any lines to the tooltip, so we can sort them appropriately
---@class cooltip_icon
---@field key1 textureid
---@field key2 number 1 for main tooltip frame, 2 for the secondary frame
---@field key3 number 1 for the left side, 2 for the right size
---@field key4 width
---@field key5 height
---@field key6 coordleft
---@field key7 coordright
---@field key8 coordtop
---@field key9 coordbottom
---@type {key1:valueamount, key2:table<string, string>, key3:cooltip_icon}
local lines_to_add = { }
for i = 1 , maxDataAllowed do
local enemyActorObject = damageTakenDataSorted [ i ] [ 4 ]
--only shows damage from enemies or from the player it self
--the player it self can only be placed on the list by the iteration above
--the iteration doesnt check friendly fire for all actors, only a few cases like Monk Stagger
if ( enemyActorObject : IsNeutralOrEnemy ( ) or enemyActorObject : Name ( ) == self : Name ( ) ) then
---@type {key1:spellid, key2:valueamount, key:actorname}
local spellTargetDamageList = { }
for spellId , spellTable in pairs ( enemyActorObject.spells . _ActorTable ) do
local damageOnTarget = spellTable.targets [ self : Name ( ) ]
if ( damageOnTarget ) then
tinsert ( spellTargetDamageList , { spellId , damageOnTarget , enemyActorObject : Name ( ) } )
end
end
--friendly fire
local friendlyFire = enemyActorObject.friendlyfire [ self : Name ( ) ]
if ( friendlyFire ) then
for spellId , valueAmount in pairs ( friendlyFire.spells ) do
table.insert ( spellTargetDamageList , { spellId , valueAmount , enemyActorObject : Name ( ) } )
end
end
for _ , spell in ipairs ( spellTargetDamageList ) do
local spellId , valueAmount , thisActorName = unpack ( spell )
local spellName , _ , spellIcon = _GetSpellInfo ( spellId )
local addTextArgs = { spellName .. " (|cFFFFFF00 " .. thisActorName .. " |r) " , Details : Format ( valueAmount ) .. " ( " .. string.format ( " %.1f " , ( valueAmount / totalDamageTaken ) * 100 ) .. " %) " }
---@type cooltip_icon
local addIconArgs = { spellIcon , 1 , 1 , iconSize.W , iconSize.H , iconBorderTexCoord.L , iconBorderTexCoord.R , iconBorderTexCoord.T , iconBorderTexCoord.B }
tinsert ( lines_to_add , {
valueAmount ,
addTextArgs ,
addIconArgs
} )
end
else
---@type actorname, valueamount, class, actor
local thisAggrossorTable = damageTakenDataSorted [ i ]
local actorName = thisAggrossorTable [ 1 ]
local amount = thisAggrossorTable [ 2 ]
local class = thisAggrossorTable [ 3 ]
local actorObject = thisAggrossorTable [ 4 ]
---@type {key1:actorname, key2:string, key3:nil, key4:color}
local addLineArgs
---@type cooltip_icon
local addIconArgs
local aggressorName = Details : GetOnlyName ( actorName )
if ( bIsMaximized and actorName : find ( Details.playername ) ) then
addLineArgs = { aggressorName , Details : Format ( amount ) .. " ( " .. string.format ( " %.1f " , ( amount / totalDamageTaken ) * 100 ) .. " %) " , nil , " yellow " }
else
addLineArgs = { aggressorName , Details : Format ( amount ) .. " ( " .. string.format ( " %.1f " , ( amount / totalDamageTaken ) * 100 ) .. " %) " }
end
if ( not class ) then
class = " UNKNOW "
end
if ( class == " UNKNOW " ) then
addIconArgs = { " Interface \\ LFGFRAME \\ LFGROLE_BW " , nil , nil , iconSize.W , iconSize.H , .25 , .5 , 0 , 1 }
else
addIconArgs = { instance.row_info . icon_file , nil , nil , iconSize.W , iconSize.H , unpack ( Details.class_coords [ class ] ) }
end
tinsert ( lines_to_add , { amount , addLineArgs , addIconArgs } )
end
end
table.sort ( lines_to_add , Details.Sort1 )
for _ , line in ipairs ( lines_to_add ) do
GameCooltip : AddLine ( unpack ( line [ 2 ] ) )
GameCooltip : AddIcon ( unpack ( line [ 3 ] ) )
Details : AddTooltipBackgroundStatusbar ( )
end
if ( subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES ) then
GameCooltip : AddLine ( " " )
GameCooltip : AddLine ( Loc [ " STRING_ATTRIBUTE_DAMAGE_DONE " ] , FormatTooltipNumber ( _ , _math_floor ( self.total ) ) )
local half = 0.00048828125
GameCooltip : AddIcon ( instance : GetSkinTexture ( ) , 1 , 1 , iconSize.W , iconSize.H , 0.005859375 + half , 0.025390625 - half , 0.3623046875 , 0.3818359375 )
Details : AddTooltipBackgroundStatusbar ( )
local heal_actor = instance.showing ( 2 , self.nome )
if ( heal_actor ) then
GameCooltip : AddLine ( Loc [ " STRING_ATTRIBUTE_HEAL_DONE " ] , FormatTooltipNumber ( _ , _math_floor ( heal_actor.heal_enemy_amt ) ) )
else
GameCooltip : AddLine ( Loc [ " STRING_ATTRIBUTE_HEAL_DONE " ] , 0 )
end
GameCooltip : AddIcon ( instance : GetSkinTexture ( ) , 1 , 1 , iconSize.W , iconSize.H , 0.037109375 + half , 0.056640625 - half , 0.3623046875 , 0.3818359375 )
Details : AddTooltipBackgroundStatusbar ( )
end
return true
end
---------FRIENDLY FIRE
function damageClass : ToolTip_FriendlyFire ( instancia , numero , barra , keydown )
local owner = self.owner
if ( owner and owner.classe ) then
r , g , b = unpack ( Details.class_colors [ owner.classe ] )
else
r , g , b = unpack ( Details.class_colors [ self.classe ] )
end
local FriendlyFire = self.friendlyfire
local FriendlyFireTotal = self.friendlyfire_total
local combat = instancia : GetShowingCombat ( )
local tabela_do_combate = instancia.showing
local showing = tabela_do_combate [ class_type ]
local icon_size = Details.tooltip . icon_size
local icon_border = Details.tooltip . icon_border_texcoord
local lineHeight = Details.tooltip . line_height
local DamagedPlayers = { }
local Skills = { }
for target_name , ff_table in pairs ( FriendlyFire ) do
local actor = combat ( 1 , target_name )
if ( actor ) then
DamagedPlayers [ # DamagedPlayers + 1 ] = { target_name , ff_table.total , actor.classe }
for spellid , amount in pairs ( ff_table.spells ) do
Skills [ spellid ] = ( Skills [ spellid ] or 0 ) + amount
end
end
end
_table_sort ( DamagedPlayers , Details.Sort2 )
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_TARGETS " ] , headerColor , # DamagedPlayers , Details.tooltip_target_icon . file , unpack ( Details.tooltip_target_icon . coords ) )
local ismaximized = false
if ( keydown == " shift " or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3 ) then
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
Details : AddTooltipHeaderStatusbar ( r , g , b , 1 )
ismaximized = true
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_shift]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay1 )
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
end
local max_abilities = Details.tooltip . tooltip_max_abilities
if ( ismaximized ) then
max_abilities = 99
end
for i = 1 , _math_min ( max_abilities , # DamagedPlayers ) do
local classe = DamagedPlayers [ i ] [ 3 ]
if ( not classe ) then
classe = " UNKNOW "
end
GameCooltip : AddLine ( Details : GetOnlyName ( DamagedPlayers [ i ] [ 1 ] ) , FormatTooltipNumber ( _ , DamagedPlayers [ i ] [ 2 ] ) .. " ( " .. format ( " %.1f " , DamagedPlayers [ i ] [ 2 ] / FriendlyFireTotal * 100 ) .. " %) " )
GameCooltip : AddIcon ( " Interface \\ AddOns \\ Details \\ images \\ espadas " , nil , nil , lineHeight , lineHeight )
Details : AddTooltipBackgroundStatusbar ( )
if ( classe == " UNKNOW " ) then
GameCooltip : AddIcon ( " Interface \\ AddOns \\ Details \\ images \\ classes_small " , nil , nil , lineHeight , lineHeight , unpack ( Details.class_coords [ " UNKNOW " ] ) )
else
local specID = Details : GetSpec ( DamagedPlayers [ i ] [ 1 ] )
if ( specID ) then
local texture , l , r , t , b = Details : GetSpecIcon ( specID , false )
GameCooltip : AddIcon ( texture , 1 , 1 , lineHeight , lineHeight , l , r , t , b )
else
GameCooltip : AddIcon ( " Interface \\ AddOns \\ Details \\ images \\ classes_small " , nil , nil , lineHeight , lineHeight , unpack ( Details.class_coords [ classe ] ) )
end
end
end
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_SPELLS " ] , headerColor , 1 , Details.tooltip_spell_icon . file , unpack ( Details.tooltip_spell_icon . coords ) )
local ismaximized = false
if ( keydown == " ctrl " or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 4 ) then
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_ctrl]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
Details : AddTooltipHeaderStatusbar ( r , g , b , 1 )
ismaximized = true
else
GameCooltip : AddIcon ( [[Interface\AddOns\Details\images\key_ctrl]] , 1 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay1 )
Details : AddTooltipHeaderStatusbar ( r , g , b , barAlha )
end
local max_abilities2 = Details.tooltip . tooltip_max_abilities
if ( ismaximized ) then
max_abilities2 = 99
end
--spells usadas no friendly fire
local SpellsInOrder = { }
for spellID , amount in pairs ( Skills ) do
SpellsInOrder [ # SpellsInOrder + 1 ] = { spellID , amount }
end
_table_sort ( SpellsInOrder , Details.Sort2 )
for i = 1 , _math_min ( max_abilities2 , # SpellsInOrder ) do
local nome , _ , icone = _GetSpellInfo ( SpellsInOrder [ i ] [ 1 ] )
GameCooltip : AddLine ( nome , FormatTooltipNumber ( _ , SpellsInOrder [ i ] [ 2 ] ) .. " ( " .. format ( " %.1f " , SpellsInOrder [ i ] [ 2 ] / FriendlyFireTotal * 100 ) .. " %) " )
GameCooltip : AddIcon ( icone , nil , nil , icon_size.W , icon_size.H , icon_border.L , icon_border.R , icon_border.T , icon_border.B )
Details : AddTooltipBackgroundStatusbar ( )
end
return true
end
--------------------------------------------- // JANELA DETALHES // ---------------------------------------------
---------DETALHES BIFURCA��O ~detalhes ~detailswindow ~bi
function damageClass : MontaInfo ( )
if ( breakdownWindowFrame.sub_atributo == 1 or breakdownWindowFrame.sub_atributo == 2 or breakdownWindowFrame.sub_atributo == 6 ) then --damage done & dps
return self : MontaInfoDamageDone ( ) --has new code for the new destails window | left scroll and 6 blocks implemented
elseif ( breakdownWindowFrame.sub_atributo == 3 ) then --damage taken
return self : MontaInfoDamageTaken ( ) --has new code for the new destails window | left and right scrolls implemented
elseif ( breakdownWindowFrame.sub_atributo == 4 ) then --friendly fire
return self : MontaInfoFriendlyFire ( ) --has new code for the new destails window | left scroll implemeneted (need to implemente the right scroll yet)
end
end
---------DETALHES bloco da direita BIFURCA��O
function damageClass : MontaDetalhes ( spellid , barra , instancia ) --these functions were used to fill the 5 blocks from the old breakdown window
if ( breakdownWindowFrame.sub_atributo == 1 or breakdownWindowFrame.sub_atributo == 2 ) then
return self : MontaDetalhesDamageDone ( spellid , barra , instancia ) --deprecated
elseif ( breakdownWindowFrame.sub_atributo == 3 ) then
return self : MontaDetalhesDamageTaken ( spellid , barra , instancia )
elseif ( breakdownWindowFrame.sub_atributo == 4 ) then
return self : MontaDetalhesFriendlyFire ( spellid , barra , instancia )
elseif ( breakdownWindowFrame.sub_atributo == 6 ) then
if ( bitBand ( self.flag_original , 0x00000400 ) ~= 0 ) then --� um jogador
return self : MontaDetalhesDamageDone ( spellid , barra , instancia ) --deprecated
end
return self : MontaDetalhesEnemy ( spellid , barra , instancia )
end
end
local friendlyFireSpellSourcesHeadersAllowed = { icon = true , name = true , rank = true , amount = true , persecond = true , percent = true }
---when hovering over the player name in the breakdown window, this function will be called to build a the list of spells used to inflict damage on that player
---@param friendlyFireAggressorActor actordamage
---@param targetName string
function damageClass . BuildFriendlySpellListFromAgressor ( friendlyFireAggressorActor , targetName )
---@type combat
local combatObject = Details : GetCombatFromBreakdownWindow ( )
---@type friendlyfiretable
local friendlyFireTable = friendlyFireAggressorActor.friendlyfire [ targetName ]
local totalDamage = friendlyFireTable.total
local spellsUsed = friendlyFireTable.spells
--create the table which will be returned with the data
---@type {topValue: number, totalValue: number, headersAllowed: table, combatTime: number}
local resultTable = { topValue = 0 , totalValue = totalDamage , headersAllowed = friendlyFireSpellSourcesHeadersAllowed , combatTime = combatObject : GetCombatTime ( ) }
--iterate among the spells used by the aggressorActor
for spellId , amountDamage in pairs ( spellsUsed ) do
--add the spell to the list
local spellName = GetSpellInfo ( spellId )
resultTable [ # resultTable + 1 ] = { spellId = spellId , total = amountDamage , petName = " " , spellScholl = Details.spell_school_cache [ spellName ] or 1 }
end
return resultTable
end
------ Friendly Fire
local friendlyFireHeadersAllowed = { icon = true , name = true , rank = true , amount = true , persecond = true , percent = true }
---build the friendly fire list, the list contains players who were damaged by this actor.
function damageClass : MontaInfoFriendlyFire ( ) --~friendlyfire ~friendly ~ff
---@type actordamage
local actorObject = self
---@type instance
local instance = breakdownWindowFrame.instancia
---@type combat
local combatObject = instance : GetCombat ( )
---@type string
local actorName = actorObject : Name ( )
---@type number
local friendlyFireTotal = actorObject.friendlyfire_total
---@type table<string, friendlyfiretable>
local damagedPlayers = actorObject.friendlyfire --players which got hit by this actor
---@type actorcontainer
local damageContainer = combatObject : GetContainer ( class_type )
local resultTable = { }
for targetName , friendlyFireTable in pairs ( damagedPlayers ) do
local amountOfFriendlyFire = friendlyFireTable.total
if ( amountOfFriendlyFire > 0 ) then
---@type actordamage this is an actor who was damaged by the friendly fire of the actorObject
local targetActorObject = damageContainer : GetActor ( targetName )
if ( targetActorObject ) then
---@type texturetable
local iconTable = Details : GetActorIcon ( targetActorObject )
---@type {name: string, amount: number, icon: texturetable, class: string}
local ffTable = { name = targetName , total = amountOfFriendlyFire , icon = iconTable , class = targetActorObject : Class ( ) }
resultTable [ # resultTable + 1 ] = ffTable
end
end
end
resultTable.totalValue = friendlyFireTotal
resultTable.combatTime = combatObject : GetCombatTime ( )
resultTable.headersAllowed = friendlyFireHeadersAllowed
Details222.BreakdownWindow . SendGenericData ( resultTable , actorObject , combatObject , instance )
if true then return end
do
local instancia = breakdownWindowFrame.instancia
local combat = instancia : GetShowingCombat ( )
local barras = breakdownWindowFrame.barras1
local barras2 = breakdownWindowFrame.barras2
local barras3 = breakdownWindowFrame.barras3
local FriendlyFireTotal = self.friendlyfire_total
local DamagedPlayers = { }
local Skills = { }
for target_name , ff_table in pairs ( self.friendlyfire ) do
local actor = combat ( 1 , target_name )
if ( actor ) then
tinsert ( DamagedPlayers , { target_name , ff_table.total , ff_table.total / FriendlyFireTotal * 100 , actor.classe } )
for spellid , amount in pairs ( ff_table.spells ) do
Skills [ spellid ] = ( Skills [ spellid ] or 0 ) + amount
end
end
end
_table_sort ( DamagedPlayers , Details.Sort2 )
local amt = # DamagedPlayers
gump : JI_AtualizaContainerBarras ( amt )
local FirstPlaceDamage = DamagedPlayers [ 1 ] and DamagedPlayers [ 1 ] [ 2 ] or 0
for index , tabela in ipairs ( DamagedPlayers ) do
local barra = barras [ index ]
if ( not barra ) then
barra = gump : CriaNovaBarraInfo1 ( instancia , index )
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 )
barra.on_focus = false
end
if ( not breakdownWindowFrame.mostrando_mouse_over ) then
if ( tabela [ 1 ] == self.detalhes ) then --tabela [1] = NOME = NOME que esta na caixa da direita
if ( not barra.on_focus ) then --se a barra n�o tiver no foco
barra.textura : SetStatusBarColor ( 129 / 255 , 125 / 255 , 69 / 255 , 1 )
barra.on_focus = true
if ( not breakdownWindowFrame.mostrando ) then
breakdownWindowFrame.mostrando = barra
end
end
else
if ( barra.on_focus ) then
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 ) --volta a cor antiga
barra : SetAlpha ( .9 ) --volta a alfa antiga
barra.on_focus = false
end
end
end
if ( index == 1 ) then
barra.textura : SetValue ( 100 )
else
barra.textura : SetValue ( tabela [ 2 ] / FirstPlaceDamage * 100 )
end
barra.lineText1 : SetText ( index .. instancia.divisores . colocacao .. Details : GetOnlyName ( tabela [ 1 ] ) ) --seta o texto da esqueda
barra.lineText4 : SetText ( Details : comma_value ( tabela [ 2 ] ) .. " ( " .. format ( " %.1f " , tabela [ 3 ] ) .. " %) " ) --seta o texto da direita
local classe = tabela [ 4 ]
if ( not classe ) then
classe = " MONSTER "
end
barra.icone : SetTexture ( breakdownWindowFrame.instancia . row_info.icon_file )
if ( Details.class_coords [ classe ] ) then
barra.icone : SetTexCoord ( unpack ( Details.class_coords [ classe ] ) )
else
barra.icone : SetTexture ( " " )
end
local color = Details.class_colors [ classe ]
if ( color ) then
barra.textura : SetStatusBarColor ( unpack ( color ) )
else
barra.textura : SetStatusBarColor ( 1 , 1 , 1 )
end
barra.minha_tabela = self
barra.show = tabela [ 1 ]
barra : Show ( )
if ( self.detalhes and self.detalhes == barra.show ) then
self : MontaDetalhes ( self.detalhes , barra , instancia )
end
end
local SkillTable = { }
for spellid , amt in pairs ( Skills ) do
local nome , _ , icone = _GetSpellInfo ( spellid )
SkillTable [ # SkillTable + 1 ] = { nome , amt , amt / FriendlyFireTotal * 100 , icone }
end
_table_sort ( SkillTable , Details.Sort2 )
amt = # SkillTable
if ( amt < 1 ) then
return
end
gump : JI_AtualizaContainerAlvos ( amt )
FirstPlaceDamage = SkillTable [ 1 ] and SkillTable [ 1 ] [ 2 ] or 0
for index , tabela in ipairs ( SkillTable ) do
local barra = barras2 [ index ]
if ( not barra ) then
barra = gump : CriaNovaBarraInfo2 ( instancia , index )
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 )
end
if ( index == 1 ) then
barra.textura : SetValue ( 100 )
else
barra.textura : SetValue ( tabela [ 2 ] / FirstPlaceDamage * 100 )
end
barra.lineText1 : SetText ( index .. instancia.divisores . colocacao .. tabela [ 1 ] ) --seta o texto da esqueda
barra.lineText4 : SetText ( Details : comma_value ( tabela [ 2 ] ) .. " ( " .. format ( " %.1f " , tabela [ 3 ] ) .. " ) " ) --seta o texto da direita
barra.icone : SetTexture ( tabela [ 4 ] )
barra.minha_tabela = nil --desativa o tooltip
barra : Show ( )
end
end
end
local damageTakenSpellSourcesHeadersAllowed = { icon = true , name = true , rank = true , amount = true , persecond = true , percent = true }
function damageClass . BuildDamageTakenSpellListFromAgressor ( targetActor , aggressorActor )
--target actor name
local targetActorName = targetActor : Name ( )
---@type combat
local combatObject = Details : GetCombatFromBreakdownWindow ( )
--get the list of spells from the aggressorActor and check each one to see if it was casted on the targetActor
---@type spellcontainer
local spellContainer = aggressorActor : GetSpellContainer ( " spell " )
--create the table which will be returned with the data
---@type {topValue: number, totalValue: number, headersAllowed: table, combatTime: number}
local resultTable = { topValue = 0 , totalValue = 0 , headersAllowed = damageTakenSpellSourcesHeadersAllowed , combatTime = combatObject : GetCombatTime ( ) }
for spellId , spellTable in spellContainer : ListSpells ( ) do
---@cast spellTable spelltable
for targetName , amount in pairs ( spellTable.targets ) do
if ( targetName == targetActorName ) then
--add the spell to the list
resultTable [ # resultTable + 1 ] = { spellId = spellId , total = amount , petName = " " , spellScholl = spellTable.spellschool }
resultTable.totalValue = resultTable.totalValue + amount
end
end
end
--iterate among the pets of the aggressorActor and get the spells casted by them
---@type table<number, actorname>
local petTable = aggressorActor.pets
for i = 1 , # petTable do
local petName = petTable [ i ]
local petActorObject = combatObject : GetActor ( DETAILS_ATTRIBUTE_DAMAGE , petName )
if ( petActorObject ) then
---@type spellcontainer
local petSpellContainer = petActorObject : GetSpellContainer ( " spell " )
for spellId , spellTable in petSpellContainer : ListSpells ( ) do
for targetName , amount in pairs ( spellTable.targets ) do
if ( targetName == targetActorName ) then
--add the spell to the list
resultTable [ # resultTable + 1 ] = { spellId = spellId , total = amount , petName = petName , spellScholl = spellTable.spellschool }
resultTable.totalValue = resultTable.totalValue + amount
end
end
end
end
end
return resultTable
end
------ Damage Taken
local damageTakenHeadersAllowed = { icon = true , name = true , rank = true , amount = true , persecond = true , percent = true }
function damageClass : MontaInfoDamageTaken ( )
---@type actordamage
local actorObject = self
---@type instance
local instance = breakdownWindowFrame.instancia
---@type combat
local combatObject = instance : GetCombat ( )
---@type string
local actorName = actorObject : Name ( )
---@type number
local damageTakenTotal = actorObject.damage_taken
---@type table<string, boolean>
local damageTakenFrom = actorObject.damage_from
---@type actorcontainer
local damageContainer = combatObject : GetContainer ( class_type )
local resultTable = { }
---@type string
for aggressorName in pairs ( damageTakenFrom ) do
local aggressorActor = damageContainer : GetActor ( aggressorName )
if ( aggressorActor ) then
---@type table<string, number>
local targets = aggressorActor : GetTargets ( )
---@type number|nil
local amountOfDamage = targets [ actorName ]
if ( amountOfDamage ) then
---@type texturetable
local iconTable = Details : GetActorIcon ( aggressorActor )
---@type {name: string, amount: number, icon: texturetable}
local damageTakenTable = { name = aggressorName , total = amountOfDamage , icon = iconTable , class = aggressorActor : Class ( ) }
resultTable [ # resultTable + 1 ] = damageTakenTable
end
end
end
resultTable.totalValue = damageTakenTotal
resultTable.combatTime = combatObject : GetCombatTime ( )
resultTable.headersAllowed = damageTakenHeadersAllowed
Details222.BreakdownWindow . SendGenericData ( resultTable , actorObject , combatObject , instance )
end
--[[exported]] function Details : UpdadeInfoBar ( row , index , spellId , name , value , formattedValue , max , percent , icon , detalhes , texCoords , spellSchool , class )
if ( index == 1 ) then
row.textura : SetValue ( 100 )
else
max = math.max ( max , 0.001 )
row.textura : SetValue ( value / max * 100 )
end
if ( type ( index ) == " number " ) then
if ( debugmode ) then
row.lineText1 : SetText ( index .. " . " .. name .. " ( " .. spellId .. " ) " )
else
row.lineText1 : SetText ( index .. " . " .. name )
end
else
row.lineText1 : SetText ( name )
end
row.lineText1 . text = row.lineText1 : GetText ( )
if ( formattedValue ) then
row.lineText4 : SetText ( formattedValue .. " ( " .. format ( " %.1f " , percent ) .. " %) " )
end
row.lineText1 : SetSize ( row : GetWidth ( ) - row.lineText4 : GetStringWidth ( ) - 40 , 15 )
if ( icon ) then
row.icone : SetTexture ( icon )
if ( icon == " Interface \\ AddOns \\ Details \\ images \\ classes_small " ) then
row.icone : SetTexCoord ( 0.25 , 0.49609375 , 0.75 , 1 )
else
row.icone : SetTexCoord ( 0 , 1 , 0 , 1 )
end
else
row.icone : SetTexture ( " " )
end
if ( not row.IconUpBorder ) then
row.IconUpBorder = CreateFrame ( " frame " , nil , row , " BackdropTemplate " )
row.IconUpBorder : SetAllPoints ( row.icone )
row.IconUpBorder : SetBackdrop ( { edgeFile = [[Interface\Buttons\WHITE8X8]] , edgeSize = 1 } )
row.IconUpBorder : SetBackdropBorderColor ( 0 , 0 , 0 , 0.75 )
end
if ( texCoords ) then
row.icone : SetTexCoord ( unpack ( texCoords ) )
else
local iconBorder = Details.tooltip . icon_border_texcoord
row.icone : SetTexCoord ( iconBorder.L , iconBorder.R , iconBorder.T , iconBorder.B )
end
row.minha_tabela = self
row.show = spellId
row : Show ( )
if ( spellSchool ) then
local schoolColor = Details.spells_school [ spellSchool ]
if ( schoolColor and schoolColor.decimals ) then
row.textura : SetStatusBarColor ( schoolColor.decimals [ 1 ] , schoolColor.decimals [ 2 ] , schoolColor.decimals [ 3 ] )
else
row.textura : SetStatusBarColor ( 1 , 1 , 1 )
end
elseif ( class ) then
local color = Details.class_colors [ class ]
if ( color and class ~= " UNKNOW " ) then
row.textura : SetStatusBarColor ( unpack ( color ) )
else
row.textura : SetStatusBarColor ( 1 , 1 , 1 )
end
else
if ( spellId == 98021 ) then --spirit linkl
row.textura : SetStatusBarColor ( 1 , 0.4 , 0.4 )
else
row.textura : SetStatusBarColor ( 1 , 1 , 1 )
end
end
if ( detalhes and self.detalhes and self.detalhes == spellId and breakdownWindowFrame.showing == index ) then
self : MontaDetalhes ( row.show , row , breakdownWindowFrame.instancia )
end
end
--lock into a line after clicking on it
--[[exported]] function Details : FocusLock ( row , spellId ) --will be deprecated
if ( not breakdownWindowFrame.mostrando_mouse_over ) then
if ( spellId == self.detalhes ) then --tabela [1] = spellid = spellid que esta na caixa da direita
if ( not row.on_focus ) then --se a barra n�o tiver no foco
row.textura : SetStatusBarColor ( 129 / 255 , 125 / 255 , 69 / 255 , 1 )
row.on_focus = true
if ( not breakdownWindowFrame.mostrando ) then
breakdownWindowFrame.mostrando = row
end
end
else
if ( row.on_focus ) then
row.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 ) --volta a cor antiga
row : SetAlpha ( .9 ) --volta a alfa antiga
row.on_focus = false
end
end
end
end
local wipeSpellCache = function ( ) --deprecated
Details : Destroy ( Details222.PlayerBreakdown . DamageSpellsCache )
end
local addToSpellCache = function ( unitGUID , spellName , spellTable ) --deprecated
local unitSpellCache = Details222.PlayerBreakdown . DamageSpellsCache [ unitGUID ]
if ( not unitSpellCache ) then
unitSpellCache = { }
Details222.PlayerBreakdown . DamageSpellsCache [ unitGUID ] = unitSpellCache
end
local spellCache = Details222.PlayerBreakdown . DamageSpellsCache [ unitGUID ] [ spellName ]
if ( not spellCache ) then
spellCache = { }
Details222.PlayerBreakdown . DamageSpellsCache [ unitGUID ] [ spellName ] = spellCache
end
table.insert ( spellCache , spellTable )
end
local getSpellDetails = function ( unitGUID , spellName ) --deprecated
local unitCachedSpells = Details222.PlayerBreakdown . DamageSpellsCache [ unitGUID ]
local spellsTableForSpellName = unitCachedSpells and unitCachedSpells [ spellName ]
if ( spellsTableForSpellName ) then --should always be valid
if ( # spellsTableForSpellName > 1 ) then
local t = spellsTableForSpellName
local spellId = t [ 1 ] . id
local newSpellTable = Details222.DamageSpells . CreateSpellTable ( spellId )
newSpellTable.n_min = 99999999
newSpellTable.c_min = 99999999
newSpellTable.n_max = 0
newSpellTable.c_max = 0
for i = 1 , # t do
for key , value in pairs ( t [ i ] ) do
if ( type ( value ) == " number " ) then
if ( key == " n_min " or key == " c_min " ) then
if ( value < newSpellTable [ key ] ) then
newSpellTable [ key ] = value
end
elseif ( key == " n_max " or key == " c_max " ) then
if ( value > newSpellTable [ key ] ) then
newSpellTable [ key ] = value
end
elseif ( key ~= " id " and key ~= " spellschool " ) then
newSpellTable [ key ] = ( newSpellTable [ key ] or 0 ) + value
end
end
end
end
return newSpellTable
else
--there's only one table, so return the first
return spellsTableForSpellName [ 1 ]
end
end
end
--[=[
current : passando todas as spells para o breakdown , até mesmo as spells que não tem merge é enviado a spell total e a a spellTable logo em seguida
isso forma uma array com o dobro do tamanho e spells duplicadas
passar as spells repetidas em uma segunda array ?
não passar nada e deixar o sistema aprender sozinho , como o sistema vai saber que precisa por uma arrow na linha ? ( para expandi - la )
--]=]
------ Damage Done & Dps
function damageClass : MontaInfoDamageDone ( ) --I guess this fills the list of spells in the topleft scrollBar in the summary tab
--the goal of this function is to build a list of spells the actor used and send the data to Details! which will delivery to the summary tab actived
--so the script only need to build the list of spells and send it to Details!
---@type actor
local actorObject = self
---@type instance
local instance = breakdownWindowFrame.instancia
---@type combat
local combatObject = instance : GetCombat ( )
---@type number
local diff = combatObject : GetDifficulty ( )
---@type string
local playerName = actorObject : Name ( )
local attribute , subAttribute = instance : GetDisplay ( )
--guild ranking on a boss
--check if is a raid encounter and if is heroic or mythic
do
if ( diff and ( diff == 15 or diff == 16 ) ) then
local db = Details.OpenStorage ( )
if ( db ) then
local bestRank , encounterTable = Details.storage : GetBestFromPlayer ( diff , combatObject : GetBossInfo ( ) . id , " damage " , playerName , true )
if ( bestRank ) then
--discover which are the player position in the guild rank
local playerTable , onEncounter , rankPosition = Details.storage : GetPlayerGuildRank ( diff , combatObject : GetBossInfo ( ) . id , " damage " , playerName , true )
local text1 = playerName .. " Guild Rank on " .. ( combatObject : GetBossInfo ( ) . name or " " ) .. " : |cFFFFFF00 " .. ( rankPosition or " x " ) .. " |r Best Dps: |cFFFFFF00 " .. Details : ToK2 ( ( bestRank [ 1 ] or 0 ) / encounterTable.elapsed ) .. " |r ( " .. encounterTable.date : gsub ( " .*%s " , " " ) .. " ) "
breakdownWindowFrame : SetStatusbarText ( text1 , 10 , " gray " )
else
breakdownWindowFrame : SetStatusbarText ( )
end
else
breakdownWindowFrame : SetStatusbarText ( )
end
else
breakdownWindowFrame : SetStatusbarText ( )
end
end
---@type breakdownspelldatalist
local breakdownSpellDataList = { }
---@type number
local totalDamageWithoutPet = actorObject.total_without_pet
---@type number
local actorTotal = actorObject.total
---@type table<number, spelltable>
local actorSpells = actorObject : GetSpellList ( )
wipeSpellCache ( )
--get time
local actorCombatTime
if ( Details.time_type == 1 or not actorObject.grupo ) then
actorCombatTime = actorObject : Tempo ( )
elseif ( Details.time_type == 2 or Details.use_realtimedps ) then
actorCombatTime = breakdownWindowFrame.instancia . showing : GetCombatTime ( )
end
--actor spells
---@type table<string, number>
local alreadyAdded = { }
local bShouldMergePlayerSpells = Details.breakdown_spell_tab . nest_players_spells_with_same_name
---@type number, spelltable
for spellId , spellTable in pairs ( actorSpells ) do
spellTable.ChartData = nil --~ChartData
---@type string
local spellName = _GetSpellInfo ( spellId )
if ( spellName ) then
---@type number in which index the spell with the same name was stored
local index = alreadyAdded [ spellName ]
if ( index and bShouldMergePlayerSpells ) then
---@type spelltableadv
local bkSpellData = breakdownSpellDataList [ index ]
bkSpellData.spellTables [ # bkSpellData.spellTables + 1 ] = spellTable
---@type bknesteddata
local nestedData = { spellId = spellId , spellTable = spellTable , actorName = " " , value = 0 }
bkSpellData.nestedData [ # bkSpellData.nestedData + 1 ] = nestedData
bkSpellData.bCanExpand = true
else
---@type spelltableadv
local bkSpellData = {
id = spellId ,
spellschool = spellTable.spellschool ,
bIsExpanded = Details222.BreakdownWindow . IsSpellExpanded ( spellId ) ,
bCanExpand = false ,
spellTables = { spellTable } ,
nestedData = { { spellId = spellId , spellTable = spellTable , actorName = " " , value = 0 } } ,
}
detailsFramework : Mixin ( bkSpellData , Details.SpellTableMixin )
breakdownSpellDataList [ # breakdownSpellDataList + 1 ] = bkSpellData
alreadyAdded [ spellName ] = # breakdownSpellDataList
end
end
end
--pets spells
local bShouldMergeSpellsWithThePet = Details.breakdown_spell_tab . nest_pet_spells_by_caster
local bShouldMergePetSpells = Details.breakdown_spell_tab . nest_pet_spells_by_name
local actorPets = actorObject : GetPets ( )
for _ , petName in ipairs ( actorPets ) do
---@type actor
local petActor = combatObject ( DETAILS_ATTRIBUTE_DAMAGE , petName )
if ( petActor ) then --PET
--get the amount of spells the pet used, if the pet used only one there`s no reason to nest one spell with the pet
local petSpellContainer = petActor : GetSpellContainer ( " spell " )
if ( bShouldMergeSpellsWithThePet and petSpellContainer : HasTwoOrMoreSpells ( ) ) then
---@type spelltableadv
local bkSpellData = {
bIsActorHeader = true , --tag this spelltable as an actor header, when the actor is the header it will nest the spells use by this actor
actorName = petName ,
npcId = petActor.aID ,
id = 0 ,
spellschool = 0 ,
bIsExpanded = Details222.BreakdownWindow . IsSpellExpanded ( petName ) ,
spellTables = { } , --populated below with the spells the pet used
nestedData = { } , --there's none data here in the main bar as the first bar is the pet name
bCanExpand = true ,
actorIcon = [[Interface\AddOns\Details\images\pets\pet_icon_1]] ,
}
detailsFramework : Mixin ( bkSpellData , Details.SpellTableMixin )
--output
breakdownSpellDataList [ # breakdownSpellDataList + 1 ] = bkSpellData
--fill here the spellTables using the actor abilities
--all these spells belong to the current actor in the loop
for spellId , spellTable in petSpellContainer : ListSpells ( ) do
local spellName , _ , spellIcon = GetSpellInfo ( spellId )
if ( spellName ) then
bkSpellData.spellTables [ # bkSpellData.spellTables + 1 ] = spellTable
---@type bknesteddata
local nestedData = { spellId = spellId , spellTable = spellTable , actorName = petName , value = 0 , bIsActorHeader = true } --value to be defined
bkSpellData.nestedData [ # bkSpellData.nestedData + 1 ] = nestedData
end
end
else
local spells = petActor : GetSpellList ( )
--all these spells belong to the current pet in the loop
for spellId , spellTable in pairs ( spells ) do
---@cast spellId number
---@cast spellTable spelltable
spellTable.ChartData = nil
--PET
---@type string
local spellName = _GetSpellInfo ( spellId )
if ( spellName ) then
---@type number in which index the spell with the same name was stored
local index = alreadyAdded [ spellName ]
if ( index and bShouldMergePetSpells ) then --PET
---@type spelltableadv
local bkSpellData = breakdownSpellDataList [ index ]
bkSpellData.spellTables [ # bkSpellData.spellTables + 1 ] = spellTable
---@type bknesteddata
local nestedData = { spellId = spellId , spellTable = spellTable , actorName = petName , value = 0 }
bkSpellData.nestedData [ # bkSpellData.nestedData + 1 ] = nestedData
bkSpellData.bCanExpand = true
else --PET
---@type spelltableadv
local bkSpellData = {
id = spellId ,
actorName = petName ,
npcId = petActor.aID ,
spellschool = spellTable.spellschool ,
bIsExpanded = Details222.BreakdownWindow . IsSpellExpanded ( spellId ) ,
bCanExpand = false ,
spellTables = { spellTable } ,
nestedData = { { spellId = spellId , spellTable = spellTable , actorName = petName , value = 0 } } ,
}
detailsFramework : Mixin ( bkSpellData , Details.SpellTableMixin )
breakdownSpellDataList [ # breakdownSpellDataList + 1 ] = bkSpellData
alreadyAdded [ spellName ] = # breakdownSpellDataList
end
end
end
end
end
end
--copy the keys from the spelltable and add them to the spelltableadv
--repeated spells will be summed
for i = 1 , # breakdownSpellDataList do
---@type spelltableadv
local bkSpellData = breakdownSpellDataList [ i ]
Details.SpellTableMixin . SumSpellTables ( bkSpellData.spellTables , bkSpellData )
--Details:Destroy(bkSpellData, "spellTables") --temporary fix for BuildSpellTargetFromBreakdownSpellData, that function need to use bkSpellData.nestedData
end
breakdownSpellDataList.totalValue = actorTotal
breakdownSpellDataList.combatTime = actorCombatTime
Details : Destroy ( alreadyAdded )
--send to the breakdown window
Details222.BreakdownWindow . SendSpellData ( breakdownSpellDataList , actorObject , combatObject , instance )
--targets
---an array of breakdowntargettable
---@type breakdowntargettablelist
local targetList = { }
local targetTotalValue = 0
local targetsTable = self : GetTargets ( )
for targetName , amount in pairs ( targetsTable ) do
---@class breakdowntargettable
local bkTargetData = {
name = targetName ,
total = amount ,
overheal = 0 ,
}
targetTotalValue = targetTotalValue + amount
tinsert ( targetList , bkTargetData )
end
targetList.totalValue = targetTotalValue
targetList.combatTime = actorCombatTime
Details222.BreakdownWindow . SendTargetData ( targetList , actorObject , combatObject , instance )
if 1 then return end
--to be deprecated and removed:
--gump:JI_AtualizaContainerBarras (#actorSpellsSorted + 1)
local max_ = breakdownSpellDataList [ 1 ] and breakdownSpellDataList [ 1 ] [ 2 ] or 0 --dano que a primeiro magia vez
local barra
--aura bar
if ( false ) then --disabled for now
barra = allLines [ 1 ]
if ( not barra ) then
barra = gump : CriaNovaBarraInfo1 ( instance , 1 )
end
self : UpdadeInfoBar ( barra , " " , - 51 , " Auras " , max_ , false , max_ , 100 , [[Interface\BUTTONS\UI-GroupLoot-DE-Up]] , true , nil , nil )
barra.textura : SetStatusBarColor ( Details.gump : ParseColors ( " purple " ) )
end
--spell bars
for index , tabela in ipairs ( breakdownSpellDataList ) do
--index = index + 1 --with the aura bar
index = index
barra = allLines [ index ]
if ( not barra ) then
barra = gump : CriaNovaBarraInfo1 ( instance , index )
end
barra.other_actor = tabela [ 6 ]
local name = tabela [ 4 ]
if ( breakdownWindowFrame.sub_atributo == 2 ) then
local formated_value = SelectedToKFunction ( _ , _math_floor ( tabela [ 2 ] / actorCombatTime ) )
self : UpdadeInfoBar ( barra , index , tabela [ 1 ] , name , tabela [ 2 ] , formated_value , max_ , tabela [ 3 ] , tabela [ 5 ] , true , nil , tabela [ 7 ] )
else
local formated_value = SelectedToKFunction ( _ , _math_floor ( tabela [ 2 ] ) )
self : UpdadeInfoBar ( barra , index , tabela [ 1 ] , name , tabela [ 2 ] , formated_value , max_ , tabela [ 3 ] , tabela [ 5 ] , true , nil , tabela [ 7 ] )
end
self : FocusLock ( barra , tabela [ 1 ] )
end
--targets
if ( instance.sub_atributo == DETAILS_SUBATTRIBUTE_ENEMIES ) then
local totalDamageTaken = self.damage_taken
local damageTakenFrom = self.damage_from
local combatObject = instance : GetShowingCombat ( )
local damageContainer = combatObject : GetContainer ( DETAILS_ATTRIBUTE_DAMAGE )
local barras = breakdownWindowFrame.barras2
local enemyTable = { }
local targetName = self : Name ( )
local enemyActorObject
for enemyName in pairs ( damageTakenFrom ) do
enemyActorObject = damageContainer : GetActor ( enemyName )
if ( enemyActorObject ) then
local damageDoneToTarget = enemyActorObject.targets [ targetName ]
if ( damageDoneToTarget ) then
local npcId = DetailsFramework : GetNpcIdFromGuid ( enemyActorObject : GetGUID ( ) )
enemyTable [ # enemyTable + 1 ] = { enemyName , damageDoneToTarget , damageDoneToTarget / totalDamageTaken * 100 , enemyActorObject : Class ( ) , npcId }
end
end
end
local enemyAmount = # enemyTable
if ( enemyAmount < 1 ) then
return true
end
gump : JI_AtualizaContainerAlvos ( enemyAmount )
table.sort ( enemyTable , Details.Sort2 )
local topDamage = enemyTable [ 1 ] and enemyTable [ 1 ] [ 2 ] or 0
local thisLine
for index , thisEnemyTable in ipairs ( enemyTable ) do
thisLine = barras [ index ]
if ( not thisLine ) then --se a barra n�o existir, criar ela ent�o
thisLine = gump : CriaNovaBarraInfo2 ( instance , index )
thisLine.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 ) --isso aqui � a parte da sele��o e descele��o
end
if ( index == 1 ) then
thisLine.textura : SetValue ( 100 )
else
thisLine.textura : SetValue ( thisEnemyTable [ 2 ] / topDamage * 100 )
end
thisLine.lineText1 : SetText ( index .. " . " .. Details : GetOnlyName ( thisEnemyTable [ 1 ] ) ) --left text
thisLine.lineText4 : SetText ( Details : comma_value ( thisEnemyTable [ 2 ] ) .. " ( " .. format ( " %.1f " , thisEnemyTable [ 3 ] ) .. " %) " ) --right text
thisLine.icone : SetTexture ( [[Interface\AddOns\Details\images\classes_small_alpha]] ) --class icon
local texCoords = Details.class_coords [ thisEnemyTable [ 4 ] ]
if ( not texCoords ) then
texCoords = Details.class_coords [ " UNKNOW " ]
end
thisLine.icone : SetTexCoord ( unpack ( texCoords ) )
local color = Details.class_colors [ thisEnemyTable [ 4 ] ]
if ( color ) then
thisLine.textura : SetStatusBarColor ( unpack ( color ) )
else
thisLine.textura : SetStatusBarColor ( 1 , 1 , 1 )
end
Details : name_space_info ( thisLine )
if ( thisLine.mouse_over ) then --atualizar o tooltip
if ( thisLine.isAlvo ) then
GameTooltip : Hide ( )
GameTooltip : SetOwner ( thisLine , " ANCHOR_TOPRIGHT " )
if ( not thisLine.minha_tabela : MontaTooltipDamageTaken ( thisLine , index ) ) then
return
end
GameTooltip : Show ( )
end
end
thisLine.minha_tabela = self --grava o jogador na tabela
thisLine.nome_inimigo = thisEnemyTable [ 1 ] --salva o nome do inimigo na barra --isso � necess�rio?
-- no rank do spell id colocar o que?
thisLine.spellid = " enemies "
thisLine : Show ( ) --mostra a barra
end
else
local combatObject = instance : GetShowingCombat ( )
local damageContainer = combatObject : GetContainer ( DETAILS_ATTRIBUTE_DAMAGE )
local allActorTargets = { }
--table with actor names and damage done which the player caused damage to
local targetsTable = self.targets
for targetName , damageDone in pairs ( targetsTable ) do
tinsert ( allActorTargets , { targetName , damageDone , damageDone / totalDamageWithoutPet * 100 } )
end
table.sort ( allActorTargets , Details.Sort2 )
local enemyAmount = # allActorTargets
if ( enemyAmount < 1 ) then
return
end
gump : JI_AtualizaContainerAlvos ( enemyAmount )
local topDamage = allActorTargets [ 1 ] and allActorTargets [ 1 ] [ 2 ] or 0
local barra
for index , targetTable in ipairs ( allActorTargets ) do
barra = breakdownWindowFrame.barras2 [ index ]
if ( not barra ) then
barra = gump : CriaNovaBarraInfo2 ( instance , index )
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 )
end
if ( index == 1 ) then
barra.textura : SetValue ( 100 )
else
barra.textura : SetValue ( targetTable [ 2 ] / topDamage * 100 )
end
local targetName = targetTable [ 1 ]
local targetActorObject = damageContainer : GetActor ( targetName )
if ( targetActorObject ) then
local npcId = DetailsFramework : GetNpcIdFromGuid ( targetActorObject : GetGUID ( ) )
local portraitTexture -- = Details222.Textures.GetPortraitTextureForNpcID(npcId) disabled
if ( portraitTexture ) then
Details222.Textures . FormatPortraitAsTexture ( portraitTexture , barra.icone )
else
targetActorObject : SetClassIcon ( barra.icone , instance , targetActorObject.classe )
end
else
barra.icone : SetTexture ( [[Interface\AddOns\Details\images\classes_small_alpha]] ) --CLASSE
local texCoords = Details.class_coords [ " ENEMY " ]
barra.icone : SetTexCoord ( unpack ( texCoords ) )
end
barra.textura : SetStatusBarColor ( 1 , 0.8 , 0.8 )
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 )
barra.lineText1 : SetText ( index .. " . " .. Details : GetOnlyName ( targetName ) )
if ( breakdownWindowFrame.sub_atributo == 2 ) then
barra.lineText4 : SetText ( Details : comma_value ( _math_floor ( targetTable [ 2 ] / actorCombatTime ) ) .. " ( " .. format ( " %.1f " , targetTable [ 3 ] ) .. " %) " )
else
barra.lineText4 : SetText ( SelectedToKFunction ( _ , targetTable [ 2 ] ) .. " ( " .. format ( " %.1f " , targetTable [ 3 ] ) .. " %) " )
end
if ( barra.mouse_over ) then --atualizar o tooltip
if ( barra.isAlvo ) then
if ( not barra.minha_tabela : MontaTooltipAlvos ( barra , index , instance ) ) then
return
end
end
end
barra.minha_tabela = self --grava o jogador na tabela
barra.nome_inimigo = targetTable [ 1 ] --salva o nome do inimigo na barra --isso � necess�rio?
-- no rank do spell id colocar o que?
barra.spellid = targetTable [ 5 ]
barra : Show ( )
end
end
end
------ Detalhe Info Friendly Fire
function damageClass : MontaDetalhesFriendlyFire ( nome , barra )
local barras = breakdownWindowFrame.barras3
local instancia = breakdownWindowFrame.instancia
local tabela_do_combate = breakdownWindowFrame.instancia . showing
local showing = tabela_do_combate [ class_type ] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable
local friendlyfire = self.friendlyfire
local ff_table = self.friendlyfire [ nome ] --assumindo que nome � o nome do Alvo que tomou dano // bastaria pegar a tabela de habilidades dele
if ( not ff_table ) then
return
end
local total = ff_table.total
local minhas_magias = { }
for spellid , amount in pairs ( ff_table.spells ) do --da foreach em cada spellid do container
local nome , _ , icone = _GetSpellInfo ( spellid )
tinsert ( minhas_magias , { spellid , amount , amount / total * 100 , nome , icone } )
end
_table_sort ( minhas_magias , Details.Sort2 )
local max_ = minhas_magias [ 1 ] and minhas_magias [ 1 ] [ 2 ] or 0 --dano que a primeiro magia vez
local lastIndex = 1
local barra
for index , tabela in ipairs ( minhas_magias ) do
lastIndex = index
barra = barras [ index ]
if ( not barra ) then --se a barra n�o existir, criar ela ent�o
barra = gump : CriaNovaBarraInfo3 ( instancia , index )
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 ) --isso aqui � a parte da sele��o e descele��o
end
barra.show = tabela [ 1 ]
if ( index == 1 ) then
barra.textura : SetValue ( 100 )
else
barra.textura : SetValue ( tabela [ 2 ] / max_ * 100 ) --muito mais rapido...
end
barra.lineText1 : SetText ( index .. instancia.divisores . colocacao .. tabela [ 4 ] ) --seta o texto da esqueda
barra.lineText4 : SetText ( Details : comma_value ( tabela [ 2 ] ) .. " " .. instancia.divisores . abre .. format ( " %.1f " , tabela [ 3 ] ) .. " % " .. instancia.divisores . fecha ) --seta o texto da direita
barra.icone : SetTexture ( tabela [ 5 ] )
barra.icone : SetTexCoord ( 0 , 1 , 0 , 1 )
barra : Show ( ) --mostra a barra
if ( index == 15 ) then
break
end
end
for i = lastIndex + 1 , # barras do
barras [ i ] : Hide ( )
end
end
-- detalhes info enemies
function damageClass : MontaDetalhesEnemy ( spellid , barra )
local container = breakdownWindowFrame.instancia . showing [ 1 ]
local barras = breakdownWindowFrame.barras3
local instancia = breakdownWindowFrame.instancia
local other_actor = barra.other_actor
if ( other_actor ) then
self = other_actor
end
if ( barra.lineText1 : IsTruncated ( ) ) then
Details : CooltipPreset ( 2 )
GameCooltip : SetOption ( " FixedWidth " , nil )
GameCooltip : AddLine ( barra.lineText1 . text )
GameCooltip : SetOwner ( barra , " bottomleft " , " topleft " , 5 , - 10 )
GameCooltip : ShowCooltip ( )
end
local spell = self.spells : PegaHabilidade ( spellid )
local targets = spell.targets
local target_pool = { }
for target_name , amount in pairs ( targets ) do
local classe
local this_actor = breakdownWindowFrame.instancia . showing ( 1 , target_name )
if ( this_actor ) then
classe = this_actor.classe or " UNKNOW "
else
classe = " UNKNOW "
end
target_pool [ # target_pool + 1 ] = { target_name , amount , classe }
end
_table_sort ( target_pool , Details.Sort2 )
local max_ = target_pool [ 1 ] and target_pool [ 1 ] [ 2 ] or 0
local lastIndex = 1
local barra
for index , tabela in ipairs ( target_pool ) do
lastIndex = index
barra = barras [ index ]
if ( not barra ) then --se a barra n�o existir, criar ela ent�o
barra = gump : CriaNovaBarraInfo3 ( instancia , index )
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 ) --isso aqui � a parte da sele��o e descele��o
end
barra.show = tabela [ 1 ]
if ( index == 1 ) then
barra.textura : SetValue ( 100 )
else
barra.textura : SetValue ( tabela [ 2 ] / max_ * 100 ) --muito mais rapido...
end
barra.lineText1 : SetText ( index .. " . " .. Details : GetOnlyName ( tabela [ 1 ] ) ) --seta o texto da esqueda
Details : name_space_info ( barra )
if ( spell.total > 0 ) then
barra.lineText4 : SetText ( Details : comma_value ( tabela [ 2 ] ) .. " ( " .. format ( " %.1f " , tabela [ 2 ] / spell.total * 100 ) .. " %) " ) --seta o texto da direita
else
barra.lineText4 : SetText ( tabela [ 2 ] .. " (0%) " ) --seta o texto da direita
end
local texCoords = Details.class_coords [ tabela [ 3 ] ]
if ( not texCoords ) then
texCoords = Details.class_coords [ " UNKNOW " ]
end
local color = Details.class_colors [ tabela [ 3 ] ]
if ( color ) then
barra.textura : SetStatusBarColor ( unpack ( color ) )
else
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 )
end
barra.icone : SetTexture ( " Interface \\ AddOns \\ Details \\ images \\ classes_small_alpha " )
barra.icone : SetTexCoord ( unpack ( texCoords ) )
barra : Show ( ) --mostra a barra
if ( index == 15 ) then
break
end
end
for i = lastIndex + 1 , # barras do
barras [ i ] : Hide ( )
end
end
------ Detalhe Info Damage Taken
function damageClass : MontaDetalhesDamageTaken ( nome , barra )
local barras = breakdownWindowFrame.barras3
local instancia = breakdownWindowFrame.instancia
local tabela_do_combate = breakdownWindowFrame.instancia . showing
local showing = tabela_do_combate [ class_type ] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable
local este_agressor = showing._ActorTable [ showing._NameIndexTable [ nome ] ]
if ( not este_agressor ) then
return
end
local conteudo = este_agressor.spells . _ActorTable --pairs[] com os IDs das magias
local actor = breakdownWindowFrame.jogador . nome
local total = este_agressor.targets [ actor ] or 0
local minhas_magias = { }
for spellid , tabela in pairs ( conteudo ) do --da foreach em cada spellid do container
local este_alvo = tabela.targets [ actor ]
if ( este_alvo ) then --esta magia deu dano no actor
local spell_nome , rank , icone = _GetSpellInfo ( spellid )
tinsert ( minhas_magias , { spellid , este_alvo , este_alvo / total * 100 , spell_nome , icone } )
end
end
_table_sort ( minhas_magias , Details.Sort2 )
--local amt = #minhas_magias
--gump:JI_AtualizaContainerBarras (amt)
local max_ = minhas_magias [ 1 ] and minhas_magias [ 1 ] [ 2 ] or 0 --dano que a primeiro magia vez
local lastIndex = 1
local barra
for index , tabela in ipairs ( minhas_magias ) do
lastIndex = index
barra = barras [ index ]
if ( not barra ) then --se a barra n�o existir, criar ela ent�o
barra = gump : CriaNovaBarraInfo3 ( instancia , index )
barra.textura : SetStatusBarColor ( 1 , 1 , 1 , 1 ) --isso aqui � a parte da sele��o e descele��o
end
barra.show = tabela [ 1 ]
if ( index == 1 ) then
barra.textura : SetValue ( 100 )
else
barra.textura : SetValue ( tabela [ 2 ] / max_ * 100 )
end
barra.lineText1 : SetText ( index .. " . " .. tabela [ 4 ] ) --seta o texto da esqueda
Details : name_space_info ( barra )
barra.lineText4 : SetText ( Details : comma_value ( tabela [ 2 ] ) .. " " .. instancia.divisores . abre .. format ( " %.1f " , tabela [ 3 ] ) .. " % " .. instancia.divisores . fecha ) --seta o texto da direita
barra.icone : SetTexture ( tabela [ 5 ] )
barra.icone : SetTexCoord ( 0 , 1 , 0 , 1 )
barra : Show ( ) --mostra a barra
if ( index == 15 ) then
break
end
end
for i = lastIndex + 1 , # barras do
barras [ i ] : Hide ( )
end
end
------ Detalhe Info Damage Done e Dps
--local defenses_table = {c = {117/255, 58/255, 0/255}, p = 0}
--local normal_table = {c = {255/255, 180/255, 0/255, 0.5}, p = 0}
--local critical_table = {c = {249/255, 74/255, 45/255, 0.5}, p = 0}
local defenses_table = { c = { 1 , 1 , 1 , 0.5 } , p = 0 }
local normal_table = { c = { 1 , 1 , 1 , 0.5 } , p = 0 }
local critical_table = { c = { 1 , 1 , 1 , 0.5 } , p = 0 }
local data_table = { }
local t1 , t2 , t3 , t4 = { } , { } , { } , { }
local function FormatSpellString ( str )
return ( string.gsub ( str , " %d+ " , function ( spellID )
local name , _ , icon = GetSpellInfo ( spellID ) ;
return string.format ( " |T%s:16|t " , icon ) ;
end ) ) ;
end
local MontaDetalhesBuffProcs = function ( actor , row , instance )
instance = instance or breakdownWindowFrame.instancia
local spec = actor.spec
if ( spec ) then
local mainAuras = Details.important_auras [ spec ]
if ( mainAuras ) then
local miscActor = instance : GetShowingCombat ( ) : GetActor ( 4 , actor : name ( ) )
if ( miscActor and miscActor.buff_uptime_spells ) then
--get the auras
local added = 0
for i = 1 , # mainAuras do
local spellID = mainAuras [ i ]
local spellObject = miscActor.buff_uptime_spells . _ActorTable [ spellID ]
if ( spellObject ) then
local spellName , spellIcon = GetSpellInfo ( spellID )
local spellUptime = spellObject.uptime
local spellApplies = spellObject.appliedamt
local spellRefreshes = spellObject.refreshamt
gump : SetaDetalheInfoTexto ( i , 100 , FormatSpellString ( " " .. spellID .. " " .. spellName ) , " Activations: " .. spellApplies , " " , " Refreshes: " .. spellRefreshes , " " , " Uptime: " .. spellUptime .. " s " )
added = added + 1
end
end
for i = added + 1 , 5 do
gump : HidaDetalheInfo ( i )
end
return
end
end
end
for i = 1 , 5 do
gump : HidaDetalheInfo ( i )
end
end
---called from the spell breakdown when a spellbar is hovered over
---@param spellBar breakdownspellbar
---@param spellBlockContainer breakdownspellblockframe
---@param blockIndex number
---@param summaryBlock breakdownspellblock
---@param spellId number
---@param combatTime number
---@param actorName string
---@param spellTable spelltableadv
---@param trinketData trinketdata
---@param combatObject combat
function damageClass : BuildSpellDetails ( spellBar , spellBlockContainer , blockIndex , summaryBlock , spellId , combatTime , actorName , spellTable , trinketData , combatObject )
---@type number
local totalHits = spellTable.counter
--damage section showing damage done sub section
blockIndex = blockIndex + 1
do --update the texts in the summary block
local blockLine1 , blockLine2 , blockLine3 = summaryBlock : GetLines ( )
local totalCasts = spellBar.amountCasts > 0 and spellBar.amountCasts or " (?) "
blockLine1.leftText : SetText ( Loc [ " STRING_CAST " ] .. " : " .. totalCasts ) --total amount of casts
if ( trinketData [ spellId ] and combatObject.trinketProcs ) then
local trinketProcData = combatObject.trinketProcs [ actorName ]
if ( trinketProcData ) then
local trinketProc = trinketProcData [ spellId ]
if ( trinketProc ) then
blockLine1.leftText : SetText ( " Procs: " .. trinketProc.total )
end
end
elseif ( Details.GetItemSpellInfo ( spellId ) ) then
blockLine1.leftText : SetText ( " Uses: " .. totalCasts )
end
blockLine1.rightText : SetText ( Loc [ " STRING_HITS " ] .. " : " .. totalHits ) --hits and uptime
blockLine2.leftText : SetText ( Loc [ " STRING_DAMAGE " ] .. " : " .. Details : Format ( spellTable.total ) ) --total damage
blockLine2.rightText : SetText ( Details : GetSpellSchoolFormatedName ( spellTable.spellschool ) ) --spell school
blockLine3.leftText : SetText ( Loc [ " STRING_AVERAGE " ] .. " : " .. Details : Format ( spellBar.average ) ) --average damage
if ( spellBar.perSecond and spellBar.perSecond > 0 ) then
blockLine3.rightText : SetText ( Loc [ " STRING_DPS " ] .. " : " .. Details : CommaValue ( spellBar.perSecond ) ) --dps
else
blockLine3.rightText : SetText ( Loc [ " STRING_DPS " ] .. " : " .. Details : CommaValue ( spellTable.total / combatTime ) ) --dps
end
end
local emporwerSpell = spellTable.e_total
if ( emporwerSpell ) then
local empowerLevelSum = spellTable.e_total --total sum of empower levels
local empowerAmount = spellTable.e_amt --amount of casts with empower
local empowerAmountPerLevel = spellTable.e_lvl --{[1] = 4; [2] = 9; [3] = 15}
local empowerDamagePerLevel = spellTable.e_dmg --{[1] = 54548745, [2] = 74548745}
---@type breakdownspellblock
local empowerBlock = spellBlockContainer : GetBlock ( blockIndex )
blockIndex = blockIndex + 1
local level1AverageDamage = " 0 "
local level2AverageDamage = " 0 "
local level3AverageDamage = " 0 "
local level4AverageDamage = " 0 "
local level5AverageDamage = " 0 "
if ( empowerDamagePerLevel [ 1 ] ) then
level1AverageDamage = Details : Format ( empowerDamagePerLevel [ 1 ] / empowerAmountPerLevel [ 1 ] )
end
if ( empowerDamagePerLevel [ 2 ] ) then
level2AverageDamage = Details : Format ( empowerDamagePerLevel [ 2 ] / empowerAmountPerLevel [ 2 ] )
end
if ( empowerDamagePerLevel [ 3 ] ) then
level3AverageDamage = Details : Format ( empowerDamagePerLevel [ 3 ] / empowerAmountPerLevel [ 3 ] )
end
if ( empowerDamagePerLevel [ 4 ] ) then
level4AverageDamage = Details : Format ( empowerDamagePerLevel [ 4 ] / empowerAmountPerLevel [ 4 ] )
end
if ( empowerDamagePerLevel [ 5 ] ) then
level5AverageDamage = Details : Format ( empowerDamagePerLevel [ 5 ] / empowerAmountPerLevel [ 5 ] )
end
empowerBlock : Show ( )
empowerBlock : SetValue ( 100 )
empowerBlock.sparkTexture : SetPoint ( " left " , empowerBlock , " left " , empowerBlock : GetWidth ( ) + Details.breakdown_spell_tab . blockspell_spark_offset , 0 )
empowerBlock : SetColor ( 0.200 , 0.576 , 0.498 , 0.6 )
local blockLine1 , blockLine2 , blockLine3 = empowerBlock : GetLines ( )
blockLine1.leftText : SetText ( " Spell Empower Average Level: " .. string.format ( " %.2f " , empowerLevelSum / empowerAmount ) )
if ( level1AverageDamage ~= " 0 " ) then
blockLine2.leftText : SetText ( " #1 Avg: " .. level1AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 1 ] or 0 ) .. " ) " )
end
if ( level2AverageDamage ~= " 0 " ) then
blockLine2.centerText : SetText ( " #2 Avg: " .. level2AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 2 ] or 0 ) .. " ) " )
end
if ( level3AverageDamage ~= " 0 " ) then
blockLine2.rightText : SetText ( " #3 Avg: " .. level3AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 3 ] or 0 ) .. " ) " )
end
if ( level4AverageDamage ~= " 0 " ) then
blockLine3.leftText : SetText ( " #4 Avg: " .. level4AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 4 ] or 0 ) .. " ) " )
end
if ( level5AverageDamage ~= " 0 " ) then
blockLine3.rightText : SetText ( " #5 Avg: " .. level5AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 5 ] or 0 ) .. " ) " )
end
end
--check if there's normal hits and build the block
---@type number
local normalHitsAmt = spellTable.n_amt
if ( normalHitsAmt > 0 ) then
---@type breakdownspellblock
local normalHitsBlock = spellBlockContainer : GetBlock ( blockIndex )
normalHitsBlock : Show ( )
blockIndex = blockIndex + 1
local percent = normalHitsAmt / math.max ( totalHits , 0.0001 ) * 100
normalHitsBlock : SetValue ( percent )
normalHitsBlock.sparkTexture : SetPoint ( " left " , normalHitsBlock , " left " , percent / 100 * normalHitsBlock : GetWidth ( ) + Details.breakdown_spell_tab . blockspell_spark_offset , 0 )
local blockLine1 , blockLine2 , blockLine3 = normalHitsBlock : GetLines ( )
blockLine1.leftText : SetText ( Loc [ " STRING_NORMAL_HITS " ] )
blockLine1.rightText : SetText ( normalHitsAmt .. " [|cFFC0C0C0 " .. string.format ( " %.1f " , normalHitsAmt / math.max ( totalHits , 0.0001 ) * 100 ) .. " %|r] " )
blockLine2.leftText : SetText ( Loc [ " STRING_MINIMUM_SHORT " ] .. " : " .. Details : CommaValue ( spellTable.n_min ) )
blockLine2.rightText : SetText ( Loc [ " STRING_MAXIMUM_SHORT " ] .. " : " .. Details : CommaValue ( spellTable.n_max ) )
local normalAverage = spellTable.n_total / math.max ( normalHitsAmt , 0.0001 )
blockLine3.leftText : SetText ( Loc [ " STRING_AVERAGE " ] .. " : " .. Details : CommaValue ( normalAverage ) )
local tempo = ( combatTime * spellTable.n_total ) / math.max ( spellTable.total , 0.001 )
local normalAveragePercent = spellBar.average / normalAverage * 100
local normalTempoPercent = normalAveragePercent * tempo / 100
blockLine3.rightText : SetText ( Loc [ " STRING_DPS " ] .. " : " .. Details : CommaValue ( spellTable.n_total / normalTempoPercent ) )
end
---@type number
local criticalHitsAmt = spellTable.c_amt
if ( criticalHitsAmt > 0 ) then
---@type breakdownspellblock
local critHitsBlock = spellBlockContainer : GetBlock ( blockIndex )
critHitsBlock : Show ( )
blockIndex = blockIndex + 1
local percent = Details.SpellTableMixin . GetCritPercent ( spellTable )
critHitsBlock : SetValue ( percent )
critHitsBlock.sparkTexture : SetPoint ( " left " , critHitsBlock , " left " , percent / 100 * critHitsBlock : GetWidth ( ) + Details.breakdown_spell_tab . blockspell_spark_offset , 0 )
local blockLine1 , blockLine2 , blockLine3 = critHitsBlock : GetLines ( )
blockLine1.leftText : SetText ( Loc [ " STRING_CRITICAL_HITS " ] )
blockLine1.rightText : SetText ( criticalHitsAmt .. " [|cFFC0C0C0 " .. string.format ( " %.1f " , criticalHitsAmt / math.max ( totalHits , 0.0001 ) * 100 ) .. " %|r] " )
blockLine2.leftText : SetText ( Loc [ " STRING_MINIMUM_SHORT " ] .. " : " .. Details : CommaValue ( spellTable.c_min ) )
blockLine2.rightText : SetText ( Loc [ " STRING_MAXIMUM_SHORT " ] .. " : " .. Details : CommaValue ( spellTable.c_max ) )
local critAverage = Details.SpellTableMixin . GetCritAverage ( spellTable )
blockLine3.leftText : SetText ( Loc [ " STRING_AVERAGE " ] .. " : " .. Details : CommaValue ( critAverage ) )
local tempo = ( combatTime * spellTable.c_total ) / math.max ( spellTable.total , 0.001 )
local critAveragePercent = spellBar.average / critAverage * 100
local critTempoPercent = critAveragePercent * tempo / 100
blockLine3.rightText : SetText ( Loc [ " STRING_DPS " ] .. " : " .. Details : CommaValue ( spellTable.c_total / critTempoPercent ) )
end
--missing hits
local semiDodgeAmount = spellTable.g_amt + spellTable.b_amt --glancing and blocking
local fullDodgeAmount = spellTable [ " DODGE " ] or 0
local parryAmount = spellTable [ " PARRY " ] or 0
local missedHitsAmount = spellTable [ " MISS " ] or 0
local hitErrorsAmount = parryAmount + fullDodgeAmount + missedHitsAmount
if ( semiDodgeAmount > 0 or hitErrorsAmount > 0 ) then
---@type breakdownspellblock
local defensesBlock = spellBlockContainer : GetBlock ( blockIndex )
defensesBlock : Show ( )
blockIndex = blockIndex + 1
local percent = ( semiDodgeAmount + hitErrorsAmount ) / spellTable.counter * 100
defensesBlock : SetValue ( percent )
defensesBlock.sparkTexture : SetPoint ( " left " , defensesBlock , " left " , percent / 100 * defensesBlock : GetWidth ( ) + Details.breakdown_spell_tab . blockspell_spark_offset , 0 )
local blockLine1 , blockLine2 , blockLine3 = defensesBlock : GetLines ( )
blockLine1.leftText : SetText ( Loc [ " STRING_DEFENSES " ] )
blockLine1.rightText : SetText ( ( semiDodgeAmount + hitErrorsAmount ) .. " / " .. format ( " %.1f " , percent ) .. " % " )
if ( missedHitsAmount > 0 ) then
blockLine2.leftText : SetText ( " Miss " .. " : " .. missedHitsAmount )
end
if ( parryAmount > 0 ) then
blockLine2.centerText : SetText ( Loc [ " STRING_PARRY " ] .. " : " .. parryAmount )
end
if ( fullDodgeAmount > 0 ) then
blockLine2.rightText : SetText ( Loc [ " STRING_DODGE " ] .. " : " .. fullDodgeAmount )
end
if ( spellTable.b_amt > 0 ) then
blockLine3.leftText : SetText ( Loc [ " STRING_BLOCKED " ] .. " : " .. spellTable.b_amt )
end
if ( spellTable.g_amt > 0 ) then
blockLine3.rightText : SetText ( Loc [ " STRING_GLANCING " ] .. " : " .. spellTable.g_amt )
end
end
--[=[ percent
Loc [ " STRING_GLANCING " ] .. " : " .. math.floor ( spellTable.g_amt / spellTable.counter * 100 ) .. " % "
Loc [ " STRING_BLOCKED " ] .. " : " .. math.floor ( spellTable.b_amt / spellTable.counter * 100 ) .. " % "
--]=]
if ( trinketData [ spellId ] ) then
---@type trinketdata
local trinketInfo = trinketData [ spellId ]
local minTime = trinketInfo.minTime
local maxTime = trinketInfo.maxTime
local average = trinketInfo.averageTime
---@type breakdownspellblock
local trinketBlock = spellBlockContainer : GetBlock ( blockIndex )
trinketBlock : Show ( )
trinketBlock : SetValue ( 100 )
trinketBlock.sparkTexture : SetPoint ( " left " , trinketBlock , " left " , trinketBlock : GetWidth ( ) + Details.breakdown_spell_tab . blockspell_spark_offset , 0 )
blockIndex = blockIndex + 1
local blockLine1 , blockLine2 , blockLine3 = trinketBlock : GetLines ( )
blockLine1.leftText : SetText ( " Trinket Info " )
blockLine1.rightText : SetText ( " PPM: " .. string.format ( " %.2f " , average / 60 ) )
if ( minTime == 9999999 ) then
blockLine2.leftText : SetText ( " Min Time: " .. _G [ " UNKNOWN " ] )
else
blockLine2.leftText : SetText ( " Min Time: " .. math.floor ( minTime ) )
end
blockLine2.rightText : SetText ( " Max Time: " .. math.floor ( maxTime ) )
end
end
--this build p the 6 rectangle boxes in the right side of the breakdown window summary tab
function damageClass : MontaDetalhesDamageDone ( spellId , spellLine , instance ) --this should be ~deprecated with the new breakdown tab
print ( " MontaDetalhesDamageDone - deprecated " , debugstack ( ) )
local spellTable
if ( spellLine.other_actor ) then
spellTable = spellLine.other_actor . spells._ActorTable [ spellId ]
--self = spellLine.other_actor
else
spellTable = self.spells . _ActorTable [ spellId ]
end
if ( spellId == - 51 ) then
return MontaDetalhesBuffProcs ( self , spellLine , instance )
end
if ( not spellTable ) then
return
end
local spellName , _ , icone = _GetSpellInfo ( spellId )
local bShouldMergePlayerAbilities = Details.merge_player_abilities
local bShouldMergePetAbilities = Details.merge_pet_abilities
if ( bShouldMergePlayerAbilities or bShouldMergePetAbilities ) then
local mergedSpellTable = getSpellDetails ( self : GetGUID ( ) , spellName ) --it's not merging
if ( mergedSpellTable ) then
spellTable = mergedSpellTable
end
end
Details.BreakdownWindowFrame . spell_icone : SetTexture ( icone )
local total = self.total
local meu_tempo
if ( Details.time_type == 1 or not self.grupo ) then
meu_tempo = self : Tempo ( )
elseif ( Details.time_type == 2 or Details.use_realtimedps ) then
meu_tempo = breakdownWindowFrame.instancia . showing : GetCombatTime ( )
end
local total_hits = spellTable.counter
local index = 1
local data = data_table
Details : Destroy ( t1 )
Details : Destroy ( t2 )
Details : Destroy ( t3 )
Details : Destroy ( t4 )
Details : Destroy ( data )
--GERAL
local media = 0
if ( total_hits > 0 ) then
media = spellTable.total / total_hits
end
local this_dps = nil
if ( spellTable.counter > spellTable.c_amt ) then
this_dps = Loc [ " STRING_DPS " ] .. " : " .. Details : comma_value ( spellTable.total / meu_tempo )
else
this_dps = Loc [ " STRING_DPS " ] .. " : " .. Loc [ " STRING_SEE_BELOW " ]
end
local spellschool , schooltext = spellTable.spellschool , " "
if ( spellschool ) then
local t = Details.spells_school [ spellschool ]
if ( t and t.name ) then
schooltext = t.formated
end
end
local hits_string = " " .. total_hits
local cast_string = Loc [ " STRING_CAST " ] .. " : "
local misc_actor = breakdownWindowFrame.instancia . showing ( 4 , self : name ( ) )
if ( misc_actor ) then
local uptime_spellid = spellTable.id
local debuff_uptime = misc_actor.debuff_uptime_spells and misc_actor.debuff_uptime_spells . _ActorTable [ uptime_spellid ] and misc_actor.debuff_uptime_spells . _ActorTable [ uptime_spellid ] . uptime
if ( debuff_uptime ) then
hits_string = hits_string .. " |cFFDDDD44( " .. _math_floor ( debuff_uptime / breakdownWindowFrame.instancia . showing : GetCombatTime ( ) * 100 ) .. " % uptime)|r "
end
local amountOfCasts = breakdownWindowFrame.instancia . showing : GetSpellCastAmount ( self : Name ( ) , spellName )
if ( amountOfCasts == 0 ) then
amountOfCasts = " (|cFFFFFF00?|r) "
end
cast_string = cast_string .. amountOfCasts
end
if ( spellTable.e_total ) then
cast_string = Loc [ " STRING_CAST " ] .. " : " .. " |cFFFFFF00 " .. spellTable.e_total .. " |r "
end
gump : SetaDetalheInfoTexto ( index , 100 ,
cast_string ,
Loc [ " STRING_DAMAGE " ] .. " : " .. Details : ToK ( spellTable.total ) ,
schooltext , --offhand,
Loc [ " STRING_AVERAGE " ] .. " : " .. Details : comma_value ( media ) ,
this_dps ,
Loc [ " STRING_HITS " ] .. " : " .. hits_string
)
--NORMAL
local normal_hits = spellTable.n_amt
if ( normal_hits > 0 ) then
local normal_dmg = spellTable.n_total
local media_normal = normal_dmg / normal_hits
local T = ( meu_tempo * normal_dmg ) / max ( spellTable.total , 0.001 )
local P = media / media_normal * 100
T = P * T / 100
normal_table.p = normal_hits / total_hits * 100
data [ # data + 1 ] = t1
t1 [ 1 ] = spellTable.n_amt
t1 [ 2 ] = normal_table
t1 [ 3 ] = Loc [ " STRING_NORMAL_HITS " ]
t1 [ 4 ] = Loc [ " STRING_MINIMUM_SHORT " ] .. " : " .. Details : comma_value ( spellTable.n_min )
t1 [ 5 ] = Loc [ " STRING_MAXIMUM_SHORT " ] .. " : " .. Details : comma_value ( spellTable.n_max )
t1 [ 6 ] = Loc [ " STRING_AVERAGE " ] .. " : " .. Details : comma_value ( media_normal )
t1 [ 7 ] = Loc [ " STRING_DPS " ] .. " : " .. Details : comma_value ( normal_dmg / T )
t1 [ 8 ] = normal_hits .. " [|cFFC0C0C0 " .. format ( " %.1f " , normal_hits / max ( total_hits , 0.0001 ) * 100 ) .. " %|r] "
t1 [ 9 ] = " "
end
--CRITICO
if ( spellTable.c_amt > 0 ) then
local media_critico = spellTable.c_total / spellTable.c_amt
local T = ( meu_tempo * spellTable.c_total ) / spellTable.total
local P = media / max ( media_critico , 0.0001 ) * 100
T = P * T / 100
local crit_dps = spellTable.c_total / T
if ( not crit_dps ) then
crit_dps = 0
end
critical_table.p = spellTable.c_amt / total_hits * 100
data [ # data + 1 ] = t2
t2 [ 1 ] = spellTable.c_amt
t2 [ 2 ] = critical_table
t2 [ 3 ] = Loc [ " STRING_CRITICAL_HITS " ]
t2 [ 4 ] = Loc [ " STRING_MINIMUM_SHORT " ] .. " : " .. Details : comma_value ( spellTable.c_min )
t2 [ 5 ] = Loc [ " STRING_MAXIMUM_SHORT " ] .. " : " .. Details : comma_value ( spellTable.c_max )
t2 [ 6 ] = Loc [ " STRING_AVERAGE " ] .. " : " .. Details : comma_value ( media_critico )
t2 [ 7 ] = Loc [ " STRING_DPS " ] .. " : " .. Details : comma_value ( crit_dps )
t2 [ 8 ] = spellTable.c_amt .. " [|cFFC0C0C0 " .. format ( " %.1f " , spellTable.c_amt / total_hits * 100 ) .. " %|r] "
t2 [ 9 ] = " "
end
--Outros erros: GLACING, resisted, blocked, absorbed
local outros_desvios = spellTable.g_amt + spellTable.b_amt
local parry = spellTable [ " PARRY " ] or 0
local dodge = spellTable [ " DODGE " ] or 0
local misses = spellTable [ " MISS " ] or 0
local erros = parry + dodge + misses
if ( outros_desvios > 0 or erros > 0 ) then
local porcentagem_defesas = ( outros_desvios + erros ) / total_hits * 100
data [ # data + 1 ] = t3
defenses_table.p = porcentagem_defesas
t3 [ 1 ] = outros_desvios + erros
t3 [ 2 ] = defenses_table
t3 [ 3 ] = Loc [ " STRING_DEFENSES " ]
t3 [ 4 ] = Loc [ " STRING_GLANCING " ] .. " : " .. _math_floor ( spellTable.g_amt / spellTable.counter * 100 ) .. " % "
t3 [ 5 ] = Loc [ " STRING_PARRY " ] .. " : " .. parry
t3 [ 6 ] = Loc [ " STRING_DODGE " ] .. " : " .. dodge
t3 [ 7 ] = Loc [ " STRING_BLOCKED " ] .. " : " .. _math_floor ( spellTable.b_amt / spellTable.counter * 100 )
t3 [ 8 ] = ( outros_desvios + erros ) .. " / " .. format ( " %.1f " , porcentagem_defesas ) .. " % "
t3 [ 9 ] = " MISS " .. " : " .. misses
end
--~empowered
if ( spellTable.e_total ) then
local empowerLevelSum = spellTable.e_total --total sum of empower levels
local empowerAmount = spellTable.e_amt --amount of casts with empower
local empowerAmountPerLevel = spellTable.e_lvl --{[1] = 4; [2] = 9; [3] = 15}
local empowerDamagePerLevel = spellTable.e_dmg --{[1] = 54548745, [2] = 74548745}
data [ # data + 1 ] = t4
local level1AverageDamage = " 0 "
local level2AverageDamage = " 0 "
local level3AverageDamage = " 0 "
local level4AverageDamage = " 0 "
local level5AverageDamage = " 0 "
if ( empowerDamagePerLevel [ 1 ] ) then
level1AverageDamage = Details : ToK ( empowerDamagePerLevel [ 1 ] / empowerAmountPerLevel [ 1 ] )
end
if ( empowerDamagePerLevel [ 2 ] ) then
level2AverageDamage = Details : ToK ( empowerDamagePerLevel [ 2 ] / empowerAmountPerLevel [ 2 ] )
end
if ( empowerDamagePerLevel [ 3 ] ) then
level3AverageDamage = Details : ToK ( empowerDamagePerLevel [ 3 ] / empowerAmountPerLevel [ 3 ] )
end
if ( empowerDamagePerLevel [ 4 ] ) then
level4AverageDamage = Details : ToK ( empowerDamagePerLevel [ 4 ] / empowerAmountPerLevel [ 4 ] )
end
if ( empowerDamagePerLevel [ 5 ] ) then
level5AverageDamage = Details : ToK ( empowerDamagePerLevel [ 5 ] / empowerAmountPerLevel [ 5 ] )
end
t4 [ 1 ] = 0
t4 [ 2 ] = { p = 100 , c = { 0.200 , 0.576 , 0.498 , 0.6 } }
t4 [ 3 ] = " Spell Empower Average Level: " .. format ( " %.2f " , empowerLevelSum / empowerAmount )
t4 [ 4 ] = " "
t4 [ 5 ] = " "
t4 [ 6 ] = " "
t4 [ 10 ] = " "
t4 [ 11 ] = " "
if ( level1AverageDamage ~= " 0 " ) then
t4 [ 4 ] = " Level 1 Avg: " .. level1AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 1 ] or 0 ) .. " ) "
end
if ( level2AverageDamage ~= " 0 " ) then
t4 [ 6 ] = " Level 2 Avg: " .. level2AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 2 ] or 0 ) .. " ) "
end
if ( level3AverageDamage ~= " 0 " ) then
t4 [ 11 ] = " Level 3 Avg: " .. level3AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 3 ] or 0 ) .. " ) "
end
if ( level4AverageDamage ~= " 0 " ) then
t4 [ 10 ] = " Level 4 Avg: " .. level4AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 4 ] or 0 ) .. " ) "
end
if ( level5AverageDamage ~= " 0 " ) then
t4 [ 5 ] = " Level 5 Avg: " .. level5AverageDamage .. " ( " .. ( empowerAmountPerLevel [ 5 ] or 0 ) .. " ) "
end
end
--Details:BuildPlayerDetailsSpellChart()
--DetailsPlayerDetailSmallChart.ShowChart (Details.BreakdownWindowFrame.grupos_detalhes [5].bg, info.instancia.showing, info.instancia.showing.cleu_events, self.nome, false, spellid, 1, 2, 3, 4, 5, 6, 7, 8, 15)
--spell damage chart
--events: 1 2 3 4 5 6 7 8 15
local spellTable = spellTable
local blockId = 6
if false then --debug the stuff for the chart damage done in the 6th spellblock
--GetBlockIndex doesn't exists anymore
local thatRectangle66 = Details222.BreakdownWindow . GetBlockIndex ( blockId )
thatRectangle66 = thatRectangle66 : GetFrame ( )
--hide all textures created
if ( thatRectangle66.ChartTextures ) then
for i = 1 , # thatRectangle66.ChartTextures do
thatRectangle66.ChartTextures [ i ] : Hide ( )
end
end
local chartData = Details222.TimeCapture . GetChartDataFromSpell ( spellTable )
if ( chartData and instance ) then
local width , height = thatRectangle66 : GetSize ( )
--reset which texture is the next to be used
thatRectangle66.nextChartTextureId = 1
local amountOfTimeStamps = 12
if ( not thatRectangle66.timeStamps ) then
thatRectangle66.timeStamps = { }
for i = 1 , amountOfTimeStamps do
thatRectangle66.timeStamps [ i ] = thatRectangle66 : CreateFontString ( nil , " overlay " , " GameFontNormal " )
thatRectangle66.timeStamps [ i ] : SetPoint ( " topleft " , thatRectangle66 , " topleft " , 2 + ( i - 1 ) * ( width / amountOfTimeStamps ) , - 2 )
DetailsFramework : SetFontSize ( thatRectangle66.timeStamps [ i ] , 9 )
end
end
if ( not thatRectangle66.bloodLustIndicators ) then
thatRectangle66.bloodLustIndicators = { }
for i = 1 , 5 do
local thisIndicator = thatRectangle66 : CreateTexture ( nil , " artwork " , nil , 4 )
thisIndicator : SetColorTexture ( 0.0980392 , 0.0980392 , 0.439216 )
thatRectangle66.bloodLustIndicators [ # thatRectangle66.bloodLustIndicators + 1 ] = thisIndicator
end
end
for i = 1 , # thatRectangle66.bloodLustIndicators do
thatRectangle66.bloodLustIndicators [ i ] : Hide ( )
end
if ( not thatRectangle66.ChartTextures ) then
thatRectangle66.ChartTextures = { }
function thatRectangle66 : GetChartTexture ( )
local thisTexture = thatRectangle66.ChartTextures [ thatRectangle66.nextChartTextureId ]
if ( not thisTexture ) then
thisTexture = thatRectangle66 : CreateTexture ( nil , " artwork " , nil , 5 )
thisTexture : SetColorTexture ( 1 , 1 , 1 , 0.65 )
thatRectangle66.ChartTextures [ thatRectangle66.nextChartTextureId ] = thisTexture
end
thatRectangle66.nextChartTextureId = thatRectangle66.nextChartTextureId + 1
return thisTexture
end
end
--elapsed combat time
local combatObject = instance : GetShowingCombat ( )
local combatTime = math.floor ( combatObject : GetCombatTime ( ) )
thatRectangle66.timeStamps [ 1 ] : SetText ( DetailsFramework : IntegerToTimer ( 0 ) )
for i = 2 , # thatRectangle66.timeStamps do
local timePerSegment = combatTime / # thatRectangle66.timeStamps
thatRectangle66.timeStamps [ i ] : SetText ( DetailsFramework : IntegerToTimer ( i * timePerSegment ) )
end
--compute the width oif each texture
local textureWidth = width / combatTime
--compute the max height of a texture can have
local maxValue = 0
local numData = 0
--need to put the data in order FIRST
--each damage then need to be parsed
local dataInOrder = { }
local CONST_INDEX_TIMESTAMP = 1
local CONST_INDEX_DAMAGEDONE = 2
local CONST_INDEX_EVENTDAMAGE = 3
for timeStamp , value in pairs ( chartData ) do
dataInOrder [ # dataInOrder + 1 ] = { timeStamp , value }
dataInOrder [ # dataInOrder + 1 ] = { timeStamp , value }
dataInOrder [ # dataInOrder + 1 ] = { timeStamp , value }
numData = numData + 1
end
table.sort ( dataInOrder , function ( t1 , t2 ) return t1 [ CONST_INDEX_TIMESTAMP ] < t2 [ CONST_INDEX_TIMESTAMP ] end )
local damageDoneByTime = dataInOrder
--parser the damage done
local currentTotalDamage = 0
for i = 1 , # damageDoneByTime do
local damageEvent = damageDoneByTime [ i ]
local atTime = damageEvent [ CONST_INDEX_TIMESTAMP ]
local totalDamageUntilHere = damageEvent [ CONST_INDEX_DAMAGEDONE ] --raw damage
local spellDamage = totalDamageUntilHere - currentTotalDamage
currentTotalDamage = currentTotalDamage + spellDamage
damageEvent [ CONST_INDEX_EVENTDAMAGE ] = spellDamage
maxValue = math.max ( spellDamage , maxValue )
end
--build the chart
for i = 1 , # damageDoneByTime do
--for timeStamp, value in pairs(chartData) do --as it is pairs the data is scattered
local damageEvent = damageDoneByTime [ i ]
local timeStamp = damageEvent [ CONST_INDEX_TIMESTAMP ]
local damageDone = damageEvent [ CONST_INDEX_EVENTDAMAGE ]
local thisTexture = thatRectangle66 : GetChartTexture ( )
thisTexture : SetWidth ( textureWidth )
local texturePosition = textureWidth * timeStamp
thisTexture : SetPoint ( " bottomleft " , thatRectangle66 , " bottomleft " , 1 + texturePosition , 1 )
local percentFromPeak = damageDone / maxValue --normalized
thisTexture : SetHeight ( math.min ( percentFromPeak * height , height - 15 ) )
thisTexture : Show ( )
end
--show bloodlust indicators, member .bloodlust is not guarantted
if ( combatObject.bloodlust ) then
--bloodlust not being added into the combat object, probably a bug on Parser
local bloodlustDuration = 40
for i = 1 , # combatObject.bloodlust do
thatRectangle66.bloodLustIndicators [ i ] : Show ( )
thatRectangle66.bloodLustIndicators [ i ] : SetAlpha ( 0.46 )
thatRectangle66.bloodLustIndicators [ i ] : SetSize ( bloodlustDuration / combatTime * width , height - 2 )
thatRectangle66.bloodLustIndicators [ i ] : SetPoint ( " bottomleft " , thatRectangle66 , " bottomleft " , 0 , 0 )
end
end
DetailsBreakdownWindow_DetalheInfoBG_bg_end6 : Hide ( )
thatRectangle66 : SetShown ( true )
end
end
_table_sort ( data , Details.Sort1 )
for index , tabela in ipairs ( data ) do
gump : SetaDetalheInfoTexto ( index + 1 , tabela [ 2 ] , tabela [ 3 ] , tabela [ 4 ] , tabela [ 5 ] , tabela [ 6 ] , tabela [ 7 ] , tabela [ 8 ] , tabela [ 9 ] , tabela [ 10 ] , tabela [ 11 ] , tabela [ 12 ] )
end
for i = # data + 2 , 5 do
gump : HidaDetalheInfo ( i )
end
end
function Details : BuildPlayerDetailsSpellChart ( )
local playerDetailSmallChart = DetailsPlayerDetailSmallChart
if ( not playerDetailSmallChart ) then
playerDetailSmallChart = CreateFrame ( " frame " , " DetailsPlayerDetailSmallChart " , breakdownWindowFrame , " BackdropTemplate " )
DetailsFramework : ApplyStandardBackdrop ( playerDetailSmallChart )
playerDetailSmallChart.Lines = { }
for i = 1 , 200 do
local texture = playerDetailSmallChart : CreateTexture ( nil , " artwork " )
texture : SetColorTexture ( 1 , 1 , 1 , 1 )
tinsert ( playerDetailSmallChart.Lines , texture )
end
--Details.BreakdownWindowFrame.grupos_detalhes [index]
function playerDetailSmallChart . ShowChart ( parent , combatObject , cleuData , playerName , targetName , spellId , ... )
local tokenIdList = { }
local eventList = { }
--build the list of tokens
for i = 1 , select ( " # " , ... ) do
local tokenId = select ( i , ... )
tokenIdList [ tokenId ] = true
end
--check which lines can be added
local index = 1
local peakValue = 0
for i = 1 , cleuData.n - 1 do
local event = cleuData [ i ]
if ( event [ 2 ] ) then --index 2 = token
local playerNameFilter = playerName and playerName == event [ 3 ]
local targetNameFilter = targetName and targetName == event [ 4 ]
local spellIdFilter = spellId and spellId == event [ 5 ]
if ( playerNameFilter or targetNameFilter or spellIdFilter ) then
eventList [ index ] = cleuData [ i ]
if ( peakValue < cleuData [ i ] [ 6 ] ) then
peakValue = cleuData [ i ] [ 6 ]
end
index = index + 1
end
end
end
--200 lines, adjust the mini chart
playerDetailSmallChart : SetPoint ( " topleft " , parent , " topleft " )
playerDetailSmallChart : SetPoint ( " bottomright " , parent , " bottomright " )
--update lines
local width = playerDetailSmallChart : GetWidth ( )
local combatTime = combatObject : GetCombatTime ( )
local secondsPerBar = combatTime / 200
local barWidth = width / 200
local barHeight = playerDetailSmallChart : GetHeight ( )
local currentTime = eventList [ 1 ] [ 1 ]
local currentIndex = 1
local eventAmount = # eventList
for i = 1 , # playerDetailSmallChart.Lines do
playerDetailSmallChart.Lines [ i ] : SetWidth ( width / 200 )
playerDetailSmallChart.Lines [ i ] : SetHeight ( 1 )
for o = currentIndex , eventAmount do
if ( eventList [ o ] [ 1 ] <= currentTime + secondsPerBar or eventList [ o ] [ 1 ] >= currentTime ) then
playerDetailSmallChart.Lines [ i ] : SetPoint ( " bottomleft " , playerDetailSmallChart , " bottomleft " , barWidth * ( i - 1 ) , 0 )
playerDetailSmallChart.Lines [ i ] : SetWidth ( barWidth )
playerDetailSmallChart.Lines [ i ] : SetHeight ( eventList [ o ] [ 6 ] / peakValue * barHeight )
else
currentIndex = o
break
end
end
currentTime = currentTime + secondsPerBar
end
end
end
end
function damageClass : MontaTooltipDamageTaken ( thisLine , index )
local aggressor = breakdownWindowFrame.instancia . showing [ 1 ] : PegarCombatente ( _ , thisLine.nome_inimigo )
local container = aggressor.spells . _ActorTable
local habilidades = { }
local total = 0
for spellid , spell in pairs ( container ) do
for target_name , amount in pairs ( spell.targets ) do
if ( target_name == self.nome ) then
total = total + amount
habilidades [ # habilidades + 1 ] = { spellid , amount }
end
end
end
_table_sort ( habilidades , Details.Sort2 )
GameTooltip : AddLine ( index .. " . " .. thisLine.nome_inimigo )
GameTooltip : AddLine ( Loc [ " STRING_DAMAGE_TAKEN_FROM2 " ] .. " : " )
GameTooltip : AddLine ( " " )
for index , tabela in ipairs ( habilidades ) do
local nome , _ , icone = _GetSpellInfo ( tabela [ 1 ] )
if ( index < 8 ) then
GameTooltip : AddDoubleLine ( index .. " . |T " .. icone .. " :0|t " .. nome , Details : comma_value ( tabela [ 2 ] ) .. " ( " .. format ( " %.1f " , tabela [ 2 ] / total * 100 ) .. " %) " , 1 , 1 , 1 , 1 , 1 , 1 )
else
GameTooltip : AddDoubleLine ( index .. " . " .. nome , Details : comma_value ( tabela [ 2 ] ) .. " ( " .. format ( " %.1f " , tabela [ 2 ] / total * 100 ) .. " %) " , .65 , .65 , .65 , .65 , .65 , .65 )
end
end
return true
--GameTooltip:AddDoubleLine (meus_danos[i][4][1]..": ", meus_danos[i][2].." (".._cstr("%.1f", meus_danos[i][3]).."%)", 1, 1, 1, 1, 1, 1)
end
function damageClass : MontaTooltipAlvos ( thisLine , index , instancia ) --~deprecated
local inimigo = thisLine.nome_inimigo
local habilidades = { }
local total = self.total
local i = 1
Details : FormatCooltipForSpells ( )
GameCooltip : SetOwner ( thisLine , " bottom " , " top " , 4 , - 2 )
GameCooltip : SetOption ( " MinWidth " , _math_max ( 230 , thisLine : GetWidth ( ) * 0.98 ) )
for spellid , spell in pairs ( self.spells . _ActorTable ) do
if ( spell.isReflection ) then
for target_name , amount in pairs ( spell.targets ) do
if ( target_name == inimigo ) then
for reflectedSpellId , amount in pairs ( spell.extra ) do
local spellName , _ , spellIcon = _GetSpellInfo ( reflectedSpellId )
local t = habilidades [ i ]
if ( not t ) then
habilidades [ i ] = { }
t = habilidades [ i ]
end
t [ 1 ] , t [ 2 ] , t [ 3 ] = spellName .. " (|cFFCCBBBBreflected|r) " , amount , spellIcon
i = i + 1
end
end
end
else
for target_name , amount in pairs ( spell.targets ) do
if ( target_name == inimigo ) then
local nome , _ , icone = _GetSpellInfo ( spellid )
local t = habilidades [ i ]
if ( not t ) then
habilidades [ i ] = { }
t = habilidades [ i ]
end
t [ 1 ] , t [ 2 ] , t [ 3 ] = nome , amount , icone
i = i + 1
end
end
end
end
--add pets
for _ , PetName in ipairs ( self.pets ) do
local PetActor = instancia.showing ( class_type , PetName )
if ( PetActor ) then
local PetSkillsContainer = PetActor.spells . _ActorTable
for _spellid , _skill in pairs ( PetSkillsContainer ) do
local alvos = _skill.targets
for target_name , amount in pairs ( alvos ) do
if ( target_name == inimigo ) then
local t = habilidades [ i ]
if ( not t ) then
habilidades [ i ] = { }
t = habilidades [ i ]
end
local nome , _ , icone = _GetSpellInfo ( _spellid )
t [ 1 ] , t [ 2 ] , t [ 3 ] = nome .. " ( " .. PetName : gsub ( ( " <.* " ) , " " ) .. " ) " , amount , icone
i = i + 1
end
end
end
end
end
_table_sort ( habilidades , Details.Sort2 )
--get time type
local meu_tempo
if ( Details.time_type == 1 or not self.grupo ) then
meu_tempo = self : Tempo ( )
elseif ( Details.time_type == 2 or Details.use_realtimedps ) then
meu_tempo = breakdownWindowFrame.instancia . showing : GetCombatTime ( )
end
local is_dps = breakdownWindowFrame.instancia . sub_atributo == 2
if ( is_dps ) then
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_DAMAGE_DPS_IN " ] .. " : " , { 1 , 0.9 , 0.0 , 1 } , 1 , Details.tooltip_spell_icon . file , unpack ( Details.tooltip_spell_icon . coords ) )
Details : AddTooltipHeaderStatusbar ( 1 , 1 , 1 , 1 )
else
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_DAMAGE_FROM " ] .. " : " , { 1 , 0.9 , 0.0 , 1 } , 1 , Details.tooltip_spell_icon . file , unpack ( Details.tooltip_spell_icon . coords ) )
Details : AddTooltipHeaderStatusbar ( 1 , 1 , 1 , 1 )
end
local icon_size = Details.tooltip . icon_size
local icon_border = Details.tooltip . icon_border_texcoord
local topSpellDamage = habilidades [ 1 ] and habilidades [ 1 ] [ 2 ]
if ( topSpellDamage ) then
for index , tabela in ipairs ( habilidades ) do
if ( tabela [ 2 ] < 1 ) then
break
end
if ( is_dps ) then
--GameCooltip:AddDoubleLine (index..". |T"..tabela[3]..":0|t "..tabela[1], Details:comma_value ( _math_floor(tabela[2] / meu_tempo) ).." (".._cstr("%.1f", tabela[2]/total*100).."%)", 1, 1, 1, 1, 1, 1)
GameCooltip : AddLine ( tabela [ 1 ] , Details : comma_value ( _math_floor ( tabela [ 2 ] / meu_tempo ) ) .. " ( " .. format ( " %.1f " , tabela [ 2 ] / total * 100 ) .. " %) " )
else
--GameCooltip:AddDoubleLine (index..". |T"..tabela[3]..":0|t " .. tabela[1], SelectedToKFunction(_, tabela[2]) .. " (".._cstr("%.1f", tabela[2]/total*100).."%)", 1, 1, 1, 1, 1, 1)
GameCooltip : AddLine ( tabela [ 1 ] , SelectedToKFunction ( _ , tabela [ 2 ] ) .. " ( " .. format ( " %.1f " , tabela [ 2 ] / total * 100 ) .. " %) " )
end
GameCooltip : AddIcon ( tabela [ 3 ] , nil , nil , icon_size.W + 4 , icon_size.H + 4 , icon_border.L , icon_border.R , icon_border.T , icon_border.B )
Details : AddTooltipBackgroundStatusbar ( false , tabela [ 2 ] / topSpellDamage * 100 )
end
end
GameCooltip : Show ( )
return true
end
--controls the activity time of the actor
function damageClass : GetOrChangeActivityStatus ( activityStatus )
if ( activityStatus == nil ) then
--if no value passed, return the current activity status
return self.dps_started
elseif ( activityStatus ) then
self.dps_started = true
Details222.TimeMachine . AddActor ( self )
else
self.dps_started = false
Details222.TimeMachine . RemoveActor ( self )
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--core functions
--clear cache tables when resetting data
function damageClass : ClearCacheTables ( )
for i = # ntable , 1 , - 1 do
ntable [ i ] = nil
end
for i = # vtable , 1 , - 1 do
vtable [ i ] = nil
end
for i = # bs_table , 1 , - 1 do
bs_table [ i ] = nil
end
if ( bs_tooltip_table ) then
Details : Destroy ( bs_tooltip_table )
end
if ( frags_tooltip_table ) then
Details : Destroy ( frags_tooltip_table )
end
Details : Destroy ( bs_index_table )
Details : Destroy ( tooltip_temp_table )
Details : Destroy ( tooltip_void_zone_temp )
end
--atualize a funcao de abreviacao
function damageClass : UpdateSelectedToKFunction ( )
SelectedToKFunction = ToKFunctions [ Details.ps_abbreviation ]
FormatTooltipNumber = ToKFunctions [ Details.tooltip . abbreviation ]
TooltipMaximizedMethod = Details.tooltip . maximize_method
headerColor = Details.tooltip . header_text_color
end
--diminui o total das tabelas do combate
function damageClass : subtract_total ( combat_table )
combat_table.totals [ class_type ] = combat_table.totals [ class_type ] - self.total
if ( self.grupo ) then
combat_table.totals_grupo [ class_type ] = combat_table.totals_grupo [ class_type ] - self.total
end
end
function damageClass : add_total ( combat_table )
combat_table.totals [ class_type ] = combat_table.totals [ class_type ] + self.total
if ( self.grupo ) then
combat_table.totals_grupo [ class_type ] = combat_table.totals_grupo [ class_type ] + self.total
end
end
---sum the passed actor into a combat, if the combat isn't passed, it will use the overall combat
---the function returns the actor that was created of found in the combat passed
---@param actorObject actor
---@param bRefreshActor boolean|nil
---@param combatObject combat|nil
---@return actor
function damageClass : AddToCombat ( actorObject , bRefreshActor , combatObject )
--check if there's a custom combat, if not just use the overall container
combatObject = combatObject or Details.tabela_overall --same as Details:GetCombat(DETAILS_SEGMENTID_OVERALL)
--check if the combatObject has an actor with the same name, if not, just create one new
local actorContainer = combatObject [ DETAILS_ATTRIBUTE_DAMAGE ] --same as combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
local overallActor = actorContainer._ActorTable [ actorContainer._NameIndexTable [ actorObject.nome ] ] --same as actorContainer:GetActor(actorObject:Name())
if ( not overallActor ) then
overallActor = actorContainer : GetOrCreateActor ( actorObject.serial , actorObject.nome , actorObject.flag_original , true )
overallActor.classe = actorObject.classe
overallActor : SetSpecId ( actorObject.spec )
overallActor.isTank = actorObject.isTank
overallActor.pvp = actorObject.pvp
overallActor.boss = actorObject.boss
overallActor.start_time = time ( ) - 3
overallActor.end_time = time ( )
end
overallActor.displayName = actorObject.displayName or actorObject.nome
overallActor.boss_fight_component = actorObject.boss_fight_component or overallActor.boss_fight_component
overallActor.fight_component = actorObject.fight_component or overallActor.fight_component
overallActor.grupo = actorObject.grupo or overallActor.grupo
--check if need to restore meta tables and indexes for this actor
if ( bRefreshActor ) then
--this call will reenable the metatable, __index and set the metatable on the .spells container
Details.refresh : r_atributo_damage ( actorObject )
end
--elapsed time
local endTime = actorObject.end_time
if ( not actorObject.end_time ) then
endTime = time ( )
end
local tempo = endTime - actorObject.start_time
overallActor.start_time = overallActor.start_time - tempo
--pets (add unique pet names)
for _ , petName in ipairs ( actorObject.pets ) do --same as actorObject:GetPets()
DetailsFramework.table . addunique ( overallActor.pets , petName )
end
---@cast actorObject actordamage
--sum total damage
overallActor.total = overallActor.total + actorObject.total
overallActor.total_extra = overallActor.total_extra + actorObject.total_extra
overallActor.totalabsorbed = overallActor.totalabsorbed + actorObject.totalabsorbed
--sum total damage without pet
overallActor.total_without_pet = overallActor.total_without_pet + actorObject.total_without_pet
--sum total damage taken
overallActor.damage_taken = overallActor.damage_taken + actorObject.damage_taken
--sum friendly fire
overallActor.friendlyfire_total = overallActor.friendlyfire_total + actorObject.friendlyfire_total
--sum total damage on the combatObject passed
combatObject.totals [ 1 ] = combatObject.totals [ 1 ] + actorObject.total
if ( actorObject.grupo ) then
combatObject.totals_grupo [ 1 ] = combatObject.totals_grupo [ 1 ] + actorObject.total
end
--copy damage taken from
for aggressorName , _ in pairs ( actorObject.damage_from ) do
overallActor.damage_from [ aggressorName ] = true
end
--copy targets
for targetName , amount in pairs ( actorObject.targets ) do
overallActor.targets [ targetName ] = ( overallActor.targets [ targetName ] or 0 ) + amount
end
--copy raid targets
for flag , amount in pairs ( actorObject.raid_targets ) do
overallActor.raid_targets = overallActor.raid_targets or { }
overallActor.raid_targets [ flag ] = ( overallActor.raid_targets [ flag ] or 0 ) + amount
end
---@type spellcontainer
local overallSpellsContainer = overallActor.spells --same as overallActor:GetSpellContainer("spell")
--copy spell table
for spellId , spellTable in pairs ( actorObject.spells . _ActorTable ) do --same as overallSpellsContainer:GetRawSpellTable()
--var name has 'overall' but this function accepts any combat table
local overallSpellTable = overallSpellsContainer : GetOrCreateSpell ( spellId , true )
--sum spell targets
for targetName , amount in pairs ( spellTable.targets ) do
overallSpellTable.targets [ targetName ] = ( overallSpellTable.targets [ targetName ] or 0 ) + amount
end
--refresh and add extra values
for extraSpellId , amount in pairs ( spellTable.extra ) do
overallSpellTable.extra [ extraSpellId ] = ( overallSpellTable.extra [ extraSpellId ] or 0 ) + amount
end
overallSpellTable.spellschool = spellTable.spellschool
--sum all values of the spelltable which can be summed
for key , value in pairs ( spellTable ) do
if ( type ( value ) == " number " ) then
if ( key ~= " id " and key ~= " spellschool " ) then
if ( not overallSpellTable [ key ] ) then
overallSpellTable [ key ] = 0
end
if ( key == " n_min " or key == " c_min " ) then
if ( overallSpellTable [ key ] > value ) then
overallSpellTable [ key ] = value
end
elseif ( key == " n_max " or key == " c_max " ) then
if ( overallSpellTable [ key ] < value ) then
overallSpellTable [ key ] = value
end
else
overallSpellTable [ key ] = overallSpellTable [ key ] + value
end
end
--empowered spells
elseif ( key == " e_dmg " or key == " e_lvl " ) then
if ( not overallSpellTable [ key ] ) then
overallSpellTable [ key ] = { }
end
for empowermentLevel , empowermentValue in pairs ( spellTable [ key ] ) do
overallSpellTable [ key ] [ empowermentLevel ] = empowermentValue
end
end
end
end
if ( actorObject.augmentedSpellsContainer ) then
local overallAugmentedSpellsContainer = overallActor.augmentedSpellsContainer or spellContainerClass : CreateSpellContainer ( Details.container_type . CONTAINER_DAMAGE_CLASS )
overallActor.augmentedSpellsContainer = overallAugmentedSpellsContainer
for spellId , spellTable in pairs ( actorObject.augmentedSpellsContainer . _ActorTable ) do --same as actorObject.augmentedSpellsContainer:GetRawSpellTable()
local overallSpellTable = overallAugmentedSpellsContainer : GetOrCreateSpell ( spellId , true )
overallSpellTable.total = overallSpellTable.total + spellTable.total
for targetName , amount in pairs ( spellTable.targets ) do
overallSpellTable.targets [ targetName ] = ( overallSpellTable.targets [ targetName ] or 0 ) + amount
end
end
end
--copy the friendly fire container
for targetName , friendlyFireTable in pairs ( actorObject.friendlyfire ) do
--get or create the friendly fire table in the overall data
local friendlyFireOverall = overallActor.friendlyfire [ targetName ] or overallActor : CreateFFTable ( targetName )
--sum the total
friendlyFireOverall.total = friendlyFireOverall.total + friendlyFireTable.total
--sum spells
for friendlyFireSpellId , amount in pairs ( friendlyFireTable.spells ) do
friendlyFireOverall.spells [ friendlyFireSpellId ] = ( friendlyFireOverall.spells [ friendlyFireSpellId ] or 0 ) + amount
end
end
return overallActor
end
--actor 1 is who will receive the sum from actor2
function Details . SumDamageActors ( actor1 , actor2 , actorContainer ) --not called anywhere, can be deprecated
--general
actor1.total = actor1.total + actor2.total
actor1.damage_taken = actor1.damage_taken + actor2.damage_taken
actor1.totalabsorbed = actor1.totalabsorbed + actor2.totalabsorbed
actor1.total_without_pet = actor1.total_without_pet + actor2.total_without_pet
actor1.friendlyfire_total = actor1.friendlyfire_total + actor2.friendlyfire_total
--damage taken from
for actorName in pairs ( actor2.damage_from ) do
actor1.damage_from [ actorName ] = true
--add the damage done to actor2 into the damage done to target1
if ( actorContainer ) then
--get the actor that caused the damage on actor2
local actorObject = actorContainer : GetActor ( actorName )
if ( actorObject ) then
local damageToActor2 = ( actorObject.targets [ actor2.nome ] ) or 0
actorObject.targets [ actor1.nome ] = ( actorObject.targets [ actor1.nome ] or 0 ) + damageToActor2
end
end
end
--targets
for actorName , damageDone in pairs ( actor2.targets ) do
actor1.targets [ actorName ] = ( actor1.targets [ actorName ] or 0 ) + damageDone
end
--pets
for i = 1 , # actor2.pets do
DetailsFramework.table . addunique ( actor1.pets , actor2.pets [ i ] )
end
--raid targets
for raidTargetFlag , damageDone in pairs ( actor2.raid_targets ) do
actor1.raid_targets [ raidTargetFlag ] = ( actor1.raid_targets [ raidTargetFlag ] or 0 ) + damageDone
end
--friendly fire
for actorName , ffTable in pairs ( actor2.friendlyfire ) do
actor1.friendlyfire [ actorName ] = actor1.friendlyfire [ actorName ] or actor1 : CreateFFTable ( actorName )
actor1.friendlyfire [ actorName ] . total = actor1.friendlyfire [ actorName ] . total + ffTable.total
for spellId , damageDone in pairs ( ffTable.spells ) do
actor1.friendlyfire [ actorName ] . spells [ spellId ] = ( actor1.friendlyfire [ actorName ] . spells [ spellId ] or 0 ) + damageDone
end
end
--spells
local ignoredKeys = {
id = true ,
spellschool = true ,
}
local actor1Spells = actor1.spells
for spellId , spellTable in pairs ( actor2.spells . _ActorTable ) do
local actor1Spell = actor1Spells : GetOrCreateSpell ( spellId , true , " DAMAGE_DONE " )
--genetal spell attributes
for key , value in pairs ( spellTable ) do
if ( type ( value ) == " number " ) then
if ( not ignoredKeys [ key ] ) then
if ( key == " n_min " or key == " c_min " ) then
if ( actor1Spell [ key ] > value ) then
actor1Spell [ key ] = value
end
elseif ( key == " n_max " or key == " c_max " ) then
if ( actor1Spell [ key ] < value ) then
actor1Spell [ key ] = value
end
else
actor1Spell [ key ] = actor1Spell [ key ] + value
end
end
end
end
--spell targets
for targetName , damageDone in pairs ( spellTable ) do
actor1Spell.targets [ targetName ] = ( actor1Spell.targets [ targetName ] or 0 ) + damageDone
end
end
end
damageClass.__add = function ( tabela1 , tabela2 )
--tempo decorrido
local tempo = ( tabela2.end_time or time ( ) ) - tabela2.start_time
tabela1.start_time = tabela1.start_time - tempo
--total de dano
tabela1.total = tabela1.total + tabela2.total
tabela1.totalabsorbed = tabela1.totalabsorbed + tabela2.totalabsorbed
--total de dano sem o pet
tabela1.total_without_pet = tabela1.total_without_pet + tabela2.total_without_pet
--total de dano que o cara levou
tabela1.damage_taken = tabela1.damage_taken + tabela2.damage_taken
--total do friendly fire causado
tabela1.friendlyfire_total = tabela1.friendlyfire_total + tabela2.friendlyfire_total
--soma o damage_from
for nome , _ in pairs ( tabela2.damage_from ) do
tabela1.damage_from [ nome ] = true
end
--pets (add unique pet names)
for _ , petName in ipairs ( tabela2.pets ) do
local hasPet = false
for i = 1 , # tabela1.pets do
if ( tabela1.pets [ i ] == petName ) then
hasPet = true
break
end
end
if ( not hasPet ) then
tabela1.pets [ # tabela1.pets + 1 ] = petName
end
end
--soma os containers de alvos
for target_name , amount in pairs ( tabela2.targets ) do
tabela1.targets [ target_name ] = ( tabela1.targets [ target_name ] or 0 ) + amount
end
--soma o container de raid targets
for flag , amount in pairs ( tabela2.raid_targets ) do
tabela1.raid_targets [ flag ] = ( tabela1.raid_targets [ flag ] or 0 ) + amount
end
--soma o container de habilidades
for spellid , habilidade in pairs ( tabela2.spells . _ActorTable ) do
--pega a habilidade no primeiro ator
local habilidade_tabela1 = tabela1.spells : PegaHabilidade ( spellid , true , " SPELL_DAMAGE " , false )
--soma os alvos
for target_name , amount in pairs ( habilidade.targets ) do
habilidade_tabela1.targets [ target_name ] = ( habilidade_tabela1.targets [ target_name ] or 0 ) + amount
end
--soma os extras
for spellId , amount in pairs ( habilidade.extra ) do
habilidade_tabela1.extra = ( habilidade_tabela1.extra [ spellId ] or 0 ) + amount
end
--soma os valores da habilidade
for key , value in pairs ( habilidade ) do
if ( type ( value ) == " number " ) then
if ( key ~= " id " and key ~= " spellschool " ) then
if ( not habilidade_tabela1 [ key ] ) then
habilidade_tabela1 [ key ] = 0
end
if ( key == " n_min " or key == " c_min " ) then
if ( habilidade_tabela1 [ key ] > value ) then
habilidade_tabela1 [ key ] = value
end
elseif ( key == " n_max " or key == " c_max " ) then
if ( habilidade_tabela1 [ key ] < value ) then
habilidade_tabela1 [ key ] = value
end
else
habilidade_tabela1 [ key ] = habilidade_tabela1 [ key ] + value
end
end
elseif ( key == " e_dmg " or key == " e_lvl " ) then
if ( not habilidade_tabela1 [ key ] ) then
habilidade_tabela1 [ key ] = { }
end
for empowermentLevel , empowermentValue in pairs ( habilidade [ key ] ) do
habilidade_tabela1 [ key ] [ empowermentLevel ] = habilidade_tabela1 [ key ] [ empowermentValue ] or 0 + empowermentValue
end
end
end
end
--soma o container de friendly fire
for target_name , ff_table in pairs ( tabela2.friendlyfire ) do
--pega o ator ff no ator principal
local friendlyFire_tabela1 = tabela1.friendlyfire [ target_name ] or tabela1 : CreateFFTable ( target_name )
--soma o total
friendlyFire_tabela1.total = friendlyFire_tabela1.total + ff_table.total
--soma as habilidades
for spellid , amount in pairs ( ff_table.spells ) do
friendlyFire_tabela1.spells [ spellid ] = ( friendlyFire_tabela1.spells [ spellid ] or 0 ) + amount
end
end
return tabela1
end
damageClass.__sub = function ( tabela1 , tabela2 )
--tempo decorrido
local tempo = ( tabela2.end_time or time ( ) ) - tabela2.start_time
tabela1.start_time = tabela1.start_time + tempo
--total de dano
tabela1.total = tabela1.total - tabela2.total
tabela1.totalabsorbed = tabela1.totalabsorbed - tabela2.totalabsorbed
--total de dano sem o pet
tabela1.total_without_pet = tabela1.total_without_pet - tabela2.total_without_pet
--total de dano que o cara levou
tabela1.damage_taken = tabela1.damage_taken - tabela2.damage_taken
--total do friendly fire causado
tabela1.friendlyfire_total = tabela1.friendlyfire_total - tabela2.friendlyfire_total
--reduz os containers de alvos
for target_name , amount in pairs ( tabela2.targets ) do
local alvo_tabela1 = tabela1.targets [ target_name ]
if ( alvo_tabela1 ) then
tabela1.targets [ target_name ] = tabela1.targets [ target_name ] - amount
end
end
--reduz o container de raid targets
for flag , amount in pairs ( tabela2.raid_targets ) do
if ( tabela1.raid_targets [ flag ] ) then
tabela1.raid_targets [ flag ] = _math_max ( tabela1.raid_targets [ flag ] - amount , 0 )
end
end
--reduz o container de habilidades
for spellid , habilidade in pairs ( tabela2.spells . _ActorTable ) do
--get the spell from the first actor
local habilidade_tabela1 = tabela1.spells : PegaHabilidade ( spellid , true , " SPELL_DAMAGE " , false )
--subtract targets
for target_name , amount in pairs ( habilidade.targets ) do
local alvo_tabela1 = habilidade_tabela1.targets [ target_name ]
if ( alvo_tabela1 ) then
habilidade_tabela1.targets [ target_name ] = habilidade_tabela1.targets [ target_name ] - amount
end
end
--subtract extra table
for spellId , amount in pairs ( habilidade.extra ) do
local extra_tabela1 = habilidade_tabela1.extra [ spellId ]
if ( extra_tabela1 ) then
habilidade_tabela1.extra [ spellId ] = habilidade_tabela1.extra [ spellId ] - amount
end
end
--subtrai os valores da habilidade
for key , value in pairs ( habilidade ) do
if ( type ( value ) == " number " ) then
if ( key ~= " id " and key ~= " spellschool " ) then
if ( not habilidade_tabela1 [ key ] ) then
habilidade_tabela1 [ key ] = 0
end
if ( key == " n_min " or key == " c_min " ) then
if ( habilidade_tabela1 [ key ] > value ) then
habilidade_tabela1 [ key ] = value
end
elseif ( key == " n_max " or key == " c_max " ) then
if ( habilidade_tabela1 [ key ] < value ) then
habilidade_tabela1 [ key ] = value
end
else
habilidade_tabela1 [ key ] = habilidade_tabela1 [ key ] - value
end
end
end
end
end
--reduz o container de friendly fire
for target_name , ff_table in pairs ( tabela2.friendlyfire ) do
--pega o ator ff no ator principal
local friendlyFire_tabela1 = tabela1.friendlyfire [ target_name ]
if ( friendlyFire_tabela1 ) then
friendlyFire_tabela1.total = friendlyFire_tabela1.total - ff_table.total
for spellid , amount in pairs ( ff_table.spells ) do
if ( friendlyFire_tabela1.spells [ spellid ] ) then
friendlyFire_tabela1.spells [ spellid ] = friendlyFire_tabela1.spells [ spellid ] - amount
end
end
end
end
return tabela1
end
function Details . refresh : r_atributo_damage ( actorObject )
detailsFramework : Mixin ( actorObject , Details222.Mixins . ActorMixin )
detailsFramework : Mixin ( actorObject , damageClassMixin )
setmetatable ( actorObject , Details.atributo_damage )
actorObject.__index = Details.atributo_damage
--restore metatable for the spell container
Details.refresh : r_container_habilidades ( actorObject.spells )
if ( actorObject.augmentedSpellsContainer ) then
Details.refresh : r_container_habilidades ( actorObject.augmentedSpellsContainer )
end
end
function Details . clear : c_atributo_damage ( este_jogador )
este_jogador.__index = nil
este_jogador.links = nil
este_jogador.minha_barra = nil
Details.clear : c_container_habilidades ( este_jogador.spells )
end
--[[
--enemy damage done
i = 1
local enemy = combat ( 1 , enemy_name )
if ( enemy ) then
local damage_done = 0
--get targets
for target_name , amount in pairs ( enemy.targets ) do
local player = combat ( 1 , target_name )
if ( player and player.grupo ) then
local t = tooltip_temp_table [ i ]
if ( not t ) then
tooltip_temp_table [ i ] = { }
t = tooltip_temp_table [ i ]
end
t [ 1 ] = player
t [ 2 ] = amount
damage_done = damage_done + amount
i = i + 1
end
end
--first clenup
for o = i , # tooltip_temp_table do
local t = tooltip_temp_table [ o ]
t [ 2 ] = 0
t [ 1 ] = 0
end
_table_sort ( tooltip_temp_table , Details.Sort2 )
--enemy damage taken
Details : AddTooltipSpellHeaderText ( Loc [ " STRING_ATTRIBUTE_DAMAGE " ] , headerColor , i - 1 , true )
GameCooltip : AddIcon ( [=[Interface\Buttons\UI-MicroStream-Green]=] , 2 , 1 , 14 , 14 , 0.1875 , 0.8125 , 0.15625 , 0.78125 )
GameCooltip : AddIcon ( [=[Interface\AddOns\Details\images\key_shift]=] , 2 , 2 , Details.tooltip_key_size_width , Details.tooltip_key_size_height , 0 , 1 , 0 , 0.640625 , Details.tooltip_key_overlay2 )
GameCooltip : AddStatusBar ( 100 , 2 , 0.7 , g , b , 1 )
--build the tooltip
for o = 1 , i - 1 do
local player = tooltip_temp_table [ o ] [ 1 ]
local total = tooltip_temp_table [ o ] [ 2 ]
local player_name = player : name ( )
if ( player_name : find ( Details.playername ) ) then
GameCooltip : AddLine ( player_name .. " : " , FormatTooltipNumber ( _ , total ) .. " ( " .. _cstr ( " %.1f " , ( total / damage_done ) * 100 ) .. " %) " , 2 , " yellow " )
else
GameCooltip : AddLine ( player_name .. " : " , FormatTooltipNumber ( _ , total ) .. " ( " .. _cstr ( " %.1f " , ( total / damage_done ) * 100 ) .. " %) " , 2 )
end
local classe = player : class ( )
if ( not classe ) then
classe = " UNKNOW "
end
if ( classe == " UNKNOW " ) then
GameCooltip : AddIcon ( " Interface \\ LFGFRAME \\ LFGROLE_BW " , 2 , nil , 14 , 14 , .25 , .5 , 0 , 1 )
else
GameCooltip : AddIcon ( instancia.row_info . icon_file , 2 , nil , 14 , 14 , _unpack ( Details.class_coords [ classe ] ) )
end
Details : AddTooltipBackgroundStatusbar ( 2 )
end
end
--clean up
for o = 1 , # tooltip_temp_table do
local t = tooltip_temp_table [ o ]
t [ 2 ] = 0
t [ 1 ] = 0
end
--]]