• 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!

TFS 1.X+ Loot Box not functioning properly

Extrodus

|| Blazera.net ||
Premium User
Joined
Dec 22, 2008
Messages
2,731
Solutions
7
Reaction score
537
Location
Canada
Hey there everyone; I'm having a couple issues with the script below and would love some help!

1. When purchasing a chest; the chest recieves multiple items.
The below picture is of an uncommon box, which brings me to the second issue.
1664813031655.png

2. Items are not being kept to their specified tiers. For example the yellow gem should only come with the legendary box, green gem only to the common box, etc.
Idealy the way the box should work is if you loot an uncommon box, it has a chance to add items specified with that tier only.

3. boxRewardCount is set as a config option but not called to in the script. This feature would be nice to have incase we would like to allow more than 1 item to drop in the specified tier. I suppose would be fine to add an item from a tier that is below; this way you will always receive the boxRewardCount if it is set to 2+ but there is only one item in the box tier available.

Lua:
local RANDOM_ITEM_CATEGORY_COMMON = 1
local RANDOM_ITEM_CATEGORY_UNCOMMON = 2
local RANDOM_ITEM_CATEGORY_SEMI_RARE = 3
local RANDOM_ITEM_CATEGORY_RARE = 4
local RANDOM_ITEM_CATEGORY_LEGENDARY = 5

local config = {
    talkAction = "!lootbox", -- only for admins
    randomItems = {
        {
            id = "green gem",
            chance = 100,
            count = {1, 1}, -- 1-1
            allowCategories = {
                RANDOM_ITEM_CATEGORY_COMMON
            }
        },
        {
            id = "blue gem",
            chance = 100,
            count = {1, 1},
            allowCategories = {
                RANDOM_ITEM_CATEGORY_UNCOMMON
            }
        },
        {
            id = "red gem",
            chance = 100,
            count = {1, 1},
            allowCategories = {
                RANDOM_ITEM_CATEGORY_SEMI_RARE
            }
        },
        {
            id = "purple gem",
            chance = 100,
            count = {1, 1},
            allowCategories = {
                RANDOM_ITEM_CATEGORY_RARE
            }
        },
        {
            id = "yellow gem",
            chance = 100,
            count = {1, 1},
            allowCategories = {
                RANDOM_ITEM_CATEGORY_LEGENDARY
            }
        }
    },
    customAttributeKey = "randomBoxCategory",
    categories = {
        {
            id = RANDOM_ITEM_CATEGORY_COMMON,
            name = "Common",
            chance = 80, -- 60%
        },
        {
            id = RANDOM_ITEM_CATEGORY_UNCOMMON,
            name = "Uncommon",
            chance = 60, -- 50%
        },
        {
            id = RANDOM_ITEM_CATEGORY_SEMI_RARE,
            name = "Semi-Rare",
            chance = 40, -- 40%
        },
        {
            id = RANDOM_ITEM_CATEGORY_RARE,
            name = "Rare",
            chance = 20, -- 30%
        },
        {
            id = RANDOM_ITEM_CATEGORY_LEGENDARY,
            name = "Legendary",
            chance = 5, -- 5%
        }
    },

    boxItemId = 1738, -- box
    boxRewardCount = 1, -- count of items in box
    boxCustomName = "loot box", -- box custom name
    boxCustomDescription = "Many magical wonders are held within this box. Do you have what it takes to free them?", -- box custom description
    boxPrice = 10000 * 50, -- box price 50 crystal coins
    leverActionId = 39015, -- lever action id
    leverItemdIdOn = 1945, -- lever item id on
    leverItemdIdOff = 1946 -- lever item id off
}

local function getRandomCategory(allowCategories)
    for _, ac in pairs(allowCategories) do
        local category = config.categories[ac]
        if category then
            if category.chance >= math.random(1, 100) then
                return category
            end
        end
    end
end

local function createRandomBox()
    local box = Game.createItem(config.boxItemId, 1)
    if box then
        box:setAttribute(ITEM_ATTRIBUTE_NAME, config.boxCustomName)
        box:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, config.boxCustomDescription)
        for _, randomItem in pairs(config.randomItems) do
            if randomItem.chance >= math.random(0, 100) then
                local count = math.random(randomItem.count[1], randomItem.count[2])
                for i = 1, randomItem.stacks or 1 do
                    local item = Game.createItem(randomItem.id, count)
                    if item then
                        if randomItem.allowCategories then
                            local category = getRandomCategory(randomItem.allowCategories)
                            if category then
                                box:setCustomAttribute(config.customAttributeKey, category.id)
                            end
                        end

                        if box:addItemEx(item) ~= RETURNVALUE_NOERROR then
                            item:remove()
                            break
                        end
                    end
                end
            end
        end
        return box
    end
end

local talkAction = TalkAction(config.talkAction)

function talkAction.onSay(player, words, param, type)
    local target = Player(param)
    if not target then
        player:sendCancelMessage("Player not found.")
        return false
    end

    local box = createRandomBox()
    if not box then
        debugPrint("[RandomBox] Error: Could not create box.")
        return false
    end

    local returnValue = target:addItemEx(box)
    if returnValue ~= RETURNVALUE_NOERROR then
        box:remove()
        player:sendCancelMessage(returnValue)
        return false
    end

    target:sendTextMessage(MESSAGE_INFO_DESCR, "You have been given a loot box.")
    return false
end

talkAction:accountType(ACCOUNT_TYPE_GOD)
talkAction:access(true)
talkAction:separator(" ")
talkAction:register()

local action = Action()

function action.onUse(player, item, fromPos, target, toPos, isHotkey)
    if player:getMoney() < config.boxPrice then
        player:sendCancelMessage("You do not have enough, this box costs 50x Crystal Coins.")
        return true
    end

    local box = createRandomBox()
    if not box then
        debugPrint("[RandomBox] Error: Could not create box.")
        return true
    end

    if player:addItemEx(box) ~= RETURNVALUE_NOERROR then
        box:remove()
        player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return true
    end

    player:removeMoney(config.boxPrice)
    player:sendTextMessage(MESSAGE_INFO_DESCR, "You purchased a loot box.")
    item:transform(item:getId() == config.leverItemdIdOn and config.leverItemdIdOff or config.leverItemdIdOn)
    player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_YELLOW)
    return true
end

action:aid(config.leverActionId)
action:register()

local ec = EventCallback

function ec.onLook(player, thing, position, distance, description)
    if thing:isItem() then
        local category = thing:getCustomAttribute(config.customAttributeKey)
        if category then
            description = description .. "\n[" .. config.categories[category].name .. "]"
        end
    end
    return description
end

ec:register(1)

Any help is greatly appreciated!
 
Last edited:
Lua:
if category.chance >= math.random(1, 100) then
                return category

if it fail all rolls you will get no chest at all
+ wrong loop
your script have
Code:
allowCategories = {5)
why use for key, value?
anyway
Code:
for i = 1, randomItem.stacks or 1 do
where you have randomitem.stacks? in your code is always for i = 1, 1 do

idk, its so overcomplicated script and 2 configs, would be much easier if u just msg how script should work from start to end in 1 message and write this system from 0
 
Lua:
if category.chance >= math.random(1, 100) then
                return category

if it fail all rolls you will get no chest at all
+ wrong loop
your script have
Code:
allowCategories = {5)
why use for key, value?
anyway
Code:
for i = 1, randomItem.stacks or 1 do
where you have randomitem.stacks? in your code is always for i = 1, 1 do

idk, its so overcomplicated script and 2 configs, would be much easier if u just msg how script should work from start to end in 1 message and write this system from 0
Agreed it seems a bit all over the place; I personally didn't write this code. I've kind of came to the same conclusion which is why I had to post for support rather than fixing it myself. Couldn't really follow what was going on and why xD

As mentioned above the way it should work is pretty straight simple; just a loot box that generates a tier when made and will add items from that tier.

Code:
Idealy the way the box should work is if you loot an uncommon box, it has a chance to add items specified with that tier only.

Config option "BoxMaxItems = 1" incase we would like to allow more than 1 item to drop in the specified tier. If only one item in selected tier, then add an item from a tier that is below rather than creating multiple of the same item.
 
Back
Top