• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

DPS Tracker

Xikini

I whore myself out for likes
Senator
Premium User
Joined
Nov 17, 2010
Messages
6,798
Solutions
581
Reaction score
5,361
Main function here is the DPS Tracking.

I included a tester function to just print to console..
but maybe you can send the information to the client, and have it update there for the player..
or attach it to a specific monster, like a training dummy, and let players see their dps.

Use it however you like. lol

bandicam2024-02-1121-29-28-262-ezgif.com-video-to-gif-converter.gif

Lua:
local DPS_dropoff = 60 -- seconds (damage beyond 60 seconds, is removed)

local dpsChart = {
--    [playerId] = {
--        totalDPS = 0,
--        damageChart = {
--            {damage = 0, timestamp = os.mtime()},
--            {damage = 0, timestamp = os.mtime()},
--            {damage = 0, timestamp = os.mtime()}
--        }
--    }
}


local function updateDPSChart(playerId, newDamage)
    if not dpsChart[playerId] then
        dpsChart[playerId] = {totalDPS = 0, damageChart = {}}
    end
    local currentTime = os.mtime()
    while #dpsChart[playerId].damageChart > 0 and (dpsChart[playerId].damageChart[1].timestamp + (DPS_dropoff * 1000)) < currentTime do
        dpsChart[playerId].totalDPS = dpsChart[playerId].totalDPS - dpsChart[playerId].damageChart[1].damage
        table.remove(dpsChart[playerId].damageChart, 1)
    end
    if newDamage then
        dpsChart[playerId].damageChart[#dpsChart[playerId].damageChart + 1] = {damage = newDamage, timestamp = currentTime}
        dpsChart[playerId].totalDPS = dpsChart[playerId].totalDPS + newDamage
    end
end

local function getDPS(playerId)
    if not dpsChart[playerId] then
        return 0
    end
    updateDPSChart(playerId)
    if #dpsChart[playerId].damageChart == 0 then
        return 0
    end
    local currentTime = os.mtime()
    local oldestTimestamp = dpsChart[playerId].damageChart[1].timestamp
    local timeSpanSeconds = (currentTime - oldestTimestamp) / 1000
    timeSpanSeconds = math.min(timeSpanSeconds, DPS_dropoff)
    if timeSpanSeconds < 0 then
        return 0
    end
    timeSpanSeconds = math.max(timeSpanSeconds, 1)
    return math.floor(dpsChart[playerId].totalDPS / timeSpanSeconds)
end


local healthChange = CreatureEvent("onHealthChange_DPS_Tracker")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if attacker:isPlayer() then
        updateDPSChart(attacker:getId(), (primaryDamage + secondaryDamage) * -1)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()


local eventCallback = EventCallback

function eventCallback.onSpawn(creature, position, startup, artificial)
    creature:registerEvent("onHealthChange_DPS_Tracker")
    return true
end

eventCallback:register(-666)



-- example usage, where we ping to console every second
local function pingDPS(playerId)
    local player = Player(playerId)
    if not player then
        return
    end
    print("Current DPS: " .. getDPS(playerId))
    addEvent(pingDPS, 1000, playerId)
end


local creatureevent = CreatureEvent("onLogin_DPS_Ping")

function creatureevent.onLogin(player)
    addEvent(pingDPS, 1000, player:getId())
    return true
end

creatureevent:register()
 
Main function here is the DPS Tracking.

I included a tester function to just print to console..
but maybe you can send the information to the client, and have it update there for the player..
or attach it to a specific monster, like a training dummy, and let players see their dps.

Use it however you like. lol

View attachment 82033

Lua:
local DPS_dropoff = 60 -- seconds (damage beyond 60 seconds, is removed)

local dpsChart = {
--    [playerId] = {
--        totalDPS = 0,
--        damageChart = {
--            {damage = 0, timestamp = os.mtime()},
--            {damage = 0, timestamp = os.mtime()},
--            {damage = 0, timestamp = os.mtime()}
--        }
--    }
}


local function updateDPSChart(playerId, newDamage)
    if not dpsChart[playerId] then
        dpsChart[playerId] = {totalDPS = 0, damageChart = {}}
    end
    local currentTime = os.mtime()
    while #dpsChart[playerId].damageChart > 0 and (dpsChart[playerId].damageChart[1].timestamp + (DPS_dropoff * 1000)) < currentTime do
        dpsChart[playerId].totalDPS = dpsChart[playerId].totalDPS - dpsChart[playerId].damageChart[1].damage
        table.remove(dpsChart[playerId].damageChart, 1)
    end
    if newDamage then
        dpsChart[playerId].damageChart[#dpsChart[playerId].damageChart + 1] = {damage = newDamage, timestamp = currentTime}
        dpsChart[playerId].totalDPS = dpsChart[playerId].totalDPS + newDamage
    end
end

local function getDPS(playerId)
    if not dpsChart[playerId] then
        return 0
    end
    updateDPSChart(playerId)
    if #dpsChart[playerId].damageChart == 0 then
        return 0
    end
    local currentTime = os.mtime()
    local oldestTimestamp = dpsChart[playerId].damageChart[1].timestamp
    local timeSpanSeconds = (currentTime - oldestTimestamp) / 1000
    timeSpanSeconds = math.min(timeSpanSeconds, DPS_dropoff)
    if timeSpanSeconds < 0 then
        return 0
    end
    timeSpanSeconds = math.max(timeSpanSeconds, 1)
    return math.floor(dpsChart[playerId].totalDPS / timeSpanSeconds)
end


local healthChange = CreatureEvent("onHealthChange_DPS_Tracker")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if attacker:isPlayer() then
        updateDPSChart(attacker:getId(), (primaryDamage + secondaryDamage) * -1)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()


local eventCallback = EventCallback

function eventCallback.onSpawn(creature, position, startup, artificial)
    creature:registerEvent("onHealthChange_DPS_Tracker")
    return true
end

eventCallback:register(-666)



-- example usage, where we ping to console every second
local function pingDPS(playerId)
    local player = Player(playerId)
    if not player then
        return
    end
    print("Current DPS: " .. getDPS(playerId))
    addEvent(pingDPS, 1000, playerId)
end


local creatureevent = CreatureEvent("onLogin_DPS_Ping")

function creatureevent.onLogin(player)
    addEvent(pingDPS, 1000, player:getId())
    return true
end

creatureevent:register()
Working perfectly! Great Xikini! Great! :)
 
Back
Top