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

Help essentia refill system

Started by it1p, 01 June 2014 - 08:44 AM
it1p #1
Posted 01 June 2014 - 10:44 AM
Hello guys,

I'm sitting in front of my computer for two hours thinking of a solution for this problem, but i can't figure it out.
I am using Direwolf20's essentia refill system, but i have a problem with tables.

In this piece of code i am getting a error:

jars = peripheral.getNames()
function scanEssentia()
  for i,j in ipairs(jars) do
	 if peripheral.getType(j) == "tilejar" then
	   asp = peripheral.call(j, "getAspects")
	   print(asp)
	   countasp = peripheral.call(j, "getAspectCount", asp)
	   if countasp > 0 then
	   essentia[asp] = math.floor(countasp)
	   end
	 end
  end
end

And the error i get is:
aspects:7: Invalid aspect name

I know the problem is the 'asp' thing, because if i print it, i get:
table: 1fabfebc

Can you guys please help me out?

Thanks in advance!
- Tim
Whitecatblack #2
Posted 01 June 2014 - 05:12 PM
Hi Tim,
it1p said:
And the error i get is:
aspects:7: Invalid aspect name'
I am doing a similar project as yours, except I am writing my own code. It is still in progress, but I think I can assist you.

The function peripheral.getAspects(), when the peripheral is an aspect jar, will return a table that looks like this:

{1.0={name=aspectName, quantity=aspectAmount}}
The curly brackets { } indicate a table within its bounds, so anything between an opening curly bracket and a closing curly bracket are part of a table.

So if I were reading a jar with, say, 16 Ignis in it, getAspects() would return:

{1.0={name=Ignis, quantity=16}}

In a table, {key=value} is the format entries are presented in. (key) can be a number or a string and (value) can be a number or a string or a table. To read a table's value spot, I just need to limit what part of the table I want to be shown to me. So, if I had something like this:

Table1 = {toast=bread, cat=animal}
Where I have a table with two entries, separated by a comma. And I wanted to first print the (key) value "toast" and then print what the entry with a (key) value of toast was, I would do:

Table1 = {toast=bread, cat=animal}
print("toast")
print(Table1["toast"])
For printing "toast", I am just printing a string with the word toast. For printing "bread", I am using square brackets, which specify that I only want to print what the (key) value "toast" of Table1 is equal to, instead of printing the whole table (i.e. even though I am not doing anything with the second table entry {cat=animal}, it will still exist in that table if I wanted to read it). So using this, I can, if needed, access only a certain part of a table without disrupting other parts.

So back to our aspect jar's table. If we look closely, we can see that within this table, there is another table. Well how do we access that inner table? All we have to do to access the inner table is limit what we see to only what the first entry is equal to by using peripheral.getAspects()[1] which will instead output:

{name=Ignis, quantity=16}

Alright, now we have access directly to the inner table, now what? Well, now we can access the individual entries of that inner table by using what we learned earlier:

AspectName = peripheral.getAspects()[1]["name"]
AspectAmount = peripheral.getAspects()[1]["quantity"]
With peripheral being the aspect jar. I have parentheses around "name" and "table" because they are strings. Using this, we now have the variable AspectName = "Ignis" and the variable AspectAmount = 16 to work with.

So with this knowledge hopefully you can figure out how to modify the code to make it function again. If you are having trouble modifying the code to do what I wrote above, or you don't understand something I wrote, feel free to respond. Also, if you have any more problems with this setup in general, again, feel free to respond about it, I am happy to help ^_^/> .

Whitecatblack
Edited on 02 June 2014 - 12:22 AM
it1p #3
Posted 01 June 2014 - 07:10 PM
Hi Whitecatblack,

Thank you for you answer!
But i have a (little) problem: i can't run this code:


asp = j.getAspects()

If i run the code above I get the attempt to call nil error.
but what i can do is:


asp = peripheral.call(j, "getAspects")

How can I do the same thing you did; in a peripheral.call?

Thank you!
- Tim
Whitecatblack #4
Posted 01 June 2014 - 08:43 PM
it1p said:
How can I do the same thing you did; in a peripheral.call?
Alright Tim, it looks like what you are doing is on the right track, based on the lines you are working with here:

asp = peripheral.call(j, "getAspects")
You're so close, just a couple things to format what part of the table you want to see, and you're there! The way peripheral.call() works is like this: It is a way to access a peripheral and get information from it, like peripheral.wrap(); except it isn't permanent access to the peripheral, like peripheral.wrap() is, because you will have to peripheral.call() every time you want to get information from that peripheral. So peripheral.call has 3 arguments; First is the name of the peripheral you are trying to call. For instance, if I wanted to peripheral.call() a monitor directly touching the top of my computer, the first argument would be "top", because that is how I refer to it. For aspect jars, you find their call name when you connect/disconnect/click on the wired modems, which will tell you it in the chat; and make sure you put quotes around it, because it is a string (i.e. it will be something like "tilejar_38"). Second argument is the function you want to be run on the peripheral, exclude the parentheses or any arguments for that function itself. The third argument is an argument for the function you inputted in the second argument, but in your case, it has no arguments, so you only have to input the first two arguments.

So, to isolate name and quantity, in the table, we are going to isolate the variable asp the same as I showed you in my last post:

asp = peripheral.call(j, "getAspects")[1])
Now, asp is equal to the inner table, instead of the outer table.

If I wanted to only call the peripheral once for both name and quantity, I could do this:

asp = peripheral.call(j, "getAspects")[1])
aspName = asp["name"]
aspAmount = asp["quantity"]
Or, if I wanted to fit it into two variables only:

aspName = peripheral.call(j, "getAspects")[1]["name"])
aspAmount = peripheral.call(j, "getAspects")[1]["quantity"])
Both of these work, and they will both output aspName = name of the aspect in the jar, aspAmount = amount of aspect in the jar.

Questions?

Whitecatblack
Edited on 01 June 2014 - 08:42 PM
it1p #5
Posted 02 June 2014 - 07:05 AM
Hello Whitecatblack!

Thanks a lot, it works now!
You saved me a lot of time :)/>

Thanks again,
Tim
Whitecatblack #6
Posted 02 June 2014 - 04:20 PM
No problem Tim, happy to help. As I said earlier, feel free to post any more issues you might have.

Whitecatblack
GamerNebulae #7
Posted 02 June 2014 - 06:09 PM
This code looks very familiar… I tried updating my code (program is called Computed Magic here in the programs section) to the version of OpenPeriperals as you are using. This is just a little warning. If you start using Logistics Pipes with this, there is a bug in v0.3.3 of OpenPeripherals where the LogisticsPipes aren't interpreted as they should be and their functions are not there unless you list them on a blacklist. If you are trying to gather the information and write it on a monitor for instance, this version is way better.
Edited on 02 June 2014 - 04:09 PM
Whitecatblack #8
Posted 02 June 2014 - 06:23 PM
GamerNebulae said:
This is just a little warning. If you start using Logistics Pipes with this (…)

I decided to challenge myself to not use logistics pipes for this project, to make it a bit harder. But yea, your comment is probably relevant anyway for other people working through similar projects.

Whitecatblack
GamerNebulae #9
Posted 02 June 2014 - 08:31 PM
I decided to challenge myself to not use logistics pipes for this project, to make it a bit harder. But yea, your comment is probably relevant anyway for other people working through similar projects.

Whitecatblack

How would you do it then? As far as my knowledge goes, it's only possible for LogisticsPipes to get an item by its specific NBT data…
Whitecatblack #10
Posted 02 June 2014 - 08:56 PM
GamerNebulae said:
(..) it's only possible for LogisticsPipes to get an item by its specific NBT data…
Correct, there is currently no other method besides logistics pipes that are able to call an item based on NBT data. I can do a full explanation of how my system works, and even beyond that, how the the code works to do it all, if you want, but the trick is: the TT(Thaumic Tinkerer) Aspectualizer. I have a brief overview of what I expect of my system here in a related thread if you are interested.

Whitecatblack
Edited on 02 June 2014 - 06:56 PM