Pet container rewritten

This commit is contained in:
Tercio Jose
2024-06-14 18:30:20 -03:00
committed by andrew6180
parent 85fff228df
commit f6c59381ab
25 changed files with 784 additions and 469 deletions
+15 -1
View File
@@ -201,7 +201,20 @@
---@field spec specializationid
---@class customspellinfo : {name: string, isPassive: boolean, itemId: number, icon: string|number}
---@class customiteminfo: {itemId: number, isPassive: boolean, nameExtra: string?, icon: string|number|nil}
---@class customiteminfo: table
---@field itemId number
---@field isPassive boolean?
---@field nameExtra string?
---@field icon string|number|nil
---@field onUse boolean?
---@field isSummon boolean?
---@field castId spellid?
---@field defaultName string?
---@field aura1 spellid?
---@field aura2 spellid?
---@class savedspelldata : {key1: number, key2: string, key3: number}
---@class alternatepowertable : {last: number, total: number}
@@ -799,6 +812,7 @@
---@class details222 : table
---@field TimeMachine timemachine
---@field PetContainer petcontainer
---@class profile_breakdown_settings : table
---@field font_size number
+1
View File
@@ -5,6 +5,7 @@
---@field reverse fun(tbl:table) : table reverse the order of an array
---@field append fun(tbl1:table, tbl2:table) : table append the array of table2 to table1
---@field duplicate fun(tblReceiving:table, tblGiving:table) : table copy the values from table2 to table1 overwriting existing values, ignores __index and __newindex, keys pointing to a UIObject are preserved
---@field countkeys fun(tbl:table) : number count the keys of a table
---@field copy fun(tblReceiving:table, tblGiving:table) : table copy the values from table2 to table1 overwriting existing values, ignores __index and __newindex, threat UIObjects as regular tables
---@field deploy fun(tblReceiving:table, tblGiving:table) : table copy keys/values that does exist on tblGiving but not in tblReceiving
---@field copytocompress fun(tblReceiving:table, tblGiving:table) : table copy the values from table2 to table1 overwriting existing values, ignores __index, functions and tables with a 'GetObjectType' key
+11
View File
@@ -543,6 +543,17 @@ function DF.table.setfrompath(t, path, value)
return false
end
---return the amount of keys in a table
---@param t table
---@return number
function DF.table.countkeys(t)
local count = 0
for _ in pairs(t) do
count = count + 1
end
return count
end
---find the value inside the table, and it it's not found, add it
---@param t table
---@param index integer|any
+52
View File
@@ -311,6 +311,58 @@ local getSpellListAsHashTableFromSpellBook = function()
end
end
--get class shared spells from the spell book
local tabName, tabTexture, offset, numSpells, isGuild, offspecId = GetSpellTabInfo(CONST_SPELLBOOK_CLASSSPELLS_TABID)
offset = offset + 1
local tabEnd = offset + numSpells
for entryOffset = offset, tabEnd - 1 do
local spellType, spellId = GetSpellBookItemInfo(entryOffset, spellBookPlayerEnum)
if (spellId) then
if (spellType == "SPELL") then
spellId = GetOverrideSpell(spellId)
local spellName = GetSpellInfo(spellId)
local bIsPassive = IsPassiveSpell(spellId, spellBookPlayerEnum)
if LIB_OPEN_RAID_MULTI_OVERRIDE_SPELLS[spellId] then
for _, overrideSpellId in pairs(LIB_OPEN_RAID_MULTI_OVERRIDE_SPELLS[spellId]) do
completeListOfSpells[overrideSpellId] = true
end
elseif (spellName and not bIsPassive) then
completeListOfSpells[spellId] = true
else
if (not spellName) then
--print("no spellname")
--print(GetSpellInfo(spellId))
elseif (bIsPassive) then
--print("is passive")
--print(GetSpellInfo(spellId))
end
end
end
end
end
local getNumPetSpells = function()
--'HasPetSpells' contradicts the name and return the amount of pet spells available instead of a boolean
return HasPetSpells()
end
--get pet spells from the pet spellbook
local numPetSpells = getNumPetSpells()
if (numPetSpells) then
for i = 1, numPetSpells do
local spellName, _, unmaskedSpellId = GetSpellBookItemName(i, spellBookPetEnum)
if (unmaskedSpellId) then
unmaskedSpellId = GetOverrideSpell(unmaskedSpellId)
local bIsPassive = IsPassiveSpell(unmaskedSpellId, spellBookPetEnum)
if (spellName and not bIsPassive) then
completeListOfSpells[unmaskedSpellId] = true
end
end
end
end
return completeListOfSpells
end
+1 -1
View File
@@ -31,7 +31,7 @@ LIB_OPEN_RAID_CAN_LOAD = false
local major = "LibOpenRaid-1.0"
local CONST_LIB_VERSION = 127
local CONST_LIB_VERSION = 128
if (LIB_OPEN_RAID_MAX_VERSION) then
if (CONST_LIB_VERSION <= LIB_OPEN_RAID_MAX_VERSION) then
+97 -114
View File
@@ -23,7 +23,7 @@
Details.dont_open_news = true
Details.game_version = version
Details.userversion = version .. " " .. Details.build_counter
Details.realversion = 156 --core version, this is used to check API version for scripts and plugins (see alias below)
Details.realversion = 158 --core version, this is used to check API version for scripts and plugins (see alias below)
Details.APIVersion = Details.realversion --core version
Details.version = Details.userversion .. " (core " .. Details.realversion .. ")" --simple stirng to show to players
@@ -102,8 +102,20 @@
Details222.DamageSpells = {}
--namespace for texture
Details222.Textures = {}
--namespace for pet
Details222.Pets = {}
Details222.PetContainer = {
---@type table<guid, petdata>
Pets = {},
---@type table<guid, boolean>
IgnoredActors = {},
---table that stores the player guid as keys and their petguid as values
---this is useful to know which pets are the legit class pet from the UNIT_PET event
---@type table<guid, guid>
UnitPetCache = {},
}
--auto run code
Details222.AutoRunCode = {}
--options panel
@@ -133,6 +145,8 @@
Details222.GuessSpecSchedules = {
Schedules = {},
}
Details222.Profiling = {}
Details222.ProfilingCache = {}
Details222.TimeMachine = {}
Details222.OnUseItem = {Trinkets = {}}
@@ -452,7 +466,6 @@ do
"- 'ClearTempTables' renamed to 'ClearCacheTables'.",
"- 'SpellIsDot' renamed to 'SetAsDotSpell'.",
"- 'FlagCurrentCombat' remamed to 'FlagNewCombat_PVPState'.",
"- 'UpdateContainerCombatentes' renamed to 'UpdatePetCache'.",
"- 'segmentClass:AddCombat(combatObject)' renamed to 'Details222.Combat.AddCombat(combatToBeAdded)'.",
"- 'CurrentCombat.verifica_combate' timer is now obsolete.",
"- 'Details.last_closed_combat' is now obsolete.",
@@ -617,7 +630,6 @@ do
--ignored pets
_detalhes.pets_ignored = {}
_detalhes.pets_no_owner = {}
_detalhes.pets_players = {}
--dual candidates
_detalhes.duel_candidates = {}
--armazena as skins disponveis para as janelas
@@ -1401,8 +1413,7 @@ do
_detalhes.tabela_historico = _detalhes.historico:CreateNewSegmentDatabase()
_detalhes.tabela_overall = _detalhes.combate:NovaTabela()
_detalhes.tabela_vigente = _detalhes.combate:NovaTabela (_, _detalhes.tabela_overall)
_detalhes.tabela_pets = _detalhes.container_pets:NovoContainer()
_detalhes:UpdatePetCache()
Details222.PetContainer.Reset()
_detalhes_database.tabela_overall = nil
_detalhes_database.tabela_historico = nil
@@ -1496,120 +1507,35 @@ function Details222.ClassCache.MakeCache()
end
end
Details222.UnitIdCache.Raid = {
[1] = "raid1",
[2] = "raid2",
[3] = "raid3",
[4] = "raid4",
[5] = "raid5",
[6] = "raid6",
[7] = "raid7",
[8] = "raid8",
[9] = "raid9",
[10] = "raid10",
[11] = "raid11",
[12] = "raid12",
[13] = "raid13",
[14] = "raid14",
[15] = "raid15",
[16] = "raid16",
[17] = "raid17",
[18] = "raid18",
[19] = "raid19",
[20] = "raid20",
[21] = "raid21",
[22] = "raid22",
[23] = "raid23",
[24] = "raid24",
[25] = "raid25",
[26] = "raid26",
[27] = "raid27",
[28] = "raid28",
[29] = "raid29",
[30] = "raid30",
[31] = "raid31",
[32] = "raid32",
[33] = "raid33",
[34] = "raid34",
[35] = "raid35",
[36] = "raid36",
[37] = "raid37",
[38] = "raid38",
[39] = "raid39",
[40] = "raid40",
}
Details222.UnitIdCache.Party = {"player"}
Details222.UnitIdCache.PartyPet = {"playetpet"}
for i = 1, 4 do
table.insert(Details222.UnitIdCache.Party, "party" .. i)
table.insert(Details222.UnitIdCache.PartyPet, "partypet" .. i)
end
Details222.UnitIdCache.Party = {
[1] = "party1",
[2] = "party2",
[3] = "party3",
[4] = "party4",
}
Details222.UnitIdCache.Raid = {}
Details222.UnitIdCache.RaidPet = {}
for i = 1, 40 do
Details222.UnitIdCache.Raid[i] = "raid" .. i
Details222.UnitIdCache.RaidPet[i] = "raidpet" .. i
end
Details222.UnitIdCache.PartyIds = {"player", "party1", "party2", "party3", "party4"}
Details222.UnitIdCache.Boss = {}
for i = 1, 9 do
Details222.UnitIdCache.Boss[i] = "boss" .. i
end
Details222.UnitIdCache.Boss = {
[1] = "boss1",
[2] = "boss2",
[3] = "boss3",
[4] = "boss4",
[5] = "boss5",
[6] = "boss6",
[7] = "boss7",
[8] = "boss8",
[9] = "boss9",
}
Details222.UnitIdCache.Nameplate = {}
for i = 1, 40 do
Details222.UnitIdCache.Nameplate[i] = "nameplate" .. i
end
Details222.UnitIdCache.Nameplate = {
[1] = "nameplate1",
[2] = "nameplate2",
[3] = "nameplate3",
[4] = "nameplate4",
[5] = "nameplate5",
[6] = "nameplate6",
[7] = "nameplate7",
[8] = "nameplate8",
[9] = "nameplate9",
[10] = "nameplate10",
[11] = "nameplate11",
[12] = "nameplate12",
[13] = "nameplate13",
[14] = "nameplate14",
[15] = "nameplate15",
[16] = "nameplate16",
[17] = "nameplate17",
[18] = "nameplate18",
[19] = "nameplate19",
[20] = "nameplate20",
[21] = "nameplate21",
[22] = "nameplate22",
[23] = "nameplate23",
[24] = "nameplate24",
[25] = "nameplate25",
[26] = "nameplate26",
[27] = "nameplate27",
[28] = "nameplate28",
[29] = "nameplate29",
[30] = "nameplate30",
[31] = "nameplate31",
[32] = "nameplate32",
[33] = "nameplate33",
[34] = "nameplate34",
[35] = "nameplate35",
[36] = "nameplate36",
[37] = "nameplate37",
[38] = "nameplate38",
[39] = "nameplate39",
[40] = "nameplate40",
}
Details222.UnitIdCache.Arena = {}
for i = 1, 5 do
Details222.UnitIdCache.Arena[i] = "arena" .. i
end
Details222.UnitIdCache.Arena = {
[1] = "arena1",
[2] = "arena2",
[3] = "arena3",
[4] = "arena4",
[5] = "arena5",
}
function Details222.Tables.MakeWeakTable(mode)
local newTable = {}
@@ -1640,6 +1566,63 @@ function Details222.PlayerStats:SetStat(statName, value)
Details.player_stats[statName] = value
end
local profileStartFunc = function(functionName)
local profile = Details222.ProfilingCache[functionName]
if (not profile) then
Details222.ProfilingCache[functionName] = {elapsed = 0, startTime = 0, runs = 0}
profile = Details222.ProfilingCache[functionName]
end
profile.startTime = debugprofilestop()
profile.runs = profile.runs + 1
end
local profileStopFunc = function(functionName)
local profile = Details222.ProfilingCache[functionName]
if (profile) then
profile.elapsed = profile.elapsed + debugprofilestop() - profile.startTime
end
end
function Details222.Profiling.ProfileStart()end
function Details222.Profiling.ProfileStop()end
function Details222.Profiling.EnableProfiler()
Details222.Profiling.ProfileStart = profileStartFunc
Details222.Profiling.ProfileStop = profileStopFunc
end
function Details222.Profiling.DisableProfiler()
Details222.Profiling.ProfileStart = function()end
Details222.Profiling.ProfileStop = function()end
end
function Details222.Profiling.ResetProfiler()
table.wipe(Details222.ProfilingCache)
end
if (select(4, GetBuildInfo()) >= 100000) then
Details222.Profiling.EnableProfiler()
end
function Details:ProfilerResult()
local resultTable = {}
local total = 0
for functionName, profile in pairs(Details222.ProfilingCache) do
local runTime = string.format("%.3f", profile.elapsed / 1000)
resultTable[functionName] = runTime .. " ms | runs: " .. profile.runs
total = total + profile.elapsed
end
resultTable["Total"] = string.format("%.3f", total / 1000) .. " ms"
dumpt(resultTable)
end
function Details:ResetProfilerResult()
end
---destroy a table and remove it from the object, if the key isn't passed, the object itself is destroyed
---@param object any
---@param key string|nil
+1 -10
View File
@@ -24,15 +24,9 @@ local _
local addonName, Details222 = ...
local detailsFramework = DetailsFramework
local gump = _detalhes.gump
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
local gump = _detalhes.gump
local container_habilidades = _detalhes.container_habilidades
local container_combatentes = _detalhes.container_combatentes
local container_pets = _detalhes.container_pets
local atributo_energy = _detalhes.atributo_energy
local habilidade_energy = _detalhes.habilidade_energy
local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS
--local modo_ALONE = _detalhes.modos.alone
@@ -41,9 +35,6 @@ local modo_ALL = _detalhes.modos.all
local class_type = _detalhes.atributos.e_energy
local DATA_TYPE_START = _detalhes._detalhes_props.DATA_TYPE_START
local DATA_TYPE_END = _detalhes._detalhes_props.DATA_TYPE_END
local ToKFunctions = _detalhes.ToKFunctions
local SelectedToKFunction = ToKFunctions [1]
local UsingCustomLeftText = false
+45 -58
View File
@@ -13,8 +13,6 @@
local _IsInInstance = IsInInstance --api local
local UnitGUID = UnitGUID --api local
local strsplit = strsplit --api local
local setmetatable = setmetatable --lua local
local bitBand = bit.band --lua local
local bitBor = bit.bor --lua local
@@ -27,7 +25,6 @@
local GetNumDeclensionSets = _G.GetNumDeclensionSets
local DeclineName = _G.DeclineName
local pet_tooltip_frame = _G.DetailsPetOwnerFinder
local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true)
@@ -49,22 +46,23 @@
local container_misc = Details.container_type.CONTAINER_MISC_CLASS
local container_enemydebufftarget_target = Details.container_type.CONTAINER_ENEMYDEBUFFTARGET_CLASS
local container_pets = {}
---@type petcontainer
local petContainer = Details222.PetContainer
---@type table<guid, petdata>
local petCache = petContainer.Pets
--flags
local REACTION_HOSTILE = 0x00000040
local IS_GROUP_OBJECT = 0x00000007
local REACTION_FRIENDLY = 0x00000010
local OBJECT_TYPE_MASK = 0x0000FC00
local OBJECT_TYPE_OBJECT = 0x00004000
local OBJECT_TYPE_PET = 0x00001000
local OBJECT_TYPE_GUARDIAN = 0x00002000
local OBJECT_TYPE_CONTROL_NPC = 0x00000200
local OBJECT_TYPE_PETGUARDIAN = OBJECT_TYPE_PET + OBJECT_TYPE_GUARDIAN
local OBJECT_TYPE_NPC = 0x00000800
local OBJECT_TYPE_PLAYER = 0x00000400
local debugPetname = false
local REACTION_HOSTILE = 0x00000040
local IS_GROUP_OBJECT = 0x00000007
local REACTION_FRIENDLY = 0x00000010
local OBJECT_TYPE_MASK = 0x0000FC00
local OBJECT_TYPE_OBJECT = 0x00004000
local OBJECT_TYPE_PETGUARDIAN = 0x00003000
local OBJECT_TYPE_GUARDIAN = 0x00002000
local OBJECT_TYPE_PET = 0x00001000
local OBJECT_TYPE_NPC = 0x00000800
local OBJECT_TYPE_PLAYER = 0x00000400
local OBJECT_TYPE_PETS = OBJECT_TYPE_PET + OBJECT_TYPE_GUARDIAN
local SPELLID_SANGUINE_HEAL = 226510
local sanguineActorName = Details222.GetSpellInfo(SPELLID_SANGUINE_HEAL)
@@ -179,27 +177,28 @@ end
---@return string|nil ownerName
---@return string|nil ownerGUID
---@return integer|nil ownerFlags
function Details222.Pets.GetPetOwner(petGUID, petName)
function Details222.Pets.GetPetOwner(petGUID, petName) --this is under the Pets namespace, the new pet system is under the PetContainer namespace
pet_tooltip_frame:SetOwner(WorldFrame, "ANCHOR_NONE")
pet_tooltip_frame:SetHyperlink(("unit:" .. petGUID) or "")
---@type combat
local currentCombat = Details:GetCurrentCombat()
local ownerName, ownerGUID, ownerFlags
if (not Details.tabela_vigente) then return end --Should exist at all times but load. Just in case.
if (not currentCombat) then return end --Should exist at all times but load. Just in case.
for i=1,3 do --Loop through the 3 texts on the PetOwnerFinder tooltip
local actorNameString = _G["DetailsPetOwnerFinderTextLeft"..i]
if (actorNameString and not ownerName) then --Tooltip line exists and we haven't found a valid match yes.
local actorName = actorNameString:GetText()
if (actorName and type(actorName) == "string") then
local isInRaid = Details.tabela_vigente.raid_roster[actorName]
local isInRaid = currentCombat.raid_roster[actorName]
if (isInRaid) then
ownerGUID = UnitGUID(actorName)
ownerName = actorName
ownerFlags = 0x514
else
if (CONST_CLIENT_LANGUAGE == "ruRU") then --If russian client, then test for declensions in the string of text.
for playerName, _ in pairs(Details.tabela_vigente.raid_roster) do
for playerName, _ in pairs(currentCombat.raid_roster) do
local pName = playerName
playerName = playerName:gsub("%-.*", "") --remove realm name
if (find_name_declension(actorName, playerName)) then
@@ -212,7 +211,7 @@ end
else
for playerName in actorName:gmatch("([^%s']+)") do
playerName = playerName:gsub(",", "")
local playerIsOnRaidCache = Details.tabela_vigente.raid_roster[playerName]
local playerIsOnRaidCache = currentCombat.raid_roster[playerName]
if (playerIsOnRaidCache) then
ownerGUID = UnitGUID(playerName)
ownerName = playerName
@@ -552,7 +551,7 @@ end
end
end
--does this actor has an owner?
--does this actor has an owner? (a.k.a. is a pet)
elseif (ownerActorObject) then
actorObject.owner = ownerActorObject
actorObject.ownerName = ownerActorObject.nome
@@ -562,6 +561,9 @@ end
else
actorObject.displayName = actorName
end
local npcId = Details:GetNpcIdFromGuid(actorSerial)
local petCustomname = Details222.Pets.GetPetNameFromCustomSpells(actorObject.displayName, spellId, npcId)
else
--anything else that isn't a player or a pet
actorObject.displayName = actorName
@@ -593,20 +595,21 @@ end
end
end
--pet black list locally for this file
local petBlackList = {}
local petOwnerFound = function(ownerName, petGUID, petName, petFlags, self, ownerGUID, ownerFlags)
local ownerGuid = ownerGUID or UnitGUID(ownerName)
local petOwnerFound = function(ownerName, petGuid, petName, petFlags, self, ownerGuid, ownerFlags)
local ownerGuid = ownerGuid or UnitGUID(ownerName)
if (ownerGuid) then
-- 0xA00 is the flag for NPC controlled, NPC unit. 0x500 is the flag for Player Controlled, Player Unit.
-- Or those together with the last 2 hex bits for reaction/affiliation to 'guess' the correct flags.
if not ownerFlags then
local npcControlled = bitBand(petFlags, 0x200) ~= 0
ownerFlags = bitBor( npcControlled and 0xA00 or 0x500, bitBand(petFlags, 0xFF))
ownerFlags = bitBor(npcControlled and 0xA00 or 0x500, bitBand(petFlags, 0xFF))
end
Details.tabela_pets:AddPet(petGUID, petName, petFlags, ownerGuid, ownerName, ownerFlags)
local petNameWithOwner, ownerName, ownerGUID, ownerFlags = Details.tabela_pets:GetPetOwner(petGUID, petName, petFlags)
petContainer.AddPet(petGuid, petName, petFlags, ownerGuid, ownerName, ownerFlags)
local petNameWithOwner, ownerName, ownerGUID, ownerFlags = petContainer.GetOwner(petGuid, petName)
local petOwnerActorObject
@@ -640,27 +643,29 @@ end
local petOwnerObject
actorSerial = actorSerial or "ns"
if (container_pets[actorSerial]) then --this is a registered pet
local petName, ownerName, ownerGUID, ownerFlag = Details.tabela_pets:GetPetOwner(actorSerial, actorName, actorFlags)
if (petName and ownerName and ownerGUID ~= actorSerial) then
--check if this actor is a pet and the pet is in the pet cache
if (petContainer.IsPetInCache(actorSerial)) then --this is a registered pet
local petName, ownerName, ownerGuid, ownerFlag = petContainer.GetOwner(actorSerial, actorName)
if (petName and ownerName and ownerGuid and ownerGuid ~= actorSerial and ownerFlag) then
actorName = petName
petOwnerObject = self:PegarCombatente(ownerGUID, ownerName, ownerFlag, true)
petOwnerObject = self:PegarCombatente(ownerGuid, ownerName, ownerFlag, true)
end
--this actor isn't in the pet cache
elseif (not petBlackList[actorSerial]) then --check if is a pet
petBlackList[actorSerial] = true
--try to find the owner
if (actorFlags and bitBand(actorFlags, OBJECT_TYPE_PETGUARDIAN) ~= 0) then
local ownerName, ownerGUID, ownerFlags = Details222.Pets.GetPetOwner(actorSerial, actorName)
if (ownerName and ownerGUID) then
--Don't pass ownerFlags just in case the cached owner happens to be an enemy last combat, but ally now.
local newPetName, ownerObject = petOwnerFound(ownerName, actorSerial, actorName, actorFlags, self, ownerGUID)
local ownerName, ownerGuid, ownerFlags = petContainer.GetOwner(actorSerial, actorName)
if (ownerName and ownerGuid) then
--don't pass ownerFlags just in case the cached owner happens to be an enemy from last combat, but ally now.
local newPetName, ownerObject = petOwnerFound(ownerName, actorSerial, actorName, actorFlags, self, ownerGuid)
if (newPetName and ownerObject) then
actorName, petOwnerObject = newPetName, ownerObject
end
end
end
petBlackList[actorSerial] = true
end
--get the actor index in the hash map
@@ -755,19 +760,6 @@ end
if (petOwnerObject) then
AddUnique(petOwnerObject.pets, actorName)
end
elseif (self.tipo == container_energy_target) then --deprecated
newActor.mana = 0
newActor.e_rage = 0
newActor.e_energy = 0
newActor.runepower = 0
print("111111111111111111")
elseif (self.tipo == container_enemydebufftarget_target) then --deprecated
newActor.uptime = 0
newActor.actived = false
newActor.activedamt = 0
print("222222222222222222")
end
--sanguine affix
@@ -818,11 +810,6 @@ end
end
end
function Details:UpdatePetCache()
container_pets = Details.tabela_pets.pets
Details:UpdatePetsOnParser()
end
function Details:ClearCCPetsBlackList()
Details:Destroy(petBlackList)
end
+418 -193
View File
@@ -1,245 +1,470 @@
local Details = _G.Details
local container_pets = Details.container_pets
local _
local addonName, Details222 = ...
---@type detailsframework
local detailsFramework = DetailsFramework
--what is a unit pet? unit pets are persistant pets (with no expiration time) which the player has full control over it.
--the event UNIT_PET is triggered by the client each time a unit pet is summoned or dismissed
local UnitGUID = _G.UnitGUID
local UnitName = _G.UnitName
local IsInRaid = _G.IsInRaid
local IsInGroup = _G.IsInGroup
local GetNumGroupMembers = _G.GetNumGroupMembers
local setmetatable = setmetatable
local bitBand = bit.band --lua local
local pairs = pairs
local unitIDRaidCache = Details222.UnitIdCache.Raid
---@class petdata : table
---@field ownerName actorname
---@field ownerGuid guid
---@field ownerFlags number
---@field petName actorname
---@field petGuid guid
---@field petFlags number
---@field bIsFriendly boolean
---@field foundTime number
---@field displayName actorname
---@field hashName string petName + <ownerName-OwnerRealmName>
---@field summonSpellId number?
--details locals
local bIsIgnored = Details.pets_ignored
---@class petcontainer : table
---@field Pets table<guid, petdata>
---@field IgnoredActors table<guid, boolean>
---@field UnitPetCache table<guid, guid>
---@field GetPetInfo fun(petGuid: guid):petdata
---@field AddPet fun(petGuid: guid, petName: actorname?, petFlags: number?, ownerGuid: guid?, ownerName: actorname?, ownerFlags: number?, summonSpellId: number?):petdata
---@field AddPetByTable fun(petData: petdata):petdata
---@field PetScan fun()
---@field Reset fun()
---@field IgnorePet fun(petGuid: guid)
---@field IsPetInCache fun(petGuid: guid):boolean
---@field RemovePet fun(petGuid: guid, bRemoveFromParser: boolean?)
---@field GetOwner fun(petGuid: guid, petName:string):actorname?, actorname?, guid?, number?
---@field SavePetFrom_UNITPET fun(unitGuid: guid, petGuid: guid)
---@field IsPetFrom_UNITPET fun(unitGuid: guid):boolean
---@field GetUnitPetFrom_UNITPET fun(unitGuid: guid):guid
---@field RemovePetFrom_UNITPET fun(unitGuid: guid)
---@field GetPets fun():table<guid, petdata>
---@field DoMaintenance fun()
---@field UNIT_PET fun(unitId: string)
function container_pets:NovoContainer()
local newPetContainer = {}
setmetatable(newPetContainer, Details.container_pets)
---@type petinfo
local newPetCacheTable = {}
newPetContainer.pets = newPetCacheTable
newPetContainer._ActorTable = {}
return newPetContainer
end
--[=[
["petContainer.PetScan.ENCOUNTER_END"] = "0.000 ms | runs: 2",
["Details:UpdatePets"] = "0.001 ms | runs: 14",
["petContainer.DoMaintenance"] = "0.000 ms | runs: 3",
["petContainer.GetOwner"] = "0.027 ms | runs: 1451",
["petContainer.PetScan.UpdatePets"] = "0.001 ms | runs: 14",
["Total"] = "0.038 ms",
["petContainer.UNIT_PET"] = "0.000 ms | runs: 2",
["petContainer.PetScan.CombatStart"] = "0.000 ms | runs: 4",
["petContainer.AddPet"] = "0.001 ms | runs: 183",
["petContainer.PetScan.GetOwner"] = "0.008 ms | runs: 183",
["petContainer.SetPetData"] = "0.000 ms | runs: 1",
--]=]
local OBJECT_TYPE_PET = 0x00001000
local OBJECT_IN_GROUP = 0x00000007
function container_pets:GetPetOwner(petGUID, petName, petFlags)
--sair se o pet estiver na ignore
if (bIsIgnored[petGUID]) then
--details locals
local petContainer = Details222.PetContainer
---copy all pet data from the passed table into the pet cache
---@param petData table<guid, petdata>
function petContainer.SetPetData(petData)
Details222.Profiling.ProfileStart("petContainer.SetPetData")
---@type guid, table<guid, petdata>
for petGuid, thisPetData in pairs(petData) do
petContainer.Pets[petGuid] = thisPetData
end
Details222.Profiling.ProfileStop("petContainer.SetPetData")
end
---return a table where the pet data are stored
function petContainer.GetPets()
return petContainer.Pets
end
---reset the pet cache, wiping Pets, UnitPetCache and IgnoredActors
function petContainer.Reset()
table.wipe(petContainer.Pets)
table.wipe(petContainer.UnitPetCache)
table.wipe(petContainer.IgnoredActors)
end
function Details.DebugPets()
local amountPets = 0
print("amounf of pets:", detailsFramework.table.countkeys(petContainer.Pets))
local toShow = {petContainer.Pets, petContainer.UnitPetCache, petContainer.IgnoredActors}
dumpt(toShow)
end
---add a pet guid into the ignored list, when a pet is ignored the system will not try to find its owner as it already failed to find it once
---@param petGuid guid
function petContainer.IgnorePet(petGuid)
petContainer.IgnoredActors[petGuid] = true
end
---remove a pet from the cache
---@param petGuid guid
---@param bRemoveFromParser boolean?
function petContainer.RemovePet(petGuid, bRemoveFromParser)
if (bRemoveFromParser) then
Details.parser:RevomeActorFromCache(petGuid)
end
petContainer.RemovePetFrom_UNITPET(petGuid)
petContainer.Pets[petGuid] = nil
end
---return the pet data from the cache by passing the pet guid
---@param petGuid guid
function petContainer.GetPetInfo(petGuid)
return petContainer.Pets[petGuid]
end
---return tue if the pet guid is inside the pet cache
---@param petGuid guid
---@return boolean
function petContainer.IsPetInCache(petGuid)
return petContainer.Pets[petGuid] ~= nil
end
---@param petData petdata
function petContainer.AddPetByTable(petData)
local newPetData = petContainer.AddPet(petData.petGuid, petData.petName, petData.petFlags, petData.ownerGuid, petData.ownerName, petData.ownerFlags, petData.summonSpellId)
return newPetData
end
---@param petGuid guid
---@param petName actorname
---@param petFlags number
---@param ownerGuid guid
---@param ownerName actorname
---@param ownerFlags number
---@param summonSpellId number
---@return petdata
function petContainer.AddPet(petGuid, petName, petFlags, ownerGuid, ownerName, ownerFlags, summonSpellId)
Details222.Profiling.ProfileStart("petContainer.AddPet")
local bIsFriendly = petFlags and bitBand(petFlags, OBJECT_TYPE_PET) ~= 0 and bitBand(petFlags, OBJECT_IN_GROUP) ~= 0
if (not ownerName) then
print("NO OWNER NAME",petGuid, petName, petFlags, ownerGuid, ownerName, ownerFlags, summonSpellId)
--NO OWNER NAME Creature-0-4218-2549-4490-61056-00006A5157 Primal Earth Elemental 2600 nil nil nil 118323 --spellId 118323: Earth Elemental
--NO OWNER NAME Pet-0-4218-2549-4490-26125-0102D77C2C Casketmuncher 4648 nil nil nil 52150 --spellId: 52150 raise dead
--NO OWNER NAME Creature-0-4214-2569-1456-202167-00006B35A1 Ray of Anguish 2632 nil nil nil 402191 --spellId: 402191 Ray of Anguish
--NO OWNER NAME Creature-0-2085-2657-26413-98035-00006C9B11 Dreadstalker 8466 nil nil nil 193332 --Call Dreadstalkers
--NO OWNER NAME Creature-0-2085-2657-26413-98035-0000EC9B11 Dreadstalker 8466 nil nil nil 193331 --Call Dreadstalkers
--NO OWNER NAME Creature-0-2085-2657-26894-54983-00006C9EB4 Treant 8466 nil nil nil 102693 --Grove Guardians
Details222.Profiling.ProfileStop("petContainer.AddPet")
---@diagnostic disable-next-line: missing-return-value
return
end
--buscar pelo pet no container de pets
local petInfo = self.pets[petGUID]
if (petInfo) then
--in merging operations, make sure to not add the owner name a second time in the name
--print("====================================")
--print(petName)
--print(debugstack())
--check if the pet name already has the owner name in, if not, add it
if (not petName:find("<")) then
--get the owner name
local ownerName = petInfo[1]
--add the owner name to the pet name
petName = petName .. " <".. ownerName ..">"
end
---@type petdata
local petData = {
ownerName = ownerName,
ownerGuid = ownerGuid,
ownerFlags = ownerFlags,
petName = petName,
petGuid = petGuid,
petFlags = petFlags,
bIsFriendly = bIsFriendly,
summonSpellId = summonSpellId,
foundTime = Details._tempo,
displayName = petName,
hashName = petName .. " <" .. ownerName .. ">"
}
return petName, petInfo[1], petInfo[2], petInfo[3] --petName, ownerName, ownerGUID, ownerFlags
end
petContainer.Pets[petGuid] = petData
Details222.Profiling.ProfileStop("petContainer.AddPet")
return petData
end
--buscar pelo pet na raide
local ownerName, ownerGUID, ownerFlags
function petContainer.PetScan(from)
Details222.Profiling.ProfileStart("petContainer.PetScan." .. from)
if (IsInRaid()) then
for i = 1, GetNumGroupMembers() do
if (petGUID == UnitGUID("raidpet"..i)) then
ownerGUID = UnitGUID(unitIDRaidCache[i])
ownerFlags = 0x00000417 --emulate sourceflag flag
local unitName = Details:GetFullName(unitIDRaidCache[i])
ownerName = unitName
local unitIds = Details222.UnitIdCache.Raid
for i = 1, #unitIds do
local ownerUnitId = unitIds[i]
if (UnitExists(ownerUnitId)) then
local petUnitId = Details222.UnitIdCache.RaidPet[i]
local petGuid = UnitGUID(petUnitId)
if (petGuid) then
if (not petContainer.IsPetInCache(petGuid)) then
local petName = UnitName(petUnitId)
local ownerFullName = Details:GetFullName(ownerUnitId)
---@type petdata
local petData = {
ownerName = ownerFullName,
ownerGuid = UnitGUID(ownerUnitId),
ownerFlags = 0x514,
petName = petName,
petGuid = petGuid,
petFlags = 0x1114,
bIsFriendly = true,
foundTime = Details._tempo,
displayName = petName,
hashName = petName .. " <" .. ownerFullName .. ">"
}
petContainer.AddPetByTable(petData)
end
end
end
end
elseif (IsInGroup()) then
for i = 1, GetNumGroupMembers()-1 do
if (petGUID == UnitGUID("partypet"..i)) then
ownerGUID = UnitGUID("party"..i)
ownerFlags = 0x00000417 --emulate sourceflag flag
local unitName = Details:GetFullName("party"..i)
ownerName = unitName
local unitIds = Details222.UnitIdCache.Party
for i = 1, #unitIds do
local ownerUnitId = unitIds[i]
if (UnitExists(ownerUnitId)) then
local petUnitId = Details222.UnitIdCache.PartyPet[i]
local petGuid = UnitGUID(petUnitId)
if (petGuid) then
if (not petContainer.IsPetInCache(petGuid)) then
local petName = UnitName(petUnitId)
local ownerFullName = Details:GetFullName(ownerUnitId)
---@type petdata
local petData = {
ownerName = ownerFullName,
ownerGuid = UnitGUID(ownerUnitId),
ownerFlags = 0x514,
petName = petName,
petGuid = petGuid,
petFlags = 0x1114,
bIsFriendly = true,
foundTime = Details._tempo,
displayName = petName,
hashName = petName .. " <" .. ownerFullName .. ">"
}
petContainer.AddPetByTable(petData)
end
end
end
end
end
if (not ownerName) then
if (petGUID == UnitGUID("pet")) then
ownerName = Details:GetFullName("player")
ownerGUID = UnitGUID("player")
if (IsInGroup() or IsInRaid()) then
ownerFlags = 0x00000417 --emulate sourceflag flag
else
ownerFlags = 0x00000411 --emulate sourceflag flag
end
end
end
if (ownerName) then
local foundTime = Details._tempo
self.pets[petGUID] = {ownerName, ownerGUID, ownerFlags, foundTime, true, petName, petGUID} --adicionada a flag emulada
if (not petName:find("<")) then
petName = petName .. " <".. ownerName ..">"
end
return petName, ownerName, ownerGUID, ownerFlags
else
if (petFlags and bitBand(petFlags, OBJECT_TYPE_PET) ~= 0) then --is a pet
if (not Details.pets_no_owner[petGUID] and bitBand(petFlags, OBJECT_IN_GROUP) ~= 0) then
Details.pets_no_owner[petGUID] = {petName, petFlags}
Details:Msg("couldn't find the owner of the pet:", petName)
local petGuid = UnitGUID("pet")
if (petGuid) then
if (not petContainer.IsPetInCache(petGuid)) then
local petName = UnitName("pet")
local ownerFullName = Details:GetFullName("player")
---@type petdata
local petData = {
ownerName = ownerFullName,
ownerGuid = UnitGUID("player"),
ownerFlags = 0x514,
petName = petName,
petGuid = petGuid,
petFlags = 0x1114,
bIsFriendly = true,
foundTime = Details._tempo,
displayName = petName,
hashName = petName .. " <" .. ownerFullName .. ">"
}
petContainer.AddPetByTable(petData)
end
end
end
Details222.Profiling.ProfileStop("petContainer.PetScan." .. from)
end
---@param petGuid guid
---@param petName actorname
---@return actorname?, actorname?, guid?, number?
function petContainer.GetOwner(petGuid, petName)
Details222.Profiling.ProfileStart("petContainer.GetOwner")
--check if this pet is being ignored
if (petContainer.IgnoredActors[petGuid]) then
Details222.Profiling.ProfileStop("petContainer.GetOwner")
return
end
--check if the pet is already in the cache
local petInfo = petContainer.GetPetInfo(petGuid)
if (petInfo) then
Details222.Profiling.ProfileStop("petContainer.GetOwner")
return petInfo.hashName, petInfo.ownerName, petInfo.ownerGuid, petInfo.ownerFlags
end
--attempt to find the pet owner by searching the party, raid or the player pet
--pet scan already adds the pet into the cache
petContainer.PetScan("GetOwner")
--check if the pet scan found the pet owner
local petInfo = petContainer.GetPetInfo(petGuid)
if (petInfo) then
Details222.Profiling.ProfileStop("petContainer.GetOwner")
return petInfo.hashName, petInfo.ownerName, petInfo.ownerGuid, petInfo.ownerFlags
end
--attempt to get the pet owner by tooltip scan
local ownerName, ownerGuid, ownerFlags = Details222.Pets.GetPetOwner(petGuid, petName)
--if the tooltip scan worked, add the pet into the cache
if (ownerName) then
---@type petdata
local petData = {
ownerName = ownerName,
ownerGuid = ownerGuid,
ownerFlags = ownerFlags,
petName = petName,
petGuid = petGuid,
petFlags = 0x1114,
bIsFriendly = false,
foundTime = Details._tempo,
displayName = petName,
hashName = petName .. " <" .. ownerName .. ">"
}
petContainer.AddPetByTable(petData)
Details222.Profiling.ProfileStop("petContainer.GetOwner")
return petData.hashName, petData.ownerName, petData.ownerGuid, petData.ownerFlags
end
--couldn't find the pet owner, ignore this pet
petContainer.IgnorePet(petGuid)
Details222.Profiling.ProfileStop("petContainer.GetOwner")
return nil
end
---store in a cache the pet from UNIT_PET
---@param unitGuid guid
---@param petGuid guid
function petContainer.SavePetFrom_UNITPET(unitGuid, petGuid)
petContainer.UnitPetCache[unitGuid] = petGuid
end
---returns true if the petGuid passed is a pet from the UNIT_PET event
---@param unitGuid guid
---@return boolean
function petContainer.IsPetFrom_UNITPET(unitGuid)
return petContainer.UnitPetCache[unitGuid] ~= nil
end
---returns the petGuid from the UNIT_PET event
---@param unitGuid guid
---@return guid
function petContainer.GetUnitPetFrom_UNITPET(unitGuid)
return petContainer.UnitPetCache[unitGuid]
end
---remove a pet guid from the unit pet cache
---@param unitGuid guid
function petContainer.RemovePetFrom_UNITPET(unitGuid)
petContainer.UnitPetCache[unitGuid] = nil
end
function petContainer.UNIT_PET(unitId)
Details222.Profiling.ProfileStart("petContainer.UNIT_PET")
local ownerGuid = UnitGUID(unitId)
--print("owner guid:", ownerGuid)
if (ownerGuid) then
do
--check if the player had a pet and remove it from the cache
--this guarantees that the pet is not in the cache when the new pet is added
--is the UNIT_PET event was triggered by a pet being dismissed
local petGuid = petContainer.GetUnitPetFrom_UNITPET(ownerGuid)
if (petGuid) then
--print("pet existed!")
petContainer.RemovePet(petGuid, true)
end
end
do
local petUnitId = unitId .. "pet"
--print("pet unitId", petUnitId)
if (UnitExists(petUnitId)) then
--print("player pet exists!")
--add the new pet into the pet cache
local petGuid = UnitGUID(petUnitId)
if (petGuid) then
if (not petContainer.IsPetInCache(petGuid)) then
local ownerFullName = Details:GetFullName(unitId)
local petName = UnitName(petUnitId)
---@type petdata
local petData = {
ownerName = ownerFullName,
ownerGuid = ownerGuid,
ownerFlags = 0x514,
petName = petName,
petGuid = petGuid,
petFlags = 0x1114,
bIsFriendly = true,
foundTime = Details._tempo,
displayName = petName,
hashName = petName .. " <" .. ownerFullName .. ">"
}
--print(petData.petName, petData.hashName)
petContainer.AddPetByTable(petData)
petContainer.SavePetFrom_UNITPET(ownerGuid, petGuid)
else
--print("pet already in cache! ALREADY ALREADT")
end
end
else
--print("player pet does not exist!NOPNOPNOPNOP")
end
end
end
Details222.Profiling.ProfileStop("petContainer.UNIT_PET")
end
function petContainer.DoMaintenance()
Details222.Profiling.ProfileStart("petContainer.DoMaintenance")
local petCache = petContainer.Pets
for petGuid, petData in pairs(petCache) do
local petInfo = petContainer.GetPetInfo(petGuid)
--check if the pet is a unit pet, unit pets are persistant, never timeout
local bIsUnitPet = petContainer.IsPetFrom_UNITPET(petGuid)
if (bIsUnitPet) then
if (not petInfo or not UnitExists(petInfo.ownerGuid) or not UnitExists(petInfo.ownerName)) then
petContainer.RemovePet(petGuid, true)
end
else
bIsIgnored[petGUID] = true
end
end
end
function container_pets:Unpet(...)
local unitId = ...
local ownerGUID = UnitGUID(unitId)
if (ownerGUID) then
--remove existing pet from thecache
do
local petGUID = Details.pets_players[ownerGUID]
if (petGUID) then
Details.parser:RevomeActorFromCache(petGUID)
container_pets:Remover(petGUID)
Details.pets_players[ownerGUID] = nil
end
end
--check if the player has a new pet
do
local petGUID = UnitGUID(unitId .. "pet")
if (petGUID) then
if (not Details.tabela_pets.pets[petGUID]) then
local unitName = Details:GetFullName(unitId)
Details.tabela_pets:AddPet(petGUID, UnitName(unitId .. "pet"), 0x1114, ownerGUID, unitName, 0x514)
end
Details.parser:RevomeActorFromCache(petGUID)
container_pets:PlayerPet(ownerGUID, petGUID)
local expirationTime = petData.foundTime + 1800
if (expirationTime < Details._tempo + 1) then
petContainer.RemovePet(petGuid, true)
end
end
end
end
function container_pets:PlayerPet(player_serial, pet_serial)
Details.pets_players[player_serial] = pet_serial
end
function container_pets:BuscarPets()
if (IsInRaid()) then
for i = 1, GetNumGroupMembers(), 1 do
local petGUID = UnitGUID("raidpet" .. i)
if (petGUID) then
if (not Details.tabela_pets.pets[petGUID]) then
local unitName = Details:GetFullName(unitIDRaidCache[i])
local ownerGUID = UnitGUID(unitIDRaidCache[i])
Details.tabela_pets:AddPet(petGUID, UnitName("raidpet"..i), 0x1114, ownerGUID, unitName, 0x514)
Details.parser:RevomeActorFromCache(petGUID)
container_pets:PlayerPet(ownerGUID, petGUID)
end
end
end
elseif (IsInGroup()) then
for i = 1, GetNumGroupMembers()-1, 1 do
local petGUID = UnitGUID("partypet"..i)
if (petGUID) then
if (not Details.tabela_pets.pets[petGUID]) then
local unitName = Details:GetFullName("party"..i)
Details.tabela_pets:AddPet(petGUID, UnitName("partypet"..i), 0x1114, UnitGUID("party"..i), unitName, 0x514)
end
end
end
local petGUID = UnitGUID("pet")
if (petGUID) then
if (not Details.tabela_pets.pets[petGUID]) then
Details.tabela_pets:AddPet(petGUID, UnitName("pet"), 0x1114, UnitGUID("player"), Details.playername, 0x514)
end
end
else
local petGUID = UnitGUID("pet")
if (petGUID) then
if (not Details.tabela_pets.pets[petGUID]) then
Details.tabela_pets:AddPet(petGUID, UnitName("pet"), 0x1114, UnitGUID("player"), Details.playername, 0x514)
end
end
end
end
function container_pets:Remover(petGUID)
if (Details.tabela_pets.pets[petGUID]) then
Details:Destroy(Details.tabela_pets.pets[petGUID])
end
Details.tabela_pets.pets[petGUID] = nil
end
function container_pets:AddPet(petGUID, petName, petFlags, ownerGUID, ownerName, ownerFlags)
if (petFlags and bitBand(petFlags, OBJECT_TYPE_PET) ~= 0 and bitBand(petFlags, OBJECT_IN_GROUP) ~= 0) then
self.pets[petGUID] = {ownerName, ownerGUID, ownerFlags, Details._tempo, true, petName, petGUID}
else
self.pets[petGUID] = {ownerName, ownerGUID, ownerFlags, Details._tempo, false, petName, petGUID}
end
end
function Details:WipePets()
return Details:Destroy(Details.tabela_pets.pets)
end
function Details222.Pets.PetContainerCleanup()
--erase old pet table by creating a new one
local newPetTable = {}
--minimum of 90 minutes to clean a pet from the pet table data
for petGUID, petTable in pairs(Details.tabela_pets.pets) do
if ((petTable[4] + 5400 > Details._tempo + 1) or (petTable[5] and petTable[4] + 43200 > Details._tempo)) then
newPetTable[petGUID] = petTable
end
end
Details.tabela_pets.pets = newPetTable
Details:UpdatePetCache()
Details222.Profiling.ProfileStop("petContainer.DoMaintenance")
end
local bHasSchedule = false
function Details:UpdatePets()
Details222.Profiling.ProfileStart("Details:UpdatePets")
bHasSchedule = false
return container_pets:BuscarPets()
petContainer.PetScan("UpdatePets")
Details222.Profiling.ProfileStop("Details:UpdatePets")
end
function Details:SchedulePetUpdate(seconds)
if (bHasSchedule) then
return
end
bHasSchedule = true
seconds = seconds or 5
Details.Schedules.NewTimer(seconds or 5, Details.UpdatePets, Details)
Details.Schedules.NewTimer(seconds, Details.UpdatePets, Details)
end
function Details.refresh:r_container_pets(container)
setmetatable(container, container_pets)
end
+7 -4
View File
@@ -15,6 +15,9 @@ local wipe = table.wipe
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
---@type petcontainer
local petContainer = Details222.PetContainer
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--API
@@ -890,7 +893,8 @@ function segmentClass:ResetAllCombatData()
Details:Destroy(Details.cache_damage_group)
Details:Destroy(Details.cache_healing_group)
Details222.Pets.PetContainerCleanup()
petContainer.DoMaintenance()
Details:ResetSpecCache(true)
--stop combat ticker
@@ -941,9 +945,8 @@ function segmentClass:ResetAllCombatData()
Details.tabela_vigente = combatClass:NovaTabela(nil, Details.tabela_overall)
--create new container to store pets
Details.tabela_pets = Details.container_pets:NovoContainer()
Details:UpdatePetCache()
Details.container_pets:BuscarPets()
petContainer.Reset()
petContainer.PetScan("ResetAllCombatData")
end
---@type instance[]
+2 -20
View File
@@ -305,7 +305,6 @@
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--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
@@ -369,7 +368,7 @@
Details:Destroy(Details.encounter_end_table)
Details:Destroy(Details.pets_ignored)
Details:Destroy(Details.pets_no_owner)
Details.container_pets:BuscarPets()
Details222.PetContainer.PetScan("CombatStart")
Details:Destroy(Details.cache_damage_group)
Details:Destroy(Details.cache_healing_group)
@@ -1208,21 +1207,7 @@
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)
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
@@ -1230,9 +1215,6 @@
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)
+1 -4
View File
@@ -87,9 +87,6 @@ local classTypeUtility = Details.atributos.misc
end
function Details:RestoreMetatables() --called from Details222.LoadSavedVariables.CombatSegments() --restore actor containers indexes e metatables
--pet table
setmetatable(Details.tabela_pets, Details.container_pets)
--segment container
setmetatable(Details.tabela_historico, Details.historico)
@@ -718,7 +715,7 @@ local classTypeUtility = Details.atributos.misc
end
--cleanup backlisted pets within the handler of actor containers
Details222.Pets.PetContainerCleanup()
Details222.PetContainer.DoMaintenance()
Details:ClearCCPetsBlackList()
--cleanup spec cache
+31 -19
View File
@@ -28,7 +28,6 @@
local _UnitGroupRolesAssigned = detailsFramework.UnitGroupRolesAssigned
local _GetSpellInfo = Details.getspellinfo
local _tempo = time()
local _, Details222 = ...
_ = nil
local shield_cache = Details.ShieldCache --details local
@@ -77,6 +76,10 @@
local _current_energy_container = _current_combat [3]
local _current_misc_container = _current_combat [4]
--pet container cache
---@type petcontainer
local petContainer = Details222.PetContainer
local names_cache = {}
--damage
local damage_cache = setmetatable({}, Details.weaktable)
@@ -112,7 +115,8 @@
--shield spellid cache
local shield_spellid_cache = {}
--pets
local container_pets = {} --just initialize table (placeholder)
local petCache = petContainer.Pets
--ignore deaths
local ignore_death_cache = {}
--cache
@@ -1682,18 +1686,24 @@
12/14 21:14:44.545 SPELL_SUMMON,Creature-0-4391-615-3107-15439-00001A8313,"Fire Elemental Totem",0x2112,0x0,Creature-0-4391-615-3107-15438-00001A8313,"Greater Fire Elemental",0x2112,0x0,32982,"Fire Elemental Totem",0x1
]]
if npcId == 15438 then
petContainer.AddPet(petSerial, "Greater Fire Elemental", petFlags, sourceSerial, sourceName, sourceFlags, spellId)
end
petName = Details222.Pets.GetPetNameFromCustomSpells(petName, spellId, npcId)
--pet summon another pet
local petTable = container_pets[sourceSerial]
local petTable = petCache[sourceSerial]
if (petTable) then
sourceName, sourceSerial, sourceFlags = petTable[1], petTable[2], petTable[3]
end
petTable = container_pets[petSerial]
petTable = petCache[petSerial]
if (petTable) then
sourceName, sourceSerial, sourceFlags = petTable[1], petTable[2], petTable[3]
end
Details.tabela_pets:AddPet(petSerial, petName, petFlags, sourceSerial, sourceName, sourceFlags)
petContainer.AddPet(petSerial, petName, petFlags, sourceSerial, sourceName, sourceFlags, spellId)
end
-----------------------------------------------------------------------------------------------------------------------------------------
@@ -2390,7 +2400,7 @@
--player itself
parser:add_buff_uptime(token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, "BUFF_UPTIME_IN")
elseif (container_pets[sourceSerial] and container_pets[sourceSerial][2] == targetSerial) then
elseif (petCache[sourceSerial] and petCache[sourceSerial][2] == targetSerial) then
--pet putting an aura on its owner
parser:add_buff_uptime(token, time, targetSerial, targetName, targetFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, "BUFF_UPTIME_IN")
@@ -2505,7 +2515,7 @@
--call record buffs uptime
parser:add_buff_uptime (token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, "BUFF_UPTIME_REFRESH")
elseif (container_pets [sourceSerial] and container_pets [sourceSerial][2] == targetSerial) then
elseif (petCache [sourceSerial] and petCache [sourceSerial][2] == targetSerial) then
--um pet colocando uma aura do dono
parser:add_buff_uptime (token, time, targetSerial, targetName, targetFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, "BUFF_UPTIME_REFRESH")
@@ -2572,7 +2582,7 @@
elseif (sourceName == targetName and raid_members_cache[sourceSerial] and _in_combat) then
--call record buffs uptime
parser:add_buff_uptime(token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, "BUFF_UPTIME_OUT")
elseif (container_pets[sourceSerial] and container_pets[sourceSerial][2] == targetSerial) then
elseif (petCache[sourceSerial] and petCache[sourceSerial][2] == targetSerial) then
--um pet colocando uma aura do dono
parser:add_buff_uptime(token, time, targetSerial, targetName, targetFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, "BUFF_UPTIME_OUT")
@@ -3425,14 +3435,12 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
end
if (not ownerActor) then
petName, ownerName, ownerGUID, ownerFlags = Details.tabela_pets:GetPetOwner(sourceSerial, sourceName, sourceFlags)
petName, ownerName, ownerGUID, ownerFlags = petContainer.GetOwner(sourceSerial, targetName)
if (petName) then
ownerActor = _current_misc_container:GetOrCreateActor(ownerGUID, ownerName, ownerFlags, true)
end
end
--local sourceActor, ownerActor, sourceName = _current_misc_container:GetOrCreateActor(sourceSerial, sourceName, sourceFlags, true)
------------------------------------------------------------------------------------------------
--build containers on the fly
if (not sourceActor.interrupt) then
@@ -3920,6 +3928,11 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
---@param targetName string
---@param targetFlags number
function parser:dead(token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags)
---@cast Details222 details222
if (petContainer.Pets[targetSerial]) then
petContainer.RemovePet(targetSerial)
end
--early checks and fixes
if (not targetName) then
return
@@ -4939,6 +4952,9 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
end
end
petContainer.Reset()
C_Timer.After(1, function() petContainer.PetScan("ENCOUNTER_END") end)
--tag item level of all players
local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true)
local allPlayersGear = openRaidLib and openRaidLib.GetAllUnitsGear()
@@ -4966,8 +4982,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
return true
end
function Details.parser_functions:UNIT_PET(...)
Details.container_pets:Unpet(...)
function Details.parser_functions:UNIT_PET(unitId)
petContainer.UNIT_PET(unitId)
Details:SchedulePetUpdate(1)
end
@@ -5483,7 +5499,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
if (Details.in_group) then
--player entered in a group, cleanup and set the new enviromnent
Details222.GarbageCollector.RestartInternalGarbageCollector(true)
Details:WipePets()
petContainer.Reset()
Details:SchedulePetUpdate(1)
Details:InstanceCall(Details.AdjustAlphaByContext)
@@ -5503,7 +5519,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
if (not Details.in_group) then
--player left the group, run routines to cleanup the environment
Details222.GarbageCollector.RestartInternalGarbageCollector(true)
Details:WipePets()
petContainer.Reset()
Details:SchedulePetUpdate(1)
Details:Destroy(Details.details_users)
Details:InstanceCall(Details.AdjustAlphaByContext)
@@ -5967,10 +5983,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
_tempo = Details._tempo
end
function Details:UpdatePetsOnParser()
container_pets = Details.tabela_pets.pets
end
function Details:GetActorFromCache(value)
return damage_cache[value] or damage_cache_pets[value] or damage_cache_petsOwners[value]
end
@@ -10,7 +10,6 @@ local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink --api local
local GetSpellInfo = GetSpellInfo
local _GetSpellInfo = Details.GetSpellInfo
local GameTooltip = GameTooltip
local IsShiftKeyDown = IsShiftKeyDown
local DF = DetailsFramework
local tinsert = table.insert
@@ -10,7 +10,6 @@ local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink
local GetSpellInfo = Details222.GetSpellInfo
local _GetSpellInfo = Details.GetSpellInfo
local GameTooltip = GameTooltip
local IsShiftKeyDown = IsShiftKeyDown
local DF = DetailsFramework
local detailsFramework = DetailsFramework
local tinsert = table.insert
@@ -1199,6 +1199,8 @@ local refreshSpellsFunc = function(scrollFrame, scrollData, offset, totalLines)
nameToUse = bkSpellData.actorName
end
--both calls are equal but the traceback will be different in case of an error
if (bIsActorHeader) then
updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount)
@@ -27,6 +27,7 @@ local mythicDungeonCharts = Details222.MythicPlus.Charts.Listener
local mythicDungeonFrames = Details222.MythicPlus.Frames
local CONST_DEBUG_MODE = false
local SOFT_DEBUG_MODE = true
--debug
_G.MythicDungeonFrames = mythicDungeonFrames
@@ -103,6 +104,12 @@ function lootFrame.UpdateUnitLoot(unitBanner)
---@type details_loot_cache[]
local lootCandidates = {}
if (SOFT_DEBUG_MODE) then
if (UnitIsUnit("player", unitId)) then
Details:Msg("Loot UpdateUnitLoot:", unitName, GetTime())
end
end
if (lootCache) then
local lootCacheSize = #lootCache
if (lootCacheSize > 0) then
@@ -137,6 +144,12 @@ function lootFrame.UpdateUnitLoot(unitBanner)
mythicDungeonFrames.ReadyFrame.StopTextDotAnimation()
lootSquare:Show()
if (SOFT_DEBUG_MODE) then
if (UnitIsUnit("player", unitId)) then
Details:Msg("Loot DISPLAYED:", unitName, GetTime())
end
end
end
end
@@ -177,6 +190,10 @@ lootFrame:SetScript("OnEvent", function(self, event, ...)
}
table.insert(lootFrame.LootCache[unitName], lootCacheTable)
if (SOFT_DEBUG_MODE) then
Details:Msg("Loot ADDED:", unitName, itemLink, effectiveILvl, itemQuality, baseItemLevel)
end
--check if the end of mythic plus frame is opened and call a function to update the loot frame of the player
if (mythicDungeonFrames.ReadyFrame and mythicDungeonFrames.ReadyFrame:IsVisible()) then
C_Timer.After(1.5, function()
@@ -186,6 +203,10 @@ lootFrame:SetScript("OnEvent", function(self, event, ...)
end
end)
end
else
if (SOFT_DEBUG_MODE) then
Details:Msg("Loot SKIPPED:", unitName, itemLink, effectiveILvl, itemQuality, baseItemLevel)
end
end
end
end
-4
View File
@@ -5,10 +5,6 @@ do
local Details = _G.Details
local addonName, Details222 = ...
local setmetatable = setmetatable
-------- container que armazena o cache de pets
Details.container_pets = {}
Details.container_pets.__index = Details.container_pets
setmetatable(Details.container_pets, Details)
-------- time machine controla o tempo em combate dos jogadores
Details.timeMachine = {}
+11 -11
View File
@@ -136,17 +136,18 @@ function Details222.LoadSavedVariables.CombatSegments()
Details.tabela_historico = Details.historico:CreateNewSegmentDatabase()
Details.tabela_overall = Details.combate:NovaTabela()
Details.tabela_vigente = Details.combate:NovaTabela(_, Details.tabela_overall)
Details.tabela_pets = Details.container_pets:NovoContainer()
Details:UpdatePetCache()
Details222.PetContainer.Reset()
if (currentCharacterData.tabela_pets) then
Details:Destroy(currentCharacterData.tabela_pets) --saved pet data
currentCharacterData.tabela_pets = nil
if (currentCharacterData.saved_pet_cache) then
Details:Destroy(currentCharacterData.saved_pet_cache) --saved pet data
currentCharacterData.saved_pet_cache = nil
end
if (currentCharacterData.tabela_overall) then --saved overall data
Details:Destroy(currentCharacterData.tabela_overall)
currentCharacterData.tabela_overall = nil
end
if (currentCharacterData.tabela_historico) then
Details:Destroy(currentCharacterData.tabela_historico)
currentCharacterData.tabela_historico = nil
@@ -156,12 +157,12 @@ function Details222.LoadSavedVariables.CombatSegments()
else
--pet owners cache saved on logout
do
Details.tabela_pets = Details.container_pets:NovoContainer()
if (currentCharacterData.tabela_pets) then
Details222.PetContainer.Reset()
if (currentCharacterData.saved_pet_cache) then
--pet ownership table only exists if the player logoff inside a raid or dungeon
Details.tabela_pets.pets = Details.CopyTable(currentCharacterData.tabela_pets)
Details:Destroy(currentCharacterData.tabela_pets)
currentCharacterData.tabela_pets = nil
Details222.PetContainer.SetPetData(currentCharacterData.saved_pet_cache)
Details:Destroy(currentCharacterData.saved_pet_cache)
currentCharacterData.saved_pet_cache = nil
end
end
@@ -194,7 +195,6 @@ function Details222.LoadSavedVariables.CombatSegments()
actorContainer.need_refresh = true
end
Details:UpdatePetCache()
Details:RestoreMetatables()
end
end
+1 -1
View File
@@ -99,7 +99,7 @@ function Details:SaveConfig()
local name, instanceType = GetInstanceInfo()
if (instanceType == "party" or instanceType == "raid") then
--save pet ownership information
_detalhes_database.tabela_pets = Details.tabela_pets.pets
_detalhes_database.saved_pet_cache = Details222.PetContainer.GetPets()
end
--clear temporarly time data (charts)
+1 -22
View File
@@ -387,28 +387,7 @@ function SlashCmdList.DETAILS (msg, editbox)
instance2.baseframe:SetPoint("bottomright", RightChatToggleButton, "topright", -1, 1)
elseif (msg == "pets") then
local petFrame = Details.PetFrame
if (not petFrame) then
petFrame = Details:CreateListPanel()
Details.PetFrame = petFrame
end
local i = 1
for k, v in pairs(Details.tabela_pets.pets) do
petFrame:add( k .. ": " .. v[1] .. " | " .. v[2] .. " | " .. v[3] .. " | " .. v[6], i)
i = i + 1
end
petFrame:Show()
elseif (msg == "savepets") then
Details.tabela_vigente.saved_pets = {}
for k, v in pairs(Details.tabela_pets.pets) do
Details.tabela_vigente.saved_pets[k] = {v[1], v[2], v[3]}
end
Details:Msg("pet table has been saved on current combat.")
Details.DebugPets()
elseif (msg == "model") then
local frame = CreateFrame("PlayerModel");
+19
View File
@@ -99,6 +99,7 @@ do
---@type table<number, customiteminfo>
local customItemList = {}
Details222.CustomItemList = customItemList
local iconSize = 14
local coords = {0.14, 0.86, 0.14, 0.86}
@@ -139,6 +140,24 @@ do
[8] = {name = Loc ["STRING_ENVIRONMENTAL_SLIME"], icon = [[Interface\ICONS\Ability_Creature_Poison_02]]},
}
function Details222.Pets.GetPetNameFromCustomSpells(petName, spellId, npcId)
---@type customiteminfo
local customItem = Details222.CustomItemList[spellId]
if (customItem and customItem.isSummon) then
local defaultName = customItem.defaultName
if (defaultName) then
petName = defaultName
if (customItem.nameExtra) then
petName = petName .. " " .. customItem.nameExtra
end
return petName
end
end
return petName
end
if (LIB_OPEN_RAID_SPELL_CUSTOM_NAMES) then
for spellId, customTable in pairs(LIB_OPEN_RAID_SPELL_CUSTOM_NAMES) do
local customName = customTable.name
+38 -3
View File
@@ -18,6 +18,41 @@ do
local weakTable = {__mode = "v"}
local Details222 = {}
local GetSpellInfo = GetSpellInfo or C_Spell.GetSpellInfo
Details222.GetSpellInfo = GetSpellInfo
local UnitBuff = UnitBuff or C_UnitAuras.GetBuffDataByIndex
Details222.UnitBuff = UnitBuff
local UnitDebuff = UnitDebuff or C_UnitAuras.GetDebuffDataByIndex
Details222.UnitDebuff = UnitDebuff
if (DetailsFramework.IsWarWow()) then
Details222.GetSpellInfo = function(...)
local result = GetSpellInfo(...)
if result then
return result.name, 1, result.iconID
end
end
Details222.UnitBuff = function(unitToken, index, filter)
local auraData = C_UnitAuras.GetBuffDataByIndex(unitToken, index, filter)
if (not auraData) then
return nil
end
return AuraUtil.UnpackAuraData(auraData)
end
Details222.UnitDebuff = function(unitToken, index, filter)
local auraData = C_UnitAuras.GetDebuffDataByIndex(unitToken, index, filter)
if (not auraData) then
return nil
end
return AuraUtil.UnpackAuraData(auraData)
end
end
---@class compare : frame
---@field mainPlayerObject actor the actor object of the main player being compared
---@field isComparisonTab boolean indicates this frame is part of the comparison tab
@@ -458,7 +493,7 @@ do
--amount of casts
local combatObject = Details:GetCombatFromBreakdownWindow()
local castAmount = combatObject:GetSpellCastAmount(playerName, Details.GetSpellInfo(spellId))
local castAmount = combatObject:GetSpellCastAmount(playerName, Details222.GetSpellInfo(spellId))
local playerMiscObject = combatObject:GetActor(DETAILS_ATTRIBUTE_MISC, playerName)
if (castAmount > 0) then
@@ -579,7 +614,7 @@ do
local combatObject = Details:GetCombatFromBreakdownWindow()
local playerMiscObject = combatObject:GetActor(DETAILS_ATTRIBUTE_MISC, playerName)
local castAmount = combatObject:GetSpellCastAmount(playerName, Details.GetSpellInfo(spellId))
local castAmount = combatObject:GetSpellCastAmount(playerName, Details222.GetSpellInfo(spellId))
if (castAmount > 0) then
tooltip.casts_label2:SetText(getPercentComparison(mainCastAmount, castAmount))
tooltip.casts_label3:SetText(castAmount)
@@ -2052,4 +2087,4 @@ do
end
end
end
end
end
+8 -1
View File
@@ -479,7 +479,14 @@ do
for index, combate in ipairs(segmentList) do
if (combate.is_boss and combate.is_boss.index) then
local bossIcon = Details:GetBossEncounterTexture(combate.is_boss.id or combate.is_boss.encounter or combate.is_boss.name)
resultTable[#resultTable+1] = {value = index, label = "#" .. index .. " " .. combate.is_boss.name, icon = bossIcon, iconsize = {32, 20}, texcoord = {0, 1, 0, 0.9}, onclick = encounterDetails.OpenAndRefresh}
resultTable[#resultTable+1] = {
value = index,
label = "#" .. index .. " " .. (combate.is_boss.encounter or combate.is_boss.name or _G["UNKNOWN"]),
icon = bossIcon,
iconsize = {32, 20},
texcoord = {0, 1, 0, 0.9},
onclick = encounterDetails.OpenAndRefresh
}
end
end
@@ -824,4 +824,4 @@ function DetailsRaidCheck:OnEvent(_, event, ...)
end
end
end
end
end