cc-tweaked / CC-Tweaked

Just another ComputerCraft fork
https://tweaked.cc
928 stars 212 forks source link

Directional block placement by turtles #204

Open StefanJanssen95 opened 5 years ago

StefanJanssen95 commented 5 years ago

I would love to see a way for turtles to have more control over the placement of stairs, torches, logs, chests and other blocks that are influenced by the direction they are placed in.

How the feature/change should work Currently there is some base logic on the way these blocks are placed. Example for slabs: turtle.place() defaults to the bottom placement, turtle.placeUp() defaults to the bottom placement turtle.placeDown() defaults to the top placement. When there is a block below the position the slab will be placed in it, the slab will be placed in the bottom Otherwise when there is a block above the position the slab will be placed in it, the slab will be placed in the top

For stairs it also depends on the surrounding blocks, and maybe the direction of the turtle. In my opinion the way this works is really confusing. My suggestion would be to have the turtle.place*() functions allow for parameters x, y and z. It should default to the way a turtle places at the moment so existing systems won't break down and things won't become more difficult for the beginners.

The effect of x, y and z should be decided by greater than 0, less than 0 and equals 0. How these values should be interpreted is up for discussion (see below)

Some rationale/use case for a feature. Having more control over the placement of blocks we can make turtles build more advanced structures without having to do strange movements, block placing/destroying/placing.

Discussion points: How should the values be interpreted?

StefanJanssen95 commented 5 years ago

How should the values be interpreted? I have multiple ideas about this. It can be both interpreted both relative to the world coordinate system or relative to the turtles direction.

Then it can both be interpreted as look direction or look from direction.

SquidDev commented 5 years ago

So for reference, the current placing algorithm is as follows:

Visual illustration of block placing.

  1. Attempt to place against the block in front.
  2. Attempt to place on the floor (only when doing .place())
  3. Attempt to place against the turtle.

This means you end up with placement logic like so:

Stairs being placed by turtles in the above configurations

Obviously this isn't especially intuitive (though it is fairly predictable once you know the logic).

However, the important thing to note here is that we have to place the block against something, and where that something is dictates which direction the placed block is facing. It's not easy just to say "place this facing in X direction", if there's nothing in X to place against.

One alternative solution, which is what we did for CCTweaks, is to try to rotate the block after placing it. From memory, it worked quite well, though I'm sure there's lots of edge cases under which it'd break.

CodingBenny commented 4 years ago

Obviously this isn't especially intuitive (though it is fairly predictable once you know the logic).

I don't think that many players know that. I would prefer if it was placed against the turtle always. That way you could just approach the block from a different direction without testing if there are any surrounding blocks.

neumond commented 4 years ago

How about single string instead x/y/z? Like top, bottom, front, back, left, right, upper left, upper right, upper front, upper back. Every side is as seen from turtle.

It's not easy just to say "place this facing in X direction", if there's nothing in X to place against

I don't think this is a problem. It would be sufficient to return false, error if a block can't be placed in such direction here. Turtles can even place liquids right in the air.

CodingBenny commented 4 years ago

Would it be possible to pass nbt e.g. "{facing=west}" and set the block like in the setblock command?

SquidDev commented 4 years ago

Would it be possible to pass nbt e.g. "{facing=west}" and set the block like in the setblock command?

Yes and no. So there's a fair few blocks which follow a common interface (i.e extend BlockDirectional, etc...), but there's also many which don't.

For instance, CC's wired modems encode their facing state in a custom enum, which means that we'd have no clue how to rotate it.

Minecraft does have a method to rotate a block, but unfortunately this does mean "rotate by 90 degrees" rather than "face north".

CodingBenny commented 4 years ago

My thought process was: If we can pass parts of the block state to the turtle then the user can see what the facing should be in the f3 screen and hardcode it into the turtle without any need to rotate it.

Or if you want to have a block with the same orientation as another one, you could use the nbt from turtle.inspect().state and turtle.inspect().metadata