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

Solved attempt to get length of field 'inside' (a nil value)

Xikini

I whore myself out for likes
Senator
Joined
Nov 17, 2010
Messages
6,832
Solutions
586
Reaction score
5,414
0.3.7

Been wracking my brain for a couple of hours, and still no idea why this is happening.
I can easily get the values if I simply print the exact location, but trying to find the items by going through the loops.. just not working for me.

I've stripped my over-all script down to the bare minimum, so you guys can see what I'm doing..

Generally I'm trying to find the weight of all items , including containers, from inside the table.
I would use this value somewhere else eventually, but that's the jist of it.

For this example it's trying to find the brown backpack, with a green backpack inside, which contains a steel helmet.
Of course, this is useless, but it's just testing the functionality of the script.
Visually, it would look like this.
J2BnYRN.png

Code:
[22:9:51.593] [Error - Action Interface]
[22:9:51.593] data/actions/scripts/aaCarlExampleScripts/easy_chests_test.lua:onUse
[22:9:51.593] Description:
[22:9:51.593] ...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:29: attempt to get length of field 'inside' (a nil value)
[22:9:51.593] stack traceback:
[22:9:51.593]  ...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:29: in function 'getAllItemWeight'
[22:9:51.593]  ...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:47: in function <...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:44>
Code:
local t = {
  [1] = {aid = 45801, use_container = 1, container = 1988, inside = {
      [1] = { use_container = 1, container = 1998, inside = {
         [1] = { item_id = 2457, item_count = 1 },
         [2] = { item_id = 2457, item_count = 1 }
         }
      },
      [2] = { use_container = 0, item_id = 12649, item_count = 1 }
      }
  }
}

local n = 0
local m = 0

function getAllItemWeight(weight)
   local items = {}
   local count = {}
   local weight = 0
   if t[n].use_container == 1 then
     table.insert(items, t[n].container)
     table.insert(count, 1)
   end
   for i = 1, #t[n].inside do
     if t[n].use_container == 1 then
       table.insert(items, t[n].inside[i].container)
       table.insert(count, 1)
       m = i
       for i = 1, #t[n].inside[m].inside do -- line 29
         table.insert(items, t[n].inside[m].inside[i].item_id)
         table.insert(count, t[n].inside[m].inside[i].item_count)
       end
     else
       table.insert(items, t[n].inside[i].item_id)
       table.insert(count, t[n].inside[i].item_count)
     end
   end
   for i = 1, #items do
     weight = (weight + (getItemWeightById(items[i], count[i])))
   end
   return weight
end

function onUse(cid, item, fromPosition, itemEx, toPosition)
   for i = 1, #t do
     n = i
     print(getAllItemWeight(weight))
   end
   return true
end
 
Last edited:
0.3.7

Been wracking my brain for a couple of hours, and still no idea why this is happening.
I can easily get the values if I simply print the exact location, but trying to find the items by going through the loops.. just not working for me.

I've stripped my over-all script down to the bare minimum, so you guys can see what I'm doing..

Generally I'm trying to find the weight of all items , including containers, from inside the table.
I would use this value somewhere else eventually, but that's the jist of it.

For this example it's trying to find the brown backpack, with a green backpack inside, which contains a steel helmet.
Of course, this is useless, but it's just testing the functionality of the script.
Visually, it would look like this.
J2BnYRN.png

Code:
[22:9:51.593] [Error - Action Interface]
[22:9:51.593] data/actions/scripts/aaCarlExampleScripts/easy_chests_test.lua:onUse
[22:9:51.593] Description:
[22:9:51.593] ...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:29: attempt to get length of field 'inside' (a nil value)
[22:9:51.593] stack traceback:
[22:9:51.593]  ...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:29: in function 'getAllItemWeight'
[22:9:51.593]  ...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:47: in function <...ns/scripts/aaCarlExampleScripts/easy_chests_test.lua:44>
Code:
local t = {
  [1] = {aid = 45801, use_container = 1, container = 1988, inside = {
      [1] = { use_container = 1, container = 1998, inside = {
         [1] = { item_id = 2457, item_count = 1 },
         [2] = { item_id = 2457, item_count = 1 }
         }
      },
      [2] = { use_container = 0, item_id = 12649, item_count = 1 }
      }
  }
}

local n = 0
local m = 0

function getAllItemWeight(weight)
   local items = {}
   local count = {}
   local weight = 0
   if t[n].use_container == 1 then
     table.insert(items, t[n].container)
     table.insert(count, 1)
   end
   for i = 1, #t[n].inside do
     if t[n].use_container == 1 then
       table.insert(items, t[n].inside[i].container)
       table.insert(count, 1)
       m = i
       for i = 1, #t[n].inside[m].inside do -- line 29
         table.insert(items, t[n].inside[m].inside[i].item_id)
         table.insert(count, t[n].inside[m].inside[i].item_count)
       end
     else
       table.insert(items, t[n].inside[i].item_id)
       table.insert(count, t[n].inside[i].item_count)
     end
   end
   for i = 1, #items do
     weight = (weight + (getItemWeightById(items[i], count[i])))
   end
   return weight
end

function onUse(cid, item, fromPosition, itemEx, toPosition)
   for i = 1, #t do
     n = i
     print(getAllItemWeight(weight))
   end
   return true
end

Why don't you do it recursively? Look this function I made (TFS 1.2):

Code:
function Container.getItems(self)
   local ret = {}
   local size = self:getSize()
   for i = 0, size-1 do
     local item = self:getItem(i)
     if item:isContainer() then
       local items = Container(item:getUniqueId()):getItems()
       for i = 1, #items do
         table.insert(ret, items[i])
       end
     else
       table.insert(ret, item)
     end
   end
return ret
end

Your function is so stripped and messy its hard to understand but if I got it right you wanna insert the itemid of every item in the table and their count in the other and then get the weights. Here its how you can do:

Code:
t = {
  [1] = {aid = 45801, item_id = 1998, inside = {
      [1] = {item_id = 1998, inside = {
         [1] = { item_id = 2457, item_count = 1 },
         [2] = { item_id = 2457, item_count = 1 }
         }
      },
      [2] = {item_id = 12649, item_count = 1 }
      }
  }
}

function getAllItems(tab)
    local items = {}
    local count = {}
    for i = 1, #tab do
        table.insert(items, tab[i].item_id)
        table.insert(count, tab[i].item_count or 1)
        if tab[i].inside then
            local subitems, subcounts = getAllItems(tab[i].inside)
            for x = 1, #subitems do
                table.insert(items, subitems[x])
                table.insert(count, subcounts[x])
            end
        end
    end
    return items, count
end

function getAllItemsWeight(items, count)
    local weight = 0
    for i = 1, #items do
        weight = (weight + (getItemWeightById(items[i], count[i])))
    end
    return weight
end

local items, count = getAllItems(t)
local weight = getAllItemsWeight(items, count)

You don't need those "container" and "use_container", if the table has inside in it it is because its a container.
 
@MatheusMkalo
You shouldn't alter a script, you should just resolve the issue, the comparison value might be an essential aspect of the script.

That was a free one for you, your welcome :)
 
@Codex NG , @MatheusMkalo
I appreciate the help, as always. :p
But the error was occuring, because of line 25
Code:
if t[n].use_container == 1 then
It was meant to be
Code:
if t[n].inside[i].use_container == 1 then
 
@MatheusMkalo
You shouldn't alter a script, you should just resolve the issue, the comparison value might be an essential aspect of the script.

That was a free one for you, your welcome :)
I shouldn't resolve it, it doesn't work like that. I should fix the flaws in the code. That code was only going to work for 1 backpack inside another one it would not go deeper.
If I was being paid to make this work as it is it would be another story.

Why don't you try to resolve the issue? Then you will see that is not possible because the script is incomplete. I don't wanna play guessing game so no ty.

Code:
function getAllItemWeight(weight)
   local items = {}
   local count = {}
   local weight = 0
   if t[n].use_container == 1 then
     table.insert(items, t[n].container)
     table.insert(count, 1)
   end
   for i = 1, #t[n].inside do
     if t[n].use_container == 1 then
       table.insert(items, t[n].inside[i].container)
       table.insert(count, 1)
       m = i
       for i = 1, #t[n].inside[m].inside do -- line 29
         table.insert(items, t[n].inside[m].inside[i].item_id)
         table.insert(count, t[n].inside[m].inside[i].item_count)
       end
     else
       table.insert(items, t[n].inside[i].item_id)
       table.insert(count, t[n].inside[i].item_count)
     end
   end
   for i = 1, #items do
     weight = (weight + (getItemWeightById(items[i], count[i])))
   end
   return weight
end

n is nil, t is an upvalue, and the whole script is messy.
 
Back
Top