Skip to content

Introduction

Availability

  • The cooldown feature is part of Harmony starting from version 2.1.0.
  • Remember, this feature is only accessible on the server side; there's no support for client.

In Harmony, the cooldown API makes managing cooldowns an easier task. It offers a range of functions to set up and handle cooldowns with different persistence levels.

With this API, you can easily check remaining cooldown time, see if a cooldown is active, and more.

Supported Cooldown Types

  • temporary: This type of cooldown is temporary, meaning they vanish after a server restart.
  • persistent: These cooldowns survive server restarts, staying active even if the server goes down and comes back up.
  • super-persistent: Even if your server goes down for a while, cooldowns of this type will still be active when it comes back up. For instance, if a cooldown started an hour ago and you start your server up next week, it'll still have an hour left before it's over.

Methods

Harmony.Cooldown.create(options)

This method sets up a new cooldown instance. It requires an options table as input, which can include the following fields:

OptionTypeRequired?Description
idstringNoThe ID of the cooldown instance. If absent, a random ID will be generated.
typestringYesThe type of cooldown instance. Must be one of temporary, persistent, or super-persistent.
length or durationnumberYesThe duration of the cooldown in seconds.
sourcestring/numberNoA unique identifier for the source of the cooldown (e.g., 'player:123').
datatableNoExtra data linked to the cooldown instance.

Return value

Returns the newly created cooldown instance.

Example

lua
local cd = Harmony.Cooldown.create({
  length = 60, -- 1 minute
  type = 'persistent',
  data = { foo = 'bar' }
})

local myCooldown = Harmony.Cooldown.create({
  type = 'persistent',
  length = 60, -- 1 minute
  id = 'myCooldownId',
  data = { key = "value" },
})

Harmony.Cooldown.searchById(id)

This method returnes a cooldown with the provided ID.

OptionTypeRequired?Description
idstringYesThe ID of the cooldown object.

Harmony.Cooldown.searchBySource(source)

This method returnes cooldowns associated with the specified source.

OptionTypeRequired?Description
sourcestring/numberYesA unique identifier for the source of the cooldown (e.g., 'player:123').

Heads Up

This function operates effectively only when a source is assigned to a cooldown instance.

But what exactly is the source? Short answer it could be anything!

For example, if the cooldown is applied to a player, their server ID could serve as the source. If it's linked to a character, their character identifier might be the source. Similarly, if it's attached to a vehicle, its plate could be the source. You get the idea.

lua
local myCooldown = Harmony.Cooldown.create({
  length = 60, -- 1 minute
  source = 1
})

myCooldown = Harmony.Cooldown.searchBySource(1)

myCooldown = Harmony.Cooldown.create({
  type = 'persistent',
  length = 60, -- 1 minute
  id = 'anotherCD',
  source = 'PLATE1234'
})

myCooldown = Harmony.Cooldown.searchBySource('PLATE1234')

Cooldown:isExpired()

This method checks if the cooldown has expired and returns a boolean indicating whether it is still active, along with the time elapsed since it was created.

Return value

  • boolean: true if the cooldown has expired, false otherwise.
  • number: The time elapsed since the cooldown was created.

Example

lua
local isExpired, elapsedTime = myCooldown:isExpired()
print(isExpired, elapsedTime)

Cooldown:hasExpired()

This method is essentially the same as isExpired().

Cooldown:isOnCooldown()

This method checks if the cooldown is currently active.

Note

isOnCooldown() and isExpired() are opposites of each other. If isOnCooldown() returns true, isExpired() will return false, and vice versa.

Return value

  • boolean: true if the cooldown is still active, false otherwise.

Example

lua
local onCooldown = myCooldown:isOnCooldown()
print(onCooldown)

Cooldown:setData(data)

This method sets the additional data associated with the cooldown.

Example

lua
myCooldown:setData({ bar = 'baz' })

Cooldown:getData()

This method returns the additional data associated with the cooldown.

Return value

  • table: A table representing the additional data.

Example

lua
local additionalData = myCooldown:getData()

Cooldown:setLength(length)

This method sets the length of the cooldown.

Parameters

  • number: A number representing the new length of the cooldown in seconds.

Example

lua
myCooldown:setLength(120)

Cooldown:setDuration(duration)

This method sets the length of the cooldown same as Cooldown:setLength(length).

Cooldown:setOnCooldown()

This method sets the cooldown to be active.

lua
cd:setOnCooldown()

Cooldown:getTimeRemaining()

This method returns the time remaining on a particular cooldown.

Return value

  • number: The time remaining as a number of seconds.

Example

lua
local options = {
    id = "myResourceCooldown",
    length = 600 -- 10 minutes
}

local cooldown = Harmony.Cooldown.create(options)
cooldown:setOnCooldown()

Citizen.Wait(3000)

print("Time remaining on cooldown:", cooldown:getTimeRemaining())

Cooldown:resetUsage()

This method resets the usage count for a particular cooldown. It takes no arguments and returns the new usage count, which is set to 0.

Example

lua
local options = {
    id = "myResourceCooldown",
    length = 600 -- 10 minutes
}

local cooldown = Harmony.Cooldown.create(options)
cooldown:setOnCooldown()

-- use the resource once
cooldown.usage = 1

-- reset the usage count
cooldown:resetUsage()

print("Usage count:", cooldown.usage)

Cooldown:destroy()

This method removes a cooldown instance.

Example

lua
local options = {
    id = "myResourceCooldown",
    length = 600 -- 10 minutes
}

local cooldown = Harmony.Cooldown.create(options)
cooldown:setOnCooldown()

-- destroy the cooldown object
cooldown:destroy()

Example

Drill Cooldown

Let's say you have a script for a heist mission in which players can drill open a safe to access valuable loot. However, you want to prevent players from spamming the drill and making the mission too easy. You can use the Cooldown feature to implement a cooldown for the drill.

Here's an example:

  • server.lua
lua
local Harmony = exports['keep-harmony']:GetCoreObject()

-- Initializing drill cooldown
local drillCooldown = Harmony.Cooldown.create{
    length = 30, -- 30 seconds
    type = 'temporary'
}

-- Function to use the drill
local function useDrill(src)
    if drillCooldown:getTimeRemaining() <= 0 then
        -- Perform drill action
        drillCooldown:setOnCooldown()
        -- Notify client about the cooldown
        TriggerClientEvent('drill:startUsingDrill', src) 
    else
        local remainingTime = drillCooldown:getTimeRemaining()
        -- Notify client about remaining cooldown
        TriggerClientEvent('drill:cooldownIsActive', src, remainingTime) 
    end
end

-- Register server event to use the drill
RegisterServerEvent('heist:useDrill', function()
    local src = source
    useDrill(src)
end)

local resource_name = GetCurrentResourceName()

AddEventHandler('onResourceStop', function(resourceName)
    if (resource_name ~= resourceName) then return end

    drillCooldown:destroy()
end)
  • client.lua
lua
local function requestDrillUsage()
    TriggerServerEvent('heist:useDrill')
end

-- Register command to use the drill
RegisterCommand('drill', function()
    requestDrillUsage()
end, false)

RegisterNetEvent('drill:startUsingDrill', function()
    -- main dril to start the proccess
end)

RegisterNetEvent('drill:cooldownIsActive', function(remainingTime)
    remainingTime = math.ceil(remainingTime)
    print('The drill is on cooldown. Please wait ' .. remainingTime .. ' seconds.')
end)