add cooldowns on custom potions. TFS 1.2 (10.98)

oshrigames

Active Member
Joined
Nov 9, 2012
Messages
213
Best answers
0
Reaction score
38
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 ♥
 

Yalasari

Active Member
Joined
Jul 16, 2017
Messages
70
Best answers
6
Reaction score
37
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
 
OP
oshrigames

oshrigames

Active Member
Joined
Nov 9, 2012
Messages
213
Best answers
0
Reaction score
38
Location
israel
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
 

Ramirow

Advanced OT User
Joined
Aug 22, 2009
Messages
510
Best answers
13
Reaction score
207
Location
Argentina
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:

 

Yalasari

Active Member
Joined
Jul 16, 2017
Messages
70
Best answers
6
Reaction score
37
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:

andu

Sold 649 scripts, 25 maps and 9 events!
Joined
Aug 7, 2009
Messages
923
Best answers
13
Reaction score
280
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:
OP
oshrigames

oshrigames

Active Member
Joined
Nov 9, 2012
Messages
213
Best answers
0
Reaction score
38
Location
israel
thanks for all your help guys, andu system works like a charm ♥

much appreciated :)
 

andu

Sold 649 scripts, 25 maps and 9 events!
Joined
Aug 7, 2009
Messages
923
Best answers
13
Reaction score
280
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:
Top