3

I built a flat circular plane in minecraft, and am trying to force players to remain within this area. The circle is 161x161 centered around 0, 44, 0. I then placed a command block at the very center, with the command tp @a[rm=80,r=85] 0 45 0. This teleports everyone more than 80 and less than 85 blocks from the command block back to the center of the circle, creating basically a hemisphere (the sphere is cut in half by the circular plane) to move within.

However, I want to instead restrict movement to a cylinder from y=44 to y=infinity. With this method you would only be teleported when your x and z coordinates exceeded the boundary of the 161x161 circle, ignoring your y coordinate. You would be able to stand at the edge of the circle and fly up as high as you wanted without being teleported. This does need to keep the same property of the previous command to not teleport players outside 85 blocks. It will only teleport those who have an x and z change of between 80 and 85 blocks ( 85>sqrt(x²+y²)>80 )

I tried variations of the command involving the dy argument, but this only removed the teleport all together.

Note: If it is not possible to have an infinite height limit, restricting to any value above y=70 would also work. In addition, the ideal minimum of y=44 can be changed, but not increased.

  • First idea: Would a cuboid also be ok? Second idea: Creating a tower of armor stands and selecting everyone in a radius around them. Not very elegant, but could work. Also: Using r/rm and dx/dy/dz together makes it only select the cross section of the two. I'll think more about this in a few hours. – Fabian Röling Aug 9 '17 at 11:29
  • Where do you want to teleport the players to? To a fixed location? That would be easy. Or just as much inwards as needed? That's very complicated. – Fabian Röling Aug 9 '17 at 16:23
2

To expand on Fabian's first solution i bring example of how to implement it.

First of we need to setup a scoreboard objective

/scoreboard objectives add inCylinder dummy inCylinder

By using this command we create a scoreboard objective InCylinder that can hold any number,

Then we summon 1 armor stand with coordinate 0 on y axis, so

/summon armor_stand 413 0 456 {NoGravity:1b}

413 is the x coordinate of the center of the cylinder,

456 is the z coordinate of the center of the cylinder,

0 shouldn't be changed

next step is to summon armor stands recursively above the original armor stand, Backup your world before doing this step

/execute @e[type=armor_stand,c=-1] ~ ~ ~ summon armor_stand ~ ~1 ~ {NoGravity:1b}

you put this in a repeating command block and let it run for ~14 seconds to summon armor stands up to y=256 because you can't build above 256 it would be useless to summon armor stands

now for the actual detecting

execute @e[type=armor_stand] ~ ~ ~ execute @a[r={SPECIFY_RADIUS_HERE}] ~ ~ ~ scoreboard players set @s inCylinder 2

put the above command into a repeating command block, and set it to always active, then connect it to a chain command block (always active)

execute @a ~ ~ ~ scoreboard players remove @s inCylinder 1

then the last chain command block does

execute @a[score_inCylinder=0] ~ ~ ~ {YOUR_COMMAND_HERE}
  • 1
    Very nice usage of c=-1. I don't think the armour stands have to be so close together, it saves quite a bit of performance without reducing accuracy too much to make the distances bigger, for example if they are 10 blocks apart, the innermost part of the border is only 0.16 blocks further in the middle than the outermost part. – Fabian Röling Jun 18 '18 at 18:30
1

I don't think this is exactly possible. The three types of area related target selector arguments are x/y/z, dx/dy/dz and r/rm. x/y/z moves the starting point, dx/dy/dz form a cuboid and r/rm forms a sphere. If you combine the two, you can only select the cross area of the two. This can never form a cylinder.

But you can approximate it. You want to target players flying out anyway, so with the maximum speed in Spectator you won't detect them at exactly the border anyway (because command blocks/functions are restricted to 20/s and you can move up to 4 blocks in that time in Spectator mode. So you don't need to be perfectly exact with it anyway. Here are two solutions for an approximation:

Solution 1, approximating the mantle: You can put armor stands along the center axis of the cylinder (every 10 blocks should be enough), then give every player inside a radius around them a tag and then teleport everyone without the tag. Don't forget to remove the tag from everyone (*) afterwards! This makes your space look a bit like a pyramid cake (without the hole in the middle):

pyramid cake

Solution 2, approximating the area: You can use multiple rectangles to approximate the circle. You can either do it like it's done in limit calculations:

rectangle approximation

or use the rectangles you get here (drag the point), that would probably lower the amount of rectangles you need for the same accuracy. Again, you would tag everyone inside with dx/dy/dz (y=0,dy=256), then teleport everyone without a tag and then remove the tag. This way your area would look like when someone builds a circle in Minecraft out of blocks, but you can choose the resolution.

  • This answer assumes that you already have some knowledge about commands (because your question sounds like it). If you need the exact commands to use, just tell me. – Fabian Röling Aug 9 '17 at 17:26
0

There's a possibility that I didn't even consider before for some reason. It should even work in 1.12.2.

Summon a dummy entity at a known height and the center of the circle.

/summon armor_stand ~ 0 ~ {Marker:1,Invisible:1,NoGravity:1,NoAI:1,Tags:[""]}

Now you can just start the command execution at every player, shift it to the known height of the armour stand, check if the armour stand is in a range and, if necessary, shift the execution position back to the player:

execute at @p positioned ~ 0 ~ if entity @e[type=armor_stand,distance=..10] run <command>

It works just as easily for outside the circle (at least in 1.13+, otherwise you have to use temporary tags):

execute at @p positioned ~ 0 ~ unless entity @e[type=armor_stand,distance=..10] run <command>
-1

A really simple way you could do this without really any commands is with barriers (invisible blocks). I'm not sure this would be the way you would want to do it if you want them to be able to leave this area later but you could just use

/give (username) barrier

to get a barrier and then build them around that area.

  • He mentions flying, so the players are in Creative (or Spectator) mode and barriers don't stop them. – Fabian Röling Jun 18 '18 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.