• 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 [Canary] [TFS 1.3] EXP Boost

rbQ321

Member
Joined
Jun 22, 2010
Messages
25
Reaction score
6
Hi. I downloaded script for Canary server for EXP Boost, but i have a problem.
When i use scroll (ID: 22772) in console i got this error:
Code:
[2025-11-02 11:42:00.065] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\actions\boost_experience_itemCanary1340.lua:callback]
timerEvent: []
 callbackId:[]
function: []
error [...data\scripts\actions\boost_experience_itemCanary1340.lua:27: attempt to call method 'getXpBoostPercent' (a nil value)
stack traceback:
        [C]: in function 'getXpBoostPercent'
        ...data\scripts\actions\boost_experience_itemCanary1340.lua:27: in function 'applyXpBoost'
        ...data\scripts\actions\boost_experience_itemCanary1340.lua:81: in function <...data\scripts\actions\boost_experience_itemCanary1340.lua:76>]

boost_experience_itemCanary1340.lua:
LUA:
local expscroll = Action()

-- Define the exact XP boost to apply (50%)
local BOOST_XP_VALUE = 50

-- Define storage keys for boost tracking
GameStore = GameStore or {}
GameStore.Storages = GameStore.Storages or {}
GameStore.Storages.expBoostStart = 1000 -- This is where we store the start time of the boost
GameStore.Storages.expBoostCount = 1001 -- Used to check if the boost is already applied

-- Function to apply a 50% XP boost
local function applyXpBoost(player)
    -- Check if a boost is already active
    local currentBoost = player:getStorageValue(GameStore.Storages.expBoostCount) or 0

    -- If a boost is active (i.e. we already have 50% XP boost)
    if currentBoost == 1 then
        local remainingTime = player:getXpBoostTime()
        local minutes = math.floor(remainingTime / 60)
        local seconds = remainingTime % 60
        player:say("You already have an active 50% XP boost. Time left: " .. minutes .. " minutes and " .. seconds .. " seconds.", TALKTYPE_MONSTER_SAY)
        return false -- Exit if a boost is already active
    end

    -- Add exactly 50% XP boost
    local currentXpGain = player:getXpBoostPercent() or 100 -- Get the current XP gain
    player:setXpBoostPercent(currentXpGain + BOOST_XP_VALUE) -- Add 50%

    -- Set the boost duration to 60 minutes (3600 seconds)
    player:setXpBoostTime(3600)

    -- Mark that a 50% XP boost is active
    player:setStorageValue(GameStore.Storages.expBoostCount, 1)

    -- Set the start time for the XP boost
    player:setStorageValue(GameStore.Storages.expBoostStart, os.time())

    return true
end

-- Function to reset XP boost and revert to the player's original XP gain
local function resetXpBoost(player)
    -- Get the player's current XP gain and reduce by 50%
    local currentXpGain = player:getXpBoostPercent() or 100
    player:setXpBoostPercent(currentXpGain - BOOST_XP_VALUE)  -- Reduce by 50% boost

    -- Reset boost time and start time
    player:setXpBoostTime(0)
    player:setStorageValue(GameStore.Storages.expBoostCount, 0) -- Mark that boost is no longer active
    player:setStorageValue(GameStore.Storages.expBoostStart, -1) -- Reset start time

    -- Inform the player
    player:say("Your XP boost has expired. You are back to your previous experience rate.", TALKTYPE_MONSTER_SAY)
end

-- Function to check if XP boost has expired and reset it if necessary
local function checkXpBoostExpiration(player)
    local boostStartTime = player:getStorageValue(GameStore.Storages.expBoostStart)

    -- If no boost has started, skip the check
    if boostStartTime == -1 or boostStartTime == nil then
        return
    end

    -- Calculate how long the boost has been active
    local elapsedTime = os.time() - boostStartTime

    -- If the boost duration has passed (3600 seconds = 60 minutes), reset the boost
    if elapsedTime >= 3600 then
        resetXpBoost(player)
    end
end

-- Main function for using XP scroll
function expscroll.onUse(player, item, fromPosition, itemEx, toPosition)
    -- Check if the boost should be reset first
    checkXpBoostExpiration(player)

    -- Apply the XP boost if no other boost is active
    if applyXpBoost(player) then
        item:remove(1) -- Remove the scroll after use
    end

    return true -- XP boost successfully applied
end

-- Register action for XP scroll
expscroll:id(22772)
expscroll:register()

-- Check and apply boost when the player logs in
local login = CreatureEvent("onLogin")
function login.onLogin(player)
    checkXpBoostExpiration(player) -- Check if the boost has expired at login
    return true
end
login:register()

-- Periodically check if XP boost has expired during the game
function onThink(interval)
    local players = Game.getPlayers() -- Get all online players
    for _, player in ipairs(players) do
        checkXpBoostExpiration(player) -- Check if the XP boost has expired for each player
    end
    return true
end

also boost_experience_item.lua:

LUA:
local expscroll = Action()

function expscroll.onUse(cid, item, fromPosition, itemEx, toPosition)
    local player = Player(cid)
    local remainingBoost = player:getExpBoostStamina()
    local currentExpBoostTime = player:getExpBoostStamina()
    local expBoostCount = player:getStorageValue(GameStore.Storages.expBoostCount)

    if expBoostCount >= 3 then -- Xp boost can only be used 3 times a day
        player:say('You have reached the limit for today, try again after Server Save.', TALKTYPE_MONSTER_SAY)
        return true
    end
    
    if (remainingBoost > 0) then -- If player still has an active xp boost, don't let him use another one
        player:say('You already have an active XP boost.', TALKTYPE_MONSTER_SAY)
        return true
    end
    
    player:setStoreXpBoost(50)
    player:setExpBoostStamina(currentExpBoostTime + 3600)
    Item(item.uid):remove(1)
    player:say('Your hour of 50% bonus XP has started!', TALKTYPE_MONSTER_SAY)
    return true
end

expscroll:id(ITEMIDHERE)
expscroll:register()

Can someone explain it for me or just fix it?
 
I don't know why to edit sources with such simple code. Below is the usual Action + Events(Player)

Code (Action):
LUA:
local config = {
    time = 100,
    storage = 200011
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You still have extra experience time left.")
        return true
    end

    player:setStorageValue(config.storage, os.time() + config.time * 3600)
    player:sendTextMessage(MESSAGE_INFO_DESCR, string.format("You have activated %d hour%s of double experience.", config.time, config.time ~= 1 and "s" or ""))
    item:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)
    return true
end
Code (Player):
LUA:
-- Apply Extra Experience
 local config = {
    rate = 2,
    storage = 200011,
}

    if self:getStorageValue(config.storage) >= os.time() then
        exp = exp * config.rate
    end
 
I don't know why to edit sources with such simple code. Below is the usual Action + Events(Player)

Code (Action):
LUA:
local config = {
    time = 100,
    storage = 200011
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You still have extra experience time left.")
        return true
    end

    player:setStorageValue(config.storage, os.time() + config.time * 3600)
    player:sendTextMessage(MESSAGE_INFO_DESCR, string.format("You have activated %d hour%s of double experience.", config.time, config.time ~= 1 and "s" or ""))
    item:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)
    return true
end
Code (Player):
LUA:
-- Apply Extra Experience
 local config = {
    rate = 2,
    storage = 200011,
}

    if self:getStorageValue(config.storage) >= os.time() then
        exp = exp * config.rate
    end
I use it and it's not work too.
 
you have added the required code to events/player.lua

do you have any errors in the console?
It works flawlessly for me...
 
you have added the required code to events/player.lua

do you have any errors in the console?
It works flawlessly for me...
When I use the scroll (ID: 22772), nothing happens, and there are no errors in the console either. Besides adding these two codes (event/script/player.lua and scripts/actions/boost_exp.lua), should I add anything else anywhere?

If I remember correctly, in older versions of the engine, something was also added to the actions.xml file.
 
Of course, yes, you also need to register the code in actions.xml



-------

I don't have much experience with revscript but you can also try this:
LUA:
local config = {
    time = 100, -- Czas trwania bonusu w godzinach
    storage = 200011, -- Storage ID dla czasu trwania bonusu
    rate = 2 -- Mnożnik doświadczenia
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You still have extra experience time left.")
        return true
    end

    player:setStorageValue(config.storage, os.time() + config.time * 3600)
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have activated %d hour%s of double experience.", config.time, config.time ~= 1 and "s" or ""))
    fromPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)
    return true
end

function onGainExperience(player, source, exp, rawExp)
    if player:getStorageValue(config.storage) >= os.time() then
        return exp * config.rate
    end
    return exp
end
 
Of course, yes, you also need to register the code in actions.xml



-------

I don't have much experience with revscript but you can also try this:
LUA:
local config = {
    time = 100, -- Czas trwania bonusu w godzinach
    storage = 200011, -- Storage ID dla czasu trwania bonusu
    rate = 2 -- Mnożnik doświadczenia
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You still have extra experience time left.")
        return true
    end

    player:setStorageValue(config.storage, os.time() + config.time * 3600)
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have activated %d hour%s of double experience.", config.time, config.time ~= 1 and "s" or ""))
    fromPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)
    return true
end

function onGainExperience(player, source, exp, rawExp)
    if player:getStorageValue(config.storage) >= os.time() then
        return exp * config.rate
    end
    return exp
end

Funny thing, because there is no actions.xml file in the Canary folder.

only .xml files are in data > XML :

1739356835670.webp

In the server console, it also doesn’t show that actions.xml is being loaded.
1739357513302.webp
 
Last edited:
This title confused me... Did you take the script from Canary and add it to your TFS 1.3, or are you using Canary?

So, I made the script here... Just a note about EventCallback: if you're using Canary, I'm not sure whether it's EventCallback, Event(), or EventCallback()—it depends on the mechanism. In my case, it's Event().

If you want to check, go to data/scripts/events or EventCallback/, open any file, and see if it uses EventCallback. If so, then the script is correct. You can try it out... It hasn't been tested.


You can add this to data/scripts/filename.lua. This is a RevScript.
LUA:
local config = {
    time = 100, -- Time in hours for the bonus experience
    storage = 200011, -- Storage ID for the bonus experience time
    item_scroll_exp = 22772, -- Item ID of the experience scroll
    expBonus = 1.5 -- Experience multiplier (50% bonus)
}

local expscroll = Action()
function expscroll.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local _player = Player(item:getTopParent())
    if not _player or _player:getGuid() ~= player:getGuid() then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "The experience scroll must be in your inventory to be used.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You still have extra experience time left.")
        return true
    end

    player:setStorageValue(config.storage, os.time() + config.time * 3600)
    player:sendTextMessage(MESSAGE_INFO_DESCR, string.format("You have activated %d hour%s of 50%% bonus experience.", config.time, config.time ~= 1 and "s" or ""))

    item:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)

    item:remove(1)
    return true
end
expscroll:id(config.item_scroll_exp)
expscroll:register()

local ec = EventCallback
ec.onGainExperience = function(player, source, exp, rawExp)
    if not source:isMonster() then
        return exp
    end

    if player:getStorageValue(config.storage) >= os.time() then
        exp = exp * config.expBonus
    end

    return exp
end
ec:register()

local function checkXpBoostExpiration(playerGuid)
    local player = Player(playerGuid)
    if player and player:getStorageValue(config.storage) < os.time() and player:getStorageValue(config.storage) > 0 then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Your 50% bonus experience has expired.")
        player:setStorageValue(config.storage, 0)
    end
end

local login = CreatureEvent("onLogin")
function login.onLogin(player)
    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Welcome back! Your 50% bonus experience is still active.")
        addEvent(checkXpBoostExpiration, 1000, player:getGuid())
    end
    return true
end
login:register()
 
This title confused me... Did you take the script from Canary and add it to your TFS 1.3, or are you using Canary?

So, I made the script here... Just a note about EventCallback: if you're using Canary, I'm not sure whether it's EventCallback, Event(), or EventCallback()—it depends on the mechanism. In my case, it's Event().

If you want to check, go to data/scripts/events or EventCallback/, open any file, and see if it uses EventCallback. If so, then the script is correct. You can try it out... It hasn't been tested.


You can add this to data/scripts/filename.lua. This is a RevScript.
LUA:
local config = {
    time = 100, -- Time in hours for the bonus experience
    storage = 200011, -- Storage ID for the bonus experience time
    item_scroll_exp = 22772, -- Item ID of the experience scroll
    expBonus = 1.5 -- Experience multiplier (50% bonus)
}

local expscroll = Action()
function expscroll.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local _player = Player(item:getTopParent())
    if not _player or _player:getGuid() ~= player:getGuid() then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "The experience scroll must be in your inventory to be used.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You still have extra experience time left.")
        return true
    end

    player:setStorageValue(config.storage, os.time() + config.time * 3600)
    player:sendTextMessage(MESSAGE_INFO_DESCR, string.format("You have activated %d hour%s of 50%% bonus experience.", config.time, config.time ~= 1 and "s" or ""))

    item:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)

    item:remove(1)
    return true
end
expscroll:id(config.item_scroll_exp)
expscroll:register()

local ec = EventCallback
ec.onGainExperience = function(player, source, exp, rawExp)
    if not source:isMonster() then
        return exp
    end

    if player:getStorageValue(config.storage) >= os.time() then
        exp = exp * config.expBonus
    end

    return exp
end
ec:register()

local function checkXpBoostExpiration(playerGuid)
    local player = Player(playerGuid)
    if player and player:getStorageValue(config.storage) < os.time() and player:getStorageValue(config.storage) > 0 then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Your 50% bonus experience has expired.")
        player:setStorageValue(config.storage, 0)
    end
end

local login = CreatureEvent("onLogin")
function login.onLogin(player)
    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Welcome back! Your 50% bonus experience is still active.")
        addEvent(checkXpBoostExpiration, 1000, player:getGuid())
    end
    return true
end
login:register()
Server is Canary - version 1.3.0
1739358905151.webpSome errors in server console with this script.

Code:
[2025-12-02 12:11:31.931] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\actions\boosted_exp.lua]
timerEvent: []
 callbackId:[]
function: []
error [...esktop\TFSnajnowszy\data\scripts\actions\boosted_exp.lua:33: attempt to call global 'Event' (a nil value)
stack traceback:
        [C]: in function 'Event'
        ...esktop\TFSnajnowszy\data\scripts\actions\boosted_exp.lua:33: in main chunk]
[2025-12-02 12:11:31.931] [error] boosted_exp.lua
[2025-12-02 12:11:31.932] [error]
[2025-12-02 12:11:31.998] [warning] [Actions::registerLuaItemEvent] - Duplicate registered item with id: 22772 in range from id: 22771, to id: 22772
[2025-12-02 12:11:32.063] [warning] [Actions::registerLuaItemEvent] - Duplicate registered item with id: 22772 in range from id: 22772, to id: 22772
[2025-12-02 12:11:32.064] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua]
timerEvent: []
 callbackId:[]
function: []
error [...\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua:44: attempt to index local 'ec' (a nil value)
stack traceback:
        [C]: in function '__newindex'
        ...\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua:44: in main chunk]
[2025-12-02 12:11:32.064] [error] boosted_exp.lua
[2025-12-02 12:11:32.065] [error]

I can use scroll in game but i dont get exp boost.
 
Server is Canary - version 1.3.0
View attachment 90158Some errors in server console with this script.

Code:
[2025-12-02 12:11:31.931] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\actions\boosted_exp.lua]
timerEvent: []
 callbackId:[]
function: []
error [...esktop\TFSnajnowszy\data\scripts\actions\boosted_exp.lua:33: attempt to call global 'Event' (a nil value)
stack traceback:
        [C]: in function 'Event'
        ...esktop\TFSnajnowszy\data\scripts\actions\boosted_exp.lua:33: in main chunk]
[2025-12-02 12:11:31.931] [error] boosted_exp.lua
[2025-12-02 12:11:31.932] [error]
[2025-12-02 12:11:31.998] [warning] [Actions::registerLuaItemEvent] - Duplicate registered item with id: 22772 in range from id: 22771, to id: 22772
[2025-12-02 12:11:32.063] [warning] [Actions::registerLuaItemEvent] - Duplicate registered item with id: 22772 in range from id: 22772, to id: 22772
[2025-12-02 12:11:32.064] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua]
timerEvent: []
 callbackId:[]
function: []
error [...\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua:44: attempt to index local 'ec' (a nil value)
stack traceback:
        [C]: in function '__newindex'
        ...\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua:44: in main chunk]
[2025-12-02 12:11:32.064] [error] boosted_exp.lua
[2025-12-02 12:11:32.065] [error]

I can use scroll in game but i dont get exp boost.
This error is related to local ec = EventCallback. I'm not sure which one is correct... As I mentioned, it could be EventCallback, EventCallback(), Event(), or maybe even EventCallback("name scroll example").

Here’s an example from the official Canary version 3.1.2:

So, show me your EventCallback, send it here, and then I'll correct it properly.


Or an alternative solution: remove the entire part.
LUA:
local ec = EventCallback
ec.onGainExperience = function(player, source, exp, rawExp)
    if not source:isMonster() then
        return exp
    end

    if player:getStorageValue(config.storage) >= os.time() then
        exp = exp * config.expBonus
    end

    return exp
end
ec:register()



Then, go to data/events/scripts/player.lua, look for the function function Player:onGainExperience(target, exp, rawExp), add it anywhere inside, and test it.
LUA:
    -- Scroll XP 50%
    local storage = 200011
    if self:getStorageValue(storage) >= os.time() then
        exp = exp * 1.5 -- 50% bonus
    end
 
Last edited:
This error is related to local ec = EventCallback. I'm not sure which one is correct... As I mentioned, it could be EventCallback, EventCallback(), Event(), or maybe even EventCallback("name scroll example").

Here’s an example from the official Canary version 3.1.2:

So, show me your EventCallback, send it here, and then I'll correct it properly.


Or an alternative solution: remove the entire local ec = EventCallback part.
LUA:
local ec = EventCallback
ec.onGainExperience = function(player, source, exp, rawExp)
    if not source:isMonster() then
        return exp
    end

    if player:getStorageValue(config.storage) >= os.time() then
        exp = exp * config.expBonus
    end

    return exp
end
ec:register()



Then, go to data/events/scripts/player.lua, look for the function function Player:onGainExperience(target, exp, rawExp), add it anywhere inside, and test it.
LUA:
    -- Scroll XP 50%
    local storage = 200011
    if self:getStorageValue(storage) >= os.time() then
        exp = exp * 1.5 -- 50% bonus
    end
I tried all the solutions you suggested, but errors still appear in the console.

Code:
[2025-12-02 14:14:32.047] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua]
timerEvent: []
 callbackId:[]
function: []
error [...\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua:44: attempt to index local 'ec' (a nil value)
stack traceback:
        [C]: in function '__newindex'
        ...\robpu\Desktop\TFSnajnowszy\data\scripts\boosted_exp.lua:44: in main chunk]
 
I did what you wrote. There are no errors in the console, but the script still doesn't work.

It only shows messages that the scroll has been used or that its effect is still active. However, the exp boost does not increase.

In this location, I placed the script in player.lua:



LUA:
function Player:onGainExperience(source, exp, rawExp)
    if not source or source:isPlayer() then
        return exp
    end

    -- Scroll XP 50%
    local storage = 200011
    if self:getStorageValue(storage) >= os.time() then
        exp = exp * 1.5 -- 50% bonus
    end

    -- Soul regeneration
    local vocation = self:getVocation()
    if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
        soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks())
        self:addCondition(soulCondition)
    end

and here is boosted_exp.lua

LUA:
local config = {
    time = 1, -- Time in hours for the bonus experience
    storage = 200011, -- Storage ID for the bonus experience time
    item_scroll_exp = 22772, -- Item ID of the experience scroll
    expBonus = 1.5 -- Experience multiplier (50% bonus)
}

local expscroll = Action()
function expscroll.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local _player = Player(item:getTopParent())
    if not _player or _player:getGuid() ~= player:getGuid() then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "The experience scroll must be in your inventory to be used.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You still have extra experience time left.")
        return true
    end

    player:setStorageValue(config.storage, os.time() + config.time * 3600)
    player:sendTextMessage(MESSAGE_INFO_DESCR, string.format("You have activated %d hour%s of 50%% bonus experience.", config.time, config.time ~= 1 and "s" or ""))

    item:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)

    item:remove(1)
    return true
end
expscroll:id(config.item_scroll_exp)
expscroll:register()



local function checkXpBoostExpiration(playerGuid)
    local player = Player(playerGuid)
    if player and player:getStorageValue(config.storage) < os.time() and player:getStorageValue(config.storage) > 0 then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Your 50% bonus experience has expired.")
        player:setStorageValue(config.storage, 0)
    end
end

local login = CreatureEvent("onLogin")
function login.onLogin(player)
    if player:getStorageValue(config.storage) >= os.time() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Welcome back! Your 50% bonus experience is still active.")
        addEvent(checkXpBoostExpiration, 1000, player:getGuid())
    end
    return true
end
login:register()
 
Last edited:
LUA:
local xpBoostItem = Action()

function xpBoostItem.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local boostTime = 120 * 60 -- 120 minut (czas w sekundach)
    local boostValue = 50 -- 200% więcej expa

    -- Sprawdzamy, czy gracz już ma aktywnego boosta
    if player:getExpBoostStamina() > 0 then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You already have an active XP boost.")
        return true
    end

    -- Aktywujemy XP Boost
    player:setStoreXpBoost(boostValue)
    player:setExpBoostStamina(boostTime)

    player:say("You will receive 50% more experience for 2 hours!", TALKTYPE_MONSTER_SAY)
    player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)

    -- Usuwamy przedmiot z ekwipunku gracza
    item:remove(1)

    return true
end

xpBoostItem:id(11510) -- Zamień "11510" na ID przedmiotu
xpBoostItem:register()

It works, but it cannot be used with the XP Boost available in the in-game store :( .

Anyway, thanks for help.
 
Do you shop using the same boostValue as is doing your script?
It's hard for me to answer that question. The script is a modification of something found on the internet by artificial intelligence (AI). I don't even know where to look for information about what the server currently uses for XP Boost in the store.

If you could help me fix this script so that it works independently and allows the use of both XP Boosts (the one from the store and the one from this script), I would be very grateful.
 
Back
Top