• 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] Simple Autoloot

Jpstafe

Well-Known Member
Joined
Aug 8, 2011
Messages
507
Reaction score
68
Hello otland community, I bring this simple autoloot that worked for me in tfs 1.2 for my 8.0.

Autolot Commands:
XML:
!autoloot add, itemId or name -- Adding a item to the list
!autoloot remove, itemId or name -- Removing a item from the list
!autoloot show -- Show the autoLoot list
!autoloot clear -- Clears the autoLoot list

let's go to :
data/global.lua
we open the file and add at the end:
Lua:
-- AutoLoot config
    AUTO_LOOT_MAX_ITEMS = 5

    -- Reserved storage
    AUTOLOOT_STORAGE_START = 10000
    AUTOLOOT_STORAGE_END = AUTOLOOT_STORAGE_START + AUTO_LOOT_MAX_ITEMS
-- AutoLoot config end

AUTO_LOOT_MAX_ITEMS = 5 is the maximum number of items to collect

in Data/talkactions/talkactions.xml we add:
XML:
<talkaction words="!autoloot" separator=" " script="autoloot.lua"/>


in Data/talkactions/scripts we add a new file and rename it to autoloot.lua and paste this inside
Lua:
function onSay(player, words, param)
    local split = param:split(",")

    local action = split[1]
    if action == "add" then
        local item = split[2]:gsub("%s+", "", 1)
        local itemType = ItemType(item)
        if itemType:getId() == 0 then
            itemType = ItemType(tonumber(item))
            if itemType:getId() == 0 then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is no item with that id or name.")
                return false
            end
        end

        local itemName = tonumber(split[2]) and itemType:getName() or item
        local size = 0
        for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
            local storage = player:getStorageValue(i)
            if size == AUTO_LOOT_MAX_ITEMS then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The list is full, please remove from the list to make some room.")
                break
            end

            if storage == itemType:getId() then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." is already in the list.")
                break
            end

            if storage <= 0 then
                player:setStorageValue(i, itemType:getId())
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." has been added to the list.")
                break
            end

            size = size + 1
        end
    elseif action == "remove" then
        local item = split[2]:gsub("%s+", "", 1)
        local itemType = ItemType(item)
        if itemType:getId() == 0 then
            itemType = ItemType(tonumber(item))
            if itemType:getId() == 0 then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is no item with that id or name.")
                return false
            end
        end

        local itemName = tonumber(split[2]) and itemType:getName() or item
        for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
            if player:getStorageValue(i) == itemType:getId() then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." has been removed from the list.")
                player:setStorageValue(i, 0)
                return false
            end
        end

        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." was not founded in the list.")
    elseif action == "show" then
        local text = "-- Auto Loot List --\n"
        local count = 1
        for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
            local storage = player:getStorageValue(i)
            if storage > 0 then
                text = string.format("%s%d. %s\n", text, count, ItemType(storage):getName())
                count = count + 1
            end
        end

        if text == "" then
            text = "Empty"
        end
 
        player:showTextDialog(1950, text, false)
    elseif action == "clear" then
        for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
            player:setStorageValue(i, 0)
        end

        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The autoloot list has been cleared.")
    else
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Use the commands: !autoloot {add, remove, show, clear}")
    end

    return false
end

Now let's not go:
Data/creaturescripts/creaturescripts.xml
XML:
<event type="kill" name="AutoLoot" script="autoloot.lua" />
in Data/creaturescripts/scripts we copy any file and rename it to autoloot.lua and paste this inside:
Lua:
local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return
    end

    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:isContainer() then
        return
    end

    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        for a = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(a)
            if containerItem then
                for b = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                    if player:getStorageValue(b) == containerItem:getId() then
                        containerItem:moveTo(player)
                    end
                end
            end
        end
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end

    addEvent(scanContainer, 100, player:getId(), target:getPosition())
    return true

and in login.lua we register:
Lua:
player:registerEvent("AutoLoot")

pedrito.png

It worked perfectly for me, the only thing is that when we add the items, it takes it well if you put the id, it doesn't take it if we put the name... if you can solve that, you can publish it here!
I hope it works for you
 
Not too bad. You have an obvious issue though just from a quick glance.

You are using onKill and calling an addEvent to fetch the most top "down" item after 100ms. If there are multiple creatures that die stacked on the same tile, they will all only fetch the freshest corpse on top.

You should run the autoloot via the onDropLoot event callback instead, in which you can directly pass the corpse. Or integrate the autoloot directly in onDropLoot, and save having to add the items into the corpse container in the first place (if they are able to be autolooted)
 
Not too bad. You have an obvious issue though just from a quick glance.

You are using onKill and calling an addEvent to fetch the most top "down" item after 100ms. If there are multiple creatures that die stacked on the same tile, they will all only fetch the freshest corpse on top.

You should run the autoloot via the onDropLoot event callback instead, in which you can directly pass the corpse. Or integrate the autoloot directly in onDropLoot, and save having to add the items into the corpse container in the first place (if they are able to be autolooted)
thanks for giving me this information
 
Back
Top