Lua Auto loot collecting item in bag

dervin13

Excellent OT User
Joined
Apr 26, 2008
Messages
432
Reaction score
15
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
 

zxmatzx

Well-Known Member
Joined
Dec 1, 2010
Messages
88
Reaction score
23
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...
 
OP
dervin13

dervin13

Excellent OT User
Joined
Apr 26, 2008
Messages
432
Reaction score
15
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 :(
 

zxmatzx

Well-Known Member
Joined
Dec 1, 2010
Messages
88
Reaction score
23
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:
OP
dervin13

dervin13

Excellent OT User
Joined
Apr 26, 2008
Messages
432
Reaction score
15
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:
OP
dervin13

dervin13

Excellent OT User
Joined
Apr 26, 2008
Messages
432
Reaction score
15
@zxmatzx
Code:
data/creaturescripts/scripts/autoloot.lua:onKill
data/creaturescripts/scripts/autoloot.lua:35: attempt to index local 'corpse' (a
 nil value)
 

zxmatzx

Well-Known Member
Joined
Dec 1, 2010
Messages
88
Reaction score
23
@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:
OP
dervin13

dervin13

Excellent OT User
Joined
Apr 26, 2008
Messages
432
Reaction score
15
Perfect!! thank you so much
 

zxmatzx

Well-Known Member
Joined
Dec 1, 2010
Messages
88
Reaction score
23
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:
Top