diff --git a/Details.toc b/Details.toc index fe39b459..add61354 100644 --- a/Details.toc +++ b/Details.toc @@ -1,7 +1,7 @@ ## Interface: 100200 ## Title: Details! Damage Meter ## Notes: Essential tool to impress that chick in your raid. -## SavedVariables: _detalhes_global, __details_backup +## SavedVariables: _detalhes_global, __details_backup, __details_debug ## SavedVariablesPerCharacter: _detalhes_database ## OptionalDeps: Ace3, LibSharedMedia-3.0, LibWindow-1.1, LibDBIcon-1.0, NickTag-1.0, LibDataBroker-1.1, LibGraph-2.0 ## Version: #@project-version@ @@ -72,6 +72,7 @@ functions\warcraftlogs.lua functions\textures.lua functions\journal.lua +core\aura_scan.lua core\timemachine.lua frames\anime.lua diff --git a/Details_Classic.toc b/Details_Classic.toc index 6053d695..cda9919e 100644 --- a/Details_Classic.toc +++ b/Details_Classic.toc @@ -67,6 +67,7 @@ functions\testbars.lua functions\warcraftlogs.lua functions\textures.lua +core\aura_scan.lua core\timemachine.lua frames\anime.lua diff --git a/Details_Wrath.toc b/Details_Wrath.toc index cb4312fa..b4310ff1 100644 --- a/Details_Wrath.toc +++ b/Details_Wrath.toc @@ -67,6 +67,7 @@ functions\testbars.lua functions\warcraftlogs.lua functions\textures.lua +core\aura_scan.lua core\timemachine.lua frames\anime.lua diff --git a/Libs/DF/cooltip.lua b/Libs/DF/cooltip.lua index a2301656..82111369 100644 --- a/Libs/DF/cooltip.lua +++ b/Libs/DF/cooltip.lua @@ -1861,14 +1861,15 @@ function DF:CreateCoolTip() if (type(spellId) == "number") then spellId = C_SpellBook.GetOverrideSpell(spellId) local spellName, spellRank, spellIcon, castTime, minRange, maxRange = GetSpellInfo(spellId) + --castTime zero represents an instant cast or a channeled cast if (spellName) then local spellDescription = GetSpellDescription(spellId) local cooldownTime, globalCooldown = GetSpellBaseCooldown(spellId) --local cooldown = cooldownTime / 1000 local bIsPassive = IsPassiveSpell(spellId, "player") local chargesAvailable, maxCharges, chargeCooldownStart, rechargeTime, chargeModRate = GetSpellCharges(spellId) - local tResourceCost = GetSpellPowerCost(spellId) + local tResourceCost = GetSpellPowerCost(spellId) --[=[ hasRequiredAura=false, type=0, diff --git a/Libs/DF/fw.lua b/Libs/DF/fw.lua index de1b4566..831dd499 100644 --- a/Libs/DF/fw.lua +++ b/Libs/DF/fw.lua @@ -1,6 +1,6 @@ -local dversion = 497 +local dversion = 498 local major, minor = "DetailsFramework-1.0", dversion local DF, oldminor = LibStub:NewLibrary(major, minor) diff --git a/Libs/DF/unitframe.lua b/Libs/DF/unitframe.lua index 23594fe8..976285aa 100644 --- a/Libs/DF/unitframe.lua +++ b/Libs/DF/unitframe.lua @@ -1457,8 +1457,22 @@ detailsFramework.CastFrameFunctions = { end end, - UpdateCastingInfo = function(self, unit) - local name, text, texture, startTime, endTime, isTradeSkill, castID, notInterruptible, spellID = CastInfo.UnitCastingInfo(unit) + UpdateCastingInfo = function(self, unit, ...) + local unitID, castID, spellID = ... + local name, text, texture, startTime, endTime, isTradeSkill, uciCastID, notInterruptible, uciSpellID = CastInfo.UnitCastingInfo(unit) + spellID = uciSpellID or spellID + castID = uciCastID or castID + + if spellID and (not name or not texture or not text) then + local siName, _, siIcon, siCastTime = GetSpellInfo(spellID) + texture = texture or siIcon + name = name or siName + text = text or siName + if not startTime then + startTime = GetTime() + endTime = startTime + siCastTime + end + end --is valid? if (not self:IsValid(unit, name, isTradeSkill, true)) then @@ -1519,8 +1533,8 @@ detailsFramework.CastFrameFunctions = { self:UpdateInterruptState() end, - UNIT_SPELLCAST_START = function(self, unit) - self:UpdateCastingInfo(unit) + UNIT_SPELLCAST_START = function(self, unit, ...) + self:UpdateCastingInfo(unit, ...) self:RunHooksForWidget("OnCastStart", self, self.unit, "UNIT_SPELLCAST_START") end, @@ -1570,7 +1584,20 @@ detailsFramework.CastFrameFunctions = { UpdateChannelInfo = function(self, unit, ...) local unitID, castID, spellID = ... - local name, text, texture, startTime, endTime, isTradeSkill, notInterruptible, spellID, _, numStages = CastInfo.UnitChannelInfo (unit) + local name, text, texture, startTime, endTime, isTradeSkill, notInterruptible, uciSpellID, _, numStages = CastInfo.UnitChannelInfo (unit) + spellID = uciSpellID or spellID + castID = uciCastID or castID + + if spellID and (not name or not texture or not text) then + local siName, _, siIcon, siCastTime = GetSpellInfo(spellID) + texture = texture or siIcon + name = name or siName + text = text or siName + if not startTime then + startTime = GetTime() + endTime = startTime + siCastTime + end + end --is valid? if (not self:IsValid (unit, name, isTradeSkill, true)) then diff --git a/Libs/LibOpenRaid/LibOpenRaid.lua b/Libs/LibOpenRaid/LibOpenRaid.lua index e76eddfb..700d9c42 100644 --- a/Libs/LibOpenRaid/LibOpenRaid.lua +++ b/Libs/LibOpenRaid/LibOpenRaid.lua @@ -43,7 +43,7 @@ if (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE and not isExpansion_Dragonflight()) t end local major = "LibOpenRaid-1.0" -local CONST_LIB_VERSION = 119 +local CONST_LIB_VERSION = 120 if (LIB_OPEN_RAID_MAX_VERSION) then if (CONST_LIB_VERSION <= LIB_OPEN_RAID_MAX_VERSION) then @@ -563,8 +563,8 @@ end ["sendPvPTalent_Schedule"] = 14, ["leaveCombat_Schedule"] = 18, ["encounterEndCooldownsCheck_Schedule"] = 24, - ["sendKeystoneInfoToParty_Schedule"] = 2, - ["sendKeystoneInfoToGuild_Schedule"] = 2, + --["sendKeystoneInfoToParty_Schedule"] = 2, + --["sendKeystoneInfoToGuild_Schedule"] = 2, } openRaidLib.Schedules = { @@ -613,7 +613,7 @@ end if (openRaidLib.Schedules.IsUniqueTimerOnCooldown(namespace, scheduleName)) then return end - time = defaultScheduleCooldownTimeByScheduleName[scheduleName] + time = defaultScheduleCooldownTimeByScheduleName[scheduleName] or time else openRaidLib.Schedules.CancelUniqueTimer(namespace, scheduleName) end @@ -2689,11 +2689,17 @@ openRaidLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNREQUEST_PREFIX, openRaid local _, instanceType = GetInstanceInfo() if (instanceType == "party") then - openRaidLib.Schedules.NewUniqueTimer(0.01, openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty, "KeystoneInfoManager", "sendKeystoneInfoToParty_Schedule") + openRaidLib.Schedules.NewUniqueTimer(math.random(1), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty, "KeystoneInfoManager", "sendKeystoneInfoToParty_Schedule") + + elseif (instanceType == "raid" or instanceType == "pvp") then + openRaidLib.Schedules.NewUniqueTimer(math.random(0, 30) + math.random(1), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty, "KeystoneInfoManager", "sendKeystoneInfoToParty_Schedule") + + else + openRaidLib.Schedules.NewUniqueTimer(math.random(4), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty, "KeystoneInfoManager", "sendKeystoneInfoToParty_Schedule") end if (IsInGuild()) then - openRaidLib.Schedules.NewUniqueTimer(math.random(0, 3) + math.random(), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToGuild, "KeystoneInfoManager", "sendKeystoneInfoToGuild_Schedule") + openRaidLib.Schedules.NewUniqueTimer(math.random(0, 10) + math.random(), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToGuild, "KeystoneInfoManager", "sendKeystoneInfoToGuild_Schedule") end end openRaidLib.commHandler.RegisterComm(CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX, openRaidLib.KeystoneInfoManager.OnReceiveRequestData) diff --git a/boot.lua b/boot.lua index 37a3cb00..67bc29e5 100644 --- a/boot.lua +++ b/boot.lua @@ -10,6 +10,11 @@ --add the original name to the global namespace _detalhes = _G.Details --[[GLOBAL]] + __details_debug = __details_debug or {} + if (__details_debug.prescience_timeline) then + wipe(__details_debug.prescience_timeline) + end + local addonName, Details222 = ... local version, build, date, tocversion = GetBuildInfo() @@ -74,6 +79,12 @@ return Details222.ColorScheme[colorScheme] end + function Details222.DebugMsg(...) + if (Details.debug) then + print("|cFFCCAAAADetails! Debug:|r", ...) + end + end + --namespace for damage spells (spellTable) Details222.DamageSpells = {} --namespace for texture @@ -127,6 +138,8 @@ } --store all data from the encounter journal Details222.EncounterJournalDump = {} + --aura scanner + Details222.AuraScan = {} ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --initialization stuff @@ -1490,6 +1503,8 @@ Details222.UnitIdCache.Party = { [4] = "party4", } +Details222.UnitIdCache.PartyIds = {"player", "party1", "party2", "party3", "party4"} + Details222.UnitIdCache.Boss = { [1] = "boss1", [2] = "boss2", diff --git a/classes/class_combat.lua b/classes/class_combat.lua index 2be32975..016a5a55 100644 --- a/classes/class_combat.lua +++ b/classes/class_combat.lua @@ -686,6 +686,8 @@ function classCombat:NovaTabela(bTimeStarted, overallCombatObject, combatId, ... combatObject.end_time = nil end + combatObject.is_challenge = Details:IsInMythicPlus() + -- o container ir� armazenar as classes de dano -- cria um novo container de indexes de seriais de jogadores --par�metro 1 classe armazenada no container, par�metro 2 = flag da classe combatObject[1].need_refresh = true combatObject[2].need_refresh = true diff --git a/classes/class_damage.lua b/classes/class_damage.lua index 6d96efa8..ade1c1bd 100644 --- a/classes/class_damage.lua +++ b/classes/class_damage.lua @@ -3463,13 +3463,26 @@ function damageClass.PredictedAugSpellsOnEnter(self) ---@type actorcontainer local utilityContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_MISC) + ---@type table> local buffUptimeTable = {} - --for each actor in the container + local CONST_SPELLID_EBONMIGHT = 395152 + local CONST_SPELLID_PRESCIENCE = 410089 + local CONST_SPELLID_BLACKATTUNEMENT = 403264 + + ---@type actor[] + local augmentationEvokers = {} + + --prescience and ebon might updatime on each actor for _, actorObject in utilityContainer:ListActors() do ---@type spellcontainer local receivedBuffs = actorObject.received_buffs_spells + --check if the actor is an augmentation evoker + if (actorObject.spec == 1473) then + augmentationEvokers[#augmentationEvokers+1] = actorObject + end + if (receivedBuffs and actorObject:IsPlayer() and actorObject:IsGroupPlayer()) then for sourceNameSpellId, spellTable in receivedBuffs:ListSpells() do local sourceName, spellId = strsplit("@", sourceNameSpellId) @@ -3477,20 +3490,28 @@ function damageClass.PredictedAugSpellsOnEnter(self) spellId = tonumber(spellId) local spellName, _, spellIcon = Details.GetSpellInfo(spellId) - if (spellName) then + if (spellName and spellId) then sourceName = detailsFramework:RemoveRealmName(sourceName) local targetName = actorObject:Name() targetName = detailsFramework:RemoveRealmName(targetName) local uptime = spellTable.uptime or 0 - buffUptimeTable[#buffUptimeTable+1] = {spellId, uptime, sourceName, targetName, actorObject:Class()} + local bCanShowOnTooltip = true + buffUptimeTable[spellId] = buffUptimeTable[spellId] or {} + table.insert(buffUptimeTable[spellId], {spellId, uptime, sourceName, targetName, actorObject:Class(), bCanShowOnTooltip}) end end end end end - table.sort(buffUptimeTable, Details.Sort2) + for spellId, buffTable in pairs(buffUptimeTable) do + local totalUptime = 0 + for i = 1, #buffTable do + totalUptime = totalUptime + buffTable[i][2] + end + table.sort(buffTable, Details.Sort2) + end Details:FormatCooltipForSpells() Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #buffUptimeTable, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords)) @@ -3499,24 +3520,86 @@ function damageClass.PredictedAugSpellsOnEnter(self) local iconSize = 22 local iconBorderInfo = Details.tooltip.icon_border_texcoord + --add the total combat time into the tooltip local combatTimeMinutes, combatTimeSeconds = math.floor(combatTime / 60), math.floor(combatTime % 60) GameCooltip:AddLine("Combat Time", combatTimeMinutes .. "m " .. combatTimeSeconds .. "s" .. " (" .. format("%.1f", 100) .. "%)") GameCooltip:AddIcon([[Interface\TARGETINGFRAME\UnitFrameIcons]], nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B) - Details:AddTooltipBackgroundStatusbar(false, 100, true, "green") + Details:AddTooltipBackgroundStatusbar(false, 100, true, "limegreen") - if (#buffUptimeTable > 0) then - for i = 1, min(30, #buffUptimeTable) do - local uptimeTable = buffUptimeTable[i] + GameCooltip:AddLine("", "") + GameCooltip:AddIcon("", nil, nil, 1, 1) + + local ebonMightTable = buffUptimeTable[CONST_SPELLID_EBONMIGHT][1] + if (ebonMightTable) then + local uptime = ebonMightTable[2] + local spellName, _, spellIcon = _GetSpellInfo(CONST_SPELLID_EBONMIGHT) + local uptimePercent = uptime / combatTime * 100 + local sourceName = ebonMightTable[3] + + if (uptime <= combatTime) then + local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60) + if (minutes > 0) then + GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") + Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "limegreen") + else + GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") + Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "limegreen") + end + + GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B) + end + end + + GameCooltip:AddLine("", "") + GameCooltip:AddIcon("", nil, nil, 1, 1) + + for i = 1, #augmentationEvokers do + local actorObject = augmentationEvokers[i] + if (actorObject:Name() == actorName) then + local buffUptimeSpellContainer = actorObject:GetSpellContainer("buff") + if (buffUptimeSpellContainer) then + local spellTable = buffUptimeSpellContainer:GetSpell(403264) + if (spellTable) then + local uptime = spellTable.uptime + local spellName, _, spellIcon = _GetSpellInfo(CONST_SPELLID_BLACKATTUNEMENT) + local uptimePercent = uptime / combatTime * 100 + + if (uptime <= combatTime) then + local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60) + if (minutes > 0) then + GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") + Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, "limegreen") + else + GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") + Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, "limegreen") + end + + GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B) + end + end + end + end + end + + GameCooltip:AddLine("", "") + GameCooltip:AddIcon("", nil, nil, 1, 1) + + --add the buff uptime into the tooltip + local allPrescienceTargets = buffUptimeTable[CONST_SPELLID_PRESCIENCE] + if (#allPrescienceTargets > 0) then + for i = 1, math.min(30, #allPrescienceTargets) do + local uptimeTable = allPrescienceTargets[i] local spellId = uptimeTable[1] local uptime = uptimeTable[2] local sourceName = uptimeTable[3] local targetName = uptimeTable[4] local targetClass = uptimeTable[5] + local bCanShow = uptimeTable[6] local uptimePercent = uptime / combatTime * 100 - if (uptime > 0 and uptimePercent < 99.5) then + if (uptime > 0 and uptimePercent < 99.5 and bCanShow) then local spellName, _, spellIcon = _GetSpellInfo(spellId) if (sourceName) then @@ -3529,10 +3612,10 @@ function damageClass.PredictedAugSpellsOnEnter(self) local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60) if (minutes > 0) then GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") - Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "green") + Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "limegreen") else GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") - Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "green") + Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "limegreen") end GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B) @@ -3542,6 +3625,36 @@ function damageClass.PredictedAugSpellsOnEnter(self) else GameCooltip:AddLine(Loc ["STRING_NO_SPELL"]) end + + local evokerObject = combatObject:GetActor(DETAILS_ATTRIBUTE_MISC, actorName) + + GameCooltip:AddLine(" ") + GameCooltip:AddIcon(" ", 1, 1, 10, 10) + + if (evokerObject) then + GameCooltip:AddLine("Prescience Uptime by Amount of Applications") + local prescienceData = evokerObject.cleu_prescience_time --real time + + if (prescienceData) then + prescienceData = prescienceData.stackTime + local totalTimeWithPrescienceUp = 0 + + for amountOfPrescienceApplied, time in ipairs(prescienceData) do + totalTimeWithPrescienceUp = totalTimeWithPrescienceUp + time + end + + for amountOfPrescienceApplied, time in ipairs(prescienceData) do + if (time > 0) then + local uptimePercent = time / combatTime * 100 + local timeString = detailsFramework:IntegerToTimer(time) + GameCooltip:AddLine("Presciece Applied: " .. amountOfPrescienceApplied, timeString .. " (" .. format("%.1f", uptimePercent) .. "%)") + --5199639 prescience icon + GameCooltip:AddIcon([[Interface\AddOns\Details\images\spells\prescience_time]], nil, nil, iconSize, iconSize) + Details:AddTooltipBackgroundStatusbar(false, time/totalTimeWithPrescienceUp*100, true, "green") + end + end + end + end end GameCooltip:AddLine("feature under test, can't disable atm") diff --git a/classes/class_utility.lua b/classes/class_utility.lua index a47769c3..d36ed427 100644 --- a/classes/class_utility.lua +++ b/classes/class_utility.lua @@ -1335,115 +1335,93 @@ function _detalhes:CloseEnemyDebuffsUptime() return end -function _detalhes:CatchRaidDebuffUptime (in_or_out) -- "DEBUFF_UPTIME_IN" +function _detalhes:CatchRaidDebuffUptime(sOperationType) -- "DEBUFF_UPTIME_IN" + if (sOperationType == "DEBUFF_UPTIME_OUT") then + local combatObject = Details:GetCurrentCombat() + local utilityContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_MISC) - if (in_or_out == "DEBUFF_UPTIME_OUT") then - local combat = _detalhes.tabela_vigente - local misc_container = combat [4]._ActorTable --error attempt to index a new value - - for _, actor in ipairs(misc_container) do - if (actor.debuff_uptime) then - for spellid, spell in pairs(actor.debuff_uptime_spells._ActorTable) do - if (spell.actived and spell.actived_at) then - spell.uptime = spell.uptime + _detalhes._tempo - spell.actived_at - actor.debuff_uptime = actor.debuff_uptime + _detalhes._tempo - spell.actived_at - spell.actived = false - spell.actived_at = nil + for _, actorObject in utilityContainer:ListActors() do + if (actorObject.debuff_uptime) then + for spellId, spellTable in pairs(actorObject.debuff_uptime_spells._ActorTable) do + if (spellTable.actived and spellTable.actived_at) then + spellTable.uptime = spellTable.uptime + _detalhes._tempo - spellTable.actived_at + actorObject.debuff_uptime = actorObject.debuff_uptime + _detalhes._tempo - spellTable.actived_at + spellTable.actived = false + spellTable.actived_at = nil end end end end - return - end - local cacheGetTime = GetTime() + elseif (sOperationType == "DEBUFF_UPTIME_IN") then + local cacheGetTime = GetTime() - if (IsInRaid()) then + if (IsInRaid()) then - local checked = {} + local checked = {} - for raidIndex = 1, GetNumGroupMembers() do + for raidIndex = 1, GetNumGroupMembers() do - local target = "raid"..raidIndex.."target" - local his_target = UnitGUID(target) + local target = "raid"..raidIndex.."target" + local his_target = UnitGUID(target) - if (his_target and not checked [his_target]) then - local rect = UnitReaction (target, "player") - if (rect and rect <= 4) then + if (his_target and not checked [his_target]) then + local rect = UnitReaction (target, "player") + if (rect and rect <= 4) then + + checked [his_target] = true + + for debuffIndex = 1, 41 do + local name, _, _, _, _, _, _, unitCaster, _, _, spellid = UnitDebuff (target, debuffIndex) + if (name and unitCaster) then + local playerGUID = UnitGUID(unitCaster) + if (playerGUID) then + + local playerName, realmName = _UnitName (unitCaster) + if (realmName and realmName ~= "") then + playerName = playerName .. "-" .. realmName + end + + _detalhes.parser:add_debuff_uptime (nil, cacheGetTime, playerGUID, playerName, 0x00000417, his_target, _UnitName (target), 0x842, nil, spellid, name, sOperationType) + end + end + end + end + end + end + + elseif (IsInGroup()) then + + local checked = {} + + for raidIndex = 1, GetNumGroupMembers()-1 do + local his_target = UnitGUID("party"..raidIndex.."target") + local rect = UnitReaction ("party"..raidIndex.."target", "player") + if (his_target and not checked [his_target] and rect and rect <= 4) then checked [his_target] = true - for debuffIndex = 1, 41 do - local name, _, _, _, _, _, _, unitCaster, _, _, spellid = UnitDebuff (target, debuffIndex) + for debuffIndex = 1, 40 do + local name, _, _, _, _, _, _, unitCaster, _, _, spellid = UnitDebuff ("party"..raidIndex.."target", debuffIndex) if (name and unitCaster) then + local playerName, realmName = _UnitName (unitCaster) local playerGUID = UnitGUID(unitCaster) if (playerGUID) then - - local playerName, realmName = _UnitName (unitCaster) if (realmName and realmName ~= "") then playerName = playerName .. "-" .. realmName end - _detalhes.parser:add_debuff_uptime (nil, cacheGetTime, playerGUID, playerName, 0x00000417, his_target, _UnitName (target), 0x842, nil, spellid, name, in_or_out) + _detalhes.parser:add_debuff_uptime (nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName ("party"..raidIndex.."target"), 0x842, nil, spellid, name, sOperationType) end end end end end - end - elseif (IsInGroup()) then - - local checked = {} - - for raidIndex = 1, GetNumGroupMembers()-1 do - local his_target = UnitGUID("party"..raidIndex.."target") - local rect = UnitReaction ("party"..raidIndex.."target", "player") + local his_target = UnitGUID("playertarget") + local rect = UnitReaction ("playertarget", "player") if (his_target and not checked [his_target] and rect and rect <= 4) then - - checked [his_target] = true - - for debuffIndex = 1, 40 do - local name, _, _, _, _, _, _, unitCaster, _, _, spellid = UnitDebuff ("party"..raidIndex.."target", debuffIndex) - if (name and unitCaster) then - local playerName, realmName = _UnitName (unitCaster) - local playerGUID = UnitGUID(unitCaster) - if (playerGUID) then - if (realmName and realmName ~= "") then - playerName = playerName .. "-" .. realmName - end - - _detalhes.parser:add_debuff_uptime (nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName ("party"..raidIndex.."target"), 0x842, nil, spellid, name, in_or_out) - end - end - end - end - end - - local his_target = UnitGUID("playertarget") - local rect = UnitReaction ("playertarget", "player") - if (his_target and not checked [his_target] and rect and rect <= 4) then - for debuffIndex = 1, 40 do - local name, _, _, _, _, _, _, unitCaster, _, _, spellid = UnitDebuff ("playertarget", debuffIndex) - if (name and unitCaster) then - local playerName, realmName = _UnitName (unitCaster) - local playerGUID = UnitGUID(unitCaster) - if (playerGUID) then - if (realmName and realmName ~= "") then - playerName = playerName .. "-" .. realmName - end - _detalhes.parser:add_debuff_uptime (nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName ("playertarget"), 0x842, nil, spellid, name, in_or_out) - end - end - end - end - - else - local his_target = UnitGUID("playertarget") - if (his_target) then - local reaction = UnitReaction ("playertarget", "player") - if (reaction and reaction <= 4) then for debuffIndex = 1, 40 do local name, _, _, _, _, _, _, unitCaster, _, _, spellid = UnitDebuff ("playertarget", debuffIndex) if (name and unitCaster) then @@ -1453,7 +1431,28 @@ function _detalhes:CatchRaidDebuffUptime (in_or_out) -- "DEBUFF_UPTIME_IN" if (realmName and realmName ~= "") then playerName = playerName .. "-" .. realmName end - _detalhes.parser:add_debuff_uptime (nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName ("playertarget"), 0x842, nil, spellid, name, in_or_out) + _detalhes.parser:add_debuff_uptime (nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName ("playertarget"), 0x842, nil, spellid, name, sOperationType) + end + end + end + end + + else + local his_target = UnitGUID("playertarget") + if (his_target) then + local reaction = UnitReaction ("playertarget", "player") + if (reaction and reaction <= 4) then + for debuffIndex = 1, 40 do + local name, _, _, _, _, _, _, unitCaster, _, _, spellid = UnitDebuff ("playertarget", debuffIndex) + if (name and unitCaster) then + local playerName, realmName = _UnitName (unitCaster) + local playerGUID = UnitGUID(unitCaster) + if (playerGUID) then + if (realmName and realmName ~= "") then + playerName = playerName .. "-" .. realmName + end + _detalhes.parser:add_debuff_uptime (nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName ("playertarget"), 0x842, nil, spellid, name, sOperationType) + end end end end @@ -1672,6 +1671,10 @@ function _detalhes:CatchRaidBuffUptime(sOperationType) -- _detalhes:Msg(string_output) end + + if (sOperationType == "BUFF_UPTIME_OUT") then + + end end local Sort2Reverse = function(a, b) @@ -2595,6 +2598,17 @@ function atributo_misc:r_connect_shadow(actor, no_refresh, combat_object) DetailsFramework.table.addunique(shadow.pets, petName) end + if (actor.cleu_prescience_time) then + local shadowPrescienceStackData = shadow.cleu_prescience_time + if (not shadowPrescienceStackData) then + shadow.cleu_prescience_time = detailsFramework.table.copy({}, actor.cleu_prescience_time) + else + for amountOfPrescienceApplied, time in pairs(actor.cleu_prescience_time.stackTime) do + shadow.cleu_prescience_time.stackTime[amountOfPrescienceApplied] = shadow.cleu_prescience_time.stackTime[amountOfPrescienceApplied] + time + end + end + end + if (actor.cc_done) then if (not shadow.cc_done_targets) then shadow.cc_done = _detalhes:GetOrderNumber() @@ -2948,6 +2962,17 @@ function _detalhes.clear:c_atributo_misc (este_jogador) end atributo_misc.__add = function(tabela1, tabela2) + if (tabela2.cleu_prescience_time) then --timeline + local shadowPrescienceStackData = tabela1.cleu_prescience_time + if (not shadowPrescienceStackData) then + tabela1.cleu_prescience_time = detailsFramework.table.copy({}, tabela2.cleu_prescience_time) + else + for amountOfPrescienceApplied, time in pairs(tabela2.cleu_prescience_time.stackTime) do + tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] = tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] + time + end + end + end + if (tabela2.cc_done) then tabela1.cc_done = tabela1.cc_done + tabela2.cc_done @@ -3223,6 +3248,15 @@ local subtractKeyValues = function(habilidade, habilidade_tabela1) end atributo_misc.__sub = function(tabela1, tabela2) + if (tabela2.cleu_prescience_time) then --timeline + local shadowPrescienceStackData = tabela1.cleu_prescience_time + if (shadowPrescienceStackData) then + for amountOfPrescienceApplied, time in pairs(tabela2.cleu_prescience_time.stackTime) do + tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] = tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] - time + end + end + end + if (tabela2.cc_done) then tabela1.cc_done = tabela1.cc_done - tabela2.cc_done diff --git a/classes/container_segments.lua b/classes/container_segments.lua index d99437a3..2098b4bf 100644 --- a/classes/container_segments.lua +++ b/classes/container_segments.lua @@ -153,7 +153,7 @@ function segmentClass:AddToOverallData(combatObject) if (combatObject.instance_type == "raid" and combatObject.is_boss) then if (Details.last_encounter ~= Details.last_encounter2) then if (Details.debug) then - Details:Msg("(debug) new boss detected 'overall_clear_newboss' is true, cleaning overall data.") + --Details:Msg("(debug) new boss detected 'overall_clear_newboss' is true, cleaning overall data.") end for index, combat in ipairs(Details:GetCombatSegments()) do @@ -198,7 +198,7 @@ function segmentClass:AddToOverallData(combatObject) end if (Details.debug) then - Details:Msg("(debug) adding the segment to overall data: " .. (combatObject:GetCombatName(true) or "no name") .. " with time of: " .. (combatObject:GetCombatTime() or "no time")) + --Details:Msg("(debug) adding the segment to overall data: " .. (combatObject:GetCombatName(true) or "no name") .. " with time of: " .. (combatObject:GetCombatTime() or "no time")) end Details.tabela_overall = Details.tabela_overall + combatObject @@ -487,7 +487,7 @@ function Details222.Combat.AddCombat(combatToBeAdded) if (bCanAddToOverall) then if (Details.debug) then - Details:Msg("(debug) overall data flag match addind the combat to overall data.") + --Details:Msg("(debug) overall data flag match addind the combat to overall data.") end --add to overall data segmentClass:AddToOverallData(combatToBeAdded) @@ -566,7 +566,7 @@ function segmentClass:AddCombat(combatObject) local canAddToOverall = Details:CanAddCombatToOverall(combatObject) if (canAddToOverall) then if (Details.debug) then - Details:Msg("(debug) overall data flag match addind the combat to overall data.") + --Details:Msg("(debug) overall data flag match addind the combat to overall data.") end segmentClass:AddToOverallData(combatObject) end diff --git a/core/aura_scan.lua b/core/aura_scan.lua new file mode 100644 index 00000000..9d10e155 --- /dev/null +++ b/core/aura_scan.lua @@ -0,0 +1,382 @@ + +local Details = _G.Details +local addonName, Details222 = ... +local detailsFramework = DetailsFramework +local _ + +local AuraUtil, wipe, C_UnitAuras, GetSpellInfo, GetTime, UnitGUID, UnitExists = AuraUtil, table.wipe, C_UnitAuras, GetSpellInfo, GetTime, UnitGUID, UnitExists + +local AuraScan = Details222.AuraScan +AuraScan.Enabled = false +AuraScan.Callbacks = {} +AuraScan.AurasToScan = {} +---store the auras applied to the unit, format: [unitGUID] = {auraInstanceId = aurainfo} +---@type table> +AuraScan.UnitAurasStorage = {} +AuraScan.AurasToTimeline = {} --which spells should be added to the timeline +AuraScan.AuraTimelineStorage = {} --store the timeline here + +function AuraScan.RegisterCallback(callback) + AuraScan.Callbacks[callback] = true +end + +function AuraScan.UnregisterCallback(callback) + AuraScan.Callbacks[callback] = nil +end + +---return a table with all auras applied to the unit, format: [unitGUID] = {auraInstanceId = aurainfo} +function AuraScan.GetOrCreateUnitAuraTable(unitGUID) + local auras = AuraScan.UnitAurasStorage[unitGUID] + if (not auras) then + auras = {} + AuraScan.UnitAurasStorage[unitGUID] = auras + end + return auras +end + +function AuraScan.WipeAllUnitAuraTables() + wipe(AuraScan.UnitAurasStorage) +end + +function AuraScan.WipeUnitAuraTable(unitGUID) + local auras = AuraScan.GetOrCreateUnitAuraTable(unitGUID) + wipe(auras) +end + +function AuraScan.GetAura(unitGUID, spellId) + if (not unitGUID or not spellId) then + return false + end + + local auraTbl = AuraScan.GetOrCreateUnitAuraTable(unitGUID) + if (not auraTbl) then + --happens if the guid is invalid + return false + end + + return auraTbl[spellId] +end + +function AuraScan.AddAura(spellId, bAddToTimeLine) + if (not spellId or type(spellId) ~= "number") then + Details:Msg("AuraScan.AddAura() called, but spellId is not a number.") + return + end + + local spellName = GetSpellInfo(spellId) + + if (spellName) then + AuraScan.AurasToScan[spellId] = true + if (bAddToTimeLine) then + AuraScan.AurasToTimeline[spellId] = true + end + else + Details:Msg("AuraScan.AddAura() called, but spellId is not a valid spell.") + end +end + +--is the aura added? +function AuraScan.IsAuraAdded(spellId) + if (not spellId or type(spellId) ~= "number") then + Details:Msg("AuraScan.IsAuraAdded() called, but spellId is not a number.") + return + end + return AuraScan.AurasToScan[spellId] +end + +function AuraScan.RemoveAura(spellId) + if (not spellId or type(spellId) ~= "number") then + Details:Msg("AuraScan.RemoveAura() called, but spellId is not a number.") + return + end + AuraScan.AurasToScan[spellId] = nil + AuraScan.AurasToTimeline[spellId] = nil +end + +function AuraScan.RemoveAllAuras() + wipe(AuraScan.AurasToScan) +end + +------------------------------------------------------------------------------------------------------------------------------ +--aura parser + +---@class details_auratimeline : table +---@field time number time when this aura had its status changed +---@field appliedTime number time when this aura was applied +---@field removedTime number time when this aura was removed +---@field expireTime number +---@field event string +---@field sourceName string +---@field targetName string +---@field targetGUID string +---@field spellId number +---@field closed boolean when true this received received aura In and Out +---@field duration number +---@field elapsedTime number +---@field auraInstanceID number +---@field addTimeLineTable details_auratimeline + +---@type table +local unitAuraTable +local targetUnitGUID +local targetName +local bIsInitialScan = false +local timeLastAuraRemovedFromTimeLine = 0 +local sourceNameLastAuraRemovedFromTimeLine = 0 +local auraInstanceIdLastAuraRemovedFromTimeLine = 0 + +local fAddAura = function(auraInfo) + ---@cast auraInfo aurainfo + local spellId = auraInfo.spellId + + if (auraInfo and auraInfo.auraInstanceID and spellId) then + if (AuraScan.IsAuraAdded(spellId)) then + unitAuraTable[auraInfo.auraInstanceID] = auraInfo + auraInfo.targetName = targetName + auraInfo.targetGUID = targetUnitGUID + + if (bIsInitialScan) then + if (auraInfo.name == "Prescience") then + Details222.DebugMsg("|cFFFFFF00INIT! Prescience Added.") + end + end + + --callback + for callback in pairs(AuraScan.Callbacks) do + callback("AURA_UPDATE", targetUnitGUID, auraInfo, "BUFF_UPTIME_IN") + end + + if (AuraScan.AurasToTimeline[spellId]) then + local sourceName = Details:GetFullName(auraInfo.sourceUnit) + local lastestEventAdded = AuraScan.AuraTimelineStorage[#AuraScan.AuraTimelineStorage] + + if (not lastestEventAdded or lastestEventAdded.time ~= GetTime() or lastestEventAdded.targetName ~= targetName) then + ---@type details_auratimeline + ---@diagnostic disable-next-line: missing-fields + local auraTimelineTable = { + appliedTime = GetTime(), + time = GetTime(), + removedTime = 0, + expireTime = auraInfo.expirationTime, --the format is GetTime() + event = "BUFF_UPTIME_IN", + sourceName = sourceName, + targetName = targetName, + targetGUID = targetUnitGUID, + spellId = spellId, + closed = false, + duration = auraInfo.duration, + elapsedTime = 0, + auraInstanceID = auraInfo.auraInstanceID, + name = auraInfo.name, + combatTime = Details:GetCurrentCombat():GetCombatTime(), + } + AuraScan.AuraTimelineStorage[#AuraScan.AuraTimelineStorage+1] = auraTimelineTable + end + end + end + end +end + +local fUpdateAura = function(auraInfo) + if (AuraScan.AurasToTimeline[auraInfo.spellId]) then + --find the aura in the timeline and update the expiration time + for i = #AuraScan.AuraTimelineStorage, 1, -1 do + local auraTimelineTable = AuraScan.AuraTimelineStorage[i] + if (auraTimelineTable.auraInstanceID == auraInfo.auraInstanceID) then + local elapsedTime = GetTime() - auraTimelineTable.time + auraTimelineTable.elapsedTime = auraTimelineTable.elapsedTime + elapsedTime + + auraTimelineTable.time = GetTime() + auraTimelineTable.expireTime = auraInfo.expirationTime + auraTimelineTable.duration = auraInfo.duration + auraTimelineTable.closed = false + Details222.DebugMsg("|cFFFFFF00REFRESH! Prescience Updated. Duration:", auraTimelineTable.duration) + break + end + end + end +end + +local fRemoveAura = function(auraInstanceId) + local auraInfo = unitAuraTable[auraInstanceId] + if (auraInfo) then + unitAuraTable[auraInstanceId] = nil + + --callback + for callback in pairs(AuraScan.Callbacks) do + callback("AURA_UPDATE", targetUnitGUID, auraInfo, "BUFF_UPTIME_OUT") + end + + if (AuraScan.AurasToTimeline[auraInfo.spellId]) then + local sourceName = Details:GetFullName(auraInfo.sourceUnit) + if (timeLastAuraRemovedFromTimeLine ~= GetTime() or auraInstanceIdLastAuraRemovedFromTimeLine ~= auraInstanceId) then + --find the aura in the timeline and update the elapsedTime + local auraTimelineTableWhenAdded + for i = #AuraScan.AuraTimelineStorage, 1, -1 do + local auraTimelineTable = AuraScan.AuraTimelineStorage[i] + if (auraTimelineTable.auraInstanceID == auraInstanceId) then + local elapsedTime = GetTime() - auraTimelineTable.time + auraTimelineTable.elapsedTime = auraTimelineTable.elapsedTime + elapsedTime + auraTimelineTableWhenAdded = auraTimelineTable + break + end + end + + if (not auraTimelineTableWhenAdded) then + Details:Msg("|cFFFF9900AuraScan: fRemoveAura() addedAura was not found in the timeline.") + return + end + + --create a new table with the information when the aura was removed + ---@type details_auratimeline + local auraClosure = { + time = GetTime(), + appliedTime = auraTimelineTableWhenAdded.appliedTime, + removedTime = GetTime(), + elapsedTime = auraTimelineTableWhenAdded.elapsedTime, + expireTime = 0, + event = "BUFF_UPTIME_OUT", + sourceName = sourceName, + targetName = targetName, + targetGUID = targetUnitGUID, + spellId = auraInfo.spellId, + closed = true, + duration = auraInfo.expirationTime, + auraInstanceID = auraInstanceId, + addTimeLineTable = auraTimelineTableWhenAdded, + name = auraInfo.name, + combatTime = Details:GetCurrentCombat():GetCombatTime(), + } + + AuraScan.AuraTimelineStorage[#AuraScan.AuraTimelineStorage+1] = auraClosure + + timeLastAuraRemovedFromTimeLine = GetTime() + sourceNameLastAuraRemovedFromTimeLine = sourceName + auraInstanceIdLastAuraRemovedFromTimeLine = auraInstanceId + end + end + end +end + +local fFullAuraScan = function(unitId, unitGUID) + local maxCount = nil + local bUsePackedAura = true + unitAuraTable = AuraScan.GetOrCreateUnitAuraTable(unitGUID) + AuraUtil.ForEachAura(unitId, "HELPFUL", maxCount, fAddAura, bUsePackedAura) +end + +function AuraScan.OnEvent(frame, eventName, unitId, updateInfo) + --get the unit guid + local unitGUID = UnitGUID(unitId) + if (not unitGUID) then + return + end + + if (not updateInfo or updateInfo.isFullUpdate) then + AuraScan.WipeUnitAuraTable(unitGUID) + unitAuraTable = AuraScan.GetOrCreateUnitAuraTable(unitGUID) + fFullAuraScan(unitId, unitGUID) + return + end + + targetUnitGUID = unitGUID + targetName = Details:GetFullName(unitId) + + --auras added + if (updateInfo.addedAuras) then + unitAuraTable = AuraScan.GetOrCreateUnitAuraTable(unitGUID) + for auraIndex = 1, #updateInfo.addedAuras do + ---@type aurainfo + local auraInfo = updateInfo.addedAuras[auraIndex] + print(unitId, targetName, auraInfo.name) + fAddAura(auraInfo) + end + end + + --auras updated + if (updateInfo.updatedAuraInstanceIDs) then + unitAuraTable = AuraScan.GetOrCreateUnitAuraTable(unitGUID) + for auraIndex = 1, #updateInfo.updatedAuraInstanceIDs do + local auraInstanceId = updateInfo.updatedAuraInstanceIDs[auraIndex] + ---@type aurainfo + local auraInfo = C_UnitAuras.GetAuraDataByAuraInstanceID(unitId, auraInstanceId) + if (auraInfo and auraInfo.auraInstanceID) then + if (auraInfo.name == "Prescience") then + local thisAuraInfo = unitAuraTable[auraInfo.auraInstanceID] + if (not thisAuraInfo) then + Details222.DebugMsg("|cFFFFAA00Prescience Updated, but not found in the table.") + end + end + fUpdateAura(auraInfo) + end + end + end + + --auras removed + if (updateInfo.removedAuraInstanceIDs) then + unitAuraTable = AuraScan.GetOrCreateUnitAuraTable(unitGUID) + for auraIndex = 1, #updateInfo.removedAuraInstanceIDs do + local auraInstanceId = updateInfo.removedAuraInstanceIDs[auraIndex] + fRemoveAura(auraInstanceId) + end + end +end + + +------------------------------------------------------------------------------------------------------------------------------ + +local scanFrame = CreateFrame("frame", "DetailsAuraScanFrame", UIParent) + +function AuraScan.Start() + AuraScan.Enabled = true + + --clear the up table holding the current player being scanned + wipe(unitAuraTable or {}) + --clear the cache of auras + AuraScan.WipeAllUnitAuraTables() + + bIsInitialScan = true + + --do the initial aura scan + for i = 1, 4 do --need to change this on raid groups, atm it's only for party + local unitId = "party" .. i + if (UnitExists(unitId)) then + local unitGUID = UnitGUID(unitId) + fFullAuraScan(unitId, unitGUID) + end + end + + local unitId = "player" + local unitGUID = UnitGUID(unitId) + fFullAuraScan(unitId, unitGUID) + + bIsInitialScan = false + + DetailsAuraScanFrame:RegisterEvent("UNIT_AURA") + DetailsAuraScanFrame:SetScript("OnEvent", AuraScan.OnEvent) +end + +function AuraScan.Stop() + if (AuraScan.Enabled) then + AuraScan.Enabled = false + DetailsAuraScanFrame:UnregisterEvent("UNIT_AURA") + DetailsAuraScanFrame:SetScript("OnEvent", nil) + + --close all opened auras (by running the remove function) + for targetGUID, auras in pairs(AuraScan.UnitAurasStorage) do + unitAuraTable = AuraScan.GetOrCreateUnitAuraTable(targetGUID) + for auraInstanceID, auraInfo in pairs(auras) do + targetUnitGUID = targetGUID + targetName = auraInfo["targetName"] + fRemoveAura(auraInstanceID) + end + end + + --callback + for callback in pairs(AuraScan.Callbacks) do + callback("TIMELINE_READY", AuraScan.AuraTimelineStorage) + end + else + Details:Msg("AuraScan.Stop() called, but AuraScan is not enabled.") + end +end \ No newline at end of file diff --git a/core/control.lua b/core/control.lua index d1d3f6b5..f68caaa7 100644 --- a/core/control.lua +++ b/core/control.lua @@ -295,8 +295,8 @@ function Details:EntrarEmCombate (...) if (Details.debug) then Details:Msg("(debug) |cFFFFFF00started a new combat|r|cFFFF7700", Details.encounter_table and Details.encounter_table.name or "") - local from = debugstack(2, 1, 0) - print("from:", from) + --local from = debugstack(2, 1, 0) + --print("from:", from) end local segmentsTable = Details:GetCombatSegments() @@ -355,14 +355,29 @@ local bFromCombatStart = true Details:UpdateParserGears(bFromCombatStart) - --get all buff already applied before the combat start + --retrieve all buffs applied before the combat starts C_Timer.After(0.05, function() - --wait the initial aura wipe done by the client on certain situations + --wait for the initial aura wipe performed by the client in certain situations Details:CatchRaidBuffUptime("BUFF_UPTIME_IN") end) Details:CatchRaidDebuffUptime("DEBUFF_UPTIME_IN") Details:UptadeRaidMembersCache() + --is inside a mythic dungeon and running a mythic+? + + if (newCombatObject.is_challenge or Details.debug) then + --local bRegisterAuraScanTimeLine = true + --Details222.AuraScan.AddAura(395152) --ebon might + --Details222.AuraScan.AddAura(395296) --the evoker buff on it self + --Details222.AuraScan.AddAura(410089--[[, bRegisterAuraScanTimeLine--]]) --prescience + --Details222.AuraScan.AddAura(413984) --Shifting Sands + --Details222.AuraScan.AddAura(409560) --Temporal Wound + --Details222.AuraScan.AddAura(360827) --Blistering Scales + --Details222.AuraScan.AddAura(410263) --Inferno's Blessing + --Details222.AuraScan.RegisterCallback(Details222.SpecHelpers[1473].OnAugmentationBuffUpdate) + --Details222.AuraScan.Start() --combat started (m+ active) + end + --Details222.TimeCapture.StartCombatTimer(Details.tabela_vigente) --we already have boss information? build .is_boss table @@ -464,6 +479,8 @@ ---@type combat local currentCombat = Details:GetCurrentCombat() + Details:SendEvent("COMBAT_PLAYER_LEAVING", nil, currentCombat) + if (currentCombat.bIsClosed) then return end @@ -505,13 +522,17 @@ end end - Details:OnCombatPhaseChanged() --.PhaseData is nil here on alpha-32 + Details:OnCombatPhaseChanged() if (currentCombat.bossFunction) then Details:CancelTimer(currentCombat.bossFunction) currentCombat.bossFunction = nil end + if (currentCombat.is_challenge or Details.debug) then + --Details222.AuraScan.Stop() --combat ended (m+ active) + end + --stop combat ticker Details:StopCombatTicker() @@ -621,7 +642,7 @@ local enemy = Details:FindEnemy() if (enemy and Details.debug) then - Details:Msg("(debug) enemy found", enemy) + --Details:Msg("(debug) enemy found", enemy) end currentCombat.enemy = enemy @@ -692,7 +713,7 @@ Details:CaptureSet(false, "spellcast", false, 15) if (Details.debug) then - Details:Msg("(debug) freezing parser for 15 seconds.") + --Details:Msg("(debug) freezing parser for 15 seconds.") end end @@ -839,12 +860,12 @@ Details.pre_pot_used = nil - --do not wipe the encounter table if is in the argus encounter ~REMOVE on 8.0 + --do not wipe the encounter table if is in the argus encounter if (Details.encounter_table and Details.encounter_table.id ~= 2092) then Details:Destroy(Details.encounter_table) else if (Details.debug) then - Details:Msg("(debug) in argus encounter, cannot wipe the encounter table.") + --Details:Msg("(debug) in argus encounter, cannot wipe the encounter table.") end end diff --git a/core/gears.lua b/core/gears.lua index 879a658e..03827938 100644 --- a/core/gears.lua +++ b/core/gears.lua @@ -1869,7 +1869,7 @@ local MIN_ILEVEL_TO_STORE = 50 local LOOP_TIME = 7 function _detalhes:IlvlFromNetwork (player, realm, core, serialNumber, itemLevel, talentsSelected, currentSpec) - if (_detalhes.debug) then + if (_detalhes.debug and false) then local talents = "Invalid Talents" if (type(talentsSelected) == "table") then talents = "" @@ -1877,7 +1877,7 @@ function _detalhes:IlvlFromNetwork (player, realm, core, serialNumber, itemLevel talents = talents .. talentsSelected [i] .. "," end end - _detalhes:Msg("(debug) Received PlayerInfo Data: " .. (player or "Invalid Player Name") .. " | " .. (itemLevel or "Invalid Item Level") .. " | " .. (currentSpec or "Invalid Spec") .. " | " .. talents .. " | " .. (serialNumber or "Invalid Serial")) + Details222.DebugMsg("Received PlayerInfo Data: " .. (player or "Invalid Player Name") .. " | " .. (itemLevel or "Invalid Item Level") .. " | " .. (currentSpec or "Invalid Spec") .. " | " .. talents .. " | " .. (serialNumber or "Invalid Serial")) end if (not player) then diff --git a/core/meta.lua b/core/meta.lua index 29618091..4fb676ab 100644 --- a/core/meta.lua +++ b/core/meta.lua @@ -683,9 +683,9 @@ local classTypeUtility = Details.atributos.misc if (Details.debug) then if (bShouldForceCollect) then - Details:Msg("(debug) collecting garbage with forced state:", bShouldForceCollect) + --Details:Msg("(debug) collecting garbage with forced state:", bShouldForceCollect) else - Details:Msg("(debug) collecting garbage.") + --Details:Msg("(debug) collecting garbage.") end end @@ -730,8 +730,8 @@ local classTypeUtility = Details.atributos.misc Details222.GarbageCollector.lastCollectTime = Details._tempo if (Details.debug) then - Details:Msg("(debug) executing: collectgarbage().") - collectgarbage() + --Details:Msg("(debug) executing: collectgarbage().") + --collectgarbage() end end diff --git a/core/parser.lua b/core/parser.lua index 13764124..5e5f9b38 100755 --- a/core/parser.lua +++ b/core/parser.lua @@ -190,12 +190,12 @@ ---@field key7 number local augmentation_aura_list = { - [395152] = true,--ebon might (evoker 10.1.5) 395296 = the evoker buff on it self - [413984] = true, - [410089] = true,--prescience (evoker 10.1.5) - [409560] = true, - [360827] = true, - [410263] = true, + [395152] = true, --ebon might (evoker 10.1.5) 395296 = the evoker buff on it self + [413984] = true, --Shifting Sands + [410089] = true, --prescience (evoker 10.1.5) + [409560] = true, --Temporal Wound + [360827] = true, --Blistering Scales + [410263] = true, --Inferno's Blessing } --list of buffs given by another player but should also be credited to the which received it @@ -213,6 +213,7 @@ local augmentation_cache = { ebon_might = {}, prescience = {}, + prescience_stacks = {}, ---@type table breath_targets = {}, flyaway = {}, @@ -778,7 +779,6 @@ sourceFlags = reflection.who_flags --data of the aura that caused the reflection - --print("2", spellid, GetSpellInfo(spellid)) isreflected = spellId --which spell was reflected spellId = reflection.spellid --which spell made the reflection spellName = reflection.spellname @@ -908,7 +908,7 @@ Details.WhoAggroTimer = C_Timer.NewTimer(0.1, whoAggro) Details.WhoAggroTimer.HitBy = "|cFFFFFF00First Hit|r: " .. (link or "") .. " from " .. (sourceName or "Unknown") - print("debug:", Details.WhoAggroTimer.HitBy) + Details:Msg("(debug):", Details.WhoAggroTimer.HitBy) end Details:EntrarEmCombate(sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags) @@ -1714,7 +1714,7 @@ local this_event = t[i] if (not this_event) then - return print("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) + return Details:Msg("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) end this_event [1] = true --true if this is a damage || false for healing @@ -1809,7 +1809,7 @@ local this_event = t [i] if (not this_event) then - return print("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) + return Details:Msg("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) end this_event [1] = true --true if this is a damage || false for healing @@ -1929,7 +1929,7 @@ local this_event = t [i] if (not this_event) then - return print("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) + return Details:Msg("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) end this_event [1] = true --true if this is a damage || false for healing @@ -2827,7 +2827,7 @@ local thisEvent = deathLog[i] if (not thisEvent) then - return print("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) + return Details:Msg("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) end thisEvent[1] = 5 --5 = buff aplication @@ -3328,7 +3328,7 @@ local this_event = t [i] if (not this_event) then - return print("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) + return Details:Msg("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) end this_event [1] = 4 --4 = debuff aplication @@ -3375,7 +3375,7 @@ local this_event = t [i] if (not this_event) then - return print("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) + return Details:Msg("Parser Event Error -> Set to 16 DeathLogs and /reload", i, _amount_of_last_events) end this_event [1] = 4 --4 = debuff aplication @@ -3931,7 +3931,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 petName, ownerName, ownerGUID, ownerFlags = Details.tabela_pets:GetPetOwner(sourceSerial, sourceName, sourceFlags) if (petName) then ownerActor = _current_misc_container:GetOrCreateActor(ownerGUID, ownerName, ownerFlags, true) - --print("pet found:", petName, ownerName, ownerGUID, ownerFlags) end end @@ -4084,10 +4083,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 amountOfCasts = amountOfCasts + 1 _current_combat.amountCasts[sourceName][spellName] = amountOfCasts - --if (sourceSerial == UnitGUID("player")) then - -- print(sourceName, spellName, amountOfCasts) - --end - ------------------------------------------------------------------------------------------------ --record cooldowns cast which can't track with buff applyed --a player is the caster @@ -4609,7 +4604,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 newEventTable[4] = enemyCastTime --when the event happened using unix time newEventTable[5] = 0 --player health when the event happened newEventTable[6] = enemyName --source name - --print("addin enemy cast event", alvo_name, i, enemyCastTime+0.1, ">", eventTime) tinsert(eventsBeforePlayerDeath, i, newEventTable) currentEnemyCastIndex = enemyCastEventIndex + 1 break @@ -5137,6 +5131,29 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 return Details.zone_type end + local gotAggro = false + function Details.parser_functions:UNIT_FLAGS(...) + if (gotAggro) then + return + end + + if (Details:GetZoneType() ~= "raid" and Details:GetZoneType() ~= "party") then + return + end + + local unitId = ... + + if (UnitExists(unitId)) then + if (UnitAffectingCombat(unitId) and not UnitAffectingCombat("player")) then + Details.LastAggro = UnitName(unitId) + gotAggro = true + C_Timer.After(1, function() + gotAggro = false + end) + end + end + end + function Details.parser_functions:ZONE_CHANGED_NEW_AREA(...) return Details.Schedules.After(1, Details.Check_ZONE_CHANGED_NEW_AREA) end @@ -5152,6 +5169,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 _in_resting_zone = IsResting() parser:WipeSourceCache() + Details.listener:UnregisterEvent("UNIT_FLAGS") _is_in_instance = false @@ -5174,10 +5192,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 Details.time_type = Details.time_type_original - if (Details.debug) then - Details:Msg("(debug) zone change:", Details.zone_name, "is a", Details.zone_type, "zone.") - end - if (Details.is_in_arena and zoneType ~= "arena") then Details:LeftArena() end @@ -5260,6 +5274,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 Details.ScheduleLoadStorage() end end + + Details.listener:RegisterEvent("UNIT_FLAGS") end if (Details:IsInInstance()) then @@ -5306,7 +5322,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 if (zoneType == "party") then local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true) if (openRaidLib) then - print("sent my keystone to party") openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty() end end @@ -5315,6 +5330,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 Details.current_exp_raid_encounters[encounterID] = true end + Details222.DebugMsg("|cFFFFFF00Who Aggro by UNIT_FLAGS:", Details.LastAggro) + if (not Details.WhoAggroTimer and Details.announce_firsthit.enabled) then Details.WhoAggroTimer = C_Timer.NewTimer(0.1, whoAggro) for i = 1, 5 do @@ -5382,8 +5399,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 return end - Details222.Cache.ClearAugmentationCache() - Details.latest_ENCOUNTER_END = Details.latest_ENCOUNTER_END or 0 if (Details.latest_ENCOUNTER_END + 15 > GetTime()) then return @@ -5432,6 +5447,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 Details:SendEvent("COMBAT_ENCOUNTER_END", nil, ...) + Details222.Cache.ClearAugmentationCache() + Details:Destroy(Details.encounter_table) Details:Destroy(dk_pets_cache.army) Details:Destroy(dk_pets_cache.apoc) @@ -5619,7 +5636,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 --can also run when the player leaves combat state (regen enabled) function Details:RunScheduledEventsAfterCombat(OnRegenEnabled) if (Details.debug) then - Details:Msg("(debug) running scheduled events after combat end.") + --Details:Msg("(debug) running scheduled events after combat end.") end @@ -5724,20 +5741,14 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 wipe(keystoneLevels) local libOpenRaid = LibStub("LibOpenRaid-1.0", true) - --print("saveGroupMembersKeystoneLevel() called", libOpenRaid, GetNumGroupMembers()-1) - for i = 1, GetNumGroupMembers()-1 do local unitId = "party" .. i if (UnitExists(unitId)) then local unitKeystoneInfo = libOpenRaid.GetKeystoneInfo(unitId) - --print("unitExists", unitId, unitKeystoneInfo) if (unitKeystoneInfo) then local unitName = Details:GetFullName(unitId) keystoneLevels[unitName] = unitKeystoneInfo.level - --print("saved keystone level for", unitName, unitKeystoneInfo.level) end - else - --print("unit does not exist", unitId) end end @@ -5747,7 +5758,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 if (unitKeystoneInfo) then local unitName = Details:GetFullName(unitId) keystoneLevels[unitName] = unitKeystoneInfo.level - --print("saved keystone level for", unitName, unitKeystoneInfo.level) end end end @@ -5805,9 +5815,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 C_Timer.After(0, function() if (ChallengeModeCompleteBanner) then ChallengeModeCompleteBanner.timeToHold = 0.1 - --print("ChallengeModeCompleteBanner.timeToHold Existed!") - else - --print("ChallengeModeCompleteBanner.timeToHold DID NOT Existed!") end end) end @@ -5852,10 +5859,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 end function Details.parser_functions:PLAYER_REGEN_ENABLED(...) - if (Details.debug) then - Details:Msg("(debug) |cFFFFFF00PLAYER_REGEN_ENABLED|r event triggered.") - end - if (Details.auto_swap_to_dynamic_overall) then Details:InstanceCall(autoSwapDynamicOverallData, false) end @@ -5949,6 +5952,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 end end + --[=[ --this is mostly triggered when the player enters in a dual against another player function Details.parser_functions:UNIT_FACTION(unit) if (true) then @@ -6001,6 +6005,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 end end end + --]=] function Details.parser_functions:ROLE_CHANGED_INFORM(...) if (Details.last_assigned_role ~= _UnitGroupRolesAssigned("player")) then @@ -6637,39 +6642,39 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 for n, nn in pairs(damage_cache) do amount = amount + 1 end - print("parser damage_cache", amount) + Details:Msg("parser damage_cache", amount) amount = 0 for n, nn in pairs(damage_cache_pets) do amount = amount + 1 end - print("parser damage_cache_pets", amount) + Details:Msg("parser damage_cache_pets", amount) amount = 0 for n, nn in pairs(damage_cache_petsOwners) do amount = amount + 1 end - print("parser damage_cache_petsOwners", amount) + Details:Msg("parser damage_cache_petsOwners", amount) amount = 0 for n, nn in pairs(healing_cache) do amount = amount + 1 end - print("parser healing_cache", amount) + Details:Msg("parser healing_cache", amount) amount = 0 for n, nn in pairs(energy_cache) do amount = amount + 1 end - print("parser energy_cache", amount) + Details:Msg("parser energy_cache", amount) amount = 0 for n, nn in pairs(misc_cache) do amount = amount + 1 end - print("parser misc_cache", amount) - print("group damage", #Details.cache_damage_group) - print("group damage", #Details.cache_healing_group) + Details:Msg("parser misc_cache", amount) + Details:Msg("group damage", #Details.cache_damage_group) + Details:Msg("group damage", #Details.cache_healing_group) end function Details:GetActorsOnDamageCache() @@ -6680,14 +6685,17 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 return Details.cache_healing_group end + --called when the zone type changes and ENCOUNTER_END event function Details222.Cache.ClearAugmentationCache() Details:Destroy(augmentation_cache.ebon_might) --~roskash Details:Destroy(augmentation_cache.prescience) Details:Destroy(augmentation_cache.shield) Details:Destroy(augmentation_cache.infernobless) Details:Destroy(augmentation_cache.breath_targets) + Details:Destroy(augmentation_cache.prescience_stacks) end + --called when restaring the garbage collector, on some options change, at the end of a combat (before COMBAT_PLAYER_LEAVE and after COMBAT_PLAYER_LEAVING) function Details:ClearParserCache(bIsFromCombatStart) --~wipe Details:Destroy(damage_cache) Details:Destroy(damage_cache_pets) @@ -6720,6 +6728,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 if (Details.zone_type ~= "party") then Details:Destroy(augmentation_cache.ebon_might) --~roskash Details:Destroy(augmentation_cache.prescience) + Details:Destroy(augmentation_cache.prescience_stacks) Details:Destroy(augmentation_cache.shield) Details:Destroy(augmentation_cache.infernobless) end @@ -7033,7 +7042,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 is_using_spellId_override = Details.override_spellids - return Details:ClearParserCache(bIsFromCombatStart) + Details:ClearParserCache(bIsFromCombatStart) end function Details.DumpIgnoredNpcs() @@ -7275,3 +7284,16 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 end + +function detailsParserDebugFrame:BlinkIcon(spellId, iconId) + local spellName, _, spellIcon = GetSpellInfo(spellId) + local icon = self.AllIcons[iconId] + + if (spellIcon) then + icon:SetTexture(spellIcon) + icon:Show() + C_Timer.After(1, function() + icon:Hide() + end) + end +end \ No newline at end of file diff --git a/core/util.lua b/core/util.lua index 14dc8764..db3e230c 100644 --- a/core/util.lua +++ b/core/util.lua @@ -35,6 +35,10 @@ local gump = Details.gump --details local + function Details:IsInMythicPlus() + return C_ChallengeMode and C_ChallengeMode.IsChallengeModeActive and C_ChallengeMode.IsChallengeModeActive() + end + local predicateFunc = function(spellIdToFind, casterName, _, name, icon, applications, dispelName, duration, expirationTime, sourceUnitId, isStealable, nameplateShowPersonal, spellId, canApplyAura, isBossAura, isFromPlayerOrPlayerPet, nameplateShowAll, timeMod, applications) if (spellIdToFind == spellId and UnitExists(sourceUnitId)) then if (casterName == Details:GetUnitNameForAPI(sourceUnitId)) then @@ -1287,7 +1291,7 @@ end --coach feature if (not Details.Coach.Server.IsEnabled()) then if (Details.debug) then - Details:Msg("coach is disabled, the combat is now over!") + --Details:Msg("coach is disabled, the combat is now over!") end end diff --git a/frames/window_breakdown/breakdown_spells_targetframes.lua b/frames/window_breakdown/breakdown_spells_targetframes.lua index c2538d7d..ed4b2d20 100644 --- a/frames/window_breakdown/breakdown_spells_targetframes.lua +++ b/frames/window_breakdown/breakdown_spells_targetframes.lua @@ -85,6 +85,24 @@ local updateTargetBar = function(targetBar, index, combatObject, scrollFrame, he --statusbar color targetBar.statusBar:SetStatusBarColor(1, 1, 1, 1) + + local platerNameplates = _G.Plater + if (platerNameplates) then + local npcId = tonumber(targetActorObject.aID) + if (npcId) then + local platerProfile = platerNameplates.db.profile + local npcColors = platerProfile.npc_colors + local platerNpcColorTable = npcColors[npcId] + if (platerNpcColorTable) then + if (platerNpcColorTable[1] == true) then + local color = platerNpcColorTable[3] + local r, g, b, a = DF:ParseColors(color) + targetBar.statusBar:SetStatusBarColor(r, g, b, a) + end + end + end + end + targetBar.combatTime = combatTime targetBar.actorName = bkTargetData.name diff --git a/functions/events.lua b/functions/events.lua index 4bc2849e..1fbcdb6b 100644 --- a/functions/events.lua +++ b/functions/events.lua @@ -36,6 +36,7 @@ ["COMBAT_ENCOUNTER_END"] = {}, ["COMBAT_PLAYER_ENTER"] = {}, ["COMBAT_PLAYER_LEAVE"] = {}, + ["COMBAT_PLAYER_LEAVING"] = {}, ["COMBAT_PLAYER_TIMESTARTED"] = {}, ["COMBAT_BOSS_WIPE"] = {}, ["COMBAT_BOSS_DEFEATED"] = {}, @@ -49,6 +50,7 @@ ["COMBAT_ARENA_END"] = {}, ["COMBAT_MYTHICDUNGEON_START"] = {}, ["COMBAT_MYTHICDUNGEON_END"] = {}, + ["COMBAT_MYTHICPLUS_OVERALL_READY"] = {}, --area ["ZONE_TYPE_CHANGED"] = {}, @@ -100,6 +102,7 @@ local common_events = { ["COMBAT_ENCOUNTER_END"] = true, ["COMBAT_PLAYER_ENTER"] = true, ["COMBAT_PLAYER_LEAVE"] = true, + ["COMBAT_PLAYER_LEAVING"] = true, ["COMBAT_PLAYER_TIMESTARTED"] = true, ["COMBAT_BOSS_WIPE"] = true, ["COMBAT_BOSS_DEFEATED"] = true, @@ -113,6 +116,7 @@ local common_events = { ["COMBAT_ARENA_END"] = true, ["COMBAT_MYTHICDUNGEON_START"] = true, ["COMBAT_MYTHICDUNGEON_END"] = true, + ["COMBAT_MYTHICPLUS_OVERALL_READY"] = true, ["GROUP_ONENTER"] = true, ["GROUP_ONLEAVE"] = true, ["ZONE_TYPE_CHANGED"] = true, diff --git a/functions/mythicdungeon.lua b/functions/mythicdungeon.lua index c71f98c7..31a82397 100644 --- a/functions/mythicdungeon.lua +++ b/functions/mythicdungeon.lua @@ -64,6 +64,8 @@ function DetailsMythicPlusFrame.MergeSegmentsOnEnd() --~merge local newCombat = Details:GetCurrentCombat() local segmentsTable = Details:GetCombatSegments() + newCombat.is_challenge = true + local timeInCombat = 0 local startDate, endDate = "", "" local lastSegment @@ -209,6 +211,8 @@ function DetailsMythicPlusFrame.MergeSegmentsOnEnd() --~merge instance:InstanceAlert ("Showing Mythic+ Run Segment", {[[Interface\AddOns\Details\images\icons]], 16, 16, false, 434/512, 466/512, 243/512, 273/512}, 6, func, true) end end + + Details:SendEvent("COMBAT_MYTHICPLUS_OVERALL_READY") end --after each boss fight, if enalbed on settings, create an extra segment with all trash segments from the boss just killed diff --git a/functions/slash.lua b/functions/slash.lua index 58f6842b..df6d5ec6 100644 --- a/functions/slash.lua +++ b/functions/slash.lua @@ -1933,9 +1933,11 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0") if (openRaidLib) then if (not DetailsKeystoneInfoFrame) then + ---@type detailsframework + local detailsFramework = DetailsFramework local CONST_WINDOW_WIDTH = 614 - local CONST_WINDOW_HEIGHT = 700 + local CONST_WINDOW_HEIGHT = 720 local CONST_SCROLL_LINE_HEIGHT = 20 local CONST_SCROLL_LINE_AMOUNT = 30 @@ -1948,7 +1950,7 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then local backdrop_color_inguild = {.5, .8, .5, 0.2} local backdrop_color_on_enter_inguild = {.5, 1, .5, 0.4} - local f = DetailsFramework:CreateSimplePanel(UIParent, CONST_WINDOW_WIDTH, CONST_WINDOW_HEIGHT, "M+ Keystones (/key)", "DetailsKeystoneInfoFrame") + local f = detailsFramework:CreateSimplePanel(UIParent, CONST_WINDOW_WIDTH, CONST_WINDOW_HEIGHT, "M+ Keystones (/key)", "DetailsKeystoneInfoFrame") f:SetPoint("center", UIParent, "center", 0, 0) f:SetScript("OnMouseDown", nil) --disable framework native moving scripts @@ -1959,15 +1961,43 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then LibWindow.MakeDraggable(f) LibWindow.RestorePosition(f) - local scaleBar = DetailsFramework:CreateScaleBar(f, Details.keystone_frame) + f:SetScript("OnEvent", function(self, event, ...) + if (f:IsShown()) then + if (event == "GUILD_ROSTER_UPDATE") then + local bUpdateOkay = ... + if (bUpdateOkay) then + self:RefreshData() + end + end + end + end) + + local scaleBar = detailsFramework:CreateScaleBar(f, Details.keystone_frame) f:SetScale(Details.keystone_frame.scale) - local statusBar = DetailsFramework:CreateStatusBar(f) + local statusBar = detailsFramework:CreateStatusBar(f) statusBar.text = statusBar:CreateFontString(nil, "overlay", "GameFontNormal") statusBar.text:SetPoint("left", statusBar, "left", 5, 0) - statusBar.text:SetText("By Terciob | From Details! Damage Meter|Built with Details! Framework | Data from Open Raid Library") - DetailsFramework:SetFontSize(statusBar.text, 11) - DetailsFramework:SetFontColor(statusBar.text, "gray") + statusBar.text:SetText("By Terciob | From Details! Damage Meter") + detailsFramework:SetFontSize(statusBar.text, 12) + detailsFramework:SetFontColor(statusBar.text, "gray") + + local requestFromGuildButton = detailsFramework:CreateButton(f, function() + local guildName = GetGuildInfo("player") + if (guildName) then + f:RegisterEvent("GUILD_ROSTER_UPDATE") + C_Timer.After(30, function() + f:UnregisterEvent("GUILD_ROSTER_UPDATE") + end) + C_GuildInfo.GuildRoster() + openRaidLib.RequestKeystoneDataFromGuild() + end + end, 100, 20, "Request from Guild") + requestFromGuildButton:SetPoint("bottomleft", statusBar, "topleft", 2, 2) + requestFromGuildButton:SetTemplate(detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")) + requestFromGuildButton:SetIcon("UI-RefreshButton", 20, 20, "overlay", {0, 1, 0, 1}, "lawngreen") + requestFromGuildButton:SetFrameLevel(f:GetFrameLevel()+5) + f.RequestFromGuildButton = requestFromGuildButton --header local headerTable = { @@ -1995,8 +2025,8 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then header_click_callback = headerOnClickCallback, } - f.Header = DetailsFramework:CreateHeader(f, headerTable, headerOptions, "DetailsKeystoneInfoFrameHeader") - f.Header:SetPoint("topleft", f, "topleft", 5, -25) + f.Header = detailsFramework:CreateHeader(f, headerTable, headerOptions, "DetailsKeystoneInfoFrameHeader") + f.Header:SetPoint("topleft", f, "topleft", 3, -25) --scroll local refreshScrollLines = function(self, data, offset, totalLines) @@ -2033,13 +2063,13 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then line.icon:SetTexCoord(L+0.02, R-0.02, T+0.02, B-0.02) --remove the realm name from the player name (if any) - local unitNameNoRealm = DetailsFramework:RemoveRealmName(unitName) + local unitNameNoRealm = detailsFramework:RemoveRealmName(unitName) line.playerNameText.text = unitNameNoRealm line.keystoneLevelText.text = level line.dungeonNameText.text = mapName - DetailsFramework:TruncateText(line.dungeonNameText, 240) + detailsFramework:TruncateText(line.dungeonNameText, 240) line.classicDungeonNameText.text = "" --mapNameChallenge - DetailsFramework:TruncateText(line.classicDungeonNameText, 120) + detailsFramework:TruncateText(line.classicDungeonNameText, 120) line.inMyParty = inMyParty > 0 line.inMyGuild = isGuildMember @@ -2083,8 +2113,8 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then end end - local scrollFrame = DetailsFramework:CreateScrollBox(f, "$parentScroll", refreshScrollLines, {}, CONST_WINDOW_WIDTH-10, CONST_WINDOW_HEIGHT-70, CONST_SCROLL_LINE_AMOUNT, CONST_SCROLL_LINE_HEIGHT) - DetailsFramework:ReskinSlider(scrollFrame) + local scrollFrame = detailsFramework:CreateScrollBox(f, "$parentScroll", refreshScrollLines, {}, CONST_WINDOW_WIDTH-10, CONST_WINDOW_HEIGHT-90, CONST_SCROLL_LINE_AMOUNT, CONST_SCROLL_LINE_HEIGHT) + detailsFramework:ReskinSlider(scrollFrame) scrollFrame:SetPoint("topleft", f.Header, "bottomleft", -1, -1) scrollFrame:SetPoint("topright", f.Header, "bottomright", 0, -1) @@ -2115,7 +2145,7 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}) line:SetBackdropColor(unpack(backdrop_color)) - DetailsFramework:Mixin(line, DetailsFramework.HeaderFunctions) + detailsFramework:Mixin(line, detailsFramework.HeaderFunctions) line:SetScript("OnEnter", lineOnEnter) line:SetScript("OnLeave", lineOnLeave) @@ -2125,19 +2155,19 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then icon:SetSize(CONST_SCROLL_LINE_HEIGHT - 2, CONST_SCROLL_LINE_HEIGHT - 2) --player name - local playerNameText = DetailsFramework:CreateLabel(line) + local playerNameText = detailsFramework:CreateLabel(line, "") --keystone level - local keystoneLevelText = DetailsFramework:CreateLabel(line) + local keystoneLevelText = detailsFramework:CreateLabel(line, "") --dungeon name - local dungeonNameText = DetailsFramework:CreateLabel(line) + local dungeonNameText = detailsFramework:CreateLabel(line, "") --classic dungeon name - local classicDungeonNameText = DetailsFramework:CreateLabel(line) + local classicDungeonNameText = detailsFramework:CreateLabel(line, "") --player rating - local ratingText = DetailsFramework:CreateLabel(line) + local ratingText = detailsFramework:CreateLabel(line, "") line.icon = icon line.playerNameText = playerNameText @@ -2170,6 +2200,16 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then local guildUsers = {} local totalMembers, onlineMembers, onlineAndMobileMembers = GetNumGuildMembers() + --[=[ + local unitsInMyGroup = { + [Details:GetFullName("player")] = true, + } + for i = 1, GetNumGroupMembers() do + local unitName = Details:GetFullName("party" .. i) + unitsInMyGroup[unitName] = true + end + --]=] + --create a string to use into the gsub call when removing the realm name from the player name, by default all player names returned from GetGuildRosterInfo() has PlayerName-RealmName format local realmNameGsub = "%-.*" local guildName = GetGuildInfo("player") @@ -2258,18 +2298,23 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then --sort by player class if (columnIndex == 1) then sortByIndex = 5 + --sort by player name elseif (columnIndex == 2) then sortByIndex = 1 + --sort by keystone level elseif (columnIndex == 3) then sortByIndex = 2 + --sort by dungeon name elseif (columnIndex == 4) then sortByIndex = 3 + --sort by classic dungeon name --elseif (columnIndex == 5) then -- sortByIndex = 4 + --sort by mythic+ ranting elseif (columnIndex == 5) then sortByIndex = 6 @@ -2290,7 +2335,7 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then end end - newData.offlineGuildPlayers = DetailsFramework.table.reverse(newData.offlineGuildPlayers) + newData.offlineGuildPlayers = detailsFramework.table.reverse(newData.offlineGuildPlayers) --put players in the group at the top of the list if (IsInGroup() and not IsInRaid()) then @@ -2334,17 +2379,23 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then end) end - --call an update on the guild roster - if (C_GuildInfo and C_GuildInfo.GuildRoster) then - C_GuildInfo.GuildRoster() - end - --show the frame DetailsKeystoneInfoFrame:Show() openRaidLib.RegisterCallback(DetailsKeystoneInfoFrame, "KeystoneUpdate", "OnKeystoneUpdate") - openRaidLib.WipeKeystoneData() + local guildName = GetGuildInfo("player") + if (guildName) then + --call an update on the guild roster + if (C_GuildInfo and C_GuildInfo.GuildRoster) then + C_GuildInfo.GuildRoster() + end + DetailsKeystoneInfoFrame.RequestFromGuildButton:Enable() + else + DetailsKeystoneInfoFrame.RequestFromGuildButton:Disable() + end + + --openRaidLib.WipeKeystoneData() if (IsInRaid()) then openRaidLib.RequestKeystoneDataFromRaid() @@ -2352,8 +2403,6 @@ if (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then openRaidLib.RequestKeystoneDataFromParty() end - openRaidLib.RequestKeystoneDataFromGuild() - DetailsKeystoneInfoFrame.RefreshData() end end diff --git a/functions/spec_augmentation.lua b/functions/spec_augmentation.lua index e0392435..f54d65c8 100644 --- a/functions/spec_augmentation.lua +++ b/functions/spec_augmentation.lua @@ -3,6 +3,13 @@ local addonName, Details222 = ... local Details = Details local _ +local CONST_SPELLID_EBONMIGHT = 395152 +local CONST_SPELLID_SS = 413984 +local CONST_SPELLID_PRESCIENCE = 410089 +local CONST_SPELLID_EONS_BREATH = 409560 +local CONST_SPELLID_TANK_SHIELD = 360827 +local CONST_SPELLID_INFERNOBLESS = 410263 + local UnitExists = UnitExists local UnitIsUnit = UnitIsUnit @@ -11,12 +18,240 @@ local augmentationCache = Details222.SpecHelpers[1473].augmentation_cache local playerRealmName = GetRealmName() +local getAmountOfBuffsAppliedBySpellId = function(spellId) + local amountBuffs = 0 + local spellName = GetSpellInfo(spellId) + for i, unitId in ipairs(Details222.UnitIdCache.PartyIds) do + if (UnitExists(unitId)) then + for o = 1, 40 do + local auraName = UnitBuff(unitId, o) + if (auraName == spellName) then + amountBuffs = amountBuffs + 1 + break + elseif (not auraName) then + break + end + end + else + break + end + end + return amountBuffs +end +local eventListener = Details:CreateEventListener() +--eventListener:RegisterEvent("COMBAT_PLAYER_ENTER") +eventListener:RegisterEvent("COMBAT_PLAYER_LEAVING", function(eventName, combatObject) + --close the time on the current amount of prescience stacks the evoker have + ---@type combat + local combat = Details:GetCurrentCombat() + ---@type actorcontainer + local damageContainer = combat:GetContainer(DETAILS_ATTRIBUTE_MISC) + --print(1, "COMBAT_PLAYER_LEAVING", next(augmentationCache.prescience_stacks)) + for actorName, stackInfo in pairs(augmentationCache.prescience_stacks) do + local actorObject = damageContainer:GetActor(actorName) + local currentAmountOfApplications = stackInfo.currentStacks + if (currentAmountOfApplications >= 1 and currentAmountOfApplications <= 5) then + --close the time the evoker had this amount of stacks + local timeOfTheLastEvent = stackInfo.latestStackUpdateTime + local timeNow = GetTime() + local timeDiff = timeNow - timeOfTheLastEvent + if (timeDiff > 0) then + stackInfo.stackTime[currentAmountOfApplications] = stackInfo.stackTime[currentAmountOfApplications] + timeDiff + end + end + + actorObject.prescience_stack_data_by_timeline = DetailsFramework.table.copy({}, stackInfo.stackTime) + end +end) + +---@class details_evoker_presciencetimeline : table +---@field currentStacks number amount of stacks the evoker has at the moment +---@field stackTime table amountof time the evoker had the amount of stacks, one stack if the first index, 5 stacks if the last index +---@field latestStackUpdateTime number GetTime() of the latest stack amount update, this is used to calculate the time the evoker had each amount of stacks + +local latestPrescienceEvent = 0 +local latestAuraInstanceId = 0 +function augmentationFunctions.OnAugmentationBuffUpdate(eventName, ...) + ---@combat + local currentCombat = Details:GetCurrentCombat() + + --test #1: calculate the amount of stack in real time + if (eventName == "AURA_UPDATE" and Details.in_combat) then + local targetGUID, auraInfo, eventType = ... + local spellId = auraInfo.spellId + + if (spellId == CONST_SPELLID_PRESCIENCE) then + --[=[ + if (latestPrescienceEvent ~= GetTime()) then + latestPrescienceEvent = GetTime() + latestAuraInstanceId = auraInfo.instanceId + else + if (latestAuraInstanceId == auraInfo.instanceId) then + return + end + latestPrescienceEvent = GetTime() + latestAuraInstanceId = auraInfo.instanceId + end + + if ((currentCombat and currentCombat.is_challenge) or Details.debug) then + local sourceUnitId = auraInfo.sourceUnit + local sourceGUID = UnitGUID(sourceUnitId) + local sourceName = Details:GetFullName(sourceUnitId) + + local evokerUtilityObject = currentCombat:GetContainer(DETAILS_ATTRIBUTE_MISC):GetOrCreateActor(sourceGUID, sourceName, 0x514, true) + + if (evokerUtilityObject) then + local stackInfo = evokerUtilityObject.prescience_stack_data2 + if (not stackInfo) then + stackInfo = { + currentStacks = 0, + stackTime = {0, 0, 0, 0, 0}, + latestStackUpdateTime = GetTime() + } + evokerUtilityObject.prescience_stack_data2 = stackInfo + end + + if (eventType == "BUFF_UPTIME_IN") then + local currentAmountOfApplications = stackInfo.currentStacks + --print("in", currentAmountOfApplications, GetTime()) + if (currentAmountOfApplications > 0) then + --the the time the evoker had this amount of stacks + local timeOfTheLastEvent = stackInfo.latestStackUpdateTime + local timeNow = GetTime() + local timeDiff = timeNow - timeOfTheLastEvent + if (timeDiff > 0) then + stackInfo.stackTime[currentAmountOfApplications] = stackInfo.stackTime[currentAmountOfApplications] + timeDiff + end + end + + stackInfo.latestStackUpdateTime = GetTime() + stackInfo.currentStacks = stackInfo.currentStacks + 1 + + elseif (eventType == "BUFF_UPTIME_OUT") then + local currentAmountOfApplications = stackInfo.currentStacks + --print("out", currentAmountOfApplications) + if (currentAmountOfApplications > 0) then + --the the time the evoker had this amount of stacks + local timeOfTheLastEvent = stackInfo.latestStackUpdateTime + local timeNow = GetTime() + local timeDiff = timeNow - timeOfTheLastEvent + if (timeDiff > 0) then + stackInfo.stackTime[currentAmountOfApplications] = stackInfo.stackTime[currentAmountOfApplications] + timeDiff + end + end + + stackInfo.latestStackUpdateTime = GetTime() + stackInfo.currentStacks = stackInfo.currentStacks - 1 + end + end + end + --]=] + end + + --test #2: calculate the amount of stacks post combat using a list of events (timeline) + --note to self: I'm not working with real time data, these are past events, GetTime() and time() will always return the same value + elseif (eventName == "TIMELINE_READY") then --not in use + --if true then return end + --timelineTable is an indexed table with all the timeline events + ---@type details_auratimeline[] + local timelineTable = ... + + __details_debug.prescience_timeline = __details_debug.prescience_timeline or {} + __details_debug.prescience_timeline[#__details_debug.prescience_timeline+1] = timelineTable + + --amount of time the evoker had the amount of stacks + --[evokerName] = details_evoker_presciencetimeline + ---@type table + local prescienceStacksByEvoker = {} + + for i = 1, #timelineTable do + ---@type details_auratimeline + local auraEvent = timelineTable[i] + if (auraEvent.spellId == CONST_SPELLID_PRESCIENCE) then + local evokerName = auraEvent.sourceName + ---@type details_evoker_presciencetimeline + local evokerPrescienceStackInfo = prescienceStacksByEvoker[evokerName] + + if (auraEvent.event == "BUFF_UPTIME_IN") then + if (not evokerPrescienceStackInfo) then + evokerPrescienceStackInfo = { + currentStacks = 0, + stackTime = {0, 0, 0, 0, 0}, + latestStackUpdateTime = 0 + } + prescienceStacksByEvoker[evokerName] = evokerPrescienceStackInfo + end + + local currentAmountOfStacks = evokerPrescienceStackInfo.currentStacks + + --the evoker gained a stack, so we need to add the time he had the previous amount of stacks + if (currentAmountOfStacks > 0) then + local timeWithThisAmountOfStacks = evokerPrescienceStackInfo.stackTime[currentAmountOfStacks] + if (timeWithThisAmountOfStacks) then + local appliedTime = auraEvent.appliedTime + local timeDiff = appliedTime - evokerPrescienceStackInfo.latestStackUpdateTime + if (timeDiff > 0) then + evokerPrescienceStackInfo.stackTime[currentAmountOfStacks] = timeWithThisAmountOfStacks + timeDiff + end + end + end + + evokerPrescienceStackInfo.latestStackUpdateTime = auraEvent.appliedTime + evokerPrescienceStackInfo.currentStacks = currentAmountOfStacks + 1 + + elseif (auraEvent.event == "BUFF_UPTIME_OUT") then + if (evokerPrescienceStackInfo) then + --the evoker lost a stack, so we need to add the time he had the previous amount of stacks + local currentAmountOfStacks = evokerPrescienceStackInfo.currentStacks + local timeWithThisAmountOfStacks = evokerPrescienceStackInfo.stackTime[currentAmountOfStacks] + + auraEvent.addTimeLineTable.closed = true + + if (timeWithThisAmountOfStacks) then + local timeNow = auraEvent.removedTime + local timeDiff = timeNow - evokerPrescienceStackInfo.latestStackUpdateTime + if (timeDiff > 0) then + evokerPrescienceStackInfo.stackTime[currentAmountOfStacks] = timeWithThisAmountOfStacks + timeDiff + end + end + + evokerPrescienceStackInfo.currentStacks = evokerPrescienceStackInfo.currentStacks - 1 + evokerPrescienceStackInfo.latestStackUpdateTime = auraEvent.removedTime + end + end + end + end + + --iterate again and print the tables with the key 'closed' that are not set to true + local nonClosedTables = {} + for i = 1, #timelineTable do + ---@type details_auratimeline + local auraEvent = timelineTable[i] + if (auraEvent.spellId == CONST_SPELLID_PRESCIENCE) then + if (auraEvent.event == "BUFF_UPTIME_IN") then + if (not auraEvent.closed) then + nonClosedTables[#nonClosedTables+1] = auraEvent + end + end + end + end + + Details222.DebugMsg("|cFFFFFF00Non Closed Tables:", #nonClosedTables) + + for evokerName, evokerPrescienceStackInfo in pairs(prescienceStacksByEvoker) do --table 'prescience_stack_data_by_timeline' not found, something wrong here + local evokerUtilityObject = currentCombat:GetContainer(DETAILS_ATTRIBUTE_MISC):GetActor(evokerName) + if (evokerUtilityObject) then + evokerUtilityObject.prescience_stack_data_by_timeline = DetailsFramework.table.copy({}, evokerPrescienceStackInfo.stackTime) + end + end + end +end function augmentationFunctions.BuffIn(token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, spellschool, auraType, amount) - if (not UnitAffectingCombat("player")) then --need documentation + if (not Details.in_combat) then --when the player enter and leave combat, it tracks which players had buffs applied return end @@ -43,10 +278,42 @@ function augmentationFunctions.BuffIn(token, time, sourceSerial, sourceName, sou end elseif (spellId == 410089) then --prescience + --added Prescience to a player (targetName) augmentationCache.prescience[targetSerial] = augmentationCache.prescience[targetSerial] or {} local evokerInfo = {sourceSerial, sourceName, sourceFlags, amount} table.insert(augmentationCache.prescience[targetSerial], evokerInfo) + ---@combat + local currentCombat = Details:GetCurrentCombat() + local evokerUtilityObject = currentCombat:GetContainer(DETAILS_ATTRIBUTE_MISC):GetOrCreateActor(sourceSerial, sourceName, sourceFlags, true) + local stackInfo = evokerUtilityObject.cleu_prescience_time + if (not stackInfo) then + stackInfo = { + currentStacks = 0, + stackTime = {0, 0, 0, 0, 0}, + latestStackUpdateTime = GetTime() + } + evokerUtilityObject.cleu_prescience_time = stackInfo + end + + local prescienceApplied = getAmountOfBuffsAppliedBySpellId(CONST_SPELLID_PRESCIENCE) + + if (prescienceApplied > 0) then + local currentAmountOfApplications = stackInfo.currentStacks + if (currentAmountOfApplications >= 1 and currentAmountOfApplications <= 5) then + --the the time the evoker had this amount of stacks + local timeOfTheLastEvent = stackInfo.latestStackUpdateTime + local timeNow = GetTime() + local timeDiff = timeNow - timeOfTheLastEvent + if (timeDiff > 0) then + stackInfo.stackTime[currentAmountOfApplications] = stackInfo.stackTime[currentAmountOfApplications] + timeDiff + end + end + + stackInfo.latestStackUpdateTime = GetTime() + stackInfo.currentStacks = prescienceApplied + end + elseif (spellId == 409560) then --eons breath local unitIDAffected = Details:FindUnitIDByUnitSerial(targetSerial) if (unitIDAffected) then @@ -76,6 +343,8 @@ function augmentationFunctions.BuffIn(token, time, sourceSerial, sourceName, sou end end + + function augmentationFunctions.BuffRefresh(token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, spellschool, tipo, amount) if (spellId == 395152) then local bFound = false @@ -146,7 +415,11 @@ end function augmentationFunctions.BuffOut(token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, spellSchool, tipo, amount) - if (spellId == 395152) then + if (not Details.in_combat) then --when the player enter and leave combat, it tracks which players had buffs applied + return + end + + if (spellId == 395152) then --ebon might if (augmentationCache.ebon_might[targetSerial]) then --print("tinha buff", targetName, targetSerial) for index, evokerInfo in ipairs(augmentationCache.ebon_might[targetSerial]) do @@ -159,7 +432,7 @@ function augmentationFunctions.BuffOut(token, time, sourceSerial, sourceName, so end end - elseif (spellId == 413984) then + elseif (spellId == 413984) then --ss if (augmentationCache.ss[targetSerial]) then for index, evokerInfo in ipairs(augmentationCache.ss[targetSerial]) do if (evokerInfo[1] == sourceSerial) then @@ -169,7 +442,7 @@ function augmentationFunctions.BuffOut(token, time, sourceSerial, sourceName, so end end - elseif (spellId == 410089) then + elseif (spellId == 410089) then --prescience if (augmentationCache.prescience[targetSerial]) then for index, evokerInfo in ipairs(augmentationCache.prescience[targetSerial]) do if (evokerInfo[1] == sourceSerial) then @@ -177,6 +450,30 @@ function augmentationFunctions.BuffOut(token, time, sourceSerial, sourceName, so break end end + + ---@combat + local currentCombat = Details:GetCurrentCombat() + local evokerUtilityObject = currentCombat:GetContainer(DETAILS_ATTRIBUTE_MISC):GetOrCreateActor(sourceSerial, sourceName, sourceFlags, true) + local stackInfo = evokerUtilityObject.cleu_prescience_time + + if (stackInfo) then + local prescienceApplied = getAmountOfBuffsAppliedBySpellId(CONST_SPELLID_PRESCIENCE) + if (prescienceApplied >= 0) then + local currentAmountOfApplications = stackInfo.currentStacks + if (currentAmountOfApplications >= 1 and currentAmountOfApplications <= 5) then + --the the time the evoker had this amount of stacks + local timeOfTheLastEvent = stackInfo.latestStackUpdateTime + local timeNow = GetTime() + local timeDiff = timeNow - timeOfTheLastEvent + if (timeDiff > 0) then + stackInfo.stackTime[currentAmountOfApplications] = stackInfo.stackTime[currentAmountOfApplications] + timeDiff + end + end + + stackInfo.latestStackUpdateTime = GetTime() + stackInfo.currentStacks = prescienceApplied + end + end end elseif (spellId == 360827) then diff --git a/functions/spells.lua b/functions/spells.lua index 8539d047..650ee93b 100644 --- a/functions/spells.lua +++ b/functions/spells.lua @@ -4074,7 +4074,7 @@ local SplitLoadFunc = function(self, deltaTime) if (not container) then if (Details.debug) then - Details:Msg("(debug) finished index spells.") + --Details:Msg("(debug) finished index spells.") end SplitLoadFrame:SetScript("OnUpdate", nil) return @@ -4096,7 +4096,7 @@ local SplitLoadFunc = function(self, deltaTime) if (SplitLoadFrame.NextActorContainer == 5) then SplitLoadFrame:SetScript("OnUpdate", nil) if (Details.debug) then - Details:Msg("(debug) finished index spells.") + --Details:Msg("(debug) finished index spells.") end return end @@ -4187,7 +4187,7 @@ end function Details.StoreSpells() if (Details.debug) then - Details:Msg("(debug) started to index spells.") + --Details:Msg("(debug) started to index spells.") end SplitLoadFrame:SetScript("OnUpdate", SplitLoadFunc) SplitLoadFrame.NextActorContainer = 1 diff --git a/images/spells/prescience_time.jpg b/images/spells/prescience_time.jpg new file mode 100644 index 00000000..442d1e0c Binary files /dev/null and b/images/spells/prescience_time.jpg differ