You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.5 KiB

3 years ago
local Details = _G.Details
local addonName, Details222 = ...
3 years ago
--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 = Details222.CurrentDPS.Cache
---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
3 years ago
---@type frame
3 years ago
local currentDpsFrame = CreateFrame("frame", "DetailsCurrentDpsUpdaterFrame", UIParent)
--amount of time to wait between each sample collection
3 years ago
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
3 years ago
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
3 years ago
local cacheOverflowIndex = cacheSize + 1
---return how many seconds of data is being used to calculate the current dps
---@return number
function Details222.CurrentDPS.GetTimeSample()
return secondsOfData
end
---on tick function
---@param self frame
---@param deltaTime number time elapsed between frames
3 years ago
currentDpsFrame.OnUpdateFunc = function(self, deltaTime)
currentDelay = currentDelay + deltaTime
if (currentDelay < delayTimeBetweenUpdates) then
return
end
---@type actorcontainer
local damageContainer = currentCombatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
3 years ago
for index, actorObject in damageContainer:ListActors() do
---@cast actorObject actor
if (actorObject.grupo) then
---@type details_currentdps_actorcache
local dpsCache = getActorDpsCache(actorObject.serial)
3 years ago
--get the damage done on this tick
local totalDamageThisTick = actorObject.total - dpsCache.latestDamageAmount
3 years ago
--add the damage to the cache
table.insert(dpsCache.cache, 1, totalDamageThisTick)
3 years ago
--set the latest damage amount
dpsCache.latestDamageAmount = actorObject.total
3 years ago
--sum the total damage the actor inflicted
dpsCache.totalDamage = dpsCache.totalDamage + totalDamageThisTick
3 years ago
--cut the damage
local damageRemoved = table.remove(dpsCache.cache, cacheOverflowIndex)
3 years ago
if (damageRemoved) then
dpsCache.totalDamage = dpsCache.totalDamage - damageRemoved
dpsCache.totalDamage = math.max(0, dpsCache.totalDamage) --safe guard
3 years ago
end
end
end
currentDelay = 0
end
---return the value of the current dps for the given player
---serial = guid
---@param serial guid
---@return number|nil
function Details.CurrentDps.GetCurrentDps(serial)
local dpsCache = currentDPSCache[serial]
if (dpsCache) then
local dps = dpsCache.totalDamage / secondsOfData
return math.floor(dps)
end
end
---return if the window bars can be sorted by real time dps
---@return boolean
function Details.CurrentDps.CanSortByRealTimeDps()
if (not Details.in_combat) then
return false
end
local bOrderDpsByRealTime = Details.use_realtimedps and Details.realtimedps_order_bars
if (not bOrderDpsByRealTime) then
bOrderDpsByRealTime = Details.realtimedps_always_arena and Details.zone_type == "arena"
end
return bOrderDpsByRealTime
end
3 years ago
--start the proccess of updating the current dps and hps for each player
function Details.CurrentDps.StartCurrentDpsTracker()
currentCombatObject = Details:GetCurrentCombat()
Details:Destroy(currentDPSCache)
3 years ago
currentDpsFrame:SetScript("OnUpdate", currentDpsFrame.OnUpdateFunc)
end
3 years ago
--stop what the function above started
function Details.CurrentDps.StopCurrentDpsTracker()
currentDpsFrame:SetScript("OnUpdate", nil)
end
--handle internal details! events
local eventListener = Details:CreateEventListener()
3 years ago
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", function()
--check if can start the real time dps tracker
local bCanStartRealTimeDpsTracker = Details.use_realtimedps or (Details.combat_log.evoker_show_realtimedps and Details.playerspecid == 1473)
if (not bCanStartRealTimeDpsTracker) then
bCanStartRealTimeDpsTracker = Details.zone_type == "arena" and Details.realtimedps_always_arena
end
5 months ago
--the new arena summary window will start the real time dps tracker any way
if (Details.zone_type == "arena") then
--bCanStartRealTimeDpsTracker = true
end
if (bCanStartRealTimeDpsTracker) then
Details.CurrentDps.StartCurrentDpsTracker()
end
3 years ago
end)
3 years ago
eventListener:RegisterEvent("COMBAT_PLAYER_LEAVE", function()
Details.CurrentDps.StopCurrentDpsTracker()
end)