local CalculateDamage = CreatureEvent("CalculateDamage")
-- Table to store damage data
local damageData = {}
local reportInterval = 60 -- Interval in seconds for final DPS report
local updateInterval = 1 -- Interval for DPS updates in seconds
local cooldownPeriod = 3 -- Cooldown period in seconds after final report
local inactivityTimeout = 5 -- Timeout in seconds to stop DPS display if no new damage
-- Function to reset damage counters for a specific player
local function resetDamageCounters(playerId)
damageData[playerId] = {
totalDamageLastMinute = 0,
startTime = os.time(),
lastDamageTime = os.time(),
onCooldown = false,
active = false
}
end
-- Function to send animated DPS text
local function sendDPSAnimation(position, message)
local spectators = Game.getSpectators(position, false, true, 8, 8, 8, 8)
for i = 1, #spectators do
local player = spectators[i]
if player:isPlayer() then
player:say(message, TALKTYPE_MONSTER_SAY, false, player, position)
end
end
end
-- Function to handle DPS reporting for each player
local function reportDPS(creature)
if not creature or not creature:isMonster() then return end -- Ensure creature is valid
local currentTime = os.time()
for playerId, data in pairs(damageData) do
if not data.active then
-- Skip reporting if the data is inactive
return
end
local elapsedTime = currentTime - data.startTime
local timeSinceLastDamage = currentTime - data.lastDamageTime
if elapsedTime >= reportInterval then
-- Final DPS report at the end of the interval
local dps = data.totalDamageLastMinute / reportInterval
creature:say("Final DPS: " .. math.floor(dps) .. " damage per second.", TALKTYPE_MONSTER_SAY)
-- Enter cooldown and deactivate to stop further displays
data.onCooldown = true
data.active = false
sendDPSAnimation(creature:getPosition(), "Resetting in progress...")
-- Schedule a reset after the cooldown period
addEvent(function()
data.onCooldown = false -- End cooldown
end, cooldownPeriod * 1000)
elseif timeSinceLastDamage >= inactivityTimeout then
-- Stop displaying DPS if inactive for too long
data.active = false
elseif not data.onCooldown then
-- Ongoing DPS updates as animated text
local dps = data.totalDamageLastMinute / elapsedTime
sendDPSAnimation(creature:getPosition(), "DPS: " .. math.floor(dps))
end
end
-- Schedule the next DPS report with a wrapper to pass the creature correctly
addEvent(function() reportDPS(creature) end, updateInterval * 1000)
end
-- Event handler for when the dummy takes damage
function CalculateDamage.onHealthChange(creature, attacker, primaryDamage, primaryType)
if creature:getName():lower() ~= "dummy" then
return primaryDamage -- Not the dummy, ignore and proceed with normal damage
end
if attacker and attacker:isPlayer() then
local playerId = attacker:getId()
-- Initialize or reset data if it's a new session or after cooldown
if not damageData[playerId] or not damageData[playerId].active then
resetDamageCounters(playerId)
damageData[playerId].active = true -- Reactivate for new session
end
-- Only accumulate damage if not on cooldown
if damageData[playerId].active and not damageData[playerId].onCooldown then
local totalDamage = math.abs(primaryDamage or 0)
damageData[playerId].totalDamageLastMinute = damageData[playerId].totalDamageLastMinute + totalDamage
damageData[playerId].lastDamageTime = os.time() -- Update last damage time
end
end
-- Report DPS periodically
reportDPS(creature)
return primaryDamage -- Allow the damage to be processed normally
end
CalculateDamage:register()