• 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 On use item gives random item that could be rare

demon088

#088 in the Horde
Joined
Jun 17, 2009
Messages
249
Solutions
3
Reaction score
30
Location
Hell
Hello again OtLand!
I've been working on mixing systems that gives you random equipment using an item and obtained items could be improved like this post from @zbizu - https://otland.net/threads/tfs-1-1-random-item-stats.228990. This system works giving creature loots with items that can be "rare" or anything else with aditional attributes like def +15%. This system is totally working for me on TFS 1.2 and I wanted to add another way to obtain rare items not only by looting them, but quests or this item action.

This code is an action of an item capable of give you random items:
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
 doSendMagicEffect(getPlayerPosition(cid), 31)
local RANDOM_ITEM = {7903, 24429, 2488, 7891}    
 local randomChance = math.random(2, #RANDOM_ITEM)
      doPlayerAddItem(cid, RANDOM_ITEM[randomChance], 1)
   doRemoveItem(item.uid, 1)
   return true
end
I've been trying to mix both systems but I think I'm not enough experienced for making such system works. I'd be thankful if you could help me with this and I'd be happy to share this system with the OtLand community!
 
tried to make it as configurable as possible (but not exactly 100% fool-proof, so read my comments) and explain how you can configure your things
untested because i'm too lazy to spend a minute to test even though it took me like 15 mins to write this, however i don't see any errors
as for making zbizu's system work with it, i believe you can edit the item after it's created? (i haven't bothered to read the code, but i hope it works this way)
if so, you can set a variable inside of the onUse function like so:
Lua:
local newitem = player:addItem(reward.id, reward.count)
then you can just use newitem as your object to set the rarity or w/e
Lua:
local rewards = {
    -- legendary items
    [{1, 5}] = { -- [{min, max}] chance
        {id = 2160, count = 50},                             -- 1st way of making an item, id and maximum count required
        {ids = {2160, 2148}, count = 50},                    -- 2nd way, all ids listed will have the same maximum count
        {ids = {2160, 2148}},                                -- 3rd way, all ids listed will have default count of 1
        {name = "Gold Coin", count = 3},                     -- 4th way, name and count required
        {names = {"Gold Coin", "Platinum Coin"}, count = 3}, -- 5th way, all names listed will have default count of 1
        {names = {"Gold Coin", "Platinum Coin"}},            -- 6th way, all names listed will have default count of 1
        2148,                                                -- 7th way, ids listed this way will have default count of 1
        "Crystal Coin"                                       -- 8th way, names listed will have a default count of 1
        -- note: count can be used as {min, max} (example: {5, 20}) and it will pick a number between min and max to give
    }
}

--[[ example table:

local rewards = {
    -- legendary
    [{1, 5]}] = {
        {id = 2544, count = {15, 30}}, -- arrows with 15-30 count
        {names = {"Demon Helmet", "Demon Shield", "Demon Armor", "Demon Legs"}}, -- demon set (one will be picked)
    },
    -- common
    [{6, 100}] = {
        {id = 2160, count = {33, 66}} -- crystal coins with 33-66 count
        "Golden Amulet",
        "Frozen Starlight",
        "Leather Boots",
    }
}

]]

local function selectReward()
    local rand = math.random(100)
    for tier, itemlist in pairs(rewards) do
        if (rand >= tier[1] and rand <= tier[2]) then
            local reward = itemlist[math.random(#itemlist)]
            local count = nil
            if type(reward) == "table" then
                if reward.ids then
                    reward = reward.ids[math.random(#reward.ids)]
                else
                    reward = reward.id
                end
                if reward.names then
                    reward = ItemType(reward.names[math.random(#reward.names)]):getId()
                else
                    reward = ItemType(reward.name):getId()
                end
                if reward.count and type(reward.count) == "table" then
                    count = math.random(reward.count[1], reward.count[2])
                else
                    count = reward.count
                end
            elseif type(reward) == "string" then
                reward = ItemType(reward):getId()
            end
            return {id = reward, count = count or 1}
        end
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local reward = selectReward()
    local it = ItemType(reward.id)
    local msg = string.format("You have recieved %s %s!", (reward.count > 1 and reward.count) or it:getArticle(), (reward.count > 1 and it:getPluralName()) or it:getName())
    player:addItem(reward.id, reward.count)
    player:sendMessage(MESSAGE_INFO_DESCR, msg)
    item:remove(1)
    return true
end
 
Last edited:
tried to make it as configurable as possible (but not exactly 100% fool-proof, so read my comments) and explain how you can configure your things
untested because i'm too lazy to spend a minute to test even though it took me like 15 mins to write this, however i don't see any errors
as for making zbizu's system work with it, i believe you can edit the item after it's created? (i haven't bothered to read the code, but i hope it works this way)
if so, you can set a variable inside of the onUse function like so:
Lua:
local newitem = player:addItem(reward.id, reward.count)
then you can just use newitem as your object to set the rarity or w/e
Lua:
local rewards = {
    -- legendary items
    [{1, 5}] = { -- [{min, max}] chance
        {id = 2160, count = 50},                             -- 1st way of making an item, id and maximum count required
        {ids = {2160, 2148}, count = 50},                    -- 2nd way, all ids listed will have the same maximum count
        {ids = {2160, 2148}},                                -- 3rd way, all ids listed will have default count of 1
        {name = "Gold Coin", count = 3},                     -- 4th way, name and count required
        {names = {"Gold Coin", "Platinum Coin"}, count = 3}, -- 5th way, all names listed will have default count of 1
        {names = {"Gold Coin", "Platinum Coin"}},            -- 6th way, all names listed will have default count of 1
        2148,                                                -- 7th way, ids listed this way will have default count of 1
        "Crystal Coin"                                       -- 8th way, names listed will have a default count of 1
        -- note: count can be used as {min, max} (example: {5, 20}) and it will pick a number between min and max to give
    }
}

--[[ example table:

local rewards = {
    -- legendary
    [{1, 5]}] = {
        {id = 2544, count = {15, 30}}, -- arrows with 15-30 count
        {names = {"Demon Helmet", "Demon Shield", "Demon Armor", "Demon Legs"}}, -- demon set (one will be picked)
    },
    -- common
    [{6, 100}] = {
        {id = 2160, count = {33, 66}} -- crystal coins with 33-66 count
        "Golden Amulet",
        "Frozen Starlight",
        "Leather Boots",
    }
}

]]

local function selectReward()
    local rand = math.random(100)
    for tier, itemlist in pairs(rewards) do
        if (rand >= tier[1] and rand <= tier[2]) then
            local reward = itemlist[math.random(#itemlist)]
            local count = nil
            if type(reward) == "table" then
                if reward.ids then
                    reward = reward.ids[math.random(#reward.ids)]
                else
                    reward = reward.id
                end
                if reward.names then
                    reward = ItemType(reward.names[math.random(#reward.names)]):getId()
                else
                    reward = ItemType(reward.name):getId()
                end
                if reward.count and type(reward.count) == "table" then
                    count = math.random(reward.count[1], reward.count[2])
                else
                    count = reward.count
                end
            elseif type(reward) == "string" then
                reward = ItemType(reward):getId()
            end
            return {id = reward, count = count or 1}
        end
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local reward = selectReward()
    local it = ItemType(reward.id)
    local msg = string.format("You have recieved %s %s!", (reward.count > 1 and reward.count) or it:getArticle(), (reward.count > 1 and it:getPluralName()) or it:getName())
    player:addItem(reward.id, reward.count)
    player:sendMessage(MESSAGE_INFO_DESCR, msg)
    item:remove(1)
    return true
end
I tested this and I got this issue:
Code:
Lua Script Error: [Action Interface]
data/actions/scripts/other/equip1as.lua:onUse
data/actions/scripts/other/equip1as.lua:251: attempt to call global 'doPlayerRegisterEvent' (a nil value)
stack traceback:
        [C]: in function 'doPlayerRegisterEvent'
        data/actions/scripts/other/equip1as.lua:251: in function <data/actions/scripts/other/equip1as.lua:1>

Lua Script Error: [Action Interface]
data/actions/scripts/other/equip1as.lua:onUse
data/actions/scripts/other/equip1as.lua:67: attempt to index local 'reward' (a nil value)
stack traceback:
        [C]: in function '__index'
        data/actions/scripts/other/equip1as.lua:67: in function <data/actions/scripts/other/equip1as.lua:65>
BUMP: I'm sorry for doing this, but I'd like such system in my OTS xd Would be so cool.
 
Last edited:
Code:
[{1, 5}]
doesnt look like a legit way to declare a table (never seen this in other people scripts)
try
Code:
[0] = {} -- tier 1
[1] = {} -- tier 2
Code:
local roll = math.random(1, 100)
local tier
if roll < 6 then -- 0-5
tier = 0
elseif roll < 50 then -- 6-49
tier = 1
elseif roll < 100 then -- 50-99
tier = 2
end
 
Back
Top