This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
DjTranceFire's profile picture

Tables inside tables.

Started by DjTranceFire, 28 January 2015 - 10:37 PM
DjTranceFire #1
Posted 28 January 2015 - 11:37 PM
Hey there.
I'm currently trying to learn all that luaf and CC stuff and therefor i'm trying to create a small program and expand it.
I have done that with AE2 ME and i'm trying to extract items with CC.
Before the latest update everything works fine.

Spoiler

me = peripheral.wrap("bottom")
list = me.getAvailableItems()

for number, item in pairs(list) do
    if item.id == "minecraft:planks" then
        me.exportItem(list[number], 1, 0)
        print("Exported")
    end
end

This was my old code. It was relativly easy after i understood the openp/docs about "exportItems"
After the latest update it broke my code. The item tables changed in a way i do not yet understand.
This was the old table of items inside the ME.
Spoiler


1:
    dmg: 0
    display_name: Mana Bean
    raw_name: item.itemmanabean
    qty: 0
    ench:
    max_size: 64
    name: ItemManaBean
    ore_dict:
    nbt_id: 4b6ccebf85c96dde4d085c3c4f064878
    max_dmg: 0
    id: Thaumcraft:ItemManaBean
    mod_id: Thaumcraft
    is_craftable: true
2:
    display_name: Mana Bean
    qty: 59
    dmg: 0
    max_dmg: 0
    raw_name: item.itemmanabean
    name: ItemManaBean
    id: Thaumcraft:ItemManaBean
    ench:
    ore_dict:
    nbt_id: a48486be825d662a858a1c09ad41a858
    max_size: 64
    mod_id: Thaumcraft
3:
    display_name: Mana Bean
    qty: 59
    dmg: 0
    max_dmg: 0
    raw_name: item.itemmanabean
    name: ItemManaBean
    id: Thaumcraft:ItemManaBean
    ench:
    ore_dict:
    nbt_id: d458a442d7760e5e40c17efc5d7fc9e2
    max_size: 64
    mod_id: Thaumcraft

This is the new table layout

Spoiler

1:
    is_fluid: false
    is_item: true
    size: 59
    fingerprint:
        id: Thaumcraft:ItemManaBean
        dmg: 0
        nbt_hash: 6d1c371dc8953ab3b349d038149fbabf
    is_craftable: true
2:
    is_fluid: false
    is_item: true
    size: 59
    fingerprint:
        id: Thaumcraft:ItemManaBean
        dmg: 0
        nbt_hash: ad5cc1bd74d2230c5c483e4c1bbc7948
    is_craftable: false
3:
    is_fluid: false
    is_item: true
    size: 59
    fingerprint:
        id: Thaumcraft:ItemManaBean
        dmg: 0
        nbt_hash: 18add493aeeb97a3fe71cf8130fe8675
    is_craftable: false

If i now try to print the "nbt_hash" it just prints some empty lines.
I think this is because it uses tables inside of tables if i understand the layout the right way.
I'm new to lua and even newer to all that table stuff. I'm happy enough i know that tables exist.. :D/>

With the old table layout i just had to run this code to print everything:


me = peripheral.wrap("bottom")
liste = me.getAvailableItems()

for nummer, item in pairs(liste) do
	    print(item.id.." "..item.dmg.." "..item.qty.." "..item.nbt_id)
end

But how do i print for example the nbt_hash from the new layout?
How do i use my code to request items with a given nbt_hash?
Sorry for my bad english, i hope its not to hard to understand.
Bomb Bloke #2
Posted 28 January 2015 - 11:43 PM
for number, item in pairs(list) do
            print(item.fingerprint.id.." "..item.fingerprint.dmg.." "..item.fingerprint.nbt_hash)
end

… should do the trick.

I've got a hunch that your requestCrafting issues might now be solved along these lines:

me.requestCrafting(list[number].fingerprint, 1, "test")
DjTranceFire #3
Posted 29 January 2015 - 12:19 AM
for number, item in pairs(list) do
			print(item.fingerprint.id.." "..item.fingerprint.dmg.." "..item.fingerprint.nbt_hash)
end

… should do the trick.

I've got a hunch that your requestCrafting issues might now be solved along these lines:

me.requestCrafting(list[number].fingerprint, 1, "test")

Thank you. Thats working fine! :)/>
And you are right. The requestCrafting issue is solved now.
If i get it right, my code was working but openp wasnt.. :/
Now i just have to rewrite everything to the new way openp works with AE2 and hope they doesnt change it again in the future.

How i only have one more problem.
I want to craft the item if there are not enough items to export. After crafting the items i want to export them.
Crafting with AE2 does take some time so i cant request and instantly request the items.
Because the time depends on the amount of items crafted, i cant just use sleep.

I tried this but its not working. I think its just as wrong as possible.. :D/>

Spoiler

me = peripheral.wrap("bottom")
list = me.getAvailableItems()

itemqty = 12

for number, item in pairs(list) do
    if item.fingerprint.nbt_hash == "6d1c371dc8953ab3b349d038149fbabf" then
        if item.size >= itemqty then
            me.exportItem(list[number].fingerprint, "WEST", itemqty, 0)
            print("Exported")
        else
            itemqty = itemqty - item.size
            me.requestCrafting(list[number].fingerprint, itemqty , "test")
            print("Crafting")
            while item.size < itemqty do
                sleep(0.5)
                print(item.size)
            end
            me.exportItem(list[number].fingerprint, "WEST", itemqty, 0)
            print("Exported")
        end
    end
end

It just prints "0" every time even if the crafting process is done.
The reason is obvious. But i have no real clue how to fix it.. :/
Did i realy have to request the table again and again?
And how would i do this in the easiest way?
Dragon53535 #4
Posted 29 January 2015 - 01:14 AM
You are correct, you would have to update the existing data in such a way that would let you find the correct item you've already used. A method like that could be grabbing the table again, and then saying item = list[number] and see if that works
DjTranceFire #5
Posted 29 January 2015 - 07:51 PM
You are correct, you would have to update the existing data in such a way that would let you find the correct item you've already used. A method like that could be grabbing the table again, and then saying item = list[number] and see if that works

Any examples or ideas about that?
Tryed some methods but without any luck. :(/>
Dragon53535 #6
Posted 29 January 2015 - 09:39 PM

local function findUpdated()
  local newlist = me.getAvailableItems()
  for num,item in pairs(newlist) do
	if item.fingerprint.nbt_hash == "6d1c371dc8953ab3b349d038146fbabf" then
	  return item
	end
  end
end
This would return the correct item in the table. So when updating, you could keep checking and updating.


local newitem = item
while newitem.size &amp;lt; itemqty do
  sleep(0.5)
  newitem = findUpdated()
  print(newitem.size)
end
Your code also says itemqty = itemqty - item.size.
This calculation is incorrect and will lead to inaccuracies. Say item.size is 11, itemqty will now be 1, 11 will never be less than 1. You need to create a new variable to store the amount you need to create, without overriding the amount you want total.
ALSO! list[number] == item. To cut down on your space, replace all list[number]'s with item

Edit: Fixed my errors
Edited on 29 January 2015 - 11:07 PM
DjTranceFire #7
Posted 29 January 2015 - 10:49 PM
So if i have understood everything correctly it should look like this? (Fixed line 9 (= to ==)

Spoiler

me = peripheral.wrap("bottom")
list = me.getAvailableItems()

itemqty = 12

local function findUpdated()
	local newlist = me.getAvailableItems()
	for num,item in pairs(newlist) do
		if item.fingerprint.ntb_hash == "6d1c371dc8953ab3b349d038149fbabf" then
			return item
		end
	end
end

for number, item in pairs(list) do
	if item.fingerprint.nbt_hash == "6d1c371dc8953ab3b349d038149fbabf" then
		if item.size >= itemqty then
			me.exportItem(item.fingerprint, "WEST", itemqty, 0)
			print("Exported "..itemqty.."x "..item.fingerprint.id)
		else
			crafting = itemqty-item.size
			me.requestCrafting(item.fingerprint, crafting, "test")
			print ("Crafting "..crafting.."x "..item.fingerprint.id)
			local newitem = item
			while newitem.size < itemqty do
				sleep(0.5)
				newitem = findUpdated()
				print(newitem.size)
			end
			me.exportItem(item.fingerprint, "WEST", itemqty, 0)
			print("Exported "..itemqty.."x "..item.fingerprint.id)
		end
	end
end


If yes, its not working.


test:28: attempt to index ? (a nil value)

If not, what have i misunderstood?
Edited on 29 January 2015 - 09:50 PM
Dragon53535 #8
Posted 29 January 2015 - 10:54 PM
Make sure that the fingerprint.nbt_hash is the same on the items. Perhaps the nbt_hash is different. because right now it's not finding the correct item.
DjTranceFire #9
Posted 29 January 2015 - 11:13 PM
I checked everything twice and the nbt_hash is correct.
Its exporting the item and it crafts the correct item.
Even while printing these error its crafting the item.
Dragon53535 #10
Posted 29 January 2015 - 11:20 PM
Make sure that the one in the function is correct as well. The error stems from it not finding that nbt_hash

Also, thank you for noticing the messed up comparison ='s
Edited on 29 January 2015 - 10:21 PM
DjTranceFire #11
Posted 29 January 2015 - 11:27 PM
Ah now i finally found the problem.. :D/>


if item.fingerprint.ntb_hash = "6d1c371dc8953ab3b349d038149fbabf" then

This is the code you provided.
And this the correct one.


if item.fingerprint.nbt_hash == "6d1c371dc8953ab3b349d038149fbabf" then

I just saw the missing = but never checked the rest of the function.
ntb | nbt
Its working fine now! :)/>
Thank you all very much!
Its realy nice to see a community helping. Sadly very rare in other communitys.

So for everyone getting here with google or the boardsearch, this is the final working code:

Spoiler

me = peripheral.wrap("bottom")
list = me.getAvailableItems()

itemqty = 12

local function findUpdated()
    local newlist = me.getAvailableItems()
    for num,item in pairs(newlist) do
        if item.fingerprint.nbt_hash == "6d1c371dc8953ab3b349d038149fbabf" then
            return item
        end
    end
end

for number, item in pairs(list) do
    if item.fingerprint.nbt_hash == "6d1c371dc8953ab3b349d038149fbabf" then
        if item.size >= itemqty then
            me.exportItem(item.fingerprint, "WEST", itemqty, 0)
            print("Exported "..itemqty.."x "..item.fingerprint.id)
        else
            crafting = itemqty-item.size
            me.requestCrafting(item.fingerprint, crafting, "test")
            print ("Crafting "..crafting.."x "..item.fingerprint.id)
            local newitem = item
            while newitem.size < itemqty do
                sleep(0.5)
                newitem = findUpdated()
                print(newitem.size)
            end
            me.exportItem(item.fingerprint, "WEST", itemqty, 0)
            print("Exported "..itemqty.."x "..item.fingerprint.id)
        end
    end
end


Now i have to learn everything about tables to use this code for what i realy need.
I realy hope the biggest steps are done! :D/>
Dragon53535 #12
Posted 29 January 2015 - 11:41 PM
Jesus this is not my proudest moment. I had very terrible spelling and code I should probably look harder at it. Thank you for finding that lol.