• 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 Player rewards by vocation

Finkelz

Premium User
Premium User
Joined
Apr 22, 2013
Messages
39
Solutions
1
Reaction score
15
Hi everyone!
I'm trying to make a rewards system by vocation, but seems I can't get it to work.
I am using TFS 1.2

This is my script:
Lua:
local rewards = {
   [{1,5}] = { -- sorcerer
     [20] = {items = {{itemid = 2160, count = 2}, {itemid = 8900, count = 1}}, storage = 40953},
     [50] = {items = {{itemid = 2160, count = 5}, {itemid = 8902, count = 1}}, storage = 40955},
     [80] = {items = {{itemid = 2160, count = 10}, {itemid = 18409, count = 1}, {itemid = 18390, count = 1}}, storage = 40955},
     [150] = {items = {{itemid = 2160, count = 20}, {itemid = 16112, count = 1}}, storage = 40955},
   },
   [{2,6}] = { -- druid
     [20] = {items = {{itemid = 2160, count = 2}, {itemid = 8900, count = 1}}, storage = 40955},
     [50] = {items = {{itemid = 2160, count = 5}, {itemid = 8902, count = 1}}, storage = 40955},
     [80] = {items = {{itemid = 2160, count = 10}, {itemid = 18411, count = 1}, {itemid = 18412, count = 1}}, storage = 40955},
     [150] = {items = {{itemid = 2160, count = 20}, {itemid = 16112, count = 1}}, storage = 40955},
   },
   [{3,7}] = { -- paladin
     [20] = {items = {{itemid = 2160, count = 2}}, storage = 40955},
     [50] = {items = {{itemid = 2160, count = 5}}, storage = 40955},
     [80] = {items = {{itemid = 2160, count = 10}, {itemid = 8855, count = 1}, {itemid = 15644, count = 1}}, storage = 40955},
     [150] = {items = {{itemid = 2160, count = 20}, {itemid = 22417, count = 1}, {itemid = 22420, count = 1}}, storage = 40955},
   },
   [{4,8}] = { -- knight
     [20] = {items = {{itemid = 2160, count = 2}, {itemid = 8900, count = 1}}, storage = 40955},
     [50] = {items = {{itemid = 2160, count = 5}, {itemid = 8902, count = 1}}, storage = 40955},
     [80] = {items = {{itemid = 2160, count = 10}, {itemid = 2536, count = 1}}, storage = 40955},
     [150] = {items = {{itemid = 2160, count = 20}, {itemid = 18410, count = 1}}, storage = 40955},
   }
}
function onAdvance(player, skill, oldlevel, newlevel)
    if skill ~= SKILL_LEVEL then
     return true
    end
    for voc, x in pairs(rewards) do
        if isInArray(voc, player:getVocation()) then
        for level, z in pairs(x) do
            if newlevel >= level and player:getStorageValue(z.storage) < 1 then
                player:setStorageValue(z.storage, 1)
                for v = 1, #z.items do
                    player:addItem(z.items[v].itemid, z.items[v].count)
                end
                if newlevel == 80 then
                    if player:getVocation() == 4 or player:getVocation() == 8 then
                        club = player:getSkillLevel(SKILL_CLUB)
                        sword = player:getSkillLevel(SKILL_SWORD)
                        axe = player:getSkillLevel(SKILL_AXE)
                        if club > sword and club > axe then -- CLUB
                            player:addItem(22410, 1)
                            player:addItem(22413, 1)
                        elseif sword > club and sword > axe then -- SWORD
                            player:addItem(22398, 1)
                            player:addItem(22401, 1)
                        elseif axe > club and axe > sword then -- AXE
                            player:addItem(22404, 1)
                            player:addItem(22407, 1)
                        end
                    end
                end
                if newlevel == 150 then
                    if player:getVocation() == 4 or player:getVocation() == 8 then
                        club = player:getSkillLevel(SKILL_CLUB)
                        sword = player:getSkillLevel(SKILL_SWORD)
                        axe = player:getSkillLevel(SKILL_AXE)
                        if club > sword and club > axe then -- CLUB
                            player:addItem(22411, 1)
                            player:addItem(22414, 1)
                        elseif sword > club and sword > axe then -- SWORD
                            player:addItem(22399, 1)
                            player:addItem(22402, 1)
                        elseif axe > club and axe > sword then -- AXE
                            player:addItem(22405, 1)
                            player:addItem(22408, 1)
                        end
                    end
                end
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Congratulations, you reached level "..level.." and received your rewards!")
                player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_YELLOW)
                player:setStorageValue(z.storage, 1)
            end
        end
    end
    end
    return true
end

No error or anything, but nothing happens.
Also, if someone has an idea how to give the knight weapons according to skill in a prettier/more efficient way, I'm open to suggestions.

Thanks in advance!
 
Solution
OK!
So I use a unique key to mark a quest/reward, and set it's value to 1 to mark it as received.
I get that part, thanks alot for the explanation! @Colandus
The part in my script that I don't get past now is this:
Lua:
if isInArray(voc, player:getVocation()) then
    print(player:getVocation())

So then I tried to print the value of player:getVocation(), and I get some hex shit: 0 x a7b8c9a1
I think the problem is that the IF statement above never returns true, as the function was changed and no longer returns the ID of the vocation.
I looked up in the documentation: Metatable:Player · otland/forgottenserver Wiki · GitHub

But it doesn't state the return value.
My prediction is that it was...
I beleive line 34 and 35 is your issue.
You check if the storage is below 1,and only set it to value 1.
So this script will only work for their very first level up advancement, and will never reach the item giving stage again.
Your table has the same storage value everywhere.
Try printing their storage value, and see if that's the issue.
 
Thanks @Xikini ,
I'm kinda new, don't really know how to print it.
About the storage values, I don't even know what those values mean, I couldn't find any documentation for those...
Could you point me in some direction where to look?
 
A storage value is a value saved into database for each player. They have a key and value pair. You can look if a player has a storage key with a specific value. Keys and value are always numbers. Storage values can be used to set a status to know whether a player has done a specific quest, or to add exhaust to a script by setting the value to current (or future) time.

Storages are saved in table as player_id, storage_key, storage_value

To save a value you use player:setStorage(key, value). To read a value you use player:getStorage(key) which would return the current value that storage key holds, or -1 if it is not registered on that player.

Basically, calling player:setStorage(12345, 6789) will save into player_storage table in database (if we pretend player id is 5):

player_id, storage_key, storage_value
5 12345 6789

Now if you would like to know a player has done a specific quest or if you want to limit the use of an item to 1 time, you save a storage to the player with a unique key (which means you need to know which storage keys aren't already used in your server). Normally we do this with the value 1 for the value, because we only need to check if it's not -1 if he didn't previously have that storage key registered.

E.g. Assume we have a script for a stone, when you use it you obtain an item but you may only use it once. We could do it this way (make sure to read the comments in the code for explanations):
Lua:
function onUse(player)
    if player:getStorageValue(5678) == 1 then -- if player didnt use this item before his storage value for this key should be -1 because it's never been set before, right?!
        player:sendTextMessage(MESSAGE_INFO_DESCR, "The stone is empty.")
        return true -- exit function here
    end

    player:addItem(2160, 100) -- example give an item
    player:setStorageValue(5678, 1) -- Now we set that value to 1, which means next time he uses item it will be 1 and it will send message and exit function, thus never reaching this point.
end

If you're confused, this is how it works; as I said, the storage values are stored in the database. Normally a player should have no storage values registered once his character is created. So when the player uses this stone, he does not have this storage key "5678" registered in his database. Because of that, the function player:getStorageValue(5678) will return -1 because it wasn't previously registered for the player. This means, we can safely assume that if the player does not have that storage key registered we could know he has not used this stone before. And to make sure he can't use it again, we will this time set that value to 1, which means next time he uses that item and the code checks if he has storage key 5678, it will this time be 1 and not -1.

Hope that made sense :)
 
Last edited:
OK!
So I use a unique key to mark a quest/reward, and set it's value to 1 to mark it as received.
I get that part, thanks alot for the explanation! @Colandus
The part in my script that I don't get past now is this:
Lua:
if isInArray(voc, player:getVocation()) then
    print(player:getVocation())

So then I tried to print the value of player:getVocation(), and I get some hex shit: 0 x a7b8c9a1
I think the problem is that the IF statement above never returns true, as the function was changed and no longer returns the ID of the vocation.
I looked up in the documentation: Metatable:Player · otland/forgottenserver Wiki · GitHub
getVocation()
Description: N/A
Parameters: None
Returns: N/A
Example:

local player = Player(...)
player:getVocation()
Added in version: 1.0
But it doesn't state the return value.
My prediction is that it was changed and doesn't return an ID anymore...
Any idea?
 
OK!
So I use a unique key to mark a quest/reward, and set it's value to 1 to mark it as received.
I get that part, thanks alot for the explanation! @Colandus
The part in my script that I don't get past now is this:
Lua:
if isInArray(voc, player:getVocation()) then
    print(player:getVocation())

So then I tried to print the value of player:getVocation(), and I get some hex shit: 0 x a7b8c9a1
I think the problem is that the IF statement above never returns true, as the function was changed and no longer returns the ID of the vocation.
I looked up in the documentation: Metatable:Player · otland/forgottenserver Wiki · GitHub

But it doesn't state the return value.
My prediction is that it was changed and doesn't return an ID anymore...
Any idea?
it returns the userdata for the vocation (a userdata is a raw memory value which holds information)
use player:getVocation():getId()
since player:getVocation() returns a userdata for vocation, you can use vocation methods on it (aka the getId method in this case)
 
Solution
Back
Top