• 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 Auto loot collecting item in bag

dervin13

Active Member
Joined
Apr 26, 2008
Messages
458
Solutions
1
Reaction score
28
Is it possible to make this autoloot collect the item inside the bag in corpse when you kill it?

thanks

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 i = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(i)
            if containerItem then
                for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                    if player:getStorageValue(i) == 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
end
 
Solution
@zxmatzx no errors, but nothing happens
I tested here and could not figure out what happens. Sometimes he gets the monster's corpse, sometimes not. In the same position.
I have a code that works with the same function Tile (pos):getTopDownItem() and it works perfectly ... I will continue testing.

After some tests, try this one... Can u send a monster that drop itens inside bag?

Lua:
local function scanContainer(cid, container)
    local player = Player(cid)
    if not player then
        return false
    end

    local containerItensCount = container:getItemHoldingCount()
    if containerItensCount <= 0 then
        return true
    end
    for i = 1, containerItensCount do
        local containerItem = container:getItem(i...
Hello,
I can't test now, i just wrote and sending to you.
When i get home, i can test if don't work...

Lua:
local function scanContainer(cid, corpse)
    local player = Player(cid)
    if not player then
        return false
    end
    
    if not corpse or not corpse:isContainer() then
        return false
    end
    
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        local containerItensCount = corpse:getItemHoldingCount()
        if containerItensCount <= 0 then
            return true
        end
        for i = 1, containerItensCount do
            local containerItem = corpse:getItem(i - 1)
            if containerItem then
                if containerItem:isContainer() then
                    scanContainer(cid, containerItem)
                else
                    for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                        if player:getStorageValue(i) == containerItem:getId() then
                            containerItem:moveTo(player) --this works? :o U don't need to pass a Container?
                        end
                    end
                end
            end
        end
    end
end

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

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

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


I would rewrite the code...
 
Hello,
I can't test now, i just wrote and sending to you.
When i get home, i can test if don't work...

Lua:
local function scanContainer(cid, corpse)
    local player = Player(cid)
    if not player then
        return false
    end
   
    if not corpse or not corpse:isContainer() then
        return false
    end
   
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        local containerItensCount = corpse:getItemHoldingCount()
        if containerItensCount <= 0 then
            return true
        end
        for i = 1, containerItensCount do
            local containerItem = corpse:getItem(i - 1)
            if containerItem then
                if containerItem:isContainer() then
                    scanContainer(cid, containerItem)
                else
                    for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                        if player:getStorageValue(i) == containerItem:getId() then
                            containerItem:moveTo(player) --this works? :o U don't need to pass a Container?
                        end
                    end
                end
            end
        end
    end
end

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

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

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


I would rewrite the code...

Nothing happens :(
 
Nothing happens :(
I tested, worked fine here. I would change moveTo function, idk...
Add to you creaturescripts/scripts folder, named as "autoLoot.lua":
Lua:
local function scanContainer(cid, container)
    local player = Player(cid)
    if not player then
        return false
    end

    local containerItensCount = container:getItemHoldingCount()
    if containerItensCount <= 0 then
        return true
    end
    for i = 1, containerItensCount do
        local containerItem = container:getItem(i - 1)
        if containerItem then
            if containerItem:isContainer() then
                scanContainer(cid, containerItem)
            else
                for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                    if player:getStorageValue(i) == containerItem:getId() then
                        containerItem:moveTo(player)
                    end
                end
            end
        end
    end
    return true
end

local function autoLoot(pos, cid)
    local c = Tile(pos):getTopDownItem()
    if c ~= nil then
        if c:isContainer() then
            if c:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then --GOD ACCOUNT DON'T GOT CORPSEOWNER VALUE WHEN KILL A MONSTER
                scanContainer(cid, c)
            end
        end   
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
    
    addEvent(autoLoot, 2, target:getPosition(), player:getId())
    return true
end
Register in creaturescripts.xml:
XML:
<event type="kill" name="autoLoot" script="autoLoot.lua"/>

In you login.lua, above "return true":
Lua:
player:registerEvent("autoLoot")

@dervin13 look now, i can't test atm... sorry
 
Last edited:
I tested, worked fine here. I would change moveTo function, idk...
Add to you creaturescripts/scripts folder, named as "autoLoot.lua":
Lua:
local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return false
    end
 
    local corpse = Tile(position):getTopDownItem()
 
    if not corpse or not corpse:isContainer() then
        return false
    end
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        local containerItensCount = corpse:getItemHoldingCount()
        if containerItensCount <= 0 then
            return true
        end
        for i = 1, containerItensCount do
            local containerItem = corpse:getItem(i - 1)
            if containerItem then
                if containerItem:isContainer() then
                    scanContainer(cid, containerItem)
                else
                    for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                        if player:getStorageValue(i) == containerItem:getId() then
                            containerItem:moveTo(player)
                        end
                    end
                end
            end
        end
    end
end

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

    addEvent(scanContainer, 1000, player:getId(), target:getPosition())
    return true
end
Register in creaturescripts.xml:
XML:
<event type="kill" name="autoLoot" script="autoLoot.lua"/>

In you login.lua, above "return true":
Lua:
player:registerEvent("autoLoot")

Did you check is collecting items inside bag?

also i got this error

Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/creaturescripts/scripts/autoloot.lua:7: attempt to index a nil value
 
Last edited:
@zxmatzx
Code:
data/creaturescripts/scripts/autoloot.lua:onKill
data/creaturescripts/scripts/autoloot.lua:35: attempt to index local 'corpse' (a
 nil value)
 
@zxmatzx no errors, but nothing happens
I tested here and could not figure out what happens. Sometimes he gets the monster's corpse, sometimes not. In the same position.
I have a code that works with the same function Tile (pos):getTopDownItem() and it works perfectly ... I will continue testing.

After some tests, try this one... Can u send a monster that drop itens inside bag?

Lua:
local function scanContainer(cid, container)
    local player = Player(cid)
    if not player then
        return false
    end

    local containerItensCount = container:getItemHoldingCount()
    if containerItensCount <= 0 then
        return true
    end
    for i = 1, containerItensCount do
        local containerItem = container:getItem(i - 1)
        if containerItem then
            if containerItem:isContainer() then
                scanContainer(cid, containerItem)
            else
                for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                    if player:getStorageValue(i) == containerItem:getId() then
                        containerItem:moveTo(player)
                    end
                end
            end
        end
    end
    return true
end

local function autoLoot(pos, cid)
    local c = Tile(pos):getTopDownItem()
    if c ~= nil then
        if c:isContainer() then
            if c:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then --GOD ACCOUNT DON'T GOT CORPSEOWNER VALUE WHEN KILL A MONSTER
                scanContainer(cid, c)
            end
        end   
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
    
    addEvent(autoLoot, 2, target:getPosition(), player:getId())
    return true
end
 
Last edited:
Solution
Edited Code, now fully working.

Lua:
local function scanContainer(cid, container)
    local player = Player(cid)
    if not player then
        return false
    end

    local containerItensCount = container:getItemHoldingCount()
    if containerItensCount <= 0 then
        return true
    end
    local itensToLoot = {}
    for i = 1, containerItensCount do
        local containerItem = container:getItem(i - 1)
        if containerItem then
            if containerItem:isContainer() then
                scanContainer(cid, containerItem)
            else
                for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
                    if player:getStorageValue(i) == containerItem:getId() then
                        local tempItem = {itemId = containerItem:getId(), uid = containerItem.uid, count = containerItem:getCount()}
                        table.insert(itensToLoot, tempItem)
                    end
                end
            end
        end
    end
  
    if #itensToLoot > 0 then
        for i = 1, #itensToLoot do
            Item(itensToLoot[i].uid):remove(-1)
            player:addItem(itensToLoot[i].itemId, itensToLoot[i].count)
        end
    end
    return true
end

local function autoLoot(pos, cid)
    local c = Tile(pos):getTopDownItem()
    if c ~= nil then
        if c:isContainer() then
            if c:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then --GOD ACCOUNT DON'T GOT CORPSEOWNER VALUE WHEN KILL A MONSTER
                scanContainer(cid, c)
            end
        end 
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
  
    addEvent(autoLoot, 2, target:getPosition(), player:getId())
    return true
end
 
Last edited:
Back
Top