Test for approximate rotation
So lets say you have an entity which happens to be of type=Player
.
Such that a command block, when powered
testfor @e[r=15,type=Player] {}
will output true.
Now, lets teleport this player
tp @e[r=15,type=Player] ~ ~ ~ -90 45
They should now be facing due east and at the ground.
Now if I test for this:
testfor @e[r=15,type=Player] {Rotation:[0:-90f,1:45f]}
I'll output true as well.
Now the player turns around. the same command block will now output false (Proving that the command block has successfully tested for a players rotation)
but the rotation is a floating point number, having many decimals of accuracy, and the only way to have it tested and it be true (unless you get realllllly lucky and land on exactly -90.000000000) is to tp the player to have that rotation.
I'd like to be able to test for a player's rotation, but in a natural state.
So the fundamental question is... Can i test for a data tag which is Close to a given value?
Ideally it would look like this:
testfor @e[type=Player,r=15] {Rotation:[0:{min:-45,max:-125}]}
but I know this is wrong. So anyone, has anyone found a solution to testing for approximate data tags?
Solution 1:
Here's a video by MNSweet demonstrating rotational direction detection:
Rather than checking the NBT data (i.e. using {}
), rotation can be tested for using the target selector arguments ry
, rym
, rx
, and rxm
, denoting the maximum and minimum view angle in the horizontal (east, south, etc.) and vertical (up, down) direction, respectively.
For example, to test for someone looking South (=0±22), use
testfor @a[ry=22,rym=-22]
To test for someone looking 45° upwards (±10) and to the northeast (=135±22)
testfor @a[ry=-113,rym=-157,rx=55,rxm=35]
See Commands wiki page for more information.
Solution 2:
I like a function which returns one of the 8 directions. As a standard keypad has 8 directions from the 5 in the middle, and as maps usually show North at the top, I assign 8 to North, 2 to South, 3 to Southeast, etc. BUT, I also like to know if I am looking up or down. If I am looking up, that is a 5 and looking down is 0. That makes it easy to place a block right where I am looking (of course if it is UP you'd want to place it up 2 blocks so you won't clunk your head. /testfor will return a list of targets matching the condition, so check if what returns is the target you are interested in (your player name).
First I check for up/down:
UP /testfor @a[rxm=-90,rx=-66] if true return 5
DN /testfor @a[rxm=66,rx=90] if true return 0
Now do a general check to find out a quadrant using two tests:
/testfor @a[rym=-22.5,ry=157.5]
/testfor @a[rym=-112.5,ry=67.5]
Depending on whether the target was found for both tests:
0 0 89 /testfor @a[rym=-157.5,ry=-112.5] if true return 9 else return 8
0 1 63 /testfor @a[rym=-67.5,ry=-22.5] if true return 3 else return 6
1 0 74 /testfor @a[rym=112.5,ry=157.5] if true return 7 else return 4
1 1 12 /testfor @a[rym=22.5,ry=67.5] if true return 1 else return 2
/testfor with a username and parameters didn't seem to work for me.