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

RevScripts Help with small autoloot

Manuel Audaz

New Member
Joined
Jan 10, 2024
Messages
8
Reaction score
1
This script does not move more than 20 items to the gold pouch. I believe this occurs because the gold pouch is not defined as a container in items.xml. If the gold pouch is the only container with free space inside the main bp, the items will drop into the pouch, but only until 20 items are completed, after that, no items will drop into the pouch. Would anyone know how to solve this problem?

Canary 1332

Lua:
local autoloot = {
    talkaction = "!autoloot",
    storageBase = 70000,
    limit = 20
}

local autolootCache = {}

local function getPlayerLimit(player)
    return player:isPremium() and autoloot.limit or autoloot.limit
end

local function getPlayerAutolootItems(player)
    local limits = getPlayerLimit(player)
    local guid = player:getGuid()
    local itemsCache = autolootCache[guid]
    if itemsCache then
        if #itemsCache > limits then
            local newCache = {unpack(itemsCache, 1, limits)}
            autolootCache[guid] = newCache
            return newCache
        end
        return itemsCache
    end

    local items = {}
    for i = 1, limits do
        local itemType = ItemType(tonumber(player:getStorageValue(autoloot.storageBase + i)) or 0)
        if itemType and itemType:getId() ~= 0 then
            items[#items +1] = itemType:getId()
        end
    end

    autolootCache[guid] = items
    return items
end

local function setPlayerAutolootItems(player, items)
    for i = 1, autoloot.limit do
        local itemId = items[i] or -1
        player:setStorageValue(autoloot.storageBase + i, itemId)
    end
    return true
end

local function addPlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for _, id in pairs(items) do
        if itemId == id then
            return false
        end
    end
    items[#items +1] = itemId
    return setPlayerAutolootItems(player, items)
end

local function removePlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for i, id in pairs(items) do
        if itemId == id then
            table.remove(items, i)
            return setPlayerAutolootItems(player, items)
        end
    end
    return false
end

local function hasPlayerAutolootItem(player, itemId)
    for _, id in pairs(getPlayerAutolootItems(player)) do
        if itemId == id then
            return true
        end
    end
    return false
end

local ec = EventCallback()

function ec.monsterOnDropLoot(monster, corpse)
    if not corpse:getType():isContainer() then
        return
    end

    local corpseOwner = Player(corpse:getCorpseOwner())
    if not corpseOwner then
    return
    end
    local items = corpse:getItems()
    for _, item in pairs(items) do
        if hasPlayerAutolootItem(corpseOwner, item:getId()) then
            if not item:moveTo(corpseOwner) then
                corpseOwner:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have no capacity.")
                break
            end
        end
    end
end

ec:register()

local talkAction = TalkAction(autoloot.talkaction)

function talkAction.onSay(player, words, param, type)
    local split = param:splitTrimmed(",")
    local action = split[1]
    if not action then
        player:showTextDialog(3043, string.format("Examples of use:\n%s add,gold coin\n%s remove,gold coin\n%s clear\n%s show\n\n~Available slots~\nlimit: %d", words, words, words, words, autoloot.limit), false)
        return false
    end

    if action == "clear" then
        autolootCache[player:getGuid()] = {} -- Limpa o cache dos itens do jogador
        setPlayerAutolootItems(player, {}) -- Limpa os itens no storage do jogador
        player:sendCancelMessage("Autoloot list cleared.")
        return false
    elseif action == "show" then
        local items = getPlayerAutolootItems(player)
        local description = {string.format('~ Your autoloot list, capacity: %d/%d ~\n', #items, autoloot.limit)}
        for i, itemId in pairs(items) do
            description[#description +1] = string.format("%d) %s", i, ItemType(itemId):getName())
        end
        player:showTextDialog(3043, table.concat(description, '\n'), false)
        return false
    end

    local function getItemType()
        local itemType = ItemType(split[2])
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(tonumber(split[2]) or 0)
            if not itemType or itemType:getId() == 0 then
                player:sendCancelMessage(string.format("The item %s does not exist!", split[2]))
                return false
            end
        end
        return itemType
    end

    if action == "add" then
        local itemType = getItemType()
        if itemType then
            if #getPlayerAutolootItems(player) >= autoloot.limit then
                player:sendCancelMessage(string.format("Your autoloot only allows you to add %d items.", autoloot.limit))
                return false
            end

            if addPlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("You have added %s to the list.", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s already exists!", itemType:getName()))
            end
        end
        return false
    elseif action == "remove" then
        local itemType = getItemType()
        if itemType then
            if removePlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("You have removed %s from the list.", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s does not exist in the list.", itemType:getName()))
            end
        end
        return false
    end

    return false
end

talkAction:groupType("normal")
talkAction:separator(" ")
talkAction:register()

local creatureEvent = CreatureEvent("autolootCleanCache")

function creatureEvent.onLogout(player)
    local guid = player:getGuid()
    local items = getPlayerAutolootItems(player)
    setPlayerAutolootItems(player, items) -- Atualiza os itens no storage antes do logout
    autolootCache[guid] = nil -- Remove o jogador do cache
    return true
end

creatureEvent:register()
 
Go to data/global.lua

1.Add
Lua:
Storage = {
    autolootBase = 99995, -- Adjust the base value as needed
    autolootGoldActive = 99996, -- Adjust the value as needed
}
Goto data/scripts/create new .lua
2.Go to data/scriptss/autoloot.lua
PASTE

Code:
local autoloot = {
    freeAccountLimit = 10,
    premiumAccountLimit = 20,
}

local autolootCache = {}

local function getPlayerLimit(player)
    if player then
        return player:isPremium() and autoloot.premiumAccountLimit or autoloot.freeAccountLimit
    end
    return false
end

local function getPlayerAutolootItems(player)
    local limits = getPlayerLimit(player)
    if limits then
        local guid = player:getGuid()
        if guid then
            local itemsCache = autolootCache[guid]
            if itemsCache then
                if #itemsCache > limits then
                    local newChache = { unpack(itemsCache, 1, limits) }
                    autolootCache[guid] = newChache
                    return newChache
                end
                return itemsCache
            end

            local items = {}
            for i = 1, limits do
                local itemType = ItemType(math.max(player:getStorageValue(Storage.autolootBase + i)), 0)
                if itemType then
                    if itemType:getId() ~= 0 then
                        items[#items + 1] = itemType:getId()
                    end
                end
            end

            autolootCache[guid] = items
            return items
        end
    end
    return false
end

local function setPlayerAutolootItems(player, items)
    if items then
        local limit = getPlayerLimit(player)
        if limit then
            for i = limit, 1, -1 do
                player:setStorageValue(Storage.autolootBase + i, (items[i] and items[i] or -1))
            end
        end
        return true
    end
    return false
end

local function addPlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    if items then
        for _, id in pairs(items) do
            if itemId == id then
                return false
            end
        end
        items[#items + 1] = itemId
        return setPlayerAutolootItems(player, items)
    end
    return false
end

local function removePlayerAutoAlllootItem(player)
    local items = getPlayerAutolootItems(player)
    if items then
        for i, id in pairs(items) do
            table.remove(items, i)
        end
        return setPlayerAutolootItems(player, items)
    end
    return false
end

local function removePlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    if items then
        for i, id in pairs(items) do
            if itemId == id then
                table.remove(items, i)
                return setPlayerAutolootItems(player, items)
            end
        end
    end
    return false
end

local function hasPlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    if items then
        for _, id in pairs(items) do
            if itemId then
                if itemId == id then
                    return true
                end
            end
        end
    end
    return false
end

local ec = EventCallback

function ec.onDropLoot(monster, corpse)
    if not corpse:getType():isContainer() then
        return
    end

    local corpseOwner = Player(corpse:getCorpseOwner())
    if not corpseOwner then
        return
    end

    local items = corpse:getItems()
    local mType = monster:getType()
    local text = "Autoloot from " .. mType:getNameDescription() .. ":"

    if items then
        for _, item in pairs(items) do
            if item:getId() == 1987 then  -- Zmiana na ID reprezentujące plecak
                local bagItems = item:getItems()
                if bagItems then
                    for _, bagItem in pairs(bagItems) do
                        handleItem(corpseOwner, bagItem, text)
                    end
                end
            else
                handleItem(corpseOwner, item, text)
            end
        end
    end
end

function handleItem(player, item, text)
    local itemId = item:getId()
    local itemAmount = item:getCount()

    if table.contains({ ITEM_GOLD_COIN, ITEM_PLATINUM_COIN, ITEM_CRYSTAL_COIN, 10559 }, itemId) and player:getStorageValue(Storage.autolootGoldAtive) == 1 then
        if itemAmount then
            item:remove(itemAmount)
            local amount = itemAmount
            if itemId == ITEM_PLATINUM_COIN then
                amount = amount * 100
            elseif itemId == ITEM_CRYSTAL_COIN then
                amount = amount * 10000
            elseif itemId == 10559 then
                amount = amount * 1000000
            end
            player:setBankBalance(player:getBankBalance() + amount)
            player:sendTextMessage(MESSAGE_INFO_DESCR, text .. " " .. amount .. " gold " .. (amount > 1 and "coins were transferred" or "coin has been transferred") .. " to your bank account.")
        end
    else
        if hasPlayerAutolootItem(player, itemId) then
            local itemName = itemAmount > 1 and item:getPluralName() or item:getName()
            local itemArticle = item:getArticle() ~= "" and item:getArticle() or "a"
            if not item:moveTo(player) then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "[AUTO LOOT] You don't have capacity.")
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, text .. " " .. (itemAmount > 1 and itemAmount or itemArticle) .. " " .. itemName .. ".")
            end
        end
    end
end

ec:register(3)
local talkAction = TalkAction("!autoloot")

function talkAction.onSay(player, words, param, type)
    local split = param:splitTrimmed(",")
    local action = split[1]
    if not action then
        player:showTextDialog(8977, "[AUTO LOOT] Commands:" .. "\n\n"
            .. "!autoloot clear" .. "\n"
            .. "!autoloot list" .. "\n"
            .. "!autoloot add, itemName" .. "\n"
            .. "!autoloot remove, itemName" .. "\n"
            .. "!autoloot gold" .. "\n\n"
            .. "Number of slots: " .. "\n"
            .. autoloot.freeAccountLimit .. " free account" .. "\n"
            .. autoloot.premiumAccountLimit .. " premium account")
        return false
    end

    if not table.contains({ "clear", "list", "add", "remove", "gold" }, action) then
        player:showTextDialog(8977, "[AUTO LOOT] Commands:" .. "\n\n"
            .. "!autoloot clear" .. "\n"
            .. "!autoloot list" .. "\n"
            .. "!autoloot add, itemName" .. "\n"
            .. "!autoloot remove, itemName" .. "\n"
            .. "!autoloot gold" .. "\n\n"
            .. "Quantidade de slots: " .. "\n"
            .. autoloot.freeAccountLimit .. " free account" .. "\n"
            .. autoloot.premiumAccountLimit .. " premium account")
        return false
    end

    -- !autoloot clear
    if action == "clear" then
        removePlayerAutoAlllootItem(player)
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[AUTO LOOT] Clean autoloot list.")
        return false

        -- !autoloot list
    elseif action == "list" then
        local items = getPlayerAutolootItems(player)
        if items then
            local limit = getPlayerLimit(player)
            if limit then
                local description = { string.format('[AUTO LOOT] Capacity: %d/%d ~\n\nList of items:\n-----------------------------', #items, limit) }
                for i, itemId in pairs(items) do
                    description[#description + 1] = string.format("%d) %s", i, ItemType(itemId):getName())
                end
                player:showTextDialog(8977, table.concat(description, '\n'), false)
            end
        end
        return false
    end

    local function getItemType()
        local itemType = ItemType(split[2])
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(tonumber(split[2]) or 0)
            if not itemType or itemType:getId() == 0 then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("[AUTO LOOT] The item %s does not exist!", split[2]))
                return false
            end
        end
        return itemType
    end

    -- !autoloot add, itemName
    if action == "add" then
        local itemType = getItemType()
        if itemType then
            local limits = getPlayerLimit(player)
            if limits then
                local items = getPlayerAutolootItems(player)
                if items then
                    if #items >= limits then
                        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("[AUTO LOOT] Your autoloot only allows you to add %d items.", limits))
                        return false
                    end

                    if addPlayerAutolootItem(player, itemType:getId()) then
                        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("[AUTO LOOT] Perfect, you added the autoloot list: %s", itemType:getName()))
                    else
                        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("[AUTO LOOT] Item %s is already on the list!", itemType:getName()))
                    end
                end
            end
        end
        return false

        -- !autoloot remove, itemName
    elseif action == "remove" then
        local itemType = getItemType()
        if itemType then
            if removePlayerAutolootItem(player, itemType:getId()) then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("[AUTO LOOT] Perfect, you removed it from the autoloot list: %s", itemType:getName()))
            else
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("[AUTO LOOT] Item %s is not in your list.", itemType:getName()))
            end
        end
        return false

        -- !autoloot gold
    elseif action == "gold" then
        player:setStorageValue(Storage.autolootGoldAtive, player:getStorageValue(Storage.autolootGoldAtive) == 1 and 0 or 1)
        local check = player:getStorageValue(Storage.autolootGoldAtive) == 1 and "activated" or "disabled"
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[AUTO LOOT] You " .. check .. " collecting money by autoloot.")
        return false
    end

    return false
end

talkAction:separator(" ")
talkAction:register()

local creatureEvent = CreatureEvent("autolootCleanCache")

function creatureEvent.onLogout(player)
    if not player:isInEvent("collect gold") then
        local items = getPlayerAutolootItems(player)
        if items then
            setPlayerAutolootItems(player, items)
            autolootCache[player:getGuid()] = nil
        end
    end
    return true
end
 
Thx man. I am having some problems:

Code:
[2024-19-06 02:28:50.208] [error] Lua Script Error Detected
---------------------------------------
Interface: Scripts Interface
Script ID: C:\arquivos ot\reset\clone-best2\data/scripts\talkactions\player\auto
loot.lua
Function: EventCallbackFunctions::luaEventCallbackRegister
Error Description: EventCallback is nil, failed to register script
Stack Trace:
EventCallback is nil, failed to register script
stack traceback:
        [C]: in function 'register'
        ...clone-best2\data/scripts\talkactions\player\autoloot.lua:175: in main
 chunk
---------------------------------------

Code:
[2024-19-06 02:31:14.390] [error] Lua Script Error Detected
---------------------------------------
Interface: Scripts Interface
Script ID: C:\arquivos ot\reset\clone-best2\data/scripts\talkactions\player\auto
loot.lua:callback
Error Description: ...clone-best2\data/scripts\talkactions\player\autoloot.lua:3
2: attempt to perform arithmetic on field 'autolootBase' (a nil value)
stack traceback:
        [C]: in function '__add'
        ...clone-best2\data/scripts\talkactions\player\autoloot.lua:32: in funct
ion 'getPlayerAutolootItems'
        ...clone-best2\data/scripts\talkactions\player\autoloot.lua:215: in func
tion <...clone-best2\data/scripts\talkactions\player\autoloot.lua:178>
---------------------------------------
 
Back
Top