diff --git a/Definitions.lua b/Definitions.lua index 96e9d65c..f63d63fd 100644 --- a/Definitions.lua +++ b/Definitions.lua @@ -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 diff --git a/Libs/DF/definitions.lua b/Libs/DF/definitions.lua index 352c6d1a..d4f019b7 100644 --- a/Libs/DF/definitions.lua +++ b/Libs/DF/definitions.lua @@ -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 diff --git a/Libs/DF/fw.lua b/Libs/DF/fw.lua index e4480a60..134f186e 100644 --- a/Libs/DF/fw.lua +++ b/Libs/DF/fw.lua @@ -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 diff --git a/Libs/LibOpenRaid/GetPlayerInformation.lua b/Libs/LibOpenRaid/GetPlayerInformation.lua index 1c037a5e..1dd58e0e 100644 --- a/Libs/LibOpenRaid/GetPlayerInformation.lua +++ b/Libs/LibOpenRaid/GetPlayerInformation.lua @@ -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 diff --git a/Libs/LibOpenRaid/LibOpenRaid.lua b/Libs/LibOpenRaid/LibOpenRaid.lua index db45ec5b..3bcb93df 100644 --- a/Libs/LibOpenRaid/LibOpenRaid.lua +++ b/Libs/LibOpenRaid/LibOpenRaid.lua @@ -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 diff --git a/boot.lua b/boot.lua index c72f5aae..20d7e345 100644 --- a/boot.lua +++ b/boot.lua @@ -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 + Pets = {}, + ---@type table + 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 + 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 dispon�veis 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 diff --git a/classes/class_resources.lua b/classes/class_resources.lua index 624d380e..e28f4cb7 100644 --- a/classes/class_resources.lua +++ b/classes/class_resources.lua @@ -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 diff --git a/classes/container_actors.lua b/classes/container_actors.lua index 7d0e32fb..e7d9ce98 100644 --- a/classes/container_actors.lua +++ b/classes/container_actors.lua @@ -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 + 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 diff --git a/classes/container_pets.lua b/classes/container_pets.lua index 1975d216..f88f3281 100644 --- a/classes/container_pets.lua +++ b/classes/container_pets.lua @@ -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 + +---@field summonSpellId number? ---details locals -local bIsIgnored = Details.pets_ignored +---@class petcontainer : table +---@field Pets table +---@field IgnoredActors table +---@field UnitPetCache table +---@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 +---@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 +function petContainer.SetPetData(petData) + Details222.Profiling.ProfileStart("petContainer.SetPetData") + ---@type guid, table + 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 - diff --git a/classes/container_segments.lua b/classes/container_segments.lua index 80af9c92..3fdc1165 100644 --- a/classes/container_segments.lua +++ b/classes/container_segments.lua @@ -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[] diff --git a/core/control.lua b/core/control.lua index 7e3ed064..1b7c2736 100644 --- a/core/control.lua +++ b/core/control.lua @@ -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) diff --git a/core/meta.lua b/core/meta.lua index 2b81a063..ed1a3ac5 100644 --- a/core/meta.lua +++ b/core/meta.lua @@ -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 diff --git a/core/parser.lua b/core/parser.lua index f19ed758..dda86806 100755 --- a/core/parser.lua +++ b/core/parser.lua @@ -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 diff --git a/frames/window_breakdown/breakdown_spells_genericframes.lua b/frames/window_breakdown/breakdown_spells_genericframes.lua index 995a8e8d..02dc5b0b 100644 --- a/frames/window_breakdown/breakdown_spells_genericframes.lua +++ b/frames/window_breakdown/breakdown_spells_genericframes.lua @@ -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 diff --git a/frames/window_breakdown/breakdown_spells_phaseframes.lua b/frames/window_breakdown/breakdown_spells_phaseframes.lua index 66b30800..a3619062 100644 --- a/frames/window_breakdown/breakdown_spells_phaseframes.lua +++ b/frames/window_breakdown/breakdown_spells_phaseframes.lua @@ -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 diff --git a/frames/window_breakdown/breakdown_spells_spellframes.lua b/frames/window_breakdown/breakdown_spells_spellframes.lua index cc8eb73a..5dedd446 100644 --- a/frames/window_breakdown/breakdown_spells_spellframes.lua +++ b/frames/window_breakdown/breakdown_spells_spellframes.lua @@ -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) diff --git a/frames/window_mythicplus/window_end_of_run.lua b/frames/window_mythicplus/window_end_of_run.lua index 763be0f4..b81b09db 100644 --- a/frames/window_mythicplus/window_end_of_run.lua +++ b/frames/window_mythicplus/window_end_of_run.lua @@ -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 diff --git a/functions/classes.lua b/functions/classes.lua index e2d10def..79e8e51b 100644 --- a/functions/classes.lua +++ b/functions/classes.lua @@ -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 = {} diff --git a/functions/loaddata.lua b/functions/loaddata.lua index 95e6fa7d..dff86b83 100644 --- a/functions/loaddata.lua +++ b/functions/loaddata.lua @@ -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 diff --git a/functions/savedata.lua b/functions/savedata.lua index e1971a51..51768ac8 100644 --- a/functions/savedata.lua +++ b/functions/savedata.lua @@ -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) diff --git a/functions/slash.lua b/functions/slash.lua index 98c8648d..61d9b7c5 100644 --- a/functions/slash.lua +++ b/functions/slash.lua @@ -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"); diff --git a/functions/spellcache.lua b/functions/spellcache.lua index a02e03d1..ca375793 100644 --- a/functions/spellcache.lua +++ b/functions/spellcache.lua @@ -99,6 +99,7 @@ do ---@type table 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 diff --git a/plugins/Details_Compare2/Details_Compare2.lua b/plugins/Details_Compare2/Details_Compare2.lua index 4633721e..e2920931 100644 --- a/plugins/Details_Compare2/Details_Compare2.lua +++ b/plugins/Details_Compare2/Details_Compare2.lua @@ -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 \ No newline at end of file diff --git a/plugins/Details_EncounterDetails/frames.lua b/plugins/Details_EncounterDetails/frames.lua index e6a777f2..d9a73619 100644 --- a/plugins/Details_EncounterDetails/frames.lua +++ b/plugins/Details_EncounterDetails/frames.lua @@ -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 diff --git a/plugins/Details_RaidCheck/Details_RaidCheck.lua b/plugins/Details_RaidCheck/Details_RaidCheck.lua index 0a8d90cc..6c8a969e 100644 --- a/plugins/Details_RaidCheck/Details_RaidCheck.lua +++ b/plugins/Details_RaidCheck/Details_RaidCheck.lua @@ -824,4 +824,4 @@ function DetailsRaidCheck:OnEvent(_, event, ...) end end end -end +end \ No newline at end of file