Lua Auto loot collecting item in bag

dervin13

Excellent OT User
Joined
Apr 26, 2008
Messages
438
Best answers
1
Reaction score
16
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

Intermediate OT User
Joined
Dec 1, 2010
Messages
150
Best answers
5
Reaction score
37
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
438
Best answers
1
Reaction score
16
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

Intermediate OT User
Joined
Dec 1, 2010
Messages
150
Best answers
5
Reaction score
37
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
438
Best answers
1
Reaction score
16
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
438
Best answers
1
Reaction score
16
@zxmatzx
Code:
data/creaturescripts/scripts/autoloot.lua:onKill
data/creaturescripts/scripts/autoloot.lua:35: attempt to index local 'corpse' (a
 nil value)
 

zxmatzx

Intermediate OT User
Joined
Dec 1, 2010
Messages
150
Best answers
5
Reaction score
37
@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
438
Best answers
1
Reaction score
16
Perfect!! thank you so much
 

zxmatzx

Intermediate OT User
Joined
Dec 1, 2010
Messages
150
Best answers
5
Reaction score
37
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