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

Heal cooldown doesnt work

henkas

Well-Known Member
Joined
Jul 8, 2015
Messages
993
Solutions
5
Reaction score
55
Hi,
so im using spell groups but when i use buff i cant cast healing. This is buff
XML:
<instant group="support" spellid="133" name="power up" words="power up" selftarget="1" aggressive="0" lvl="200" maglv="100" mana="5000" soul="0" exhaustion="30000" enabled="1" script="power up.lua"></instant>
This is heals i use
XML:
    <instant group="healing" spellid="135" name="body regeneration" words="body regeneration" selftarget="1" aggressive="0"  lvl="30"     maglv="50"  mana="1500" soul="0" exhaustion="1000" prem="1" enabled="1" script="regeneration.lua"></instant>
    <instant group="healing" spellid="135" name="small body regeneration" words="small body regeneration" selftarget="1" aggressive="0"  lvl="5" maglv="3"  mana="300" soul="0" exhaustion="1000" prem="0" enabled="1" script="sregeneration.lua"></instant>
 
Solution
if it's a 1.x based server then cid would be userdata in this case.
cid:getId() is what you're searching for.
Guess I need to stop helping with 1.x servers.
These minor differences cause a lot of small issues I personally can't troubleshoot without a server log.
Oh well.
Its tfs 1.2 by ninja
Try this.
Lua:
local exhaust = {}

local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_EFFECT, 28)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false)
 
local condition = createConditionObject(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_TICKS, 30000)
condition:setParameter(CONDITION_PARAM_SKILL_SWORD, 10)...
Hi,
so im using spell groups but when i use buff i cant cast healing. This is buff
XML:
<instant group="support" spellid="133" name="power up" words="power up" selftarget="1" aggressive="0" lvl="200" maglv="100" mana="5000" soul="0" exhaustion="30000" enabled="1" script="power up.lua"></instant>
This is heals i use
XML:
    <instant group="healing" spellid="135" name="body regeneration" words="body regeneration" selftarget="1" aggressive="0"  lvl="30"     maglv="50"  mana="1500" soul="0" exhaustion="1000" prem="1" enabled="1" script="regeneration.lua"></instant>
    <instant group="healing" spellid="135" name="small body regeneration" words="small body regeneration" selftarget="1" aggressive="0"  lvl="5" maglv="3"  mana="300" soul="0" exhaustion="1000" prem="0" enabled="1" script="sregeneration.lua"></instant>
instead of exhaust, use..
XML:
cooldown="1000" groupcooldown="1000"
 
Last edited:
otland/forgottenserver (https://github.com/otland/forgottenserver/blob/1.2/data/spells/spells.xml)
In a normal spells.xml document 'exhaustion' is never used.

There's is 3 separate groups. "attack", "support", "healing"
cooldown is spellid specific.
groupcooldown is group specific.

From your comment history, you are using TFS 1.2.
This should be fully functional in your distribution.
Im using ninja edition which doesnt have this stuff. ninjalulz/forgottenserver (https://github.com/ninjalulz/forgottenserver/blob/8.6/data/spells/spells.xml)
I even had to add groups in source because it didnt had group function in spells.xml
Overall like i said it doesnt work. Or you meant to say to replace buff and heal exhaustion with
cooldown="1000" groupcooldown="1000"
because i changed it only on buff
 
Im using ninja edition which doesnt have this stuff. ninjalulz/forgottenserver (https://github.com/ninjalulz/forgottenserver/blob/8.6/data/spells/spells.xml)
I even had to add groups in source because it didnt had group function in spells.xml
Overall like i said it doesnt work. Or you meant to say to replace buff and heal exhaustion with
cooldown="1000" groupcooldown="1000"
because i changed it only on buff
ahhhh, damn that sucks.
Umm, well you could do it another way, via lua.
Use a table, and count via milliseconds.. It's a bit more time consuming, and it's individual to each script, but you won't have to source edit.

Below would be for 0.3.7 servers, so you may need to adjust cid for player, and 'doPlayerSendCancel' to whatever message thing tfs 1.2 uses.
But at least it'll give you a base to work from.

so at the top of your script put a table
Lua:
local exhaust = {}
Then inside your spell, right under onCastSpell, you'd put your checks
Then change '2000' to whatever exhaust you want to use.
Lua:
local cur_time = os.mtime()
if not exhaust[cid] or cur_time > exhaust[cid] then
    exhaust[cid] = cur_time + 2000
end
if cur_time < exhaust[cid] then
    local next_time = (exhaust[cid] - cur_time) / 1000
    doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
    return false
end
Should work anyways. Unless your server doesn't have os.mtime()... which would really suck.
Welp, hope that works.
 
ahhhh, damn that sucks.
Umm, well you could do it another way, via lua.
Use a table, and count via milliseconds.. It's a bit more time consuming, and it's individual to each script, but you won't have to source edit.

Below would be for 0.3.7 servers, so you may need to adjust cid for player, and 'doPlayerSendCancel' to whatever message thing tfs 1.2 uses.
But at least it'll give you a base to work from.

so at the top of your script put a table
Lua:
local exhaust = {}
Then inside your spell, right under onCastSpell, you'd put your checks
Then change '2000' to whatever exhaust you want to use.
Lua:
local cur_time = os.mtime()
if not exhaust[cid] or cur_time > exhaust[cid] then
    exhaust[cid] = cur_time + 2000
end
if cur_time < exhaust[cid] then
    local next_time = (exhaust[cid] - cur_time) / 1000
    doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
    return false
end
Should work anyways. Unless your server doesn't have os.mtime()... which would really suck.
Welp, hope that works.
Wait lets start everything all over again so it looks like everything works how it is in previous code i gave only with groups and etc so i tested on localhost everything is perfect then i went to linux and this is where exhaustion appears, so we can say it doesnt work on linux.
 
ahhhh, damn that sucks.
Umm, well you could do it another way, via lua.
Use a table, and count via milliseconds.. It's a bit more time consuming, and it's individual to each script, but you won't have to source edit.

Below would be for 0.3.7 servers, so you may need to adjust cid for player, and 'doPlayerSendCancel' to whatever message thing tfs 1.2 uses.
But at least it'll give you a base to work from.

so at the top of your script put a table
Lua:
local exhaust = {}
Then inside your spell, right under onCastSpell, you'd put your checks
Then change '2000' to whatever exhaust you want to use.
Lua:
local cur_time = os.mtime()
if not exhaust[cid] or cur_time > exhaust[cid] then
    exhaust[cid] = cur_time + 2000
end
if cur_time < exhaust[cid] then
    local next_time = (exhaust[cid] - cur_time) / 1000
    doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
    return false
end
Should work anyways. Unless your server doesn't have os.mtime()... which would really suck.
Welp, hope that works.
You code gives error 'table index is a nil' in 26line which is
exhaust[cid] = cur_time + 30000
 
You code gives error 'table index is a nil' in 26line which is
exhaust[cid] = cur_time + 30000
Had some logic failure in the first one, but otherwise there is no issue.
Here's one I just tested.
s2EpGHa.gif

Lua:
local exhaust = {}

function onCastSpell(cid, var)
    local cur_time = os.mtime()
    if not exhaust[cid] then
        exhaust[cid] = 0
    end
    if exhaust[cid] > cur_time then
        local next_time = (exhaust[cid] - cur_time) / 1000
        doSendAnimatedText(getThingPosition(cid), "Exhausted. Can use again in " .. next_time .. " seconds.", COLOR_ORANGE, nil)
        return false
    end
    exhaust[cid] = cur_time + 2000
    doSendAnimatedText(getThingPosition(cid), "Test!", COLOR_ORANGE, nil)
    return true
end
 
Had some logic failure in the first one, but otherwise there is no issue.
Here's one I just tested.
s2EpGHa.gif

Lua:
local exhaust = {}

function onCastSpell(cid, var)
    local cur_time = os.mtime()
    if not exhaust[cid] then
        exhaust[cid] = 0
    end
    if exhaust[cid] > cur_time then
        local next_time = (exhaust[cid] - cur_time) / 1000
        doSendAnimatedText(getThingPosition(cid), "Exhausted. Can use again in " .. next_time .. " seconds.", COLOR_ORANGE, nil)
        return false
    end
    exhaust[cid] = cur_time + 2000
    doSendAnimatedText(getThingPosition(cid), "Test!", COLOR_ORANGE, nil)
    return true
end
So first of all i gives getThingPosition error. But nvm i can use doPlayerSendCancel. About cooldown it doesnt work i cam spam as much as i want
Lua:
function onCastSpell(cid, var)
    local cur_time = os.mtime()
    if not exhaust[cid] then
        exhaust[cid] = 0
    end
    if exhaust[cid] > cur_time then
        local next_time = (exhaust[cid] - cur_time) / 1000
        doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
        return false
    end
    exhaust[cid] = cur_time + 30000
    return true
end
 
I added prints to your script. Changed nothing else.
Tested, and worked perfectly fine.
---
edit: If you test it and don't get the same results as below, show us a screenshot.
---
RbTyI8L.png

Lua:
local exhaust = {}

function onCastSpell(cid, var)
    local cur_time = os.mtime()
    print("cur_time = " .. cur_time .. "")
    if not exhaust[cid] then
        exhaust[cid] = 0
    end
    print("exhaust[cid] = " .. exhaust[cid] .. "")
    if exhaust[cid] > cur_time then
        local next_time = (exhaust[cid] - cur_time) / 1000
        doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
        print("exhausted. " .. exhaust[cid] .. " - " .. cur_time .. " = " .. (exhaust[cid] - cur_time) .. "")
        print("----")
        return false
    end
    exhaust[cid] = cur_time + 30000
    print("Success.")
    print("----")
    return true
end
You aren't on a GOD/GM character?
Being on a god or player character won't matter for this.
It's just simple lua functions.
 
Last edited:
I added prints to your script. Changed nothing else.
Tested, and worked perfectly fine.
---
edit: If you test it and don't get the same results as below, show us a screenshot.
---
RbTyI8L.png

Lua:
local exhaust = {}

function onCastSpell(cid, var)
    local cur_time = os.mtime()
    print("cur_time = " .. cur_time .. "")
    if not exhaust[cid] then
        exhaust[cid] = 0
    end
    print("exhaust[cid] = " .. exhaust[cid] .. "")
    if exhaust[cid] > cur_time then
        local next_time = (exhaust[cid] - cur_time) / 1000
        doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
        print("exhausted. " .. exhaust[cid] .. " - " .. cur_time .. " = " .. (exhaust[cid] - cur_time) .. "")
        print("----")
        return false
    end
    exhaust[cid] = cur_time + 30000
    print("Success.")
    print("----")
    return true
end

Being on a god or player character won't matter for this.
It's just simple lua functions.
36317
 
How..?
Do you have the table at the top of the script? 'local exhaust = {}' ?
It has to be above the onCast function.

add me on discord if you think everything looks fine and still having an issue with this method.
Xikini#0001
Yes everything is at the top
Lua:
local exhaust = {}

local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_EFFECT, 28)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false)
 
local condition = createConditionObject(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_TICKS, 30000)
condition:setParameter(CONDITION_PARAM_SKILL_SWORD, 10)
condition:setParameter(CONDITION_PARAM_SKILL_AXE, 10)
condition:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 10)
condition:setParameter(CONDITION_PARAM_SKILL_SHIELD, 10)
condition:setParameter(CONDITION_PARAM_SKILL_FISHING, 10)
condition:setParameter(CONDITION_PARAM_SKILL_CLUB, 15)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 5000)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANAPOINTS, 5000)
condition:setParameter(CONDITION_PARAM_BUFF, true)
setCombatCondition(combat, condition)
 
function onCastSpell(cid, var)
    local cur_time = os.mtime()
    print("cur_time = " .. cur_time .. "")
    if not exhaust[cid] then
        exhaust[cid] = 0
    end
    print("exhaust[cid] = " .. exhaust[cid] .. "")
    if exhaust[cid] > cur_time then
        local next_time = (exhaust[cid] - cur_time) / 1000
        doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
        print("exhausted. " .. exhaust[cid] .. " - " .. cur_time .. " = " .. (exhaust[cid] - cur_time) .. "")
        print("----")
        return false
    end
    exhaust[cid] = cur_time + 30000
    print("Success.")
    print("----")
    return true
end
 
Yes everything is at the top
Lua:
local exhaust = {}

local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_EFFECT, 28)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false)

local condition = createConditionObject(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_TICKS, 30000)
condition:setParameter(CONDITION_PARAM_SKILL_SWORD, 10)
condition:setParameter(CONDITION_PARAM_SKILL_AXE, 10)
condition:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 10)
condition:setParameter(CONDITION_PARAM_SKILL_SHIELD, 10)
condition:setParameter(CONDITION_PARAM_SKILL_FISHING, 10)
condition:setParameter(CONDITION_PARAM_SKILL_CLUB, 15)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 5000)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANAPOINTS, 5000)
condition:setParameter(CONDITION_PARAM_BUFF, true)
setCombatCondition(combat, condition)

function onCastSpell(cid, var)
    local cur_time = os.mtime()
    print("cur_time = " .. cur_time .. "")
    if not exhaust[cid] then
        exhaust[cid] = 0
    end
    print("exhaust[cid] = " .. exhaust[cid] .. "")
    if exhaust[cid] > cur_time then
        local next_time = (exhaust[cid] - cur_time) / 1000
        doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
        print("exhausted. " .. exhaust[cid] .. " - " .. cur_time .. " = " .. (exhaust[cid] - cur_time) .. "")
        print("----")
        return false
    end
    exhaust[cid] = cur_time + 30000
    print("Success.")
    print("----")
    return true
end
I don't have a 1.x server to troubleshoot why your table isn't staying loaded between uses.

Initial thoughts are..
Check that cid is actually a valid number..

If yes.. then maybe 1.x spells are reloading the locals every time spell is cast for some odd reason?
If this is the case try the table without using local. (rename to something more specific.. spell_name_exhaust = {}.. so it's not overwritten accidentally)

If still not working, bring the table somewhere outside of the spell system..?
Try table inside of libs folder. (rename.. blah blah)

--
Sorry, I'm not sure what else to try but above.

If you end up needing to place it in lib, you could start making the table more complex, so you don't need a new global table for every spell you're wanting to use this in.
But eh, test and find out what will get it working is the first part.
 
if it's a 1.x based server then cid would be userdata in this case.
cid:getId() is what you're searching for.
Its tfs 1.2 by ninja
 
if it's a 1.x based server then cid would be userdata in this case.
cid:getId() is what you're searching for.
Guess I need to stop helping with 1.x servers.
These minor differences cause a lot of small issues I personally can't troubleshoot without a server log.
Oh well.
Its tfs 1.2 by ninja
Try this.
Lua:
local exhaust = {}

local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_EFFECT, 28)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false)
 
local condition = createConditionObject(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_TICKS, 30000)
condition:setParameter(CONDITION_PARAM_SKILL_SWORD, 10)
condition:setParameter(CONDITION_PARAM_SKILL_AXE, 10)
condition:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 10)
condition:setParameter(CONDITION_PARAM_SKILL_SHIELD, 10)
condition:setParameter(CONDITION_PARAM_SKILL_FISHING, 10)
condition:setParameter(CONDITION_PARAM_SKILL_CLUB, 15)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, 5000)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANAPOINTS, 5000)
condition:setParameter(CONDITION_PARAM_BUFF, true)
setCombatCondition(combat, condition)
 
function onCastSpell(cid, var)
    local cur_time, playerid = os.mtime(), cid:getId()
    print("cur_time = " .. cur_time .. "")
    if not exhaust[playerid] then
        exhaust[playerid] = 0
    end
    print("exhaust[playerid] = " .. exhaust[playerid] .. "")
    if exhaust[playerid] > cur_time then
        local next_time = (exhaust[playerid] - cur_time) / 1000
        doPlayerSendCancel(cid, "Exhausted. Can use again in " .. next_time .. " seconds.")
        print("exhausted. " .. exhaust[playerid] .. " - " .. cur_time .. " = " .. (exhaust[playerid] - cur_time) .. "")
        print("----")
        return false
    end
    exhaust[playerid] = cur_time + 30000
    print("Success.")
    print("----")
    return true
end
 
Solution
Back
Top