You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1927 lines
68 KiB
1927 lines
68 KiB
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
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 = Details.atributo_damage --details local
|
|
local atributo_heal = Details.atributo_heal --details local
|
|
local atributo_energy = Details.atributo_energy --details local
|
|
local atributo_misc = Details.atributo_misc --details local
|
|
local atributo_custom = Details.atributo_custom --details local
|
|
local info = Details.playerDetailWindow --details local
|
|
|
|
local UnitGroupRolesAssigned = DetailsFramework.UnitGroupRolesAssigned
|
|
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--> constants
|
|
|
|
local modo_GROUP = Details.modos.group
|
|
local modo_ALL = Details.modos.all
|
|
local class_type_dano = Details.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 Details: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
|
|
if (InstanceType == "party") then
|
|
if (Details:GetBossNames (Details.zone_id)) then
|
|
return Loc ["STRING_SEGMENT_TRASH"]
|
|
end
|
|
else
|
|
return Loc ["STRING_SEGMENT_TRASH"]
|
|
end
|
|
end
|
|
|
|
for _, actor in ipairs (Details.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 == Details.playername) then
|
|
return actor.nome
|
|
else
|
|
local _target_actor = Details.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 (Details.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_not_registered = function (t, ZoneName, ZoneMapID, DifficultyID)
|
|
|
|
local boss_table = {
|
|
index = 0,
|
|
name = t[1],
|
|
encounter = t[1],
|
|
zone = ZoneName,
|
|
mapid = ZoneMapID,
|
|
diff = DifficultyID,
|
|
diff_string = select (4, GetInstanceInfo()),
|
|
ej_instance_id = t[5],
|
|
id = t[2],
|
|
bossimage = t[4],
|
|
}
|
|
|
|
Details.tabela_vigente.is_boss = boss_table
|
|
end
|
|
|
|
local boss_found = function (index, name, zone, mapid, diff, encounterid)
|
|
|
|
local mapID = C_Map.GetBestMapForUnit ("player")
|
|
local ejid
|
|
if (mapID) then
|
|
ejid = DetailsFramework.EncounterJournal.EJ_GetInstanceForMap (mapID)
|
|
end
|
|
|
|
if (not mapID) then
|
|
--print ("Details! exeption handled: zone has no map")
|
|
return
|
|
end
|
|
|
|
if (ejid == 0) then
|
|
ejid = Details: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,
|
|
}
|
|
|
|
if (not Details:IsRaidRegistered (mapid) and Details.zone_type == "raid") then
|
|
local boss_list = Details:GetCurrentDungeonBossListFromEJ()
|
|
if (boss_list) then
|
|
local ActorsContainer = Details.tabela_vigente [class_type_dano]._ActorTable
|
|
if (ActorsContainer) then
|
|
for index, Actor in ipairs (ActorsContainer) do
|
|
if (not Actor.grupo) then
|
|
if (boss_list [Actor.nome]) then
|
|
Actor.boss = true
|
|
boss_table.bossimage = boss_list [Actor.nome][4]
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Details.tabela_vigente.is_boss = boss_table
|
|
|
|
if (Details.in_combat and not Details.leaving_combat) then
|
|
|
|
--> catch boss function if any
|
|
local bossFunction, bossFunctionType = Details:GetBossFunction (ZoneMapID, BossIndex)
|
|
if (bossFunction) then
|
|
if (_bit_band (bossFunctionType, 0x1) ~= 0) then --realtime
|
|
Details.bossFunction = bossFunction
|
|
Details.tabela_vigente.bossFunction = Details:ScheduleTimer ("bossFunction", 1)
|
|
end
|
|
end
|
|
|
|
if (Details.zone_type ~= "raid") then
|
|
local endType, endData = Details:GetEncounterEnd (ZoneMapID, BossIndex)
|
|
if (endType and endData) then
|
|
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) setting boss end type to:", endType)
|
|
end
|
|
|
|
Details.encounter_end_table.type = endType
|
|
Details.encounter_end_table.killed = {}
|
|
Details.encounter_end_table.data = {}
|
|
|
|
if (type (endData) == "table") then
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) boss type is table:", endType)
|
|
end
|
|
if (endType == 1 or endType == 2) then
|
|
for _, npcID in ipairs (endData) do
|
|
Details.encounter_end_table.data [npcID] = false
|
|
end
|
|
end
|
|
else
|
|
if (endType == 1 or endType == 2) then
|
|
Details.encounter_end_table.data [endData] = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--> we the boss was found during the combat table creation, we must postpone the event trigger
|
|
if (not Details.tabela_vigente.IsBeingCreated) then
|
|
Details:SendEvent ("COMBAT_BOSS_FOUND", nil, index, name)
|
|
Details:CheckFor_SuppressedWindowsOnEncounterFound()
|
|
end
|
|
|
|
return boss_table
|
|
end
|
|
|
|
function Details:ReadBossFrames()
|
|
|
|
if (Details.tabela_vigente.is_boss) then
|
|
return --no need to check
|
|
end
|
|
|
|
if (Details.encounter_table.name) then
|
|
local encounter_table = Details.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 = Details:GetNpcIdFromGuid (guid)
|
|
|
|
if (serial) then
|
|
|
|
local ZoneName, _, DifficultyID, _, _, _, _, ZoneMapID = _GetInstanceInfo()
|
|
|
|
local BossIds = Details:GetBossIds (ZoneMapID)
|
|
if (BossIds) then
|
|
local BossIndex = BossIds [serial]
|
|
|
|
if (BossIndex) then
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) boss found:",Details:GetBossName (ZoneMapID, BossIndex))
|
|
end
|
|
|
|
return boss_found (BossIndex, Details: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 Details:FindBoss (noJournalSearch)
|
|
|
|
if (Details.encounter_table.name) then
|
|
local encounter_table = Details.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 = Details:GetBossIds (ZoneMapID)
|
|
|
|
if (BossIds) then
|
|
local BossIndex = nil
|
|
local ActorsContainer = Details.tabela_vigente [class_type_dano]._ActorTable
|
|
|
|
if (ActorsContainer) then
|
|
for index, Actor in ipairs (ActorsContainer) do
|
|
if (not Actor.grupo) then
|
|
local serial = Details:GetNpcIdFromGuid (Actor.serial)
|
|
if (serial) then
|
|
BossIndex = BossIds [serial]
|
|
if (BossIndex) then
|
|
Actor.boss = true
|
|
return boss_found (BossIndex, Details:GetBossName (ZoneMapID, BossIndex), ZoneName, ZoneMapID, DifficultyID)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
noJournalSearch = true --> disabling the scan on encounter journal
|
|
|
|
if (not noJournalSearch) then
|
|
local in_instance = IsInInstance() --> garrison returns party as instance type.
|
|
if ((InstanceType == "party" or InstanceType == "raid") and in_instance) then
|
|
local boss_list = Details:GetCurrentDungeonBossListFromEJ()
|
|
if (boss_list) then
|
|
local ActorsContainer = Details.tabela_vigente [class_type_dano]._ActorTable
|
|
if (ActorsContainer) then
|
|
for index, Actor in ipairs (ActorsContainer) do
|
|
if (not Actor.grupo) then
|
|
if (boss_list [Actor.nome]) then
|
|
Actor.boss = true
|
|
return boss_found_not_registered (boss_list [Actor.nome], ZoneName, ZoneMapID, DifficultyID)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--> internal functions
|
|
-- Details.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}
|
|
function Details:StartCombat(...)
|
|
return Details:EntrarEmCombate (...)
|
|
end
|
|
|
|
-- ~start ~inicio ~novo �ovo
|
|
function Details:EntrarEmCombate (...)
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) |cFFFFFF00started a new combat|r|cFFFF7700", Details.encounter_table and Details.encounter_table.name or "")
|
|
--local from = debugstack (2, 1, 0)
|
|
--print (from)
|
|
end
|
|
|
|
if (not Details.tabela_historico.tabelas[1]) then
|
|
Details.tabela_overall = Details.combate:NovaTabela()
|
|
|
|
Details:InstanciaCallFunction (Details.ResetaGump, nil, -1) --> reseta scrollbar, iterators, rodap�, etc
|
|
Details:InstanciaCallFunction (Details.InstanciaFadeBarras, -1) --> esconde todas as barras
|
|
Details:InstanciaCallFunction (Details.AtualizaSegmentos) --> atualiza o showing
|
|
end
|
|
|
|
--> re-lock nos tempos da tabela passada -- lock again last table times
|
|
Details.tabela_vigente:TravarTempos()
|
|
|
|
local n_combate = Details:NumeroCombate (1) --aumenta o contador de combates -- combat number up
|
|
|
|
--> cria a nova tabela de combates -- create new table
|
|
local ultimo_combate = Details.tabela_vigente
|
|
Details.tabela_vigente = Details.combate:NovaTabela (true, Details.tabela_overall, n_combate, ...) --cria uma nova tabela de combate
|
|
|
|
--> flag this combat as being created
|
|
Details.tabela_vigente.IsBeingCreated = true
|
|
|
|
Details.tabela_vigente.previous_combat = ultimo_combate
|
|
|
|
Details.tabela_vigente:seta_data (Details._detalhes_props.DATA_TYPE_START) --seta na tabela do combate a data do inicio do combate -- setup time data
|
|
Details.in_combat = true --sinaliza ao addon que h� um combate em andamento -- in combat flag up
|
|
Details.tabela_vigente.combat_id = n_combate --> grava o n�mero deste combate na tabela atual -- setup combat id on new table
|
|
Details.last_combat_pre_pot_used = nil
|
|
|
|
Details:FlagCurrentCombat()
|
|
|
|
--> � o timer que ve se o jogador ta em combate ou n�o -- check if any party or raid members are in combat
|
|
Details.tabela_vigente.verifica_combate = Details:ScheduleRepeatingTimer ("EstaEmCombate", 1)
|
|
|
|
Details:ClearCCPetsBlackList()
|
|
|
|
_table_wipe (Details.encounter_end_table)
|
|
|
|
_table_wipe (Details.pets_ignored)
|
|
_table_wipe (Details.pets_no_owner)
|
|
Details.container_pets:BuscarPets()
|
|
|
|
_table_wipe (Details.cache_damage_group)
|
|
_table_wipe (Details.cache_healing_group)
|
|
Details:UpdateParserGears()
|
|
|
|
--> get all buff already applied before the combat start
|
|
Details:CatchRaidBuffUptime ("BUFF_UPTIME_IN")
|
|
Details:CatchRaidDebuffUptime ("DEBUFF_UPTIME_IN")
|
|
Details:UptadeRaidMembersCache()
|
|
|
|
--> we already have boss information? build .is_boss table
|
|
if (Details.encounter_table.id and Details.encounter_table ["start"] >= GetTime() - 3 and not Details.encounter_table ["end"]) then
|
|
local encounter_table = Details.encounter_table
|
|
--> boss_found will trigger "COMBAT_BOSS_FOUND" event, but at this point of the combat creation is safe to send it
|
|
boss_found (encounter_table.index, encounter_table.name, encounter_table.zone, encounter_table.mapid, encounter_table.diff, encounter_table.id)
|
|
else
|
|
--> if we don't have this infor right now, lets check in few seconds dop
|
|
if (Details.EncounterInformation [Details.zone_id]) then
|
|
Details:ScheduleTimer ("ReadBossFrames", 1)
|
|
Details:ScheduleTimer ("ReadBossFrames", 30)
|
|
end
|
|
end
|
|
|
|
--> if the window is showing current segment, switch it for the new combat
|
|
--> also if the window has auto current, jump to current segment
|
|
Details:InstanciaCallFunction (Details.TrocaSegmentoAtual, Details.tabela_vigente.is_boss and true)
|
|
|
|
--> clear hosts and make the cloud capture stuff
|
|
Details.host_of = nil
|
|
Details.host_by = nil
|
|
|
|
if (Details.in_group and Details.cloud_capture) then
|
|
if (Details:IsInInstance() or Details.debug) then
|
|
if (not Details:CaptureIsAllEnabled()) then
|
|
Details:ScheduleSendCloudRequest()
|
|
--if (Details.debug) then
|
|
-- Details:Msg ("(debug) requesting a cloud server.")
|
|
--end
|
|
end
|
|
else
|
|
--if (Details.debug) then
|
|
-- Details:Msg ("(debug) isn't inside a registred instance", Details:IsInInstance())
|
|
--end
|
|
end
|
|
else
|
|
--if (Details.debug) then
|
|
-- Details:Msg ("(debug) isn't in group or cloud is turned off", Details.in_group, Details.cloud_capture)
|
|
--end
|
|
end
|
|
|
|
--> hide / alpha / switch in combat
|
|
for index, instancia in ipairs (Details.tabela_instancias) do
|
|
if (instancia.ativa) then
|
|
instancia:CheckSwitchOnCombatStart (true)
|
|
end
|
|
end
|
|
|
|
Details:InstanceCall (Details.CheckPsUpdate)
|
|
|
|
--> combat creation is completed, remove the flag
|
|
Details.tabela_vigente.IsBeingCreated = nil
|
|
|
|
Details:SendEvent ("COMBAT_PLAYER_ENTER", nil, Details.tabela_vigente, Details.encounter_table and Details.encounter_table.id)
|
|
|
|
if (Details.tabela_vigente.is_boss) then
|
|
--> the encounter was found through encounter_start event
|
|
Details:SendEvent ("COMBAT_BOSS_FOUND", nil, Details.tabela_vigente.is_boss.index, Details.tabela_vigente.is_boss.name)
|
|
end
|
|
|
|
Details:CheckSwitchToCurrent()
|
|
Details:CheckForTextTimeCounter (true)
|
|
|
|
--> stop bar testing if any
|
|
Details:StopTestBarUpdate()
|
|
end
|
|
|
|
function Details:DelayedSyncAlert()
|
|
local lower_instance = Details:GetLowerInstanceNumber()
|
|
if (lower_instance) then
|
|
lower_instance = Details: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
|
|
|
|
function Details:ScheduleSyncPlayerActorData()
|
|
if ((IsInGroup() or IsInRaid()) and (Details.zone_type == "party" or Details.zone_type == "raid")) then
|
|
--> do not sync if in battleground or arena
|
|
Details:SendCharacterData()
|
|
end
|
|
end
|
|
|
|
function Details:EndCombat()
|
|
return Details:SairDoCombate()
|
|
end
|
|
|
|
-- ~end ~leave
|
|
function Details:SairDoCombate (bossKilled, from_encounter_end)
|
|
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) |cFFFFFF00ended a combat|r|cFFFF7700", Details.encounter_table and Details.encounter_table.name or "")
|
|
end
|
|
|
|
--> in case of something somehow someway call to close the same combat a second time.
|
|
if (Details.tabela_vigente == Details.last_closed_combat) then
|
|
return
|
|
end
|
|
Details.last_closed_combat = Details.tabela_vigente
|
|
|
|
--if (Details.statistics) then
|
|
-- for k, v in pairs (Details.statistics) do
|
|
-- print (k, v)
|
|
-- end
|
|
--end
|
|
|
|
Details.leaving_combat = true
|
|
Details.last_combat_time = _tempo
|
|
|
|
Details:CatchRaidBuffUptime ("BUFF_UPTIME_OUT")
|
|
Details:CatchRaidDebuffUptime ("DEBUFF_UPTIME_OUT")
|
|
Details:CloseEnemyDebuffsUptime()
|
|
|
|
--> check if this isn't a boss and try to find a boss in the segment
|
|
if (not Details.tabela_vigente.is_boss) then
|
|
|
|
--> if this is a mythic+ dungeon, do not scan for encounter journal boss names in the actor list
|
|
Details:FindBoss()
|
|
|
|
--> still didn't find the boss
|
|
if (not Details.tabela_vigente.is_boss) then
|
|
local ZoneName, _, DifficultyID, _, _, _, _, ZoneMapID = _GetInstanceInfo()
|
|
local findboss = Details:GetRaidBossFindFunction (ZoneMapID)
|
|
if (findboss) then
|
|
local BossIndex = findboss()
|
|
if (BossIndex) then
|
|
boss_found (BossIndex, Details:GetBossName (ZoneMapID, BossIndex), ZoneName, ZoneMapID, DifficultyID)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (Details.tabela_vigente.bossFunction) then
|
|
Details:CancelTimer (Details.tabela_vigente.bossFunction)
|
|
Details.tabela_vigente.bossFunction = nil
|
|
end
|
|
|
|
--> finaliza a checagem se esta ou n�o no combate -- finish combat check
|
|
if (Details.tabela_vigente.verifica_combate) then
|
|
Details:CancelTimer (Details.tabela_vigente.verifica_combate)
|
|
Details.tabela_vigente.verifica_combate = nil
|
|
end
|
|
|
|
--> lock timers
|
|
Details.tabela_vigente:TravarTempos()
|
|
|
|
--> get waste shields
|
|
if (Details.close_shields) then
|
|
Details:CloseShields (Details.tabela_vigente)
|
|
end
|
|
|
|
--> salva hora, minuto, segundo do fim da luta
|
|
Details.tabela_vigente:seta_data (Details._detalhes_props.DATA_TYPE_END)
|
|
Details.tabela_vigente:seta_tempo_decorrido()
|
|
|
|
--> drop last events table to garbage collector
|
|
Details.tabela_vigente.player_last_events = {}
|
|
|
|
--> flag instance type
|
|
local _, InstanceType = _GetInstanceInfo()
|
|
Details.tabela_vigente.instance_type = InstanceType
|
|
|
|
if (not Details.tabela_vigente.is_boss and from_encounter_end and type (from_encounter_end) == "table") then
|
|
local encounterID, encounterName, difficultyID, raidSize, endStatus = unpack (from_encounter_end)
|
|
if (encounterID) then
|
|
local ZoneName, InstanceType, DifficultyID, DifficultyName, _, _, _, ZoneMapID = GetInstanceInfo()
|
|
|
|
local mapID = C_Map.GetBestMapForUnit ("player")
|
|
|
|
if (not mapID) then
|
|
mapID = 0
|
|
end
|
|
|
|
local ejid = DetailsFramework.EncounterJournal.EJ_GetInstanceForMap (mapID)
|
|
|
|
if (ejid == 0) then
|
|
ejid = Details:GetInstanceEJID()
|
|
end
|
|
local _, boss_index = Details:GetBossEncounterDetailsFromEncounterId (ZoneMapID, encounterID)
|
|
|
|
Details.tabela_vigente.is_boss = {
|
|
index = boss_index or 0,
|
|
name = encounterName,
|
|
encounter = encounterName,
|
|
zone = ZoneName,
|
|
mapid = ZoneMapID,
|
|
diff = DifficultyID,
|
|
diff_string = DifficultyName,
|
|
ej_instance_id = ejid or 0,
|
|
id = encounterID,
|
|
}
|
|
end
|
|
end
|
|
|
|
--> tag as a mythic dungeon segment, can be any type of segment, this tag also avoid the segment to be tagged as trash
|
|
local mythicLevel = C_ChallengeMode and C_ChallengeMode.GetActiveKeystoneInfo()
|
|
if (mythicLevel and mythicLevel >= 2) then
|
|
Details.tabela_vigente.is_mythic_dungeon_segment = true
|
|
Details.tabela_vigente.is_mythic_dungeon_run_id = Details.mythic_dungeon_id
|
|
end
|
|
|
|
--> send item level after a combat if is in raid or party group
|
|
C_Timer.After (1, Details.ScheduleSyncPlayerActorData)
|
|
|
|
--if this segment isn't a boss fight
|
|
if (not Details.tabela_vigente.is_boss) then
|
|
|
|
if (Details.tabela_vigente.is_pvp or Details.tabela_vigente.is_arena) then
|
|
Details:FlagActorsOnPvPCombat()
|
|
end
|
|
|
|
if (Details.tabela_vigente.is_arena) then
|
|
Details.tabela_vigente.enemy = "[" .. ARENA .. "] " .. Details.tabela_vigente.is_arena.name
|
|
end
|
|
|
|
local in_instance = IsInInstance() --> garrison returns party as instance type.
|
|
if ((InstanceType == "party" or InstanceType == "raid") and in_instance) then
|
|
if (InstanceType == "party") then
|
|
if (Details.tabela_vigente.is_mythic_dungeon_segment) then --setted just above
|
|
--is inside a mythic+ dungeon and this is not a boss segment, so tag it as a dungeon mythic+ trash segment
|
|
local zoneName, instanceType, difficultyID, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID, instanceGroupSize = GetInstanceInfo()
|
|
Details.tabela_vigente.is_mythic_dungeon_trash = {
|
|
ZoneName = zoneName,
|
|
MapID = instanceMapID,
|
|
Level = Details.MythicPlus.Level,
|
|
EJID = Details.MythicPlus.ejID,
|
|
}
|
|
else
|
|
--> tag the combat as trash clean up
|
|
Details.tabela_vigente.is_trash = true
|
|
end
|
|
else
|
|
Details.tabela_vigente.is_trash = true
|
|
end
|
|
else
|
|
if (not in_instance) then
|
|
if (Details.world_combat_is_trash) then
|
|
Details.tabela_vigente.is_temporary = true
|
|
end
|
|
end
|
|
end
|
|
|
|
if (not Details.tabela_vigente.enemy) then
|
|
local enemy = Details:FindEnemy()
|
|
|
|
if (enemy and Details.debug) then
|
|
Details:Msg ("(debug) enemy found", enemy)
|
|
end
|
|
|
|
Details.tabela_vigente.enemy = enemy
|
|
end
|
|
|
|
if (Details.debug) then
|
|
-- Details:Msg ("(debug) forcing equalize actors behavior.")
|
|
-- Details:EqualizeActorsSchedule (Details.host_of)
|
|
end
|
|
|
|
--> verifica memoria
|
|
Details:FlagActorsOnCommonFight() --fight_component
|
|
--Details:CheckMemoryAfterCombat() -- 7.2.5 is doing some weird errors even out of combat
|
|
else
|
|
|
|
--this segment is a boss fight
|
|
if (not InCombatLockdown() and not UnitAffectingCombat ("player")) then
|
|
|
|
else
|
|
--Details.schedule_flag_boss_components = true
|
|
end
|
|
|
|
--calling here without checking for combat since the does not ran too long for scripts
|
|
Details:FlagActorsOnBossFight()
|
|
|
|
local boss_id = Details.encounter_table.id
|
|
|
|
if (bossKilled) then
|
|
Details.tabela_vigente.is_boss.killed = true
|
|
|
|
--> add to storage
|
|
if (not InCombatLockdown() and not UnitAffectingCombat ("player") and not Details.logoff_saving_data) then
|
|
local successful, errortext = pcall (Details.Database.StoreEncounter)
|
|
if (not successful) then
|
|
Details:Msg ("error occurred on Details.Database.StoreEncounter():", errortext)
|
|
end
|
|
else
|
|
Details.schedule_store_boss_encounter = true
|
|
end
|
|
|
|
Details:SendEvent ("COMBAT_BOSS_DEFEATED", nil, Details.tabela_vigente)
|
|
|
|
Details:CheckFor_TrashSuppressionOnEncounterEnd()
|
|
else
|
|
Details:SendEvent ("COMBAT_BOSS_WIPE", nil, Details.tabela_vigente)
|
|
|
|
--> add to storage
|
|
if (not InCombatLockdown() and not UnitAffectingCombat ("player") and not Details.logoff_saving_data) then
|
|
local successful, errortext = pcall (Details.Database.StoreWipe)
|
|
if (not successful) then
|
|
Details:Msg ("error occurred on Details.Database.StoreWipe():", errortext)
|
|
end
|
|
else
|
|
Details.schedule_store_boss_encounter_wipe = true
|
|
end
|
|
|
|
end
|
|
|
|
--if (Details:GetBossDetails (Details.tabela_vigente.is_boss.mapid, Details.tabela_vigente.is_boss.index) or ) then
|
|
|
|
Details.tabela_vigente.is_boss.index = Details.tabela_vigente.is_boss.index or 1
|
|
|
|
Details.tabela_vigente.enemy = Details.tabela_vigente.is_boss.encounter
|
|
|
|
if (Details.tabela_vigente.instance_type == "raid") then
|
|
|
|
Details.last_encounter2 = Details.last_encounter
|
|
Details.last_encounter = Details.tabela_vigente.is_boss.name
|
|
|
|
if (Details.pre_pot_used) then
|
|
Details.last_combat_pre_pot_used = Details.CopyTable (Details.pre_pot_used)
|
|
end
|
|
|
|
if (Details.pre_pot_used and Details.announce_prepots.enabled) then
|
|
Details:Msg (Details.pre_pot_used or "")
|
|
Details.pre_pot_used = nil
|
|
end
|
|
end
|
|
|
|
if (from_encounter_end) then
|
|
if (Details.encounter_table.start) then
|
|
Details.tabela_vigente:SetStartTime (Details.encounter_table.start)
|
|
end
|
|
Details.tabela_vigente:SetEndTime (Details.encounter_table ["end"] or GetTime())
|
|
end
|
|
|
|
--> encounter boss function
|
|
local bossFunction, bossFunctionType = Details:GetBossFunction (Details.tabela_vigente.is_boss.mapid or 0, Details.tabela_vigente.is_boss.index or 0)
|
|
if (bossFunction) then
|
|
if (_bit_band (bossFunctionType, 0x2) ~= 0) then --end of combat
|
|
if (not Details.logoff_saving_data) then
|
|
local successful, errortext = pcall (bossFunction, Details.tabela_vigente)
|
|
if (not successful) then
|
|
Details:Msg ("error occurred on Encounter Boss Function:", errortext)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (Details.tabela_vigente.instance_type == "raid") then
|
|
--> schedule captures off
|
|
|
|
Details:CaptureSet (false, "damage", false, 15)
|
|
Details:CaptureSet (false, "energy", false, 15)
|
|
Details:CaptureSet (false, "aura", false, 15)
|
|
Details:CaptureSet (false, "energy", false, 15)
|
|
Details:CaptureSet (false, "spellcast", false, 15)
|
|
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) freezing parser for 15 seconds.")
|
|
end
|
|
end
|
|
|
|
--> schedule sync
|
|
Details:EqualizeActorsSchedule (Details.host_of)
|
|
if (Details:GetEncounterEqualize (Details.tabela_vigente.is_boss.mapid, Details.tabela_vigente.is_boss.index)) then
|
|
Details:ScheduleTimer ("DelayedSyncAlert", 3)
|
|
end
|
|
|
|
--else
|
|
-- if (Details.debug) then
|
|
-- Details:EqualizeActorsSchedule (Details.host_of)
|
|
-- end
|
|
--end
|
|
end
|
|
|
|
if (Details.solo) then
|
|
--> debuffs need a checkup, not well functional right now
|
|
Details.CloseSoloDebuffs()
|
|
end
|
|
|
|
local tempo_do_combate = Details.tabela_vigente:GetCombatTime()
|
|
local invalid_combat
|
|
|
|
local zoneName, zoneType = GetInstanceInfo()
|
|
if (not Details.tabela_vigente.discard_segment and (zoneType == "none" or tempo_do_combate >= Details.minimum_combat_time or not Details.tabela_historico.tabelas[1])) then
|
|
Details.tabela_historico:adicionar (Details.tabela_vigente) --move a tabela atual para dentro do hist�rico
|
|
--8.0.1 miss data isn't required at the moment, spells like akari's soul has been removed from the game
|
|
--Details:CanSendMissData()
|
|
|
|
if (Details.tabela_vigente.is_boss) then
|
|
if (IsInRaid()) then
|
|
local cleuID = Details.tabela_vigente.is_boss.id
|
|
local diff = Details.tabela_vigente.is_boss.diff
|
|
if (cleuID and diff == 16) then -- 16 mythic
|
|
local raidData = Details.raid_data
|
|
|
|
--get or build mythic raid data table
|
|
local mythicRaidData = raidData.mythic_raid_data
|
|
if (not mythicRaidData) then
|
|
mythicRaidData = {}
|
|
raidData.mythic_raid_data = mythicRaidData
|
|
end
|
|
|
|
--get or build a table for this cleuID
|
|
mythicRaidData [cleuID] = mythicRaidData [cleuID] or {wipes = 0, kills = 0, best_try = 1, longest = 0, try_history = {}}
|
|
local cleuIDData = mythicRaidData [cleuID]
|
|
|
|
--store encounter data for plugins and weakauras
|
|
if (Details.tabela_vigente:GetCombatTime() > cleuIDData.longest) then
|
|
cleuIDData.longest = Details.tabela_vigente:GetCombatTime()
|
|
end
|
|
|
|
if (Details.tabela_vigente.is_boss.killed) then
|
|
cleuIDData.kills = cleuIDData.kills + 1
|
|
cleuIDData.best_try = 0
|
|
tinsert (cleuIDData.try_history, {0, Details.tabela_vigente:GetCombatTime()})
|
|
--print ("KILL", "best try", cleuIDData.best_try, "amt kills", cleuIDData.kills, "wipes", cleuIDData.wipes, "longest", cleuIDData.longest)
|
|
else
|
|
cleuIDData.wipes = cleuIDData.wipes + 1
|
|
if (Details.boss1_health_percent and Details.boss1_health_percent < cleuIDData.best_try) then
|
|
cleuIDData.best_try = Details.boss1_health_percent
|
|
tinsert (cleuIDData.try_history, {Details.boss1_health_percent, Details.tabela_vigente:GetCombatTime()})
|
|
end
|
|
--print ("WIPE", "best try", cleuIDData.best_try, "amt kills", cleuIDData.kills, "wipes", cleuIDData.wipes, "longest", cleuIDData.longest)
|
|
end
|
|
end
|
|
end
|
|
--
|
|
end
|
|
|
|
--the combat is valid, see if the user is sharing data with somebody
|
|
if (Details.shareData) then
|
|
local zipData = Details:CompressData (Details.tabela_vigente, "comm")
|
|
if (zipData) then
|
|
print ("has zip data")
|
|
end
|
|
end
|
|
|
|
else
|
|
invalid_combat = Details.tabela_vigente
|
|
|
|
--> tutorial about the combat time < then 'minimum_combat_time'
|
|
local hasSeenTutorial = Details:GetTutorialCVar ("MIN_COMBAT_TIME")
|
|
if (not hasSeenTutorial) then
|
|
local lower_instance = Details:GetLowerInstanceNumber()
|
|
if (lower_instance) then
|
|
lower_instance = Details:GetInstance (lower_instance)
|
|
if (lower_instance) then
|
|
lower_instance:InstanceAlert ("combat ignored: less than 5 seconds.", {[[Interface\BUTTONS\UI-GROUPLOOT-PASS-DOWN]], 18, 18, false, 0, 1, 0, 1}, 20, {function() Details:Msg ("combat ignored: elapsed time less than 5 seconds."); Details:Msg ("add '|cFFFFFF00Details.minimum_combat_time = 2;|r' on Auto Run Code to change the minimum time.") end})
|
|
Details:SetTutorialCVar ("MIN_COMBAT_TIME", true)
|
|
end
|
|
end
|
|
end
|
|
|
|
--in case of a forced discard segment, just check a second time if we have a previous combat.
|
|
if (not Details.tabela_historico.tabelas[1]) then
|
|
Details.tabela_vigente = Details.tabela_vigente
|
|
else
|
|
Details.tabela_vigente = Details.tabela_historico.tabelas[1] --> pega a tabela do ultimo combate
|
|
end
|
|
|
|
if (Details.tabela_vigente:GetStartTime() == 0) then
|
|
--Details.tabela_vigente.start_time = Details._tempo
|
|
Details.tabela_vigente:SetStartTime (_GetTime())
|
|
--Details.tabela_vigente.end_time = Details._tempo
|
|
Details.tabela_vigente:SetEndTime (_GetTime())
|
|
end
|
|
|
|
Details.tabela_vigente.resincked = true
|
|
|
|
--> tabela foi descartada, precisa atualizar os baseframes // precisa atualizer todos ou apenas o overall?
|
|
Details:InstanciaCallFunction (Details.AtualizarJanela)
|
|
|
|
if (Details.solo) then
|
|
local esta_instancia = Details.tabela_instancias[Details.solo]
|
|
if (Details.SoloTables.CombatID == Details:NumeroCombate()) then --> significa que o solo mode validou o combate, como matar um bixo muito low level com uma s� porrada
|
|
if (Details.SoloTables.CombatIDLast and Details.SoloTables.CombatIDLast ~= 0) then --> volta os dados da luta anterior
|
|
|
|
Details.SoloTables.CombatID = Details.SoloTables.CombatIDLast
|
|
|
|
else
|
|
if (Details.RefreshSolo) then
|
|
Details:RefreshSolo()
|
|
end
|
|
Details.SoloTables.CombatID = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
Details:NumeroCombate (-1)
|
|
end
|
|
|
|
Details.host_of = nil
|
|
Details.host_by = nil
|
|
|
|
if (Details.cloud_process) then
|
|
Details:CancelTimer (Details.cloud_process)
|
|
end
|
|
|
|
Details.in_combat = false
|
|
Details.leaving_combat = false
|
|
|
|
Details:OnCombatPhaseChanged()
|
|
_table_wipe (Details.tabela_vigente.PhaseData.damage_section)
|
|
_table_wipe (Details.tabela_vigente.PhaseData.heal_section)
|
|
|
|
_table_wipe (Details.cache_damage_group)
|
|
_table_wipe (Details.cache_healing_group)
|
|
|
|
Details:UpdateParserGears()
|
|
|
|
--> hide / alpha in combat
|
|
for index, instancia in ipairs (Details.tabela_instancias) do
|
|
if (instancia.ativa) then
|
|
if (instancia.auto_switch_to_old) then
|
|
instancia:CheckSwitchOnCombatEnd()
|
|
end
|
|
end
|
|
end
|
|
|
|
Details.pre_pot_used = nil
|
|
|
|
--> do not wipe the encounter table if is in the argus encounter ~REMOVE on 8.0
|
|
if (Details.encounter_table and Details.encounter_table.id ~= 2092) then
|
|
_table_wipe (Details.encounter_table)
|
|
else
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) in argus encounter, cannot wipe the encounter table.")
|
|
end
|
|
end
|
|
|
|
Details:InstanceCall (Details.CheckPsUpdate)
|
|
|
|
if (invalid_combat) then
|
|
Details:SendEvent ("COMBAT_INVALID")
|
|
Details:SendEvent ("COMBAT_PLAYER_LEAVE", nil, invalid_combat)
|
|
else
|
|
Details:SendEvent ("COMBAT_PLAYER_LEAVE", nil, Details.tabela_vigente)
|
|
end
|
|
|
|
Details:CheckForTextTimeCounter()
|
|
Details.StoreSpells()
|
|
Details:RunScheduledEventsAfterCombat()
|
|
end
|
|
|
|
function Details:GetPlayersInArena()
|
|
local aliados = GetNumGroupMembers() -- LE_PARTY_CATEGORY_HOME
|
|
for i = 1, aliados-1 do
|
|
local role = UnitGroupRolesAssigned and UnitGroupRolesAssigned("party" .. i) or "DAMAGER"
|
|
if (role ~= "NONE" and UnitExists("party" .. i)) then
|
|
local name = GetUnitName ("party" .. i, true)
|
|
Details.arena_table [name] = {role = role}
|
|
end
|
|
end
|
|
|
|
local role = UnitGroupRolesAssigned and UnitGroupRolesAssigned("player") or "DAMAGER"
|
|
if (role ~= "NONE") then
|
|
local name = GetUnitName ("player", true)
|
|
Details.arena_table [name] = {role = role}
|
|
end
|
|
|
|
--enemies
|
|
local enemiesAmount = GetNumArenaOpponentSpecs and GetNumArenaOpponentSpecs() or 5
|
|
table.wipe(_detalhes.arena_enemies)
|
|
|
|
for i = 1, enemiesAmount do
|
|
local enemyName = _G.GetUnitName("arena" .. i, true)
|
|
if (enemyName) then
|
|
_detalhes.arena_enemies[enemyName] = "arena" .. i
|
|
end
|
|
end
|
|
end
|
|
|
|
--attempt to get the arena unitId for an actor
|
|
function Details:GuessArenaEnemyUnitId(unitName)
|
|
for i = 1, 5 do
|
|
local unitId = "arena" .. i
|
|
local enemyName = _G.GetUnitName(unitId, true)
|
|
if (enemyName == unitName) then
|
|
_detalhes.arena_enemies[enemyName] = unitId
|
|
return unitId
|
|
end
|
|
end
|
|
end
|
|
|
|
local string_arena_enemyteam_damage = [[
|
|
local combat = Details:GetCombat ("current")
|
|
local total = 0
|
|
|
|
for _, actor in combat[1]:ListActors() do
|
|
if (actor.arena_enemy) then
|
|
total = total + actor.total
|
|
end
|
|
end
|
|
|
|
return total
|
|
]]
|
|
|
|
local string_arena_myteam_damage = [[
|
|
local combat = Details:GetCombat ("current")
|
|
local total = 0
|
|
|
|
for _, actor in combat[1]:ListActors() do
|
|
if (actor.arena_ally) then
|
|
total = total + actor.total
|
|
end
|
|
end
|
|
|
|
return total
|
|
]]
|
|
|
|
local string_arena_enemyteam_heal = [[
|
|
local combat = Details:GetCombat ("current")
|
|
local total = 0
|
|
|
|
for _, actor in combat[2]:ListActors() do
|
|
if (actor.arena_enemy) then
|
|
total = total + actor.total
|
|
end
|
|
end
|
|
|
|
return total
|
|
]]
|
|
|
|
local string_arena_myteam_heal = [[
|
|
local combat = Details:GetCombat ("current")
|
|
local total = 0
|
|
|
|
for _, actor in combat[2]:ListActors() do
|
|
if (actor.arena_ally) then
|
|
total = total + actor.total
|
|
end
|
|
end
|
|
|
|
return total
|
|
]]
|
|
|
|
function Details:CreateArenaSegment()
|
|
Details:GetPlayersInArena()
|
|
|
|
Details.arena_begun = true
|
|
Details.start_arena = nil
|
|
|
|
if (Details.in_combat) then
|
|
Details:SairDoCombate()
|
|
end
|
|
|
|
--> registra os gr�ficos
|
|
Details:TimeDataRegister ("Your Team Damage", string_arena_myteam_damage, nil, "Details!", "v1.0", [[Interface\ICONS\Ability_DualWield]], true, true)
|
|
Details:TimeDataRegister ("Enemy Team Damage", string_arena_enemyteam_damage, nil, "Details!", "v1.0", [[Interface\ICONS\Ability_DualWield]], true, true)
|
|
|
|
Details:TimeDataRegister ("Your Team Healing", string_arena_myteam_heal, nil, "Details!", "v1.0", [[Interface\ICONS\Ability_DualWield]], true, true)
|
|
Details:TimeDataRegister ("Enemy Team Healing", string_arena_enemyteam_heal, nil, "Details!", "v1.0", [[Interface\ICONS\Ability_DualWield]], true, true)
|
|
|
|
--> inicia um novo combate
|
|
Details:EntrarEmCombate()
|
|
|
|
--> sinaliza que esse combate � arena
|
|
Details.tabela_vigente.arena = true
|
|
Details.tabela_vigente.is_arena = {name = Details.zone_name, zone = Details.zone_name, mapid = Details.zone_id}
|
|
|
|
Details:SendEvent("COMBAT_ARENA_START")
|
|
end
|
|
|
|
function Details:StartArenaSegment(...)
|
|
if (Details.debug) then
|
|
Details:Msg("(debug) starting a new arena segment.")
|
|
end
|
|
|
|
local _, timeSeconds = select(1, ...)
|
|
|
|
if (Details.start_arena) then
|
|
Details:CancelTimer(Details.start_arena, true)
|
|
end
|
|
Details.start_arena = Details:ScheduleTimer("CreateArenaSegment", timeSeconds)
|
|
Details:GetPlayersInArena()
|
|
end
|
|
|
|
function Details:EnteredInArena()
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) the player EnteredInArena().")
|
|
end
|
|
|
|
Details.arena_begun = false
|
|
|
|
Details:GetPlayersInArena()
|
|
end
|
|
|
|
function Details:LeftArena()
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) player LeftArena().")
|
|
end
|
|
|
|
Details.is_in_arena = false
|
|
Details.arena_begun = false
|
|
|
|
if (Details.start_arena) then
|
|
Details:CancelTimer (Details.start_arena, true)
|
|
end
|
|
|
|
Details:TimeDataUnregister ("Your Team Damage")
|
|
Details:TimeDataUnregister ("Enemy Team Damage")
|
|
|
|
Details:TimeDataUnregister ("Your Team Healing")
|
|
Details:TimeDataUnregister ("Enemy Team Healing")
|
|
|
|
Details:SendEvent ("COMBAT_ARENA_END")
|
|
end
|
|
|
|
local validSpells = {
|
|
[220893] = {class = "ROGUE", spec = 261, maxPercent = 0.075, container = 1, commID = "MISSDATA_ROGUE_SOULRIP"},
|
|
--[11366] = {class = "MAGE", spec = 63, maxPercent = 0.9, container = 1, commID = "MISSDATA_ROGUE_SOULRIP"},
|
|
}
|
|
|
|
function Details:CanSendMissData()
|
|
if (not IsInRaid() and not IsInGroup()) then
|
|
return
|
|
end
|
|
local _, playerClass = UnitClass ("player")
|
|
local specIndex = DetailsFramework.GetSpecialization()
|
|
local playerSpecID
|
|
if (specIndex) then
|
|
playerSpecID = DetailsFramework.GetSpecializationInfo (specIndex)
|
|
end
|
|
|
|
if (playerSpecID and playerClass) then
|
|
for spellID, t in pairs (validSpells) do
|
|
if (playerClass == t.class and playerSpecID == t.spec) then
|
|
Details:SendMissData (spellID, t.container, Details.network.ids [t.commID])
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function Details:SendMissData (spellID, containerType, commID)
|
|
local combat = Details.tabela_vigente
|
|
if (combat) then
|
|
local damageActor = combat (containerType, Details.playername)
|
|
if (damageActor) then
|
|
local spell = damageActor.spells:GetSpell (spellID)
|
|
if (spell) then
|
|
local data = {
|
|
[1] = containerType,
|
|
[2] = spellID,
|
|
[3] = spell.total,
|
|
[4] = spell.counter
|
|
}
|
|
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) sending miss data packet:", spellID, containerType, commID)
|
|
end
|
|
|
|
Details:SendRaidOrPartyData (commID, data)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Details.HandleMissData (playerName, data)
|
|
local combat = Details.tabela_vigente
|
|
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) miss data received from:", playerName, "spellID:", data [2], data [3], data [4])
|
|
end
|
|
|
|
if (combat) then
|
|
local containerType = data[1]
|
|
if (type (containerType) ~= "number" or containerType < 1 or containerType > 4) then
|
|
return
|
|
end
|
|
|
|
local damageActor = combat (containerType, playerName)
|
|
if (damageActor) then
|
|
local spellID = data[2] --a spellID has been passed?
|
|
if (not spellID or type (spellID) ~= "number") then
|
|
return
|
|
end
|
|
|
|
local validateSpell = validSpells [spellID]
|
|
if (not validateSpell) then --is a valid spell?
|
|
return
|
|
end
|
|
|
|
--does the target player fit in the spell requirement on OUR end?
|
|
local class, spec, maxPercent = validateSpell.class, validateSpell.spec, validateSpell.maxPercent
|
|
if (class ~= damageActor.classe or spec ~= damageActor.spec) then
|
|
return
|
|
end
|
|
|
|
local total, counter = data[3], data[4]
|
|
if (type (total) ~= "number" or type (counter) ~= "number") then
|
|
return
|
|
end
|
|
|
|
if (total > (damageActor.total * maxPercent)) then
|
|
return
|
|
end
|
|
|
|
local spellObject = damageActor.spells:PegaHabilidade (spellID, true)
|
|
if (spellObject) then
|
|
if (spellObject.total < total and total > 0 and damageActor.nome ~= Details.playername) then
|
|
local difference = total - spellObject.total
|
|
if (difference > 0) then
|
|
spellObject.total = total
|
|
spellObject.counter = counter
|
|
damageActor.total = damageActor.total + difference
|
|
|
|
combat [containerType].need_refresh = true
|
|
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) miss data successful added from:", playerName, data [2], "difference:", difference)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Details:MakeEqualizeOnActor (player, realm, receivedActor)
|
|
|
|
if (true) then --> disabled for testing
|
|
return
|
|
end
|
|
|
|
local combat = Details:GetCombat ("current")
|
|
local damage, heal, energy, misc = Details:GetAllActors ("current", player)
|
|
|
|
if (not damage and not heal and not energy and not misc) then
|
|
|
|
--> try adding server name
|
|
damage, heal, energy, misc = Details: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 = Details: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 (Details.debug) then
|
|
Details:Msg ("(debug) equalize received actor:", actorName, damage, heal)
|
|
end
|
|
else
|
|
if (Details.debug) then
|
|
Details: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 (Details.debug) then
|
|
Details: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 Details:EqualizePets()
|
|
--> check for pets without owner
|
|
for _, actor in ipairs (Details.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 Details.tabela_pets.pets [actor.serial]) then
|
|
Details:SendPetOwnerRequest (actor.serial, actor.nome)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Details:EqualizeActorsSchedule (host_of)
|
|
|
|
--> store pets sent through 'needpetowner'
|
|
Details.sent_pets = Details.sent_pets or {n = time()}
|
|
if (Details.sent_pets.n+20 < time()) then
|
|
_table_wipe (Details.sent_pets)
|
|
Details.sent_pets.n = time()
|
|
end
|
|
|
|
--> pet equilize disabled on details 1.4.0
|
|
--Details:ScheduleTimer ("EqualizePets", 1+math.random())
|
|
|
|
--> do not equilize if there is any disabled capture
|
|
--if (Details:CaptureIsAllEnabled()) then
|
|
Details:ScheduleTimer ("EqualizeActors", 2+math.random()+math.random() , host_of)
|
|
--end
|
|
end
|
|
|
|
function Details:EqualizeActors (host_of)
|
|
|
|
--> Disabling the sync. Since WoD combatlog are sent between player on phased zones during encounters.
|
|
if (not host_of or true) then --> full disabled for testing
|
|
return
|
|
end
|
|
|
|
if (Details.debug) then
|
|
Details:Msg ("(debug) sending equilize actor data")
|
|
end
|
|
|
|
local damage, heal, energy, misc
|
|
|
|
if (host_of) then
|
|
damage, heal, energy, misc = Details:GetAllActors ("current", host_of)
|
|
else
|
|
damage, heal, energy, misc = Details:GetAllActors ("current", Details.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
|
|
Details:SendRaidDataAs (Details.network.ids.CLOUD_EQUALIZE, host_of, nil, data)
|
|
Details:EqualizeActors()
|
|
else
|
|
Details:SendRaidData (Details.network.ids.CLOUD_EQUALIZE, data)
|
|
end
|
|
|
|
end
|
|
|
|
function Details:FlagActorsOnPvPCombat()
|
|
for class_type, container in ipairs (Details.tabela_vigente) do
|
|
for _, actor in ipairs (container._ActorTable) do
|
|
actor.pvp_component = true
|
|
end
|
|
end
|
|
end
|
|
|
|
function Details:FlagActorsOnBossFight()
|
|
for class_type, container in ipairs (Details.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 Details:FlagActorsOnCommonFight()
|
|
|
|
local damage_container = Details.tabela_vigente [1]
|
|
local healing_container = Details.tabela_vigente [2]
|
|
local energy_container = Details.tabela_vigente [3]
|
|
local misc_container = Details.tabela_vigente [4]
|
|
|
|
local mythicDungeonRun = Details.tabela_vigente.is_mythic_dungeon_segment
|
|
|
|
for class_type, container in ipairs ({damage_container, healing_container}) do
|
|
|
|
for _, actor in ipairs (container._ActorTable) do
|
|
|
|
if (mythicDungeonRun) then
|
|
actor.fight_component = true
|
|
end
|
|
|
|
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 Details: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 Details:PostponeInstanceToCurrent (instance)
|
|
if (
|
|
not instance.last_interaction or
|
|
(
|
|
(instance.ativa) and
|
|
(instance.last_interaction+3 < _tempo) and
|
|
(not DetailsReportWindow or not DetailsReportWindow:IsShown()) and
|
|
(not Details.playerDetailWindow:IsShown())
|
|
)
|
|
) then
|
|
instance._postponing_current = nil
|
|
if (instance.segmento == 0) then
|
|
return Details:TrocaSegmentoAtual (instance)
|
|
else
|
|
return
|
|
end
|
|
end
|
|
if (instance.is_interacting and instance.last_interaction < _tempo) then
|
|
instance.last_interaction = _tempo
|
|
end
|
|
instance._postponing_current = Details:ScheduleTimer ("PostponeInstanceToCurrent", 1, instance)
|
|
end
|
|
|
|
function Details:TrocaSegmentoAtual (instancia, is_encounter)
|
|
if (instancia.segmento == 0 and instancia.baseframe and instancia.ativa) then
|
|
|
|
if (not is_encounter) then
|
|
if (instancia.is_interacting) then
|
|
if (not instancia.last_interaction or instancia.last_interaction < _tempo) then
|
|
instancia.last_interaction = _tempo or time()
|
|
end
|
|
end
|
|
|
|
if ((instancia.last_interaction and (instancia.last_interaction+3 > Details._tempo)) or (DetailsReportWindow and DetailsReportWindow:IsShown()) or (Details.playerDetailWindow:IsShown())) then
|
|
--> postpone
|
|
instancia._postponing_current = Details:ScheduleTimer ("PostponeInstanceToCurrent", 1, instancia)
|
|
return
|
|
end
|
|
end
|
|
|
|
--print ("==> Changing the Segment now! - control.lua 1220")
|
|
|
|
instancia.last_interaction = _tempo - 4 --pode setar, completou o ciclo
|
|
instancia._postponing_current = nil
|
|
instancia.showing = Details.tabela_vigente
|
|
instancia:ResetaGump()
|
|
Details.FadeHandler.Fader (instancia, "in", nil, "barras")
|
|
end
|
|
end
|
|
|
|
function Details:SetTrashSuppression (n)
|
|
assert (type (n) == "number", "SetTrashSuppression expects a number on index 1.")
|
|
if (n < 0) then
|
|
n = 0
|
|
end
|
|
Details.instances_suppress_trash = n
|
|
end
|
|
function Details:CheckFor_SuppressedWindowsOnEncounterFound()
|
|
for _, instance in Details:ListInstances() do
|
|
if (instance.ativa and instance.baseframe and (not instance.last_interaction or instance.last_interaction > _tempo) and instance.segmento == 0) then
|
|
Details:TrocaSegmentoAtual (instance, true)
|
|
end
|
|
end
|
|
end
|
|
function Details:CheckFor_EnabledTrashSuppression()
|
|
if (Details.HasTrashSuppression and Details.HasTrashSuppression > _tempo) then
|
|
self.last_interaction = Details.HasTrashSuppression
|
|
end
|
|
end
|
|
function Details:SetTrashSuppressionAfterEncounter()
|
|
Details:InstanceCall ("CheckFor_EnabledTrashSuppression")
|
|
end
|
|
function Details:CheckFor_TrashSuppressionOnEncounterEnd()
|
|
if (Details.instances_suppress_trash > 0) then
|
|
Details.HasTrashSuppression = _tempo + Details.instances_suppress_trash
|
|
--> delaying in 3 seconds for other stuff like auto open windows after combat.
|
|
Details:ScheduleTimer ("SetTrashSuppressionAfterEncounter", 3)
|
|
end
|
|
end
|
|
|
|
--> internal GetCombatId() version
|
|
function Details:NumeroCombate (flag)
|
|
if (flag == 0) then
|
|
Details.combat_id = 0
|
|
elseif (flag) then
|
|
Details.combat_id = Details.combat_id + flag
|
|
end
|
|
return Details.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 Details:AddTooltipReportLineText()
|
|
GameCooltip:AddLine (Loc ["STRING_CLICK_REPORT_LINE1"], Loc ["STRING_CLICK_REPORT_LINE2"])
|
|
GameCooltip:AddStatusBar (100, 1, 0, 0, 0, 0.8)
|
|
end
|
|
|
|
function Details:AddTooltipBackgroundStatusbar (side, value, useSpark)
|
|
Details.tooltip.background [4] = 0.8
|
|
Details.tooltip.icon_size.W = Details.tooltip.line_height
|
|
Details.tooltip.icon_size.H = Details.tooltip.line_height
|
|
|
|
value = value or 100
|
|
|
|
if (not side) then
|
|
local r, g, b, a = unpack (Details.tooltip.background)
|
|
GameCooltip:AddStatusBar (value, 1, r, g, b, a, useSpark, {value = 100, color = {.21, .21, .21, 0.8}, texture = [[Interface\AddOns\Details\images\bar_serenity]]})
|
|
|
|
else
|
|
GameCooltip:AddStatusBar (value, 2, unpack (Details.tooltip.background))
|
|
end
|
|
end
|
|
|
|
function Details:AddTooltipHeaderStatusbar (r, g, b, a)
|
|
local r, g, b, a, statusbarGlow, backgroundBar = unpack (Details.tooltip.header_statusbar)
|
|
GameCooltip:AddStatusBar (100, 1, r, g, b, a, statusbarGlow, backgroundBar, "Skyline")
|
|
end
|
|
|
|
-- /run local a,b=Details.tooltip.header_statusbar,0.3;a[1]=b;a[2]=b;a[3]=b;a[4]=0.8;
|
|
|
|
function Details:AddTooltipSpellHeaderText (headerText, headerColor, amount, iconTexture, L, R, T, B, separator)
|
|
|
|
if (separator and separator == true) then
|
|
GameCooltip:AddLine ("", "", nil, nil, 1, 1, 1, 1, 8)
|
|
|
|
return
|
|
end
|
|
|
|
if (Details.tooltip.show_amount) then
|
|
GameCooltip:AddLine (headerText, "x" .. amount .. "", nil, headerColor, 1, 1, 1, .4, Details.tooltip.fontsize_title)
|
|
else
|
|
GameCooltip:AddLine (headerText, nil, nil, headerColor, nil, Details.tooltip.fontsize_title)
|
|
end
|
|
|
|
if (iconTexture) then
|
|
GameCooltip:AddIcon (iconTexture, 1, 1, 14, 14, L or 0, R or 1, T or 0, B or 1)
|
|
end
|
|
end
|
|
|
|
local bgColor, borderColor = {0, 0, 0, 0.8}, {0, 0, 0, 0} --{0.37, 0.37, 0.37, .75}, {.30, .30, .30, .3}
|
|
|
|
function Details:FormatCooltipForSpells()
|
|
local GameCooltip = GameCooltip
|
|
|
|
GameCooltip:Reset()
|
|
GameCooltip:SetType ("tooltip")
|
|
|
|
GameCooltip:SetOption ("StatusBarTexture", [[Interface\AddOns\Details\images\bar_background]])
|
|
|
|
GameCooltip:SetOption ("TextSize", Details.tooltip.fontsize)
|
|
GameCooltip:SetOption ("TextFont", Details.tooltip.fontface)
|
|
GameCooltip:SetOption ("TextColor", Details.tooltip.fontcolor)
|
|
GameCooltip:SetOption ("TextColorRight", Details.tooltip.fontcolor_right)
|
|
GameCooltip:SetOption ("TextShadow", Details.tooltip.fontshadow and "OUTLINE")
|
|
|
|
GameCooltip:SetOption ("LeftBorderSize", -5)
|
|
GameCooltip:SetOption ("RightBorderSize", 5)
|
|
GameCooltip:SetOption ("RightTextMargin", 0)
|
|
GameCooltip:SetOption ("VerticalOffset", 9)
|
|
GameCooltip:SetOption ("AlignAsBlizzTooltip", true)
|
|
GameCooltip:SetOption ("AlignAsBlizzTooltipFrameHeightOffset", -8)
|
|
GameCooltip:SetOption ("LineHeightSizeOffset", 4)
|
|
GameCooltip:SetOption ("VerticalPadding", -4)
|
|
|
|
GameCooltip:SetBackdrop (1, Details.cooltip_preset2_backdrop, bgColor, borderColor)
|
|
end
|
|
|
|
function Details:BuildInstanceBarTooltip (frame)
|
|
local GameCooltip = GameCooltip
|
|
Details:FormatCooltipForSpells()
|
|
GameCooltip:SetOption ("MinWidth", _math_max (230, self.baseframe:GetWidth()*0.98))
|
|
|
|
local myPoint = Details.tooltip.anchor_point
|
|
local anchorPoint = Details.tooltip.anchor_relative
|
|
local x_Offset = Details.tooltip.anchor_offset[1]
|
|
local y_Offset = Details.tooltip.anchor_offset[2]
|
|
|
|
if (Details.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
|
|
end
|
|
|
|
function Details:MontaTooltip (frame, whichRowLine, keydown)
|
|
|
|
self:BuildInstanceBarTooltip (frame)
|
|
|
|
local GameCooltip = GameCooltip
|
|
|
|
local esta_barra = self.barras [whichRowLine] --> 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 Details:ToolTipDead (self, objeto, esta_barra, keydown) --> inst�ncia, [morte], barra
|
|
elseif (objeto.byspell) then
|
|
return Details:ToolTipBySpell (self, objeto, esta_barra, keydown)
|
|
elseif (objeto.frags) then
|
|
return Details:ToolTipFrags (self, objeto, esta_barra, keydown)
|
|
elseif (objeto.boss_debuff) then
|
|
return Details:ToolTipVoidZones (self, objeto, esta_barra, keydown)
|
|
end
|
|
|
|
local t = objeto:ToolTip (self, whichRowLine, 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 and not Details.ignore_nicktag) 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 Details.ignore_nicktag and avatar [1]) or objeto.nome, textPoint, avatarTextColor, 14, SharedMedia:Fetch ("font", Details.tooltip.fontface)) --> text [1] nickname
|
|
end
|
|
else
|
|
--if (Details.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", Details.tooltip.fontface)) --> text [1] nickname
|
|
--end
|
|
end
|
|
end
|
|
|
|
GameCooltip:ShowCooltip()
|
|
end
|
|
end
|
|
|
|
function Details.gump:UpdateTooltip (whichRowLine, esta_barra, instancia)
|
|
if (_IsShiftKeyDown()) then
|
|
return instancia:MontaTooltip (esta_barra, whichRowLine, "shift")
|
|
elseif (_IsControlKeyDown()) then
|
|
return instancia:MontaTooltip (esta_barra, whichRowLine, "ctrl")
|
|
elseif (_IsAltKeyDown()) then
|
|
return instancia:MontaTooltip (esta_barra, whichRowLine, "alt")
|
|
else
|
|
return instancia:MontaTooltip (esta_barra, whichRowLine)
|
|
end
|
|
end
|
|
|
|
function Details:EndRefresh (instancia, total, combatTable, showing)
|
|
Details:EsconderBarrasNaoUsadas (instancia, showing)
|
|
end
|
|
|
|
function Details: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
|
|
--print ("mostrando", instancia.rows_showing, instancia.rows_created)
|
|
for barra_numero = instancia.rows_showing+1, instancia.rows_created do
|
|
Details.FadeHandler.Fader (instancia.barras[barra_numero], "in")
|
|
end
|
|
instancia.v_barras = false
|
|
|
|
if (instancia.rows_showing == 0 and instancia:GetSegment() == -1) then -- -1 overall data
|
|
if (not instancia:IsShowingOverallDataWarning()) then
|
|
local tutorial = Details:GetTutorialCVar ("OVERALLDATA_WARNING1") or 0
|
|
if ((type (tutorial) == "number") and (tutorial < 60)) then
|
|
Details:SetTutorialCVar ("OVERALLDATA_WARNING1", tutorial + 1)
|
|
instancia:ShowOverallDataWarning (true)
|
|
end
|
|
end
|
|
else
|
|
if (instancia:IsShowingOverallDataWarning()) then
|
|
instancia:ShowOverallDataWarning (false)
|
|
end
|
|
end
|
|
end
|
|
|
|
return showing
|
|
end
|
|
|
|
--> call update functions
|
|
function Details:RefreshAllMainWindows (forcar)
|
|
|
|
local combatTable = self.showing
|
|
|
|
--the the segment does not have a valid combat, freeze the window
|
|
if (not combatTable) then
|
|
if (not self.freezed) then
|
|
return self:Freeze()
|
|
end
|
|
return
|
|
end
|
|
|
|
local need_refresh = combatTable[self.atributo].need_refresh
|
|
if (not need_refresh and not forcar) then
|
|
return --> n�o precisa de refresh
|
|
--else
|
|
--combatTable[self.atributo].need_refresh = false
|
|
end
|
|
|
|
if (self.atributo == 1) then --> damage
|
|
return atributo_damage:RefreshWindow(self, combatTable, forcar, nil, need_refresh)
|
|
|
|
elseif (self.atributo == 2) then --> heal
|
|
return atributo_heal:RefreshWindow(self, combatTable, forcar, nil, need_refresh)
|
|
|
|
elseif (self.atributo == 3) then --> energy
|
|
return atributo_energy:RefreshWindow(self, combatTable, forcar, nil, need_refresh)
|
|
|
|
elseif (self.atributo == 4) then --> outros
|
|
return atributo_misc:RefreshWindow(self, combatTable, forcar, nil, need_refresh)
|
|
|
|
elseif (self.atributo == 5) then --> ocustom
|
|
return atributo_custom:RefreshWindow(self, combatTable, forcar, nil, need_refresh)
|
|
end
|
|
|
|
end
|
|
|
|
function Details:ForceRefresh()
|
|
self:RefreshMainWindow(true)
|
|
end
|
|
|
|
function Details:RefreshMainWindow(instance, forceRefresh)
|
|
if (not instance or type(instance) == "boolean") then
|
|
forceRefresh = instance
|
|
instance = self
|
|
end
|
|
|
|
if (not forceRefresh) then
|
|
Details.LastUpdateTick = Details._tempo
|
|
end
|
|
|
|
if (instance == -1) then
|
|
--update
|
|
for index, instance in ipairs(Details.tabela_instancias) do
|
|
if (instance.ativa) then
|
|
if (instance.modo == modo_GROUP or instance.modo == modo_ALL) then
|
|
instance:RefreshAllMainWindows(forceRefresh)
|
|
--print("all instances got updates")
|
|
end
|
|
end
|
|
end
|
|
|
|
--flag windows as no need update next tick
|
|
for index, instance in ipairs(Details.tabela_instancias) do
|
|
if (instance.ativa and instance.showing) then
|
|
if (instance.modo == modo_GROUP or instance.modo == modo_ALL) then
|
|
if (instance.atributo <= 4) then
|
|
instance.showing [instance.atributo].need_refresh = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (not forceRefresh) then --update player details window if opened
|
|
if (info.ativo) then
|
|
--print("info.jogador:MontaInfo()")
|
|
return info.jogador:MontaInfo()
|
|
end
|
|
end
|
|
|
|
return
|
|
|
|
else
|
|
if (not instance.ativa) then
|
|
--print("instance not actived", instance.RefreshMainWindow, 1+nil)
|
|
return
|
|
end
|
|
end
|
|
|
|
if (instance.modo == modo_ALL or instance.modo == modo_GROUP) then
|
|
--print("updating all instances...")
|
|
return instance:RefreshAllMainWindows (forceRefresh)
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--> core
|
|
|
|
function Details:AutoEraseConfirm()
|
|
|
|
local panel = _G.DetailsEraseDataConfirmation
|
|
if (not panel) then
|
|
panel = CreateFrame("frame", "DetailsEraseDataConfirmation", UIParent, "BackdropTemplate")
|
|
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)
|
|
|
|
DetailsFramework:ApplyStandardBackdrop(panel)
|
|
|
|
panel:SetScript("OnMouseDown", function (self, button)
|
|
if (button == "RightButton") then
|
|
panel:Hide()
|
|
end
|
|
end)
|
|
|
|
--[=[
|
|
create 3 options
|
|
- overall data only
|
|
- current data only
|
|
- both
|
|
|
|
--=]=]
|
|
|
|
local text = Details.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 = Details.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 = Details.gump:CreateButton (panel, function() panel:Hide(); Details.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 Details:CheckForAutoErase (mapid)
|
|
if (Details.last_instance_id ~= mapid) then
|
|
Details.tabela_historico:resetar_overall()
|
|
|
|
if (Details.segments_auto_erase == 2) then
|
|
--ask
|
|
Details:ScheduleTimer ("AutoEraseConfirm", 1)
|
|
elseif (Details.segments_auto_erase == 3) then
|
|
--erase
|
|
Details.tabela_historico:resetar()
|
|
end
|
|
else
|
|
if (_tempo > Details.last_instance_time + 21600) then --6 hours
|
|
if (Details.segments_auto_erase == 2) then
|
|
--ask
|
|
Details:ScheduleTimer ("AutoEraseConfirm", 1)
|
|
elseif (Details.segments_auto_erase == 3) then
|
|
--erase
|
|
Details.tabela_historico:resetar()
|
|
end
|
|
end
|
|
end
|
|
|
|
Details.last_instance_id = mapid
|
|
Details.last_instance_time = _tempo
|
|
--Details.last_instance_time = 0 --debug
|
|
end
|
|
|
|
function Details:UpdateControl()
|
|
_tempo = Details._tempo
|
|
end
|
|
|
|
|