- Added Spirit Link Totem damage and healing on death log.

- Added the total of life exchanged by the Spirit Link Totem on player detail window.
- Added more spells for crowd control.
- Added scroll on bookmark panel.
This commit is contained in:
Tercio
2015-03-26 15:09:21 -03:00
parent 0c126196d2
commit af0a447b0d
16 changed files with 689 additions and 235 deletions
+169 -56
View File
@@ -40,18 +40,67 @@ DETAILS_SUBATTRIBUTE_DCOOLDOWN = 6
DETAILS_SUBATTRIBUTE_BUFFUPTIME = 7
DETAILS_SUBATTRIBUTE_DEBUFFUPTIME = 8
TL;DR
=======================================
A history segment container is the higher table in the hierarchy, it holds combat objects.
A Combat Object has 4 tables: damage on index 1, healing on index 2, energy on index 3, misc on index 4.
Those tables are called 'containers', these containers holds 'Actor Objects'.
Actor Objects hold a target table and a spell table.
Each player will have 4 tables, one for each attribute, e.g. 1 for store its damage, another for the healing done.
Actor Objects also has specific members for each attribute, see below.
Getting Details! Object:
=======================================
Just get the global 'Details', for instance:
local details = _G.Details
Getting a Combat Object:
=======================================
combat = Details:GetCurrentCombat()
returns the current combat object.
combat = Details:GetCombat (combat)
returns the requested combat object.
if 'combat' is omitted, returns the current combat.
combat can be a number: -1 for overall, 0 for current and > 0 for past segments.
combat also can be a string "overall" or "current".
history_segment_container = Details:GetCombatSegments()
returns the numeric table containing all past segments.
Gettings an Actor:
=======================================
local actor = Details:GetActor (combat = "current", attribute = 1, actorname = playername)
returns the actor for the requested combat, attribute and actor name.
if all parameters are omitted, returns the damage actor object of the player for the current combat.
Combat Object:
=======================================
Combat Objects holds the containers for each main attribute.
A Combat object is a table with 4 numerical indexes holding: damage, healing, energy and misc containers.
function for combat objects:
actor = combat ( attribute, character_name )
returns actor object
returns an actor object
container = combat:GetContainer (attribute)
characterList = combat:GetActorList ( attribute )
returns a numeric table with all actors of the specific attribute, contains players, npcs, pets, etc.
chartData = combat:GetTimeData ( chart_data_name )
returns the table containing the data for create a chart.
combatName = combat:GetCombatName ( try_to_find )
returns the segment name, e.g. "Trainning Dummy", if try_to_find is true, it searches the combat for a enemy name.
bossInfo = combat:GetBossInfo()
returns the table containing informations about the boss encounter.
table members: name, zone, mapid, diff, diff_string, id, ej_instance_id, killed, index
time = combat:GetCombatTime()
returns the length of the combat in seconds, if the combat is in progress, returns the current elapsed time.
minutes, seconds = GetFormatedCombatTime()
returns the combat time formated with minutes and seconds.
startDate, endDate = combat:GetDate()
returns the start and end date as %H:%M:%S.
@@ -62,23 +111,23 @@ returns true if the combat is a trash segment.
encounterDiff = combat:GetDifficulty()
returns the difficulty number of the raid encounter.
bossInfo = combat:GetBossInfo()
returns the table containing informations about the boss encounter.
deaths = combat:GetDeaths()
returns a numeric table containing the deaths.
returns a numeric table containing the deaths, table is ordered by first death to last death.
combatNumber = combat:GetCombatNumber()
returns the unique ID number for the combat.
combatName = combat:GetCombatName ( try_to_find )
returns the segment name, e.g. "Trainning Dummy", if try_to_find is true, it searches the combat for a enemy name.
container = combat:GetContainer ( attribute )
returns the container table for the requested attribute.
characterList = combat:GetActorList ( attribute )
returns a numeric table with all actors of the specific attribute.
chartData = combat:GetTimeData ( chart_data_name )
returns the table containing the data for create a chart.
time = combat:GetCombatTime()
returns the length of the combat, if the combat is in progress, returns the elapsed time.
start_at = GetStartTime()
returns the GetTime() of when the combat started.
ended_at = GetEndTime()
returns the GetTime() of when the combat ended.
DETAILS_TOTALS_ONLYGROUP = true
@@ -89,35 +138,18 @@ returns the total of the requested attribute.
Other Calls:
_detalhes:GetCurrentCombat()
returns the current combat object.
_detalhes:GetCombatSegments()
returns the numeric table containing all past segments.
_detalhes:GetCombatNumber()
Details:GetCombatNumber()
returns the current unique combat number counter.
combat number is a unique number given to each combat started, this number won't
reset when data is wiped and each character have its own combat number counter.
_detalhes:IsInCombat()
Details:IsInCombat()
returns if Details! is in combat or not.
_detalhes:GetCombat (combat = "current")
returns the requested combat object.
is 'combat' is omitted, returns the current combat.
combat can be a number: -1 for overall, 0 for current and > 0 for past segments.
combat also can be a string "overall" for overall combat and "current" for current segment.
damage, healing, energy, misc = _detalhes:GetAllActors (combat, actorname)
damage, healing, energy, misc = Details:GetAllActors (combat, actorname)
returns all the four actor objects for the requested combat and actor.
combat must be a combat object.
local actor = _detalhes:GetActor (combat = "current", attribute = 1, actorname = playername)
returns the actor for the requested combat, attribute and actor name.
if all parameters are omitted, returns the damage actor object of the player for the current combat.
Container Object:
=======================================
@@ -135,24 +167,24 @@ similar to GetTotal, but only counts the total of raid members.
ipairs_list = container:ListActors()
returns a iterated table of actors inside the container.
Usage: for index, actor in container:ListActors() do
Usage: 'for index, actor in container:ListActors() do'
Actor Object:
=======================================
Holds all total keys, spells and targets of a character.
Holds keys, spells and targets of a character.
name = actor:Name()
name = actor:name()
returns the actor's name.
displayName = actor:GetDisplayName()
returns the name shown on the player bar, can soffer modifications from realm name removed, nicknames, etc.
returns the name shown on the player bar, can suffer modifications from realm name removed, nicknames, etc.
name = actor:GetOnlyName()
returns only the actor name, remove realm or owner names.
class = actor:Class()
class = actor:class()
returns the actor class.
activity = actor:Tempo()
@@ -179,28 +211,109 @@ returns a spell table of requested spell id.
r, g, b = actor:GetBarColor()
returns the color which the player bar will be painted on the window, it respects owner, arena team, enemy, monster.
r, g, b = _detalhes:GetClassColor()
r, g, b = Details:GetClassColor()
returns the class color.
icon, left, right, top, bottom = actor:GetClassIcon()
texture, left, right, top, bottom = actor:GetClassIcon()
returns the icon texture path and the texture's texcoords.
Damage Actor Keys:
Keys for Damage Actors:
=======================================
total = total of damage done.
total_without_pet = without pet.
damage_taken = total of damage taken.
last_dps = cache of the last calculed dps, it's best just use actor.total / actor:Tempo()
last_event = when the last event for this actor occured.
start_time = time when this actor started to apply damage.
end_time = time when the actor stopped with damage.
friendlyfire_total = amount of friendlyfire.
members:
actor.total = total of damage done.
actor.total_without_pet = without pet.
actor.damage_taken = total of damage taken.
actor.last_event = when the last event for this actor occured.
actor.start_time = time when this actor started to apply damage.
actor.end_time = time when the actor stopped with damage.
actor.friendlyfire_total = amount of friendlyfire.
targets = hash table of targets: targetName, amount.
damage_from = hash table of actors which applied damage to this actor: aggresorName, true.
pets = numeric table of GUIDs of pets summoned by this actor.
friendlyfire = hash table of friendly fire targets: targetName, table {total = 0, spells = hash table: spellId, amount}
spells = hash table with spells used to apply damage: spellId, spellTable.
containers:
actor.targets = hash table of targets: {[targetName] = amount}.
actor.damage_from = hash table of actors which applied damage to this actor: {[aggresorName] = true}.
actor.pets = numeric table of GUIDs of pets summoned by this actor.
actor.friendlyfire = hash table of friendly fire targets: {[targetName] = table {total = 0, spells = hash table: {[spellId] = amount}}}
actor.spells = hash table with spells used to apply damage: {[spellId] = spellTable}.
Getting Dps:
For activity time: actor.total / actor:Tempo()
For effective time: actor.total / combat:GetCombatTime()
Keys for Healing Actors:
=======================================
members:
actor.total = total of healing done.
actor.totalover = total of overheal.
actor.totalabsorb = total of absorbs.
actor.total_without_pet = total without count the healing done from pets.
actor.totalover_without_pet = overheal without pets.
actor.heal_enemy_amt = how much this actor healing an enemy actor.
actor.healing_taken = total of received healing.
actor.last_event = when the last event for this actor occured.
actor.start_time = time when this actor started to apply heals.
actor.end_time = time when the actor stopped with healing.
containers:
actor.spells = hash table with spells used to apply heals: {[spellId] = spellTable}.
actor.targets = hash table of targets: {[targetName] = amount}.
actor.targets_overheal = hash table of overhealed targets: {[targetName] = amount}.
actor.targets_absorbs = hash table of shield absorbs: {[targetName] = amount}.
actor.healing_from = hash table of actors which applied healing to this actor: {[healerName] = true}.
actor.pets = numeric table of GUIDs of pets summoned by this actor.
actor.heal_enemy = spells used to heal the enemy: {[spellid] = amount healed}
Keys for Energy Actors:
=======================================
actor.total = total of energy generated.
actor.received = total of energy received.
actor.resource = total of resource generated.
actor.resource_type = type of the resource used by the actor.
actor.pets = numeric table of GUIDs of pets summoned by this actor.
actor.targets = hash table of targets: {[targetName] = amount}.
actor.spells = hash table with spells used to generate energy: {[spellId] = spellTable}.
Keys for Misc Actors:
=======================================
these members and container may not be present on all actors, depends if the actor performed the action.
cc_done = amount of crowd control done.
cc_done_targets = cc done targets {[targetName] = amount}.
cc_done_spells = spells used to make the cc.
interrupt = amount of interrupts.
interrupt_targets = target which was its spell interrupted {[targetName] = amount}.
interrupt_spells = spells used to interrupt.
interrompeu_oque = spells interrupted.
buff_uptime = seconds of all buff uptime.
buff_uptime_targets =
buff_uptime_spells =
debuff_uptime =
debuff_uptime_targets = {[targetName] = amount}.
debuff_uptime_spells =
cooldowns_defensive = amount of defensive cooldowns used.
cooldowns_defensive_targets = in which player the cooldown was used.
cooldowns_defensive_spells = spells used.
ress = amount of resses.
ress_targets = {[targetName] = amount}.
ress_spells =
dispell = amount of dispells done.
dispell_targets = {[targetName] = amount}.
dispell_spells =
dispell_oque =
cc_break =
cc_break_targets = {[targetName] = amount}.
cc_break_spells =
cc_break_oque =
+11 -4
View File
File diff suppressed because one or more lines are too long
+5 -1
View File
@@ -2614,7 +2614,11 @@ end
row.textura:SetStatusBarColor (1, 1, 1)
end
else
row.textura:SetStatusBarColor (1, 1, 1)
if (spellid == 98021) then
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 info.showing == index) then
+8 -4
View File
@@ -394,8 +394,8 @@ function _detalhes:StoreEncounter (combat)
local diff = combat:GetDifficulty()
--> check for heroic mode
if (diff == 14 or diff == 15 or diff == 16) then --test on raid finder ' or diff == 17'
--> check for heroic and mythic
if (diff == 15 or diff == 16) then --test on raid finder ' or diff == 17' -- normal mode: diff == 14 or
--> check the guild name
local match = 0
@@ -474,10 +474,12 @@ function _detalhes:StoreEncounter (combat)
player_name = player_name .. "-" .. player_realm
end
local _, _, class = UnitClass (player_name)
local damage_actor = damage_container_pool [damage_container_hash [player_name]]
if (damage_actor) then
local guid = UnitGUID (player_name) or UnitGUID (UnitName ("raid" .. i))
this_combat_data.damage [player_name] = {floor (damage_actor.total), _detalhes.item_level_pool [guid] or 0}
this_combat_data.damage [player_name] = {floor (damage_actor.total), _detalhes.item_level_pool [guid] and _detalhes.item_level_pool [guid].ilvl or 0, class or 0}
end
elseif (role == "HEALER") then
local player_name, player_realm = UnitName ("raid" .. i)
@@ -485,10 +487,12 @@ function _detalhes:StoreEncounter (combat)
player_name = player_name .. "-" .. player_realm
end
local _, _, class = UnitClass (player_name)
local heal_actor = healing_container_pool [healing_container_hash [player_name]]
if (heal_actor) then
local guid = UnitGUID (player_name) or UnitGUID (UnitName ("raid" .. i))
this_combat_data.healing [player_name] = {floor (heal_actor.total), _detalhes.item_level_pool [guid] or 0}
this_combat_data.healing [player_name] = {floor (heal_actor.total), _detalhes.item_level_pool [guid] and _detalhes.item_level_pool [guid].ilvl or 0, class or 0}
end
end
+157 -3
View File
@@ -185,7 +185,7 @@
--> spirit link toten
if (spellid == 98021) then
return
return parser:SLT_damage (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, spellid, spellname, spelltype, amount, overkill, school, resisted, blocked, absorbed, critical, glacing, crushing, isoffhand, multistrike)
end
------------------------------------------------------------------------------------------------
@@ -372,7 +372,7 @@
local this_event = t [i]
if (not this_event) then
print ("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _death_event_amt)
return print ("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _death_event_amt)
end
this_event [1] = true --> true if this is a damage || false for healing
@@ -539,6 +539,103 @@
return spell_damage_func (spell, alvo_serial, alvo_name, alvo_flags, amount, who_name, resisted, blocked, absorbed, critical, glacing, token, multistrike, isoffhand)
end
function parser:SLT_damage (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, spellid, spellname, spelltype, amount, overkill, school, resisted, blocked, absorbed, critical, glacing, crushing, isoffhand, multistrike)
--> get the damager and target actors
local este_jogador, meu_dono = damage_cache [who_serial] or damage_cache_pets [who_serial], damage_cache_petsOwners [who_serial]
if (not este_jogador) then --> pode ser um desconhecido ou um pet
este_jogador, meu_dono, who_name = _current_damage_container:PegarCombatente (who_serial, who_name, who_flags, true)
if (meu_dono) then --> é um pet
damage_cache_pets [who_serial] = este_jogador
damage_cache_petsOwners [who_serial] = meu_dono
if (not damage_cache [meu_dono.serial]) then
damage_cache [meu_dono.serial] = meu_dono
end
else
if (who_flags) then --> ter certeza que não é um pet
if (who_serial ~= "") then
damage_cache [who_serial] = este_jogador
else
if (who_name:find ("%[")) then
local _, _, icon = _GetSpellInfo (spellid or 1)
este_jogador.spellicon = icon
end
end
end
end
elseif (meu_dono) then
who_name = who_name .. " <" .. meu_dono.nome .. ">"
end
--> his target
local jogador_alvo, alvo_dono = damage_cache [alvo_serial] or damage_cache_pets [alvo_serial], damage_cache_petsOwners [alvo_serial]
if (not jogador_alvo) then
jogador_alvo, alvo_dono, alvo_name = _current_damage_container:PegarCombatente (alvo_serial, alvo_name, alvo_flags, true)
if (alvo_dono) then
damage_cache_pets [alvo_serial] = jogador_alvo
damage_cache_petsOwners [alvo_serial] = alvo_dono
--conferir se o dono já esta no cache
if (not damage_cache [alvo_dono.serial]) then
damage_cache [alvo_dono.serial] = alvo_dono
end
else
if (alvo_flags) then --> ter certeza que não é um pet
damage_cache [alvo_serial] = jogador_alvo
end
end
elseif (alvo_dono) then
--> é um pet
alvo_name = alvo_name .. " <" .. alvo_dono.nome .. ">"
end
--> last event
este_jogador.last_event = _tempo
--> record death log
local t = last_events_cache [alvo_name]
if (not t) then
t = _current_combat:CreateLastEventsTable (alvo_name)
end
local i = t.n
local this_event = t [i]
if (not this_event) then
return print ("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _death_event_amt)
end
this_event [1] = true --> true if this is a damage || false for healing
this_event [2] = spellid --> spellid || false if this is a battle ress line
this_event [3] = amount --> amount of damage or healing
this_event [4] = time --> parser time
this_event [5] = _UnitHealth (alvo_name) --> current unit heal
this_event [6] = who_name --> source name
this_event [7] = absorbed
this_event [8] = school
this_event [9] = false
this_event [10] = overkill
i = i + 1
if (i == _death_event_amt+1) then
t.n = 1
else
t.n = i
end
end
--function parser:swingmissed (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, missType, isOffHand, amountMissed)
function parser:swingmissed (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, missType, isOffHand, multistrike, amountMissed) --, isOffHand, multistrike, amountMissed, arg1
return parser:missed (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, 1, "Corpo-a-Corpo", 00000001, missType, isOffHand, multistrike, amountMissed) --, isOffHand, multistrike, amountMissed, arg1
@@ -786,7 +883,7 @@
--> spirit link toten
if (spellid == 98021) then
return
return parser:SLT_healing (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, spellid, spellname, spelltype, amount, overhealing, absorbed, critical, multistrike, is_shield)
end
--[[statistics]]-- _detalhes.statistics.heal_calls = _detalhes.statistics.heal_calls + 1
@@ -968,6 +1065,63 @@
end
end
function parser:SLT_healing (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, spellid, spellname, spelltype, amount, overhealing, absorbed, critical, multistrike, is_shield)
--> get actors
local este_jogador, meu_dono = healing_cache [who_name]
if (not este_jogador) then --> pode ser um desconhecido ou um pet
este_jogador, meu_dono, who_name = _current_heal_container:PegarCombatente (who_serial, who_name, who_flags, true)
if (not meu_dono and who_flags) then --> se não for um pet, adicionar no cache
healing_cache [who_name] = este_jogador
end
end
local jogador_alvo, alvo_dono = healing_cache [alvo_name]
if (not jogador_alvo) then
jogador_alvo, alvo_dono, alvo_name = _current_heal_container:PegarCombatente (alvo_serial, alvo_name, alvo_flags, true)
if (not alvo_dono and alvo_flags) then
healing_cache [alvo_name] = jogador_alvo
end
end
este_jogador.last_event = _tempo
local t = last_events_cache [alvo_name]
if (not t) then
t = _current_combat:CreateLastEventsTable (alvo_name)
end
local i = t.n
local this_event = t [i]
this_event [1] = false --> true if this is a damage || false for healing
this_event [2] = spellid --> spellid || false if this is a battle ress line
this_event [3] = amount --> amount of damage or healing
this_event [4] = time --> parser time
this_event [5] = _UnitHealth (alvo_name) --> current unit heal
this_event [6] = who_name --> source name
this_event [7] = is_shield
this_event [8] = absorbed
i = i + 1
if (i == _death_event_amt+1) then
t.n = 1
else
t.n = i
end
local spell = este_jogador.spells._ActorTable [spellid]
if (not spell) then
spell = este_jogador.spells:PegaHabilidade (spellid, true, token)
spell.neutral = true
end
return spell_heal_func (spell, alvo_serial, alvo_name, alvo_flags, absorbed + amount - overhealing, who_name, absorbed, critical, overhealing, nil, multistrike)
end
-----------------------------------------------------------------------------------------------------------------------------------------
--> BUFFS & DEBUFFS serach key: ~buff ~aura ~shield |
-----------------------------------------------------------------------------------------------------------------------------------------
+4 -4
View File
@@ -2192,7 +2192,7 @@
if LDB then
local databroker = LDB:NewDataObject ("Details!", {
local databroker = LDB:NewDataObject ("Details", {
type = "data source",
icon = [[Interface\AddOns\Details\images\minimap]],
text = "0",
@@ -2303,8 +2303,8 @@
end,
})
if (databroker and not LDBIcon:IsRegistered ("Details!")) then
LDBIcon:Register ("Details!", databroker, self.minimap)
if (databroker and not LDBIcon:IsRegistered ("Details")) then
LDBIcon:Register ("Details", databroker, self.minimap)
end
_detalhes.databroker = databroker
@@ -2359,7 +2359,7 @@
if (_G.HotCorners) then
_G.HotCorners:RegisterHotCornerButton (
--> absolute name
"Details!",
"Details",
--> corner
"TOPLEFT",
--> config table
+3
View File
@@ -121,6 +121,9 @@ do
function _detalhes:Class (actor)
return self.classe or actor.classe
end
function _detalhes:class (actor)
return self.classe or actor.classe
end
function _detalhes:GetActorSpells()
return self.spells._ActorTable
end
+4 -1
View File
@@ -829,6 +829,7 @@ local default_profile = {
--> minimap
minimap = {hide = false, radius = 160, minimapPos = 220, onclick_what_todo = 1, text_type = 1, text_format = 3},
data_broker_text = "",
--> horcorner
hotcorner_topleft = {hide = false},
@@ -846,14 +847,16 @@ local default_profile = {
--> segments
segments_amount = 12,
segments_amount_to_save = 5,
segments_panic_mode = true,
segments_panic_mode = false,
segments_auto_erase = 1,
--> instances
instances_amount = 5,
instances_segments_locked = false,
--> if clear ungroup characters when logout
clear_ungrouped = true,
--> if clear graphic data when logout
clear_graphic = true,
+2
View File
@@ -65,6 +65,8 @@ do
[7] = {name = Loc ["STRING_ENVIRONMENTAL_LAVA"], icon = [[Interface\ICONS\Ability_Rhyolith_Volcano]]},
[8] = {name = Loc ["STRING_ENVIRONMENTAL_SLIME"], icon = [[Interface\ICONS\Ability_Creature_Poison_02]]},
[98021] = {name = Loc ["STRING_SPIRIT_LINK_TOTEM"]},
[44461] = {name = GetSpellInfo (44461) .. " (" .. Loc ["STRING_EXPLOSION"] .. ")"}, --> Living Bomb (explosion)
[161576] = {name = GetSpellInfo (161576) .. " (" .. Loc ["STRING_EXPLOSION"] .. ")"}, --> Ko'ragh's Overflowing Energy (explosion)
+119 -45
View File
@@ -1432,67 +1432,141 @@ do
--[29842] = "WARRIOR", --undribled wrath
}
-- updated on 24/03/2015 (@Tonyleila - WoWInterface)
_detalhes.CrowdControlSpells = {
--Racials
[28730] = true, -- Arcane Torrent (be)
[47779] = true, -- Arcane Torrent (be)
[50613] = true, -- Arcane Torrent (be)
[107079] = true, -- Quaking Palm (pandaren)
[20549] = true, -- War Stomp (tauren)
--death knight
[96294] = true, --chains of ice
[108194] = true, -- Asphyxiate
[96294] = true, -- Chains of ice
[47481] = true, -- Gnaw
[47528] = true, -- Mind Freeze
[91797] = true, -- Monstrous Blow
[115001] = true, -- Remorseless Winter (Stunned)
[47476] = true, -- Strangulate
--druid
--hibernate
--[2637] = true, --hibernate
[339] = true, --entangling toots
[33786] = true, -- Cyclone
[339] = true, -- Entangling Toots
[45334] = true, -- Immobilized (from Wild Charge)
[99] = true, -- Incapacitating Roar
[22570] = true, -- Maim
[102359] = true, -- Mass Entanglement
[5211] = true, -- Mighty Bash (talent)
[163505] = true, -- Rake (stealth)
[106839] = true, -- Skull Bash
[81261] = true, -- Solar Beam
[107566] = true, -- Staggering Shout
--hunter
[3355] = true, --freezing trap
[24335] = true, --wyvern sting
[136634] = true, --narrow escape
--[4167] = true, --web (spider)
--[19503] = true, --scatter shot
[117405] = true, -- Binding Shot
[64803] = true, -- Entrapment
[3355] = true, -- Freezing trap
[24394] = true, -- Intimidation (pet)
[128405] = true, -- Narrow Escape
[136634] = true, -- Narrow Wscape
[24335] = true, -- Wyvern sting
[19386] = true, -- Wyvern sting
--mage
[118] = true, --polymorph sheep
[61305] = true, --polymorph black cat
[28272] = true, --polymorph pig
[61721] = true, --polymorph rabbit
[61780] = true, --polymorph turkey
[28271] = true, --polymorph turtle
[122] = true, --frost nova
[33395] = true, --freeze
[111340] = true, --ice ward
[82691] = true, --ring of frost
[2139] = true, -- Counterspell
[44572] = true, -- Deep Freeze
[58534] = true, -- Deep Freeze
[31661] = true, -- Dragon's Breath
[33395] = true, -- Freeze (pet)
[122] = true, -- Frost Nova
[102051] = true, -- Frostjaw
[157997] = true, -- Ice Nova
[111340] = true, -- Ice Ward
[118] = true, -- Polymorph sheep
[28272] = true, -- Polymorph pig
[126819] = true, -- Polymorph pig 2
[61305] = true, -- Polymorph black cat
[61721] = true, -- Polymorph rabbit
[61780] = true, -- Polymorph turkey
[28271] = true, -- Polymorph turtle
[161354] = true, -- Polymorph Monkey
[161353] = true, -- Polymorph Polar Bear Cub
[161355] = true, -- Polymorph Penguin
[82691] = true, -- Ring of frost
--monk
[116706] = true, --disable
[123393] = true, -- Breath of Fire
[119392] = true, -- Charging Ox Wave
[116706] = true, -- Disable
[120086] = true, -- Fists of Fury
[117418] = true, -- Fists of Fury
[119381] = true, -- Leg Sweep
[115078] = true, -- Paralysis
[116705] = true, -- Spear Hand Strike
--paladin
[105421] = true, --blinding light
[20066] = true, --repentance
--prist
--shackle undead
[8122] = true, --psychic scream
[9484] = true, --shackle undead
[31935] = true, -- Avenger's Shield
[105421] = true, -- Blinding light
[105593] = true, -- Fist of Justice
[853] = true, -- Hammer of Justice
[20066] = true, -- Repentance
[145067] = true, -- Turn Evil
--priest
[605] = true, -- Dominate Mind
[87194] = true, -- Glyph of Mind Blast
[88625] = true, -- Holy Word: Chastise
[64044] = true, -- Psychic Horror
[8122] = true, -- Psychic scream
[9484] = true, -- Shackle undead
[15487] = true, -- Silence
[131556] = true, -- Sin and Punishment
[114404] = true, -- Void Tendril's Grasp
--rogue
[2094] = true, --blind
[1776] = true, --gouge
[6770] = true, --sap
[408] = true, --kidney shot
[1833] = true, --cheap shot
[2094] = true, -- Blind
[1833] = true, -- Cheap shot
[1330] = true, -- Garrote
[1776] = true, -- Gouge
[1766] = true, -- Kick
[408] = true, -- Kidney shot
[6770] = true, -- Sap
[76577] = true, -- Smoke Bomb
--shaman
[51514] = true, --hex
[64695] = true, --earthgrab (earthgrab totem)
--[76780] = true, --bind elemental
[64695] = true, -- Earthgrab (earthgrab totem)
[77505] = true, -- Earthquake
[51514] = true, -- Hex
[118905] = true, -- Static Charge
[51490] = true, -- Thunderstorm
[57994] = true, -- Wind Shear
--warlock
[6358] = true, --seduction (succubus)
[115268] = true, --mesmerize (shivarra)
[118699] = true, --fear
[5484] = true, --howl of terror
[89766] = true, -- Axe Toss (Felguard)
[111397] = true, -- Blood Horror
[170996] = true, -- Debilitate (terrorguard)
[5782] = true, -- Fear
[118699] = true, -- Fear
[5484] = true, -- Howl of terror
[115268] = true, -- Mesmerize (shivarra)
[6789] = true, -- Mortal Coil
[6358] = true, -- Seduction (succubus
[30283] = true, -- Shadowfury
[19647] = true, -- Spell Lock (Felhunters)
[31117] = true, -- Unstable Affliction
--warrior
[5246] = true, --intimidating shout
[107566] = true, --staggering shout
[100] = true, -- Charge
[105771] = true, -- Charge
[118895] = true, -- Dragon Roar
[5246] = true, -- Intimidating shout
[6552] = true, -- Pummel
[132168] = true, -- Shockwave
[107566] = true, -- Staggering shout
[132169] = true, -- Storm Bolt
[7922] = true, -- Warbringer
}
_detalhes.AbsorbSpells = {
+6
View File
@@ -3304,6 +3304,12 @@ local row_on_enter = function (self)
GameTooltip:Show()
end
end
if (self.show == 98021) then
GameTooltip:SetOwner (self, "ANCHOR_TOPLEFT")
GameTooltip:AddLine (Loc ["STRING_SPIRIT_LINK_TOTEM_DESC"])
GameTooltip:Show()
end
--> da zoom no icone
self.icone:SetWidth (17)
+158 -109
View File
@@ -552,8 +552,11 @@ function _detalhes.switch:Config (_,_, atributo, sub_atributo)
return
end
_detalhes.switch.table [_detalhes.switch.current_button].atributo = atributo
_detalhes.switch.table [_detalhes.switch.current_button].sub_atributo = sub_atributo
_detalhes.switch.table [_detalhes.switch.editing_bookmark].atributo = atributo
_detalhes.switch.table [_detalhes.switch.editing_bookmark].sub_atributo = sub_atributo
_detalhes.switch.editing_bookmark = nil
_detalhes.switch:Update()
end
@@ -568,68 +571,71 @@ end
end
end
local paramTable = _detalhes.switch.buttons [number] and _detalhes.switch.buttons [number].funcParam2
if (paramTable) then
local bookmark = _detalhes.switch.table [number]
if (bookmark) then
_detalhes.switch.current_instancia = instance
if (not paramTable.atributo) then
_detalhes:Msg (string.format (Loc ["STRING_SWITCH_SELECTMSG"], number))
if (not bookmark.atributo) then
return _detalhes:Msg (string.format (Loc ["STRING_SWITCH_SELECTMSG"], number))
end
return _detalhes:FastSwitch (paramTable)
_detalhes:FastSwitch (nil, bookmark, number)
--return _detalhes:FastSwitch (paramTable)
end
end
function _detalhes:FastSwitch (_this)
_detalhes.switch.current_button = _this.button
if (not _this.atributo) then --> botão direito
function _detalhes:FastSwitch (button, bookmark, bookmark_number, select_new)
if (select_new or not bookmark.atributo) then
GameCooltip:Reset()
GameCooltip:SetType (3)
GameCooltip:SetFixedParameter (_detalhes.switch.current_instancia)
GameCooltip:SetOwner (_detalhes.switch.buttons [_this.button])
GameCooltip:SetOwner (button)
_detalhes.switch.editing_bookmark = bookmark_number
_detalhes:MontaAtributosOption (_detalhes.switch.current_instancia, _detalhes.switch.Config)
GameCooltip:SetColor (1, {.1, .1, .1, .3})
GameCooltip:SetColor (2, {.1, .1, .1, .3})
GameCooltip:SetOption ("HeightAnchorMod", -7)
GameCooltip:SetBackdrop (1, _detalhes.tooltip_backdrop, backgroundColor, _detalhes.tooltip_border_color)
GameCooltip:SetBackdrop (2, _detalhes.tooltip_backdrop, backgroundColor, _detalhes.tooltip_border_color)
GameCooltip:ShowCooltip()
else --> botão esquerdo
if (IsShiftKeyDown()) then
--> get a closed window or created a new one.
local instance = _detalhes:CreateInstance()
if (not instance) then
_detalhes.switch.CloseMe()
return _detalhes:Msg (Loc ["STRING_WINDOW_NOTFOUND"])
end
_detalhes.switch.current_instancia = instance
end
if (_detalhes.switch.current_instancia.modo == _detalhes._detalhes_props["MODO_ALONE"]) then
_detalhes.switch.current_instancia:AlteraModo (_detalhes.switch.current_instancia, 2)
elseif (_detalhes.switch.current_instancia.modo == _detalhes._detalhes_props["MODO_RAID"]) then
_detalhes.switch.current_instancia:AlteraModo (_detalhes.switch.current_instancia, 2)
end
_detalhes.switch.current_instancia:TrocaTabela (_detalhes.switch.current_instancia, true, _this.atributo, _this.sub_atributo)
_detalhes.switch.CloseMe()
return GameCooltip:ShowCooltip()
end
if (IsShiftKeyDown()) then
--> get a closed window or created a new one.
local instance = _detalhes:CreateInstance()
if (not instance) then
_detalhes.switch.CloseMe()
return _detalhes:Msg (Loc ["STRING_WINDOW_NOTFOUND"])
end
_detalhes.switch.current_instancia = instance
end
if (_detalhes.switch.current_instancia.modo == _detalhes._detalhes_props["MODO_ALONE"]) then
_detalhes.switch.current_instancia:AlteraModo (_detalhes.switch.current_instancia, 2)
elseif (_detalhes.switch.current_instancia.modo == _detalhes._detalhes_props["MODO_RAID"]) then
_detalhes.switch.current_instancia:AlteraModo (_detalhes.switch.current_instancia, 2)
end
_detalhes.switch.current_instancia:TrocaTabela (_detalhes.switch.current_instancia, true, bookmark.atributo, bookmark.sub_atributo)
_detalhes.switch.CloseMe()
end
-- nao tem suporte a solo mode tank mode
-- nao tem suporte a custom até agora, não sei como vai ficar
function _detalhes.switch:InitSwitch()
return _detalhes.switch:Update()
local instancia = _detalhes.tabela_instancias [1]
_detalhes.switch:ShowMe (instancia)
_detalhes.switch:CloseMe()
--return _detalhes.switch:Update()
end
function _detalhes.switch:OnRemoveCustom (CustomIndex)
@@ -655,40 +661,39 @@ function _detalhes.switch:Update()
local x = 10
local y = 5
local jump = false
local got_empty
local hide_the_rest
for i = 1, slots do
local options = _detalhes.switch.table [i]
if (not options) then
options = {atributo = nil, sub_atributo = nil}
_detalhes.switch.table [i] = options
end
local offset = FauxScrollFrame_GetOffset (DetailsSwitchPanelScroll)
local slots_shown = _detalhes.switch.slots
for i = 1, slots_shown do
--bookmark index
local index = (offset * _detalhes.switch.vertical_amt) + i
--button
local button = _detalhes.switch.buttons [i]
if (not button) then
button = _detalhes.switch:NewSwitchButton (_detalhes.switch.frame, i, x, y, jump)
button:SetFrameLevel (_detalhes.switch.frame:GetFrameLevel()+2)
_detalhes.switch.showing = _detalhes.switch.showing + 1
end
local options = _detalhes.switch.table [index]
if (not options and index <= 40) then
options = {}
_detalhes.switch.table [index] = options
end
local param2Table = {
["instancia"] = _detalhes.switch.current_instancia,
["button"] = i,
["atributo"] = options.atributo,
["sub_atributo"] = options.sub_atributo
}
button.funcParam2 = param2Table
button.button2.funcParam2 = param2Table
button.bookmark_number = index --button on icon
button.button2.bookmark_number = index --button on text
local icone
local coords
local name
local vcolor
if (options.sub_atributo) then
if (options and options.sub_atributo) then
if (options.atributo == 5) then --> custom
local CustomObject = _detalhes.custom [options.sub_atributo]
if (not CustomObject) then --> ele já foi deletado
@@ -716,43 +721,32 @@ function _detalhes.switch:Update()
coords = {0, 1, 0, 1}
name = Loc ["STRING_SWITCH_CLICKME"]
vcolor = vertex_color_unknown
got_empty = true
end
--if (hide_the_rest) then
--button:Hide()
--button.button2:Hide()
--button.fundo:Hide()
--else
button:Show()
button.button2:Show()
button.fundo:Show()
button.button2.texto:SetText (name)
button.textureNormal:SetTexture (icone, true)
button.textureNormal:SetTexCoord (_unpack (coords))
button.textureNormal:SetVertexColor (_unpack (vcolor))
button.texturePushed:SetTexture (icone, true)
button.texturePushed:SetTexCoord (_unpack (coords))
button.texturePushed:SetVertexColor (_unpack (vcolor))
button.textureH:SetTexture (icone, true)
button.textureH:SetVertexColor (_unpack (vcolor))
button.textureH:SetTexCoord (_unpack (coords))
button:ChangeIcon (button.textureNormal, button.texturePushed, _, button.textureH)
if (name == Loc ["STRING_SWITCH_CLICKME"]) then
--button.button2.texto:SetTextColor (.3, .3, .3, 1)
button:SetAlpha (0.3)
else
--button.button2.texto:SetTextColor (.8, .8, .8, 1)
button:SetAlpha (1)
end
if (got_empty) then
hide_the_rest = true
end
--end
button:Show()
button.button2:Show()
button.fundo:Show()
button.button2.texto:SetText (name)
button.textureNormal:SetTexture (icone, true)
button.textureNormal:SetTexCoord (_unpack (coords))
button.textureNormal:SetVertexColor (_unpack (vcolor))
button.texturePushed:SetTexture (icone, true)
button.texturePushed:SetTexCoord (_unpack (coords))
button.texturePushed:SetVertexColor (_unpack (vcolor))
button.textureH:SetTexture (icone, true)
button.textureH:SetVertexColor (_unpack (vcolor))
button.textureH:SetTexCoord (_unpack (coords))
button:ChangeIcon (button.textureNormal, button.texturePushed, nil, button.textureH)
if (name == Loc ["STRING_SWITCH_CLICKME"]) then
--button.button2.texto:SetTextColor (.3, .3, .3, 1)
button:SetAlpha (0.3)
else
--button.button2.texto:SetTextColor (.8, .8, .8, 1)
button:SetAlpha (1)
end
if (jump) then
x = x - 125
@@ -765,8 +759,16 @@ function _detalhes.switch:Update()
end
FauxScrollFrame_Update (DetailsSwitchPanelScroll, ceil (40 / _detalhes.switch.vertical_amt) , _detalhes.switch.horizontal_amt, 20)
end
local scroll = CreateFrame ("scrollframe", "DetailsSwitchPanelScroll", DetailsSwitchPanel, "FauxScrollFrameTemplate")
scroll:SetAllPoints()
scroll:SetScript ("OnVerticalScroll", function (self, offset) FauxScrollFrame_OnVerticalScroll (self, offset, 20, _detalhes.switch.Update) end) --altura
scroll.ScrollBar:Hide()
scroll.ScrollBar.ScrollUpButton:Hide()
scroll.ScrollBar.ScrollDownButton:Hide()
function _detalhes.switch:Resize (precisa_mostrar)
local x = 7
@@ -780,18 +782,22 @@ function _detalhes.switch:Resize (precisa_mostrar)
local total_amt = horizontal_amt * vertical_amt
if (precisa_mostrar > total_amt) then
vertical_amt = floor ((window_height - y) / 15)
y_increment = 15
--vertical_amt = floor ((window_height - y) / 15)
--y_increment = 15
end
local size = window_width / horizontal_amt
_detalhes.switch.y_increment = y_increment
local size = window_width / horizontal_amt
local frame = _detalhes.switch.frame
for index, button in ipairs (_detalhes.switch.buttons) do
button:Hide()
end
_detalhes.switch.vertical_amt = vertical_amt
_detalhes.switch.horizontal_amt = horizontal_amt
local i = 1
for vertical = 1, vertical_amt do
x = 7
@@ -875,7 +881,7 @@ function _detalhes.switch:Resize2()
end
local onenter = function (self)
if (not _detalhes.switch.table [self.index].atributo) then
if (not _detalhes.switch.table [self.id].atributo) then
GameCooltip:Reset()
_detalhes:CooltipPreset (1)
GameCooltip:AddLine ("add bookmark")
@@ -939,6 +945,45 @@ local oniconleave = function (self)
end
end
local left_box_on_click = function (self, button)
if (button == "RightButton") then
--select another bookmark
_detalhes:FastSwitch (self, bookmark, self.bookmark_number, true)
else
--change the display
local bookmark = _detalhes.switch.table [self.bookmark_number]
if (bookmark.atributo) then
_detalhes:FastSwitch (self, bookmark, self.bookmark_number)
else
--invalid bookmark, select another bookmark
_detalhes:FastSwitch (self, bookmark, self.bookmark_number, true)
end
end
end
local right_box_on_click = function (self, button)
if (button == "RightButton") then
--close the bookmark menu
_detalhes.switch:CloseMe()
else
--change the display
local bookmark = _detalhes.switch.table [self.bookmark_number]
if (bookmark.atributo) then
_detalhes:FastSwitch (self, bookmark, self.bookmark_number)
else
--invalid bookmark, select another bookmark
_detalhes:FastSwitch (self, bookmark, self.bookmark_number, true)
end
end
end
local change_icon = function (self, icon1, icon2, icon3, icon4)
self:SetNormalTexture (icon1)
self:SetPushedTexture (icon2)
self:SetDisabledTexture (icon3)
self:SetHighlightTexture (icon4, "ADD")
end
function _detalhes.switch:NewSwitchButton (frame, index, x, y, rightButton)
local paramTable = {
@@ -949,13 +994,14 @@ function _detalhes.switch:NewSwitchButton (frame, index, x, y, rightButton)
}
--botao dentro da caixa
local button = gump:NewDetailsButton (frame, frame, _, _detalhes.FastSwitch, nil, paramTable, 15, 15, "", "", "", "",
{rightFunc = {func = _detalhes.FastSwitch, param1 = nil, param2 = {atributo = nil, button = index}}, OnGrab = "PassClick"}, "DetailsSwitchPanelButton_1_"..index)
local button = CreateFrame ("button", "DetailsSwitchPanelButton_1_"..index, frame)
button:SetSize (15, 15)
button:SetPoint ("topleft", frame, "topleft", x, -y)
button.rightButton = rightButton
button.MouseOnEnterHook = oniconenter
button.MouseOnLeaveHook = oniconleave
button:SetScript ("OnMouseDown", left_box_on_click)
button:SetScript ("OnEnter", oniconenter)
button:SetScript ("OnLeave", oniconleave)
button.ChangeIcon = change_icon
button.id = index
--borda
button.fundo = button:CreateTexture (nil, "overlay")
@@ -984,10 +1030,15 @@ function _detalhes.switch:NewSwitchButton (frame, index, x, y, rightButton)
button.line2:SetPoint ("bottomleft", button, "bottomright", fundo_x, fundo_y)
--botao do fundo marrom
local button2 = gump:NewDetailsButton (button, button, _, _detalhes.FastSwitch, nil, paramTable, 1, 1, button.line, "", "", button.line2,
{rightFunc = {func = _detalhes.switch.CloseMe, param1 = nil, param2 = nil}, OnGrab = "PassClick"}, "DetailsSwitchPanelButton_2_"..index)
local button2 = CreateFrame ("button", "DetailsSwitchPanelButton_2_"..index, button)
button2:SetSize (1, 1)
button2:SetPoint ("topleft", button, "topright", 1, 0)
button2:SetPoint ("bottomright", button, "bottomright", 90, 0)
button2:SetScript ("OnMouseDown", right_box_on_click)
button2:SetScript ("OnEnter", onenter)
button2:SetScript ("OnLeave", onleave)
button2.id = index
button.button2 = button2
--icone
@@ -1017,8 +1068,6 @@ function _detalhes.switch:NewSwitchButton (frame, index, x, y, rightButton)
button2.MouseOnLeaveHook = onleave
_detalhes.switch.buttons [index] = button
button.index = index
button2.index = index
return button
end
@@ -1,5 +1,5 @@
DETAILS_STORAGE_VERSION = 3
DETAILS_STORAGE_VERSION = 4
function _detalhes:CreateStorageDB()
DetailsDataStorage = {
@@ -23,7 +23,7 @@ f:SetScript ("OnEvent", function (self, event, addonName)
if (DetailsDataStorage.VERSION < DETAILS_STORAGE_VERSION) then
--> do revisions
if (DetailsDataStorage.VERSION < 3) then
if (DetailsDataStorage.VERSION < 4) then
table.wipe (DetailsDataStorage)
DetailsDataStorage = _detalhes:CreateStorageDB()
end
@@ -262,6 +262,19 @@ local function CreatePluginFrames (data)
EncounterDetails.showing = true
--> [1] button to show [2] button animation: "star", "blink" or true (blink)
EncounterDetails:ShowToolbarIcon (EncounterDetails.ToolbarButton, "star")
--EncounterDetails:SetTutorialCVar ("ENCOUNTER_DETAILS_TUTORIAL1", false)
if (not EncounterDetails:GetTutorialCVar ("ENCOUNTER_DETAILS_TUTORIAL1")) then
EncounterDetails:SetTutorialCVar ("ENCOUNTER_DETAILS_TUTORIAL1", true)
local plugin_icon_alert = CreateFrame ("frame", "EncounterDetailsPopUp1", EncounterDetails.ToolbarButton, "DetailsHelpBoxTemplate")
plugin_icon_alert.ArrowUP:Show()
plugin_icon_alert.ArrowGlowUP:Show()
plugin_icon_alert.Text:SetText ("Encounter Details is Ready!\n\nTake a look in the encounter summary, click here!")
plugin_icon_alert:SetPoint ("bottom", EncounterDetails.ToolbarButton, "top", 0, 30)
plugin_icon_alert:Show()
end
end
--> hide icon on toolbar
@@ -286,6 +299,13 @@ local function CreatePluginFrames (data)
if (EncounterDetailsFrame.ShowType == "graph") then
EncounterDetails:BuildDpsGraphic()
end
--EncounterDetails:SetTutorialCVar ("ENCOUNTER_DETAILS_TUTORIAL2", false)
if (not EncounterDetails:GetTutorialCVar ("ENCOUNTER_DETAILS_TUTORIAL2")) then
EncounterDetails:SetTutorialCVar ("ENCOUNTER_DETAILS_TUTORIAL2", true)
EncounterDetails:ButtonsTutorial()
end
return true
end
@@ -1175,6 +1175,7 @@ do
end
end
-- ~button
--summary
BossFrame.buttonSwitchNormal = DetailsFrameWork:NewDetailsButton (BossFrame, BossFrame, _, BossFrame.switch, "main", nil, 26, 33)
BossFrame.buttonSwitchNormal:SetPoint ("bottomright", BossFrame, "bottomright", -270, 5)
@@ -1212,6 +1213,23 @@ do
aa:SetHeight (33)
aa:SetAllPoints()
--> tutorial frame
function EncounterDetails:ButtonsTutorial()
local tutorial_frame = CreateFrame ("frame", nil, BossFrame)
tutorial_frame:SetFrameStrata ("FULLSCREEN")
tutorial_frame:SetPoint ("topleft", t, "topleft")
tutorial_frame:SetPoint ("bottomright", aa, "bottomright")
local plugin_icon_alert = CreateFrame ("frame", "EncounterDetailsPopUp2", tutorial_frame, "DetailsHelpBoxTemplate")
plugin_icon_alert.ArrowUP:Show()
plugin_icon_alert.ArrowGlowUP:Show()
plugin_icon_alert.Text:SetText ("Select here, the module you want to see:")
plugin_icon_alert:SetPoint ("bottom", tutorial_frame, "top", 0, 30)
plugin_icon_alert:Show()
end
u = BossFrame.buttonSwitchGraphic:CreateTexture (nil, "overlay")
u:SetTexture ("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons")
u:SetTexCoord (0.8984375, 1, 0, 0.515625)
+3 -6
View File
@@ -347,8 +347,7 @@ function _G._detalhes:Start()
_detalhes:AddDefaultCustomDisplays()
--> Reset for the new structure
if (_detalhes_database.last_realversion and _detalhes_database.last_realversion < 65 and enable_reset_warning) then
if (_detalhes_database.last_realversion and _detalhes_database.last_realversion < 66 and enable_reset_warning) then
function _detalhes:ResetDataStorage()
if (not IsAddOnLoaded ("Details_DataStorage")) then
local loaded, reason = LoadAddOn ("Details_DataStorage")
@@ -366,12 +365,10 @@ function _G._detalhes:Start()
end
_detalhes:ScheduleTimer ("ResetDataStorage", 1)
_detalhes:SetTooltipBackdrop (_detalhes.default_profile.tooltip.border_texture, _detalhes.default_profile.tooltip.border_size, table_deepcopy (_detalhes.default_profile.tooltip.border_color))
_detalhes.tooltip.show_amount = true
_detalhes.segments_panic_mode = false
end
if (_detalhes_database.last_realversion and _detalhes_database.last_realversion < 47 and enable_reset_warning) then
for i = #_detalhes.custom, 1, -1 do
_detalhes.atributo_custom:RemoveCustom (i)