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

Auto Loot Tfs 1.3

lico69

New Member
Joined
Mar 11, 2011
Messages
38
Reaction score
1
Hey guys, me again! Im using Printer autoloot - AutoLoot System for tfs 1.x

Im facing some problems, the system works well, but items inside a container (bag or backpack) didnt go for the check. I tried editing the code with some others variables but none made effect. Any tips?

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
 
Solution
Ok, lets see if I got your tip. Can you check?

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)...
Hey guys, me again! Im using Printer autoloot - AutoLoot System for tfs 1.x

Im facing some problems, the system works well, but items inside a container (bag or backpack) didnt go for the check. I tried editing the code with some others variables but none made effect. Any tips?

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

This code here just searches the corpse
Lua:
local containerItem = corpse:getItem(a)
And this code here
Lua:
if player:getStorageValue(b) == containerItem:getId() then

Determines the item to look for, but if the bag or container which contains the items is not listed or at least assigned a storage then its ignored by the script and not moved into the player's bag.
The bad thing would be to automatically assign the container (bag) to the list because then everything in the bag would also be collected. You'll need to account for a container and search through it.

How to resolve?
This whole section of code could be reused again with some modifications, but what I would do is re-write it as a generic function
Lua:
    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

Or you could use this rather from data\actions\lib\actions.lua as an example for a function
Lua:
        if target:isContainer() then
            for i = target:getSize() - 1, 0, -1 do
                local containerItem = target:getItem(i)
                if containerItem then
                    containerItem:moveTo(toPosition)
                end
            end
        end
 
Ok. I got your tip, its fully working, there's some way to optimize it?

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
   
    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 and containerItem:isContainer() then
                for i = containerItem:getSize() - 1, 0, -1 do
                    local containerItem = containerItem:getItem(i)
                    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
    end
   
end
 
Last edited:
Ok, lets see if I got your tip. Can you check?

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
   if containerItem:isContainer() then
    for i = containerItem:getSize() - 1, 0, -1 do
    local bagItem = containerItem:getItem(i)
     if bagItem then
      if player:getStorageValue(b) == bagItem:getId() then
       bagItem:moveTo(player)
      end
     end
    end
   end
        end
    end
end
This won't work at all because you're not following the logic of the script. As I have said many times, scripting or coding in general is not about copy & paste or changing values...

I am not really interested in writing the code for you because you are not going to learn anything that way, so lets break down the logic of the script line by line so that you can see why you need to learn the language.

This particular function scanContainer is only accessible within the curent script because it has been defined as a local function.
It has 2 parameters cid & position, cid should be a number value & position should be a table of x,y,z coordinates
Lua:
local function scanContainer(cid, position)

Once the function is called and a value is passed to the cid parameter it is now known as an argument. This argument is then passed to
Player which based on the information provided by cid may or maynot produce a player userdata
Lua:
    local player = Player(cid)

The if is asking whether player (the condition) has a value if it does then the condition will return true or false however because there
is a not in front of the condition (player) the not takes the return value of true or false returns the opposite.
So if the condition (in this case player) originally return true now it returns false and vice versa.

Essentially if it (the condition) is not a player then execute the next line and return control back to whatever called this function
Lua:
    if not player then
        return
    end

If player is a player continue on and pass the position to Tile and get the top most item (the corpse) at that position
and store that value in corpse (we are expecting userdata)
Lua:
    local corpse = Tile(position):getTopDownItem()

So now this if statement is checking to make sure that corpse contains a value of some sorts, the or logical operator will also check the 2nd condition
which is whether or not corpse is a container
Since both conditions have not in front of them if either of them return a false value the not operator will make that condition true and execute the next
line which will return control back to whatever called it ending the execution of this portion of the script
Lua:
    if not corpse or not corpse:isContainer() then
        return
    end

If all went well this if condition will check if the corpse (userdata) is indeed a valid corpse and if the corpse has a getAttribute flag ITEM_ATTRIBUTE_CORPSEOWNER (ownership) associated
with it that can be compared to the current player (the one who killed it) if both conditions return true then it will proceed forward to the next line of the script
if either return false then the function will end right here and return back to whatever called it. (yes I know there is no return statement)

Return is only used if there is an intended value return or you want to break execution of any following procedure
Lua:
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then

Now we create a for loop using corpse container size since we validated that this userdata is indeed a container.
The iteration won't be starting at 1 instead it will be starting at the max amount of slots this container has - 1
An example is 20 slots, 20 - 1 = 19, so a will hold the initial value of 19 and it will count down to 0 at a step value of -1.. e.g. 19, 18, 17 etc
Lua:
        for a = corpse:getSize() - 1, 0, -1 do

This next line uses the current number stored in a and passes it to corpse:getItem at the corpse's slot index of a and returns the item (userdata)
containerItem
Lua:
            local containerItem = corpse:getItem(a)


This code here checks to see if containerItem holds a value
Lua:
            if containerItem then

This code here takes AUTOLOOT_STORAGE_START as its starting point while storing each iteration original value AUTOLOOT_STORAGE_START
plus 1 into to b until it reaches the value of AUTOLOOT_STORAGE_END
Lua:
                for b = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do

Next this if statement will determine whether the condition its comparison of b being passed to player:getStorageValue if it equals containerItem:getId is true
if its false this part of the script will end right here and control will return back to whatever called this function
Lua:
                    if player:getStorageValue(b) == containerItem:getId() then

If everything went well up to this point then the containerItem (userdata) will execute the method moveTo and give the item to the player
Lua:
                        containerItem:moveTo(player)

Lua:
                    end -- closes the if statement
                end -- closes the for loop
            end -- closes the if statement
        end -- closes the for loop
    end -- closes the if loop
end -- closes the function

Now that you know how this part of the script executes, now you can use logic and determine where to execute code that will allow you to search for additional containers.
 
Last edited:
Solution
This won't work at all because you're not following the logic of the script. As I have said many times, scripting or coding in general is not about copy & paste or changing values...

I am not really interested in writing the code for you because you are not going to learn anything that way, so lets break down the logic of the script line by line so that you can see why you need to learn the language.

This particular function scanContainer is only accessible within the curent script because it has been defined as a local function.
It has 2 parameters cid & position, cid should be a number value & position should be a table of x,y,z coordinates
Lua:
local function scanContainer(cid, position)

Once the function is called and a value is passed to the cid parameter it is now known as an argument. This argument is then passed to
Player which based on the information provided by cid may or maynot produce a player userdata
Lua:
    local player = Player(cid)

The if is asking whether player (the condition) has a value if it does then the condition will return true or false however because there
is a not in front of the condition (player) the not takes the return value of true or false returns the opposite.
So if the condition (in this case player) originally return true now it returns false and vice versa.

Essentially if it (the condition) is not a player then execute the next line and return control back to whatever called this function
Lua:
    if not player then
        return
    end

If player is a player continue on and pass the position to Tile and get the top most item (the corpse) at that position
and store that value in corpse (we are expecting userdata)
Lua:
    local corpse = Tile(position):getTopDownItem()

So now this if statement is checking to make sure that corpse contains a value of some sorts, the or logical operator will also check the 2nd condition
which is whether or not corpse is a container
Since both conditions have not in front of them if either of them return a false value the not operator will make that condition true and execute the next
line which will return control back to whatever called it ending the execution of this portion of the script
Lua:
    if not corpse or not corpse:isContainer() then
        return
    end

If all went well this if condition will check if the corpse (userdata) is indeed a valid corpse and if the corpse has a getAttribute flag ITEM_ATTRIBUTE_CORPSEOWNER (ownership) associated
with it that can be compared to the current player (the one who killed it) if both conditions return true then it will proceed forward to the next line of the script
if either return false then the function will end right here and return back to whatever called it. (yes I know there is no return statement)

Return is only used if there is an intended value return or you want to break execution of any following procedure
Lua:
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then

Now we create a for loop using corpse container size since we validated that this userdata is indeed a container.
The iteration won't be starting at 1 instead it will be starting at the max amount of slots this container has - 1
An example is 20 slots, 20 - 1 = 19, so a will hold the initial value of 19 and it will count down to 0 at a step value of -1.. e.g. 19, 18, 17 etc
Lua:
        for a = corpse:getSize() - 1, 0, -1 do

This next line uses the current number stored in a and passes it to corpse:getItem at the corpse's slot index of a and returns the item (userdata)
containerItem
Lua:
            local containerItem = corpse:getItem(a)


This code here checks to see if containerItem holds a value
Lua:
            if containerItem then

This code here takes AUTOLOOT_STORAGE_START as its starting point while storing each iteration original value AUTOLOOT_STORAGE_START
plus 1 into to b until it reaches the value of AUTOLOOT_STORAGE_END
Lua:
                for b = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do

Next this if statement will determine whether the condition its comparison of b being passed to player:getStorageValue if it equals containerItem:getId is true
if its false this part of the script will end right here and control will return back to whatever called this function
Lua:
                    if player:getStorageValue(b) == containerItem:getId() then

If everything went well up to this point then the containerItem (userdata) will execute the method moveTo and give the item to the player
Lua:
                        containerItem:moveTo(player)

Lua:
                    end -- closes the if statement
                end -- closes the for loop
            end -- closes the if statement
        end -- closes the for loop
    end -- closes the if loop
end -- closes the function

Now that you know how this part of the script executes, now you can use logic and determine where to execute code that will allow you to search for additional containers.

Does it work with TFS 1.1? I'd really like to try this one.
 
Back
Top