• 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!

add cooldowns on custom potions. TFS 1.2 (10.98)

oshrigames

Active Member
Joined
Nov 9, 2012
Messages
222
Reaction score
47
Location
israel
hello :)

first im using TFS 1.2 (protocol 10.98).
id like to add a cooldown on my custom potions ive been working on for my alchemy system.
for balance reasons i need to make sure not multiple potions can be used at once and have exhaustion for the user.

i've tried but failed in all my attempts to do it on my own.
1) custom pot can be used once per 5 minutes.
2) only one pot effect can be active at a time.
3) diffrent player can't by pass 2. by use potion his friend.

this is a one of my potions (which will release once it's all done)
potions ideas:
ID 21449.
Elixir of Fortitude (tier 3+)
Buff: +8 hp per 2 sec, +100 max hp.
Debuff: minor paralyze, drunk.
Duration: 60 sec.
exhaustion: 5 min.


Lua:
local combat = Combat()
    combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
    combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)
    combat:setCondition(condition)
 
local condition = Condition(CONDITION_REGENERATION)
    condition:setParameter(CONDITION_PARAM_SUBID, 3)
    condition:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 8) -- heal 8 hp every 2 sec
    condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 2000) -- 2 sec
    condition:setParameter(CONDITION_PARAM_BUFF_SPELL, true)

local condition1 = Condition(CONDITION_ATTRIBUTES)
    condition1:setParameter(CONDITION_PARAM_SUBID, 2)
    condition1:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition1:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 100) -- gain 100 to max hp
    
local condition2 = Condition(CONDITION_PARALYZE)
    condition2:setParameter(CONDITION_PARAM_SUBID, 1)
    condition2:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition2:setFormula(-0.4, 0, -0.4, 0) -- base speed = 200 | exemple A: (0.2, 0, 0.2, 0) = 240 speed. (20% of base speed) | exemple B: (0, 20, 0, 20) = 210 speed. (20/2)
    
local condition3 = Condition(CONDITION_DRUNK)
    condition3:setParameter(CONDITION_PARAM_TICKS, 60000)
    
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
        player:addCondition(condition)
            if player:addCondition(condition1) and player:addCondition(condition2) and player:addCondition(condition3) then
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        Item(item.uid):remove(1)
    end
    return true
end

any help will be much appreciated ♥
 
Solution
Install my custom cooldown system. In 2015~ (before TFS 1.0) I was selling it for 10$

In data/lib/lib.lua add this line:
Code:
dofile('data/lib/systems/SYS-cooldown.lua')

Now copy this to your data/lib/systems/SYS-cooldown.lua
Lua:
-- by andu from OTLand

function getPlayerCd(cid, cooldownId)
    return getPlayerStorageValue(cid, cooldownId)-os.time()
end

function doPlayerSayCd(cid, cooldownId)
    local mini = ""
    local text = ""
    if getPlayerStorageValue(cid, cooldownId)-os.time() > 59 and getPlayerStorageValue(cid, cooldownId)-os.time() < 3600 then
        local saytime = math.ceil((getPlayerStorageValue(cid, cooldownId)-os.time())/60)
        if saytime ~= 1 then
            mini = "s"
        end
        text = "Cooldown: "...
Try this

Lua:
local cooldown_storage = <your value here>

local combat = Combat()
    combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
    combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)
    combat:setCondition(condition)
 
local condition = Condition(CONDITION_REGENERATION)
    condition:setParameter(CONDITION_PARAM_SUBID, 3)
    condition:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 8) -- heal 8 hp every 2 sec
    condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 2000) -- 2 sec
    condition:setParameter(CONDITION_PARAM_BUFF_SPELL, true)

local condition1 = Condition(CONDITION_ATTRIBUTES)
    condition1:setParameter(CONDITION_PARAM_SUBID, 2)
    condition1:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition1:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 100) -- gain 100 to max hp
    
local condition2 = Condition(CONDITION_PARALYZE)
    condition2:setParameter(CONDITION_PARAM_SUBID, 1)
    condition2:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition2:setFormula(-0.4, 0, -0.4, 0) -- base speed = 200 | exemple A: (0.2, 0, 0.2, 0) = 240 speed. (20% of base speed) | exemple B: (0, 20, 0, 20) = 210 speed. (20/2)
    
local condition3 = Condition(CONDITION_DRUNK)
    condition3:setParameter(CONDITION_PARAM_TICKS, 60000)
    
function onUse(player, item, fromPosition, target, toPosition, isHotkey)

    if type(target) == "userdata" and not target:isPlayer() then
        return false
    end
    
    if (os.date() - target:getStorageValue(cooldown_storage)) < (5 * 60) then
        if target:addCondition(condition) and target:addCondition(condition1) and target:addCondition(condition2) and target:addCondition(condition3) then
            target:getPosition():sendMagicEffect(CONST_ME_POFF)
            target:setStorageValue(cooldown_storage, os.date())
            Item(item.uid):remove(1)
        end
    else
        target:sendTextMessage(MESSAGE_INFO_DESCR, 'You have to wait ' .. os.date("%M minutes, %S seconds", os.date() - target:getStorageValue(cooldown_storage)) .. ' before drinking this potion.')
        return false
    end
    
    return true
    
end

I used here storage value to save timestamp of last potion use, if current time subtracted by timestamp is larger than 5 minutes (5 * 60 sec) you can proceed and apply conditions and insert new timestamp value. If it is smaller than 5 minutes - send a message about it and cancel script execution.

You can easily adjust this script to other potions also.

Remember to set cooldown_storage
 
i get this error


Code:
Lua Script Error: [Action Interface]
data/actions/scripts/custom/elixir_of_fortitude.lua:onUse
data/actions/scripts/custom/elixir_of_fortitude.lua:34: attempt to perform arithmetic on a string value
stack traceback:
        [C]: in function '__sub'
        data/actions/scripts/custom/elixir_of_fortitude.lua:34: in function <data/actions/scripts/custom/elixir_of_fortitude.lua:28>

cooldown_storage i set to 15040
 
I may be wrong but, os.data returns a string of characters so that's why you can't perform an arithmetic operation with it. Have you tried to use os.time instead of date? You could maybe save the os.time timestamp once the users drinks a potion, then if he tries to drink another you just check the value saved against os.time + the amount of time you choose as exhaust.
Post automatically merged:

 
Yeah, that's basically how my script does it, And you are right, all os.date() have to be replaced with os.time() (except this one which format timestamp to mins and sec) My fault, code should how look like this:
Lua:
local cooldown_storage = <your value here>

local combat = Combat()
    combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
    combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)
    combat:setCondition(condition)
 
local condition = Condition(CONDITION_REGENERATION)
    condition:setParameter(CONDITION_PARAM_SUBID, 3)
    condition:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 8) -- heal 8 hp every 2 sec
    condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 2000) -- 2 sec
    condition:setParameter(CONDITION_PARAM_BUFF_SPELL, true)

local condition1 = Condition(CONDITION_ATTRIBUTES)
    condition1:setParameter(CONDITION_PARAM_SUBID, 2)
    condition1:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition1:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 100) -- gain 100 to max hp
    
local condition2 = Condition(CONDITION_PARALYZE)
    condition2:setParameter(CONDITION_PARAM_SUBID, 1)
    condition2:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    condition2:setFormula(-0.4, 0, -0.4, 0) -- base speed = 200 | exemple A: (0.2, 0, 0.2, 0) = 240 speed. (20% of base speed) | exemple B: (0, 20, 0, 20) = 210 speed. (20/2)
    
local condition3 = Condition(CONDITION_DRUNK)
    condition3:setParameter(CONDITION_PARAM_TICKS, 60000)
    
function onUse(player, item, fromPosition, target, toPosition, isHotkey)

    if type(target) == "userdata" and not target:isPlayer() then
        return false
    end
    
    if (os.time() - target:getStorageValue(cooldown_storage)) < (5 * 60) then
        if target:addCondition(condition) and target:addCondition(condition1) and target:addCondition(condition2) and target:addCondition(condition3) then
            target:getPosition():sendMagicEffect(CONST_ME_POFF)
            target:setStorageValue(cooldown_storage, os.time())
            Item(item.uid):remove(1)
        end
    else
        target:sendTextMessage(MESSAGE_INFO_DESCR, 'You have to wait ' .. os.date("%M minutes, %S seconds", os.time() - target:getStorageValue(cooldown_storage)) .. ' before drinking this potion.')
        return false
    end
    
    return true
    
end
 
Last edited:
Install my custom cooldown system. In 2015~ (before TFS 1.0) I was selling it for 10$

In data/lib/lib.lua add this line:
Code:
dofile('data/lib/systems/SYS-cooldown.lua')

Now copy this to your data/lib/systems/SYS-cooldown.lua
Lua:
-- by andu from OTLand

function getPlayerCd(cid, cooldownId)
    return getPlayerStorageValue(cid, cooldownId)-os.time()
end

function doPlayerSayCd(cid, cooldownId)
    local mini = ""
    local text = ""
    if getPlayerStorageValue(cid, cooldownId)-os.time() > 59 and getPlayerStorageValue(cid, cooldownId)-os.time() < 3600 then
        local saytime = math.ceil((getPlayerStorageValue(cid, cooldownId)-os.time())/60)
        if saytime ~= 1 then
            mini = "s"
        end
        text = "Cooldown: " ..saytime.." minute" ..mini.." left."
    elseif getPlayerStorageValue(cid, cooldownId)-os.time() > 3599 then
        local saytime = math.ceil((getPlayerStorageValue(cid, cooldownId)-os.time())/3600)
        if saytime ~= 1 then
            mini = "s"
        end
        text = "Cooldown: " ..saytime.." hour" ..mini.." left."
    else
        text = "Cooldown: " ..(getPlayerStorageValue(cid, cooldownId)-os.time()).." seconds left."
    end
    doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF)
    return doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, text)
end

function setPlayerCd(cid, cooldownId, value)
    if getPlayerAccess(cid) >= 4 then
        value = 0
    end
    return setPlayerStorageValue(cid, cooldownId, os.time()+value)
end

function checkSpellCd(cid, id, time)
    if getPlayerCd(cid, id) > 0 then
        doPlayerSayCd(cid, id)
        return false
    end
    return setPlayerCd(cid, id, time)
end

It will work for everything, actions, spells, movements, globalevents, creaturescripts etc. Now if you want to control something with cooldown just add this line before main code:
Lua:
if checkSpellCd(player, cooldown_id, time_in_seconds) == false then return false end

Also I fixed your code to match what you need. I also changed condition1 etc to something more user friendly. You don't have to use combat if you going to apply only conditions. Every spell can be done without 'combat' thing. Even exori. Combat thing is useful only if you going to shorten very complicated things, like GFB what checks players in large area, applies dmg to every one hit etc. Also 'combat' requires variant in 3rd argument. So you will have to convert it to variant with numberToVariant for example. In your case player is a caster and a target at once. So you will have to convert player's id to variant to be able to use execute:combat under onUse function.

Elixir of Fortitude (tier 3+)
Buff: +8 hp per 2 sec, +100 max hp.
Debuff: minor paralyze, drunk.
Duration: 60 sec.
exhaustion: 5 min.

Lua:
local time_in_seconds = 5 * 60 -- in seconds
local cooldown_id = 123456

local regen = Condition(CONDITION_REGENERATION)
    regen:setParameter(CONDITION_PARAM_SUBID, 3)
    regen:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    regen:setParameter(CONDITION_PARAM_HEALTHGAIN, 8) -- heal 8 hp every 2 sec
    regen:setParameter(CONDITION_PARAM_HEALTHTICKS, 2000) -- 2 sec
    regen:setParameter(CONDITION_PARAM_BUFF_SPELL, true)

local maxhp = Condition(CONDITION_ATTRIBUTES)
    maxhp:setParameter(CONDITION_PARAM_SUBID, 2)
    maxhp:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    maxhp:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 100) -- gain 100 to max hp

local paral = Condition(CONDITION_PARALYZE)
    paral:setParameter(CONDITION_PARAM_SUBID, 1)
    paral:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    paral:setFormula(-0.4, 0, -0.4, 0) -- base speed = 200 | exemple A: (0.2, 0, 0.2, 0) = 240 speed. (20% of base speed) | exemple B: (0, 20, 0, 20) = 210 speed. (20/2)

local drunk = Condition(CONDITION_DRUNK)
    drunk:setParameter(CONDITION_PARAM_TICKS, 60000)
    drunk:setParameter(CONDITION_PARAM_SUBID, 4)

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if checkSpellCd(player, cooldown_id, time_in_seconds) == false then return false end -- added line for andu's cooldown system
    player:addCondition(regen)
    player:addCondition(maxhp)
    player:addCondition(paral)
    player:addCondition(drunk)
    player:getPosition():sendMagicEffect(CONST_ME_POFF)
    Item(item.uid):remove(1)
    return true
end
 
Last edited:
Solution
If you have errors on characters what casts spells for the first time then you have to replace this in lib:

Lua:
function checkSpellCd(cid, id, time)
    if getPlayerCd(cid, id) > 0 then
        doPlayerSayCd(cid, id)
        return false
    end
    return setPlayerCd(cid, id, time)
end

with this:
Lua:
function checkSpellCd(cid, id, time)
    local cd = getPlayerCd(cid, id)
    if cd ~= nil then
        if cd > 0 then
            doPlayerSayCd(cid, id)
            return false
        end
    end
    setPlayerCd(cid, id, time)
    return true
end
 
Last edited:
Install my custom cooldown system. In 2015~ (before TFS 1.0) I was selling it for 10$

In data/lib/lib.lua add this line:
Code:
dofile('data/lib/systems/SYS-cooldown.lua')

Now copy this to your data/lib/systems/SYS-cooldown.lua
Lua:
-- by andu from OTLand

function getPlayerCd(cid, cooldownId)
    return getPlayerStorageValue(cid, cooldownId)-os.time()
end

function doPlayerSayCd(cid, cooldownId)
    local mini = ""
    local text = ""
    if getPlayerStorageValue(cid, cooldownId)-os.time() > 59 and getPlayerStorageValue(cid, cooldownId)-os.time() < 3600 then
        local saytime = math.ceil((getPlayerStorageValue(cid, cooldownId)-os.time())/60)
        if saytime ~= 1 then
            mini = "s"
        end
        text = "Cooldown: " ..saytime.." minute" ..mini.." left."
    elseif getPlayerStorageValue(cid, cooldownId)-os.time() > 3599 then
        local saytime = math.ceil((getPlayerStorageValue(cid, cooldownId)-os.time())/3600)
        if saytime ~= 1 then
            mini = "s"
        end
        text = "Cooldown: " ..saytime.." hour" ..mini.." left."
    else
        text = "Cooldown: " ..(getPlayerStorageValue(cid, cooldownId)-os.time()).." seconds left."
    end
    doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF)
    return doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, text)
end

function setPlayerCd(cid, cooldownId, value)
    if getPlayerAccess(cid) >= 4 then
        value = 0
    end
    return setPlayerStorageValue(cid, cooldownId, os.time()+value)
end

function checkSpellCd(cid, id, time)
    if getPlayerCd(cid, id) > 0 then
        doPlayerSayCd(cid, id)
        return false
    end
    return setPlayerCd(cid, id, time)
end

It will work for everything, actions, spells, movements, globalevents, creaturescripts etc. Now if you want to control something with cooldown just add this line before main code:
Lua:
if checkSpellCd(player, cooldown_id, time_in_seconds) == false then return false end

Also I fixed your code to match what you need. I also changed condition1 etc to something more user friendly. You don't have to use combat if you going to apply only conditions. Every spell can be done without 'combat' thing. Even exori. Combat thing is useful only if you going to shorten very complicated things, like GFB what checks players in large area, applies dmg to every one hit etc. Also 'combat' requires variant in 3rd argument. So you will have to convert it to variant with numberToVariant for example. In your case player is a caster and a target at once. So you will have to convert player's id to variant to be able to use execute:combat under onUse function.

Elixir of Fortitude (tier 3+)
Buff: +8 hp per 2 sec, +100 max hp.
Debuff: minor paralyze, drunk.
Duration: 60 sec.
exhaustion: 5 min.

Lua:
local time_in_seconds = 5 * 60 -- in seconds
local cooldown_id = 123456

local regen = Condition(CONDITION_REGENERATION)
    regen:setParameter(CONDITION_PARAM_SUBID, 3)
    regen:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    regen:setParameter(CONDITION_PARAM_HEALTHGAIN, 8) -- heal 8 hp every 2 sec
    regen:setParameter(CONDITION_PARAM_HEALTHTICKS, 2000) -- 2 sec
    regen:setParameter(CONDITION_PARAM_BUFF_SPELL, true)

local maxhp = Condition(CONDITION_ATTRIBUTES)
    maxhp:setParameter(CONDITION_PARAM_SUBID, 2)
    maxhp:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    maxhp:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 100) -- gain 100 to max hp

local paral = Condition(CONDITION_PARALYZE)
    paral:setParameter(CONDITION_PARAM_SUBID, 1)
    paral:setParameter(CONDITION_PARAM_TICKS, 60000) -- 1 minute
    paral:setFormula(-0.4, 0, -0.4, 0) -- base speed = 200 | exemple A: (0.2, 0, 0.2, 0) = 240 speed. (20% of base speed) | exemple B: (0, 20, 0, 20) = 210 speed. (20/2)

local drunk = Condition(CONDITION_DRUNK)
    drunk:setParameter(CONDITION_PARAM_TICKS, 60000)
    drunk:setParameter(CONDITION_PARAM_SUBID, 4)

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if checkSpellCd(player, cooldown_id, time_in_seconds) == false then return false end -- added line for andu's cooldown system
    player:addCondition(regen)
    player:addCondition(maxhp)
    player:addCondition(paral)
    player:addCondition(drunk)
    player:getPosition():sendMagicEffect(CONST_ME_POFF)
    Item(item.uid):remove(1)
    return true
end
Does this system work on spells?
Solved
Lua:
function onCastSpell(player, variant)
    if checkSpellCd(player, cooldown_id, time_in_seconds) == false then return false end
    return combat:execute(player, variant)
end
 
Last edited:
Back
Top