Notice to YSPilots/YSFLIGHT

Notice to YSPilots/YSFLIGHT
Legacy Pack available under the YSFLIGHT category.
Any individual requests for a model must be made to my email address, see bottom of the page..

Friday, 5 January 2018

Computer Craft and Tinkers Construct (Minecraft)

I've been experimenting a bit with Tinkers Construct and ComputerCraft in Minecraft.
If you don't know what any of those 3 things are, this post is not for you!

The problem I've been trying to solve is this: I've got masses of molten metal in the smeltery, and I want to automatically drain it into a casting basin. I could do this manually, but I've got a lot of metal!
I should also preface this by saying I know very little about Lua, the programing language of ComputerCraft, possibly hence my difficulty solving the issue.

Now, computercraft interfaces with tinkers by way of the OpenPeripherals mod - which gives access to commands such as getTankInfo().

Through OpenPeripherals, it is possible to talk to the Tinkers Smeltery - by way of the drain port for some reason.

So, this is the setup - I've got a computer next to the drain port
I've not yet implemented the actual triggering of the faucet, for now I'm just trying to read the contents of the tanks!

Now, there were a few examples online where people had done apparently similar things, but I couldn't make them work! So I started from scratch.. more or less.

In the lua commandline I could get"left","getTankInfo")to give me a huge long list of all the tasty goodness I wanted to know from the smeltery, but dropping this into an actual application, along the lines of:

tank = peripheral.wrap("left")

gave me nothing, well, it gave me this: table:4d09e6ec...

So, it must be a table then!

To iterate through a table in lua is 

for key, value in pairs(yourTable) do
   print("here is your key: "..key.." and here is your value          "..value)

So adapting it for my use:

for key, value in pairs(tank.getTankInfo()) do
   print("here is your key: "..key.." and here is your value          "..value)

No. No such luck. Attempt to concatenate string and table... Its got a table, within a table?! What fresh madness is this?! Okay, lets take table 1 from that then! I read that there are 2 tables for each tank, the main tank with all the smeltery contents, and the fuel tank (lava), and the first one is the smeltery contents. So, table 1 it is!

for key, value in pairs(tank.getTankInfo()[1]) do
   print("here is your key: "..key.." and here is your value          "..value)
The [1] bit just lets us take the first key in the table, so the first table of tables, and then iterate through that table.

What did this give us?

here is your key: capacity and here is your value 11792
smeltery:4 attempt to concatenate string and table

WHAT?! again?! A table in a table in a table?! 
So first off, I want an actual object for the table, not tank.getTankInfo()... so I'm just going to have 
tankTable = tank.getTankInfo()[1]

So, this should give us the table for the smeltery contents, and it goes something like:
capacity: 11792
>another table containing who knows what!

Lets go back to the lua commandline again, and do our"left","getTankInfo")again and have a closer look:

The bit at the bottom that I can see reads:

  capacity = 1728,
  contents = {
    rawName = "Molten Lead",
    amount = 1728,
    name = "lead.molten",
    id = 187,
Very annoying that blogger doesn't let me do tabs.. but never mind!
So, this is mirroring what we had been seeing, the first key is "capacity", with its value being whatever the capacity in the smeltery is, then is a table, and thats as far as it let me get before. But now we can see the contents of the table! (appropriately called, contents)

So within the contents table is the name of the material, its capacity (again, mirroring the "capacity key") , another name (lead.molten), and the ID, which I'm assuming is the minecraft item ID (nope, 187 is IC2.blockWall... no idea then!)

Anyway! We know the name of the table in the table now! So I'm going to try and get the contents table out as a separate object again, so I'm just going to go:

tankTable = tank.getTankInfo()[1]
contentsTable = tankTable["contents"]

And now, we iterate through the contents table:

for key, value in pairs(contentsTable) do
   print("here is your key: "..key.." and here is your value          "..value)

What do we get:

here is your key: rawName and here is your value Molten Iron
here is your key: amount and here is your value 1680
here is your key: name and here is your value iron.molten
here is your key: id and here is your value 170

It works!
Interestingly, this is the material at the bottom of the smeltery contents, if I change the material at the bottom to bronze:
raw name becomes "Molten Bronze" - so the first table tank.getTankInfo()[1] is the "active" or bottom material in the smeltery - and if I do tank.getTankInfo()[2] I get the 2nd material! Nothing to do with the fuel tanks!

So, now I've figured out how to get the table in a table in a table, I'm going to use my contentsTable object for now:


What do we get?


Woop woop! it works! I can have that as a variable now, and use that in an if statement to open and close the faucet when there is enough metal to fill a casting basin!
For that I'm going to use a rednet cable just to pass the redstone signal through to the faucet.

  1. local tank = peripheral.wrap("left")
  2. local tankTable = tank.getTankInfo()[1]
  3. local contentsTable = tankTable["contents"]
  4. local quantity = contentsTable["amount"]
  5. while true do
  6.   if quantity > 1296 then
  7.     print(quantity)
  8.     redstone.setOutput("front",true)
  9.     sleep(5)
  10.     redstone.setOutput("front",false)
  11.     print(quantity)
  12.     sleep(5)
  13.   end
  14. end

Ooo, nice code formatting! So this is copied from the pastebin I put up:
The first bit I've explained....
From line 5. I've not explained yet.... while true do just repeats the rest infinitely.

if quantity > 1296 then

What this bit does is:
First: if the quantity value from our table is greater than 1296mB (which is 9 ingots), then it is going to do the rest:
print(quantity) is just going to write the quantity on the screen for me
redstone.setOutput("front",true) - this is where my computer placement kind of screwed up... The rednet cable came out the front... Not so pretty, but it works! So, this basically just outputs a redstone signal fron the front of the computer, if you put redstone dust on the ground, it'll light up. The signal is going through the rednet cable to the faucet, so at this point, it opens the faucet.
sleep(5) - just hang about for a bit while the faucet is doing its thing
redstone.setOutput("front", false) - switch the faucet off again, resetting it for the next load, then it prints the quantity again to the screen (was more for debugging than anything...), hang about for a bit with another sleep(5), and then do it all again!

So yea! It works nicely! Another little thing though - the casting basin normally needs emptying by hand when it's finished casting - but if you put a hopper underneath, it empties itself - put an itemduct under that going into your chest/storage, and

No comments: