From 1d65d798b31406bfb0eaa4dc22235466d0faeda1 Mon Sep 17 00:00:00 2001 From: Tercio Jose Date: Mon, 30 Sep 2024 16:16:05 -0300 Subject: [PATCH] Added Ebon Might uptime per player in the evoker extra bar tooltip --- classes/class_damage.lua | 94 +++++++++----- core/aura_scan.lua | 14 +- functions/spec_augmentation.lua | 224 ++------------------------------ 3 files changed, 82 insertions(+), 250 deletions(-) diff --git a/classes/class_damage.lua b/classes/class_damage.lua index 121556e47..fe0bebc1e 100644 --- a/classes/class_damage.lua +++ b/classes/class_damage.lua @@ -3046,7 +3046,7 @@ function damageClass:RefreshLine(instanceObject, lineContainer, whichRowLine, ra return self:RefreshLineValue(thisLine, instanceObject, previousData, bForceRefresh, percentNumber, bUseAnimations, total, instanceObject.top) end ----show an extra statusbar on the line, after the main statusbar +---show an extra statusbar on the line, after the main statusbar ~extra ~statusbar ---@param thisLine table ---@param amount valueamount ---@param extraAmount valueamount @@ -3510,7 +3510,7 @@ function Details:RefreshBarra(thisLine, instance, fromResize) --[[exported]] self:SetBarLeftText(thisLine, instance, enemy, arenaEnemy, arenaAlly, UsingCustomLeftText) end ----comment +---~aug ~evoker ---@param self table extraStatusbar frame function damageClass.PredictedAugSpellsOnEnter(self) if (Details.show_aug_predicted_spell_damage) then @@ -3575,25 +3575,36 @@ function damageClass.PredictedAugSpellsOnEnter(self) ---@type table> local buffUptimeTable = {} + local iconSize = 22 + local iconBorderInfo = Details.tooltip.icon_border_texcoord + local CONST_SPELLID_EBONMIGHT = 395152 local CONST_SPELLID_PRESCIENCE = 410089 local CONST_SPELLID_BLACKATTUNEMENT = 403264 local CONST_SPELLID_BLISTERING_SCALES = 360827 + local ebonMightSpellName, _, ebonMightSpellIcon = Details.GetSpellInfo(CONST_SPELLID_EBONMIGHT) + local _, _, ebonMightOnSelfIcon = Details.GetSpellInfo(395296) + ---@type actor[] local augmentationEvokers = {} + local thisEvokerObject = utilityContainer:GetActor(actorName) + --prescience and ebon might updatime on each actor - for _, actorObject in utilityContainer:ListActors() do + for _, actorUtilityObject in utilityContainer:ListActors() do ---@type spellcontainer - local receivedBuffs = actorObject.received_buffs_spells + local receivedBuffs = actorUtilityObject.received_buffs_spells --check if the actor is an augmentation evoker - if (actorObject.spec == 1473) then - augmentationEvokers[#augmentationEvokers+1] = actorObject + if (actorUtilityObject.spec == 1473) then + augmentationEvokers[#augmentationEvokers+1] = actorUtilityObject + if (actorUtilityObject:Name() == actorName) then + thisEvokerObject = actorUtilityObject + end end - if (receivedBuffs and actorObject:IsPlayer() and actorObject:IsGroupPlayer()) then + if (receivedBuffs and actorUtilityObject:IsPlayer() and actorUtilityObject:IsGroupPlayer()) then for sourceNameSpellId, spellTable in receivedBuffs:ListSpells() do local sourceName, spellId = strsplit("@", sourceNameSpellId) if (sourceName == actorName) then @@ -3602,13 +3613,13 @@ function damageClass.PredictedAugSpellsOnEnter(self) if (spellName and spellId) then sourceName = detailsFramework:RemoveRealmName(sourceName) - local targetName = actorObject:Name() + local targetName = actorUtilityObject:Name() targetName = detailsFramework:RemoveRealmName(targetName) local uptime = spellTable.uptime or 0 local bCanShowOnTooltip = true buffUptimeTable[spellId] = buffUptimeTable[spellId] or {} - table.insert(buffUptimeTable[spellId], {spellId, uptime, sourceName, targetName, actorObject:Class(), bCanShowOnTooltip}) + table.insert(buffUptimeTable[spellId], {spellId, uptime, sourceName, targetName, actorUtilityObject:Class(), bCanShowOnTooltip}) end end end @@ -3627,9 +3638,6 @@ function damageClass.PredictedAugSpellsOnEnter(self) Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #buffUptimeTable, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords)) Details:AddTooltipHeaderStatusbar(.1, .1, .1, 0.834) - 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) .. "%)") @@ -3639,24 +3647,50 @@ function damageClass.PredictedAugSpellsOnEnter(self) 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 "darkgreen") - else - GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") - Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "darkgreen") - end + --show the caster evoker ebonmight uptime on the tooltip + local thisEvokerEbonMightSpellTable = thisEvokerObject.buff_uptime_spells:GetSpell(395296) + local evokerEbonMightUptime = thisEvokerEbonMightSpellTable and thisEvokerEbonMightSpellTable.uptime + local ebonMightColor = "saddlebrown" + + if (evokerEbonMightUptime) then + local minutes, seconds = math.floor(evokerEbonMightUptime / 60), math.floor(evokerEbonMightUptime % 60) + local percent = evokerEbonMightUptime / combatTime * 100 - GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B) + if (minutes > 0) then + GameCooltip:AddLine(ebonMightSpellName .. " (self)", minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", percent) .. "%)") + Details:AddTooltipBackgroundStatusbar(false, percent, true, ebonMightColor) + else + GameCooltip:AddLine(ebonMightSpellName .. " (self)", seconds .. "s" .. " (" .. format("%.1f", percent) .. "%)") + Details:AddTooltipBackgroundStatusbar(false, percent, true, ebonMightColor) + end + + GameCooltip:AddIcon(ebonMightOnSelfIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B) + end + + local ebonMightTable = buffUptimeTable[CONST_SPELLID_EBONMIGHT] + + --all ebon mights + for i = 1, #ebonMightTable do + local thisEbonMightTable = ebonMightTable[i] + local uptime = thisEbonMightTable[2] + local evokerName = thisEbonMightTable[3] + local targetName = thisEbonMightTable[4] + local targetClass = thisEbonMightTable[5] + + local spellName = ebonMightSpellName + + if (evokerName) then + targetName = detailsFramework:AddClassColorToText(targetName, targetClass) + targetName = detailsFramework:AddClassIconToText(targetName, targetName, targetClass) + spellName = spellName .. " [" .. targetName .. " ]" + end + + local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60) + if (uptime > 0) then + local uptimePercent = uptime / combatTime * 100 + GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)") + GameCooltip:AddIcon(ebonMightSpellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B) + Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, ebonMightColor) end end @@ -3735,7 +3769,7 @@ function damageClass.PredictedAugSpellsOnEnter(self) if (sourceName) then targetName = detailsFramework:AddClassColorToText(targetName, targetClass) targetName = detailsFramework:AddClassIconToText(targetName, targetName, targetClass) - spellName = spellName .. " [" .. targetName .. "]" + spellName = spellName .. " [" .. targetName .. " ]" end if (uptime <= combatTime) then diff --git a/core/aura_scan.lua b/core/aura_scan.lua index c825c9ce6..b8ebe5c9f 100644 --- a/core/aura_scan.lua +++ b/core/aura_scan.lua @@ -53,6 +53,7 @@ function AuraScan.CheckForOneHourBuffs() if (Details222.OneHourAuras[spellId]) then --is this buff have 100% uptime? if (spellTable.uptime == combatTime) then + --remove the spell fro the container utilityActor.buff_uptime = utilityActor.buff_uptime - spellTable.uptime utilityActor.buff_uptime_spells._ActorTable[spellId] = nil end @@ -63,6 +64,9 @@ function AuraScan.CheckForOneHourBuffs() end end +------------------------------ +---------Aura Scan ~aura ~scan + function AuraScan.RegisterCallback(callback) AuraScan.Callbacks[callback] = true end @@ -372,7 +376,7 @@ end ------------------------------------------------------------------------------------------------------------------------------ -local scanFrame = CreateFrame("frame", "DetailsAuraScanFrame", UIParent) +local scanFrame = CreateFrame("frame") function AuraScan.Start() AuraScan.Enabled = true @@ -399,15 +403,15 @@ function AuraScan.Start() bIsInitialScan = false - DetailsAuraScanFrame:RegisterEvent("UNIT_AURA") - DetailsAuraScanFrame:SetScript("OnEvent", AuraScan.OnEvent) + scanFrame:RegisterEvent("UNIT_AURA") + scanFrame:SetScript("OnEvent", AuraScan.OnEvent) end function AuraScan.Stop() if (AuraScan.Enabled) then AuraScan.Enabled = false - DetailsAuraScanFrame:UnregisterEvent("UNIT_AURA") - DetailsAuraScanFrame:SetScript("OnEvent", nil) + scanFrame:UnregisterEvent("UNIT_AURA") + scanFrame:SetScript("OnEvent", nil) --close all opened auras (by running the remove function) for targetGUID, auras in pairs(AuraScan.UnitAurasStorage) do diff --git a/functions/spec_augmentation.lua b/functions/spec_augmentation.lua index 3f190a747..82991b23a 100644 --- a/functions/spec_augmentation.lua +++ b/functions/spec_augmentation.lua @@ -14,15 +14,12 @@ local CONST_SPELLID_TANK_SHIELD = 360827 local CONST_SPELLID_INFERNOBLESS = 410263 local UnitExists = UnitExists -local UnitIsUnit = UnitIsUnit local GetSpellInfo = Details222.GetSpellInfo local UnitAuraBySpellName = C_UnitAuras.GetAuraDataBySpellName local augmentationFunctions = Details222.SpecHelpers[1473] local augmentationCache = Details222.SpecHelpers[1473].augmentation_cache -local playerRealmName = GetRealmName() - local getAmountOfBuffsAppliedBySpellId = function(spellId) local amountBuffs = 0 local spellName = GetSpellInfo(spellId) @@ -41,7 +38,6 @@ local getAmountOfBuffsAppliedBySpellId = function(spellId) end local eventListener = Details:CreateEventListener() ---eventListener:RegisterEvent("COMBAT_PLAYER_ENTER") eventListener:RegisterEvent("COMBAT_PLAYER_LEAVING", function(eventName, combatObject) --check if the expansion the player is playing has the augmentation evokers if (not detailsFramework.ExpansionHasAugEvoker()) then @@ -62,30 +58,31 @@ eventListener:RegisterEvent("COMBAT_PLAYER_LEAVING", function(eventName, combatO local augEvokerObject for index, actorObject in damageContainer:ListActors() do - --check the specId to know if the actor has the augmentation specId + --is this actor an augmentation evoker? if (actorObject.spec == 1473) then amountOfAugEvokers = amountOfAugEvokers + 1 - players[#players+1] = actorObject augEvokerObject = actorObject + players[#players+1] = actorObject elseif (actorObject:IsPlayer()) then players[#players+1] = actorObject end end - --print("players", #players, "amountOfAugEvokers:", amountOfAugEvokers, augEvokerObject and augEvokerObject:Name() or "nil") - if (amountOfAugEvokers == 1 and augEvokerObject) then local breathOfEonsDamage = 0 local infernoBlessingDamage = 0 local fateMirrorDamage = 0 local blisteringScalesDamage = 0 + --all players found in the damage container for i = 1, #players do ---@actor local playerObject = players[i] local spellContainer = playerObject:GetSpellContainer("spell") + --get the damage done by this player, where the spell is a spell of the evoker + local breathOfEons = spellContainer:GetSpell(CONST_SPELLID_EONS_BREATH) local infornoBlessing = spellContainer:GetSpell(CONST_SPELLID_INFERNOBLESS) local blisteringScales = spellContainer:GetSpell(CONST_SPELLID_TANK_SHIELD) @@ -110,6 +107,7 @@ eventListener:RegisterEvent("COMBAT_PLAYER_LEAVING", function(eventName, combatO local augmentedSpellContainer = augEvokerObject.augmentedSpellsContainer + --add the damage of each spell to a special spell container within the augmentation damage object if (breathOfEonsDamage > 0) then local bCanCreateSpellIfMissing = true local breathOfEonsSpell = augmentedSpellContainer:GetOrCreateSpell(CONST_SPELLID_EONS_BREATH, bCanCreateSpellIfMissing, "SPELL_DAMAGE") @@ -134,214 +132,9 @@ eventListener:RegisterEvent("COMBAT_PLAYER_LEAVING", function(eventName, combatO fateMirrorSpell.total = fateMirrorDamage end end - - --[=[ - ---@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 - +--this is called from the parser when a buff is applied and the spellId is registered in the augmentation_aura_list function augmentationFunctions.BuffIn(token, time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, spellschool, auraType, amount) if (not Details.in_combat) then --when the player enter and leave combat, it tracks which players had buffs applied return @@ -384,8 +177,9 @@ function augmentationFunctions.BuffIn(token, time, sourceSerial, sourceName, sou local evokerInfo = {sourceSerial, sourceName, sourceFlags, amount} table.insert(augmentationCache.prescience[targetSerial], evokerInfo) - ---@combat + ---@type combat local currentCombat = Details:GetCurrentCombat() + ---@type actor local evokerUtilityObject = currentCombat:GetContainer(DETAILS_ATTRIBUTE_MISC):GetOrCreateActor(sourceSerial, sourceName, sourceFlags, true) local stackInfo = evokerUtilityObject.cleu_prescience_time if (not stackInfo) then