• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Tier upgrade [different exhaust]

  • Thread starter Thread starter Tibia Demon
  • Start date Start date
T

Tibia Demon

Guest
I use Infernum's tier upgrade
and when I change timeBetweenExActions in config.lua it still has small exhaust.
Can I add different exhaust to it? Because playing with timeBetweenExActions will affect other scripts aswell.
and how can I change this to remove more than 1 of the upgrading item.
LUA:
item:remove(1)
 
Is it same exhaust on all actions or I am mistaken?
C++:
bool Actions::useItemEx(Player* player, const Position& fromPos, const Position& toPos,
                        uint8_t toStackPos, Item* item, bool isHotkey, Creature* creature/* = nullptr*/)
{
    player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::EX_ACTIONS_DELAY_INTERVAL));
I need to make scripts with different exhaust not only this one, 1000ms can be too much on few scripts and can be low on others.
 
Any idea? I am trying to remove timeBetweenExActions exhaust and add separated exhaust to this script and some other ones.
Is it possible or now exhaust is globally applied to all action scripts through C++?
In the past it used to be added to each script through Lua lines like this one.
LUA:
local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setParameter(CONDITION_PARAM_TICKS, getConfigInfo('timeBetweenActions'))
    if not (player:addCondition(condition) or player:addCondition(exhaust)) then
        return false
    end
So you can change every script to suit your needs but what about now?
 
Any idea? I am trying to remove timeBetweenExActions exhaust and add separated exhaust to this script and some other ones.
Is it possible or now exhaust is globally applied to all action scripts through C++?
In the past it used to be added to each script through Lua lines like this one.
LUA:
local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setParameter(CONDITION_PARAM_TICKS, getConfigInfo('timeBetweenActions'))
    if not (player:addCondition(condition) or player:addCondition(exhaust)) then
        return false
    end
So you can change every script to suit your needs but what about now?
If you change this line:
Code:
exhaust:setParameter(CONDITION_PARAM_TICKS, getConfigInfo('timeBetweenActions'))
to this:
Code:
exhaust:setParameter(CONDITION_PARAM_TICKS, 500)
It won't take info from config, but instead set exhaust for 0,5 sec (500ms).
How it works:
Let's say you have 2 scripts, script 1 and script 2.
If script 1 sets exhaust for 500ms. You won't be able to use neither script 1 nor script 2 for 500ms.
It is the same the other way (even with different number like 1000 which is 1 sec for example).

Now if you want to set a different cooldowns for each script (so that you can use script 2 even if you can't use script 1).
Make them add different conditions. (Which in your example is CONDITION_EXHAUST_HEAL).
You can either use some existing ones or create new ones in source.
 
If you change this line:
Code:
exhaust:setParameter(CONDITION_PARAM_TICKS, getConfigInfo('timeBetweenActions'))
to this:
Code:
exhaust:setParameter(CONDITION_PARAM_TICKS, 500)
It won't take info from config, but instead set exhaust for 0,5 sec (500ms).
How it works:
Let's say you have 2 scripts, script 1 and script 2.
If script 1 sets exhaust for 500ms. You won't be able to use neither script 1 nor script 2 for 500ms.
It is the same the other way (even with different number like 1000 which is 1 sec for example).

Now if you want to set a different cooldowns for each script (so that you can use script 2 even if you can't use script 1).
Make them add different conditions. (Which in your example is CONDITION_EXHAUST_HEAL).
You can either use some existing ones or create new ones in source.
I know that it used to work like this but now on the tier upgrading script
LUA:
-- Tier Upgrader by Stigma: https://otland.net/threads/tfs-0-4-1-2-tier-upgrading-system.245047/
-- Converted to TFS 1.3 Revscriptsys by Stigma

local action = Action()

local config = {
    messages = {
        success = {
            text  = 'SUCCESS',
            talkType = TALKTYPE_MONSTER_SAY,
            effect   = CONST_ME_FIREWORK_RED
        },

        fail = {
            text  = 'FAILED',
            talkType = TALKTYPE_MONSTER_SAY,
            effect   = CONST_ME_POFF
        },
    },

    gear = {
        -- [key id] = {tier = item tier, upgraderType = 'key, soil, crystal, etc (whatever you want it to say, there's no limit)', chance = upgrade chance}
        [9112] = {tier = 1, upgraderType = 'key', chance = 2,
            items = {
                -- [from id] = [to id]
                [2505] = 2492,
                [2160] = 2148
            }
        },
        [9111] = {tier = 2, upgraderType = 'key', chance = 80,
            items = {
                [2148] = 2160
            }
        }
    }
}

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    -- Using player's position if the target item is located in a container, otherwise use the item's position located on the map
    local pos = target:getPosition().x == 65535 and player:getPosition() or target:getPosition()
    -- Make sure the player is not attempting to target a creature
    if not target:isItem() then
        player:sendCancelMessage('You must select an item.')
        pos:sendMagicEffect(CONST_ME_POFF)
        return true
    end
    -- Attempt to get the config based on which key id the player is using
    local keyConfig = config.gear[item:getId()]
    -- Adding article to full item name if possible, ex: "a sword"
    local name  = (target:getArticle() ~= '') and string.format('%s %s', target:getArticle(), target:getName()) or target:getName()
    if keyConfig then
        -- Directly attempt to access the item id to upgrade to by indexing the item list with the target item's id
        local upgradeId = keyConfig.items[target:getId()]
        -- Prevent attempting to upgrade an item that isn't in config
        if not upgradeId then
            player:sendCancelMessage(string.format('You are unable to upgrade %s with a tier %d %s.', (name == '') and 'this' or name, keyConfig.tier, keyConfig.upgraderType))
            pos:sendMagicEffect(CONST_ME_POFF)
            return true
        end
        -- Prevent attempting to upgrade a stackable item that has more than 1 in it's stack
        if target:getCount() > 1 then
            player:sendCancelMessage('You may only upgrade this item one at a time.')
            pos:sendMagicEffect(CONST_ME_POFF)
            return true
        end
        -- Use the "success" table in config if the random value is less than or equal to the chance, otherwise use the "fail" table
        local confKey = (math.random(100) <= keyConfig.chance and 'success' or 'fail')
        local resultConfig = config.messages[confKey]
        pos:sendMagicEffect(resultConfig.effect)
        player:say(resultConfig.text, resultConfig.talkType)
        if confKey == 'success' then
            target:transform(upgradeId)
        end
        -- Make sure to remove only 1 item in the case the upgrader is a stackable item
        item:remove(1)
    end
    return true
end

-- Automatically register the key ids in config
for keyId, _ in pairs(config.gear) do
    action:id(keyId)
end
action:register() -- Enable the action for use
It calls timeBetweenActions from config although it isn't added anywhere in the script.
It has to be added somewhere else I believe its the C++ lines I posted before.
So what if I needed to add different exhaust to this one?
 
I know that it used to work like this but now on the tier upgrading script
It calls timeBetweenActions from config although it isn't added anywhere in the script.
It has to be added somewhere else I believe its the C++ lines I posted before.
So what if I needed to add different exhaust to this one?
I mean, you can set global exhaust to some low number (500ms for example) and add some longer ones to the scripts you want with the condition.
 
No it doesn't work I have changed the script now it looks like this
LUA:
-- Tier Upgrader by Stigma: https://otland.net/threads/tfs-0-4-1-2-tier-upgrading-system.245047/
-- Converted to TFS 1.3 Revscriptsys by Stigma

local action = Action()

local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setParameter(CONDITION_PARAM_TICKS, 10000)

local config = {
    messages = {
        success = {
            text  = 'SUCCESS',
            talkType = TALKTYPE_MONSTER_SAY,
            effect   = CONST_ME_FIREWORK_RED
        },

        fail = {
            text  = 'FAILED',
            talkType = TALKTYPE_MONSTER_SAY,
            effect   = CONST_ME_POFF
        },
    },

    gear = {
        -- [key id] = {tier = item tier, upgraderType = 'key, soil, crystal, etc (whatever you want it to say, there's no limit)', chance = upgrade chance}
        [9112] = {tier = 1, upgraderType = 'key', chance = 2,
            items = {
                -- [from id] = [to id]
                [2505] = 2492,
                [2160] = 2148
            }
        },
        [9111] = {tier = 2, upgraderType = 'key', chance = 80,
            items = {
                [2148] = 2160
            }
        }
    }
}

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    -- Using player's position if the target item is located in a container, otherwise use the item's position located on the map
    local pos = target:getPosition().x == 65535 and player:getPosition() or target:getPosition()
    if not (player:addCondition(condition) or player:addCondition(exhaust)) then
        return false
    end
    -- Make sure the player is not attempting to target a creature
    if not target:isItem() then
        player:sendCancelMessage('You must select an item.')
        pos:sendMagicEffect(CONST_ME_POFF)
        return true
    end
    -- Attempt to get the config based on which key id the player is using
    local keyConfig = config.gear[item:getId()]
    -- Adding article to full item name if possible, ex: "a sword"
    local name  = (target:getArticle() ~= '') and string.format('%s %s', target:getArticle(), target:getName()) or target:getName()
    if keyConfig then
        -- Directly attempt to access the item id to upgrade to by indexing the item list with the target item's id
        local upgradeId = keyConfig.items[target:getId()]
        -- Prevent attempting to upgrade an item that isn't in config
        if not upgradeId then
            player:sendCancelMessage(string.format('You are unable to upgrade %s with a tier %d %s.', (name == '') and 'this' or name, keyConfig.tier, keyConfig.upgraderType))
            pos:sendMagicEffect(CONST_ME_POFF)
            return true
        end
        -- Prevent attempting to upgrade a stackable item that has more than 1 in it's stack
        if target:getCount() > 1 then
            player:sendCancelMessage('You may only upgrade this item one at a time.')
            pos:sendMagicEffect(CONST_ME_POFF)
            return true
        end
        -- Use the "success" table in config if the random value is less than or equal to the chance, otherwise use the "fail" table
        local confKey = (math.random(100) <= keyConfig.chance and 'success' or 'fail')
        local resultConfig = config.messages[confKey]
        pos:sendMagicEffect(resultConfig.effect)
        player:say(resultConfig.text, resultConfig.talkType)
        if confKey == 'success' then
            target:transform(upgradeId)
        end
        -- Make sure to remove only 1 item in the case the upgrader is a stackable item
        item:remove(1)
    end
    return true
end

-- Automatically register the key ids in config
for keyId, _ in pairs(config.gear) do
    action:id(keyId)
end
action:register() -- Enable the action for use
It should have 10 seconds exhaust after each use right? It doesn't have 10 seconds exhaust.
It has 500 ms exhaust as I have in config.lua
timeBetweenExActions = 500
so the lines I added are useless because it still calling the config value instead of calling the 10 seconds value.
LUA:
local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setParameter(CONDITION_PARAM_TICKS, 10000)

if not (player:addCondition(condition) or player:addCondition(exhaust)) then
        return false
   end
 
Add this part inside a function too.
Code:
local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setParameter(CONDITION_PARAM_TICKS, 10000)
Also try doing it like this:
Code:
local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setTicks(10000)
if player:getCondition(CONDITION_EXHAUST_HEAL) then
    player:sendCancelMessage("You are exhausted.")
    return false
else
    player:addCondition(exhaust)
end
 
Still only reads the config value
LUA:
-- Tier Upgrader by Stigma: https://otland.net/threads/tfs-0-4-1-2-tier-upgrading-system.245047/
-- Converted to TFS 1.3 Revscriptsys by Stigma

local action = Action()

local config = {
    messages = {
        success = {
            text  = 'SUCCESS',
            talkType = TALKTYPE_MONSTER_SAY,
            effect   = CONST_ME_FIREWORK_RED
        },

        fail = {
            text  = 'FAILED',
            talkType = TALKTYPE_MONSTER_SAY,
            effect   = CONST_ME_POFF
        },
    },

    gear = {
        -- [key id] = {tier = item tier, upgraderType = 'key, soil, crystal, etc (whatever you want it to say, there's no limit)', chance = upgrade chance}
        [9112] = {tier = 1, upgraderType = 'key', chance = 2,
            items = {
                -- [from id] = [to id]
                [2505] = 2492,
                [2160] = 2148
            }
        },
        [9111] = {tier = 2, upgraderType = 'key', chance = 80,
            items = {
                [2148] = 2160
            }
        }
    }
}

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    -- Using player's position if the target item is located in a container, otherwise use the item's position located on the map
    local pos = target:getPosition().x == 65535 and player:getPosition() or target:getPosition()
    local exhaust = Condition(CONDITION_EXHAUST_HEAL)
    exhaust:setParameter(CONDITION_PARAM_TICKS, 10000)
    if not (player:addCondition(condition) or player:addCondition(exhaust)) then
        return false
    end
    -- Make sure the player is not attempting to target a creature
    if not target:isItem() then
        player:sendCancelMessage('You must select an item.')
        pos:sendMagicEffect(CONST_ME_POFF)
        return true
    end
    -- Attempt to get the config based on which key id the player is using
    local keyConfig = config.gear[item:getId()]
    -- Adding article to full item name if possible, ex: "a sword"
    local name  = (target:getArticle() ~= '') and string.format('%s %s', target:getArticle(), target:getName()) or target:getName()
    if keyConfig then
        -- Directly attempt to access the item id to upgrade to by indexing the item list with the target item's id
        local upgradeId = keyConfig.items[target:getId()]
        -- Prevent attempting to upgrade an item that isn't in config
        if not upgradeId then
            player:sendCancelMessage(string.format('You are unable to upgrade %s with a tier %d %s.', (name == '') and 'this' or name, keyConfig.tier, keyConfig.upgraderType))
            pos:sendMagicEffect(CONST_ME_POFF)
            return true
        end
        -- Prevent attempting to upgrade a stackable item that has more than 1 in it's stack
        if target:getCount() > 1 then
            player:sendCancelMessage('You may only upgrade this item one at a time.')
            pos:sendMagicEffect(CONST_ME_POFF)
            return true
        end
        -- Use the "success" table in config if the random value is less than or equal to the chance, otherwise use the "fail" table
        local confKey = (math.random(100) <= keyConfig.chance and 'success' or 'fail')
        local resultConfig = config.messages[confKey]
        pos:sendMagicEffect(resultConfig.effect)
        player:say(resultConfig.text, resultConfig.talkType)
        if confKey == 'success' then
            target:transform(upgradeId)
        end
        -- Make sure to remove only 1 item in the case the upgrader is a stackable item
        item:remove(1)
    end
    return true
end

-- Automatically register the key ids in config
for keyId, _ in pairs(config.gear) do
    action:id(keyId)
end
action:register() -- Enable the action for use
Post automatically merged:

This one worked now I can set higher exhaust than the one in config. @dami1310
LUA:
local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setTicks(10000)
if player:getCondition(CONDITION_EXHAUST_HEAL) then
    player:sendCancelMessage("You are exhausted.")
    return false
else
    player:addCondition(exhaust)
end
but what If I have 500 in config and I want to set lower to a script? Like 1ms or 100ms without affecting other scripts?
 
Last edited by a moderator:
Changed all of them but still can't go lower than config's value and lowering the config value will affect many other items like shovel-rope-machete :(
 
Does it need to be lower tho? 500ms is quite a low number honestly.
I have many tiers and sets so on higher ones players will need up to 10k upgraders to success and can even be more so I try to make it like 1 ms for tier upgraders only so they don't have to stay a whole day per 1 item.
Having 1 exhaust to all action scripts isn't a good move tho, Older versions like 0.4 had exhaust per script which is much more better because no one knows what kind of scripts custom servers might have.
So I think there should be another method to add lower values.
 
Last edited by a moderator:
How about editing a script so they can use 1k at once for example? Spamming hotkey is a bad idea for that.
I will think of alternatives if I got no way to lower the value but 1k at once wouldn't be so good because it can success at first-100th-500th but by using 1000 at once then success rate will be calculated each 1000 instead of each 1.
I appreciate your help, I will look around maybe I can figure something out or someone else will reply here with different method to add exhaust.
 
Having 1 exhaust to all action scripts isn't a good move tho, Older versions like 0.4 had exhaust per script which is much more better because no one knows what kind of scripts custom servers might have.
So I think there should be another method to add lower values.
Then set it in config for 1ms and change all the scripts.
Anyways, gl.
 
I am quite nooblet so can't offer much script advice other than maybe try using addevent with a custom function for the upgrades. I know that addevent can work extremely fast, fast enough to crash the server. You could also convert it to a spell since you can get 100ms exhaust without any modifications there if you don't mind switching the onUse action for a spell.

Your upgrade system is limited in speed to the users input which is probably never going to hit much lower than 50ms so a <50ms exhaust is pointless.

I think you should be trying to make the system better, not trying to modify the server to accommodate a bad system, the easiest thing to do would be creating another more valuable upgrade item and allowing players to convert them easily and in bulk with a loss that emulates the current loss due to chance.
 
I am quite nooblet so can't offer much script advice other than maybe try using addevent with a custom function for the upgrades. I know that addevent can work extremely fast, fast enough to crash the server. You could also convert it to a spell since you can get 100ms exhaust without any modifications there if you don't mind switching the onUse action for a spell.

Your upgrade system is limited in speed to the users input which is probably never going to hit much lower than 50ms so a <50ms exhaust is pointless.

I think you should be trying to make the system better, not trying to modify the server to accommodate a bad system, the easiest thing to do would be creating another more valuable upgrade item and allowing players to convert them easily and in bulk with a loss that emulates the current loss due to chance.
Thank you for the ideas.
I couldn't find any way to decrease the exhaust separately [lower than config's value] yet so I think I will start now thinking of alternatives.
 
Back
Top