• 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!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

Reply to thread

This system is based on Reward Chests. Check out the Tibia Wiki to learn more about how it works. It's simple!


In regard to the reward, it will be dispatched to the designated depot. Simply locate the 'depotId' line and specify the number of the city you wish to send it to; this will ensure direct delivery to the depot. For instance, assigning the number 1 for the primary city and 2 for Thais, and so forth, facilitates this process.

This script is the first version..

[ATTACH=full]83981[/ATTACH]

This script is configured to activate a 5-minute timer upon expiration, automatically removing the Reward Chest Id=21584. Should you wish to extend the duration or adjust it based on Tibia Wiki guidelines, it offers versatility. This system is particularly suitable for boss rooms where defeating the boss results in the transformation of its corpse into the RewardChestId. Players interact with it, and after a designated period, the chest dissipates.


When you kill the boss, it dies and transforms into a Reward Chest with ID 21584.

Follow the step-by-step installation guide provided here.

  • register the event in given monster file
    XML:

    [CODE=xml]<script>
    <event name="BossDeath"/>
    </script>[/CODE]
  • set boss corpse to 0, otherwise you will get additional loot message
    XML:
    [CODE=xml]<look type="201" corpse="0" />[/CODE]



This is RevScripts. Place the script anywhere in the data/scripts folder, whether it's a subfolder or your preferred location.

[CODE=lua]local bossesList = {

    { name = "Orshabaal", storage = 6655, expirationTime = 5 * 60, loot = { {item = 2160, count = 5, chance = 100000}, {item = 2494, count = 1, chance = 50000}, }, RewardChestId = 21584, depotID = 1 },

    { name = "Cave Rat", storage = 6656, expirationTime = 5 * 60, loot = { {item = 2160, count = 10, chance = 100000}, {item = 2498, count = 1, chance = 75000}, }, RewardChestId = 21584, depotID = 1 },

    -- Add more bosses as needed

}


local STORAGE_KEYS = {

    bossData = "boss_data",

}


local function createRewardChest(bossPosition, rewardChestId, expirationTime)

    local rewardItem = Game.createItem(rewardChestId, 1, bossPosition)

    if rewardItem then

        rewardItem:setAttribute(ITEM_ATTRIBUTE_ACTIONID, ACTION_ID)

        addEvent(function()

            if rewardItem and rewardItem:getPosition() then

                rewardItem:remove()

                local players = Game.getPlayers()

                for _, player in ipairs(players) do

                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The reward chest has disappeared!")

                end

            end

        end, expirationTime * 1000)

    else

        print("Error creating reward chest.")

    end

end


local function hasRewardExpired(player, storageKey)

    local expirationTime = player:getStorageValue(storageKey)

    return expirationTime ~= -1 and expirationTime <= os.time()

end


local creatureEvent = CreatureEvent("BossDeath")


function creatureEvent.onDeath(creature, corpse)

    local bossPosition = creature:getPosition()

    local rewardChestId = 0

    local depotID = 0

    local bossName = ""

    for _, boss in ipairs(bossesList) do

        if creature:getName():lower() == boss.name:lower() then

            rewardChestId = boss.RewardChestId

            depotID = boss.depotID

            bossName = boss.name

            break

        end

    end


    if rewardChestId ~= 0 then

        createRewardChest(bossPosition, rewardChestId, bossesList[1].expirationTime)

        creature:say("The reward chest will disappear in 5 minutes!", TALKTYPE_MONSTER_SAY)

    else

        print("Reward chest ID not found.")

    end


    for _, player in ipairs(Game.getPlayers()) do

        if player:isPlayer() then

            for _, boss in ipairs(bossesList) do

                if creature:getName():lower() == boss.name:lower() then

                    player:setStorageValue(boss.storage, 1)

                    local expirationTime = os.time() + boss.expirationTime

                    player:setStorageValue(STORAGE_KEYS.bossData, expirationTime)

                    local message = "You contributed to defeating " .. boss.name .. ". Now go to the chest to claim your reward! Expiration time: " .. os.date("%c", expirationTime)

                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message)

                end

            end

        end

    end

end


creatureEvent:register()


local function sendRewardMessage(player, bossName, receivedItems)

    local message

    if #receivedItems > 0 then

        message = "From " .. bossName .. ": " .. table.concat(receivedItems, ", ")

        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message)

        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your reward has been sent to your depot.")

    else

        message = "From " .. bossName .. ": Unfortunately, you did not receive any items."

        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message)

    end

end


local rewardAction = Action()


function rewardAction.onUse(player, item, fromPosition, target, toPosition, isHotkey)

    if not player or not player:isPlayer() or not item then

        return false

    end


    local depotID = 0

    for _, boss in ipairs(bossesList) do

        if item:getId() == boss.RewardChestId and player:getStorageValue(boss.storage) == 1 then

            depotID = boss.depotID

            local storageKey = "boss_reward_time"

            if hasRewardExpired(player, storageKey) then

                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Your reward from " .. boss.name .. " has expired.")

            else

                local depot = player:getDepotChest(depotID, true)  -- Using depotID from the boss configuration

                if not depot then

                    return false

                end


                local bag = depot:addItem(7343, 1)

                if not bag then

                   print("Failed to add the reward bag to the player's depot.")

                    return false

                end


                local receivedItems = {}

                for _, lootItem in ipairs(boss.loot) do

                    if math.random(100000) <= lootItem.chance then

                        local itemAdded = bag:addItem(lootItem.item, lootItem.count or 1)

                        if itemAdded then

                            local itemName = ItemType(lootItem.item):getPluralName() or ItemType(lootItem.item):getName()

                            table.insert(receivedItems, (lootItem.count or 1) .. "x " .. itemName)

                        end

                    end

                end


                sendRewardMessage(player, boss.name, receivedItems)

            end

            player:setStorageValue(boss.storage, 0)

            player:setStorageValue(storageKey, -1)

            break

        end

    end


    return true

end


rewardAction:aid(ACTION_ID)

rewardAction:register()

[/CODE]


This script is the second version

In the Reward Chest (for example, in the temple or boss room), you should set it up using the Action ID as shown in the image.


[ATTACH=full]83989[/ATTACH]



[ATTACH=full]83990[/ATTACH]


The individual who inflicted the most damage and another who inflicted a lesser amount both receive a reward. Conversely, those who did not contribute to any damage do not receive any reward. This system operates on a straightforward basis. I hope you found this explanation satisfactory. :)


data/scripts.

[CODE=lua]-- Define a table listing the bosses and their respective properties

local bossesList = {

    {

        name = "Orshabaal",

        storage = 6655,

        expirationTime = 7 * 24 * 60 * 60, -- 7 days

        loot = {

            {item = 2160, count = 5, chance = 100000}, -- 100% chance

            {item = 2494, count = 1, chance = 50000}, -- 50% chance

        },

        rewardChestId = 21584, -- Reward chest ID

        depotId = 1, -- Depot ID of the main city where the items will be sent

    },

    {

        name = "Cave Rat",

        storage = 6656,

        expirationTime = 7 * 24 * 60 * 60,

        loot = {

            {item = 2160, count = 10, chance = 100000}, -- 100% chance

            {item = 2498, count = 1, chance = 75000}, -- 75% chance

        },

        rewardChestId = 21584, -- Reward chest ID

        depotId = 1, -- Depot ID of the main city where the items will be sent

    },

    -- Add more bosses as needed

}


local ACTION_ID = 2550 -- You need to open the RME Editor and set it to 2550, then save.


local STORAGE_KEYS = {

    bossData = "boss_data"

}


-- Function to check if a reward has expired

local function hasRewardExpired(player, storageKey)

    local expirationTime = player:getStorageValue(storageKey)

    return expirationTime ~= -1 and expirationTime <= os.time()

end


local creatureEvent = CreatureEvent("BossDeath")


function creatureEvent.onDeath(creature, corpse, killer, mostDamageKiller)

    if killer and killer:isPlayer() then

        local creatureName = creature:getName():lower()

        for _, boss in ipairs(bossesList) do

            if creatureName == boss.name:lower() then

                -- Set reward data for the killer

                killer:setStorageValue(boss.storage, 1)

                local expirationTime = os.time() + boss.expirationTime

                killer:setStorageValue(STORAGE_KEYS.bossData, expirationTime)

                local message = "You contributed to defeating " .. boss.name .. ". Now go to the chest to claim your reward! Expiration time: " .. os.date("%c", expirationTime)

                killer:sendTextMessage(MESSAGE_EVENT_ADVANCE, message)


                -- Check if there's a most damage killer

                if mostDamageKiller and mostDamageKiller:isPlayer() and mostDamageKiller:getId() ~= killer:getId() then

                    mostDamageKiller:setStorageValue(boss.storage, 1)

                    mostDamageKiller:setStorageValue(STORAGE_KEYS.bossData, expirationTime)

                    local messageMostDamage = "You dealt the most damage to " .. boss.name .. ". Now go to the chest to claim your reward! Expiration time: " .. os.date("%c", expirationTime)

                    mostDamageKiller:sendTextMessage(MESSAGE_EVENT_ADVANCE, messageMostDamage)

                end

                break

            end

        end

    end

end


creatureEvent:register()


-- Function to send reward message to player

local function sendRewardMessage(player, bossName, receivedItems)

    if #receivedItems > 0 then

        local message = "From " .. bossName .. ": " .. table.concat(receivedItems, ", ")

        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message)

        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your reward has been sent to your depot.")

    else

        local message = "From " .. bossName .. ": Unfortunately, you did not receive any items."

        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message)

    end

end


local rewardAction = Action()


function rewardAction.onUse(player, item, fromPosition, target, toPosition, isHotkey)

    if not player or not player:isPlayer() or not item then

        return false

    end


    local rewardsClaimed = false

    for _, boss in ipairs(bossesList) do

        if item:getId() == boss.rewardChestId and player:getStorageValue(boss.storage) == 1 then

            local storageKey = STORAGE_KEYS.bossData

            if hasRewardExpired(player, storageKey) then

                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your reward from " .. boss.name .. " has expired.")

            else

                local depot = player:getDepotChest(boss.depotId, true)

                if not depot then

                    return false

                end


                local bag = depot:addItem(7343, 1)


                if not bag then

                   print("Failed to add the reward bag to the player's depot.")

                    return false

                end


                local receivedItems = {}

                for _, lootItem in ipairs(boss.loot) do

                    if math.random(100000) <= lootItem.chance then

                        local itemAdded = bag:addItem(lootItem.item, lootItem.count or 1)

                        if itemAdded then

                            local itemName = ItemType(lootItem.item):getPluralName() or ItemType(lootItem.item):getName()

                            table.insert(receivedItems, (lootItem.count or 1) .. "x " .. itemName)

                        end

                    end

                end


                if #receivedItems > 0 then

                    sendRewardMessage(player, boss.name, receivedItems)

                    player:setStorageValue(boss.storage, 0)

                    player:setStorageValue(storageKey, -1)

                    rewardsClaimed = true

                else

                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You did not receive any items from " .. boss.name .. ".")

                end

            end

        end

    end


    if not rewardsClaimed then

        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to defeat the corresponding boss first to receive the reward.")

        return false

    end


    return true

end


rewardAction:aid(ACTION_ID)

rewardAction:register()

[/CODE]


Back
Top