From 710a1e6031b2a73a29efec701687e1cb17a07fe1 Mon Sep 17 00:00:00 2001 From: tercio Date: Tue, 3 Jun 2014 16:42:40 -0300 Subject: [PATCH] - Emergencial fix for death logs which sometimes was breaking the addon data capture. - Fixed window alerts which was showing behind the bars. - Fixed a issue where Details! windows wasn't hidden when a pet battle starts. - Fixed a issue with segments menu when a window is placed on the right side of the screen. - Fixed death log issue with friendly fire hits. --- boot.lua | 7 +- classes/classe_combate.lua | 761 +++++++++++------------ classes/classe_damage.lua | 858 +++++++++++++------------- classes/classe_damage_habilidade.lua | 460 +++++++------- classes/classe_energy.lua | 5 - classes/classe_energy_habilidade.lua | 178 +++--- classes/classe_heal.lua | 5 - classes/classe_heal_habilidade.lua | 260 ++++---- classes/classe_others.lua | 5 - classes/classe_others_habilidade.lua | 459 +++++++------- classes/classe_target.lua | 88 +-- classes/container_combatentes.lua | 889 +++++++++++++-------------- classes/container_habilidades.lua | 215 ++++--- core/control.lua | 2 +- core/meta.lua | 1 - core/parser.lua | 64 +- core/util.lua | 5 - framework/cooltip.lua | 9 +- functions/classes.lua | 8 + gumps/janela_custom.lua | 250 +++----- gumps/janela_info.lua | 648 ++++++++++++++++++- gumps/janela_news.lua | 10 +- gumps/janela_principal.lua | 7 +- images/custom_bg.tga | Bin 190846 -> 248798 bytes locales/Details-enUS.lua | 21 +- locales/Details-ptBR.lua | 2 +- startup.lua | 4 + 27 files changed, 2889 insertions(+), 2332 deletions(-) diff --git a/boot.lua b/boot.lua index b9bea979..3fec9c3e 100644 --- a/boot.lua +++ b/boot.lua @@ -8,7 +8,7 @@ _ = nil _detalhes = LibStub("AceAddon-3.0"):NewAddon("_detalhes", "AceTimer-3.0", "AceComm-3.0", "AceSerializer-3.0", "NickTag-1.0", "LibHotCorners") - _detalhes.userversion = "v1.15.3a" --tirar guardian of ancient kingss + _detalhes.userversion = "v1.15.3b" --tirar guardian of ancient kingss _detalhes.version = "Alpha 019" _detalhes.realversion = 19 @@ -40,8 +40,6 @@ do _detalhes.refresh = {} --> armazena as funções para limpar e guardas os dados - Metatable functions _detalhes.clear = {} - --> armazena as fontstring usadas no addon - Store labels (fontstrings) - _detalhes.font_pool = {} --> armazena a config do painel de fast switch _detalhes.switch = {} --> armazena os estilos salvos @@ -127,6 +125,7 @@ do all = 3, --> Everything raid = 4 --> Raid } + --[[ _detalhes.flags = { --> Player and Pet player = 0x00000001,--> player character @@ -141,7 +140,7 @@ do neutral = 0x00000020,--> neutral enemy = 0x00000040--> enemy } - + --]] _detalhes.divisores = { abre = "(", --> open fecha = ")", --> close diff --git a/classes/classe_combate.lua b/classes/classe_combate.lua index f5d99b1e..608adfe6 100644 --- a/classes/classe_combate.lua +++ b/classes/classe_combate.lua @@ -1,415 +1,380 @@ ---[[ --------Details! Addon --------Class Combat - -------This file control combat class. A combat is a object wich hold combat attributes. - -------The numeric part of table is compost by 4 indexes: [1] damage, [2] heal, [3] energies and [4] misc -]] +-- combat class object -local _detalhes = _G._detalhes - ---shortcuts -local combate = _detalhes.combate -local container_combatentes = _detalhes.container_combatentes - ---flags -local REACTION_HOSTILE = 0x00000040 -local CONTROL_PLAYER = 0x00000100 - ---locals -local _setmetatable = setmetatable --> lua api -local _ipairs = ipairs --> lua api -local _pairs = pairs --> lua api -local _bit_band = bit.band --> lua api -local _date = date --> lua api -local _table_remove = table.remove - ---time hold -local _tempo = time() -local _ - ---constants - local class_type_dano = _detalhes.atributos.dano - local class_type_cura = _detalhes.atributos.cura - local class_type_e_energy = _detalhes.atributos.e_energy - local class_type_misc = _detalhes.atributos.misc - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ---[[ __call function, get an actor from current combat. - combatTable ( index, actorName ) - index: container number [1] damage, [2] heal, [3] energies and [4] misc - actorName: name of an actor (player, npc, pet, etc) --]] - -_detalhes.call_combate = function (self, class_type, name) - local container = self[class_type] - local index_mapa = container._NameIndexTable [name] - local actor = container._ActorTable [index_mapa] - return actor -end - -combate.__call = _detalhes.call_combate - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ---[[ Class Constructor ]] -function combate:NovaTabela (iniciada, _tabela_overall, combatId, ...) - - local esta_tabela = {true, true, true, true, true} - - esta_tabela [1] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_DAMAGE_CLASS, esta_tabela, combatId) --> Damage - esta_tabela [2] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_HEAL_CLASS, esta_tabela, combatId) --> Healing - esta_tabela [3] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_ENERGY_CLASS, esta_tabela, combatId) --> Energies - esta_tabela [4] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_MISC_CLASS, esta_tabela, combatId) --> Misc - esta_tabela [5] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_DAMAGE_CLASS, esta_tabela, combatId) --> place holder for customs - - _setmetatable (esta_tabela, combate) - - --> try discover if is a pvp combat - local who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags = ... - if (who_serial) then --> aqui irá identificar o boss ou o oponente - if (alvo_name and _bit_band (alvo_flags, REACTION_HOSTILE) ~= 0) then --> tentando pegar o inimigo pelo alvo - esta_tabela.contra = alvo_name - if (_bit_band (alvo_flags, CONTROL_PLAYER) ~= 0) then - esta_tabela.pvp = true --> o alvo é da facção oposta ou foi dado mind control - end - elseif (who_name and _bit_band (who_flags, REACTION_HOSTILE) ~= 0) then --> tentando pegar o inimigo pelo who caso o mob é quem deu o primeiro hit - esta_tabela.contra = who_name - if (_bit_band (who_flags, CONTROL_PLAYER) ~= 0) then - esta_tabela.pvp = true --> o who é da facção oposta ou foi dado mind control - end - else - esta_tabela.pvp = true --> se ambos são friendly, seria isso um PVP entre jogadores da mesma facções? - end - end - - --> start/end time (duration) - esta_tabela.data_fim = 0 - esta_tabela.data_inicio = 0 - - --> record last event before dead - esta_tabela.last_events_tables = {} - - --> frags - esta_tabela.frags = {} - esta_tabela.frags_need_refresh = false - - --> time data container - esta_tabela.TimeData = _detalhes:TimeDataCreateCombatTables() - - --> Skill cache (not used) - esta_tabela.CombatSkillCache = {} - - -- a tabela sem o tempo de inicio é a tabela descartavel do inicio do addon - if (iniciada) then - esta_tabela.start_time = _tempo - esta_tabela.end_time = nil - else - esta_tabela.start_time = 0 - esta_tabela.end_time = nil - end - - -- o container irá armazenar as classes de dano -- cria um novo container de indexes de seriais de jogadores --parâmetro 1 classe armazenada no container, parâmetro 2 = flag da classe - esta_tabela[1].need_refresh = true - esta_tabela[2].need_refresh = true - esta_tabela[3].need_refresh = true - esta_tabela[4].need_refresh = true - esta_tabela[5].need_refresh = true - - if (_tabela_overall) then --> link é a tabela de combate do overall - esta_tabela[1].shadow = _tabela_overall[1] --> diz ao objeto qual a shadow dele na tabela overall - esta_tabela[2].shadow = _tabela_overall[2] --> diz ao objeto qual a shadow dele na tabela overall - esta_tabela[3].shadow = _tabela_overall[3] --> diz ao objeto qual a shadow dele na tabela overall - esta_tabela[4].shadow = _tabela_overall[4] --> diz ao objeto qual a shadow dele na tabela overall - end - - -- abriga a tabela contendo o total de cada atributo - -- esta_tabela.barra_total = barra_total:NovaBarra() - --> barra total movido para um simples membro do combate: - esta_tabela.totals = { - 0, --> dano - 0, --> cura - {--> e_energy - mana = 0, --> mana - e_rage = 0, --> rage - e_energy = 0, --> energy (rogues cat) - runepower = 0 --> runepower (dk) - }, - {--> misc - cc_break = 0, --> armazena quantas quebras de CC - ress = 0, --> armazena quantos pessoas ele reviveu - interrupt = 0, --> armazena quantos interrupt a pessoa deu - dispell = 0, --> armazena quantos dispell esta pessoa recebeu - dead = 0, --> armazena quantas vezes essa pessia morreu - cooldowns_defensive = 0, --> armazena quantos cooldowns a raid usou - buff_uptime = 0, --> armazena quantos cooldowns a raid usou - debuff_uptime = 0 --> armazena quantos cooldowns a raid usou - } - } - - esta_tabela.totals_grupo = { - 0, --> dano - 0, --> cura - {--> e_energy - mana = 0, --> mana - e_rage = 0, --> rage - e_energy = 0, --> energy (rogues cat) - runepower = 0 --> runepower (dk) - }, - {--> misc - cc_break = 0, --> armazena quantas quebras de CC - ress = 0, --> armazena quantos pessoas ele reviveu - interrupt = 0, --> armazena quantos interrupt a pessoa deu - dispell = 0, --> armazena quantos dispell esta pessoa recebeu - dead = 0, --> armazena quantas vezes essa oessia morreu - cooldowns_defensive = 0, --> armazena quantos cooldowns a raid usou - buff_uptime = 0, - debuff_uptime = 0 - } - } - - return esta_tabela -end - -function combate:GetTimeData (name) - - return self.TimeData [name] - -end - -function combate:TravarTempos() - --é necessário travar o tempo em todos os atributos do combate. - - if (self [1]) then - for _, jogador in _ipairs (self [1]._ActorTable) do --> damage - if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo - jogador:TerminarTempo() - jogador:Iniciar (false) --trava o dps do jogador - --jogador.last_events_table = _detalhes:CreateActorLastEventTable() - end - end - else - --print ("combat [1] doesn't exist.") - end - if (self [2]) then - for _, jogador in _ipairs (self [2]._ActorTable) do --> healing - if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo - jogador:TerminarTempo() - jogador:Iniciar (false) --trava o dps do jogador - --print ("travando o tempo de",jogador.nome, jogador.end_time) - --jogador.last_events_table = _detalhes:CreateActorLastEventTable() - end - end - else - --print ("combat [2] doesn't exist.") - end -end - -function combate:UltimaAcao (tempo) - if (tempo) then - self.last_event = tempo - else - return self.last_event - end -end - -function combate:GetDate() - return self.data_inicio, self.data_fim -end - -function combate:seta_data (tipo) - if (tipo == _detalhes._detalhes_props.DATA_TYPE_START) then - self.data_inicio = _date ("%H:%M:%S") - elseif (tipo == _detalhes._detalhes_props.DATA_TYPE_END) then - self.data_fim = _date ("%H:%M:%S") - end -end - -function combate:GetCombatName (try_find) - if (self.is_pvp) then - return self.is_pvp.name - - elseif (self.is_boss) then - return self.is_boss.encounter - - elseif (self.is_tras) then - return Loc ["STRING_SEGMENT_TRASH"] - - else - if (self.enemy) then - return self.enemy - end - - if (try_find) then - return _detalhes:FindEnemy() - end - - end - - return Loc ["STRING_UNKNOW"] -end - -function combate:GetActorList (container) - return self [container]._ActorTable -end - -function combate:GetCombatTime() - if (self.end_time) then - --print ("tem end time") - return self.end_time - self.start_time - elseif (self.start_time and _detalhes.in_combat) then - --print ("tem start time e esta em combate") - return _tempo - self.start_time - else - --print ("retornando zero") - return 0 - end -end + local _detalhes = _G._detalhes + local _ --[[global]] DETAILS_TOTALS_ONLYGROUP = true -function combate:GetTotal (attribute, subAttribute, onlyGroup) - if (attribute == 1 or attribute == 2) then - if (onlyGroup) then - return self.totals_grupo [attribute] - else - return self.totals [attribute] - end - - elseif (attribute == 3 or attribute == 4) then - local subName = _detalhes:GetInternalSubAttributeName (attribute, subAttribute) - if (onlyGroup) then - return self.totals_grupo [attribute] [subName] - else - return self.totals [attribute] [subName] - end +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers + + local _setmetatable = setmetatable -- lua local + local _ipairs = ipairs -- lua local + local _pairs = pairs -- lua local + local _bit_band = bit.band -- lua local + local _date = date -- lua local + local _table_remove = table.remove -- lua local + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants + + local combate = _detalhes.combate + local container_combatentes = _detalhes.container_combatentes + local class_type_dano = _detalhes.atributos.dano + local class_type_cura = _detalhes.atributos.cura + local class_type_e_energy = _detalhes.atributos.e_energy + local class_type_misc = _detalhes.atributos.misc + + local REACTION_HOSTILE = 0x00000040 + local CONTROL_PLAYER = 0x00000100 + + local _tempo = time() + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> api functions + + --combat (container type, actor name) + _detalhes.call_combate = function (self, class_type, name) + local container = self[class_type] + local index_mapa = container._NameIndexTable [name] + local actor = container._ActorTable [index_mapa] + return actor end - return 0 -end + combate.__call = _detalhes.call_combate -function combate:seta_tempo_decorrido() - self.end_time = _tempo -end - -function _detalhes.refresh:r_combate (tabela_combate, shadow) - _setmetatable (tabela_combate, _detalhes.combate) - tabela_combate.__index = _detalhes.combate - tabela_combate.shadow = shadow -end - -function _detalhes.clear:c_combate (tabela_combate) - --tabela_combate.__index = {} - tabela_combate.__index = nil - tabela_combate.__call = {} - tabela_combate._combat_table = nil - tabela_combate.shadow = nil -end - -combate.__sub = function (combate1, combate2) - - if (combate1 ~= _detalhes.tabela_overall) then - return + --get the start date and end date + function combate:GetDate() + return self.data_inicio, self.data_fim end - - --> sub dano - for index, actor_T2 in _ipairs (combate2[1]._ActorTable) do - local actor_T1 = combate1[1]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) - actor_T1 = actor_T1 - actor_T2 - actor_T2:subtract_total (combate1) - end - combate1 [1].need_refresh = true - - --> sub heal - for index, actor_T2 in _ipairs (combate2[2]._ActorTable) do - local actor_T1 = combate1[2]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) - actor_T1 = actor_T1 - actor_T2 - actor_T2:subtract_total (combate1) - end - combate1 [2].need_refresh = true - - --> sub energy - for index, actor_T2 in _ipairs (combate2[3]._ActorTable) do - local actor_T1 = combate1[3]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) - actor_T1 = actor_T1 - actor_T2 - actor_T2:subtract_total (combate1) - end - combate1 [3].need_refresh = true - - --> sub misc - for index, actor_T2 in _ipairs (combate2[4]._ActorTable) do - local actor_T1 = combate1[4]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) - actor_T1 = actor_T1 - actor_T2 - actor_T2:subtract_total (combate1) - end - combate1 [4].need_refresh = true - - --> reduz o tempo - combate1.start_time = combate1.start_time + (combate2.end_time - combate2.start_time) - - --> apaga as mortes da luta diminuida - local amt_mortes = #combate2.last_events_tables --> quantas mortes teve nessa luta - if (amt_mortes > 0) then - for i = #combate1.last_events_tables, #combate1.last_events_tables-amt_mortes, -1 do - _table_remove (combate1.last_events_tables, #combate1.last_events_tables) + + --return data for charts + function combate:GetTimeData (name) + return self.TimeData [name] + end + + --return the name of the encounter or enemy + function combate:GetCombatName (try_find) + if (self.is_pvp) then + return self.is_pvp.name + elseif (self.is_boss) then + return self.is_boss.encounter + elseif (self.is_tras) then + return Loc ["STRING_SEGMENT_TRASH"] + else + if (self.enemy) then + return self.enemy + end + if (try_find) then + return _detalhes:FindEnemy() end end + return Loc ["STRING_UNKNOW"] + end + + --return a numeric table with all actors on the specific containter + function combate:GetActorList (container) + return self [container]._ActorTable + end + + --return the combat time in seconds + function combate:GetCombatTime() + if (self.end_time) then + return self.end_time - self.start_time + elseif (self.start_time and _detalhes.in_combat) then + return _tempo - self.start_time + else + return 0 + end + end + + --return the total of a specific attribute + function combate:GetTotal (attribute, subAttribute, onlyGroup) + if (attribute == 1 or attribute == 2) then + if (onlyGroup) then + return self.totals_grupo [attribute] + else + return self.totals [attribute] + end + + elseif (attribute == 3 or attribute == 4) then + local subName = _detalhes:GetInternalSubAttributeName (attribute, subAttribute) + if (onlyGroup) then + return self.totals_grupo [attribute] [subName] + else + return self.totals [attribute] [subName] + end + end + return 0 + end + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals + + --class constructor + function combate:NovaTabela (iniciada, _tabela_overall, combatId, ...) + + local esta_tabela = {true, true, true, true, true} - --> frags - for fragName, fragAmount in pairs (combate2.frags) do - if (fragAmount) then - if (combate1.frags [fragName]) then - combate1.frags [fragName] = combate1.frags [fragName] - fragAmount - else - combate1.frags [fragName] = fragAmount + esta_tabela [1] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_DAMAGE_CLASS, esta_tabela, combatId) --> Damage + esta_tabela [2] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_HEAL_CLASS, esta_tabela, combatId) --> Healing + esta_tabela [3] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_ENERGY_CLASS, esta_tabela, combatId) --> Energies + esta_tabela [4] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_MISC_CLASS, esta_tabela, combatId) --> Misc + esta_tabela [5] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_DAMAGE_CLASS, esta_tabela, combatId) --> place holder for customs + + _setmetatable (esta_tabela, combate) + + --> try discover if is a pvp combat + local who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags = ... + if (who_serial) then --> aqui irá identificar o boss ou o oponente + if (alvo_name and _bit_band (alvo_flags, REACTION_HOSTILE) ~= 0) then --> tentando pegar o inimigo pelo alvo + esta_tabela.contra = alvo_name + if (_bit_band (alvo_flags, CONTROL_PLAYER) ~= 0) then + esta_tabela.pvp = true --> o alvo é da facção oposta ou foi dado mind control + end + elseif (who_name and _bit_band (who_flags, REACTION_HOSTILE) ~= 0) then --> tentando pegar o inimigo pelo who caso o mob é quem deu o primeiro hit + esta_tabela.contra = who_name + if (_bit_band (who_flags, CONTROL_PLAYER) ~= 0) then + esta_tabela.pvp = true --> o who é da facção oposta ou foi dado mind control + end + else + esta_tabela.pvp = true --> se ambos são friendly, seria isso um PVP entre jogadores da mesma facções? + end + end + + --> start/end time (duration) + esta_tabela.data_fim = 0 + esta_tabela.data_inicio = 0 + + --> record last event before dead + esta_tabela.last_events_tables = {} + + --> frags + esta_tabela.frags = {} + esta_tabela.frags_need_refresh = false + + --> time data container + esta_tabela.TimeData = _detalhes:TimeDataCreateCombatTables() + + --> Skill cache (not used) + esta_tabela.CombatSkillCache = {} + + -- a tabela sem o tempo de inicio é a tabela descartavel do inicio do addon + if (iniciada) then + esta_tabela.start_time = _tempo + esta_tabela.end_time = nil + else + esta_tabela.start_time = 0 + esta_tabela.end_time = nil + end + + -- o container irá armazenar as classes de dano -- cria um novo container de indexes de seriais de jogadores --parâmetro 1 classe armazenada no container, parâmetro 2 = flag da classe + esta_tabela[1].need_refresh = true + esta_tabela[2].need_refresh = true + esta_tabela[3].need_refresh = true + esta_tabela[4].need_refresh = true + esta_tabela[5].need_refresh = true + + if (_tabela_overall) then --> link é a tabela de combate do overall + esta_tabela[1].shadow = _tabela_overall[1] --> diz ao objeto qual a shadow dele na tabela overall + esta_tabela[2].shadow = _tabela_overall[2] --> diz ao objeto qual a shadow dele na tabela overall + esta_tabela[3].shadow = _tabela_overall[3] --> diz ao objeto qual a shadow dele na tabela overall + esta_tabela[4].shadow = _tabela_overall[4] --> diz ao objeto qual a shadow dele na tabela overall + end + + esta_tabela.totals = { + 0, --> dano + 0, --> cura + {--> e_energy + mana = 0, --> mana + e_rage = 0, --> rage + e_energy = 0, --> energy (rogues cat) + runepower = 0 --> runepower (dk) + }, + {--> misc + cc_break = 0, --> armazena quantas quebras de CC + ress = 0, --> armazena quantos pessoas ele reviveu + interrupt = 0, --> armazena quantos interrupt a pessoa deu + dispell = 0, --> armazena quantos dispell esta pessoa recebeu + dead = 0, --> armazena quantas vezes essa pessia morreu + cooldowns_defensive = 0, --> armazena quantos cooldowns a raid usou + buff_uptime = 0, --> armazena quantos cooldowns a raid usou + debuff_uptime = 0 --> armazena quantos cooldowns a raid usou + } + } + + esta_tabela.totals_grupo = { + 0, --> dano + 0, --> cura + {--> e_energy + mana = 0, --> mana + e_rage = 0, --> rage + e_energy = 0, --> energy (rogues cat) + runepower = 0 --> runepower (dk) + }, + {--> misc + cc_break = 0, --> armazena quantas quebras de CC + ress = 0, --> armazena quantos pessoas ele reviveu + interrupt = 0, --> armazena quantos interrupt a pessoa deu + dispell = 0, --> armazena quantos dispell esta pessoa recebeu + dead = 0, --> armazena quantas vezes essa oessia morreu + cooldowns_defensive = 0, --> armazena quantos cooldowns a raid usou + buff_uptime = 0, + debuff_uptime = 0 + } + } + + return esta_tabela + end + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> core + + --trava o tempo dos jogadores após o término do combate. + function combate:TravarTempos() + if (self [1]) then + for _, jogador in _ipairs (self [1]._ActorTable) do --> damage + if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo + jogador:TerminarTempo() + jogador:Iniciar (false) --trava o dps do jogador end end end - combate1.frags_need_refresh = true - - return combate1 - -end - -combate.__add = function (combate1, combate2) - - local all_containers = {combate2 [class_type_dano]._ActorTable, combate2 [class_type_cura]._ActorTable, combate2 [class_type_e_energy]._ActorTable, combate2 [class_type_misc]._ActorTable} - - --actor.boss_fight_component - --actor.fight_component - --combat.is_boss - --combat.instance_type -- party raid - - for class_type, actor_container in ipairs (all_containers) do - for _, actor in ipairs (actor_container) do - local shadow - - if (class_type == class_type_dano) then - shadow = _detalhes.atributo_damage:r_connect_shadow (actor, true) - elseif (class_type == class_type_cura) then - shadow = _detalhes.atributo_heal:r_connect_shadow (actor, true) - elseif (class_type == class_type_e_energy) then - shadow = _detalhes.atributo_energy:r_connect_shadow (actor, true) - elseif (class_type == class_type_misc) then - shadow = _detalhes.atributo_misc:r_connect_shadow (actor, true) + if (self [2]) then + for _, jogador in _ipairs (self [2]._ActorTable) do --> healing + if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo + jogador:TerminarTempo() + jogador:Iniciar (false) --trava o dps do jogador + end end - - shadow.boss_fight_component = actor.boss_fight_component - shadow.fight_component = actor.fight_component - shadow.grupo = actor.grupo - - --if (shadow:EstaoLinkados (actor)) then - -- shadow:FazLinkagem (actor) - --end end end - - --if (combate2.end_time and combate2.start_time) then - -- combate1.start_time = combate1.start_time - (combate1.end_time - combate1.start_time) - --end - - return combate1 -end -function _detalhes:UpdateCombat() - _tempo = _detalhes._tempo -end + function combate:UltimaAcao (tempo) + if (tempo) then + self.last_event = tempo + else + return self.last_event + end + end + + function combate:seta_data (tipo) + if (tipo == _detalhes._detalhes_props.DATA_TYPE_START) then + self.data_inicio = _date ("%H:%M:%S") + elseif (tipo == _detalhes._detalhes_props.DATA_TYPE_END) then + self.data_fim = _date ("%H:%M:%S") + end + end + + function combate:seta_tempo_decorrido() + self.end_time = _tempo + end + + function _detalhes.refresh:r_combate (tabela_combate, shadow) + _setmetatable (tabela_combate, _detalhes.combate) + tabela_combate.__index = _detalhes.combate + tabela_combate.shadow = shadow + end + + function _detalhes.clear:c_combate (tabela_combate) + --tabela_combate.__index = {} + tabela_combate.__index = nil + tabela_combate.__call = {} + tabela_combate._combat_table = nil + tabela_combate.shadow = nil + end + + combate.__sub = function (combate1, combate2) + + if (combate1 ~= _detalhes.tabela_overall) then + return + end + + --> sub dano + for index, actor_T2 in _ipairs (combate2[1]._ActorTable) do + local actor_T1 = combate1[1]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) + actor_T1 = actor_T1 - actor_T2 + actor_T2:subtract_total (combate1) + end + combate1 [1].need_refresh = true + + --> sub heal + for index, actor_T2 in _ipairs (combate2[2]._ActorTable) do + local actor_T1 = combate1[2]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) + actor_T1 = actor_T1 - actor_T2 + actor_T2:subtract_total (combate1) + end + combate1 [2].need_refresh = true + + --> sub energy + for index, actor_T2 in _ipairs (combate2[3]._ActorTable) do + local actor_T1 = combate1[3]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) + actor_T1 = actor_T1 - actor_T2 + actor_T2:subtract_total (combate1) + end + combate1 [3].need_refresh = true + + --> sub misc + for index, actor_T2 in _ipairs (combate2[4]._ActorTable) do + local actor_T1 = combate1[4]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true) + actor_T1 = actor_T1 - actor_T2 + actor_T2:subtract_total (combate1) + end + combate1 [4].need_refresh = true + + --> reduz o tempo + combate1.start_time = combate1.start_time + (combate2.end_time - combate2.start_time) + + --> apaga as mortes da luta diminuida + local amt_mortes = #combate2.last_events_tables --> quantas mortes teve nessa luta + if (amt_mortes > 0) then + for i = #combate1.last_events_tables, #combate1.last_events_tables-amt_mortes, -1 do + _table_remove (combate1.last_events_tables, #combate1.last_events_tables) + end + end + + --> frags + for fragName, fragAmount in pairs (combate2.frags) do + if (fragAmount) then + if (combate1.frags [fragName]) then + combate1.frags [fragName] = combate1.frags [fragName] - fragAmount + else + combate1.frags [fragName] = fragAmount + end + end + end + combate1.frags_need_refresh = true + + return combate1 + + end + + combate.__add = function (combate1, combate2) + + local all_containers = {combate2 [class_type_dano]._ActorTable, combate2 [class_type_cura]._ActorTable, combate2 [class_type_e_energy]._ActorTable, combate2 [class_type_misc]._ActorTable} + + for class_type, actor_container in ipairs (all_containers) do + for _, actor in ipairs (actor_container) do + local shadow + + if (class_type == class_type_dano) then + shadow = _detalhes.atributo_damage:r_connect_shadow (actor, true) + elseif (class_type == class_type_cura) then + shadow = _detalhes.atributo_heal:r_connect_shadow (actor, true) + elseif (class_type == class_type_e_energy) then + shadow = _detalhes.atributo_energy:r_connect_shadow (actor, true) + elseif (class_type == class_type_misc) then + shadow = _detalhes.atributo_misc:r_connect_shadow (actor, true) + end + + shadow.boss_fight_component = actor.boss_fight_component + shadow.fight_component = actor.fight_component + shadow.grupo = actor.grupo + end + end + + return combate1 + end + + function _detalhes:UpdateCombat() + _tempo = _detalhes._tempo + end diff --git a/classes/classe_damage.lua b/classes/classe_damage.lua index 5ec7fe33..2d8586f1 100644 --- a/classes/classe_damage.lua +++ b/classes/classe_damage.lua @@ -1,132 +1,73 @@ ---why do a cleanup on classes today if i can do tomorrow? +-- damage object ---lua locals -local _cstr = string.format -local _math_floor = math.floor -local _table_sort = table.sort -local _table_insert = table.insert -local _table_size = table.getn -local _setmetatable = setmetatable -local _getmetatable = getmetatable -local _ipairs = ipairs -local _pairs = pairs -local _rawget= rawget -local _math_min = math.min -local _math_max = math.max -local _bit_band = bit.band -local _unpack = unpack -local _type = type ---api locals -local _GetSpellInfo = _detalhes.getspellinfo -local GameTooltip = GameTooltip -local _IsInRaid = IsInRaid -local _IsInGroup = IsInGroup + local _detalhes = _G._detalhes + local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" ) + local gump = _detalhes.gump + local _ -local _detalhes = _G._detalhes -local AceLocale = LibStub ("AceLocale-3.0") -local Loc = AceLocale:GetLocale ( "Details" ) +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers ---constants -local gump = _detalhes.gump -local _ + local _cstr = string.format --lua local + local _math_floor = math.floor --lua local + local _table_sort = table.sort --lua local + local _table_insert = table.insert --lua local + local _table_size = table.getn --lua local + local _setmetatable = setmetatable --lua local + local _getmetatable = getmetatable --lua local + local _ipairs = ipairs --lua local + local _pairs = pairs --lua local + local _rawget= rawget --lua local + local _math_min = math.min --lua local + local _math_max = math.max --lua local + local _bit_band = 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 = _detalhes.getspellinfo --details api -local alvo_da_habilidade = _detalhes.alvo_da_habilidade -local container_habilidades = _detalhes.container_habilidades -local container_combatentes = _detalhes.container_combatentes -local container_pets = _detalhes.container_pets -local atributo_damage = _detalhes.atributo_damage -local atributo_misc = _detalhes.atributo_misc -local habilidade_dano = _detalhes.habilidade_dano -local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants -local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC -local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS -local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE + local alvo_da_habilidade = _detalhes.alvo_da_habilidade + local container_habilidades = _detalhes.container_habilidades + local container_combatentes = _detalhes.container_combatentes + local atributo_damage = _detalhes.atributo_damage + local atributo_misc = _detalhes.atributo_misc + local habilidade_dano = _detalhes.habilidade_dano + local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS + local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS + local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE -local modo_ALONE = _detalhes.modos.alone -local modo_GROUP = _detalhes.modos.group -local modo_ALL = _detalhes.modos.all + local modo_GROUP = _detalhes.modos.group + local modo_ALL = _detalhes.modos.all -local class_type = _detalhes.atributos.dano + local class_type = _detalhes.atributos.dano -local DATA_TYPE_START = _detalhes._detalhes_props.DATA_TYPE_START -local DATA_TYPE_END = _detalhes._detalhes_props.DATA_TYPE_END + local ToKFunctions = _detalhes.ToKFunctions + local SelectedToKFunction = ToKFunctions [1] + local UsingCustomRightText = false + local FormatTooltipNumber = ToKFunctions [8] + local TooltipMaximizedMethod = 1 -local DFLAG_player = _detalhes.flags.player -local DFLAG_group = _detalhes.flags.in_group -local DFLAG_player_group = _detalhes.flags.player_in_group + local CLASS_ICON_TCOORDS = _G.CLASS_ICON_TCOORDS -local div_abre = _detalhes.divisores.abre -local div_fecha = _detalhes.divisores.fecha -local div_lugar = _detalhes.divisores.colocacao + local key_overlay = {1, 1, 1, .1} + local key_overlay_press = {1, 1, 1, .2} + local headerColor = "yellow" -local ToKFunctions = _detalhes.ToKFunctions -local SelectedToKFunction = ToKFunctions [1] -local UsingCustomRightText = false + local info = _detalhes.janela_info + local keyName -local FormatTooltipNumber = ToKFunctions [8] -local TooltipMaximizedMethod = 1 - -local CLASS_ICON_TCOORDS = _G.CLASS_ICON_TCOORDS - -local key_overlay = {1, 1, 1, .1} -local key_overlay_press = {1, 1, 1, .2} - -local headerColor = "yellow" - -local info = _detalhes.janela_info -local keyName - -function atributo_damage:NovaTabela (serial, nome, link) - - --> constructor - local _new_damageActor = { - - --> dps do objeto inicia sempre desligado - tipo = class_type, --> atributo 1 = dano - - total = 0, - total_without_pet = 0, - custom = 0, - - damage_taken = 0, --> total de dano que este jogador levou - damage_from = {}, --> armazena os nomes que deram dano neste jogador - - dps_started = false, - last_event = 0, - on_hold = false, - delay = 0, - last_value = nil, --> ultimo valor que este jogador teve, salvo quando a barra dele é atualizada - last_dps = 0, - - end_time = nil, - start_time = 0, - - pets = {}, --> armazena os nomes dos pets já com a tag do dono: pet name - - friendlyfire_total = 0, - friendlyfire = container_combatentes:NovoContainer (container_friendlyfire), - - --container armazenará os seriais dos alvos que o player aplicou dano - targets = container_combatentes:NovoContainer (container_damage_target), - - --container armazenará os IDs das habilidades usadas por este jogador - spell_tables = container_habilidades:NovoContainer (container_damage) - } + local OBJECT_TYPE_PLAYER = 0x00000400 - _setmetatable (_new_damageActor, atributo_damage) - - if (link) then --> se não for a shadow - _new_damageActor.last_events_table = _detalhes:CreateActorLastEventTable() - _new_damageActor.last_events_table.original = true - - _new_damageActor.targets.shadow = link.targets - _new_damageActor.spell_tables.shadow = link.spell_tables - _new_damageActor.friendlyfire.shadow = link.friendlyfire - end - - return _new_damageActor -end + local ntable = {} --temp + local vtable = {} --temp + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> exported functions --[[exported]] function _detalhes:CreateActorLastEventTable() local t = { {}, {}, {}, {}, {}, {}, {}, {} } @@ -187,29 +128,14 @@ end end --[[ exported]] function _detalhes:IsPlayer() - if (self.flags) then - if (_bit_band (self.flag, 0x00000001) ~= 0) then + if (self.flag_original) then + if (_bit_band (self.flag_original, OBJECT_TYPE_PLAYER) ~= 0) then return true end end return false end -local sortEnemies = function (t1, t2) - local a = _bit_band (t1.flag_original, 0x00000060) - local b = _bit_band (t2.flag_original, 0x00000060) - - if (a ~= 0 and b ~= 0) then - return t1.total > t2.total - elseif (a ~= 0 and b == 0) then - return true - elseif (a == 0 and b ~= 0) then - return false - end - - return false -end - --[[exported]] function _detalhes:ContainerSortEnemies (container, amount, keyName2) keyName = keyName2 @@ -230,338 +156,428 @@ end return amount, total end -function atributo_damage:ContainerRefreshDps (container, combat_time) +--[[Exported]] function _detalhes:TooltipForCustom (barra) + GameCooltip:AddLine (Loc ["STRING_LEFT_CLICK_SHARE"]) + return true + end - if (_detalhes.time_type == 2 or not _detalhes:CaptureGet ("damage")) then - for _, actor in _ipairs (container) do - if (actor.grupo) then - actor.last_dps = actor.total / combat_time - else +--[[exported]] function _detalhes.Sort1 (table1, table2) + return table1 [1] > table2 [1] + end + +--[[exported]] function _detalhes.Sort2 (table1, table2) + return table1 [2] > table2 [2] + end + +--[[exported]] function _detalhes.Sort3 (table1, table2) + return table1 [3] > table2 [3] + end + +--[[exported]] function _detalhes.Sort4 (table1, table2) + return table1 [4] > table2 [4] + end + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals + + function atributo_damage:NovaTabela (serial, nome, link) + + --> constructor + local _new_damageActor = { + + tipo = class_type, + + total = 0, + total_without_pet = 0, + custom = 0, + + damage_taken = 0, + damage_from = {}, + + dps_started = false, + last_event = 0, + on_hold = false, + delay = 0, + last_value = nil, + last_dps = 0, + + end_time = nil, + start_time = 0, + + pets = {}, + + friendlyfire_total = 0, + friendlyfire = container_combatentes:NovoContainer (container_friendlyfire), + + targets = container_combatentes:NovoContainer (container_damage_target), + spell_tables = container_habilidades:NovoContainer (container_damage) + } + + _setmetatable (_new_damageActor, atributo_damage) + + if (link) then + _new_damageActor.last_events_table = _detalhes:CreateActorLastEventTable() + _new_damageActor.last_events_table.original = true + + _new_damageActor.targets.shadow = link.targets + _new_damageActor.spell_tables.shadow = link.spell_tables + _new_damageActor.friendlyfire.shadow = link.friendlyfire + end + + return _new_damageActor + end + + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> special cases + + -- enemies (sort function) + local sortEnemies = function (t1, t2) + local a = _bit_band (t1.flag_original, 0x00000060) + local b = _bit_band (t2.flag_original, 0x00000060) + + if (a ~= 0 and b ~= 0) then + return t1.total > t2.total + elseif (a ~= 0 and b == 0) then + return true + elseif (a == 0 and b ~= 0) then + return false + end + + return false + end + + -- dps (calculate dps for actors) + function atributo_damage:ContainerRefreshDps (container, combat_time) + if (_detalhes.time_type == 2 or not _detalhes:CaptureGet ("damage")) then + for _, actor in _ipairs (container) do + if (actor.grupo) then + actor.last_dps = actor.total / combat_time + else + actor.last_dps = actor.total / actor:Tempo() + end + end + else + for _, actor in _ipairs (container) do actor.last_dps = actor.total / actor:Tempo() end end - else - for _, actor in _ipairs (container) do - actor.last_dps = actor.total / actor:Tempo() - end end - -end -function _detalhes:ToolTipFrags (instancia, frag, esta_barra, keydown) +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> frags - --vardump (frag) - - 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 ]] + function _detalhes:ToolTipFrags (instancia, frag, esta_barra, keydown) - if (frag_actor) then + local name = frag [1] + local GameCooltip = GameCooltip - local damage_taken_table = {} - - local took_damage_from = frag_actor.damage_from - local total_damage_taken = frag_actor.damage_taken - - for aggressor, _ in _pairs (took_damage_from) do + --> mantendo a função o mais low level possível + local damage_container = instancia.showing [1] - local damager_actor = damage_container._ActorTable [damage_container._NameIndexTable [ aggressor ]] + local frag_actor = damage_container._ActorTable [damage_container._NameIndexTable [ name ]] + + if (frag_actor) then - 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 damage_taken_table = {} + + local took_damage_from = frag_actor.damage_from + local total_damage_taken = frag_actor.damage_taken + + for aggressor, _ in _pairs (took_damage_from) do - local targets = damager_actor.targets + local damager_actor = damage_container._ActorTable [damage_container._NameIndexTable [ aggressor ]] - local specific_target = targets._ActorTable [targets._NameIndexTable [ name ]] --> é ele mesmo - if (specific_target) then - damage_taken_table [#damage_taken_table+1] = {aggressor, specific_target.total, damager_actor.classe} + 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 targets = damager_actor.targets + + local specific_target = targets._ActorTable [targets._NameIndexTable [ name ]] --> é ele mesmo + if (specific_target) then + damage_taken_table [#damage_taken_table+1] = {aggressor, specific_target.total, damager_actor.classe} + end end end - end - if (#damage_taken_table > 0) then + if (#damage_taken_table > 0) then + + _table_sort (damage_taken_table, _detalhes.Sort2) + + GameCooltip:AddLine (Loc ["STRING_DAMAGE_FROM"], nil, nil, headerColor, nil, 12) + GameCooltip:AddIcon ([[Interface\Addons\Details\images\icons]], 1, 1, 14, 14, 0.126953125, 0.1796875, 0, 0.0546875) - _table_sort (damage_taken_table, _detalhes.Sort2) - - GameCooltip:AddLine (Loc ["STRING_DAMAGE_FROM"], nil, nil, headerColor, nil, 12) - GameCooltip:AddIcon ([[Interface\Addons\Details\images\icons]], 1, 1, 14, 14, 0.126953125, 0.1796875, 0, 0.0546875) - - local min = 6 - local ismaximized = false - if (keydown == "shift" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3) then - min = 99 - ismaximized = true - end - - if (ismaximized) then - --highlight shift key - GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, 24, 12, 0, 1, 0, 0.640625, key_overlay_press) - GameCooltip:AddStatusBar (100, 1, .1, .1, .1, 1) - else - GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, 24, 12, 0, 1, 0, 0.640625, key_overlay) - GameCooltip:AddStatusBar (100, 1, .1, .1, .1, .3) - end - - for i = 1, math.min (min, #damage_taken_table) do - - local t = damage_taken_table [i] - - GameCooltip:AddLine (t [1], FormatTooltipNumber (_, t [2])) - local classe = t [3] - if (not classe) then - classe = "UNKNOW" + local min = 6 + local ismaximized = false + if (keydown == "shift" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3) then + min = 99 + ismaximized = true end - if (classe == "UNKNOW") then - GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, 14, 14, .25, .5, 0, 1) + if (ismaximized) then + --highlight shift key + GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, 24, 12, 0, 1, 0, 0.640625, key_overlay_press) + GameCooltip:AddStatusBar (100, 1, .1, .1, .1, 1) else - GameCooltip:AddIcon (instancia.row_info.icon_file, nil, nil, 14, 14, _unpack (_detalhes.class_coords [classe])) + GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, 24, 12, 0, 1, 0, 0.640625, key_overlay) + GameCooltip:AddStatusBar (100, 1, .1, .1, .1, .3) end - _detalhes:AddTooltipBackgroundStatusbar() + + for i = 1, math.min (min, #damage_taken_table) do + + local t = damage_taken_table [i] + + GameCooltip:AddLine (t [1], FormatTooltipNumber (_, t [2])) + local classe = t [3] + if (not classe) then + classe = "UNKNOW" + end + + if (classe == "UNKNOW") then + GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, 14, 14, .25, .5, 0, 1) + else + GameCooltip:AddIcon (instancia.row_info.icon_file, nil, nil, 14, 14, _unpack (_detalhes.class_coords [classe])) + end + _detalhes:AddTooltipBackgroundStatusbar() + end + + GameCooltip:AddLine ("") + GameCooltip:AddLine (Loc ["STRING_REPORT_LEFTCLICK"], nil, 1, _unpack (self.click_to_report_color)) + GameCooltip:AddIcon ([[Interface\TUTORIALFRAME\UI-TUTORIAL-FRAME]], 1, 1, 12, 16, 0.015625, 0.13671875, 0.4375, 0.59765625) + GameCooltip:ShowCooltip() + + else + GameCooltip:AddLine (Loc ["STRING_NO_DATA"], nil, 1, "white") + GameCooltip:AddIcon (instancia.row_info.icon_file, nil, nil, 14, 14, _unpack (_detalhes.class_coords ["UNKNOW"])) + GameCooltip:ShowCooltip() end - GameCooltip:AddLine ("") - GameCooltip:AddLine (Loc ["STRING_REPORT_LEFTCLICK"], nil, 1, _unpack (self.click_to_report_color)) - GameCooltip:AddIcon ([[Interface\TUTORIALFRAME\UI-TUTORIAL-FRAME]], 1, 1, 12, 16, 0.015625, 0.13671875, 0.4375, 0.59765625) - GameCooltip:ShowCooltip() - else GameCooltip:AddLine (Loc ["STRING_NO_DATA"], nil, 1, "white") GameCooltip:AddIcon (instancia.row_info.icon_file, nil, nil, 14, 14, _unpack (_detalhes.class_coords ["UNKNOW"])) GameCooltip:ShowCooltip() end - else - GameCooltip:AddLine (Loc ["STRING_NO_DATA"], nil, 1, "white") - GameCooltip:AddIcon (instancia.row_info.icon_file, nil, nil, 14, 14, _unpack (_detalhes.class_coords ["UNKNOW"])) - GameCooltip:ShowCooltip() end - -end -local function RefreshBarraFrags (tabela, barra, instancia) - atributo_damage:AtualizarFrags (tabela, tabela.minha_barra, barra.colocacao, instancia) -end + local function RefreshBarraFrags (tabela, barra, instancia) + atributo_damage:AtualizarFrags (tabela, tabela.minha_barra, barra.colocacao, instancia) + end -function atributo_damage:ReportSingleFragsLine (frag, instancia) - local barra = instancia.barras [frag.minha_barra] + function atributo_damage:ReportSingleFragsLine (frag, instancia) + local barra = instancia.barras [frag.minha_barra] - local reportar = {"Details! " .. Loc ["STRING_ATTRIBUTE_DAMAGE_TAKEN"].. ": " .. frag [1]} --> localize-me - for i = 1, GameCooltip:GetNumLines() do - local texto_left, texto_right = GameCooltip:GetText (i) - if (texto_left and texto_right) then - texto_left = texto_left:gsub (("|T(.*)|t "), "") - reportar [#reportar+1] = ""..texto_left.." "..texto_right.."" + local reportar = {"Details! " .. Loc ["STRING_ATTRIBUTE_DAMAGE_TAKEN"].. ": " .. frag [1]} --> localize-me + for i = 1, GameCooltip:GetNumLines() do + local texto_left, texto_right = GameCooltip:GetText (i) + if (texto_left and texto_right) then + texto_left = texto_left:gsub (("|T(.*)|t "), "") + reportar [#reportar+1] = ""..texto_left.." "..texto_right.."" + end end + + return _detalhes:Reportar (reportar, {_no_current = true, _no_inverse = true, _custom = true}) end - return _detalhes:Reportar (reportar, {_no_current = true, _no_inverse = true, _custom = true}) -end + function atributo_damage:AtualizarFrags (tabela, qual_barra, colocacao, instancia) -function atributo_damage:AtualizarFrags (tabela, qual_barra, colocacao, instancia) - - tabela ["frags"] = true --> marca que esta tabela é uma tabela de frags, usado no controla na hora de montar o tooltip - local esta_barra = instancia.barras [qual_barra] --> pega a referência da barra na janela - - if (not esta_barra) then - print ("DEBUG: problema com "..qual_barra.." "..lugar) - return - end - - local tabela_anterior = esta_barra.minha_tabela - - esta_barra.minha_tabela = tabela - - tabela.nome = tabela [1] --> evita dar erro ao redimencionar a janela - tabela.minha_barra = qual_barra - esta_barra.colocacao = colocacao - - if (not _getmetatable (tabela)) then - _setmetatable (tabela, {__call = RefreshBarraFrags}) - tabela._custom = true - end - - esta_barra.texto_esquerdo:SetText (colocacao .. ". " .. tabela [1]) - esta_barra.texto_direita:SetText (tabela [2]) - - if (colocacao == 1) then - esta_barra.statusbar:SetValue (100) - else - esta_barra.statusbar:SetValue (tabela [2] / instancia.top * 100) - end - - if (esta_barra.hidden or esta_barra.fading_in or esta_barra.faded) then - gump:Fade (esta_barra, "out") - end - - --> ele nao come o texto quando a instância esta muito pequena - esta_barra.textura:SetVertexColor (_unpack (_detalhes.class_colors [tabela [3]])) - - if (tabela [3] == "UNKNOW" or tabela [3] == "UNGROUPPLAYER" or tabela [3] == "ENEMY") then - esta_barra.icone_classe:SetTexture ("Interface\\LFGFRAME\\LFGROLE_BW") - esta_barra.icone_classe:SetTexCoord (.25, .5, 0, 1) - esta_barra.icone_classe:SetVertexColor (1, 1, 1) - else - esta_barra.icone_classe:SetTexture (instancia.row_info.icon_file) - esta_barra.icone_classe:SetTexCoord (_unpack (_detalhes.class_coords [tabela [3]])) - esta_barra.icone_classe:SetVertexColor (1, 1, 1) - end - - if (esta_barra.mouse_over and not instancia.baseframe.isMoving) then --> precisa atualizar o tooltip - --gump:UpdateTooltip (qual_barra, esta_barra, instancia) - end - -end - -function atributo_damage:ReportSingleVoidZoneLine (actor, instancia) - local barra = instancia.barras [actor.minha_barra] - - local reportar = {"Details! " .. Loc ["STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT"] .. ": " .. actor.nome} --> localize-me - for i = 1, GameCooltip:GetNumLines() do - local texto_left, texto_right = GameCooltip:GetText (i) - if (texto_left and texto_right) then - texto_left = texto_left:gsub (("|T(.*)|t "), "") - reportar [#reportar+1] = ""..texto_left.." "..texto_right.."" + tabela ["frags"] = true --> marca que esta tabela é uma tabela de frags, usado no controla na hora de montar o tooltip + local esta_barra = instancia.barras [qual_barra] --> pega a referência da barra na janela + + if (not esta_barra) then + print ("DEBUG: problema com "..qual_barra.." "..lugar) + return end + + local tabela_anterior = esta_barra.minha_tabela + + esta_barra.minha_tabela = tabela + + tabela.nome = tabela [1] --> evita dar erro ao redimencionar a janela + tabela.minha_barra = qual_barra + esta_barra.colocacao = colocacao + + if (not _getmetatable (tabela)) then + _setmetatable (tabela, {__call = RefreshBarraFrags}) + tabela._custom = true + end + + esta_barra.texto_esquerdo:SetText (colocacao .. ". " .. tabela [1]) + esta_barra.texto_direita:SetText (tabela [2]) + + if (colocacao == 1) then + esta_barra.statusbar:SetValue (100) + else + esta_barra.statusbar:SetValue (tabela [2] / instancia.top * 100) + end + + if (esta_barra.hidden or esta_barra.fading_in or esta_barra.faded) then + gump:Fade (esta_barra, "out") + end + + --> ele nao come o texto quando a instância esta muito pequena + esta_barra.textura:SetVertexColor (_unpack (_detalhes.class_colors [tabela [3]])) + + if (tabela [3] == "UNKNOW" or tabela [3] == "UNGROUPPLAYER" or tabela [3] == "ENEMY") then + esta_barra.icone_classe:SetTexture ("Interface\\LFGFRAME\\LFGROLE_BW") + esta_barra.icone_classe:SetTexCoord (.25, .5, 0, 1) + esta_barra.icone_classe:SetVertexColor (1, 1, 1) + else + esta_barra.icone_classe:SetTexture (instancia.row_info.icon_file) + esta_barra.icone_classe:SetTexCoord (_unpack (_detalhes.class_coords [tabela [3]])) + esta_barra.icone_classe:SetVertexColor (1, 1, 1) + end + + if (esta_barra.mouse_over and not instancia.baseframe.isMoving) then --> precisa atualizar o tooltip + --gump:UpdateTooltip (qual_barra, esta_barra, instancia) + end + + end + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> void zones + + function atributo_damage:ReportSingleVoidZoneLine (actor, instancia) + local barra = instancia.barras [actor.minha_barra] + + local reportar = {"Details! " .. Loc ["STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT"] .. ": " .. actor.nome} --> localize-me + for i = 1, GameCooltip:GetNumLines() do + local texto_left, texto_right = GameCooltip:GetText (i) + if (texto_left and texto_right) then + texto_left = texto_left:gsub (("|T(.*)|t "), "") + reportar [#reportar+1] = ""..texto_left.." "..texto_right.."" + end + end + + return _detalhes:Reportar (reportar, {_no_current = true, _no_inverse = true, _custom = true}) end - return _detalhes:Reportar (reportar, {_no_current = true, _no_inverse = true, _custom = true}) -end - -function _detalhes: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.spell_tables._ActorTable [actor.damage_spellid] - end - - if (habilidade) then - alvos = habilidade.targets - end - - local container = actor.debuff_uptime_targets._ActorTable - - for _, alvo in _ipairs (container) do - if (alvos) then - local damage_alvo = alvos._NameIndexTable [alvo.nome] - if (damage_alvo) then - damage_alvo = alvos._ActorTable [damage_alvo] - alvo.damage = damage_alvo.total + function _detalhes: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.spell_tables._ActorTable [actor.damage_spellid] + end + + if (habilidade) then + alvos = habilidade.targets + end + + local container = actor.debuff_uptime_targets._ActorTable + + for _, alvo in _ipairs (container) do + if (alvos) then + local damage_alvo = alvos._NameIndexTable [alvo.nome] + if (damage_alvo) then + damage_alvo = alvos._ActorTable [damage_alvo] + alvo.damage = damage_alvo.total + else + alvo.damage = 0 + end else alvo.damage = 0 end - else - alvo.damage = 0 end - end - --> sort no container: - _table_sort (container, function (tabela1, tabela2) - if (tabela1.damage > tabela2.damage) then - return true; - elseif (tabela1.damage == tabela2.damage) then - return tabela1.uptime > tabela2.uptime; - end - return false; - end) - - actor.debuff_uptime_targets:remapear() - - --> monta o cooltip - - local GameCooltip = GameCooltip - - GameCooltip:AddLine (Loc ["STRING_VOIDZONE_TOOLTIP"], nil, nil, headerColor, nil, 12) - GameCooltip:AddIcon ([[Interface\Addons\Details\images\icons]], 1, 1, 14, 14, 0.126953125, 0.1796875, 0, 0.0546875) - - for _, alvo in _ipairs (container) do + --> sort no container: + _table_sort (container, function (tabela1, tabela2) + if (tabela1.damage > tabela2.damage) then + return true; + elseif (tabela1.damage == tabela2.damage) then + return tabela1.uptime > tabela2.uptime; + end + return false; + end) + + actor.debuff_uptime_targets:remapear() + + --> monta o cooltip + local GameCooltip = GameCooltip + + GameCooltip:AddLine (Loc ["STRING_VOIDZONE_TOOLTIP"], nil, nil, headerColor, nil, 12) + GameCooltip:AddIcon ([[Interface\Addons\Details\images\icons]], 1, 1, 14, 14, 0.126953125, 0.1796875, 0, 0.0546875) + + for _, alvo in _ipairs (container) do - local minutos, segundos = _math_floor (alvo.uptime / 60), _math_floor (alvo.uptime % 60) - if (minutos > 0) then - GameCooltip:AddLine (alvo.nome, FormatTooltipNumber (_, alvo.damage) .. " (" .. minutos .. "m " .. segundos .. "s" .. ")") - else - GameCooltip:AddLine (alvo.nome, FormatTooltipNumber (_, alvo.damage) .. " (" .. segundos .. "s" .. ")") + local minutos, segundos = _math_floor (alvo.uptime / 60), _math_floor (alvo.uptime % 60) + if (minutos > 0) then + GameCooltip:AddLine (alvo.nome, FormatTooltipNumber (_, alvo.damage) .. " (" .. minutos .. "m " .. segundos .. "s" .. ")") + else + GameCooltip:AddLine (alvo.nome, FormatTooltipNumber (_, alvo.damage) .. " (" .. segundos .. "s" .. ")") + end + + local classe = _detalhes:GetClass (alvo.nome) + if (classe) then + GameCooltip:AddIcon ([[Interface\AddOns\Details\images\classes_small]], nil, nil, 14, 14, unpack (_detalhes.class_coords [classe])) + else + GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, 14, 14, .25, .5, 0, 1) + end + + _detalhes:AddTooltipBackgroundStatusbar() + end - local classe = _detalhes:GetClass (alvo.nome) - if (classe) then - GameCooltip:AddIcon ([[Interface\AddOns\Details\images\classes_small]], nil, nil, 14, 14, unpack (_detalhes.class_coords [classe])) - else - GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, 14, 14, .25, .5, 0, 1) + GameCooltip:AddLine ("") + GameCooltip:AddLine (Loc ["STRING_REPORT_LEFTCLICK"], nil, 1, _unpack (self.click_to_report_color)) + GameCooltip:AddIcon ([[Interface\TUTORIALFRAME\UI-TUTORIAL-FRAME]], 1, 1, 12, 16, 0.015625, 0.13671875, 0.4375, 0.59765625) + + GameCooltip:ShowCooltip() + + end + + local function RefreshBarraVoidZone (tabela, barra, instancia) + tabela:AtualizarVoidZone (tabela.minha_barra, barra.colocacao, instancia) + end + + function atributo_misc:AtualizarVoidZone (qual_barra, colocacao, instancia) + + --> pega a referência da barra na janela + local esta_barra = instancia.barras [qual_barra] + + if (not esta_barra) then + print ("DEBUG: problema com "..qual_barra.." "..lugar) + return end - _detalhes:AddTooltipBackgroundStatusbar() - - end - - GameCooltip:AddLine ("") - GameCooltip:AddLine (Loc ["STRING_REPORT_LEFTCLICK"], nil, 1, _unpack (self.click_to_report_color)) - GameCooltip:AddIcon ([[Interface\TUTORIALFRAME\UI-TUTORIAL-FRAME]], 1, 1, 12, 16, 0.015625, 0.13671875, 0.4375, 0.59765625) - - GameCooltip:ShowCooltip() - -end - -local function RefreshBarraVoidZone (tabela, barra, instancia) - tabela:AtualizarVoidZone (tabela.minha_barra, barra.colocacao, instancia) -end - -function atributo_misc:AtualizarVoidZone (qual_barra, colocacao, instancia) - - local esta_barra = instancia.barras [qual_barra] --> pega a referência da barra na janela - - if (not esta_barra) then - print ("DEBUG: problema com "..qual_barra.." "..lugar) - return - end - - self._refresh_window = RefreshBarraVoidZone - - local tabela_anterior = esta_barra.minha_tabela - - esta_barra.minha_tabela = self - - self.minha_barra = qual_barra - esta_barra.colocacao = colocacao - - esta_barra.texto_esquerdo:SetText (colocacao .. ". " .. self.nome) - esta_barra.texto_direita:SetText (self.debuff_uptime) - - --if (colocacao == 1) then + self._refresh_window = RefreshBarraVoidZone + + local tabela_anterior = esta_barra.minha_tabela + + esta_barra.minha_tabela = self + + self.minha_barra = qual_barra + esta_barra.colocacao = colocacao + + esta_barra.texto_esquerdo:SetText (colocacao .. ". " .. self.nome) + esta_barra.texto_direita:SetText (self.debuff_uptime) + esta_barra.statusbar:SetValue (100) - --else - -- esta_barra.statusbar:SetValue (self.debuff_uptime / instancia.top * 100) - --end - - if (esta_barra.hidden or esta_barra.fading_in or esta_barra.faded) then - gump:Fade (esta_barra, "out") - end - - local _, _, icon = GetSpellInfo (self.damage_spellid) - local school_color = _detalhes.school_colors [self.spellschool] - if (not school_color) then - school_color = _detalhes.school_colors ["unknown"] - end - - esta_barra.textura:SetVertexColor (_unpack (school_color)) - esta_barra.icone_classe:SetTexture (icon) - esta_barra.icone_classe:SetTexCoord (0, 1, 0, 1) - esta_barra.icone_classe:SetVertexColor (1, 1, 1) + + if (esta_barra.hidden or esta_barra.fading_in or esta_barra.faded) then + gump:Fade (esta_barra, "out") + end + + local _, _, icon = GetSpellInfo (self.damage_spellid) + local school_color = _detalhes.school_colors [self.spellschool] + if (not school_color) then + school_color = _detalhes.school_colors ["unknown"] + end + + esta_barra.textura:SetVertexColor (_unpack (school_color)) + esta_barra.icone_classe:SetTexture (icon) + esta_barra.icone_classe:SetTexCoord (0, 1, 0, 1) + esta_barra.icone_classe:SetVertexColor (1, 1, 1) + + if (esta_barra.mouse_over and not instancia.baseframe.isMoving) then + --need call a refresh function + end - if (esta_barra.mouse_over and not instancia.baseframe.isMoving) then --> precisa atualizar o tooltip - --gump:UpdateTooltip (qual_barra, esta_barra, instancia) end -end - -local ntable = {} -local vtable = {} +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> main refresh function function atributo_damage:RefreshWindow (instancia, tabela_do_combate, forcar, exportar, refresh_needed) @@ -849,7 +865,6 @@ function atributo_damage:RefreshWindow (instancia, tabela_do_combate, forcar, ex if (not using_cache) then for index, player in _ipairs (conteudo) do - --if (_bit_band (player.flag, DFLAG_player_group) >= 0x101) then --> é um player e esta em grupo 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 @@ -1401,11 +1416,7 @@ end --------------------------------------------- // TOOLTIPS // --------------------------------------------- ---[[Exported]] function _detalhes:TooltipForCustom (barra) - --GameCooltip:AddLine (barra.colocacao..". "..self.nome) - GameCooltip:AddLine (Loc ["STRING_LEFT_CLICK_SHARE"]) - return true -end + ---------> TOOLTIPS BIFURCAÇÃO @@ -1428,18 +1439,7 @@ end local r, g, b local barAlha = .6 ---[[exported]] function _detalhes.Sort1 (table1, table2) - return table1 [1] > table2 [1] - end ---[[exported]] function _detalhes.Sort2 (table1, table2) - return table1 [2] > table2 [2] - end ---[[exported]] function _detalhes.Sort3 (table1, table2) - return table1 [3] > table2 [3] - end ---[[exported]] function _detalhes.Sort4 (table1, table2) - return table1 [4] > table2 [4] - end + ---------> DAMAGE DONE & DPS diff --git a/classes/classe_damage_habilidade.lua b/classes/classe_damage_habilidade.lua index 53b24b92..4b4734e3 100644 --- a/classes/classe_damage_habilidade.lua +++ b/classes/classe_damage_habilidade.lua @@ -1,131 +1,123 @@ ---[[ classe do dano aplicado, usado nos eventos: -- SPELL_PERIODIC_DAMAGE -- SPELL_DAMAGE -- SWING_DAMAGE -- RANGE_DAMAGE +-- damage ability file -Parents: - addon -> combate atual -> Npc/Player Swicth -> Container de Habilidades -> esta tabela - ]] + local _detalhes = _G._detalhes + local _ -local _detalhes = _G._detalhes -local gump = _detalhes.gump +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers + local _setmetatable = setmetatable--lua local + local _ipairs = ipairs--lua local + local _pairs = pairs--lua local + local _UnitAura = UnitAura--api local -local alvo_da_habilidade = _detalhes.alvo_da_habilidade -local habilidade_dano = _detalhes.habilidade_dano -local container_combatentes = _detalhes.container_combatentes -local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants ---lua locals -local _setmetatable = setmetatable -local _ipairs = ipairs -local _pairs = pairs -local _ ---api locals -local _UnitAura = UnitAura ---local _GetSpellInfo = _detalhes.getspellinfo + local alvo_da_habilidade = _detalhes.alvo_da_habilidade + local habilidade_dano = _detalhes.habilidade_dano + local container_combatentes = _detalhes.container_combatentes + local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS + local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC -local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC + local _recording_ability_with_buffs = false -local _recording_ability_with_buffs = false +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals ---id, nome, type, miss, dano, cura, overkill, school, resisted, blocked, absorbed, critico, glacing, crushing -function habilidade_dano:NovaTabela (id, link, token) --aqui eu não sei que parâmetros passar + function habilidade_dano:NovaTabela (id, link, token) - local _newDamageSpell = { - - total = 0, --total de dano aplicado por esta habilidade - counter = 0, --conta quantas vezes a habilidade foi chamada - id = id, - successful_casted = 0, + local _newDamageSpell = { - --> normal - n_min = 0, - n_max = 0, - n_amt = 0, - n_dmg = 0, + total = 0, --total damage + counter = 0, --counter + id = id, --spellid + successful_casted = 0, --successful casted times (only for enemies) + + --> normal hits + n_min = 0, + n_max = 0, + n_amt = 0, + n_dmg = 0, + + --> critical hits + c_min = 0, + c_max = 0, + c_amt = 0, + c_dmg = 0, + + --> glacing hits + g_amt = 0, + g_dmg = 0, + + --> resisted + r_amt = 0, + r_dmg = 0, + + --> blocked + b_amt = 0, + b_dmg = 0, + + --> obsorved + a_amt = 0, + a_dmg = 0, + + targets = container_combatentes:NovoContainer (container_damage_target) + } - --> criticos - c_min = 0, - c_max = 0, - c_amt = 0, - c_dmg = 0, - - --> glacing - g_amt = 0, - g_dmg = 0, + _setmetatable (_newDamageSpell, habilidade_dano) - --> resisted - r_amt = 0, - r_dmg = 0, + if (link) then + _newDamageSpell.targets.shadow = link.targets + end - --> blocked - b_amt = 0, - b_dmg = 0, - - --> obsorved - a_amt = 0, - a_dmg = 0, + if (token == "SPELL_PERIODIC_DAMAGE") then + _detalhes:SpellIsDot (id) + end - targets = container_combatentes:NovoContainer (container_damage_target) - } - - _setmetatable (_newDamageSpell, habilidade_dano) - - if (link) then - _newDamageSpell.targets.shadow = link.targets - end - - if (token == "SPELL_PERIODIC_DAMAGE") then - _detalhes:SpellIsDot (id) - end - - return _newDamageSpell -end - - -function habilidade_dano:AddMiss (serial, nome, flags, who_nome, missType) - self.counter = self.counter + 1 - - local miss = self [missType] or 0 - miss = miss + 1 - self [missType] = miss - - local alvo = self.targets:PegarCombatente (serial, nome, flags, true) - return alvo:AddQuantidade (0) -end - -function habilidade_dano:AddFF (amount) - self.counter = self.counter + 1 - self.total = self.total + amount -end - -function habilidade_dano:Add (serial, nome, flag, amount, who_nome, resisted, blocked, absorbed, critical, glacing, token) - - self.counter = self.counter + 1 - - local alvo = self.targets._NameIndexTable [nome] - if (not alvo) then - alvo = self.targets:PegarCombatente (serial, nome, flag, true) - else - alvo = self.targets._ActorTable [alvo] + return _newDamageSpell end - if (resisted and resisted > 0) then - self.r_dmg = self.r_dmg+amount --> tabela.total é o total de dano - self.r_amt = self.r_amt+1 --> tabela.total é o total de dano + function habilidade_dano:AddMiss (serial, nome, flags, who_nome, missType) + self.counter = self.counter + 1 + + local miss = self [missType] or 0 + miss = miss + 1 + self [missType] = miss + + self.targets:PegarCombatente (serial, nome, flags, true) --apenas criar o alvo para a abilidade end - - if (blocked and blocked > 0) then - self.b_dmg = self.b_dmg+amount --> amount é o total de dano - self.b_amt = self.b_amt+1 --> amount é o total de dano + + function habilidade_dano:AddFF (amount) + self.counter = self.counter + 1 + self.total = self.total + amount end - - if (absorbed and absorbed > 0) then - self.a_dmg = self.a_dmg+amount --> amount é o total de dano - self.a_amt = self.a_amt+1 --> amount é o total de dano - end - + + function habilidade_dano:Add (serial, nome, flag, amount, who_nome, resisted, blocked, absorbed, critical, glacing, token) + + self.counter = self.counter + 1 + + local alvo = self.targets._NameIndexTable [nome] + if (not alvo) then + alvo = self.targets:PegarCombatente (serial, nome, flag, true) + else + alvo = self.targets._ActorTable [alvo] + end + + if (resisted and resisted > 0) then + self.r_dmg = self.r_dmg+amount --> tabela.total é o total de dano + self.r_amt = self.r_amt+1 --> tabela.total é o total de dano + end + + if (blocked and blocked > 0) then + self.b_dmg = self.b_dmg+amount --> amount é o total de dano + self.b_amt = self.b_amt+1 --> amount é o total de dano + end + + if (absorbed and absorbed > 0) then + self.a_dmg = self.a_dmg+amount --> amount é o total de dano + self.a_amt = self.a_amt+1 --> amount é o total de dano + end + self.total = self.total + amount alvo.total = alvo.total + amount @@ -152,157 +144,139 @@ function habilidade_dano:Add (serial, nome, flag, amount, who_nome, resisted, bl self.n_min = amount end end - --end - - if (_recording_ability_with_buffs) then - if (who_nome == _detalhes.playername) then --aqui ele vai detalhar tudo sobre a magia usada - local buffsNames = _detalhes.SoloTables.BuffsTableNameCache + if (_recording_ability_with_buffs) then + if (who_nome == _detalhes.playername) then --aqui ele vai detalhar tudo sobre a magia usada - local SpellBuffDetails = self.BuffTable - if (not SpellBuffDetails) then - self.BuffTable = {} - SpellBuffDetails = self.BuffTable - end - - if (token == "SPELL_PERIODIC_DAMAGE") then - --> precisa ver se ele tinha na hora que aplicou - local SoloDebuffPower = _detalhes.tabela_vigente.SoloDebuffPower - if (SoloDebuffPower) then - local ThisDebuff = SoloDebuffPower [self.id] - if (ThisDebuff) then - local ThisDebuffOnTarget = ThisDebuff [serial] - if (ThisDebuffOnTarget) then - for index, buff_name in _ipairs (ThisDebuffOnTarget.buffs) do - local buff_info = SpellBuffDetails [buff_name] or {["counter"] = 0, ["total"] = 0, ["critico"] = 0, ["critico_dano"] = 0} - buff_info.counter = buff_info.counter+1 - buff_info.total = buff_info.total+amount - if (critical ~= nil) then - buff_info.critico = buff_info.critico+1 - buff_info.critico_dano = buff_info.critico_dano+amount + local buffsNames = _detalhes.SoloTables.BuffsTableNameCache + + local SpellBuffDetails = self.BuffTable + if (not SpellBuffDetails) then + self.BuffTable = {} + SpellBuffDetails = self.BuffTable + end + + if (token == "SPELL_PERIODIC_DAMAGE") then + --> precisa ver se ele tinha na hora que aplicou + local SoloDebuffPower = _detalhes.tabela_vigente.SoloDebuffPower + if (SoloDebuffPower) then + local ThisDebuff = SoloDebuffPower [self.id] + if (ThisDebuff) then + local ThisDebuffOnTarget = ThisDebuff [serial] + if (ThisDebuffOnTarget) then + for index, buff_name in _ipairs (ThisDebuffOnTarget.buffs) do + local buff_info = SpellBuffDetails [buff_name] or {["counter"] = 0, ["total"] = 0, ["critico"] = 0, ["critico_dano"] = 0} + buff_info.counter = buff_info.counter+1 + buff_info.total = buff_info.total+amount + if (critical ~= nil) then + buff_info.critico = buff_info.critico+1 + buff_info.critico_dano = buff_info.critico_dano+amount + end + SpellBuffDetails [buff_name] = buff_info end - SpellBuffDetails [buff_name] = buff_info end end end - end - - else + + else - for BuffName, _ in _pairs (_detalhes.Buffs.BuffsTable) do - local name = _UnitAura ("player", BuffName) - if (name ~= nil) then - local buff_info = SpellBuffDetails [name] or {["counter"] = 0, ["total"] = 0, ["critico"] = 0, ["critico_dano"] = 0} - buff_info.counter = buff_info.counter+1 - buff_info.total = buff_info.total+amount - if (critical ~= nil) then - buff_info.critico = buff_info.critico+1 - buff_info.critico_dano = buff_info.critico_dano+amount + for BuffName, _ in _pairs (_detalhes.Buffs.BuffsTable) do + local name = _UnitAura ("player", BuffName) + if (name ~= nil) then + local buff_info = SpellBuffDetails [name] or {["counter"] = 0, ["total"] = 0, ["critico"] = 0, ["critico_dano"] = 0} + buff_info.counter = buff_info.counter+1 + buff_info.total = buff_info.total+amount + if (critical ~= nil) then + buff_info.critico = buff_info.critico+1 + buff_info.critico_dano = buff_info.critico_dano+amount + end + SpellBuffDetails [name] = buff_info end - SpellBuffDetails [name] = buff_info end end end end + end -end +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> core -function _detalhes.refresh:r_habilidade_dano (habilidade, shadow) --recebeu o container shadow - _setmetatable (habilidade, habilidade_dano) - habilidade.__index = habilidade_dano - habilidade.shadow = shadow._ActorTable [habilidade.id] - _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) -end + function _detalhes.refresh:r_habilidade_dano (habilidade, shadow) --recebeu o container shadow + _setmetatable (habilidade, habilidade_dano) + habilidade.__index = habilidade_dano + habilidade.shadow = shadow._ActorTable [habilidade.id] + _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) + end -function _detalhes.clear:c_habilidade_dano (habilidade) - --habilidade.__index = {} - habilidade.__index = nil - habilidade.shadow = nil - - _detalhes.clear:c_container_combatentes (habilidade.targets) -end + function _detalhes.clear:c_habilidade_dano (habilidade) + --habilidade.__index = {} + habilidade.__index = nil + habilidade.shadow = nil + + _detalhes.clear:c_container_combatentes (habilidade.targets) + end -habilidade_dano.__add = function (tabela1, tabela2) - tabela1.total = tabela1.total + tabela2.total - tabela1.counter = tabela1.counter + tabela2.counter - tabela1.successful_casted = tabela1.successful_casted + tabela2.successful_casted - - tabela1.n_min = tabela1.n_min + tabela2.n_min - tabela1.n_max = tabela1.n_max + tabela2.n_max - tabela1.n_amt = tabela1.n_amt + tabela2.n_amt - tabela1.n_dmg = tabela1.n_dmg + tabela2.n_dmg + habilidade_dano.__add = function (tabela1, tabela2) + tabela1.total = tabela1.total + tabela2.total + tabela1.counter = tabela1.counter + tabela2.counter + tabela1.successful_casted = tabela1.successful_casted + tabela2.successful_casted + + tabela1.n_min = tabela1.n_min + tabela2.n_min + tabela1.n_max = tabela1.n_max + tabela2.n_max + tabela1.n_amt = tabela1.n_amt + tabela2.n_amt + tabela1.n_dmg = tabela1.n_dmg + tabela2.n_dmg - tabela1.c_min = tabela1.c_min + tabela2.c_min - tabela1.c_max = tabela1.c_max + tabela2.c_max - tabela1.c_amt = tabela1.c_amt + tabela2.c_amt - tabela1.c_dmg = tabela1.c_dmg + tabela2.c_dmg - - --tabela1.g_min = tabela1.g_min + tabela2.g_min - --tabela1.g_max = tabela1.g_max + tabela2.g_max - tabela1.g_amt = tabela1.g_amt + tabela2.g_amt - tabela1.g_dmg = tabela1.g_dmg + tabela2.g_dmg - - --tabela1.r_min = tabela1.r_min + tabela2.r_min - --tabela1.r_max = tabela1.r_max + tabela2.r_max - tabela1.r_amt = tabela1.r_amt + tabela2.r_amt - tabela1.r_dmg = tabela1.r_dmg + tabela2.r_dmg - - --tabela1.b_min = tabela1.b_min + tabela2.b_min - --tabela1.b_max = tabela1.b_max + tabela2.b_max - tabela1.b_amt = tabela1.b_amt + tabela2.b_amt - tabela1.b_dmg = tabela1.b_dmg + tabela2.b_dmg - - --tabela1.a_min = tabela1.a_min + tabela2.a_min - --tabela1.a_max = tabela1.a_max + tabela2.a_max - tabela1.a_amt = tabela1.a_amt + tabela2.a_amt - tabela1.a_dmg = tabela1.a_dmg + tabela2.a_dmg - - --tabela1.crushing = tabela1.crushing + tabela2.crushing - - return tabela1 -end + tabela1.c_min = tabela1.c_min + tabela2.c_min + tabela1.c_max = tabela1.c_max + tabela2.c_max + tabela1.c_amt = tabela1.c_amt + tabela2.c_amt + tabela1.c_dmg = tabela1.c_dmg + tabela2.c_dmg + + tabela1.g_amt = tabela1.g_amt + tabela2.g_amt + tabela1.g_dmg = tabela1.g_dmg + tabela2.g_dmg + + tabela1.r_amt = tabela1.r_amt + tabela2.r_amt + tabela1.r_dmg = tabela1.r_dmg + tabela2.r_dmg + + tabela1.b_amt = tabela1.b_amt + tabela2.b_amt + tabela1.b_dmg = tabela1.b_dmg + tabela2.b_dmg + + tabela1.a_amt = tabela1.a_amt + tabela2.a_amt + tabela1.a_dmg = tabela1.a_dmg + tabela2.a_dmg + + return tabela1 + end -habilidade_dano.__sub = function (tabela1, tabela2) - tabela1.total = tabela1.total - tabela2.total - tabela1.counter = tabela1.counter - tabela2.counter - tabela1.successful_casted = tabela1.successful_casted - tabela2.successful_casted + habilidade_dano.__sub = function (tabela1, tabela2) + tabela1.total = tabela1.total - tabela2.total + tabela1.counter = tabela1.counter - tabela2.counter + tabela1.successful_casted = tabela1.successful_casted - tabela2.successful_casted - tabela1.n_min = tabela1.n_min - tabela2.n_min - tabela1.n_max = tabela1.n_max - tabela2.n_max - tabela1.n_amt = tabela1.n_amt - tabela2.n_amt - tabela1.n_dmg = tabela1.n_dmg - tabela2.n_dmg + tabela1.n_min = tabela1.n_min - tabela2.n_min + tabela1.n_max = tabela1.n_max - tabela2.n_max + tabela1.n_amt = tabela1.n_amt - tabela2.n_amt + tabela1.n_dmg = tabela1.n_dmg - tabela2.n_dmg - tabela1.c_min = tabela1.c_min - tabela2.c_min - tabela1.c_max = tabela1.c_max - tabela2.c_max - tabela1.c_amt = tabela1.c_amt - tabela2.c_amt - tabela1.c_dmg = tabela1.c_dmg - tabela2.c_dmg - - --tabela1.g_min = tabela1.g_min - tabela2.g_min - --tabela1.g_max = tabela1.g_max - tabela2.g_max - tabela1.g_amt = tabela1.g_amt - tabela2.g_amt - tabela1.g_dmg = tabela1.g_dmg - tabela2.g_dmg - - --tabela1.r_min = tabela1.r_min - tabela2.r_min - --tabela1.r_max = tabela1.r_max - tabela2.r_max - tabela1.r_amt = tabela1.r_amt - tabela2.r_amt - tabela1.r_dmg = tabela1.r_dmg - tabela2.r_dmg - - --tabela1.b_min = tabela1.b_min - tabela2.b_min - --tabela1.b_max = tabela1.b_max - tabela2.b_max - tabela1.b_amt = tabela1.b_amt - tabela2.b_amt - tabela1.b_dmg = tabela1.b_dmg - tabela2.b_dmg - - --tabela1.a_min = tabela1.a_min - tabela2.a_min - --tabela1.a_max = tabela1.a_max - tabela2.a_max - tabela1.a_amt = tabela1.a_amt - tabela2.a_amt - tabela1.a_dmg = tabela1.a_dmg - tabela2.a_dmg - - --tabela1.crushing = tabela1.crushing - tabela2.crushing - - return tabela1 -end + tabela1.c_min = tabela1.c_min - tabela2.c_min + tabela1.c_max = tabela1.c_max - tabela2.c_max + tabela1.c_amt = tabela1.c_amt - tabela2.c_amt + tabela1.c_dmg = tabela1.c_dmg - tabela2.c_dmg + + tabela1.g_amt = tabela1.g_amt - tabela2.g_amt + tabela1.g_dmg = tabela1.g_dmg - tabela2.g_dmg + + tabela1.r_amt = tabela1.r_amt - tabela2.r_amt + tabela1.r_dmg = tabela1.r_dmg - tabela2.r_dmg + + tabela1.b_amt = tabela1.b_amt - tabela2.b_amt + tabela1.b_dmg = tabela1.b_dmg - tabela2.b_dmg + + tabela1.a_amt = tabela1.a_amt - tabela2.a_amt + tabela1.a_dmg = tabela1.a_dmg - tabela2.a_dmg + + return tabela1 + end -function _detalhes:UpdateDamageAbilityGears() - _recording_ability_with_buffs = _detalhes.RecordPlayerAbilityWithBuffs -end + function _detalhes:UpdateDamageAbilityGears() + _recording_ability_with_buffs = _detalhes.RecordPlayerAbilityWithBuffs + end diff --git a/classes/classe_energy.lua b/classes/classe_energy.lua index 35aab44e..2a996117 100644 --- a/classes/classe_energy.lua +++ b/classes/classe_energy.lua @@ -53,10 +53,6 @@ local class_type = _detalhes.atributos.e_energy local DATA_TYPE_START = _detalhes._detalhes_props.DATA_TYPE_START local DATA_TYPE_END = _detalhes._detalhes_props.DATA_TYPE_END -local DFLAG_player = _detalhes.flags.player -local DFLAG_group = _detalhes.flags.in_group -local DFLAG_player_group = _detalhes.flags.player_in_group - local div_abre = _detalhes.divisores.abre local div_fecha = _detalhes.divisores.fecha local div_lugar = _detalhes.divisores.colocacao @@ -253,7 +249,6 @@ function atributo_energy:RefreshWindow (instancia, tabela_do_combate, forcar, ex end) for index, player in _ipairs (conteudo) do - --if (_bit_band (player.flag, DFLAG_player_group) >= 0x101) then --> é um player e esta em grupo 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 diff --git a/classes/classe_energy_habilidade.lua b/classes/classe_energy_habilidade.lua index 37302d11..ce577258 100644 --- a/classes/classe_energy_habilidade.lua +++ b/classes/classe_energy_habilidade.lua @@ -1,102 +1,112 @@ -local _detalhes = _G._detalhes -local gump = _detalhes.gump +-- energy ability file -local alvo_da_habilidade = _detalhes.alvo_da_habilidade -local habilidade_energy = _detalhes.habilidade_e_energy -local container_combatentes = _detalhes.container_combatentes -local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS + local _detalhes = _G._detalhes + local _ ---lua locals -local _setmetatable = setmetatable -local _ipairs = ipairs ---api locals -local _UnitAura = UnitAura -local _ ---local _GetSpellInfo = _detalhes.getspellinfo +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers -local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC + local _setmetatable = setmetatable --lua local + local _ipairs = ipairs --lua local + local _UnitAura = UnitAura --api local -function habilidade_energy:NovaTabela (id, link, token) +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants - local _newEnergySpell = { + local alvo_da_habilidade = _detalhes.alvo_da_habilidade + local habilidade_energy = _detalhes.habilidade_e_energy + local container_combatentes = _detalhes.container_combatentes + local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS + local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC - id = id, - counter = 0, +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals + + function habilidade_energy:NovaTabela (id, link, token) + + local _newEnergySpell = { + + id = id, + counter = 0, + + mana = 0, + e_rage = 0, + e_energy = 0, + runepower = 0, + + targets = container_combatentes:NovoContainer (container_energy_target) + } - mana = 0, - e_rage = 0, - e_energy = 0, - runepower = 0, + _setmetatable (_newEnergySpell, habilidade_energy) - targets = container_combatentes:NovoContainer (container_energy_target) - } - - _setmetatable (_newEnergySpell, habilidade_energy) - - if (link) then - _newEnergySpell.targets.shadow = link.targets - end - - return _newEnergySpell -end - -function habilidade_energy:Add (serial, nome, flag, amount, who_nome, powertype) - - self.counter = self.counter + 1 - - --local alvo = self.targets:PegarCombatente (serial, nome, flag, true) - local alvo = self.targets._NameIndexTable [nome] - if (not alvo) then - alvo = self.targets:PegarCombatente (serial, nome, flag, true) - else - alvo = self.targets._ActorTable [alvo] + if (link) then + _newEnergySpell.targets.shadow = link.targets + end + + return _newEnergySpell end - - if (powertype == 0) then --> MANA - self.mana = self.mana + amount - alvo.mana = alvo.mana + amount - elseif (powertype == 1) then --> e_rage - self.e_rage = self.e_rage + amount - alvo.e_rage = alvo.e_rage + amount - elseif (powertype == 3) then --> ENERGIA - self.e_energy = self.e_energy + amount - alvo.e_energy = alvo.e_energy + amount - elseif (powertype == 6) then --> RUNEPOWER - self.runepower = self.runepower + amount - alvo.runepower = alvo.runepower + amount + function habilidade_energy:Add (serial, nome, flag, amount, who_nome, powertype) + + self.counter = self.counter + 1 + + local alvo = self.targets._NameIndexTable [nome] + if (not alvo) then + alvo = self.targets:PegarCombatente (serial, nome, flag, true) + else + alvo = self.targets._ActorTable [alvo] + end + + if (powertype == 0) then --> MANA + self.mana = self.mana + amount + alvo.mana = alvo.mana + amount + + elseif (powertype == 1) then --> e_rage + self.e_rage = self.e_rage + amount + alvo.e_rage = alvo.e_rage + amount + + elseif (powertype == 3) then --> ENERGIA + self.e_energy = self.e_energy + amount + alvo.e_energy = alvo.e_energy + amount + + elseif (powertype == 6) then --> RUNEPOWER + self.runepower = self.runepower + amount + alvo.runepower = alvo.runepower + amount + end + end -end +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> core -function _detalhes.refresh:r_habilidade_e_energy (habilidade, shadow) --recebeu o container shadow - _setmetatable (habilidade, habilidade_energy) - habilidade.__index = habilidade_energy - - if (shadow ~= -1) then - habilidade.shadow = shadow._ActorTable[habilidade.id] - _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) - else - _detalhes.refresh:r_container_combatentes (habilidade.targets, -1) + function _detalhes.refresh:r_habilidade_e_energy (habilidade, shadow) --recebeu o container shadow + _setmetatable (habilidade, habilidade_energy) + habilidade.__index = habilidade_energy + + if (shadow ~= -1) then + habilidade.shadow = shadow._ActorTable[habilidade.id] + _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) + else + _detalhes.refresh:r_container_combatentes (habilidade.targets, -1) + end end -end -function _detalhes.clear:c_habilidade_e_energy (habilidade) - --habilidade.__index = {} - habilidade.__index = {} - habilidade.shadow = nil - - _detalhes.clear:c_container_combatentes (habilidade.targets) -end + function _detalhes.clear:c_habilidade_e_energy (habilidade) + --habilidade.__index = {} + habilidade.__index = {} + habilidade.shadow = nil + + _detalhes.clear:c_container_combatentes (habilidade.targets) + end -habilidade_energy.__sub = function (tabela1, tabela2) + habilidade_energy.__sub = function (tabela1, tabela2) - tabela1.mana = tabela1.mana - tabela2.mana - tabela1.e_rage = tabela1.e_rage - tabela2.e_rage - tabela1.e_energy = tabela1.e_energy - tabela2.e_energy - tabela1.runepower = tabela1.runepower - tabela2.runepower - - tabela1.counter = tabela1.counter - tabela2.counter + tabela1.mana = tabela1.mana - tabela2.mana + tabela1.e_rage = tabela1.e_rage - tabela2.e_rage + tabela1.e_energy = tabela1.e_energy - tabela2.e_energy + tabela1.runepower = tabela1.runepower - tabela2.runepower + + tabela1.counter = tabela1.counter - tabela2.counter - return tabela1 -end + return tabela1 + end diff --git a/classes/classe_heal.lua b/classes/classe_heal.lua index 5c019c42..37d11efb 100644 --- a/classes/classe_heal.lua +++ b/classes/classe_heal.lua @@ -52,10 +52,6 @@ local class_type = _detalhes.atributos.cura local DATA_TYPE_START = _detalhes._detalhes_props.DATA_TYPE_START local DATA_TYPE_END = _detalhes._detalhes_props.DATA_TYPE_END -local DFLAG_player = _detalhes.flags.player -local DFLAG_group = _detalhes.flags.in_group -local DFLAG_player_group = _detalhes.flags.player_in_group - local div_abre = _detalhes.divisores.abre local div_fecha = _detalhes.divisores.fecha local div_lugar = _detalhes.divisores.colocacao @@ -331,7 +327,6 @@ function atributo_heal:RefreshWindow (instancia, tabela_do_combate, forcar, expo end)--]] for index, player in _ipairs (conteudo) do - --if (_bit_band (player.flag, DFLAG_player_group) >= 0x101) then --> é um player e esta em grupo 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 diff --git a/classes/classe_heal_habilidade.lua b/classes/classe_heal_habilidade.lua index 21778142..d20af75b 100644 --- a/classes/classe_heal_habilidade.lua +++ b/classes/classe_heal_habilidade.lua @@ -1,154 +1,154 @@ ---[[ classe do dano aplicado, usado nos eventos: -- SPELL_HEAL -- SPELL_PERIODIC_HEAL -Parents: - addon -> combate atual -> Npc/Player Swicth -> Container de Habilidades -> esta tabela - ]] +-- heal ability file -local _detalhes = _G._detalhes -local gump = _detalhes.gump + local _detalhes = _G._detalhes + local _ -local alvo_da_habilidade = _detalhes.alvo_da_habilidade -local habilidade_cura = _detalhes.habilidade_cura -local container_combatentes = _detalhes.container_combatentes -local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers -local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC - ---lua locals -local _setmetatable = setmetatable ---api locals - -function habilidade_cura:NovaTabela (id, link) --aqui eu não sei que parâmetros passar - - local _newHealSpell = { + local _setmetatable = setmetatable --lua local - total = 0, - totalabsorb = 0, - counter = 0, - id = id, +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants - --> normal hits - n_min = 0, - n_max = 0, - n_amt = 0, - n_curado = 0, + local alvo_da_habilidade = _detalhes.alvo_da_habilidade + local habilidade_cura = _detalhes.habilidade_cura + local container_combatentes = _detalhes.container_combatentes + local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS + local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals + + function habilidade_cura:NovaTabela (id, link) + + local _newHealSpell = { - --> critical hits - c_min = 0, - c_max = 0, - c_amt = 0, - c_curado = 0, + total = 0, + totalabsorb = 0, + counter = 0, + id = id, - absorbed = 0, - overheal = 0, + --> normal hits + n_min = 0, + n_max = 0, + n_amt = 0, + n_curado = 0, + + --> critical hits + c_min = 0, + c_max = 0, + c_amt = 0, + c_curado = 0, + + absorbed = 0, + overheal = 0, + + targets = container_combatentes:NovoContainer (container_heal_target) + } - targets = container_combatentes:NovoContainer (container_heal_target) - } - - _setmetatable (_newHealSpell, habilidade_cura) - - if (link) then - _newHealSpell.targets.shadow = link.targets - end - - return _newHealSpell -end - ---> o primeiro parametro "spell" vira self a atrasa 1 parâmetro em todos os argumentos. -function habilidade_cura:Add (serial, nome, flag, amount, who_nome, absorbed, critical, overhealing, is_shield) - - self.counter = self.counter + 1 - - --local alvo = self.targets:PegarCombatente (serial, nome, flag, true) - local alvo = self.targets._NameIndexTable [nome] - if (not alvo) then - alvo = self.targets:PegarCombatente (serial, nome, flag, true) - else - alvo = self.targets._ActorTable [alvo] - end - - if (absorbed and absorbed > 0) then - self.absorbed = self.absorbed + absorbed - alvo.absorbed = alvo.absorbed + absorbed - end - - if (overhealing and overhealing > 0) then - self.overheal = self.overheal + overhealing - alvo.overheal = alvo.overheal + overhealing - end - - if (amount and amount > 0) then - - self.total = self.total + amount - if (is_shield) then - self.totalabsorb = self.totalabsorb + amount + _setmetatable (_newHealSpell, habilidade_cura) + + if (link) then + _newHealSpell.targets.shadow = link.targets end + + return _newHealSpell + end - alvo:AddQuantidade (amount) + function habilidade_cura:Add (serial, nome, flag, amount, who_nome, absorbed, critical, overhealing, is_shield) - if (critical) then - self.c_curado = self.c_curado+amount --> amount é o total de dano - self.c_amt = self.c_amt+1 --> amount é o total de dano - if (amount > self.c_max) then - self.c_max = amount - end - if (self.c_min > amount or self.c_min == 0) then - self.c_min = amount - end + self.counter = self.counter + 1 + + local alvo = self.targets._NameIndexTable [nome] + if (not alvo) then + alvo = self.targets:PegarCombatente (serial, nome, flag, true) else - self.n_curado = self.n_curado+amount - self.n_amt = self.n_amt+1 - if (amount > self.n_max) then - self.n_max = amount + alvo = self.targets._ActorTable [alvo] + end + + if (absorbed and absorbed > 0) then + self.absorbed = self.absorbed + absorbed + alvo.absorbed = alvo.absorbed + absorbed + end + + if (overhealing and overhealing > 0) then + self.overheal = self.overheal + overhealing + alvo.overheal = alvo.overheal + overhealing + end + + if (amount and amount > 0) then + + self.total = self.total + amount + alvo.total = alvo.total + amount + + if (is_shield) then + self.totalabsorb = self.totalabsorb + amount end - if (self.n_min > amount or self.n_min == 0) then - self.n_min = amount + + if (critical) then + self.c_curado = self.c_curado+amount --> amount é o total de dano + self.c_amt = self.c_amt+1 --> amount é o total de dano + if (amount > self.c_max) then + self.c_max = amount + end + if (self.c_min > amount or self.c_min == 0) then + self.c_min = amount + end + else + self.n_curado = self.n_curado+amount + self.n_amt = self.n_amt+1 + if (amount > self.n_max) then + self.n_max = amount + end + if (self.n_min > amount or self.n_min == 0) then + self.n_min = amount + end end end - else - alvo:AddQuantidade (0) + end -end +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> core -function _detalhes.refresh:r_habilidade_cura (habilidade, shadow) - _setmetatable (habilidade, habilidade_cura) - habilidade.__index = habilidade_cura - - if (shadow ~= -1) then - habilidade.shadow = shadow._ActorTable[habilidade.id] - _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) - else - _detalhes.refresh:r_container_combatentes (habilidade.targets, -1) + function _detalhes.refresh:r_habilidade_cura (habilidade, shadow) + _setmetatable (habilidade, habilidade_cura) + habilidade.__index = habilidade_cura + + if (shadow ~= -1) then + habilidade.shadow = shadow._ActorTable[habilidade.id] + _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) + else + _detalhes.refresh:r_container_combatentes (habilidade.targets, -1) + end end -end -function _detalhes.clear:c_habilidade_cura (habilidade) - --habilidade.__index = {} - habilidade.__index = nil - habilidade.shadow = nil - - _detalhes.clear:c_container_combatentes (habilidade.targets) -end + function _detalhes.clear:c_habilidade_cura (habilidade) + --habilidade.__index = {} + habilidade.__index = nil + habilidade.shadow = nil + + _detalhes.clear:c_container_combatentes (habilidade.targets) + end -habilidade_cura.__sub = function (tabela1, tabela2) - tabela1.total = tabela1.total - tabela2.total - tabela1.totalabsorb = tabela1.totalabsorb - tabela2.totalabsorb - tabela1.counter = tabela1.counter - tabela2.counter + habilidade_cura.__sub = function (tabela1, tabela2) + tabela1.total = tabela1.total - tabela2.total + tabela1.totalabsorb = tabela1.totalabsorb - tabela2.totalabsorb + tabela1.counter = tabela1.counter - tabela2.counter - tabela1.n_min = tabela1.n_min - tabela2.n_min - tabela1.n_max = tabela1.n_max - tabela2.n_max - tabela1.n_amt = tabela1.n_amt - tabela2.n_amt - tabela1.n_curado = tabela1.n_curado - tabela2.n_curado + tabela1.n_min = tabela1.n_min - tabela2.n_min + tabela1.n_max = tabela1.n_max - tabela2.n_max + tabela1.n_amt = tabela1.n_amt - tabela2.n_amt + tabela1.n_curado = tabela1.n_curado - tabela2.n_curado - tabela1.c_min = tabela1.c_min - tabela2.c_min - tabela1.c_max = tabela1.c_max - tabela2.c_max - tabela1.c_amt = tabela1.c_amt - tabela2.c_amt - tabela1.c_curado = tabela1.c_curado - tabela2.c_curado + tabela1.c_min = tabela1.c_min - tabela2.c_min + tabela1.c_max = tabela1.c_max - tabela2.c_max + tabela1.c_amt = tabela1.c_amt - tabela2.c_amt + tabela1.c_curado = tabela1.c_curado - tabela2.c_curado - tabela1.absorbed = tabela1.absorbed - tabela2.absorbed - tabela1.overheal = tabela1.overheal - tabela2.overheal - - return tabela1 -end + tabela1.absorbed = tabela1.absorbed - tabela2.absorbed + tabela1.overheal = tabela1.overheal - tabela2.overheal + + return tabela1 + end diff --git a/classes/classe_others.lua b/classes/classe_others.lua index 125c79a0..735b27b6 100644 --- a/classes/classe_others.lua +++ b/classes/classe_others.lua @@ -53,10 +53,6 @@ local class_type = _detalhes.atributos.misc local DATA_TYPE_START = _detalhes._detalhes_props.DATA_TYPE_START local DATA_TYPE_END = _detalhes._detalhes_props.DATA_TYPE_END -local DFLAG_player = _detalhes.flags.player -local DFLAG_group = _detalhes.flags.in_group -local DFLAG_player_group = _detalhes.flags.player_in_group - local div_abre = _detalhes.divisores.abre local div_fecha = _detalhes.divisores.fecha local div_lugar = _detalhes.divisores.colocacao @@ -547,7 +543,6 @@ function atributo_misc:RefreshWindow (instancia, tabela_do_combate, forcar, expo --end for index, player in _ipairs (conteudo) do - --if (_bit_band (player.flag, DFLAG_player_group) >= 0x101) then --> é um player e esta em grupo if (player.grupo) then --> é um player e esta em grupo if (not player[keyName] or player[keyName] < 1) then --> dano menor que 1, interromper o loop amount = index - 1 diff --git a/classes/classe_others_habilidade.lua b/classes/classe_others_habilidade.lua index a9437922..ad0a4f7a 100644 --- a/classes/classe_others_habilidade.lua +++ b/classes/classe_others_habilidade.lua @@ -1,58 +1,198 @@ -local _detalhes = _G._detalhes ---local gump = _detalhes.gump +-- misc ability file + local _detalhes = _G._detalhes + local _ -local alvo_da_habilidade = _detalhes.alvo_da_habilidade -local habilidade_misc = _detalhes.habilidade_misc -local container_combatentes = _detalhes.container_combatentes -local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers ---lua locals -local _ -local _setmetatable = setmetatable -local _ipairs = ipairs ---api locals -local _UnitAura = UnitAura + local _setmetatable = setmetatable --lua local + local _ipairs = ipairs --lua local + local _UnitAura = UnitAura --api local -local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants -function habilidade_misc:NovaTabela (id, link, token) --aqui eu não sei que parâmetros passar + local alvo_da_habilidade = _detalhes.alvo_da_habilidade + local habilidade_misc = _detalhes.habilidade_misc + local container_combatentes = _detalhes.container_combatentes + local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS + local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC - local _newMiscSpell = { - id = id, - counter = 0, - targets = container_combatentes:NovoContainer (container_misc_target) - } - - if (token == "BUFF_UPTIME" or token == "DEBUFF_UPTIME") then - _newMiscSpell.uptime = 0 - _newMiscSpell.actived = false - _newMiscSpell.activedamt = 0 - elseif (token == "SPELL_INTERRUPT") then - _newMiscSpell.interrompeu_oque = {} - elseif (token == "SPELL_DISPEL" or token == "SPELL_STOLEN") then - _newMiscSpell.dispell_oque = {} - elseif (token == "SPELL_AURA_BROKEN" or token == "SPELL_AURA_BROKEN_SPELL") then - _newMiscSpell.cc_break_oque = {} - end +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals - _setmetatable (_newMiscSpell, habilidade_misc) - - if (link) then - _newMiscSpell.targets.shadow = link.targets - end - - return _newMiscSpell -end + function habilidade_misc:NovaTabela (id, link, token) -function habilidade_misc:Add (serial, nome, flag, who_nome, token, spellID, spellName) - - --alvo:AddQuantidade (1) - if (spellID == "BUFF_OR_DEBUFF") then + local _newMiscSpell = { + id = id, + counter = 0, + targets = container_combatentes:NovoContainer (container_misc_target) + } - if (spellName == "COOLDOWN") then - self.counter = self.counter + 1 + if (token == "BUFF_UPTIME" or token == "DEBUFF_UPTIME") then + _newMiscSpell.uptime = 0 + _newMiscSpell.actived = false + _newMiscSpell.activedamt = 0 + elseif (token == "SPELL_INTERRUPT") then + _newMiscSpell.interrompeu_oque = {} + elseif (token == "SPELL_DISPEL" or token == "SPELL_STOLEN") then + _newMiscSpell.dispell_oque = {} + elseif (token == "SPELL_AURA_BROKEN" or token == "SPELL_AURA_BROKEN_SPELL") then + _newMiscSpell.cc_break_oque = {} + end + + _setmetatable (_newMiscSpell, habilidade_misc) + + if (link) then + _newMiscSpell.targets.shadow = link.targets + end + + return _newMiscSpell + end + + function habilidade_misc:Add (serial, nome, flag, who_nome, token, spellID, spellName) + + if (spellID == "BUFF_OR_DEBUFF") then - --> alvo + if (spellName == "COOLDOWN") then + self.counter = self.counter + 1 + + --> alvo + local alvo = self.targets._NameIndexTable [nome] + if (not alvo) then + alvo = self.targets:PegarCombatente (serial, nome, flag, true) + else + alvo = self.targets._ActorTable [alvo] + end + alvo.total = alvo.total + 1 + + elseif (spellName == "BUFF_UPTIME_REFRESH") then + if (self.actived_at and self.actived) then + self.uptime = self.uptime + _detalhes._tempo - self.actived_at + token.buff_uptime = token.buff_uptime + _detalhes._tempo - self.actived_at --> token = actor misc object + + end + self.actived_at = _detalhes._tempo + self.actived = true + + elseif (spellName == "BUFF_UPTIME_OUT") then + if (self.actived_at and self.actived) then + self.uptime = self.uptime + _detalhes._tempo - self.actived_at + token.buff_uptime = token.buff_uptime + _detalhes._tempo - self.actived_at --> token = actor misc object + end + self.actived = false + self.actived_at = nil + + elseif (spellName == "BUFF_UPTIME_IN" or spellName == "DEBUFF_UPTIME_IN") then + self.actived = true + self.activedamt = self.activedamt + 1 + + if (self.actived_at and self.actived and spellName == "DEBUFF_UPTIME_IN") then + --> ja esta ativo em outro mob e jogou num novo + self.uptime = self.uptime + _detalhes._tempo - self.actived_at + token.debuff_uptime = token.debuff_uptime + _detalhes._tempo - self.actived_at + end + + self.actived_at = _detalhes._tempo + + elseif (spellName == "DEBUFF_UPTIME_REFRESH") then + if (self.actived_at and self.actived) then + self.uptime = self.uptime + _detalhes._tempo - self.actived_at + token.debuff_uptime = token.debuff_uptime + _detalhes._tempo - self.actived_at + end + self.actived_at = _detalhes._tempo + self.actived = true + + elseif (spellName == "DEBUFF_UPTIME_OUT") then + if (self.actived_at and self.actived) then + self.uptime = self.uptime + _detalhes._tempo - self.actived_at + token.debuff_uptime = token.debuff_uptime + _detalhes._tempo - self.actived_at --> token = actor misc object + end + + self.activedamt = self.activedamt - 1 + + if (self.activedamt == 0) then + self.actived = false + self.actived_at = nil + else + self.actived_at = _detalhes._tempo + end + + end + + elseif (token == "SPELL_INTERRUPT") then + self.counter = self.counter + 1 + + if (not self.interrompeu_oque [spellID]) then --> interrompeu_oque a NIL value + self.interrompeu_oque [spellID] = 1 + else + self.interrompeu_oque [spellID] = self.interrompeu_oque [spellID] + 1 + end + + --alvo + local alvo = self.targets._NameIndexTable [nome] + if (not alvo) then + alvo = self.targets:PegarCombatente (serial, nome, flag, true) + else + alvo = self.targets._ActorTable [alvo] + end + alvo.total = alvo.total + 1 + + elseif (token == "SPELL_RESURRECT") then + if (not self.ress) then + self.ress = 1 + else + self.ress = self.ress + 1 + end + + --alvo + local alvo = self.targets._NameIndexTable [nome] + if (not alvo) then + alvo = self.targets:PegarCombatente (serial, nome, flag, true) + else + alvo = self.targets._ActorTable [alvo] + end + alvo.total = alvo.total + 1 + + + elseif (token == "SPELL_DISPEL" or token == "SPELL_STOLEN") then + if (not self.dispell) then + self.dispell = 1 + else + self.dispell = self.dispell + 1 + end + + if (not self.dispell_oque [spellID]) then + self.dispell_oque [spellID] = 1 + else + self.dispell_oque [spellID] = self.dispell_oque [spellID] + 1 + end + + --alvo + local alvo = self.targets._NameIndexTable [nome] + if (not alvo) then + alvo = self.targets:PegarCombatente (serial, nome, flag, true) + else + alvo = self.targets._ActorTable [alvo] + end + alvo.total = alvo.total + 1 + + + elseif (token == "SPELL_AURA_BROKEN_SPELL" or token == "SPELL_AURA_BROKEN") then + + if (not self.cc_break) then + self.cc_break = 1 + else + self.cc_break = self.cc_break + 1 + end + + if (not self.cc_break_oque [spellID]) then + self.cc_break_oque [spellID] = 1 + else + self.cc_break_oque [spellID] = self.cc_break_oque [spellID] + 1 + end + + --alvo local alvo = self.targets._NameIndexTable [nome] if (not alvo) then alvo = self.targets:PegarCombatente (serial, nome, flag, true) @@ -60,190 +200,57 @@ function habilidade_misc:Add (serial, nome, flag, who_nome, token, spellID, spel alvo = self.targets._ActorTable [alvo] end alvo.total = alvo.total + 1 - - elseif (spellName == "BUFF_UPTIME_REFRESH") then - if (self.actived_at and self.actived) then - self.uptime = self.uptime + _detalhes._tempo - self.actived_at - token.buff_uptime = token.buff_uptime + _detalhes._tempo - self.actived_at --> token = actor misc object - - end - self.actived_at = _detalhes._tempo - self.actived = true - - elseif (spellName == "BUFF_UPTIME_OUT") then - if (self.actived_at and self.actived) then - self.uptime = self.uptime + _detalhes._tempo - self.actived_at - token.buff_uptime = token.buff_uptime + _detalhes._tempo - self.actived_at --> token = actor misc object - end - self.actived = false - self.actived_at = nil - - elseif (spellName == "BUFF_UPTIME_IN" or spellName == "DEBUFF_UPTIME_IN") then - self.actived = true - self.activedamt = self.activedamt + 1 - - if (self.actived_at and self.actived and spellName == "DEBUFF_UPTIME_IN") then - --> ja esta ativo em outro mob e jogou num novo - self.uptime = self.uptime + _detalhes._tempo - self.actived_at - token.debuff_uptime = token.debuff_uptime + _detalhes._tempo - self.actived_at - end - - self.actived_at = _detalhes._tempo - - elseif (spellName == "DEBUFF_UPTIME_REFRESH") then - if (self.actived_at and self.actived) then - self.uptime = self.uptime + _detalhes._tempo - self.actived_at - token.debuff_uptime = token.debuff_uptime + _detalhes._tempo - self.actived_at - end - self.actived_at = _detalhes._tempo - self.actived = true - - elseif (spellName == "DEBUFF_UPTIME_OUT") then - if (self.actived_at and self.actived) then - self.uptime = self.uptime + _detalhes._tempo - self.actived_at - token.debuff_uptime = token.debuff_uptime + _detalhes._tempo - self.actived_at --> token = actor misc object - end - - self.activedamt = self.activedamt - 1 - - if (self.activedamt == 0) then - self.actived = false - self.actived_at = nil - else - self.actived_at = _detalhes._tempo - end - - end - - elseif (token == "SPELL_INTERRUPT") then - self.counter = self.counter + 1 - - if (not self.interrompeu_oque [spellID]) then --> interrompeu_oque a NIL value - self.interrompeu_oque [spellID] = 1 - else - self.interrompeu_oque [spellID] = self.interrompeu_oque [spellID] + 1 - end - - --alvo - local alvo = self.targets._NameIndexTable [nome] - if (not alvo) then - alvo = self.targets:PegarCombatente (serial, nome, flag, true) - else - alvo = self.targets._ActorTable [alvo] - end - alvo.total = alvo.total + 1 - - elseif (token == "SPELL_RESURRECT") then - if (not self.ress) then - self.ress = 1 - else - self.ress = self.ress + 1 - end - - --alvo - local alvo = self.targets._NameIndexTable [nome] - if (not alvo) then - alvo = self.targets:PegarCombatente (serial, nome, flag, true) - else - alvo = self.targets._ActorTable [alvo] - end - alvo.total = alvo.total + 1 - - - elseif (token == "SPELL_DISPEL" or token == "SPELL_STOLEN") then - if (not self.dispell) then - self.dispell = 1 - else - self.dispell = self.dispell + 1 - end - - if (not self.dispell_oque [spellID]) then - self.dispell_oque [spellID] = 1 - else - self.dispell_oque [spellID] = self.dispell_oque [spellID] + 1 end - --alvo - local alvo = self.targets._NameIndexTable [nome] - if (not alvo) then - alvo = self.targets:PegarCombatente (serial, nome, flag, true) - else - alvo = self.targets._ActorTable [alvo] - end - alvo.total = alvo.total + 1 - - - elseif (token == "SPELL_AURA_BROKEN_SPELL" or token == "SPELL_AURA_BROKEN") then - - if (not self.cc_break) then - self.cc_break = 1 - else - self.cc_break = self.cc_break + 1 - end - - if (not self.cc_break_oque [spellID]) then - self.cc_break_oque [spellID] = 1 - else - self.cc_break_oque [spellID] = self.cc_break_oque [spellID] + 1 - end - - --alvo - local alvo = self.targets._NameIndexTable [nome] - if (not alvo) then - alvo = self.targets:PegarCombatente (serial, nome, flag, true) - else - alvo = self.targets._ActorTable [alvo] - end - alvo.total = alvo.total + 1 end -end +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> core ---> habilidade atual e o container de habilidades da shadow -function _detalhes.refresh:r_habilidade_misc (habilidade, shadow) --recebeu o container shadow - _setmetatable (habilidade, habilidade_misc) - habilidade.__index = habilidade_misc - - if (shadow ~= -1) then - habilidade.shadow = shadow._ActorTable[habilidade.id] - _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) - else - _detalhes.refresh:r_container_combatentes (habilidade.targets, -1) - end -end - -function _detalhes.clear:c_habilidade_misc (habilidade) - --habilidade.__index = {} - habilidade.__index = nil - habilidade.shadow = nil - - _detalhes.clear:c_container_combatentes (habilidade.targets) -end - -habilidade_misc.__sub = function (tabela1, tabela2) - - --interrupts & cooldowns - tabela1.counter = tabela1.counter - tabela2.counter - - --buff uptime ou debuff uptime - if (tabela1.uptime and tabela2.uptime) then - tabela1.uptime = tabela1.uptime - tabela2.uptime - end - - --ressesrs - if (tabela1.ress and tabela2.ress) then - tabela1.ress = tabela1.ress - tabela2.ress - end - - --dispells - if (tabela1.dispell and tabela2.dispell) then - tabela1.dispell = tabela1.dispell - tabela2.dispell - end - - --cc_breaks - if (tabela1.cc_break and tabela2.cc_break) then - tabela1.cc_break = tabela1.cc_break - tabela2.cc_break + function _detalhes.refresh:r_habilidade_misc (habilidade, shadow) --recebeu o container shadow + _setmetatable (habilidade, habilidade_misc) + habilidade.__index = habilidade_misc + + if (shadow ~= -1) then + habilidade.shadow = shadow._ActorTable[habilidade.id] + _detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) + else + _detalhes.refresh:r_container_combatentes (habilidade.targets, -1) + end end - return tabela1 -end + function _detalhes.clear:c_habilidade_misc (habilidade) + --habilidade.__index = {} + habilidade.__index = nil + habilidade.shadow = nil + + _detalhes.clear:c_container_combatentes (habilidade.targets) + end + + habilidade_misc.__sub = function (tabela1, tabela2) + + --interrupts & cooldowns + tabela1.counter = tabela1.counter - tabela2.counter + + --buff uptime ou debuff uptime + if (tabela1.uptime and tabela2.uptime) then + tabela1.uptime = tabela1.uptime - tabela2.uptime + end + + --ressesrs + if (tabela1.ress and tabela2.ress) then + tabela1.ress = tabela1.ress - tabela2.ress + end + + --dispells + if (tabela1.dispell and tabela2.dispell) then + tabela1.dispell = tabela1.dispell - tabela2.dispell + end + + --cc_breaks + if (tabela1.cc_break and tabela2.cc_break) then + tabela1.cc_break = tabela1.cc_break - tabela2.cc_break + end + + return tabela1 + end diff --git a/classes/classe_target.lua b/classes/classe_target.lua index a602b484..763316cb 100644 --- a/classes/classe_target.lua +++ b/classes/classe_target.lua @@ -1,49 +1,51 @@ +-- class target file -local _detalhes = _G._detalhes ---local AceLocale = LibStub ("AceLocale-3.0") ---local Loc = AceLocale:GetLocale ( "Details" ) - -local gump = _detalhes.gump - -local alvo_da_habilidade = _detalhes.alvo_da_habilidade - ---lua locals -local _setmetatable = setmetatable ---api locals - ---esta tabela irá ser usada por todas os tipos? tipo dano, cura, interrupts? - -function alvo_da_habilidade:NovaTabela (link) - - local esta_tabela = {total = 0} - _setmetatable (esta_tabela, alvo_da_habilidade) + local _detalhes = _G._detalhes - return esta_tabela -end +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers -function alvo_da_habilidade:AddQuantidade (amt) - self.total = self.total + amt - if (self.shadow) then - return self.shadow:AddQuantidade (amt) + local _setmetatable = setmetatable --lua local + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants + + local alvo_da_habilidade = _detalhes.alvo_da_habilidade + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals + + function alvo_da_habilidade:NovaTabela (link) + + local esta_tabela = {total = 0} + _setmetatable (esta_tabela, alvo_da_habilidade) + + return esta_tabela end -end -function _detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow) - _setmetatable (este_alvo, alvo_da_habilidade) - este_alvo.__index = alvo_da_habilidade - este_alvo.shadow = shadow._ActorTable [shadow._NameIndexTable [este_alvo.nome]] -end - -function _detalhes.clear:c_alvo_da_habilidade (este_alvo) - este_alvo.shadow = nil - --este_alvo.__index = {} - este_alvo.__index = nil -end - -alvo_da_habilidade.__sub = function (tabela1, tabela2) - tabela1.total = tabela1.total - tabela2.total - if (tabela1.overheal) then - tabela1.overheal = tabela1.overheal - tabela2.overheal - tabela1.absorbed = tabela1.absorbed - tabela2.absorbed + function alvo_da_habilidade:AddQuantidade (amt) + self.total = self.total + amt + end + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> core + + function _detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow) + _setmetatable (este_alvo, alvo_da_habilidade) + este_alvo.__index = alvo_da_habilidade + este_alvo.shadow = shadow._ActorTable [shadow._NameIndexTable [este_alvo.nome]] + end + + function _detalhes.clear:c_alvo_da_habilidade (este_alvo) + este_alvo.shadow = nil + --este_alvo.__index = {} + este_alvo.__index = nil + end + + alvo_da_habilidade.__sub = function (tabela1, tabela2) + tabela1.total = tabela1.total - tabela2.total + if (tabela1.overheal) then + tabela1.overheal = tabela1.overheal - tabela2.overheal + tabela1.absorbed = tabela1.absorbed - tabela2.absorbed + end end -end diff --git a/classes/container_combatentes.lua b/classes/container_combatentes.lua index 3ca12af3..90cf7184 100644 --- a/classes/container_combatentes.lua +++ b/classes/container_combatentes.lua @@ -1,511 +1,464 @@ -local _detalhes = _G._detalhes -local gump = _detalhes.gump +-- actor container file -local combatente = _detalhes.combatente -local container_combatentes = _detalhes.container_combatentes -local alvo_da_habilidade = _detalhes.alvo_da_habilidade -local atributo_damage = _detalhes.atributo_damage -local atributo_heal = _detalhes.atributo_heal -local atributo_energy = _detalhes.atributo_energy -local atributo_misc = _detalhes.atributo_misc + local _detalhes = _G._detalhes + local _ -local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC -local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS -local container_heal = _detalhes.container_type.CONTAINER_HEAL_CLASS -local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS -local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE -local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS -local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS -local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS -local container_misc = _detalhes.container_type.CONTAINER_MISC_CLASS -local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS -local container_enemydebufftarget_target = _detalhes.container_type.CONTAINER_ENEMYDEBUFFTARGET_CLASS +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers ---api locals -local _UnitClass = UnitClass -local _IsInInstance = IsInInstance ---lua locals -local _setmetatable = setmetatable -local _getmetatable = getmetatable -local _bit_band = bit.band -local _ipairs = ipairs -local _pairs = pairs - -local _ - ---local table_insert = table.insert - ---> FLAGS <== qual o tipo do objeto -local OBJECT_TYPE_MASK = 0x0000FC00 -local OBJECT_TYPE_OBJECT = 0x00004000 -local OBJECT_TYPE_PETGUARDIAN = 0x00003000 -local OBJECT_TYPE_GUARDIAN = 0x00002000 -local OBJECT_TYPE_PET = 0x00001000 -local OBJECT_TYPE_NPC = 0x00000800 -local OBJECT_TYPE_PLAYER = 0x00000400 -local OBJECT_TYPE_PETS = OBJECT_TYPE_PET + OBJECT_TYPE_GUARDIAN -local EM_GRUPO = 0x00000007 - -local REACTION_HOSTILE = COMBATLOG_OBJECT_REACTION_HOSTILE or 0x00000040 - -function container_combatentes:NovoContainer (tipo_do_container, combatTable, combatId) - - local _newContainer = { + local _UnitClass = UnitClass --api local + local _IsInInstance = IsInInstance --api local - funcao_de_criacao = container_combatentes:FuncaoDeCriacao (tipo_do_container), - - tipo = tipo_do_container, - - combatId = combatId, - - _ActorTable = {}, - _NameIndexTable = {} - } + local _setmetatable = setmetatable --lua local + local _getmetatable = getmetatable --lua local + local _bit_band = bit.band --lua local + local _ipairs = ipairs --lua local + local _pairs = pairs --lua local - _setmetatable (_newContainer, container_combatentes) +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants - return _newContainer -end + local combatente = _detalhes.combatente + local container_combatentes = _detalhes.container_combatentes + local alvo_da_habilidade = _detalhes.alvo_da_habilidade + local atributo_damage = _detalhes.atributo_damage + local atributo_heal = _detalhes.atributo_heal + local atributo_energy = _detalhes.atributo_energy + local atributo_misc = _detalhes.atributo_misc -local function get_actor_class (novo_objeto, nome, flag) - local _, engClass = _UnitClass (nome) + local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC + local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS + local container_heal = _detalhes.container_type.CONTAINER_HEAL_CLASS + local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS + local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE + local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS + local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS + local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS + local container_misc = _detalhes.container_type.CONTAINER_MISC_CLASS + local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS + local container_enemydebufftarget_target = _detalhes.container_type.CONTAINER_ENEMYDEBUFFTARGET_CLASS - if (engClass) then - novo_objeto.classe = engClass - return - else - if (flag) then - --> conferir se o jogador é um player - if (_bit_band (flag, OBJECT_TYPE_PLAYER) ~= 0) then - novo_objeto.classe = "UNGROUPPLAYER" - return - elseif (_bit_band (flag, OBJECT_TYPE_PETGUARDIAN) ~= 0) then - novo_objeto.classe = "PET" - return - end + --> flags + local REACTION_HOSTILE = 0x00000040 + local IS_GROUP_OBJECT = 0x00000007 + local OBJECT_TYPE_MASK = 0x0000FC00 + local OBJECT_TYPE_OBJECT = 0x00004000 + local OBJECT_TYPE_PETGUARDIAN = 0x00003000 + local OBJECT_TYPE_GUARDIAN = 0x00002000 + local OBJECT_TYPE_PET = 0x00001000 + local OBJECT_TYPE_NPC = 0x00000800 + local OBJECT_TYPE_PLAYER = 0x00000400 + local OBJECT_TYPE_PETS = OBJECT_TYPE_PET + OBJECT_TYPE_GUARDIAN + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> api functions + + function container_combatentes:GetAmount (actorName, key) + key = key or "total" + local index = self._NameIndexTable [actorName] + if (index) then + return self._ActorTable [index] [key] or 0 + else + return 0 end - novo_objeto.classe = "UNKNOW" - return end -end -function container_combatentes:GetAmount (actorName, key) - key = key or "total" - local index = self._NameIndexTable [actorName] - if (index) then - return self._ActorTable [index] [key] or 0 - else - return 0 - end -end +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals -local read_actor_flag = function (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) - -- converte a flag do wow em flag do details ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - --> pega afiliação - local details_flag = 0x00000000 - - if (flag) then - --print ("tem flag") - - if (_bit_band (flag, 0x00000400) ~= 0) then --> é um player - details_flag = details_flag+0x00000001 + --> build a new actor container + function container_combatentes:NovoContainer (tipo_do_container, combat_table, combat_id) + local _newContainer = { + funcao_de_criacao = container_combatentes:FuncaoDeCriacao (tipo_do_container), - novo_objeto.displayName = _detalhes:GetNickname (serial, false, true) --> serial, default, silent - if (not novo_objeto.displayName) then + tipo = tipo_do_container, + + combatId = combat_id, + + _ActorTable = {}, + _NameIndexTable = {} + } + + _setmetatable (_newContainer, container_combatentes) + + return _newContainer + end + + --> try to get the actor class from name + local function get_actor_class (novo_objeto, nome, flag) + local _, engClass = _UnitClass (nome) + + if (engClass) then + novo_objeto.classe = engClass + return + else + if (flag) then + --> conferir se o jogador é um player + if (_bit_band (flag, OBJECT_TYPE_PLAYER) ~= 0) then + novo_objeto.classe = "UNGROUPPLAYER" + return + elseif (_bit_band (flag, OBJECT_TYPE_PETGUARDIAN) ~= 0) then + novo_objeto.classe = "PET" + return + end + end + novo_objeto.classe = "UNKNOW" + return + end + end + + --> read the actor flag + local read_actor_flag = function (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) + + if (flag) then + + --> é um player + if (_bit_band (flag, OBJECT_TYPE_PLAYER) ~= 0) then + novo_objeto.displayName = _detalhes:GetNickname (serial, false, true) --> serial, default, silent + if (not novo_objeto.displayName) then + if (_IsInInstance() and _detalhes.remove_realm_from_name) then + novo_objeto.displayName = nome:gsub (("%-.*"), "") + else + novo_objeto.displayName = nome + end + end + + if (_bit_band (flag, IS_GROUP_OBJECT) ~= 0 and novo_objeto.classe ~= "UNGROUPPLAYER") then --> faz parte do grupo + novo_objeto.grupo = true + + if (shadow_objeto) then + shadow_objeto.grupo = true + end + + if (_detalhes:IsATank (serial)) then + novo_objeto.isTank = true + if (shadow_objeto) then + shadow_objeto.isTank = true + end + end + end + + --> é um pet + elseif (dono_do_pet) then + novo_objeto.owner = dono_do_pet + novo_objeto.ownerName = dono_do_pet.nome + if (_IsInInstance() and _detalhes.remove_realm_from_name) then - novo_objeto.displayName = nome:gsub (("%-.*"), "") - --print (novo_objeto.displayName) + novo_objeto.displayName = nome:gsub (("%-.*"), ">") else novo_objeto.displayName = nome end - end - - if (_bit_band (flag, EM_GRUPO) ~= 0 and novo_objeto.classe ~= "UNGROUPPLAYER") then --> faz parte do grupo - details_flag = details_flag+0x00000100 - novo_objeto.grupo = true - - if (shadow_objeto) then - shadow_objeto.grupo = true - end - if (_detalhes:IsATank (serial)) then - novo_objeto.isTank = true - if (shadow_objeto) then - shadow_objeto.isTank = true - end - end - end - - elseif (dono_do_pet) then --> é um pet - - details_flag = details_flag+0x00000002 - novo_objeto.owner = dono_do_pet - novo_objeto.ownerName = dono_do_pet.nome - - if (_IsInInstance() and _detalhes.remove_realm_from_name) then - novo_objeto.displayName = nome:gsub (("%-.*"), ">") else novo_objeto.displayName = nome end - --if (not novo_objeto.displayName:find (">")) then - -- novo_objeto.displayName = novo_objeto.displayName .. ">" - --end - - --print ("pet -> " .. nome) - else - novo_objeto.displayName = nome - end - - -- 0x00000060 --> inimigo neutro - if (_bit_band (flag, 0x00000010) ~= 0) then --> é amigo - details_flag = details_flag+0x00000010 - - elseif (_bit_band (flag, 0x00000020) ~= 0) then --> é neutro - details_flag = details_flag+0x00000020 - --print ("neutro -> " .. nome) - - elseif (_bit_band (flag, 0x00000040) ~= 0) then --> é inimigo - - details_flag = details_flag+0x00000040 - - if (_bit_band (flag, 0x00000400) == 0 and _bit_band (flag, OBJECT_TYPE_PETGUARDIAN) == 0) then - novo_objeto.monster = true - end - --print ("inimigos -> " .. nome) - end - else - --print (flag) - end - - novo_objeto.flag = details_flag - novo_objeto.flag_original = flag - novo_objeto.serial = serial -end - -function container_combatentes:PegarCombatente (serial, nome, flag, criar, isOwner) - - --> antes de mais nada, vamos verificar se é um pet - local dono_do_pet - if (flag and _bit_band (flag, OBJECT_TYPE_PETS) ~= 0) then --> é um pet - - --> aqui ele precisaria achar as tag < > pra saber se o nome passado já não veio com o dono imbutido - --> se não tiver as tags, terá que ser posto aqui - if (not nome:find ("<") or not nome:find (">")) then --> find é lento, não teria outra forma de fazer isso? - - local nome_dele, dono_nome, dono_serial, dono_flag = _detalhes.tabela_pets:PegaDono (serial, nome, flag) - - if (nome_dele) then - - nome = nome_dele - --if (_detalhes.debug) then - -- print ("creating actor for pet:", nome, "owner:", dono_nome) - --end - - --> e se olharmos no cache do parser antes de tentar cria-lo? - - dono_do_pet = self:PegarCombatente (dono_serial, dono_nome, dono_flag, true, nome) - + --> é inimigo + if (_bit_band (flag, 0x00000040) ~= 0) then + if (_bit_band (flag, OBJECT_TYPE_PLAYER) == 0 and _bit_band (flag, OBJECT_TYPE_PETGUARDIAN) == 0) then + novo_objeto.monster = true + end end end + + novo_objeto.flag_original = flag + novo_objeto.serial = serial end - local index = self._NameIndexTable [nome] --> pega o index no mapa - if (index) then - return self._ActorTable [index], dono_do_pet, nome - - elseif (criar) then + function container_combatentes:PegarCombatente (serial, nome, flag, criar, isOwner) - -- rotinas de criação do objeto shadow ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - local shadow = self.shadow --> espelho do container no overall - local shadow_objeto - - if (shadow) then --> se tiver o espelho (não for a tabela overall já) - shadow_objeto = shadow:PegarCombatente (_, nome) --> apenas verifica se ele existe ou não - if (not shadow_objeto) then --> se não existir, cria-lo - local novo_nome = nome:gsub ((" <.*"), "") --> tira o nome do pet - shadow_objeto = shadow:PegarCombatente (serial, novo_nome, flag, true) + --> verifica se é um pet, se for confere se tem o nome do dono, se não tiver, precisa por + local dono_do_pet + if (flag and _bit_band (flag, OBJECT_TYPE_PETS) ~= 0) then --> é um pet + --> aqui ele precisaria achar as tag < > pra saber se o nome passado já não veio com o dono imbutido, se não tiver as tags, terá que ser posto aqui + if (not nome:find ("<") or not nome:find (">")) then --> find é lento, não teria outra forma de fazer isso? + local nome_dele, dono_nome, dono_serial, dono_flag = _detalhes.tabela_pets:PegaDono (serial, nome, flag) + if (nome_dele) then + nome = nome_dele + dono_do_pet = self:PegarCombatente (dono_serial, dono_nome, dono_flag, true, nome) + end end end - local novo_objeto = self.funcao_de_criacao (_, serial, nome, shadow_objeto) --> shadow_objeto passa para o classe_damage gravar no .targets e .spell_tables, mas não grava nele mesmo + --> pega o index no mapa + local index = self._NameIndexTable [nome] + --> retorna o actor + if (index) then + return self._ActorTable [index], dono_do_pet, nome - novo_objeto.nome = nome - --print (nome) - - -- tipo do container ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + --> não achou, criar + elseif (criar) then - --if (self.tipo == container_playernpc) then --> CONTAINER COMUM - - if (self.tipo == container_damage) then --> CONTAINER DAMAGE + --> espelho do container no overall + local shadow = self.shadow + local shadow_objeto - get_actor_class (novo_objeto, nome, flag) - read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) - - if (dono_do_pet) then - dono_do_pet.pets [#dono_do_pet.pets+1] = nome - end - - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - novo_objeto:CriaLink (shadow_objeto) --> criando o link - shadow_objeto.flag = details_flag - if (novo_objeto.grupo and _detalhes.in_combat) then - _detalhes.cache_damage_group [#_detalhes.cache_damage_group+1] = novo_objeto + --> se tiver o espelho (não for a tabela overall já) + if (shadow) then + --> apenas verifica se ele existe ou não + shadow_objeto = shadow:PegarCombatente (_, nome) + --> se não existir, cria-lo + if (not shadow_objeto) then + --> tira o nome do pet + local novo_nome = nome:gsub ((" <.*"), "") + --> cria o objeto + shadow_objeto = shadow:PegarCombatente (serial, novo_nome, flag, true) end end - - if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player - if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile - novo_objeto.enemy = true - end - - --> try to guess his class - if (shadow) then --> não executar 2x - _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) - end - end - - if (novo_objeto.isTank) then - novo_objeto.avoidance = _detalhes:CreateActorAvoidanceTable() - end - - elseif (self.tipo == container_heal) then --> CONTAINER HEALING - - get_actor_class (novo_objeto, nome, flag) - read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) - - if (dono_do_pet) then - dono_do_pet.pets [#dono_do_pet.pets+1] = nome - end - - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - novo_objeto:CriaLink (shadow_objeto) --> criando o link - shadow_objeto.flag = details_flag - if (novo_objeto.grupo and _detalhes.in_combat) then - _detalhes.cache_healing_group [#_detalhes.cache_healing_group+1] = novo_objeto - end - end - - if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player - if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile - novo_objeto.enemy = true --print (nome.." EH UM INIMIGO -> " .. engRace) - end - - --> try to guess his class - if (shadow) then --> não executar 2x - _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) - end - end - - - elseif (self.tipo == container_energy) then --> CONTAINER ENERGY - - get_actor_class (novo_objeto, nome, flag) - read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) - - if (dono_do_pet) then - dono_do_pet.pets [#dono_do_pet.pets+1] = nome - end - - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - novo_objeto:CriaLink (shadow_objeto) --> criando o link - shadow_objeto.flag = details_flag - end - - if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player - if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile - novo_objeto.enemy = true --print (nome.." EH UM INIMIGO -> " .. engRace) - end - - --> try to guess his class - if (shadow) then --> não executar 2x - _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) - end - end - - elseif (self.tipo == container_misc) then --> CONTAINER MISC - - get_actor_class (novo_objeto, nome, flag) - read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) - - --local teste_classe = - - if (dono_do_pet) then - dono_do_pet.pets [#dono_do_pet.pets+1] = nome - end - - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - novo_objeto:CriaLink (shadow_objeto) --> criando o link - shadow_objeto.flag = details_flag - end - - if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player - if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile - novo_objeto.enemy = true --print (nome.." EH UM INIMIGO -> " .. engRace) - end - - --> try to guess his class - if (shadow) then --> não executar 2x - _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) - end - end - - elseif (self.tipo == container_damage_target) then --> CONTAINER ALVO DO DAMAGE - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - --shadow_objeto.flag = details_flag - end - - elseif (self.tipo == container_heal_target) then --> CONTAINER ALVOS DO HEALING - novo_objeto.overheal = 0 - novo_objeto.absorbed = 0 - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - --shadow_objeto.flag = details_flag - end - - elseif (self.tipo == container_energy_target) then --> CONTAINER ALVOS DO ENERGY - - novo_objeto.mana = 0 - novo_objeto.e_rage = 0 - novo_objeto.e_energy = 0 - novo_objeto.runepower = 0 - - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - end - - elseif (self.tipo == container_enemydebufftarget_target) then - - novo_objeto.uptime = 0 - novo_objeto.actived = false - novo_objeto.activedamt = 0 - - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - end - - elseif (self.tipo == container_misc_target) then --> CONTAINER ALVOS DO MISC - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - --shadow_objeto.flag = details_flag + local novo_objeto = self.funcao_de_criacao (_, serial, nome, shadow_objeto) --> shadow_objeto passa para o classe_damage gravar no .targets e .spell_tables, mas não grava nele mesmo + novo_objeto.nome = nome + + -- tipo do container + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + + if (self.tipo == container_damage) then --> CONTAINER DAMAGE + + get_actor_class (novo_objeto, nome, flag) + read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) + + if (dono_do_pet) then + dono_do_pet.pets [#dono_do_pet.pets+1] = nome + end + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + novo_objeto:CriaLink (shadow_objeto) --> criando o link + if (novo_objeto.grupo and _detalhes.in_combat) then + _detalhes.cache_damage_group [#_detalhes.cache_damage_group+1] = novo_objeto + end + end + + if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player + if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile + novo_objeto.enemy = true + end + + --> try to guess his class + if (shadow) then --> não executar 2x + _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) + end + end + + if (novo_objeto.isTank) then + novo_objeto.avoidance = _detalhes:CreateActorAvoidanceTable() + end + + elseif (self.tipo == container_heal) then --> CONTAINER HEALING + + get_actor_class (novo_objeto, nome, flag) + read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) + + if (dono_do_pet) then + dono_do_pet.pets [#dono_do_pet.pets+1] = nome + end + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + novo_objeto:CriaLink (shadow_objeto) --> criando o link + if (novo_objeto.grupo and _detalhes.in_combat) then + _detalhes.cache_healing_group [#_detalhes.cache_healing_group+1] = novo_objeto + end + end + + if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player + if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile + novo_objeto.enemy = true --print (nome.." EH UM INIMIGO -> " .. engRace) + end + + --> try to guess his class + if (shadow) then --> não executar 2x + _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) + end + end + + + elseif (self.tipo == container_energy) then --> CONTAINER ENERGY + + get_actor_class (novo_objeto, nome, flag) + read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) + + if (dono_do_pet) then + dono_do_pet.pets [#dono_do_pet.pets+1] = nome + end + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + novo_objeto:CriaLink (shadow_objeto) --> criando o link + end + + if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player + if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile + novo_objeto.enemy = true + end + + --> try to guess his class + if (shadow) then --> não executar 2x + _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) + end + end + + elseif (self.tipo == container_misc) then --> CONTAINER MISC + + get_actor_class (novo_objeto, nome, flag) + read_actor_flag (novo_objeto, shadow_objeto, dono_do_pet, serial, flag, nome) + + --local teste_classe = + + if (dono_do_pet) then + dono_do_pet.pets [#dono_do_pet.pets+1] = nome + end + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + novo_objeto:CriaLink (shadow_objeto) --> criando o link + end + + if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player + if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile + novo_objeto.enemy = true + end + + --> try to guess his class + if (shadow) then --> não executar 2x + _detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1}) + end + end + + elseif (self.tipo == container_damage_target) then --> CONTAINER ALVO DO DAMAGE + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + end + + elseif (self.tipo == container_heal_target) then --> CONTAINER ALVOS DO HEALING + novo_objeto.overheal = 0 + novo_objeto.absorbed = 0 + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + end + + elseif (self.tipo == container_energy_target) then --> CONTAINER ALVOS DO ENERGY + + novo_objeto.mana = 0 + novo_objeto.e_rage = 0 + novo_objeto.e_energy = 0 + novo_objeto.runepower = 0 + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + end + + elseif (self.tipo == container_enemydebufftarget_target) then + + novo_objeto.uptime = 0 + novo_objeto.actived = false + novo_objeto.activedamt = 0 + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + end + + elseif (self.tipo == container_misc_target) then --> CONTAINER ALVOS DO MISC + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + end + + elseif (self.tipo == container_friendlyfire) then --> CONTAINER FRIENDLY FIRE + + get_actor_class (novo_objeto, nome) + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + end end - - elseif (self.tipo == container_friendlyfire) then --> CONTAINER FRIENDLY FIRE - - get_actor_class (novo_objeto, nome) - - if (shadow_objeto) then - novo_objeto.shadow = shadow_objeto - shadow_objeto.flag = details_flag - end - end - + + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -- grava o objeto no mapa do container ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - --[[ - if (self.tipo == container_damage) then - if (nome:find ("Lyl")) then - if (nome:find ("-")) then - print ("nome FIM com -", isOwner) - else - --print ("nome FIM okey", isOwner) - end + local size = #self._ActorTable+1 + self._ActorTable [size] = novo_objeto --> grava na tabela de indexes + self._NameIndexTable [nome] = size --> grava no hash map o index deste jogador + + return novo_objeto, dono_do_pet, nome + else + return nil, nil, nil + end + end + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> core + + function container_combatentes:FuncaoDeCriacao (tipo) + if (tipo == container_damage_target) then + return alvo_da_habilidade.NovaTabela + + elseif (tipo == container_damage) then + return atributo_damage.NovaTabela + + elseif (tipo == container_heal_target) then + return alvo_da_habilidade.NovaTabela + + elseif (tipo == container_heal) then + return atributo_heal.NovaTabela + + elseif (tipo == container_friendlyfire) then + return atributo_damage.FF_funcao_de_criacao + + elseif (tipo == container_enemydebufftarget_target) then + return alvo_da_habilidade.NovaTabela + + elseif (tipo == container_energy) then + return atributo_energy.NovaTabela + + elseif (tipo == container_energy_target) then + return alvo_da_habilidade.NovaTabela + + elseif (tipo == container_misc) then + return atributo_misc.NovaTabela + + elseif (tipo == container_misc_target) then + return alvo_da_habilidade.NovaTabela + + end + end + + --> chama a função para ser executada em todos os atores + function container_combatentes:ActorCallFunction (funcao, ...) + for index, actor in _ipairs (self._ActorTable) do + funcao (nil, actor, ...) + end + end + + function container_combatentes:remapear() + local mapa = self._NameIndexTable + local conteudo = self._ActorTable + for i = 1, #conteudo do + mapa [conteudo[i].nome] = i + end + end + + function _detalhes.refresh:r_container_combatentes (container, shadow) + --> reconstrói meta e indexes + _setmetatable (container, _detalhes.container_combatentes) + container.__index = _detalhes.container_combatentes + container.funcao_de_criacao = container_combatentes:FuncaoDeCriacao (container.tipo) + + --> repara mapa + local mapa = {} + for i = 1, #container._ActorTable do + mapa [container._ActorTable[i].nome] = i end - end - --]] + container._NameIndexTable = mapa - local size = #self._ActorTable+1 - self._ActorTable [size] = novo_objeto --> grava na tabela de indexes - self._NameIndexTable [nome] = size --> grava no hash map o index deste jogador - - return novo_objeto, dono_do_pet, nome - else - return nil, nil, nil + --> seta a shadow + container.shadow = shadow end -end -function container_combatentes:FuncaoDeCriacao (tipo) - if (tipo == container_damage_target) then - return alvo_da_habilidade.NovaTabela - - elseif (tipo == container_damage) then - return atributo_damage.NovaTabela - - elseif (tipo == container_heal_target) then - return alvo_da_habilidade.NovaTabela - - elseif (tipo == container_heal) then - return atributo_heal.NovaTabela - - elseif (tipo == container_friendlyfire) then - return atributo_damage.FF_funcao_de_criacao - - elseif (tipo == container_enemydebufftarget_target) then - return alvo_da_habilidade.NovaTabela - - elseif (tipo == container_energy) then - return atributo_energy.NovaTabela - - elseif (tipo == container_energy_target) then - return alvo_da_habilidade.NovaTabela - - elseif (tipo == container_misc) then - return atributo_misc.NovaTabela - - elseif (tipo == container_misc_target) then - return alvo_da_habilidade.NovaTabela - - end -end - ---> chama a função para ser executada em todos os atores -function container_combatentes:ActorCallFunction (funcao, ...) - for index, actor in _ipairs (self._ActorTable) do - funcao (nil, actor, ...) - end -end - -function container_combatentes:remapear() - local mapa = self._NameIndexTable - local conteudo = self._ActorTable - for i = 1, #conteudo do - mapa [conteudo[i].nome] = i - end -end - -function _detalhes.refresh:r_container_combatentes (container, shadow) - --> reconstrói meta e indexes - _setmetatable (container, _detalhes.container_combatentes) - container.__index = _detalhes.container_combatentes - container.funcao_de_criacao = container_combatentes:FuncaoDeCriacao (container.tipo) - - --> repara mapa - local mapa = {} - for i = 1, #container._ActorTable do - mapa [container._ActorTable[i].nome] = i - end - container._NameIndexTable = mapa - - --> seta a shadow - container.shadow = shadow -end - -function _detalhes.clear:c_container_combatentes (container) - --container.__index = {} - container.__index = nil - container.shadow = nil - container._NameIndexTable = nil - container.need_refresh = nil - container.funcao_de_criacao = nil -end \ No newline at end of file + function _detalhes.clear:c_container_combatentes (container) + container.__index = nil + container.shadow = nil + container._NameIndexTable = nil + container.need_refresh = nil + container.funcao_de_criacao = nil + end \ No newline at end of file diff --git a/classes/container_habilidades.lua b/classes/container_habilidades.lua index 7a042922..11d32286 100644 --- a/classes/container_habilidades.lua +++ b/classes/container_habilidades.lua @@ -1,129 +1,124 @@ +-- spells container file + local _detalhes = _G._detalhes ---local AceLocale = LibStub ("AceLocale-3.0") ---local Loc = AceLocale:GetLocale ( "Details" ) - -local gump = _detalhes.gump - -local _setmetatable = setmetatable local _ -local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC -local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS -local container_heal = _detalhes.container_type.CONTAINER_HEAL_CLASS -local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS -local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE -local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS -local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS -local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS -local container_misc = _detalhes.container_type.CONTAINER_MISC_CLASS -local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> local pointers -local habilidade_dano = _detalhes.habilidade_dano -local habilidade_cura = _detalhes.habilidade_cura -local habilidade_e_energy = _detalhes.habilidade_e_energy -local habilidade_misc = _detalhes.habilidade_misc + local _setmetatable = setmetatable --lua local -local container_habilidades = _detalhes.container_habilidades - -function container_habilidades:NovoContainer (tipo_do_container) - - local _newContainer = { - funcao_de_criacao = container_habilidades:FuncaoDeCriacao (tipo_do_container), - tipo = tipo_do_container, - _ActorTable = {} - } +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> constants - _setmetatable (_newContainer, container_habilidades) - - return _newContainer -end + local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC + local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS + local container_heal = _detalhes.container_type.CONTAINER_HEAL_CLASS + local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS + local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE + local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS + local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS + local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS + local container_misc = _detalhes.container_type.CONTAINER_MISC_CLASS + local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS -function container_habilidades:Dupe (who) - local novo_objeto = {} - if (_getmetatable (who)) then - _setmetatable (novo_objeto, _getmetatable (who)) - end - - for cprop, value in _pairs (who) do - novo_objeto[cprop] = value - end - - return novo_objeto -end + local habilidade_dano = _detalhes.habilidade_dano + local habilidade_cura = _detalhes.habilidade_cura + local habilidade_e_energy = _detalhes.habilidade_e_energy + local habilidade_misc = _detalhes.habilidade_misc -function container_habilidades:GetSpell (id) - return self._ActorTable [id] -end + local container_habilidades = _detalhes.container_habilidades -function container_habilidades:PegaHabilidade (id, criar, token, cria_shadow) - local esta_habilidade = self._ActorTable [id] - if (esta_habilidade) then - return esta_habilidade - else - if (criar) then +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--> internals + + function container_habilidades:NovoContainer (tipo_do_container) + local _newContainer = { + funcao_de_criacao = container_habilidades:FuncaoDeCriacao (tipo_do_container), + tipo = tipo_do_container, + _ActorTable = {} + } - if (cria_shadow) then - local novo_objeto = self.funcao_de_criacao (nil, id, nil, "") - self._ActorTable [id] = novo_objeto - return novo_objeto - end - - local shadow = self.shadow --> retorna o container semelhante a esta na tabela overall - local shadow_objeto = nil - - if (shadow) then --> talvez possa mandar todos os parâmetros de criação logo no inicio - shadow_objeto = shadow:PegaHabilidade (id) --> apenas verifica se ele existe ou não - if (not shadow_objeto) then --> se não existir, cria-lo - shadow_objeto = shadow:PegaHabilidade (id, true, token) - end - end - - --local novo_objeto = habilidade_dano:NovaTabela (id, shadow_objeto) - local novo_objeto = self.funcao_de_criacao (nil, id, shadow_objeto, token) - - if (shadow_objeto) then --> link é esta mesma tabela mas no container do overall - novo_objeto.shadow = shadow_objeto --> diz ao objeto qual a shadow dele na tabela overall - --novo_objeto:CriaLink (shadow_objeto) --> cria o link entre o objeto e a sua shadow - end + _setmetatable (_newContainer, container_habilidades) - self._ActorTable [id] = novo_objeto - - return novo_objeto + return _newContainer + end + + function container_habilidades:GetSpell (id) + return self._ActorTable [id] + end + + function container_habilidades:PegaHabilidade (id, criar, token, cria_shadow) + + local esta_habilidade = self._ActorTable [id] + + if (esta_habilidade) then + return esta_habilidade else - return nil + if (criar) then + + if (cria_shadow) then + local novo_objeto = self.funcao_de_criacao (nil, id, nil, "") + self._ActorTable [id] = novo_objeto + return novo_objeto + end + + local shadow = self.shadow + local shadow_objeto = nil + + if (shadow) then + --> apenas verifica se ele existe ou não + shadow_objeto = shadow:PegaHabilidade (id) + --> se não existir, cria-lo + if (not shadow_objeto) then + shadow_objeto = shadow:PegaHabilidade (id, true, token) + end + end + + local novo_objeto = self.funcao_de_criacao (nil, id, shadow_objeto, token) + + if (shadow_objeto) then + novo_objeto.shadow = shadow_objeto + end + + self._ActorTable [id] = novo_objeto + + return novo_objeto + else + return nil + end end end -end -function container_habilidades:FuncaoDeCriacao (tipo) - if (tipo == container_damage) then - return habilidade_dano.NovaTabela - - elseif (tipo == container_heal) then - return habilidade_cura.NovaTabela + function container_habilidades:FuncaoDeCriacao (tipo) + if (tipo == container_damage) then + return habilidade_dano.NovaTabela + + elseif (tipo == container_heal) then + return habilidade_cura.NovaTabela - elseif (tipo == container_energy) then - return habilidade_e_energy.NovaTabela - - elseif (tipo == container_misc) then - return habilidade_misc.NovaTabela - + elseif (tipo == container_energy) then + return habilidade_e_energy.NovaTabela + + elseif (tipo == container_misc) then + return habilidade_misc.NovaTabela + + end end -end -function _detalhes.refresh:r_container_habilidades (container, shadow) - --> reconstrói meta e indexes - _setmetatable (container, _detalhes.container_habilidades) - container.__index = _detalhes.container_habilidades - local func_criacao = container_habilidades:FuncaoDeCriacao (container.tipo) - container.funcao_de_criacao = func_criacao - --> seta a shadow - container.shadow = shadow -end + function _detalhes.refresh:r_container_habilidades (container, shadow) + --> reconstrói meta e indexes + _setmetatable (container, _detalhes.container_habilidades) + container.__index = _detalhes.container_habilidades + local func_criacao = container_habilidades:FuncaoDeCriacao (container.tipo) + container.funcao_de_criacao = func_criacao + --> seta a shadow + container.shadow = shadow + end -function _detalhes.clear:c_container_habilidades (container) - --container.__index = {} - container.__index = nil - container.shadow = nil - container.funcao_de_criacao = nil -end + function _detalhes.clear:c_container_habilidades (container) + --container.__index = {} + container.__index = nil + container.shadow = nil + container.funcao_de_criacao = nil + end diff --git a/core/control.lua b/core/control.lua index 789903a1..5f64b873 100644 --- a/core/control.lua +++ b/core/control.lua @@ -62,7 +62,7 @@ for _, actor in _ipairs (_detalhes.tabela_vigente[class_type_dano]._ActorTable) do - if (not actor.grupo and not actor.owner and not actor.nome:find ("[*]") and _bit_band (actor.flag, 0x00000060) ~= 0) then --> 0x20+0x40 neutral + enemy reaction + if (not actor.grupo and not actor.owner and not actor.nome:find ("[*]") and _bit_band (actor.flag_original, 0x00000060) ~= 0) then --> 0x20+0x40 neutral + enemy reaction if (trash_list) then local serial = tonumber (actor.serial:sub(6, 10), 16) diff --git a/core/meta.lua b/core/meta.lua index d5d24800..a167ab89 100644 --- a/core/meta.lua +++ b/core/meta.lua @@ -41,7 +41,6 @@ local class_type_cura = _detalhes.atributos.cura local class_type_e_energy = _detalhes.atributos.e_energy local class_type_misc = _detalhes.atributos.misc - local DFLAG_pet = _detalhes.flags.pet ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --> core diff --git a/core/parser.lua b/core/parser.lua index 4d7c2fb0..ca837bfc 100644 --- a/core/parser.lua +++ b/core/parser.lua @@ -339,6 +339,27 @@ --if (_bit_band (who_flags, REACTION_FRIENDLY) ~= 0 and _bit_band (alvo_flags, REACTION_FRIENDLY) ~= 0) then (old friendly check) if (raid_members_cache [who_serial] and raid_members_cache [alvo_serial]) then + --> record death log + local t = jogador_alvo.last_events_table + local i = t.n + + t.n = i + 1 + + t = t [i] + + t [1] = true --> true if this is a damage || false for healing + t [2] = spellid --> spellid || false if this is a battle ress line + t [3] = amount --> amount of damage or healing + t [4] = time --> parser time + t [5] = _UnitHealth (alvo_name) --> current unit heal + t [6] = who_name --> source name + + i = i + 1 + if (i == 9) then + jogador_alvo.last_events_table.n = 1 + end + + --> faz a adução do friendly fire este_jogador.friendlyfire_total = este_jogador.friendlyfire_total + amount local amigo = este_jogador.friendlyfire._NameIndexTable [alvo_name] @@ -1462,7 +1483,7 @@ t = t [i] - t [1] = 1 --> true if this is a damage || false for healing || 1 for cooldown? + t [1] = 1 --> true if this is a damage || false for healing || 1 for cooldown t [2] = spellid --> spellid || false if this is a battle ress line t [3] = 1 --> amount of damage or healing t [4] = time --> parser time @@ -2104,30 +2125,42 @@ end end - --_table_sort (esta_morte, _detalhes.Sort4) + _table_sort (esta_morte, _detalhes.Sort4) + --[[ _table_sort (esta_morte, function (table1, table2) - - if (not table1) then return false end - if (not table2) then return true end - - if (table1 [4] == table2 [4]) then --> os 2 tem o mesmo tempo + if (not table1) then + print (1) + return false + + elseif (not table2) then + print (2) + return false + + elseif (table1 [4] == table2 [4]) then --> os 2 tem o mesmo tempo if (type (table1 [1]) == "boolean" and table1 [1] and type (table2 [1]) == "boolean" and table2) then --> ambos sao dano + print (3) return table1 [5] > table2 [5] --> joga pra cima quem tem mais vida elseif (type (table1 [1]) == "boolean" and not table1 [1] and type (table2 [1]) == "boolean" and not table2) then --> ambos sao cura + print (4) return table1 [5] < table2 [5] --> joga pra cima quem tem menos vida else if (type (table1 [1]) == "boolean" and table1 and type (table2 [1]) == "boolean" and table2) then --> primeiro é dano e segundo é heal + print (5) return true --> passa o dano pra frente elseif (type (table2 [1]) == "boolean" and table2 and type (table1 [1]) == "boolean" and table1) then --> primeiro é heal e o segundo é dano + print (6) return false --> passa o heal pra frente else + print (7) return table1 [5] < table2 [5] --> passa quem tem menos vida end end else + print (8) return table1 [4] < table2 [4] end end) + --]] if (_hook_deaths) then --> send event to registred functions @@ -2627,6 +2660,23 @@ end end + function _detalhes.parser_functions:PET_BATTLE_OPENING_START (...) + _detalhes.pet_battle = true + for index, instance in _ipairs (_detalhes.tabela_instancias) do + if (instance.ativa) then + instance:SetWindowAlphaForCombat (true, true) + end + end + end + function _detalhes.parser_functions:PET_BATTLE_CLOSE (...) + _detalhes.pet_battle = false + for index, instance in _ipairs (_detalhes.tabela_instancias) do + if (instance.ativa) then + instance:SetWindowAlphaForCombat() + end + end + end + local parser_functions = _detalhes.parser_functions function _detalhes:OnEvent (evento, ...) diff --git a/core/util.lua b/core/util.lua index 029a7c14..05f0cd08 100644 --- a/core/util.lua +++ b/core/util.lua @@ -308,11 +308,6 @@ return nil end - --> Armazena uma label recém criada - Store a new label on the pool - function _detalhes.font_pool:add (_fontstring) - self [#self+1] = _fontstring - end - local function frame_task (self, elapsed) self.FrameTime = self.FrameTime + elapsed diff --git a/framework/cooltip.lua b/framework/cooltip.lua index ee87d512..52cd7694 100644 --- a/framework/cooltip.lua +++ b/framework/cooltip.lua @@ -1500,7 +1500,11 @@ function DetailsCreateCoolTip() if (f2_start_point < f1_end_point) then local diff = f2_start_point - f1_end_point CoolTip.overlap_checked = true - return CoolTip:SetMyPoint (host, CoolTip.internal_x_mod + diff, CoolTip.internal_y_mod) + + frame2:ClearAllPoints() + frame2:SetPoint ("bottomright", frame1, "bottomleft") + --+ diff + return CoolTip:SetMyPoint (host, CoolTip.internal_x_mod , CoolTip.internal_y_mod) end end @@ -1702,6 +1706,9 @@ function DetailsCreateCoolTip() --> wipe all data ~reset function CoolTip:Reset() + + frame2:ClearAllPoints() + frame2:SetPoint ("bottomleft", frame1, "bottomright") CoolTip.FixedValue = nil CoolTip.HaveSubMenu = false diff --git a/functions/classes.lua b/functions/classes.lua index d055f4a4..e3a3278a 100644 --- a/functions/classes.lua +++ b/functions/classes.lua @@ -99,4 +99,12 @@ do CONTAINER_MISCTARGET_CLASS = 10, CONTAINER_ENEMYDEBUFFTARGET_CLASS = 11 } + + function _detalhes:Name (actor) + return self.nome or actor.nome + end + function _detalhes:GetName (actor) + return actor.nome or self.nome + end + end diff --git a/gumps/janela_custom.lua b/gumps/janela_custom.lua index bc9db60a..cf318a9d 100644 --- a/gumps/janela_custom.lua +++ b/gumps/janela_custom.lua @@ -50,13 +50,29 @@ local function CreateCustomWindow() insets = {left = 0, right = 0, top = 0, bottom = 0}} local frame = CreateFrame ("frame", "DetailsCustomPanel", UIParent) - frame:SetPoint ("center", UIParent, "center", 100, -300) + frame:SetPoint ("center", UIParent, "center", 100, -100) frame:SetWidth (512) - frame:SetHeight (150) + frame:SetHeight (183) frame:EnableMouse (true) frame:SetMovable (true) frame:SetFrameLevel (1) + local frameD = CreateFrame ("frame", "DetailsCustomPanelDisable", frame) + frameD:SetPoint ("center", frame, "center") + frameD:SetWidth (512) + frameD:SetHeight (183) + frameD:EnableMouse (true) + frameD:SetFrameStrata ("fullscreen") + frameD:SetBackdrop ({ + bgFile = "Interface\\AddOns\\Details\\images\\background", + edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", + tile = true, tileSize = 16, edgeSize = 4}) + frameD:SetBackdropColor (0, 0, 0, .8) + frameD.string = frameD:CreateFontString (nil, "overlay", "GameFontNormal") + frameD.string:SetPoint ("center", frameD, "center") + frameD.string:SetText ("There is a problem connecting some nether tubes\nOur ethereal engineers are already working to fix this issue,\n\nTo avoid mana wyrms proliferation, this panel is disabled for now.\n(Press Escape To Close)") + --frameD:Hide() + frame.fundo = frame:CreateTexture (nil, "border") frame.fundo:SetTexture ("Interface\\AddOns\\Details\\images\\custom_bg") frame.fundo:SetPoint ("topleft", frame, "topleft") @@ -210,16 +226,7 @@ local function CreateCustomWindow() fundoBrilha:SetPoint ("left", frame.MainMenu [atributo].icon , "right", -20, -10) - --[[ - for i = 1, 5 do - if (sub_atributos [atributo].lista[i]) then - frame.SubMenu [i].text:SetText (sub_atributos [atributo].lista[i]) - frame.SubMenu [i]:Show() - else - frame.SubMenu [i]:Hide() - end - end - --]] + frame.selectAttributeDropdown:Select (1, true) end frame.MainMenu = {} @@ -245,6 +252,8 @@ local function CreateCustomWindow() local half = 0.00048828125 local size = 0.03125 + local att_names = {Loc ["STRING_CUSTOM_ATT1"], Loc ["STRING_CUSTOM_ATT2"], Loc ["STRING_CUSTOM_ATT3"], Loc ["STRING_CUSTOM_ATT4"]} + for i = 1, 4 do local button = gump:NewDetailsButton (frame, frame, _, MainMenu, i, nil, 120, 15, "", "", "", "", nil, "DetailsCustomPanelAttributeButton"..i) @@ -282,8 +291,8 @@ local function CreateCustomWindow() button.textura:SetWidth (76) button.textura:SetHeight (40) - button:SetPoint ("topleft", frame, "topleft", x, i*-25 + (y)) - button.text:SetText (atributos.lista [i]) + button:SetPoint ("topleft", frame, "topleft", x, i*-33 + (y)) + button.text:SetText (att_names [i]) button.text:SetPoint ("left", button, "left", 65, 0) button:SetFrameLevel (frame:GetFrameLevel()+2) @@ -309,20 +318,52 @@ local function CreateCustomWindow() end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - --> Edit Boxes +--> Edit Boxes local xStart = 290 local WidthMax = 220 + +--> labels + local name_text = gump:NewLabel (frame, nil, "$parentNameBoxLabel", nil, Loc ["STRING_CUSTOM_NAME"], "GameFontHighlightLeft", 11) + local spell_text = gump:NewLabel (frame, nil, "$parentSpellBoxLabel", nil, Loc ["STRING_CUSTOM_SPELLID"]) + local source_text = gump:NewLabel (frame, nil, "$parentSourceBoxLabel", nil, Loc ["STRING_CUSTOM_SOURCE"]) + local target_text = gump:NewLabel (frame, nil, "$parentTargetBoxLabel", nil, Loc ["STRING_CUSTOM_TARGET"]) + local subattribute_text = gump:NewLabel (frame, nil, "$parentSubAttributeBoxLabel", nil, Loc ["STRING_CUSTOM_ATTRIBUTE"]) -----------> The name of the custom - local MyNameSelected = function (param1, param2, texto, editbox) --print (param1, param2, texto, editbox) + name_text:SetPoint ("topleft", frame, "topleft", xStart, -45) + subattribute_text:SetPoint ("topleft", frame, "topleft", xStart, -65) + source_text:SetPoint ("topleft", frame, "topleft", xStart, -85) + target_text:SetPoint ("topleft", frame, "topleft", xStart, -105) + spell_text:SetPoint ("topleft", frame, "topleft", xStart, -125) + +--> name entry + local name_entry = gump:NewTextEntry (frame, frame, "$parentNameEntry", "TextMyNameEntry", 140, 20) + name_entry:SetFrameLevel (frame:GetFrameLevel()+2) + name_entry:SetPoint ("left", name_text, "right", 2, 0) + +--> sub attribute + + local on_choose_attribute = function (_, _, attribute_number) + frame.sub_atributo = attribute_number + end + local build_attribute_menu = function() + local menu = {} + + local attributes = _detalhes.sub_atributos [frame.atributo].lista + local icons = _detalhes.sub_atributos [frame.atributo].icones + + for index, attribute_name in ipairs (attributes) do + menu [#menu+1] = {value = index, label = attribute_name, onclick = on_choose_attribute, icon = icons [index] [1], texcoord = icons [index] [2]} + end + + return menu end - gump:NewTextBox (frame, frame, "TextMyNameEntry", SpellIDSelected, "param_1", "param_2", 100, 15, {TabOnEnterPress = true, MySpace = WidthMax}) - frame ["TextMyNameEntry"]:SetFrameLevel (frame:GetFrameLevel()+2) - frame ["TextMyNameEntry"]:SetPointAndSpace ("topleft", frame, "topleft", xStart, -45, WidthMax) - frame ["TextMyNameEntry"]:SetLabelText (Loc ["STRING_CUSTOM_NAME"]..":") -----------> Spell Name ou ID + local select_attribute = gump:NewDropDown (frame, frame, "$parentAttributeDropdown", "selectAttributeDropdown", 140, 20, build_attribute_menu) + select_attribute:SetFrameLevel (frame:GetFrameLevel()+2) + select_attribute:SetPoint ("left", subattribute_text, "right", 2, 0) + +--> spell id entry local SpellIDSelected = function (param1, param2, texto, editbox) local _ThisSpellName, _, _ThisSpellIcon = _GetSpellInfo (tonumber (texto)) if (_ThisSpellName) then @@ -336,17 +377,12 @@ local function CreateCustomWindow() end end - gump:NewTextBox (frame, frame, "TextSpellIDEntry", SpellIDSelected, "param_1", "param_2", 80, 15, {TabOnEnterPress = true, MySpace = WidthMax-20}) + local spellid_entry = gump:NewSpellEntry (frame, SpellIDSelected, 140, 20, nil, nil, "TextSpellIDEntry", "$parentSpellidEntry") + spellid_entry:SetPoint ("left", spell_text, "right", 2, 0) frame ["TextSpellIDEntry"]:SetFrameLevel (frame:GetFrameLevel()+2) - frame ["TextSpellIDEntry"]:SetPointAndSpace ("topleft", frame, "topleft", xStart, -62, WidthMax-20) - frame ["TextSpellIDEntry"]:SetLabelText (Loc ["STRING_CUSTOM_SPELLID"]) - - local openSpellEncounter = function() - - end - + local frameEncounterSkill = CreateFrame ("frame", nil, frame) - frameEncounterSkill:SetPoint ("left", frame ["TextSpellIDEntry"], "right") + frameEncounterSkill:SetPoint ("left", frame ["TextSpellIDEntry"].widget, "right") frameEncounterSkill:SetWidth (20) frameEncounterSkill:SetHeight (20) frameEncounterSkill:SetFrameLevel (frame:GetFrameLevel()+2) @@ -479,8 +515,6 @@ local function CreateCustomWindow() GameCooltip:SetOption ("HeightAnchorMod", -10) GameCooltip:ShowCooltip() - - --_detalhes.EncounterInformation [instanceTable.id] = InstanceTable end frameEncounterSkill:SetScript ("OnEnter", function() @@ -492,100 +526,17 @@ local function CreateCustomWindow() frameEncounterSkillImage:SetBlendMode ("BLEND") end) - frame ["TextSpellIDEntry"].HaveMenu = false - - frame ["TextSpellIDEntry"].OnLeaveHook = function() - _detalhes.popup.buttonOver = false - if (_detalhes.popup.ativo) then - local passou = 0 - frame ["TextSpellIDEntry"]:SetScript ("OnUpdate", function (self, elapsed) - passou = passou+elapsed - if (passou > 0.3) then - if (not _detalhes.popup.mouseOver and not _detalhes.popup.buttonOver) then - _detalhes.popup:ShowMe (false) - end - frame ["TextSpellIDEntry"]:SetScript ("OnUpdate", nil) - end - end) - else - frame ["TextSpellIDEntry"]:SetScript ("OnUpdate", nil) - end - end - - frame ["TextSpellIDEntry"].OnFocusLostHook = function() - frame ["TextSpellIDEntry"].HaveMenu = false - end - - local OnClickMenu = function (_, _, SpellID) - frame ["TextSpellIDEntry"]:SetText (SpellID) - frame ["TextSpellIDEntry"]:PressEnter() - frame ["TextSpellIDEntry"].HaveMenu = false - _detalhes.popup:ShowMe (false) - end - local _string_lower = string.lower local _string_sub = string.sub - frame ["TextSpellIDEntry"].TextChangeedHook = function (userChanged) - if (not userChanged) then - return - end - - local texto = frame ["TextSpellIDEntry"]:GetText() - texto = _detalhes:trim (texto) - texto = _string_lower (texto) - - local index = _string_sub (texto, 1, 1) - local cached = _detalhes.spellcachefull [index] - - if (cached) then - - local CoolTip = _G.GameCooltip - - CoolTip:Reset() - CoolTip:SetType ("menu") - CoolTip:SetColor ("main", "transparent") - CoolTip:SetOwner (frame ["TextSpellIDEntry"]) - CoolTip:SetOption ("NoLastSelectedBar", true) - CoolTip:SetOption ("TextSize", 9.5) - - local CoolTipTable = {} - local texcoord = {0, 1, 0, 1} - local i = 1 - - for SpellID, SpellTable in _pairs (cached) do - - if (_string_lower (SpellTable[1]):find (texto)) then - local rank = SpellTable[3] - if (not rank or rank == "") then - rank = "" - else - rank = " ("..rank..")" - end - - CoolTip:AddMenu (1, OnClickMenu, SpellID, nil, nil, SpellID..": "..SpellTable[1]..rank, SpellTable[2], true) - - if (i > 20) then - break - else - i = i + 1 - end - end - - end - - frame ["TextSpellIDEntry"].HaveMenu = true - CoolTip.buttonOver = true - CoolTip:ShowCooltip() - end - end - -----------> Source +--> source local SourceSelected = function (param1, param2, texto, editbox) end - gump:NewTextBox (frame, frame, "TextSourceEntry", SourceSelected, "param_1", "param_2", 100, 15, {TabOnEnterPress = true, MySpace = WidthMax}) + + local source_entry = gump:NewTextEntry (frame, frame, "$parentSourceEntry", "TextSourceEntry", 140, 20) + frame ["TextSourceEntry"]:SetFrameLevel (frame:GetFrameLevel()+2) - frame ["TextSourceEntry"]:SetPointAndSpace ("topleft", frame, "topleft", xStart, -79, WidthMax) - frame ["TextSourceEntry"]:SetLabelText (Loc ["STRING_CUSTOM_SOURCE"]..":") + frame ["TextSourceEntry"]:SetPoint ("left", source_text, "right", 2, 0) + frame ["TextSourceEntry"].InputHook = function() local texto = frame ["TextSourceEntry"]:GetText() texto:gsub ("[raid]", "|cFFFF00FF|r[raid]") @@ -604,26 +555,24 @@ local function CreateCustomWindow() end end ----------> Actor Name - local ActorNameSelected = function (param1, param2, texto, editbox) end - gump:NewTextBox (frame, frame, "TextActorNameEntry", ActorNameSelected, "param_1", "param_2", 100, 15, {TabOnEnterPress = true}) - frame ["TextActorNameEntry"]: SetFrameLevel (frame:GetFrameLevel()+2) - frame ["TextActorNameEntry"]:SetPointAndSpace ("topleft", frame, "topleft", xStart, -96, WidthMax) - frame ["TextActorNameEntry"]:SetLabelText (Loc ["STRING_CUSTOM_TARGET"]..":") +--> target + + local target_entry = gump:NewTextEntry (frame, frame, "$parentTargetEntry", "TextActorNameEntry", 140, 20) + frame ["TextActorNameEntry"]:SetFrameLevel (frame:GetFrameLevel()+2) + frame ["TextActorNameEntry"]:SetPoint ("left", target_text, "right", 2, 0) --> Tab Order - frame ["TextMyNameEntry"]:SetNext (frame ["TextSpellIDEntry"]) - frame ["TextSpellIDEntry"]:SetNext (frame ["TextSourceEntry"]) + frame ["TextMyNameEntry"]:SetNext (frame ["TextSourceEntry"]) frame ["TextSourceEntry"]:SetNext (frame ["TextActorNameEntry"]) - frame ["TextActorNameEntry"]:SetNext (frame ["TextMyNameEntry"]) - frame ["TextActorNameEntry"]:Disable() + frame ["TextActorNameEntry"]:SetNext (frame ["TextSpellIDEntry"]) + frame ["TextSpellIDEntry"]:SetNext (frame ["TextMyNameEntry"]) --> Tooltips --> localize-me frame ["TextMyNameEntry"].tooltip = Loc ["STRING_CUSTOM_TOOLTIPNAME"] frame ["TextSpellIDEntry"].tooltip = Loc ["STRING_CUSTOM_TOOLTIPSPELL"] frame ["TextSourceEntry"].tooltip = Loc ["STRING_CUSTOM_TOOLTIPSOURCE"] - frame ["TextActorNameEntry"].tooltip = Loc ["STRING_CUSTOM_TOOLTIPTARGET"].."\n|cFFFF0000"..Loc ["STRING_CUSTOM_TOOLTIPNOTWORKING"] + frame ["TextActorNameEntry"].tooltip = Loc ["STRING_CUSTOM_TOOLTIPTARGET"] -- .."\n|cFFFF0000"..Loc ["STRING_CUSTOM_TOOLTIPNOTWORKING"] frame.IconTexture = "Interface\\Icons\\TEMP" @@ -810,7 +759,7 @@ local function CreateCustomWindow() end local CustomName = frame ["TextMyNameEntry"].text - local SpellID = frame ["TextSpellIDEntry"].text + local SpellID = tonumber (frame ["TextSpellIDEntry"].text) local Actor = frame ["TextActorNameEntry"].text local Source = frame ["TextSourceEntry"].text @@ -826,15 +775,16 @@ local function CreateCustomWindow() return end - if (string.len (SpellID) < 1) then - --print ("Sem id da magia") - print (Loc ["STRING_CUSTOM_NOSPELL"]) - frame ["TextSpellIDEntry"]:Blink() - return - end + --if (string.len (SpellID) < 1) then + -- --print ("Sem id da magia") + -- print (Loc ["STRING_CUSTOM_NOSPELL"]) + -- frame ["TextSpellIDEntry"]:Blink() + -- return + --end - _detalhes.custom [#_detalhes.custom+1] = {name = CustomName, spell = SpellID, target = Actor, source = Source, inout = InOut, icon = frame.IconTexture, attribute = Atributo, sattribute = SubAtributo} - print (Loc ["STRING_CUSTOM_CREATED"]) + _detalhes.custom [#_detalhes.custom+1] = {name = CustomName, spell = SpellID, target = Actor, source = Source, icon = frame.IconTexture, attribute = Atributo, sattribute = SubAtributo} + --print (CustomName, Actor, Source, SpellID, frame.IconTexture, Atributo, SubAtributo) + _detalhes:Msg (Loc ["STRING_CUSTOM_CREATED"]) _detalhes:CloseCustomWindow() reset() end @@ -842,7 +792,7 @@ local function CreateCustomWindow() local IconButton = gump:NewDetailsButton (frame, frame, _, ChooseIcon, nil, nil, 80, 15, "", "", "", "", nil, "DetailsCustomPanelIconButton") IconButton.text:SetText (Loc ["STRING_CUSTOM_ICON"]) IconButton.text:SetPoint ("left", IconButton, "left", 3, 0) - IconButton:SetPoint ("topleft", frame, "topleft", xStart+21, -118) + IconButton:SetPoint ("topleft", frame, "topleft", xStart+21, -158) IconButton:SetFrameLevel (frame:GetFrameLevel()+2) IconButton:InstallCustomTexture (_, {x1 = -20, x2 = 0, y1 = 0, y2 = 0}) frame.iconbutton = IconButton @@ -856,7 +806,7 @@ local function CreateCustomWindow() local CreateButton = gump:NewDetailsButton (frame, frame, _, CreateFunction, nil, nil, 80, 15, "", "", "", "", nil, "DetailsCustomPanelCreateButton") CreateButton.text:SetText (Loc ["STRING_CUSTOM_CREATE"]) - CreateButton:SetPoint ("topleft", frame, "topleft", 413, -118) + CreateButton:SetPoint ("topleft", frame, "topleft", 413, -158) CreateButton:SetFrameLevel (frame:GetFrameLevel()+2) CreateButton:InstallCustomTexture (_, {x1 = -20, x2 = 0, y1 = 0, y2 = 0}) @@ -970,21 +920,21 @@ function _detalhes:InitCustom() end function _detalhes:OpenCustomWindow() - if (InCombatLockdown()) then - print ("|cffFF2222"..Loc ["STRING_CUSTOM_INCOMBAT"]) - return - end + --if (InCombatLockdown()) then + -- print ("|cffFF2222"..Loc ["STRING_CUSTOM_INCOMBAT"]) + -- return + --end if (not _detalhes.CustomFrame.oponed) then _detalhes.CustomFrame.oponed = true - _detalhes:BuildSpellList() + --_detalhes:BuildSpellList() _detalhes.CustomFrame:Show() end end function _detalhes:CloseCustomWindow() _detalhes.CustomFrame.oponed = false - _detalhes:ClearSpellList() + --_detalhes:ClearSpellList() _detalhes.CustomFrame:Hide() end diff --git a/gumps/janela_info.lua b/gumps/janela_info.lua index 5cd046a6..96dc6460 100644 --- a/gumps/janela_info.lua +++ b/gumps/janela_info.lua @@ -1,5 +1,6 @@ local _detalhes = _G._detalhes local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" ) +local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0") local gump = _detalhes.gump local _ @@ -7,7 +8,7 @@ local _ --local _string_len = string.len local _math_floor = math.floor local _ipairs = ipairs ---local _pairs = pairs +local _pairs = pairs local _type = type --api locals local _CreateFrame = CreateFrame @@ -1580,7 +1581,7 @@ function gump:CriaJanelaInfo() --]] end - + _detalhes:CreatePlayerDetailsTab ("Avoidance", --[1] tab name function (tabOBject, playerObject) --[2] condition if (playerObject.isTank) then @@ -1597,6 +1598,649 @@ function gump:CriaJanelaInfo() avoidance_create --[5] oncreate ) +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + local fill_compare_actors = function (self, player, other_players) + + --primeiro preenche a nossa barra + local spells_sorted = {} + for spellid, spelltable in _pairs (player.spell_tables._ActorTable) do + spells_sorted [#spells_sorted+1] = {spelltable, spelltable.total} + end + table.sort (spells_sorted, function (t1, t2) return t1[2] > t2[2] end) + + self.player = player:Name() + + local offset = FauxScrollFrame_GetOffset (self) + + local total = player.total_without_pet + local top = spells_sorted [1] [2] + + local frame2 = DetailsPlayerComparisonBox2 + frame2.player = other_players [1]:Name() + local player_2_total = other_players [1].total_without_pet + local player_2_spells_sorted = {} + for spellid, spelltable in _pairs (other_players [1].spell_tables._ActorTable) do + player_2_spells_sorted [#player_2_spells_sorted+1] = {spelltable, spelltable.total} + end + table.sort (player_2_spells_sorted, function (t1, t2) return t1[2] > t2[2] end) + local player_2_top = player_2_spells_sorted [1] [2] + local player_2_spell_info = {} + for index, spelltable in _ipairs (player_2_spells_sorted) do + player_2_spell_info [spelltable[1].id] = index + end + + local frame3 = DetailsPlayerComparisonBox3 + frame3.player = other_players [2] and other_players [2]:Name() + local player_3_total = other_players [2] and other_players [2].total_without_pet + local player_3_spells_sorted = {} + local player_3_spell_info = {} + local player_3_top + + if (other_players [2]) then + for spellid, spelltable in _pairs (other_players [2].spell_tables._ActorTable) do + player_3_spells_sorted [#player_3_spells_sorted+1] = {spelltable, spelltable.total} + end + table.sort (player_3_spells_sorted, function (t1, t2) return t1[2] > t2[2] end) + player_3_top = player_3_spells_sorted [1] [2] + for index, spelltable in _ipairs (player_3_spells_sorted) do + player_3_spell_info [spelltable[1].id] = index + end + end + + for i = 1, 9 do + local bar = self.bars [i] + local index = i + offset + + local data = spells_sorted [index] + + if (data) then + --seta no box principal + local spellid = data [1].id + local name, _, icon = _GetSpellInfo (spellid) + bar [1]:SetTexture (icon) + bar [2].lefttext:SetText (index .. ". " .. name) + bar [2].lefttext:SetTextColor (1, 1, 1, 1) + bar [2].righttext:SetText (_detalhes:ToK2Min (data [2])) -- .. " (" .. _math_floor (data [2] / total * 100) .. "%)" + bar [2]:SetValue (data [2] / top * 100) + bar [3][1] = data [1].counter --tooltip hits + bar [3][2] = data [2] / data [1].counter --tooltip average + bar [3][3] = _math_floor (data [1].c_amt / data [1].counter * 100) --tooltip critical + bar [3][4] = spellid + + --seta no segundo box + local player_2 = other_players [1] + local spell = player_2.spell_tables._ActorTable [spellid] + local bar_2 = frame2.bars [i] + + if (spell) then + bar_2 [1]:SetTexture (icon) + bar_2 [2].lefttext:SetText (player_2_spell_info [spellid] .. ". " .. name) + bar_2 [2].lefttext:SetTextColor (1, 1, 1, 1) + if (data [2] > spell.total) then + local diff = data [2] - spell.total + local up = diff / data [2] * 100 + bar_2 [2].righttext:SetText (_detalhes:ToK2Min (spell.total) .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = spell.total - data [2] + local down = diff / spell.total * 100 + bar_2 [2].righttext:SetText (_detalhes:ToK2Min (spell.total) .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + bar_2 [2]:SetValue (spell.total / player_2_top * 100) + bar_2 [3][1] = spell.counter --tooltip hits + bar_2 [3][2] = spell.total / spell.counter --tooltip average + bar_2 [3][3] = _math_floor (spell.c_amt / spell.counter * 100) --tooltip critical + else + bar_2 [1]:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) + bar_2 [2].lefttext:SetText ("-- x -- x --") + bar_2 [2].lefttext:SetTextColor (.5, .5, .5, 1) + bar_2 [2].righttext:SetText ("") + bar_2 [2]:SetValue (0) + end + + --seta o terceiro box + local bar_3 = frame3.bars [i] + + if (player_3_total) then + local player_3 = other_players [2] + local spell = player_3.spell_tables._ActorTable [spellid] + + if (spell) then + bar_3 [1]:SetTexture (icon) + bar_3 [2].lefttext:SetText (player_3_spell_info [spellid] .. ". " .. name) + bar_3 [2].lefttext:SetTextColor (1, 1, 1, 1) + if (data [2] > spell.total) then + local diff = data [2] - spell.total + local up = diff / data [2] * 100 + bar_3 [2].righttext:SetText (_detalhes:ToK2Min (spell.total) .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = spell.total - data [2] + local down = diff / spell.total * 100 + bar_3 [2].righttext:SetText (_detalhes:ToK2Min (spell.total) .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + bar_3 [2]:SetValue (spell.total / player_2_top * 100) + bar_3 [3][1] = spell.counter --tooltip hits + bar_3 [3][2] = spell.total / spell.counter --tooltip average + bar_3 [3][3] = _math_floor (spell.c_amt / spell.counter * 100) --tooltip critical + else + bar_3 [1]:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) + bar_3 [2].lefttext:SetText ("-- x -- x --") + bar_3 [2].lefttext:SetTextColor (.5, .5, .5, 1) + bar_3 [2].righttext:SetText ("") + bar_3 [2]:SetValue (0) + end + else + bar_3 [1]:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) + bar_3 [2].lefttext:SetText ("-- x -- x --") + bar_3 [2].lefttext:SetTextColor (.5, .5, .5, 1) + bar_3 [2].righttext:SetText ("") + bar_3 [2]:SetValue (0) + end + else + bar [1]:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) + bar [2].lefttext:SetText ("-- x -- x --") + bar [2].lefttext:SetTextColor (.5, .5, .5, 1) + bar [2].righttext:SetText ("") + bar [2]:SetValue (0) + local bar_2 = frame2.bars [i] + bar_2 [1]:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) + bar_2 [2].lefttext:SetText ("-- x -- x --") + bar_2 [2].lefttext:SetTextColor (.5, .5, .5, 1) + bar_2 [2].righttext:SetText ("") + bar_2 [2]:SetValue (0) + local bar_3 = frame3.bars [i] + bar_3 [1]:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) + bar_3 [2].lefttext:SetText ("-- x -- x --") + bar_3 [2].lefttext:SetTextColor (.5, .5, .5, 1) + bar_3 [2].righttext:SetText ("") + bar_3 [2]:SetValue (0) + end + + end + + for index, spelltable in _ipairs (spells_sorted) do + + end + + end + + local refresh_comparison_box = function (self) + + --atualiza a scroll + FauxScrollFrame_Update (self, math.max (self.tab.spells_amt, 10), 9, 15) + fill_compare_actors (self, self.tab.player, self.tab.players) + + end + + local refresh_target_box = function (self) + + end + + + + local compare_fill = function (tab, player, combat) + local players_to_compare = tab.players + + DetailsPlayerComparisonBox1.name_label:SetText (player:Name()) + + local label2 = _G ["DetailsPlayerComparisonBox2"].name_label + local label3 = _G ["DetailsPlayerComparisonBox3"].name_label + + if (players_to_compare [1]) then + label2:SetText (players_to_compare [1]:Name()) + end + if (players_to_compare [2]) then + label3:SetText (players_to_compare [2]:Name()) + else + label3:SetText ("Player 3") + end + + refresh_comparison_box (DetailsPlayerComparisonBox1) + end + + local on_enter = function (self) + + local frame1 = DetailsPlayerComparisonBox1 + local frame2 = DetailsPlayerComparisonBox2 + local frame3 = DetailsPlayerComparisonBox3 + + local bar1 = frame1.bars [self.index] + local bar2 = frame2.bars [self.index] + local bar3 = frame3.bars [self.index] + + frame1.tooltip:SetPoint ("bottomleft", bar1[2], "topleft", -18, 5) + frame2.tooltip:SetPoint ("bottomleft", bar2[2], "topleft", -18, 5) + frame3.tooltip:SetPoint ("bottomleft", bar3[2], "topleft", -18, 5) + + local spellid = bar1[3][4] + local player1 = frame1.player + local player2 = frame2.player + local player3 = frame3.player + + local hits = bar1[3][1] + local average = bar1[3][2] + local critical = bar1[3][3] + + local player1_misc = info.instancia.showing (4, player1) + local player2_misc = info.instancia.showing (4, player2) + local player3_misc = info.instancia.showing (4, player3) + local player1_uptime + + if (bar1[2].righttext:GetText()) then + bar1[2]:SetStatusBarColor (1, 1, 1, 1) + bar1[2].icon:SetTexCoord (.1, .9, .1, .9) + frame1.tooltip.hits_label2:SetText (hits) + frame1.tooltip.average_label2:SetText (_detalhes:ToK2Min (average)) + frame1.tooltip.crit_label2:SetText (critical .. "%") + + if (player1_misc) then + local spell = player1_misc.debuff_uptime_spell_tables and player1_misc.debuff_uptime_spell_tables._ActorTable and player1_misc.debuff_uptime_spell_tables._ActorTable [spellid] + if (spell) then + local minutos, segundos = _math_floor (spell.uptime/60), _math_floor (spell.uptime%60) + player1_uptime = spell.uptime + frame1.tooltip.uptime_label2:SetText (minutos .. "m" .. segundos .. "s") + else + frame1.tooltip.uptime_label2:SetText ("--x--x--") + end + else + frame1.tooltip.uptime_label2:SetText ("--x--x--") + end + + frame1.tooltip:Show() + end + + if (bar2[2].righttext:GetText()) then + + bar2[2]:SetStatusBarColor (1, 1, 1, 1) + bar2[2].icon:SetTexCoord (.1, .9, .1, .9) + + if (hits > bar2[3][1]) then + local diff = hits - bar2[3][1] + local up = diff / hits * 100 + frame2.tooltip.hits_label2:SetText (bar2[3][1] .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = bar2[3][1] - hits + local down = diff / bar2[3][1] * 100 + frame2.tooltip.hits_label2:SetText (bar2[3][1] .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + + if (average > bar2[3][2]) then + local diff = average - bar2[3][2] + local up = diff / average * 100 + frame2.tooltip.average_label2:SetText (_detalhes:ToK2Min (bar2[3][2]) .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = bar2[3][2] - average + local down = diff / bar2[3][2] * 100 + frame2.tooltip.average_label2:SetText (_detalhes:ToK2Min (bar2[3][2]) .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + + if (critical > bar2[3][3]) then + local diff = critical - bar2[3][3] + local up = diff / critical * 100 + frame2.tooltip.crit_label2:SetText (bar2[3][3] .. "%" .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = bar2[3][3] - critical + local down = diff / bar2[3][3] * 100 + frame2.tooltip.crit_label2:SetText (bar2[3][3] .. "%" .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + + if (player2_misc) then + local spell = player2_misc.debuff_uptime_spell_tables and player2_misc.debuff_uptime_spell_tables._ActorTable and player2_misc.debuff_uptime_spell_tables._ActorTable [spellid] + if (spell) then + local minutos, segundos = _math_floor (spell.uptime/60), _math_floor (spell.uptime%60) + if (player1_uptime > spell.uptime) then + local diff = player1_uptime - spell.uptime + local up = diff / player1_uptime * 100 + frame2.tooltip.uptime_label2:SetText (minutos .. "m" .. segundos .. "s |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = spell.uptime - player1_uptime + local down = diff / spell.uptime * 100 + frame2.tooltip.uptime_label2:SetText (minutos .. "m" .. segundos .. "s |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + else + frame2.tooltip.uptime_label2:SetText ("--x--x--") + end + else + frame2.tooltip.uptime_label2:SetText ("--x--x--") + end + + frame2.tooltip:Show() + end + + if (bar3[2].righttext:GetText()) then + bar3[2]:SetStatusBarColor (1, 1, 1, 1) + bar3[2].icon:SetTexCoord (.1, .9, .1, .9) + + if (hits > bar3[3][1]) then + local diff = hits - bar3[3][1] + local up = diff / hits * 100 + frame3.tooltip.hits_label2:SetText (bar3[3][1] .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = bar3[3][1] - hits + local down = diff / bar3[3][1] * 100 + frame3.tooltip.hits_label2:SetText (bar3[3][1] .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + + if (average > bar3[3][2]) then + local diff = average - bar3[3][2] + local up = diff / average * 100 + frame3.tooltip.average_label2:SetText (_detalhes:ToK2Min (bar3[3][2]) .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = bar3[3][2] - average + local down = diff / bar3[3][2] * 100 + frame3.tooltip.average_label2:SetText (_detalhes:ToK2Min (bar3[3][2]) .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + + if (critical > bar3[3][3]) then + local diff = critical - bar3[3][3] + local up = diff / critical * 100 + frame3.tooltip.crit_label2:SetText (bar3[3][3] .. "%" .. " |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = bar3[3][3] - critical + local down = diff / bar3[3][3] * 100 + frame3.tooltip.crit_label2:SetText (bar3[3][3] .. "%" .. " |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + + if (player3_misc) then + local spell = player3_misc.debuff_uptime_spell_tables and player3_misc.debuff_uptime_spell_tables._ActorTable and player3_misc.debuff_uptime_spell_tables._ActorTable [spellid] + if (spell) then + local minutos, segundos = _math_floor (spell.uptime/60), _math_floor (spell.uptime%60) + if (player1_uptime > spell.uptime) then + local diff = player1_uptime - spell.uptime + local up = diff / player1_uptime * 100 + frame3.tooltip.uptime_label2:SetText (minutos .. "m" .. segundos .. "s |cFFFF0000-(" .. _math_floor (up) .. "%)|r") + else + local diff = spell.uptime - player1_uptime + local down = diff / spell.uptime * 100 + frame3.tooltip.uptime_label2:SetText (minutos .. "m" .. segundos .. "s |cFF00FF00+(" .. _math_floor (down) .. "%)|r") + end + else + frame3.tooltip.uptime_label2:SetText ("--x--x--") + end + else + frame3.tooltip.uptime_label2:SetText ("--x--x--") + end + + frame3.tooltip:Show() + end + end + + local on_leave = function (self) + local frame1 = DetailsPlayerComparisonBox1 + local frame2 = DetailsPlayerComparisonBox2 + local frame3 = DetailsPlayerComparisonBox3 + + local bar1 = frame1.bars [self.index] + local bar2 = frame2.bars [self.index] + local bar3 = frame3.bars [self.index] + + bar1[2]:SetStatusBarColor (.5, .5, .5, 1) + bar1[2].icon:SetTexCoord (0, 1, 0, 1) + bar2[2]:SetStatusBarColor (.5, .5, .5, 1) + bar2[2].icon:SetTexCoord (0, 1, 0, 1) + bar3[2]:SetStatusBarColor (.5, .5, .5, 1) + bar3[2].icon:SetTexCoord (0, 1, 0, 1) + + frame1.tooltip:Hide() + frame2.tooltip:Hide() + frame3.tooltip:Hide() + end + + local compare_create = function (tab, frame) + + local create_bar = function (name, parent, index, main) + local y = ((index-1) * -15) - 7 + + local spellicon = parent:CreateTexture (nil, "overlay") + spellicon:SetSize (14, 14) + spellicon:SetPoint ("topleft", parent, "topleft", 4, y) + spellicon:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) + + local bar = CreateFrame ("StatusBar", name, parent) + bar.index = index + bar:SetPoint ("topleft", spellicon, "topright", 0, 0) + bar:SetPoint ("topright", parent, "topright", -4, y) + bar:SetStatusBarTexture (_detalhes.default_texture) + bar:SetStatusBarColor (.5, .5, .5, 1) + bar:SetMinMaxValues (0, 100) + bar:SetValue (100) + bar:SetHeight (14) + bar.icon = spellicon + + bar:SetScript ("OnEnter", on_enter) + bar:SetScript ("OnLeave", on_leave) + + bar.lefttext = bar:CreateFontString (nil, "OVERLAY", "GameFontHighlightSmall") + + local _, size, flags = bar.lefttext:GetFont() + local font = SharedMedia:Fetch ("font", "Arial Narrow") + bar.lefttext:SetFont (font, 11, "outline") + + bar.lefttext:SetPoint ("left", bar, "left", 2, 0) + bar.lefttext:SetJustifyH ("left") + bar.lefttext:SetTextColor (1, 1, 1, 1) + bar.lefttext:SetNonSpaceWrap (true) + bar.lefttext:SetWordWrap (false) + if (main) then + bar.lefttext:SetWidth (110) + else + bar.lefttext:SetWidth (70) + end + + bar.righttext = bar:CreateFontString (nil, "OVERLAY", "GameFontHighlightSmall") + bar.righttext:SetPoint ("right", bar, "right", -2, 0) + bar.righttext:SetJustifyH ("right") + bar.righttext:SetTextColor (1, 1, 1, 1) + + tinsert (parent.bars, {spellicon, bar, {0, 0, 0}}) + end + + local create_tooltip = function (name) + local tooltip = CreateFrame ("frame", name, UIParent) + tooltip:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], tile = true, tileSize = 16, edgeSize = 12, insets = {left = 1, right = 1, top = 1, bottom = 1},}) + tooltip:SetBackdropColor (0, 0, 0, 1) + tooltip:SetSize (175, 67) + tooltip:SetFrameStrata ("tooltip") + + local background = tooltip:CreateTexture (nil, "artwork") + background:SetTexture ([[Interface\SPELLBOOK\Spellbook-Page-1]]) + background:SetTexCoord (.6, 0.1, 0, 0.64453125) + background:SetVertexColor (1, 1, 1, 0.2) + background:SetPoint ("topleft", tooltip, "topleft", 2, -4) + background:SetPoint ("bottomright", tooltip, "bottomright", -4, 2) + + tooltip.hits_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.hits_label:SetPoint ("topleft", tooltip, "topleft", 10, -10) + tooltip.hits_label:SetText ("Total Hits:") + tooltip.hits_label:SetJustifyH ("left") + tooltip.hits_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.hits_label2:SetPoint ("topright", tooltip, "topright", -10, -10) + tooltip.hits_label2:SetText ("0") + tooltip.hits_label2:SetJustifyH ("right") + + tooltip.average_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.average_label:SetPoint ("topleft", tooltip, "topleft", 10, -22) + tooltip.average_label:SetText ("Average:") + tooltip.average_label:SetJustifyH ("left") + tooltip.average_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.average_label2:SetPoint ("topright", tooltip, "topright", -10, -22) + tooltip.average_label2:SetText ("0") + tooltip.average_label2:SetJustifyH ("right") + + tooltip.crit_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.crit_label:SetPoint ("topleft", tooltip, "topleft", 10, -34) + tooltip.crit_label:SetText ("Critical:") + tooltip.crit_label:SetJustifyH ("left") + tooltip.crit_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.crit_label2:SetPoint ("topright", tooltip, "topright", -10, -34) + tooltip.crit_label2:SetText ("0") + tooltip.crit_label2:SetJustifyH ("right") + + tooltip.uptime_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.uptime_label:SetPoint ("topleft", tooltip, "topleft", 10, -46) + tooltip.uptime_label:SetText ("Uptime:") + tooltip.uptime_label:SetJustifyH ("left") + tooltip.uptime_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.uptime_label2:SetPoint ("topright", tooltip, "topright", -10, -46) + tooltip.uptime_label2:SetText ("0") + tooltip.uptime_label2:SetJustifyH ("right") + + return tooltip + end + + local frame1 = CreateFrame ("scrollframe", "DetailsPlayerComparisonBox1", frame, "FauxScrollFrameTemplate") + frame1:SetScript ("OnVerticalScroll", function (self, offset) FauxScrollFrame_OnVerticalScroll (self, offset, 14, refresh_comparison_box) end) + frame1:SetSize (175, 150) + frame1:SetPoint ("topleft", frame, "topleft", 10, -30) + frame1:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left = 1, right = 1, top = 0, bottom = 1},}) + frame1:SetBackdropColor (0, 0, 0, .7) + frame1.bars = {} + frame1.tab = tab + frame1.tooltip = create_tooltip ("DetailsPlayerComparisonBox1Tooltip") + + local playername1 = frame1:CreateFontString (nil, "overlay", "GameFontNormal") + playername1:SetPoint ("bottomleft", frame1, "topleft", 2, 0) + playername1:SetText ("Player 1") + frame1.name_label = playername1 + + --criar as barras do frame1 + for i = 1, 9 do + create_bar ("DetailsPlayerComparisonBox1Bar"..i, frame1, i, true) + end + + + + --cria o box dos targets + local target1 = CreateFrame ("scrollframe", "DetailsPlayerComparisonTarget1", frame, "FauxScrollFrameTemplate") + target1:SetScript ("OnVerticalScroll", function (self, offset) FauxScrollFrame_OnVerticalScroll (self, offset, 14, refresh_target_box) end) + target1:SetSize (175, 70) + target1:SetPoint ("topleft", frame1, "bottomleft", 0, -10) + target1:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left = 1, right = 1, top = 0, bottom = 1},}) + target1:SetBackdropColor (0, 0, 0, .7) + target1.bars = {} + target1.tab = tab + + --criar as barras do target1 + for i = 1, 4 do + create_bar ("DetailsPlayerComparisonTarget1Bar"..i, target1, i, true) + end + +-------------------------------------------- + local frame2 = CreateFrame ("frame", "DetailsPlayerComparisonBox2", frame) + local frame3 = CreateFrame ("frame", "DetailsPlayerComparisonBox3", frame) + + frame2:SetPoint ("topleft", frame1, "topright", 25, 0) + frame2:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left = 1, right = 1, top = 0, bottom = 1},}) + frame2:SetSize (170, 150) + frame2:SetBackdropColor (0, 0, 0, .7) + frame2.bars = {} + frame2.tooltip = create_tooltip ("DetailsPlayerComparisonBox2Tooltip") + + local playername2 = frame2:CreateFontString (nil, "overlay", "GameFontNormal") + playername2:SetPoint ("bottomleft", frame2, "topleft", 2, 0) + playername2:SetText ("Player 2") + frame2.name_label = playername2 + + --criar as barras do frame2 + for i = 1, 9 do + create_bar ("DetailsPlayerComparisonBox2Bar"..i, frame2, i) + end + + --cria o box dos targets + local target2 = CreateFrame ("frame", "DetailsPlayerComparisonTarget2", frame) + target2:SetSize (170, 70) + target2:SetPoint ("topleft", frame2, "bottomleft", 0, -10) + target2:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left = 1, right = 1, top = 0, bottom = 1},}) + target2:SetBackdropColor (0, 0, 0, .7) + target2.bars = {} + + --criar as barras do target2 + for i = 1, 4 do + create_bar ("DetailsPlayerComparisonTarget2Bar"..i, target2, i) + end + + frame3:SetPoint ("topleft", frame2, "topright", 5, 0) + frame3:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left = 1, right = 1, top = 0, bottom = 1},}) + frame3:SetSize (170, 150) + frame3:SetBackdropColor (0, 0, 0, .7) + frame3.bars = {} + frame3.tooltip = create_tooltip ("DetailsPlayerComparisonBox3Tooltip") + + local playername3 = frame3:CreateFontString (nil, "overlay", "GameFontNormal") + playername3:SetPoint ("bottomleft", frame3, "topleft", 2, 0) + playername3:SetText ("Player 3") + frame3.name_label = playername3 + + --criar as barras do frame3 + for i = 1, 9 do + create_bar ("DetailsPlayerComparisonBox3Bar"..i, frame3, i) + end + + --cria o box dos targets + local target3 = CreateFrame ("frame", "DetailsPlayerComparisonTarget3", frame) + target3:SetSize (170, 70) + target3:SetPoint ("topleft", frame3, "bottomleft", 0, -10) + target3:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left = 1, right = 1, top = 0, bottom = 1},}) + target3:SetBackdropColor (0, 0, 0, .7) + target3.bars = {} + + --criar as barras do target1 + for i = 1, 4 do + create_bar ("DetailsPlayerComparisonTarget3Bar"..i, target3, i) + end + end + + -- ~compare + _detalhes:CreatePlayerDetailsTab ("Compare", --[1] tab name + function (tabOBject, playerObject) --[2] condition + + local same_class = {} + local class = playerObject.classe + local my_spells = {} + local my_spells_total = 0 + --> build my spell list + for spellid, _ in _pairs (playerObject.spell_tables._ActorTable) do + my_spells [spellid] = true + my_spells_total = my_spells_total + 1 + end + + tabOBject.players = {} + tabOBject.player = playerObject + tabOBject.spells_amt = my_spells_total + + for index, actor in _ipairs (info.instancia.showing [info.atributo]._ActorTable) do + if (actor.classe == class and actor ~= playerObject) then + + local same_spells = 0 + for spellid, _ in _pairs (actor.spell_tables._ActorTable) do + if (my_spells [spellid]) then + same_spells = same_spells + 1 + end + end + + local match_percentage = same_spells / my_spells_total * 100 + + if (match_percentage > 30) then + tinsert (tabOBject.players, actor) + end + end + end + + if (#tabOBject.players > 0) then + return true + end + + return false + --return true + end, + + compare_fill, --[3] fill function + + nil, --[4] onclick + + compare_create --[5] oncreate + ) + function este_gump:ShowTabs() local amt_positive = 0 diff --git a/gumps/janela_news.lua b/gumps/janela_news.lua index 07d3f850..d53a6167 100644 --- a/gumps/janela_news.lua +++ b/gumps/janela_news.lua @@ -42,7 +42,7 @@ function _detalhes:CreateOrOpenNewsWindow() local frame_upper = CreateFrame ("scrollframe", nil, frame) local frame_lower = CreateFrame ("frame", nil, frame_upper) - frame_lower:SetSize (450, 390) + frame_lower:SetSize (450, 2000) frame_upper:SetPoint ("topleft", frame, "topleft", 15, -70) frame_upper:SetWidth (465) frame_upper:SetHeight (400) @@ -66,7 +66,7 @@ function _detalhes:CreateOrOpenNewsWindow() slider:SetOrientation ("vertical"); slider:SetSize (16, 399) slider:SetPoint ("topleft", frame_upper, "topright") - slider:SetMinMaxValues (0, 1000) + slider:SetMinMaxValues (0, 2000) slider:SetValue(0) slider:SetScript("OnValueChanged", function (self) frame_upper:SetVerticalScroll (self:GetValue()) @@ -78,8 +78,8 @@ function _detalhes:CreateOrOpenNewsWindow() if (IsShiftKeyDown() and (delta > 0)) then slider:SetValue(0) elseif (IsShiftKeyDown() and (delta < 0)) then - slider:SetValue (1000) - elseif ((delta < 0) and (current < 1000)) then + slider:SetValue (2000) + elseif ((delta < 0) and (current < 2000)) then slider:SetValue (current + 20) elseif ((delta > 0) and (current > 1)) then slider:SetValue (current - 20) @@ -93,7 +93,7 @@ function _detalhes:CreateOrOpenNewsWindow() texto:SetJustifyV ("top") texto:SetTextColor (1, 1, 1) texto:SetWidth (450) - texto:SetHeight (1400) + texto:SetHeight (2500) -- /script _detalhes.OpenNewsWindow() --> forum text local forum_button = CreateFrame ("Button", "DetailsNewsWindowForumButton", frame, "OptionsButtonTemplate") diff --git a/gumps/janela_principal.lua b/gumps/janela_principal.lua index 7ea55a35..93a0d4ce 100644 --- a/gumps/janela_principal.lua +++ b/gumps/janela_principal.lua @@ -1932,6 +1932,7 @@ function CreateAlertFrame (baseframe, instancia) frame_upper:SetPoint ("left", baseframe, "left", 3, 0) frame_upper:SetPoint ("right", baseframe, "right", -3, 0) frame_upper:SetHeight (13) + frame_upper:SetFrameStrata ("fullscreen") local frame_lower = CreateFrame ("frame", "DetailsAlertFrameScrollChild" .. instancia.meu_id, frame_upper) frame_lower:SetHeight (25) @@ -2759,11 +2760,9 @@ function gump:CriaNovaBarra (instancia, index) instancia:SetFontSize (esta_barra.texto_esquerdo, instancia.row_info.font_size) instancia:SetFontFace (esta_barra.texto_esquerdo, instancia.row_info.font_face_file) - --_detalhes.font_pool:add (esta_barra.texto_esquerdo) instancia:SetFontSize (esta_barra.texto_direita, instancia.row_info.font_size) instancia:SetFontFace (esta_barra.texto_direita, instancia.row_info.font_face_file) - --_detalhes.font_pool:add (esta_barra.texto_direita) if (instancia.row_info.textL_outline) then instancia:SetFontOutline (esta_barra.texto_esquerdo, instancia.row_info.textL_outline) @@ -3267,6 +3266,10 @@ function _detalhes:SetWindowAlphaForCombat (entering_in_combat, true_hide) amount = self.hide_in_combat_alpha / 100 self.combat_changes_alpha = amount rowsamount = amount + if (_detalhes.pet_battle) then + amount = 0 + rowsamount = 0 + end else if (self.menu_alpha.enabled) then --auto transparency if (self.is_interacting) then diff --git a/images/custom_bg.tga b/images/custom_bg.tga index 4001e2d1b36cae4457d27f95d51bc527811f5bbd..c5db4a74a09d3db6a42ea0048da76cdfe66f315a 100644 GIT binary patch literal 248798 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

8#^JLaBdE|YSDfCh@g+7~9o+px;{*S)-&Gkzk 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

D_Q1 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 HKQ8+JDF0eH literal 190846 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 rhgCd color and details name @@ -130,14 +130,21 @@ if not Loc then return end Loc ["STRING_CUSTOM_REMOVE"] = "Remove" Loc ["STRING_CUSTOM_BROADCAST"] = "Shout" - Loc ["STRING_CUSTOM_NAME"] = "Custom Name" - Loc ["STRING_CUSTOM_SPELLID"] = "Spell Id" - Loc ["STRING_CUSTOM_SOURCE"] = "Source" - Loc ["STRING_CUSTOM_TARGET"] = "Target" + Loc ["STRING_CUSTOM_NAME"] = "Name:" + Loc ["STRING_CUSTOM_SPELLID"] = "Spell Id:" + Loc ["STRING_CUSTOM_SOURCE"] = "Source:" + Loc ["STRING_CUSTOM_TARGET"] = "Target:" + Loc ["STRING_CUSTOM_ATTRIBUTE"] = "Attribute:" + + Loc ["STRING_CUSTOM_ATT1"] = "Damage" + Loc ["STRING_CUSTOM_ATT2"] = "Heal" + Loc ["STRING_CUSTOM_ATT3"] = "Energy" + Loc ["STRING_CUSTOM_ATT4"] = "Misc" + Loc ["STRING_CUSTOM_TOOLTIPNAME"] = "Insert here the name of your custom display.\nAllow letters and numbers, minimum of 5 characters and 32 max." Loc ["STRING_CUSTOM_TOOLTIPSPELL"] = "Select a boss ability from the menu on the right\nor type the spell name to filter." - Loc ["STRING_CUSTOM_TOOLTIPSOURCE"] = "Spell source allow (with brackets):\n|cFF00FF00[all]|r: Search for spell in all Actors.\n|cFFFF9900[raid]|r: Search only in your raid or party members.\n|cFF33CCFF[player]|r: Check only you\nAny other text will be considered an spesific Actor name." - Loc ["STRING_CUSTOM_TOOLTIPTARGET"] = "Insert the ability (player, monster, boss) target name." + Loc ["STRING_CUSTOM_TOOLTIPSOURCE"] = "Source is who is triggering the attribute chosen.\nIt allows (maintain the brackets):\n\n|cFF00FF00[all]|r: search for matches in all characters.\n|cFFFFFF00[raid]|r: search only in your raid or party members.\n|cFF33CCFF[player]|r: only you are checked during the search for results.\n\nAny other text is considered an spesific character." + Loc ["STRING_CUSTOM_TOOLTIPTARGET"] = "Source target." Loc ["STRING_CUSTOM_TOOLTIPNOTWORKING"] = "Ouch, some gnome engineer touched this and broke it =(" Loc ["STRING_CUSTOM_BROADCASTSENT"] = "Sent" Loc ["STRING_CUSTOM_CREATED"] = "The new display has been created." diff --git a/locales/Details-ptBR.lua b/locales/Details-ptBR.lua index 1eb7b25e..59029cc3 100644 --- a/locales/Details-ptBR.lua +++ b/locales/Details-ptBR.lua @@ -3,7 +3,7 @@ if not Loc then return end -------------------------------------------------------------------------------------------------------------------------------------------- - Loc ["STRING_VERSION_LOG"] = "|cFFFFFF00v1.15.0 - v1.15.3|r:\n\n|cFFFFFF00-|r Damage -> Enemies now also show neutral creatures.\n\n|cFFFFFF00-|r Added support to dungeons, bosses and trash mobs are now recognized.\n\n|cFFFFFF00-|r Added target information for each spell in Player Detail Window.\n\n|cFFFFFF00-|r Added options for change the location of tooltips.\n\n|cFFFFFF00-|r Added options for change the Overall Data functionality.\n\n|cFFFFFF00-|r Added tooltips for lock and detach buttons.\n\n|cFFFFFF00-|r Added new row texture: Details Vidro.\n\n|cFFFFFF00-|r Revamp on death log tooltips.\n\n|cFFFFFF00-|r Improved the visual effect for the instance which current moving window can snap to.\n\n|cFFFFFF00v1.15.0: (test version) Dungeons e Overall data.\n\n|cFFFFFF00-|r Implemented a early support for Dungeons.\n\n|cFFFFFF00-|r Implemented Overall Data. Options for it are under combat tab.\n\n|cFFFFFF00-|r Implemented spell targets on Player Details Window.\n\n|cFFFFFF00v1.14.5 - 1.14.6\n\n|cFFFFFF00-|r Added option for lock segments display, so, when a segment is chosen, the other windows also change it.\n\n|cFFFFFF00-|r Added option for show the total amount of spells, targets and pets in tooltips.\n\n|cFFFFFF00-|r Finished another revamp on options panel.\n\n|cFFFFFF00-|r Now its possible open more then 1 Raid Plugins at once on diferent windows.\n\n|cFFFFFF00-|r Added a large text editor for make changes on custom texts.\n\n|cFFFFFF00-|r Added new option for enable borders on the bars.\n\n|cFFFFFF00-|r Added Death Barrier as a absorb spell.\n\n|cFFFFFF00-|r Fixed a bug on overheal tooltip where was showing the Hps instead of overheal.\n\n|cFFFFFF00v1.14.0 - v1.14.0b - v1.14.1\n\n|cFFFFFF00-|r Emergencial fix for crash after creating test bars and logoff.\n\n|cFFFFFF00-|r Fixed the default background alpha on default skin.\n\n|cFFFFFF00-|r Added spacing option under row settings for control the gap between bars.\n\n|cFFFFFF00-|r Added a new tab on options panel for tooltip configuration.\n\n|cFFFFFF00-|r Added a new tab on options panel for broker config.\n\n|cFFFFFF00-|r Added new abbreviation method called comma.\n\n|cFFFFFF00-|r All instances now have a delete button.\n\n|cFFFFFF00-|r Full re-write on the instance, delete and close buttons.\n\n|cFFFFFF00-|r HotCorners now sort icons according with most used.\n\n|cFFFFFF00-|r Few changes on all skins in order to fit on the new right menu buttons.\n\n|cFFFFFF00-|r Added Horde avatars.\n\n|cFFFFFF00-|r Fixed issue where shortcut panel shows below thw windows when its in Dialog strata.\n\n|cFFFFFF00v1.13.8 - v1.13.8a\n\n|cFFFFFF00-|r Fixed issue with Vanguard where it wasn't showing debuffs stacks on the tanks if you are a healer os dps.\n\n|cFFFFFF00-|r Added option for put stretch button on the fullscreen strata which makes it always on top of others frames.\n\n|cFFFFFF00-|r Added background and dialog stratas.\n\n|cFFFFFF00-|r Added option for percentage: follow the combat totals or the first player total.\n\n|cFFFFFF00-|r Added option for show or hide the left buttons on menu bar.\n\n|cFFFFFF00-|r Added option for change the left buttons size in the menu bar.\n\n|cFFFFFF00-|r Added option for delete a instance.\n\n|cFFFFFF00-|r Instance Segment Mini display now is more accuracy about telling the enemy in the segment.\n\n|cFFFFFF00-|r Player Details Window now show all pet abilities instead of just the total pet damage.\n\n|cFFFFFF00-|r Rework done on report texts, now the title is more shorter and also format Dps and Hps numbers.\n\n|cFFFFFF00-|r Simple Gray and again ElvUI skins got some rework.\n\n|cFFFFFF00-|r Lib HotCorner now is data broker based and shows up all broker plugins in the bar.\n\n|cFFFFFF00v1.13.5 / v1.13.5a|r\n\n|cFFFFFF00-|r Added keybinds to reset segments and scroll up/down.\n\n|cFFFFFF00-|r Added Spell Customization options where icon and the name of a spell can be changed.\n\n|cFFFFFF00-|r Added option to change the micro displays side, now it can be shown on the window top side.\n\n|cFFFFFF00-|r Micro Displays, also, should now give less problems and be more dynamic.\n\n|cFFFFFF00-|r Added Spell Customization options where icon and the name of a spell can be changed.\n\n|cFFFFFF00-|r Added option to change the micro displays side, now it can be shown on the window top side.\n\n|cFFFFFF00-|r Added options to change the transparency when out of combat and out of a group.\n\n|cFFFFFF00-|r Added and Still under development the panel for create data captures for charts.\n\n|cFFFFFF00-|r Fixed a issue with flat skin where the close button was just too big.\n\n|cFFFFFF00v1.13.0|r\n\n|cFFFFFF00-|r Added four more abbreviation types.\n\n|cFFFFFF00-|r Fixed issue where the instance menu wasnt respecting the amount limit of instances.\n\n|cFFFFFF00-|r Added options for cutomize the right text of a row.\n\n|cFFFFFF00-|r Added a option to be able to chance the framestrata of an window.\n\n|cFFFFFF00-|r Added shift, ctrl, alt interaction for rows which shows all spells, targets or pets when pressed.\n\n|cFFFFFF00-|r Fixed a issue where changing the alpha of a window makes it disappear on the next logon.\n\n|cFFFFFF00-|r Added a option for auto transparency to ignore rows.\n\n|cFFFFFF00-|r Added option to be able to set shadow on the attribute text.\n\n|cFFFFFF00-|r Fixed a issue with window snap where disabled statusbar makes a gap between the windows.\n\n|cFFFFFF00-|r Added a hidden menu on the top left corner (experimental).\n\n|cFFFFFF00v1.12.3|r\n\n|cFFFFFF00-|r - Fixed 'Healing Per Second' which wasn't working at all.\n\n|cFFFFFF00-|r - Fixed the percent amount for target of damage done where sometimes it pass 100%.\n\n|cFFFFFF00-|r - Changes on Skins: Minimalistic and Elm UI Frame Style. Its necessary re-apply.\n\n|cFFFFFF00-|r - Added more cooldowns and spells for Monk tank over avoidance panel.\n\n|cFFFFFF00-|r - Player avatar now is also shown on the Player Details window.\n\n|cFFFFFF00-|r - Leaving empty the the icon file box, make details use no icons on bars." + Loc ["STRING_VERSION_LOG"] = "|cFFFFFF00v1.15.0 - v1.15.3 - v1.15.3b|r:\n\n|cFFFFFF00-|r Emergencial fix for death logs which sometimes was breaking the addon data capture.\n\n|cFFFFFF00-|r Fixed window alerts which was showing behind the bars.\n\n|cFFFFFF00-|r Fixed death log issue with friendly fire hits.\n\n|cFFFFFF00-|r Fixed a issue where Details! windows wasn't hidden when a pet battle starts.\n\n|cFFFFFF00-|r Fixed a issue with segments menu when a window is placed on the right side of the screen.\n\n|cFFFFFF00-|r Damage -> Enemies now also show neutral creatures.\n\n|cFFFFFF00-|r Added support to dungeons, bosses and trash mobs are now recognized.\n\n|cFFFFFF00-|r Added target information for each spell in Player Detail Window.\n\n|cFFFFFF00-|r Added options for change the location of tooltips.\n\n|cFFFFFF00-|r Added options for change the Overall Data functionality.\n\n|cFFFFFF00-|r Added tooltips for lock and detach buttons.\n\n|cFFFFFF00-|r Added new row texture: Details Vidro.\n\n|cFFFFFF00-|r Revamp on death log tooltips.\n\n|cFFFFFF00-|r Improved the visual effect for the instance which current moving window can snap to.\n\n|cFFFFFF00v1.15.0: (test version) Dungeons e Overall data.\n\n|cFFFFFF00-|r Implemented a early support for Dungeons.\n\n|cFFFFFF00-|r Implemented Overall Data. Options for it are under combat tab.\n\n|cFFFFFF00-|r Implemented spell targets on Player Details Window.\n\n|cFFFFFF00v1.14.5 - 1.14.6\n\n|cFFFFFF00-|r Added option for lock segments display, so, when a segment is chosen, the other windows also change it.\n\n|cFFFFFF00-|r Added option for show the total amount of spells, targets and pets in tooltips.\n\n|cFFFFFF00-|r Finished another revamp on options panel.\n\n|cFFFFFF00-|r Now its possible open more then 1 Raid Plugins at once on diferent windows.\n\n|cFFFFFF00-|r Added a large text editor for make changes on custom texts.\n\n|cFFFFFF00-|r Added new option for enable borders on the bars.\n\n|cFFFFFF00-|r Added Death Barrier as a absorb spell.\n\n|cFFFFFF00-|r Fixed a bug on overheal tooltip where was showing the Hps instead of overheal.\n\n|cFFFFFF00v1.14.0 - v1.14.0b - v1.14.1\n\n|cFFFFFF00-|r Emergencial fix for crash after creating test bars and logoff.\n\n|cFFFFFF00-|r Fixed the default background alpha on default skin.\n\n|cFFFFFF00-|r Added spacing option under row settings for control the gap between bars.\n\n|cFFFFFF00-|r Added a new tab on options panel for tooltip configuration.\n\n|cFFFFFF00-|r Added a new tab on options panel for broker config.\n\n|cFFFFFF00-|r Added new abbreviation method called comma.\n\n|cFFFFFF00-|r All instances now have a delete button.\n\n|cFFFFFF00-|r Full re-write on the instance, delete and close buttons.\n\n|cFFFFFF00-|r HotCorners now sort icons according with most used.\n\n|cFFFFFF00-|r Few changes on all skins in order to fit on the new right menu buttons.\n\n|cFFFFFF00-|r Added Horde avatars.\n\n|cFFFFFF00-|r Fixed issue where shortcut panel shows below thw windows when its in Dialog strata.\n\n|cFFFFFF00v1.13.8 - v1.13.8a\n\n|cFFFFFF00-|r Fixed issue with Vanguard where it wasn't showing debuffs stacks on the tanks if you are a healer os dps.\n\n|cFFFFFF00-|r Added option for put stretch button on the fullscreen strata which makes it always on top of others frames.\n\n|cFFFFFF00-|r Added background and dialog stratas.\n\n|cFFFFFF00-|r Added option for percentage: follow the combat totals or the first player total.\n\n|cFFFFFF00-|r Added option for show or hide the left buttons on menu bar.\n\n|cFFFFFF00-|r Added option for change the left buttons size in the menu bar.\n\n|cFFFFFF00-|r Added option for delete a instance.\n\n|cFFFFFF00-|r Instance Segment Mini display now is more accuracy about telling the enemy in the segment.\n\n|cFFFFFF00-|r Player Details Window now show all pet abilities instead of just the total pet damage.\n\n|cFFFFFF00-|r Rework done on report texts, now the title is more shorter and also format Dps and Hps numbers.\n\n|cFFFFFF00-|r Simple Gray and again ElvUI skins got some rework.\n\n|cFFFFFF00-|r Lib HotCorner now is data broker based and shows up all broker plugins in the bar.\n\n|cFFFFFF00v1.13.5 / v1.13.5a|r\n\n|cFFFFFF00-|r Added keybinds to reset segments and scroll up/down.\n\n|cFFFFFF00-|r Added Spell Customization options where icon and the name of a spell can be changed.\n\n|cFFFFFF00-|r Added option to change the micro displays side, now it can be shown on the window top side.\n\n|cFFFFFF00-|r Micro Displays, also, should now give less problems and be more dynamic.\n\n|cFFFFFF00-|r Added Spell Customization options where icon and the name of a spell can be changed.\n\n|cFFFFFF00-|r Added option to change the micro displays side, now it can be shown on the window top side.\n\n|cFFFFFF00-|r Added options to change the transparency when out of combat and out of a group.\n\n|cFFFFFF00-|r Added and Still under development the panel for create data captures for charts.\n\n|cFFFFFF00-|r Fixed a issue with flat skin where the close button was just too big.\n\n|cFFFFFF00v1.13.0|r\n\n|cFFFFFF00-|r Added four more abbreviation types.\n\n|cFFFFFF00-|r Fixed issue where the instance menu wasnt respecting the amount limit of instances.\n\n|cFFFFFF00-|r Added options for cutomize the right text of a row.\n\n|cFFFFFF00-|r Added a option to be able to chance the framestrata of an window.\n\n|cFFFFFF00-|r Added shift, ctrl, alt interaction for rows which shows all spells, targets or pets when pressed.\n\n|cFFFFFF00-|r Fixed a issue where changing the alpha of a window makes it disappear on the next logon.\n\n|cFFFFFF00-|r Added a option for auto transparency to ignore rows.\n\n|cFFFFFF00-|r Added option to be able to set shadow on the attribute text.\n\n|cFFFFFF00-|r Fixed a issue with window snap where disabled statusbar makes a gap between the windows.\n\n|cFFFFFF00-|r Added a hidden menu on the top left corner (experimental).\n\n|cFFFFFF00v1.12.3|r\n\n|cFFFFFF00-|r - Fixed 'Healing Per Second' which wasn't working at all.\n\n|cFFFFFF00-|r - Fixed the percent amount for target of damage done where sometimes it pass 100%.\n\n|cFFFFFF00-|r - Changes on Skins: Minimalistic and Elm UI Frame Style. Its necessary re-apply.\n\n|cFFFFFF00-|r - Added more cooldowns and spells for Monk tank over avoidance panel.\n\n|cFFFFFF00-|r - Player avatar now is also shown on the Player Details window.\n\n|cFFFFFF00-|r - Leaving empty the the icon file box, make details use no icons on bars." Loc ["STRING_DETAILS1"] = "|cffffaeaeDetalhes:|r " --> color and details name diff --git a/startup.lua b/startup.lua index 2153c059..064fc653 100644 --- a/startup.lua +++ b/startup.lua @@ -219,6 +219,9 @@ function _G._detalhes:Start() self.listener:RegisterEvent ("ENCOUNTER_START") self.listener:RegisterEvent ("ENCOUNTER_END") + + self.listener:RegisterEvent ("PET_BATTLE_OPENING_START") + self.listener:RegisterEvent ("PET_BATTLE_CLOSE") --self.listener:RegisterAllEvents() @@ -1039,6 +1042,7 @@ function _G._detalhes:Start() function _detalhes:OpenOptionsWindowAtStart() --_detalhes:OpenOptionsWindow (_detalhes.tabela_instancias[1]) --print (_G ["DetailsClearSegmentsButton1"]:GetSize()) + --_detalhes:OpenCustomWindow() end _detalhes:ScheduleTimer ("OpenOptionsWindowAtStart", 2)