Files
coa-details/core/control.lua
T
Tercio c30e2312b7 - Report lines for deaths is now inverted. No need to scroll up the chat to see the cause of death anymore.
Fixed some annoyances with auto current feature where it was changing the segments even when the user were using the window.
2015-04-14 18:44:47 -03:00

1272 lines
46 KiB
Lua

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
local _tempo = time()
local _
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _math_floor = math.floor --lua local
local _math_max = math.max --lua local
local _ipairs = ipairs --lua local
local _pairs = pairs --lua local
local _table_wipe = table.wipe --lua local
local _bit_band = bit.band --lua local
local _GetInstanceInfo = GetInstanceInfo --wow api local
local _UnitExists = UnitExists --wow api local
local _UnitGUID = UnitGUID --wow api local
local _UnitName = UnitName --wow api local
local _GetTime = GetTime
local _IsAltKeyDown = IsAltKeyDown
local _IsShiftKeyDown = IsShiftKeyDown
local _IsControlKeyDown = IsControlKeyDown
local atributo_damage = _detalhes.atributo_damage --details local
local atributo_heal = _detalhes.atributo_heal --details local
local atributo_energy = _detalhes.atributo_energy --details local
local atributo_misc = _detalhes.atributo_misc --details local
local atributo_custom = _detalhes.atributo_custom --details local
local info = _detalhes.janela_info --details local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> constants
local modo_GROUP = _detalhes.modos.group
local modo_ALL = _detalhes.modos.all
local class_type_dano = _detalhes.atributos.dano
local OBJECT_TYPE_PETS = 0x00003000
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
--> try to find the opponent of last fight, can be called during a fight as well
function _detalhes:FindEnemy()
local ZoneName, InstanceType, DifficultyID, _, _, _, _, ZoneMapID = _GetInstanceInfo()
local in_instance = IsInInstance() --> garrison returns party as instance type.
if ((InstanceType == "party" or InstanceType == "raid") and in_instance) then
return Loc ["STRING_SEGMENT_TRASH"]
end
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_original, 0x00000060) ~= 0) then --> 0x20+0x40 neutral + enemy reaction
for name, _ in _pairs (actor.targets) do
if (name == _detalhes.playername) then
return actor.nome
else
local _target_actor = _detalhes.tabela_vigente (class_type_dano, name)
if (_target_actor and _target_actor.grupo) then
return actor.nome
end
end
end
end
end
for _, actor in _ipairs (_detalhes.tabela_vigente[class_type_dano]._ActorTable) do
if (actor.grupo and not actor.owner) then
for target_name, _ in _pairs (actor.targets) do
return target_name
end
end
end
return Loc ["STRING_UNKNOW"]
end
-- try get the current encounter name during the encounter
local boss_found = function (index, name, zone, mapid, diff, encounterid)
local ejid = EJ_GetCurrentInstance()
if (ejid == 0) then
ejid = _detalhes:GetInstanceEJID()
end
local boss_table = {
index = index,
name = name,
encounter = name,
zone = zone,
mapid = mapid,
diff = diff,
diff_string = select (4, GetInstanceInfo()),
ej_instance_id = ejid,
id = encounterid,
}
_detalhes.tabela_vigente.is_boss = boss_table
if (_detalhes.in_combat and not _detalhes.leaving_combat) then
--> catch boss function if any
local bossFunction, bossFunctionType = _detalhes:GetBossFunction (ZoneMapID, BossIndex)
if (bossFunction) then
if (_bit_band (bossFunctionType, 0x1) ~= 0) then --realtime
_detalhes.bossFunction = bossFunction
_detalhes.tabela_vigente.bossFunction = _detalhes:ScheduleTimer ("bossFunction", 1)
end
end
if (_detalhes.zone_type ~= "raid") then
local endType, endData = _detalhes:GetEncounterEnd (ZoneMapID, BossIndex)
if (endType and endData) then
if (_detalhes.debug) then
_detalhes:Msg ("(debug) setting boss end type to:", endType)
end
_detalhes.encounter_end_table.type = endType
_detalhes.encounter_end_table.killed = {}
_detalhes.encounter_end_table.data = {}
if (type (endData) == "table") then
if (_detalhes.debug) then
_detalhes:Msg ("(debug) boss type is table:", endType)
end
if (endType == 1 or endType == 2) then
for _, npcID in ipairs (endData) do
_detalhes.encounter_end_table.data [npcID] = false
end
end
else
if (endType == 1 or endType == 2) then
_detalhes.encounter_end_table.data [endData] = false
end
end
end
end
end
_detalhes:SendEvent ("COMBAT_BOSS_FOUND", nil, index, name)
return boss_table
end
function _detalhes:ReadBossFrames()
if (_detalhes.tabela_vigente.is_boss) then
return --no need to check
end
if (_detalhes.encounter_table.name) then
local encounter_table = _detalhes.encounter_table
return boss_found (encounter_table.index, encounter_table.name, encounter_table.zone, encounter_table.mapid, encounter_table.diff, encounter_table.id)
end
for index = 1, 5, 1 do
if (_UnitExists ("boss"..index)) then
local guid = _UnitGUID ("boss"..index)
if (guid) then
local serial = _detalhes:GetNpcIdFromGuid (guid)
if (serial) then
local ZoneName, _, DifficultyID, _, _, _, _, ZoneMapID = _GetInstanceInfo()
local BossIds = _detalhes:GetBossIds (ZoneMapID)
if (BossIds) then
local BossIndex = BossIds [serial]
if (BossIndex) then
if (_detalhes.debug) then
_detalhes:Msg ("(debug) boss found:",_detalhes:GetBossName (ZoneMapID, BossIndex))
end
return boss_found (BossIndex, _detalhes:GetBossName (ZoneMapID, BossIndex), ZoneName, ZoneMapID, DifficultyID)
end
end
end
end
end
end
end
--try to get the encounter name after the encounter (can be called during the combat as well)
function _detalhes:FindBoss()
if (_detalhes.encounter_table.name) then
local encounter_table = _detalhes.encounter_table
return boss_found (encounter_table.index, encounter_table.name, encounter_table.zone, encounter_table.mapid, encounter_table.diff, encounter_table.id)
end
local ZoneName, InstanceType, DifficultyID, _, _, _, _, ZoneMapID = _GetInstanceInfo()
local BossIds = _detalhes:GetBossIds (ZoneMapID)
if (BossIds) then
local BossIndex = nil
local ActorsContainer = _detalhes.tabela_vigente [class_type_dano]._ActorTable
if (ActorsContainer) then
for index, Actor in _ipairs (ActorsContainer) do
if (not Actor.grupo) then
local serial = _detalhes:GetNpcIdFromGuid (Actor.serial)
if (serial) then
BossIndex = BossIds [serial]
if (BossIndex) then
Actor.boss = true
return boss_found (BossIndex, _detalhes:GetBossName (ZoneMapID, BossIndex), ZoneName, ZoneMapID, DifficultyID)
end
end
end
end
end
end
return false
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
-- _detalhes.statistics = {container_calls = 0, container_pet_calls = 0, container_unknow_pet = 0, damage_calls = 0, heal_calls = 0, absorbs_calls = 0, energy_calls = 0, pets_summons = 0}
-- ~start ~inicio ~novo ñovo
function _detalhes:EntrarEmCombate (...)
if (_detalhes.debug) then
_detalhes:Msg ("(debug) started a new combat.")
end
if (not _detalhes.tabela_historico.tabelas[1]) then
_detalhes.tabela_overall = _detalhes.combate:NovaTabela()
_detalhes:InstanciaCallFunction (_detalhes.ResetaGump, nil, -1) --> reseta scrollbar, iterators, rodapé, etc
_detalhes:InstanciaCallFunction (_detalhes.InstanciaFadeBarras, -1) --> esconde todas as barras
_detalhes:InstanciaCallFunction (_detalhes.AtualizaSegmentos) --> atualiza o showing
end
--> re-lock nos tempos da tabela passada -- lock again last table times
_detalhes.tabela_vigente:TravarTempos() --> lá em cima é feito wipe, não deveria ta dando merda nisso aqui? ou ela puxa da __index e da zero jogadores no mapa e container
local n_combate = _detalhes:NumeroCombate (1) --aumenta o contador de combates -- combat number up
--> cria a nova tabela de combates -- create new table
local ultimo_combate = _detalhes.tabela_vigente
_detalhes.tabela_vigente = _detalhes.combate:NovaTabela (true, _detalhes.tabela_overall, n_combate, ...) --cria uma nova tabela de combate
_detalhes.tabela_vigente.previous_combat = ultimo_combate
--> verifica se há alguma instância mostrando o segmento atual -- change segment
_detalhes:InstanciaCallFunction (_detalhes.TrocaSegmentoAtual)
_detalhes.tabela_vigente:seta_data (_detalhes._detalhes_props.DATA_TYPE_START) --seta na tabela do combate a data do inicio do combate -- setup time data
_detalhes.in_combat = true --sinaliza ao addon que há um combate em andamento -- in combat flag up
_detalhes.tabela_vigente.combat_id = n_combate --> grava o número deste combate na tabela atual -- setup combat id on new table
_detalhes.last_combat_pre_pot_used = nil
--> é o timer que ve se o jogador ta em combate ou não -- check if any party or raid members are in combat
_detalhes.tabela_vigente.verifica_combate = _detalhes:ScheduleRepeatingTimer ("EstaEmCombate", 1)
_detalhes:ClearCCPetsBlackList()
_table_wipe (_detalhes.encounter_end_table)
_table_wipe (_detalhes.pets_ignored)
_table_wipe (_detalhes.pets_no_owner)
_detalhes.container_pets:BuscarPets()
_table_wipe (_detalhes.cache_damage_group)
_table_wipe (_detalhes.cache_healing_group)
_detalhes:UpdateParserGears()
_detalhes.host_of = nil
_detalhes.host_by = nil
if (_detalhes.in_group and _detalhes.cloud_capture) then
if (_detalhes:IsInInstance() or _detalhes.debug) then
if (not _detalhes:CaptureIsAllEnabled()) then
_detalhes:ScheduleSendCloudRequest()
if (_detalhes.debug) then
_detalhes:Msg ("(debug) requesting a cloud server.")
end
end
else
if (_detalhes.debug) then
_detalhes:Msg ("(debug) isn't inside a registred instance", _detalhes:IsInInstance())
end
end
else
if (_detalhes.debug) then
_detalhes:Msg ("(debug) isn't in group or cloud is turned off", _detalhes.in_group, _detalhes.cloud_capture)
end
end
_detalhes:CatchRaidBuffUptime ("BUFF_UPTIME_IN")
_detalhes:CatchRaidDebuffUptime ("DEBUFF_UPTIME_IN")
_detalhes:UptadeRaidMembersCache()
--> hide / alpha / switch in combat
for index, instancia in ipairs (_detalhes.tabela_instancias) do
if (instancia.ativa) then
--instancia:SetCombatAlpha (nil, nil, true) --passado para o regen disable
instancia:CheckSwitchOnCombatStart (true)
end
end
_detalhes:InstanceCall (_detalhes.CheckPsUpdate)
_detalhes:SendEvent ("COMBAT_PLAYER_ENTER", nil, _detalhes.tabela_vigente, _detalhes.encounter_table and _detalhes.encounter_table.id)
_detalhes:CheckSwitchToCurrent()
end
function _detalhes:DelayedSyncAlert()
local lower_instance = _detalhes:GetLowerInstanceNumber()
if (lower_instance) then
lower_instance = _detalhes:GetInstance (lower_instance)
if (lower_instance) then
if (not lower_instance:HaveInstanceAlert()) then
lower_instance:InstanceAlert (Loc ["STRING_EQUILIZING"], {[[Interface\COMMON\StreamCircle]], 22, 22, true}, 5, {function() end})
end
end
end
end
-- ~end ~leave
function _detalhes:SairDoCombate (bossKilled, from_encounter_end)
if (_detalhes.debug) then
_detalhes:Msg ("(debug) ended a combat.")
end
--if (_detalhes.statistics) then
-- for k, v in pairs (_detalhes.statistics) do
-- print (k, v)
-- end
--end
_detalhes.leaving_combat = true
_detalhes.last_combat_time = _tempo
if (_detalhes.schedule_remove_overall and not from_encounter_end and not InCombatLockdown()) then
if (_detalhes.debug) then
_detalhes:Msg ("(debug) found schedule overall data deletion.")
end
_detalhes.schedule_remove_overall = false
_detalhes.tabela_historico:resetar_overall()
end
_detalhes:CatchRaidBuffUptime ("BUFF_UPTIME_OUT")
_detalhes:CatchRaidDebuffUptime ("DEBUFF_UPTIME_OUT")
_detalhes:CloseEnemyDebuffsUptime()
--> pega a zona do jogador e vê se foi uma luta contra um Boss -- identifica se a luta foi com um boss
if (not _detalhes.tabela_vigente.is_boss) then
--> function which runs after a boss encounter to try recognize a encounter
_detalhes:FindBoss()
if (not _detalhes.tabela_vigente.is_boss) then
local ZoneName, _, DifficultyID, _, _, _, _, ZoneMapID = _GetInstanceInfo()
local findboss = _detalhes:GetRaidBossFindFunction (ZoneMapID)
if (findboss) then
local BossIndex = findboss()
if (BossIndex) then
boss_found (BossIndex, _detalhes:GetBossName (ZoneMapID, BossIndex), ZoneName, ZoneMapID, DifficultyID)
end
end
end
end
if (_detalhes.tabela_vigente.bossFunction) then
_detalhes:CancelTimer (_detalhes.tabela_vigente.bossFunction)
_detalhes.bossFunction = nil
end
--> finaliza a checagem se esta ou não no combate -- finish combat check
if (_detalhes.tabela_vigente.verifica_combate) then
_detalhes:CancelTimer (_detalhes.tabela_vigente.verifica_combate)
_detalhes.tabela_vigente.verifica_combate = nil
end
--> lock timers
_detalhes.tabela_vigente:TravarTempos()
--> get waste shields
if (_detalhes.close_shields) then
_detalhes:CloseShields (_detalhes.tabela_vigente)
end
--> salva hora, minuto, segundo do fim da luta
_detalhes.tabela_vigente:seta_data (_detalhes._detalhes_props.DATA_TYPE_END)
_detalhes.tabela_vigente:seta_tempo_decorrido()
--> drop last events table to garbage collector
_detalhes.tabela_vigente.player_last_events = {}
--> flag instance type
local _, InstanceType = _GetInstanceInfo()
_detalhes.tabela_vigente.instance_type = InstanceType
if (not _detalhes.tabela_vigente.is_boss) then
if (_detalhes.tabela_vigente.is_pvp) then
_detalhes:FlagActorsOnPvPCombat()
end
local in_instance = IsInInstance() --> garrison returns party as instance type.
if ((InstanceType == "party" or InstanceType == "raid") and in_instance) then
_detalhes.tabela_vigente.is_trash = true
end
if (not _detalhes.tabela_vigente.enemy) then
local enemy = _detalhes:FindEnemy()
if (enemy and _detalhes.debug) then
_detalhes:Msg ("(debug) enemy found", enemy)
end
_detalhes.tabela_vigente.enemy = enemy
end
if (_detalhes.debug) then
_detalhes:Msg ("(debug) forcing equalize actors behavior.")
_detalhes:EqualizeActorsSchedule (_detalhes.host_of)
end
--> verifica memoria
_detalhes:FlagActorsOnCommonFight() --fight_component
_detalhes:CheckMemoryAfterCombat()
else
if (not InCombatLockdown() and not UnitAffectingCombat ("player")) then
_detalhes:FlagActorsOnBossFight()
else
_detalhes.schedule_flag_boss_components = true
end
local boss_id = _detalhes.encounter_table.id
if (bossKilled) then
_detalhes.tabela_vigente.is_boss.killed = true
--> add to storage
if (not InCombatLockdown() and not UnitAffectingCombat ("player") and not _detalhes.logoff_saving_data) then
--_detalhes.StoreEncounter()
local successful, errortext = pcall (_detalhes.StoreEncounter)
if (not successful) then
_detalhes:Msg ("error occurred on StoreEncounter():", errortext)
end
else
_detalhes.schedule_store_boss_encounter = true
end
end
--if (_detalhes:GetBossDetails (_detalhes.tabela_vigente.is_boss.mapid, _detalhes.tabela_vigente.is_boss.index) or ) then
_detalhes.tabela_vigente.is_boss.index = _detalhes.tabela_vigente.is_boss.index or 1
_detalhes.tabela_vigente.enemy = _detalhes.tabela_vigente.is_boss.encounter
if (_detalhes.tabela_vigente.instance_type == "raid") then
_detalhes.last_encounter2 = _detalhes.last_encounter
_detalhes.last_encounter = _detalhes.tabela_vigente.is_boss.name
if (_detalhes.pre_pot_used) then
_detalhes.last_combat_pre_pot_used = table_deepcopy (_detalhes.pre_pot_used)
end
if (_detalhes.pre_pot_used and _detalhes.announce_prepots.enabled) then
_detalhes:Msg (_detalhes.pre_pot_used or "")
_detalhes.pre_pot_used = nil
end
end
if (from_encounter_end) then
_detalhes.tabela_vigente:SetEndTime (_detalhes.encounter_table ["end"])
end
--> encounter boss function
local bossFunction, bossFunctionType = _detalhes:GetBossFunction (_detalhes.tabela_vigente.is_boss.mapid or 0, _detalhes.tabela_vigente.is_boss.index or 0)
if (bossFunction) then
if (_bit_band (bossFunctionType, 0x2) ~= 0) then --end of combat
if (not InCombatLockdown() and not UnitAffectingCombat ("player") and not _detalhes.logoff_saving_data) then
local successful, errortext = pcall (bossFunction, _detalhes.tabela_vigente)
if (not successful) then
_detalhes:Msg ("error occurred on Encounter Boss Function:", errortext)
end
else
_detalhes.schedule_boss_function_run = bossFunction
end
end
end
if (_detalhes.tabela_vigente.instance_type == "raid") then
--> schedule captures off
_detalhes:CaptureSet (false, "damage", false, 15)
_detalhes:CaptureSet (false, "energy", false, 15)
_detalhes:CaptureSet (false, "aura", false, 15)
_detalhes:CaptureSet (false, "energy", false, 15)
_detalhes:CaptureSet (false, "spellcast", false, 15)
if (_detalhes.debug) then
_detalhes:Msg ("(debug) freezing parser for 15 seconds.")
end
end
--> schedule sync
_detalhes:EqualizeActorsSchedule (_detalhes.host_of)
if (_detalhes:GetEncounterEqualize (_detalhes.tabela_vigente.is_boss.mapid, _detalhes.tabela_vigente.is_boss.index)) then
_detalhes:ScheduleTimer ("DelayedSyncAlert", 3)
end
--else
-- if (_detalhes.debug) then
-- _detalhes:EqualizeActorsSchedule (_detalhes.host_of)
-- end
--end
end
if (_detalhes.solo) then
--> debuffs need a checkup, not well functional right now
_detalhes.CloseSoloDebuffs()
end
local tempo_do_combate = _detalhes.tabela_vigente:GetCombatTime()
local invalid_combat
--if ( tempo_do_combate >= _detalhes.minimum_combat_time) then --> tempo minimo precisa ser 5 segundos pra acrecentar a tabela ao historico
if ( tempo_do_combate >= 5 or not _detalhes.tabela_historico.tabelas[1]) then --> tempo minimo precisa ser 5 segundos pra acrecentar a tabela ao historico
_detalhes.tabela_historico:adicionar (_detalhes.tabela_vigente) --move a tabela atual para dentro do histórico
else
--print ("combat invalid...")
--> this is a little bit complicated, need a specific function for combat cancellation
--_table_wipe (_detalhes.tabela_vigente) --> descarta ela, não será mais usada
invalid_combat = _detalhes.tabela_vigente
_detalhes.tabela_vigente = _detalhes.tabela_historico.tabelas[1] --> pega a tabela do ultimo combate
if (_detalhes.tabela_vigente:GetStartTime() == 0) then
--_detalhes.tabela_vigente.start_time = _detalhes._tempo
_detalhes.tabela_vigente:SetStartTime (_GetTime())
--_detalhes.tabela_vigente.end_time = _detalhes._tempo
_detalhes.tabela_vigente:SetEndTime (_GetTime())
end
_detalhes.tabela_vigente.resincked = true
--> tabela foi descartada, precisa atualizar os baseframes // precisa atualizer todos ou apenas o overall?
_detalhes:InstanciaCallFunction (_detalhes.AtualizarJanela)
if (_detalhes.solo) then
local esta_instancia = _detalhes.tabela_instancias[_detalhes.solo]
if (_detalhes.SoloTables.CombatID == _detalhes:NumeroCombate()) then --> significa que o solo mode validou o combate, como matar um bixo muito low level com uma só porrada
if (_detalhes.SoloTables.CombatIDLast and _detalhes.SoloTables.CombatIDLast ~= 0) then --> volta os dados da luta anterior
_detalhes.SoloTables.CombatID = _detalhes.SoloTables.CombatIDLast
else
if (_detalhes.RefreshSolo) then
_detalhes:RefreshSolo()
end
_detalhes.SoloTables.CombatID = nil
end
end
end
_detalhes:NumeroCombate (-1)
end
_detalhes.host_of = nil
_detalhes.host_by = nil
if (_detalhes.cloud_process) then
_detalhes:CancelTimer (_detalhes.cloud_process)
end
_detalhes.in_combat = false
_detalhes.leaving_combat = false
_detalhes:OnCombatPhaseChanged()
_table_wipe (_detalhes.tabela_vigente.PhaseData.damage_section)
_table_wipe (_detalhes.tabela_vigente.PhaseData.heal_section)
_table_wipe (_detalhes.cache_damage_group)
_table_wipe (_detalhes.cache_healing_group)
_detalhes:UpdateParserGears()
--> hide / alpha in combat
for index, instancia in ipairs (_detalhes.tabela_instancias) do
if (instancia.ativa) then
--instancia:SetCombatAlpha (nil, nil, true) --passado para o regen enabled
if (instancia.auto_switch_to_old) then
instancia:CheckSwitchOnCombatEnd()
end
end
end
_detalhes.pre_pot_used = nil
_table_wipe (_detalhes.encounter_table)
_detalhes:InstanceCall (_detalhes.CheckPsUpdate)
if (invalid_combat) then
_detalhes:SendEvent ("COMBAT_INVALID")
_detalhes:SendEvent ("COMBAT_PLAYER_LEAVE", nil, invalid_combat)
else
_detalhes:SendEvent ("COMBAT_PLAYER_LEAVE", nil, _detalhes.tabela_vigente)
end
end
function _detalhes:GetPlayersInArena()
local aliados = GetNumGroupMembers (LE_PARTY_CATEGORY_HOME)
for i = 1, aliados-1 do
local role = UnitGroupRolesAssigned ("party" .. i)
if (role ~= "NONE") then
local name = GetUnitName ("party" .. i, true)
_detalhes.arena_table [name] = {role = role}
end
end
local role = UnitGroupRolesAssigned ("player")
if (role ~= "NONE") then
local name = GetUnitName ("player", true)
_detalhes.arena_table [name] = {role = role}
end
if (_detalhes.debug) then
_detalhes:Msg ("(debug) Found", oponentes, "enemies and", aliados, "allies")
end
end
function _detalhes:CreateArenaSegment()
_detalhes:GetPlayersInArena()
_detalhes.arena_begun = true
_detalhes.start_arena = nil
if (_detalhes.in_combat) then
_detalhes:SairDoCombate()
end
--> inicia um novo combate
_detalhes:EntrarEmCombate()
--> sinaliza que esse combate é arena
_detalhes.tabela_vigente.arena = true
_detalhes.tabela_vigente.is_arena = {name = _detalhes.zone_name, zone = _detalhes.zone_name, mapid = _detalhes.zone_id}
end
function _detalhes:StartArenaSegment (...)
if (_detalhes.debug) then
_detalhes:Msg ("(debug) starting a new arena segment.")
end
local timerType, timeSeconds, totalTime = select (1, ...)
if (_detalhes.start_arena) then
_detalhes:CancelTimer (_detalhes.start_arena, true)
end
_detalhes.start_arena = _detalhes:ScheduleTimer ("CreateArenaSegment", timeSeconds)
_detalhes:GetPlayersInArena()
end
function _detalhes:EnteredInArena()
if (_detalhes.debug) then
_detalhes:Msg ("(debug) arena detected.")
end
_detalhes.arena_begun = false
_detalhes:GetPlayersInArena()
end
function _detalhes:LeftArena()
_detalhes.is_in_arena = false
_detalhes.arena_begun = false
if (_detalhes.start_arena) then
_detalhes:CancelTimer (_detalhes.start_arena, true)
end
end
function _detalhes:MakeEqualizeOnActor (player, realm, receivedActor)
local combat = _detalhes:GetCombat ("current")
local damage, heal, energy, misc = _detalhes:GetAllActors ("current", player)
if (not damage and not heal and not energy and not misc) then
--> try adding server name
damage, heal, energy, misc = _detalhes:GetAllActors ("current", player.."-"..realm)
if (not damage and not heal and not energy and not misc) then
--> not found any actor object, so we need to create
local actorName
if (realm ~= GetRealmName()) then
actorName = player.."-"..realm
else
actorName = player
end
local guid = _detalhes:FindGUIDFromName (player)
-- 0x512 normal party
-- 0x514 normal raid
if (guid) then
damage = combat [1]:PegarCombatente (guid, actorName, 0x514, true)
heal = combat [2]:PegarCombatente (guid, actorName, 0x514, true)
energy = combat [3]:PegarCombatente (guid, actorName, 0x514, true)
misc = combat [4]:PegarCombatente (guid, actorName, 0x514, true)
if (_detalhes.debug) then
_detalhes:Msg ("(debug) equalize received actor:", actorName, damage, heal)
end
else
if (_detalhes.debug) then
_detalhes:Msg ("(debug) equalize couldn't get guid for player ",player)
end
end
end
end
combat[1].need_refresh = true
combat[2].need_refresh = true
combat[3].need_refresh = true
combat[4].need_refresh = true
if (damage) then
if (damage.total < receivedActor [1][1]) then
if (_detalhes.debug) then
_detalhes:Msg (player .. " damage before: " .. damage.total .. " damage received: " .. receivedActor [1][1])
end
damage.total = receivedActor [1][1]
end
if (damage.damage_taken < receivedActor [1][2]) then
damage.damage_taken = receivedActor [1][2]
end
if (damage.friendlyfire_total < receivedActor [1][3]) then
damage.friendlyfire_total = receivedActor [1][3]
end
end
if (heal) then
if (heal.total < receivedActor [2][1]) then
heal.total = receivedActor [2][1]
end
if (heal.totalover < receivedActor [2][2]) then
heal.totalover = receivedActor [2][2]
end
if (heal.healing_taken < receivedActor [2][3]) then
heal.healing_taken = receivedActor [2][3]
end
end
if (energy) then
if (energy.mana and (receivedActor [3][1] > 0 and energy.mana < receivedActor [3][1])) then
energy.mana = receivedActor [3][1]
end
if (energy.e_rage and (receivedActor [3][2] > 0 and energy.e_rage < receivedActor [3][2])) then
energy.e_rage = receivedActor [3][2]
end
if (energy.e_energy and (receivedActor [3][3] > 0 and energy.e_energy < receivedActor [3][3])) then
energy.e_energy = receivedActor [3][3]
end
if (energy.runepower and (receivedActor [3][4] > 0 and energy.runepower < receivedActor [3][4])) then
energy.runepower = receivedActor [3][4]
end
end
if (misc) then
if (misc.interrupt and (receivedActor [4][1] > 0 and misc.interrupt < receivedActor [4][1])) then
misc.interrupt = receivedActor [4][1]
end
if (misc.dispell and (receivedActor [4][2] > 0 and misc.dispell < receivedActor [4][2])) then
misc.dispell = receivedActor [4][2]
end
end
end
function _detalhes:EqualizePets()
--> check for pets without owner
for _, actor in _ipairs (_detalhes.tabela_vigente[1]._ActorTable) do
--> have flag and the flag tell us he is a pet
if (actor.flag_original and bit.band (actor.flag_original, OBJECT_TYPE_PETS) ~= 0) then
--> do not have owner and he isn't on owner container
if (not actor.owner and not _detalhes.tabela_pets.pets [actor.serial]) then
_detalhes:SendPetOwnerRequest (actor.serial, actor.nome)
end
end
end
end
function _detalhes:EqualizeActorsSchedule (host_of)
--> store pets sent through 'needpetowner'
_detalhes.sent_pets = _detalhes.sent_pets or {n = time()}
if (_detalhes.sent_pets.n+20 < time()) then
_table_wipe (_detalhes.sent_pets)
_detalhes.sent_pets.n = time()
end
--> pet equilize disabled on details 1.4.0
--_detalhes:ScheduleTimer ("EqualizePets", 1+math.random())
--> do not equilize if there is any disabled capture
--if (_detalhes:CaptureIsAllEnabled()) then
_detalhes:ScheduleTimer ("EqualizeActors", 2+math.random()+math.random() , host_of)
--end
end
function _detalhes:EqualizeActors (host_of)
if (_detalhes.debug) then
_detalhes:Msg ("(debug) sending equilize actor data")
end
local damage, heal, energy, misc
if (host_of) then
damage, heal, energy, misc = _detalhes:GetAllActors ("current", host_of)
else
damage, heal, energy, misc = _detalhes:GetAllActors ("current", _detalhes.playername)
end
if (damage) then
damage = {damage.total or 0, damage.damage_taken or 0, damage.friendlyfire_total or 0}
else
damage = {0, 0, 0}
end
if (heal) then
heal = {heal.total or 0, heal.totalover or 0, heal.healing_taken or 0}
else
heal = {0, 0, 0}
end
if (energy) then
energy = {energy.mana or 0, energy.e_rage or 0, energy.e_energy or 0, energy.runepower or 0}
else
energy = {0, 0, 0, 0}
end
if (misc) then
misc = {misc.interrupt or 0, misc.dispell or 0}
else
misc = {0, 0}
end
local data = {damage, heal, energy, misc}
--> envia os dados do proprio host pra ele antes
if (host_of) then
_detalhes:SendRaidDataAs (_detalhes.network.ids.CLOUD_EQUALIZE, host_of, nil, data)
_detalhes:EqualizeActors()
else
_detalhes:SendRaidData (_detalhes.network.ids.CLOUD_EQUALIZE, data)
end
end
function _detalhes:FlagActorsOnPvPCombat()
for class_type, container in _ipairs (_detalhes.tabela_vigente) do
for _, actor in _ipairs (container._ActorTable) do
actor.pvp_component = true
end
end
end
function _detalhes:FlagActorsOnBossFight()
for class_type, container in _ipairs (_detalhes.tabela_vigente) do
for _, actor in _ipairs (container._ActorTable) do
actor.boss_fight_component = true
end
end
end
local fight_component = function (energy_container, misc_container, name)
local on_energy = energy_container._ActorTable [energy_container._NameIndexTable [name]]
if (on_energy) then
on_energy.fight_component = true
end
local on_misc = misc_container._ActorTable [misc_container._NameIndexTable [name]]
if (on_misc) then
on_misc.fight_component = true
end
end
function _detalhes:FlagActorsOnCommonFight()
local damage_container = _detalhes.tabela_vigente [1]
local healing_container = _detalhes.tabela_vigente [2]
local energy_container = _detalhes.tabela_vigente [3]
local misc_container = _detalhes.tabela_vigente [4]
for class_type, container in _ipairs ({damage_container, healing_container}) do
for _, actor in _ipairs (container._ActorTable) do
if (actor.grupo) then
if (class_type == 1 or class_type == 2) then
for target_name, amount in _pairs (actor.targets) do
local target_object = container._ActorTable [container._NameIndexTable [target_name]]
if (target_object) then
target_object.fight_component = true
fight_component (energy_container, misc_container, target_name)
end
end
if (class_type == 1) then
for damager_actor, _ in _pairs (actor.damage_from) do
local target_object = container._ActorTable [container._NameIndexTable [damager_actor]]
if (target_object) then
target_object.fight_component = true
fight_component (energy_container, misc_container, damager_actor)
end
end
elseif (class_type == 2) then
for healer_actor, _ in _pairs (actor.healing_from) do
local target_object = container._ActorTable [container._NameIndexTable [healer_actor]]
if (target_object) then
target_object.fight_component = true
fight_component (energy_container, misc_container, healer_actor)
end
end
end
end
end
end
end
end
function _detalhes:AtualizarJanela (instancia, _segmento)
if (_segmento) then --> apenas atualizar janelas que estejam mostrando o segmento solicitado
if (_segmento == instancia.segmento) then
instancia:TrocaTabela (instancia, instancia.segmento, instancia.atributo, instancia.sub_atributo, true)
end
else
if (instancia.modo == modo_GROUP or instancia.modo == modo_ALL) then
instancia:TrocaTabela (instancia, instancia.segmento, instancia.atributo, instancia.sub_atributo, true)
end
end
end
function _detalhes:PostponeInstanceToCurrent (instance)
if ((instance.last_interaction+6 < _detalhes._tempo) and (not DetailsReportWindow or not DetailsReportWindow:IsShown())) then
if (instance.segmento == 0) then
return _detalhes:TrocaSegmentoAtual (instance)
end
end
_detalhes:ScheduleTimer ("PostponeInstanceToCurrent", 2, instance)
end
function _detalhes:TrocaSegmentoAtual (instancia)
if (instancia.segmento == 0) then --> esta mostrando a tabela Atual
if ((instancia.last_interaction and (instancia.last_interaction+6 > _detalhes._tempo)) or (DetailsReportWindow and DetailsReportWindow:IsShown())) then
--> postpone
return _detalhes:ScheduleTimer ("PostponeInstanceToCurrent", 2, instancia)
end
instancia.showing =_detalhes.tabela_vigente
instancia:ResetaGump()
_detalhes.gump:Fade (instancia, "in", nil, "barras")
end
end
--> internal GetCombatId() version
function _detalhes:NumeroCombate (flag)
if (flag == 0) then
_detalhes.combat_id = 0
elseif (flag) then
_detalhes.combat_id = _detalhes.combat_id + flag
end
return _detalhes.combat_id
end
--> tooltip fork / search key: ~tooltip
local avatarPoint = {"bottomleft", "topleft", -3, -4}
local backgroundPoint = {{"bottomleft", "topleft", 0, -3}, {"bottomright", "topright", 0, -3}}
local textPoint = {"left", "right", -11, -5}
local avatarTexCoord = {0, 1, 0, 1}
local backgroundColor = {0, 0, 0, 0.6}
local avatarTextColor = {1, 1, 1, 1}
function _detalhes:AddTooltipBackgroundStatusbar()
GameCooltip:AddStatusBar (100, 1, unpack (_detalhes.tooltip.background))
end
function _detalhes:AddTooltipSpellHeaderText (headerText, headerColor, r, g, b, amount)
if (_detalhes.tooltip.show_amount) then
GameCooltip:AddLine (headerText, "x" .. amount .. "", nil, headerColor, r, g, b, .5, 10)
else
GameCooltip:AddLine (headerText, nil, nil, headerColor, nil, 12)
end
end
function _detalhes:MontaTooltip (frame, qual_barra, keydown)
local GameCooltip = GameCooltip
GameCooltip:Reset()
GameCooltip:SetType ("tooltip")
GameCooltip:SetOption ("TextSize", _detalhes.tooltip.fontsize)
GameCooltip:SetOption ("TextFont", _detalhes.tooltip.fontface)
GameCooltip:SetOption ("TextColor", _detalhes.tooltip.fontcolor)
GameCooltip:SetOption ("TextColorRight", _detalhes.tooltip.fontcolor_right)
GameCooltip:SetOption ("TextShadow", _detalhes.tooltip.fontshadow and "OUTLINE")
GameCooltip:SetOption ("LeftBorderSize", -5)
GameCooltip:SetOption ("RightBorderSize", 5)
GameCooltip:SetOption ("MinWidth", _math_max (230, self.baseframe:GetWidth()*0.9))
GameCooltip:SetOption ("StatusBarTexture", [[Interface\WorldStateFrame\WORLDSTATEFINALSCORE-HIGHLIGHT]]) --[[Interface\Addons\Details\images\bar_flat]]
GameCooltip:SetBackdrop (1, _detalhes.tooltip_backdrop, backgroundColor, _detalhes.tooltip_border_color) --{.090, .090, .188, .1}
local myPoint = _detalhes.tooltip.anchor_point
local anchorPoint = _detalhes.tooltip.anchor_relative
local x_Offset = _detalhes.tooltip.anchor_offset[1]
local y_Offset = _detalhes.tooltip.anchor_offset[2]
if (_detalhes.tooltip.anchored_to == 1) then
GameCooltip:SetHost (frame, myPoint, anchorPoint, x_Offset, y_Offset)
else
GameCooltip:SetHost (DetailsTooltipAnchor, myPoint, anchorPoint, x_Offset, y_Offset)
end
local esta_barra = self.barras [qual_barra] --> barra que o mouse passou em cima e irá mostrar o tooltip
local objeto = esta_barra.minha_tabela --> pega a referencia da tabela --> retorna a classe_damage ou classe_heal
if (not objeto) then --> a barra não possui um objeto
return false
end
--verifica por tooltips especiais:
if (objeto.dead) then --> é uma barra de dead
return _detalhes:ToolTipDead (self, objeto, esta_barra, keydown) --> instância, [morte], barra
elseif (objeto.frags) then
return _detalhes:ToolTipFrags (self, objeto, esta_barra, keydown)
elseif (objeto.boss_debuff) then
return _detalhes:ToolTipVoidZones (self, objeto, esta_barra, keydown)
end
local t = objeto:ToolTip (self, qual_barra, esta_barra, keydown) --> instância, nº barra, objeto barra, keydown
if (t) then
if (objeto.serial and objeto.serial ~= "") then
local avatar = NickTag:GetNicknameTable (objeto.serial, true)
if (avatar) then
if (avatar [2] and avatar [4] and avatar [1]) then
GameCooltip:SetBannerImage (1, avatar [2], 80, 40, avatarPoint, avatarTexCoord, nil) --> overlay [2] avatar path
GameCooltip:SetBannerImage (2, avatar [4], 200, 55, backgroundPoint, avatar [5], avatar [6]) --> background
GameCooltip:SetBannerText (1, (not _detalhes.ignore_nicktag and avatar [1]) or objeto.nome, textPoint, avatarTextColor, 14, SharedMedia:Fetch ("font", _detalhes.tooltip.fontface)) --> text [1] nickname
end
else
if (_detalhes.remove_realm_from_name and objeto.displayName:find ("%*")) then
GameCooltip:SetBannerImage (1, [[Interface\AddOns\Details\images\background]], 20, 30, avatarPoint, avatarTexCoord, {0, 0, 0, 0}) --> overlay [2] avatar path
GameCooltip:SetBannerImage (2, [[Interface\PetBattles\Weather-BurntEarth]], 160, 30, {{"bottomleft", "topleft", 0, -5}, {"bottomright", "topright", 0, -5}}, {0.12, 0.88, 1, 0}, {0, 0, 0, 0.1}) --> overlay [2] avatar path {0, 0, 0, 0}
GameCooltip:SetBannerText (1, objeto.nome, {"left", "left", 11, -8}, {1, 1, 1, 0.7}, 10, SharedMedia:Fetch ("font", _detalhes.tooltip.fontface)) --> text [1] nickname
end
end
end
GameCooltip:ShowCooltip()
end
end
function _detalhes.gump:UpdateTooltip (qual_barra, esta_barra, instancia)
if (_IsShiftKeyDown()) then
return instancia:MontaTooltip (esta_barra, qual_barra, "shift")
elseif (_IsControlKeyDown()) then
return instancia:MontaTooltip (esta_barra, qual_barra, "ctrl")
elseif (_IsAltKeyDown()) then
return instancia:MontaTooltip (esta_barra, qual_barra, "alt")
else
return instancia:MontaTooltip (esta_barra, qual_barra)
end
end
function _detalhes:EndRefresh (instancia, total, tabela_do_combate, showing)
_detalhes:EsconderBarrasNaoUsadas (instancia, showing)
end
function _detalhes:EsconderBarrasNaoUsadas (instancia, showing)
--> primeira atualização após uma mudança de segmento --> verifica se há mais barras sendo mostradas do que o necessário
--------------------
if (instancia.v_barras) then
for barra_numero = instancia.rows_showing+1, instancia.rows_created do
_detalhes.gump:Fade (instancia.barras[barra_numero], "in")
end
instancia.v_barras = false
end
return showing
end
--> call update functions
function _detalhes:AtualizarALL (forcar)
local tabela_do_combate = self.showing
--> confere se a instância possui uma tabela válida
if (not tabela_do_combate) then
if (not self.freezed) then
return self:Freeze()
end
return
end
local need_refresh = tabela_do_combate[self.atributo].need_refresh
if (not need_refresh and not forcar) then
return --> não precisa de refresh
--else
--tabela_do_combate[self.atributo].need_refresh = false
end
if (self.atributo == 1) then --> damage
return atributo_damage:RefreshWindow (self, tabela_do_combate, forcar, nil, need_refresh)
elseif (self.atributo == 2) then --> heal
return atributo_heal:RefreshWindow (self, tabela_do_combate, forcar, nil, need_refresh)
elseif (self.atributo == 3) then --> energy
return atributo_energy:RefreshWindow (self, tabela_do_combate, forcar, nil, need_refresh)
elseif (self.atributo == 4) then --> outros
return atributo_misc:RefreshWindow (self, tabela_do_combate, forcar, nil, need_refresh)
elseif (self.atributo == 5) then --> ocustom
return atributo_custom:RefreshWindow (self, tabela_do_combate, forcar, nil, need_refresh)
end
end
function _detalhes:AtualizaGumpPrincipal (instancia, forcar)
if (not instancia or type (instancia) == "boolean") then --> o primeiro parâmetro não foi uma instância ou ALL
forcar = instancia
instancia = self
end
if (instancia == -1) then
--> update
for index, esta_instancia in _ipairs (_detalhes.tabela_instancias) do
if (esta_instancia.ativa) then
if (esta_instancia.modo == modo_GROUP or esta_instancia.modo == modo_ALL) then
esta_instancia:AtualizarALL (forcar)
end
end
end
--> marcar que não precisa ser atualizada
for index, esta_instancia in _ipairs (_detalhes.tabela_instancias) do
if (esta_instancia.ativa and esta_instancia.showing) then
if (esta_instancia.modo == modo_GROUP or esta_instancia.modo == modo_ALL) then
if (esta_instancia.atributo <= 4) then
esta_instancia.showing [esta_instancia.atributo].need_refresh = false
end
end
end
end
if (not forcar) then --atualizar o gump de detalhes também se ele estiver aberto
if (info.ativo) then
return info.jogador:MontaInfo()
end
end
return
else
if (not instancia.ativa) then
return
end
end
if (instancia.modo == modo_ALL or instancia.modo == modo_GROUP) then
return instancia:AtualizarALL (forcar)
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> core
function _detalhes:AutoEraseConfirm()
local panel = _G.DetailsEraseDataConfirmation
if (not panel) then
panel = CreateFrame ("frame", "DetailsEraseDataConfirmation", UIParent)
panel:SetSize (400, 85)
panel:SetBackdrop ({bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 16,
edgeFile = [[Interface\AddOns\Details\images\border_2]], edgeSize = 12})
panel:SetPoint ("center", UIParent)
panel:SetBackdropColor (0, 0, 0, 0.4)
panel:SetScript ("OnMouseDown", function (self, button)
if (button == "RightButton") then
panel:Hide()
end
end)
--local icon = _detalhes.gump:CreateImage (panel, [[Interface\AddOns\Details\images\logotipo]], 512*0.4, 256*0.4)
--icon:SetPoint ("bottomleft", panel, "topleft", -10, -11)
local text = _detalhes.gump:CreateLabel (panel, Loc ["STRING_OPTIONS_CONFIRM_ERASE"], nil, nil, "GameFontNormal")
text:SetPoint ("center", panel, "center")
text:SetPoint ("top", panel, "top", 0, -10)
local no = _detalhes.gump:CreateButton (panel, function() panel:Hide() end, 90, 20, Loc ["STRING_NO"])
no:SetPoint ("bottomleft", panel, "bottomleft", 30, 10)
no:InstallCustomTexture (nil, nil, nil, nil, true)
local yes = _detalhes.gump:CreateButton (panel, function() panel:Hide(); _detalhes.tabela_historico:resetar() end, 90, 20, Loc ["STRING_YES"])
yes:SetPoint ("bottomright", panel, "bottomright", -30, 10)
yes:InstallCustomTexture (nil, nil, nil, nil, true)
end
panel:Show()
end
function _detalhes:CheckForAutoErase (mapid)
if (_detalhes.last_instance_id ~= mapid) then
if (_detalhes.segments_auto_erase == 2) then
--ask
_detalhes:ScheduleTimer ("AutoEraseConfirm", 1)
elseif (_detalhes.segments_auto_erase == 3) then
--erase
_detalhes.tabela_historico:resetar()
end
else
if (_tempo > _detalhes.last_instance_time + 21600) then --6 hours
if (_detalhes.segments_auto_erase == 2) then
--ask
_detalhes:ScheduleTimer ("AutoEraseConfirm", 1)
elseif (_detalhes.segments_auto_erase == 3) then
--erase
_detalhes.tabela_historico:resetar()
end
end
end
_detalhes.last_instance_id = mapid
_detalhes.last_instance_time = _tempo
--_detalhes.last_instance_time = 0 --debug
end
function _detalhes:UpdateControl()
_tempo = _detalhes._tempo
end