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

Lua Script to "replace" source spell cooldown

Icaraii

Well-Known Member
Joined
Jan 5, 2020
Messages
469
Solutions
1
Reaction score
58
Hey guys, I would like a script that when you kill a monster with a specific weapon, you have a % of reducing spell cooldown by x seconds. But in order to do so, I would need a script to replace the source spell cooldown using table or storage value. However this is too complex for me to do, could somebody help?

TFS 1.3
 
Last edited:
Solution
Here I will show you an example of how it is done with pure lua, but you must bear in mind that it is not something clean and it is not a complete code, but I will give you an example to see if you dare to complete it or if someone wants to finish it for you

data/scripts/spellcooldownsystem.lua
Lua:
SpellCooldownSystem = {
    storages = {},
    cooldowns = {},
    reduction = 0.10 -- 10%
}

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogin")
function spellCooldownEvent.onLogin(player)
    SpellCooldownSystem.storages[player:getId()] = {}
    player:registerEvent("SpellCooldownSystemReduction")
    return true
end
spellCooldownEvent:register()

local spellCooldownEvent =...
You don't have to set the cooldown when someone casts the spell, it's already done by TFS. If you want to reduce current cooldows when you kill monster then you need kill event, id of spell you want to reduce that cooldown for and use of creature:getCondition and creature:addCondition.
I don't need to do anything at the spell? Just create kill event?
 
Lua:
local conditions = {CONDITION_SPELLGROUPCOOLDOWN, CONDITION_SPELLCOOLDOWN}
local monsters = {"Troll", "Rat"}

function onKill(player, target)
    if not target:isMonster() then return true end

    if (monsters and isInArray(monsters, target:getName()) or true) and math.rand(10) == 1 then
        for i=1, #conditions do
            local condition = player:getCondition(conditions[i])
            if condition then
                condition:remove()
            end
        end
    end
end
Basically, it works (or it should, didnt tested it) like that there is a 10% chance that if you kill a monster from the monsters table (or leave it empty for any monster)
it will remove the conditions (that are in conditions table) from the player that dealt the last hit.

If you want to do it for all the players that did the damage, you need to iterate over the target:getDamageMap()
 
Last edited:
Lua:
local conditions = {CONDITION_SPELLGROUPCOOLDOWN, CONDITION_SPELLCOOLDOWN}
local monsters = {"Troll", "Rat"}

function onKill(player, target)
    if not target:isMonster() then return true end

    if (monsters and isInArray(monsters, target:getName()) or true) and math.rand(10) == 1 then
        for i=1, #conditions do
            local condition = player:getCondition(conditions[i])
            if condition then
                condition:remove()
            end
        end
    end
end
untested
That will remove all cooldowns, not reduce them.
 
That will remove all cooldowns, not reduce them.
Instead of remove() you can getTicks(), substract and setTicks() as Azakelis said
Lua:
local conditions = {CONDITION_SPELLGROUPCOOLDOWN, CONDITION_SPELLCOOLDOWN}
local monsters = {"Troll", "Rat"}
local removeCondition = true
local ticksToBeRemoved = 200

function onKill(player, target)
    if not target:isMonster() then return true end

    if (monsters and isInArray(monsters, target:getName()) or true) and math.rand(10) == 1 then
        for i=1, #conditions do
            local condition = player:getCondition(conditions[i])
            if condition then
                if removeCondition then
                    condition:remove()
                else
                    local ticks = conditions:getTicks()
                    condition:setTicks(ticks - ticksToBeRemoved)
                end
            end
        end
    end
end
 
Last edited:
Lua:
local conditions = {CONDITION_SPELLGROUPCOOLDOWN, CONDITION_SPELLCOOLDOWN}
local monsters = {"Troll", "Rat"}

function onKill(player, target)
    if not target:isMonster() then return true end

    if (monsters and isInArray(monsters, target:getName()) or true) and math.rand(10) == 1 then
        for i=1, #conditions do
            local condition = player:getCondition(conditions[i])
            if condition then
                condition:remove()
            end
        end
    end
end
Basically, it works (or it should, didnt tested it) like that there is a 10% chance that if you kill a monster from the monsters table (or leave it empty for any monster)
it will remove the conditions (that are in conditions table) from the player that dealt the last hit.

If you want to do it for all the players that did the damage, you need to iterate over the target:getDamageMap()
Forgive me for the very noob question. Do I put this on creaturescript?
 
Forgive me for the very noob question. Do I put this on creaturescript?
Yes, create a script in creaturescripts/scripts, name it cooldownreducer.lua or however you like
In creaturescritps.xml
<event type="kill" name="CooldownReducer" script="cooldownreducer.lua"/>
and in login.lua
player:registerEvent("CooldownReducer")
 
<event type="kill" name="CooldownReducer" script="cooldownreducer.lua"/>
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/cooldownreducer.lua:eek:nKill
data/creaturescripts/scripts/cooldownreducer.lua:7: attempt to call field 'rand' (a nil value)
stack traceback:
[C]: in function 'rand'
data/creaturescripts/scripts/cooldownreducer.lua:7: in function <data/creaturescripts/scripts/cooldownreducer.lua:4>
should I change rand for random?

I change it, and got no errors on TFS, but it ain't working. Any suggestions?
 
Still not working and no errors on TFS. Can we put to print so we can check what is doing and what is not working?
You can put prints wherever you like :p
Keep in mind that there is only 10% chance for it to execute, and only for conditions listed in conditions, make sure they match your engine's
 
No, but in various engines, there are various cooldown conditions. Which one are you using?
The Forgotten Server - Version 1.3

Compiled with Microsoft Visual C++ version 14.2
Compiled on Jun 15 2021 21:02:56 for platform x64
Linked with LuaJIT 2.0.5 for Lua support

A server developed by Mark Samman
Visit our forum for updates, support, and resources: OTLand (https://otland.net/).
 
Here I will show you an example of how it is done with pure lua, but you must bear in mind that it is not something clean and it is not a complete code, but I will give you an example to see if you dare to complete it or if someone wants to finish it for you

data/scripts/spellcooldownsystem.lua
Lua:
SpellCooldownSystem = {
    storages = {},
    cooldowns = {},
    reduction = 0.10 -- 10%
}

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogin")
function spellCooldownEvent.onLogin(player)
    SpellCooldownSystem.storages[player:getId()] = {}
    player:registerEvent("SpellCooldownSystemReduction")
    return true
end
spellCooldownEvent:register()

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogout")
function spellCooldownEvent.onLogout(player)
    SpellCooldownSystem.storages[player:getId()] = nil
    return true
end
spellCooldownEvent:register()

function SpellCooldownSystem.canUseSpell(playerId, name, cooldown)
    if not SpellCooldownSystem.storages[playerId] then
        SpellCooldownSystem.storages[playerId] = {}
    end

    if not SpellCooldownSystem.storages[playerId][name] or SpellCooldownSystem.storages[playerId][name] <= os.mtime() then
        SpellCooldownSystem.storages[playerId][name] = os.mtime() + cooldown
        SpellCooldownSystem.cooldowns[name] = cooldown
        return true
    end
    return false
end

local event = CreatureEvent("SpellCooldownSystemReduction")
function event.onKill(player, target)
    local playerId = player:getId()
    if SpellCooldownSystem.storages[playerId] then
        for k, v in pairs(SpellCooldownSystem.storages[playerId]) do
            SpellCooldownSystem.storages[playerId][k] = SpellCooldownSystem.storages[playerId][k] - (SpellCooldownSystem.cooldowns[k] * SpellCooldownSystem.reduction)
        end
    end
    return true
end
event:register()

data/spells/spells.xml
XML:
<!-- TEST -->
    <instant group="attack" spellid="88" name="Energy Strike 2" words="exori vis 2" level="12" mana="20" premium="1" range="3" casterTargetOrDirection="1" blockwalls="1" cooldown="0" groupcooldown="0" needlearn="0" script="test.lua">
        <vocation name="Sorcerer" />
        <vocation name="Druid" />
        <vocation name="Master Sorcerer" />
        <vocation name="Elder Druid" />
    </instant>

data/spells/scripts/test.lua
Lua:
local config = {
    name = "energy strike",
    cooldown = 20 * 1000
}

local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 1.4) + 8
    local max = (level / 5) + (magicLevel * 2.2) + 14
    return -min, -max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    if SpellCooldownSystem.canUseSpell(creature:getId(), config.name, config.cooldown) then
        return combat:execute(creature, variant)
    end

    creature:sendCancelMessage("You are exahusted.")
    return false
end


GIF examples:
* Here you can see that the counter is normally reduced as time passes
GIF 13-07-2021 08-39-13 p. m..gif
* Here you can see that the time is normally reduced, but when you kill a monster the time is reduced by 10% for each monster you kill
GIF 13-07-2021 08-39-36 p. m..gif

Notes:
  • I don't recommend that you do it this way, but here is the alternative anyway.
  • This little code does not cover all possible cases, such as when a player closes section
  • As you can see, you must also configure the names manually in the file, as well as the cooldown, (this does not cover the cooldown by groups either)
 
Solution
Here I will show you an example of how it is done with pure lua, but you must bear in mind that it is not something clean and it is not a complete code, but I will give you an example to see if you dare to complete it or if someone wants to finish it for you

data/scripts/spellcooldownsystem.lua
Lua:
SpellCooldownSystem = {
    storages = {},
    cooldowns = {},
    reduction = 0.10 -- 10%
}

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogin")
function spellCooldownEvent.onLogin(player)
    SpellCooldownSystem.storages[player:getId()] = {}
    player:registerEvent("SpellCooldownSystemReduction")
    return true
end
spellCooldownEvent:register()

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogout")
function spellCooldownEvent.onLogout(player)
    SpellCooldownSystem.storages[player:getId()] = nil
    return true
end
spellCooldownEvent:register()

function SpellCooldownSystem.canUseSpell(playerId, name, cooldown)
    if not SpellCooldownSystem.storages[playerId] then
        SpellCooldownSystem.storages[playerId] = {}
    end

    if not SpellCooldownSystem.storages[playerId][name] or SpellCooldownSystem.storages[playerId][name] <= os.mtime() then
        SpellCooldownSystem.storages[playerId][name] = os.mtime() + cooldown
        SpellCooldownSystem.cooldowns[name] = cooldown
        return true
    end
    return false
end

local event = CreatureEvent("SpellCooldownSystemReduction")
function event.onKill(player, target)
    local playerId = player:getId()
    if SpellCooldownSystem.storages[playerId] then
        for k, v in pairs(SpellCooldownSystem.storages[playerId]) do
            SpellCooldownSystem.storages[playerId][k] = SpellCooldownSystem.storages[playerId][k] - (SpellCooldownSystem.cooldowns[k] * SpellCooldownSystem.reduction)
        end
    end
    return true
end
event:register()

data/spells/spells.xml
XML:
<!-- TEST -->
    <instant group="attack" spellid="88" name="Energy Strike 2" words="exori vis 2" level="12" mana="20" premium="1" range="3" casterTargetOrDirection="1" blockwalls="1" cooldown="0" groupcooldown="0" needlearn="0" script="test.lua">
        <vocation name="Sorcerer" />
        <vocation name="Druid" />
        <vocation name="Master Sorcerer" />
        <vocation name="Elder Druid" />
    </instant>

data/spells/scripts/test.lua
Lua:
local config = {
    name = "energy strike",
    cooldown = 20 * 1000
}

local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 1.4) + 8
    local max = (level / 5) + (magicLevel * 2.2) + 14
    return -min, -max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    if SpellCooldownSystem.canUseSpell(creature:getId(), config.name, config.cooldown) then
        return combat:execute(creature, variant)
    end

    creature:sendCancelMessage("You are exahusted.")
    return false
end


GIF examples:
* Here you can see that the counter is normally reduced as time passes
View attachment 60268
* Here you can see that the time is normally reduced, but when you kill a monster the time is reduced by 10% for each monster you kill
View attachment 60269

Notes:
  • I don't recommend that you do it this way, but here is the alternative anyway.
  • This little code does not cover all possible cases, such as when a player closes section
  • As you can see, you must also configure the names manually in the file, as well as the cooldown, (this does not cover the cooldown by groups either)
Nice, I will for sure do this way. I'm doing my own spells, so it will be just a few more lines at the script. Thank you very much for your time and knowledge.
Post automatically merged:

Here I will show you an example of how it is done with pure lua, but you must bear in mind that it is not something clean and it is not a complete code, but I will give you an example to see if you dare to complete it or if someone wants to finish it for you

data/scripts/spellcooldownsystem.lua
Lua:
SpellCooldownSystem = {
    storages = {},
    cooldowns = {},
    reduction = 0.10 -- 10%
}

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogin")
function spellCooldownEvent.onLogin(player)
    SpellCooldownSystem.storages[player:getId()] = {}
    player:registerEvent("SpellCooldownSystemReduction")
    return true
end
spellCooldownEvent:register()

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogout")
function spellCooldownEvent.onLogout(player)
    SpellCooldownSystem.storages[player:getId()] = nil
    return true
end
spellCooldownEvent:register()

function SpellCooldownSystem.canUseSpell(playerId, name, cooldown)
    if not SpellCooldownSystem.storages[playerId] then
        SpellCooldownSystem.storages[playerId] = {}
    end

    if not SpellCooldownSystem.storages[playerId][name] or SpellCooldownSystem.storages[playerId][name] <= os.mtime() then
        SpellCooldownSystem.storages[playerId][name] = os.mtime() + cooldown
        SpellCooldownSystem.cooldowns[name] = cooldown
        return true
    end
    return false
end

local event = CreatureEvent("SpellCooldownSystemReduction")
function event.onKill(player, target)
    local playerId = player:getId()
    if SpellCooldownSystem.storages[playerId] then
        for k, v in pairs(SpellCooldownSystem.storages[playerId]) do
            SpellCooldownSystem.storages[playerId][k] = SpellCooldownSystem.storages[playerId][k] - (SpellCooldownSystem.cooldowns[k] * SpellCooldownSystem.reduction)
        end
    end
    return true
end
event:register()

data/spells/spells.xml
XML:
<!-- TEST -->
    <instant group="attack" spellid="88" name="Energy Strike 2" words="exori vis 2" level="12" mana="20" premium="1" range="3" casterTargetOrDirection="1" blockwalls="1" cooldown="0" groupcooldown="0" needlearn="0" script="test.lua">
        <vocation name="Sorcerer" />
        <vocation name="Druid" />
        <vocation name="Master Sorcerer" />
        <vocation name="Elder Druid" />
    </instant>

data/spells/scripts/test.lua
Lua:
local config = {
    name = "energy strike",
    cooldown = 20 * 1000
}

local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 1.4) + 8
    local max = (level / 5) + (magicLevel * 2.2) + 14
    return -min, -max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    if SpellCooldownSystem.canUseSpell(creature:getId(), config.name, config.cooldown) then
        return combat:execute(creature, variant)
    end

    creature:sendCancelMessage("You are exahusted.")
    return false
end


GIF examples:
* Here you can see that the counter is normally reduced as time passes
View attachment 60268
* Here you can see that the time is normally reduced, but when you kill a monster the time is reduced by 10% for each monster you kill
View attachment 60269

Notes:
  • I don't recommend that you do it this way, but here is the alternative anyway.
  • This little code does not cover all possible cases, such as when a player closes section
  • As you can see, you must also configure the names manually in the file, as well as the cooldown, (this does not cover the cooldown by groups either)
What did you use for that count down?
Is there way to appear a message to the player saying how much seconds it reduced?
 
Last edited:
Nice, I will for sure do this way. I'm doing my own spells, so it will be just a few more lines at the script. Thank you very much for your time and knowledge.
Post automatically merged:


What did you use for that count down?
Is there way to appear a message to the player saying how much seconds it reduced?
Update this function
Lua:
local event = CreatureEvent("SpellCooldownSystemReduction")
function event.onKill(player, target)
    local playerId = player:getId()
    if SpellCooldownSystem.storages[playerId] then
        for k, v in pairs(SpellCooldownSystem.storages[playerId]) do
            local reduced = (SpellCooldownSystem.cooldowns[k] * SpellCooldownSystem.reduction)
            SpellCooldownSystem.storages[playerId][k] = SpellCooldownSystem.storages[playerId][k] - reduced
            player:sendCancelMessage(string.format("[SpellCooldownSystem] The spell %s cooldown has reduced on %d seconds.", k, math.ceil(reduced / 1000)))
        end
    end
    return true
end
event:register()

Now you will have a message on the console with the time reduction of all the spells that are on cooldown...
 
How do you send a cooldown icon with networkmessage methods? I've tried sending one, but for some reason it didn't appear in my client.
 
How do you send a cooldown icon with networkmessage methods? I've tried sending one, but for some reason it didn't appear in my client.
Lua:
-- spell cooldown
local msg = NetworkMessage()
msg:addByte(0xA4)
msg:addByte(10) -- utevo lux ID
msg:addU32(2000) -- 2 seconds
msg:sendToPlayer(player)
msg:delete()

-- group cooldown
local msg = NetworkMessage()
msg:addByte(0xA5)
msg:addByte(3) -- support group
msg:addU32(2000) -- 2 seconds
msg:sendToPlayer(player)
msg:delete()
 
How do you send a cooldown icon with networkmessage methods? I've tried sending one, but for some reason it didn't appear in my client.
Either add Player::sendSpellCooldown and Player::sendSpellGroupCooldown to luascripts or move them to Lua (what @Alpha did).

Here I will show you an example of how it is done with pure lua, but you must bear in mind that it is not something clean and it is not a complete code, but I will give you an example to see if you dare to complete it or if someone wants to finish it for you

data/scripts/spellcooldownsystem.lua
Lua:
SpellCooldownSystem = {
    storages = {},
    cooldowns = {},
    reduction = 0.10 -- 10%
}

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogin")
function spellCooldownEvent.onLogin(player)
    SpellCooldownSystem.storages[player:getId()] = {}
    player:registerEvent("SpellCooldownSystemReduction")
    return true
end
spellCooldownEvent:register()

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogout")
function spellCooldownEvent.onLogout(player)
    SpellCooldownSystem.storages[player:getId()] = nil
    return true
end
spellCooldownEvent:register()

function SpellCooldownSystem.canUseSpell(playerId, name, cooldown)
    if not SpellCooldownSystem.storages[playerId] then
        SpellCooldownSystem.storages[playerId] = {}
    end

    if not SpellCooldownSystem.storages[playerId][name] or SpellCooldownSystem.storages[playerId][name] <= os.mtime() then
        SpellCooldownSystem.storages[playerId][name] = os.mtime() + cooldown
        SpellCooldownSystem.cooldowns[name] = cooldown
        return true
    end
    return false
end

local event = CreatureEvent("SpellCooldownSystemReduction")
function event.onKill(player, target)
    local playerId = player:getId()
    if SpellCooldownSystem.storages[playerId] then
        for k, v in pairs(SpellCooldownSystem.storages[playerId]) do
            SpellCooldownSystem.storages[playerId][k] = SpellCooldownSystem.storages[playerId][k] - (SpellCooldownSystem.cooldowns[k] * SpellCooldownSystem.reduction)
        end
    end
    return true
end
event:register()

data/spells/spells.xml
XML:
<!-- TEST -->
    <instant group="attack" spellid="88" name="Energy Strike 2" words="exori vis 2" level="12" mana="20" premium="1" range="3" casterTargetOrDirection="1" blockwalls="1" cooldown="0" groupcooldown="0" needlearn="0" script="test.lua">
        <vocation name="Sorcerer" />
        <vocation name="Druid" />
        <vocation name="Master Sorcerer" />
        <vocation name="Elder Druid" />
    </instant>

data/spells/scripts/test.lua
Lua:
local config = {
    name = "energy strike",
    cooldown = 20 * 1000
}

local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 1.4) + 8
    local max = (level / 5) + (magicLevel * 2.2) + 14
    return -min, -max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    if SpellCooldownSystem.canUseSpell(creature:getId(), config.name, config.cooldown) then
        return combat:execute(creature, variant)
    end

    creature:sendCancelMessage("You are exahusted.")
    return false
end


GIF examples:
* Here you can see that the counter is normally reduced as time passes
View attachment 60268
* Here you can see that the time is normally reduced, but when you kill a monster the time is reduced by 10% for each monster you kill
View attachment 60269

Notes:
  • I don't recommend that you do it this way, but here is the alternative anyway.
  • This little code does not cover all possible cases, such as when a player closes section
  • As you can see, you must also configure the names manually in the file, as well as the cooldown, (this does not cover the cooldown by groups either)
What bothers me the most is that onCastSpell will be executed every time you cast a spell. That means all the Variant calculations (like checking if target is reachable if required etc.). I know it won't impact performance that much but it still does and TFS is built on such little things that adds up to how bad it is right now.
 
Last edited:
Update this function
Lua:
local event = CreatureEvent("SpellCooldownSystemReduction")
function event.onKill(player, target)
    local playerId = player:getId()
    if SpellCooldownSystem.storages[playerId] then
        for k, v in pairs(SpellCooldownSystem.storages[playerId]) do
            local reduced = (SpellCooldownSystem.cooldowns[k] * SpellCooldownSystem.reduction)
            SpellCooldownSystem.storages[playerId][k] = SpellCooldownSystem.storages[playerId][k] - reduced
            player:sendCancelMessage(string.format("[SpellCooldownSystem] The spell %s cooldown has reduced on %d seconds.", k, math.ceil(reduced / 1000)))
        end
    end
    return true
end
event:register()

Now you will have a message on the console with the time reduction of all the spells that are on cooldown...
I still ain't getting the message. Did anyone else test this part?
Post automatically merged:

And to add a weapon restriction, would this be the best way to do it?
Lua:
SpellCooldownSystem = {
    storages = {},
    cooldowns = {},
    reduction = 0.10 -- 10%
}

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogin")
function spellCooldownEvent.onLogin(player)
    SpellCooldownSystem.storages[player:getId()] = {}
    player:registerEvent("SpellCooldownSystemReduction")
    return true
end
spellCooldownEvent:register()

local spellCooldownEvent = CreatureEvent("SpellCooldownSystemLogout")
function spellCooldownEvent.onLogout(player)
    SpellCooldownSystem.storages[player:getId()] = nil
    return true
end
spellCooldownEvent:register()

function SpellCooldownSystem.canUseSpell(playerId, name, cooldown)
    if not SpellCooldownSystem.storages[playerId] then
        SpellCooldownSystem.storages[playerId] = {}
    end

    if not SpellCooldownSystem.storages[playerId][name] or SpellCooldownSystem.storages[playerId][name] <= os.mtime() then
        SpellCooldownSystem.storages[playerId][name] = os.mtime() + cooldown
        SpellCooldownSystem.cooldowns[name] = cooldown
        return true
    end
    return false
end

local event = CreatureEvent("SpellCooldownSystemReduction")
local weapons = {26238, 26240, 26328, 26330, 26329}
function event.onKill(player, target)
    local slotWeapon = CONST_SLOT_LEFT
    local playerId = player:getId()
    if not playerWeapon or not table.contains(weapons, playerWeapon:getId()) then
        creature:sendTextMessage(MESSAGE_STATUS_SMALL, "You need a axe in the main hand to cast this spell.")
        return false
    end
    if SpellCooldownSystem.storages[playerId] then
        for k, v in pairs(SpellCooldownSystem.storages[playerId]) do
            local reduced = (SpellCooldownSystem.cooldowns[k] * SpellCooldownSystem.reduction)
            SpellCooldownSystem.storages[playerId][k] = SpellCooldownSystem.storages[playerId][k] - reduced
            player:sendCancelMessage(string.format("[SpellCooldownSystem] The spell %s cooldown has reduced on %d seconds.", k, math.ceil(reduced / 1000)))
        end
    end
    return true
end
event:register()
 
Last edited:
With so many cancellation messages, surely it is not possible to visualize this message well, but you can change the type of message If you use OTC, you can even send an animated text to make it look much more beautiful
 
Back
Top