|
|
|
|
|
|
|
|
|
local Details = _G.Details
|
|
|
|
|
local addonName, Details222 = ...
|
|
|
|
|
|
|
|
|
|
--namespace
|
|
|
|
|
Details.CurrentDps = {}
|
|
|
|
|
|
|
|
|
|
local bIsEnabled = true
|
|
|
|
|
|
|
|
|
|
---@type combat
|
|
|
|
|
local currentCombatObject = nil
|
|
|
|
|
|
|
|
|
|
---@class details_currentdps_actorcache
|
|
|
|
|
---@field totalDamage number
|
|
|
|
|
---@field latestDamageAmount number
|
|
|
|
|
---@field cache number[]
|
|
|
|
|
|
|
|
|
|
---@type table<serial, details_currentdps_actorcache>
|
|
|
|
|
local currentDPSCache = {}
|
|
|
|
|
|
|
|
|
|
---create a new cache table
|
|
|
|
|
---@return details_currentdps_actorcache
|
|
|
|
|
local createDpsCacheTable = function()
|
|
|
|
|
---@type details_currentdps_actorcache
|
|
|
|
|
local cache = {
|
|
|
|
|
totalDamage = 0,
|
|
|
|
|
latestDamageAmount = 0,
|
|
|
|
|
cache = {},
|
|
|
|
|
}
|
|
|
|
|
return cache
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---get the actor cache from the current dps table
|
|
|
|
|
---@param serial serial
|
|
|
|
|
---@return details_currentdps_actorcache
|
|
|
|
|
local getActorDpsCache = function(serial)
|
|
|
|
|
local dpsCache = currentDPSCache[serial]
|
|
|
|
|
if (not dpsCache) then
|
|
|
|
|
dpsCache = createDpsCacheTable()
|
|
|
|
|
currentDPSCache[serial] = dpsCache
|
|
|
|
|
end
|
|
|
|
|
return dpsCache
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---@type frame
|
|
|
|
|
local currentDpsFrame = CreateFrame("frame", "DetailsCurrentDpsUpdaterFrame", UIParent)
|
|
|
|
|
|
|
|
|
|
--amount of time to wait between each sample collection
|
|
|
|
|
local delayTimeBetweenUpdates = 0.10
|
|
|
|
|
|
|
|
|
|
--sample size in time to use to calculate the current dps
|
|
|
|
|
local secondsOfData = 5
|
|
|
|
|
|
|
|
|
|
--amount of time to wait until next update
|
|
|
|
|
local currentDelay = 0
|
|
|
|
|
|
|
|
|
|
--amount of small ticks that will be stored in the cache
|
|
|
|
|
local cacheSize = secondsOfData / delayTimeBetweenUpdates
|
|
|
|
|
|
|
|
|
|
--the index of the cache that will be removed when the cache is full
|
|
|
|
|
local cacheOverflowIndex = cacheSize + 1
|
|
|
|
|
|
|
|
|
|
---on tick function
|
|
|
|
|
---@param self frame
|
|
|
|
|
---@param deltaTime number time elapsed between frames
|
|
|
|
|
currentDpsFrame.OnUpdateFunc = function(self, deltaTime)
|
|
|
|
|
currentDelay = currentDelay + deltaTime
|
|
|
|
|
if (currentDelay < delayTimeBetweenUpdates) then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---@type actorcontainer
|
|
|
|
|
local damageContainer = currentCombatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
|
|
|
|
|
|
|
|
|
|
for index, actorObject in damageContainer:ListActors() do
|
|
|
|
|
---@cast actorObject actor
|
|
|
|
|
|
|
|
|
|
if (actorObject:IsPlayer()) then
|
|
|
|
|
---@type details_currentdps_actorcache
|
|
|
|
|
local dpsCache = getActorDpsCache(actorObject.serial)
|
|
|
|
|
|
|
|
|
|
--get the damage done on this tick
|
|
|
|
|
local totalDamageThisTick = actorObject.total - dpsCache.latestDamageAmount
|
|
|
|
|
|
|
|
|
|
--add the damage to the cache
|
|
|
|
|
table.insert(dpsCache.cache, 1, totalDamageThisTick)
|
|
|
|
|
|
|
|
|
|
--set the latest damage amount
|
|
|
|
|
dpsCache.latestDamageAmount = actorObject.total
|
|
|
|
|
|
|
|
|
|
--sum the total damage the actor inflicted
|
|
|
|
|
dpsCache.totalDamage = dpsCache.totalDamage + totalDamageThisTick
|
|
|
|
|
|
|
|
|
|
--cut the damage
|
|
|
|
|
local damageRemoved = table.remove(dpsCache.cache, cacheOverflowIndex)
|
|
|
|
|
if (damageRemoved) then
|
|
|
|
|
dpsCache.totalDamage = dpsCache.totalDamage - damageRemoved
|
|
|
|
|
dpsCache.totalDamage = math.max(0, dpsCache.totalDamage) --safe guard
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
currentDelay = 0
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--serial = guid
|
|
|
|
|
function Details.CurrentDps.GetCurrentDps(serial)
|
|
|
|
|
local dpsCache = currentDPSCache[serial]
|
|
|
|
|
if (dpsCache) then
|
|
|
|
|
local dps = dpsCache.totalDamage / secondsOfData
|
|
|
|
|
return math.floor(dps)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--start the proccess of updating the current dps and hps for each player
|
|
|
|
|
function Details.CurrentDps.StartCurrentDpsTracker()
|
|
|
|
|
currentCombatObject = Details:GetCurrentCombat()
|
|
|
|
|
Details:Destroy(currentDPSCache)
|
|
|
|
|
currentDpsFrame:SetScript("OnUpdate", currentDpsFrame.OnUpdateFunc)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--stop what the function above started
|
|
|
|
|
function Details.CurrentDps.StopCurrentDpsTracker()
|
|
|
|
|
currentDpsFrame:SetScript("OnUpdate", nil)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--handle internal details! events
|
|
|
|
|
local eventListener = Details:CreateEventListener()
|
|
|
|
|
|
|
|
|
|
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", function()
|
|
|
|
|
--check if can start the real time dps tracker
|
|
|
|
|
local bCanStartRealTimeDpsTracker = Details.combat_log.evoker_show_realtimedps and Details.playerspecid == 1473
|
|
|
|
|
if (not bCanStartRealTimeDpsTracker) then
|
|
|
|
|
bCanStartRealTimeDpsTracker = Details.time_type == 3
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if (bCanStartRealTimeDpsTracker) then
|
|
|
|
|
Details.CurrentDps.StartCurrentDpsTracker()
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
eventListener:RegisterEvent("COMBAT_PLAYER_LEAVE", function()
|
|
|
|
|
Details.CurrentDps.StopCurrentDpsTracker()
|
|
|
|
|
end)
|