• 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 Disappearing items RewardLevel

n3crozzy

Member
Joined
Apr 23, 2021
Messages
48
Reaction score
14
Hey everyone!

I have a problem with the script. The script is this:
If a player reaches level 20, 35, 50, 70, 100, he or she receives rewards only once.

I have a problem that I presented in the video.
Files : Nekiro TFS 1.5 Downgrade 8.6


The script looks like this:
data/creaturescripts/scripts/levelUpReward.lua
LUA:
local rewards = {
    [20] = {
        backpack = 1991,  -- Backpack ID
        items = {
            {2152, 20},  -- Platinum Coin (20)
            {7618, 20},  -- Mana Potion (20)
            {7620, 20},  -- Life Potion (20)
            {2168, 1}    -- Ring of mana regeneration (1)
        },
        storage = 99112  -- Unique storage identifier for level 20
    },
    [35] = {
        backpack = 1992,  -- Backpack ID
        items = {
            {2152, 35},  -- Platinum Coin (35)
            {7618, 35},  -- Mana Potion (35)
            {7620, 35},  -- Life Potion (35)
            {5908, 1}    -- Skinning (50)
        },
        storage = 99113  -- Unique storage identifier for level 35
    },
    [50] = {
        backpack = 1993,  -- Backpack ID
        items = {
            {2152, 50},  -- Platinum Coin (50)
            {2216, 10},  -- Healing Ring
            {2165, 1},   -- Stealth Ring
            {2197, 1}    -- Stealth Amulet
        },
        storage = 99114  -- Unique storage identifier for level 50
    },
    [70] = {
        backpack = 1994,  -- Backpack ID
        items = {
            {2206, 1},   -- Timer Ring (5)
            {2152, 70},  -- Platinum Coin (70)
            {10306, 1}   -- 50% Stamina
        },
        storage = 99115  -- Unique storage identifier for level 70
    },
    [100] = {
        backpack = 1995,  -- Backpack ID
        items = {
            {2160, 1},   -- Crystal Coin (10)
            {5958, 1},   -- Experience Scroll 2h (10)
            {9693, 1}    -- Addon Doll (1)
        },
        storage = 99116  -- Unique storage identifier for level 100
    }
}

-- Function to grant rewards to the depot
local function giveRewardsToDepot(player, level)
    local rewardData = rewards[level]

    -- Check if rewards have already been granted
    if player:getStorageValue(rewardData.storage) == 1 then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You have already received rewards for level " .. level .. ".")
        return false
    end

    local items = rewardData.items
    local backpackId = rewardData.backpack
    local town = player:getTown()  -- Get the player's town

    if not town then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "Cannot access the player's town.")
        return false
    end

    local depotChest = player:getDepotChest(town:getId(), true) -- Get the depot for the town

    if not depotChest then
        return false  -- In case of no access to depot
    end

    -- Add backpack to the depot
    local backpack = depotChest:addItem(backpackId, 1)
    if not backpack then
        return false  -- In case of failure to add backpack
    end

    -- Add items to the backpack
    for _, reward in ipairs(items) do
        local itemId, count = reward[1], reward[2]
        backpack:addItem(itemId, count) -- Add items to the backpack
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You receive: " .. ItemType(itemId):getName() .. " x" .. count .. " in your depot backpack.")
    end

    -- Set storage value to mark rewards granted
    player:setStorageValue(rewardData.storage, 1)

    return true
end

-- Function called on level up
function onAdvance(player, skill, oldLevel, newLevel)
    if skill == SKILL_LEVEL then
        for level, _ in pairs(rewards) do
            if newLevel >= level and oldLevel < level then
                local success = giveRewardsToDepot(player, level)
                if success then
                    player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have reached level " .. level .. " and received your rewards!")
                end
            end
        end
    end
    return true
end

data/creaturescripts/creaturescripts.xml
XML:
<event type="advance" name="LevelUpReward" script="levelUpReward.lua"/>

data/creaturescripts/scripts/login.lua
LUA:
player:registerEvent("LevelUpReward")

He receives rewards at every level, but the problem arises when the character dies or loses a level. Storage is slow.
The first thoughts were to put items directly into the backpack, but the problem was that if a player did not have CAP, he did not receive rewards. Therefore, consider making a deposit.
Please help :(
 
Last edited:
All you have to do is log out and there are no more items xD I added a save at the end but it gives an error, I added it to the player's link and it worked. saves the status but after logging out it doesn't anymore xd

I'm going to read the book you sent me.
 
So yes, in the pinned topic from @Xikini.
In my file. Does not occur

in item.h below
bool isRune() const { return items[id].isRune(); }

I don't have this function in Item.h file
 
LUA:
local rewards = {
    [9] = {
        backpack = 1991,  -- Backpack ID for level 9
        items = {
            {2152, 20},  -- Platinum Coin (20)
            {7618, 20},  -- Mana Potion (20)
            {7620, 20},  -- Life Potion (20)
            {2168, 1}    -- Ring of mana regeneration (1)
        },

    },
    [10] = {
        backpack = 1992,  -- Backpack ID for level 10
        items = {
            {2152, 35},  -- Platinum Coin (35)
            {7618, 35},  -- Mana Potion (35)
            {7620, 35},  -- Life Potion (35)
            {5908, 1}    -- Skinning (50)
        },

    },
    [11] = {
        backpack = 1993,  -- Backpack ID for level 11
        items = {
            {2152, 50},  -- Platinum Coin (50)
            {2216, 10},  -- Healing Ring
            {2165, 1},   -- Stealth Ring
            {2197, 1}    -- Stealth Amulet
        },

    },
    [12] = {
        backpack = 1994,  -- Backpack ID for level 12
        items = {
            {2206, 1},   -- Timer Ring (5)
            {2152, 70},  -- Platinum Coin (70)
            {10306, 1}   -- 50% Stamina
        },

    },
    [13] = {
        backpack = 1995,  -- Backpack ID for level 13
        items = {
            {2160, 1},   -- Crystal Coin (10)
            {5958, 1},   -- Experience Scroll 2h (10)
            {9693, 1}    -- Addon Doll (1)
        },

    }
}

function onAdvance(player, skill, oldLevel, newLevel)
    if skill == SKILL_LEVEL then
        onLevelUp(player)
    end
end

function onLevelUp(player)
    local level = player:getLevel()
   
    if player:getStorageValue(level) == -1 then
        local rewardData = rewards[level]
       
        if rewardData then
            local backpackId = rewardData.backpack
            local backpack = player:addItem(backpackId, 1)
           
            local items = rewardData.items or {}
            for _, item in ipairs(items) do
                backpack:addItem(item[1], item[2])
            end
           
            local playerTown = player:getTown()
            local depotChest = player:getDepotChest(playerTown:getId(), true)
            backpack:moveTo(depotChest)
           
            player:setStorageValue(level, 1)  -- Mark rewards as received
            player:sendTextMessage(MESSAGE_INFO_DESCR, "You have received your level-up rewards! Check your hometown depot.")
        end
    else
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You have already claimed your rewards for this level.")
    end
end

Tested on Nekiro 8.6
  • Player receives a backpack sent to their hometown depot filled with rewards.
  • Only obtains rewards for each level once.
  • Upon logging out, players don't lose items that gets sent to depot.
Note: Does uses level to set storage but you can easily change that.
 
Last edited:
Thank you for checking the script that it works as planned.So, the fault lies in the database. If you say it works on Nekiro 8.6 then it should work for me. Unless my src is different.
I'm assuming a database, probably the player_depoitem table or something
 
Thank you for checking the script that it works as planned.So, the fault lies in the database. If you say it works on Nekiro 8.6 then it should work for me. Unless my src is different.
I'm assuming a database, probably the player_depoitem table or something
I was able to replicate the bug starting with your script, I believe the problem was the way it got added to depot indeed.
I edited the post but added a note that it uses the level as storage now.

Also you can safely remove this line from login.lua I think
LUA:
player:registerEvent("LevelUpReward")

Here an updated script:
  • Has now unique storage which you can set instead of taking level as storage.
  • Ability to add additional storage so it may unlock Quests at certain levels.


LUA:
local rewards = {
    [9] = {
        backpack = 1991,  -- Backpack ID for level 9
        storage = 999,     -- Unique storage ID for level 9
        questStorage = nil, -- No quest storage for level 9
        items = {
            {2152, 20},  -- Platinum Coin (20)
            {7618, 20},  -- Mana Potion (20)
            {7620, 20},  -- Life Potion (20)
            {2168, 1}    -- Ring of mana regeneration (1)
        },

    },
    [10] = {
        backpack = 1992,  -- Backpack ID for level 10
        storage = 1000,    -- Unique storage ID for level 10
        questStorage = {1500, 2}, -- Unlock quest storage for level 10
        items = {
            {2152, 35},  -- Platinum Coin (35)
            {7618, 35},  -- Mana Potion (35)
            {7620, 35},  -- Life Potion (35)
            {5908, 1}    -- Skinning (50)
        },

    },
    [11] = {
        backpack = 1993,  -- Backpack ID for level 11
        storage = 1001,    -- Unique storage ID for level 11
        questStorage = nil, -- No quest storage for level 11
        items = {
            {2152, 50},  -- Platinum Coin (50)
            {2216, 10},  -- Healing Ring
            {2165, 1},   -- Stealth Ring
            {2197, 1}    -- Stealth Amulet
        },

    },
    [12] = {
        backpack = 1994,  -- Backpack ID for level 12
        storage = 1002,    -- Unique storage ID for level 12
        questStorage = nil, -- No quest storage for level 12
        items = {
            {2206, 1},   -- Timer Ring (5)
            {2152, 70},  -- Platinum Coin (70)
            {10306, 1}   -- 50% Stamina
        },

    },
    [13] = {
        backpack = 1995,  -- Backpack ID for level 13
        storage = 1003,    -- Unique storage ID for level 13
        questStorage = nil, -- No quest storage for level 13
        items = {
            {2160, 1},   -- Crystal Coin (10)
            {5958, 1},   -- Experience Scroll 2h (10)
            {9693, 1}    -- Addon Doll (1)
        },

    }
}

function onAdvance(player, skill, oldLevel, newLevel)
    if skill == SKILL_LEVEL then
        onLevelUp(player)
    end
end

function onLevelUp(player)
    local level = player:getLevel()
   
    local rewardData = rewards[level]
    if rewardData and player:getStorageValue(rewardData.storage) == -1 then
        local backpackId = rewardData.backpack
        local backpack = player:addItem(backpackId, 1)
       

        local items = rewardData.items or {}
        for _, item in ipairs(items) do
            backpack:addItem(item[1], item[2])
        end

        local playerTown = player:getTown()
        local depotChest = player:getDepotChest(playerTown:getId(), true)
        backpack:moveTo(depotChest)
       
        player:setStorageValue(rewardData.storage, 1)
       
        if rewardData.questStorage then
            player:setStorageValue(rewardData.questStorage[1], rewardData.questStorage[2])
        end
       
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You have received your level-up rewards! Check your hometown depot.")
    else
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You have already claimed your rewards for this level.")
    end
end
 
SI'll check the corrected script and let you know :)I'll tell you that I thought the script I shared was unfinished and probably got lost. You tested this script and it works, so it should work for me too. If not, it's possible that there's something wrong with the table in the database. As for the source itself, I'm using this one.
HTML:
https://www.virustotal.com/gui/file/acbddca8989404d7c1fab45d4eb1c5c12a5cec9ea124d525c0b76997b04cf2f2?nocache=1

Code:
https://www.easypaste.org/file/L3KHiUdj/TFS-1.5-Downgrades-8.60.zip?lang=pl
 
I was able to replicate the bug starting with your script, I believe the problem was the way it got added to depot indeed.
I edited the post but added a note that it uses the level as storage now.

Also you can safely remove this line from login.lua I think
LUA:
player:registerEvent("LevelUpReward")

Here an updated script:
  • Has now unique storage which you can set instead of taking level as storage.
  • Ability to add additional storage so it may unlock Quests at certain levels.


LUA:
local rewards = {
    [9] = {
        backpack = 1991,  -- Backpack ID for level 9
        storage = 999,     -- Unique storage ID for level 9
        questStorage = nil, -- No quest storage for level 9
        items = {
            {2152, 20},  -- Platinum Coin (20)
            {7618, 20},  -- Mana Potion (20)
            {7620, 20},  -- Life Potion (20)
            {2168, 1}    -- Ring of mana regeneration (1)
        },

    },
    [10] = {
        backpack = 1992,  -- Backpack ID for level 10
        storage = 1000,    -- Unique storage ID for level 10
        questStorage = {1500, 2}, -- Unlock quest storage for level 10
        items = {
            {2152, 35},  -- Platinum Coin (35)
            {7618, 35},  -- Mana Potion (35)
            {7620, 35},  -- Life Potion (35)
            {5908, 1}    -- Skinning (50)
        },

    },
    [11] = {
        backpack = 1993,  -- Backpack ID for level 11
        storage = 1001,    -- Unique storage ID for level 11
        questStorage = nil, -- No quest storage for level 11
        items = {
            {2152, 50},  -- Platinum Coin (50)
            {2216, 10},  -- Healing Ring
            {2165, 1},   -- Stealth Ring
            {2197, 1}    -- Stealth Amulet
        },

    },
    [12] = {
        backpack = 1994,  -- Backpack ID for level 12
        storage = 1002,    -- Unique storage ID for level 12
        questStorage = nil, -- No quest storage for level 12
        items = {
            {2206, 1},   -- Timer Ring (5)
            {2152, 70},  -- Platinum Coin (70)
            {10306, 1}   -- 50% Stamina
        },

    },
    [13] = {
        backpack = 1995,  -- Backpack ID for level 13
        storage = 1003,    -- Unique storage ID for level 13
        questStorage = nil, -- No quest storage for level 13
        items = {
            {2160, 1},   -- Crystal Coin (10)
            {5958, 1},   -- Experience Scroll 2h (10)
            {9693, 1}    -- Addon Doll (1)
        },

    }
}

function onAdvance(player, skill, oldLevel, newLevel)
    if skill == SKILL_LEVEL then
        onLevelUp(player)
    end
end

function onLevelUp(player)
    local level = player:getLevel()
  
    local rewardData = rewards[level]
    if rewardData and player:getStorageValue(rewardData.storage) == -1 then
        local backpackId = rewardData.backpack
        local backpack = player:addItem(backpackId, 1)
      

        local items = rewardData.items or {}
        for _, item in ipairs(items) do
            backpack:addItem(item[1], item[2])
        end

        local playerTown = player:getTown()
        local depotChest = player:getDepotChest(playerTown:getId(), true)
        backpack:moveTo(depotChest)
      
        player:setStorageValue(rewardData.storage, 1)
      
        if rewardData.questStorage then
            player:setStorageValue(rewardData.questStorage[1], rewardData.questStorage[2])
        end
      
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You have received your level-up rewards! Check your hometown depot.")
    else
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You have already claimed your rewards for this level.")
    end
end
Hey, I checked the script! I will explain to you what is wrong and what is good.
When I set rewards to 10, 11, 12, 13.
After reaching level 10, the rewards go to the deposit, but when you log out, they disappear.
Then when I reach level 11 and log out, the items stay. Just like with the other levels. It's the same with the first backpack, but it disappears.
When I set a wider level 20, 40, 60. Every time I get a reward and log out, items disappear.
Deposits work normally, something is wrong with this script.
 
Both scripts I gave works perfect for me on a nekiro 8.6 distro, i'm not sure what could go wrong if you use the same distro 🤔
 
@n3crozzy
You need remove data/creaturescript/levelUpReward.lua and also remove the tag & "event type="advance" name="LevelUpReward" script="levelUpReward.lua";. After that, remove the onLogin line player:registerEvent("LevelUpReward"). Once I updated the script, it started working for you. When you reach level 25, items are immediately sent to the depot with a message confirming the successful delivery. If you die, lose a level, and log out, the item remains in the depot as expected.

It's just a revscript. Place it in data/scripts/creaturescript and test it.

LevelUpReward.lua


LUA:
local rewards = {
    [25] = {
        backpack = 1991,  -- Backpack ID
        items = {
            {2152, 20},  -- Platinum Coin (20)
            {7618, 20},  -- Mana Potion (20)
            {7620, 20},  -- Life Potion (20)
            {2168, 1}    -- Ring of mana regeneration (1)
        },
        storage = 99112  -- Unique storage identifier for level 35
    },
    [35] = {
        backpack = 1993,  -- Backpack ID
        items = {
            {2152, 50},  -- Platinum Coin (50)
            {2216, 10},  -- Healing Ring
            {2165, 1},   -- Stealth Ring
            {2197, 1}    -- Stealth Amulet
        },
        storage = 99114  -- Unique storage identifier for level 50
    },
    [70] = {
        backpack = 1994,  -- Backpack ID
        items = {
            {2206, 1},   -- Timer Ring (5)
            {2152, 70},  -- Platinum Coin (70)
            {10306, 1}   -- 50% Stamina
        },
        storage = 99115  -- Unique storage identifier for level 70
    },
    [100] = {
        backpack = 1995,  -- Backpack ID
        items = {
            {2160, 1},   -- Crystal Coin (1)
            {5958, 1},   -- Experience Scroll 2h (1)
            {9693, 1}    -- Addon Doll (1)
        },
        storage = 99116  -- Unique storage identifier for level 100
    }
}

local function giveRewardsToDepot(player, level)
    local rewardData = rewards[level]
    if not rewardData then
        return false
    end

    if player:getStorageValue(rewardData.storage) == 1 then
        return false
    end

    local town = player:getTown()
    if not town then
        return false
    end

    local depotChest = player:getDepotChest(town:getId(), true)
    if not depotChest then
        return false
    end

    local backpack = depotChest:addItem(rewardData.backpack, 1)
    if not backpack then
        return false
    end

    local rewardMessage = "Level " .. level .. " rewards sent to your depot:\n"

    for _, reward in ipairs(rewardData.items) do
        local itemId, count = reward[1], reward[2]
        if backpack:addItem(itemId, count) then
            local itemName = ItemType(itemId):getName()
            rewardMessage = rewardMessage .. "- " .. itemName .. " x" .. count .. "\n"
        end
    end

    player:setStorageValue(rewardData.storage, 1)

    player:sendTextMessage(MESSAGE_EVENT_ORANGE, rewardMessage)
    return true
end

local advanceEvent = CreatureEvent("advanceRewards")

function advanceEvent.onAdvance(player, skill, oldLevel, newLevel)
    if skill == SKILL_LEVEL then
        for level, _ in pairs(rewards) do
            if newLevel >= level and oldLevel < level then
                giveRewardsToDepot(player, level)
            end
        end
    end
    return true
end

advanceEvent:register()

local loginEvent = CreatureEvent("loginRewards")

function loginEvent.onLogin(player)
    player:registerEvent("advanceRewards")
    
    local playerLevel = player:getLevel()
    for level, rewardData in pairs(rewards) do
        local storageValue = player:getStorageValue(rewardData.storage)
        
        if playerLevel >= level and storageValue ~= 1 then
            giveRewardsToDepot(player, level)
        end
    end
    
    return true
end

loginEvent:register()
Code:
 
Hey guys, I just got up. I'll check the script and get back to you! I think this will be the final script and it will work as it should. Thanks for all your help, you're all great. I'll check it out right away :)
 
It doesn't look like problem with Lua script. It looks like problem with C++ code that saves depot:
Replace that bool needsSave = false; with bool needsSave = true; and it will always save player depot.
 
Come back, I checked, it looks like this.
number1
Number2

Strange behavior, I have no idea what it is about.
in the cpp file as you mentioned.
LUA:
//save depot locker items
    bool needsSave = false;

    for (const auto& it : player->depotLockerMap) {
        if (it.second->needsSave()) {
            needsSave = true;
            break;
        }
    }

Well, it's supposed to be false, can I set it to true?
I'll get in touch

I leave the backpack intact and get a second backpack and when I log out, they stay?
It seems to work, it doesn't work... ;/
 
Last edited:
Well, it's supposed to be false, can I set it to true?
It should detect that some item was added/removed to/from depot and save depot, only if it's modified. It's pretty badly written in nekiro downgrade and probably does not work as intended.
That's why removing this detection - change it to true to make it always save depot - should fix problem with disappearing items.
 
Works! Editing in the cpp file helped,
setting from false to true! Thank you for your help!!!
Thank you all for your help! For sharing the refreshed code
The famous Gesior!
I can go further! I'm looking for global exp, skill, loot [ for each player ]
 
Last edited:

Similar threads

Back
Top