# Util Creating Structures that rotate depending on the Player's direction

Discussion in 'Resources' started by BlackKnight625, Jun 18, 2015.

?

## So, what do you think?

100.0%

0 vote(s)
0.0%
3. ### That wasn't very usefull

0 vote(s)
0.0%
Not open for further replies.
1. Offline

### BlackKnight625

Hello, I'm BlackKnight625 and yesterday and today, I created some methods that will be pretty useful if you want to create a small structure when a Player right clicks a block or something. But as you know, if you use coordinates the structure will face the same direction every time. Well.... not anymore!
So, here's how it works: First, we create a method that will return the direction that a Player is facing.
Code:
```public static String getCardinalDirection(Player player) {
double rotation = (player.getLocation().getYaw() - 90) % 360;
if (rotation < 0) {
rotation += 360.0;
}
if (0 <= rotation && rotation < 45) {
return "W";
} else if (45 <= rotation && rotation < 135) {
return "N";
} else if (135 <= rotation && rotation < 225) {
return "E";
} else if (225 <= rotation && rotation < 315) {
return "S";
} else if (315 <= rotation && rotation < 360) {
return "W";
} else {
return null;
}
}```
If you want to be more precise, then:
Code:
```public static String getAproximateCardinalDirection(Player player) {
double rotation = (player.getLocation().getYaw() - 90) % 360;
if (rotation < 0) {
rotation += 360.0;
}
if (0 <= rotation && rotation < 22.5) {
return "W";
} else if (22.5 <= rotation && rotation < 67.5) {
return "NW";
} else if (67.5 <= rotation && rotation < 112.5) {
return "N";
} else if (112.5 <= rotation && rotation < 157.5) {
return "NE";
} else if (157.5 <= rotation && rotation < 202.5) {
return "E";
} else if (202.5 <= rotation && rotation < 247.5) {
return "SE";
} else if (247.5 <= rotation && rotation < 292.5) {
return "S";
} else if (292.5 <= rotation && rotation < 337.5) {
return "SW";
} else if (337.5 <= rotation && rotation < 360.0) {
return "W";
} else {
return null;
}
}```
(I copied part of this code from the internet, but the following code I made it myself.)

So, now that we have the direction in which the Player is facing, we can generate our own structure with this:
Code:
```//This method is Static because I put it in another Class
public static Block createBlockRelative(Player p, String direction, int x, int y, int z, Material m) {
int xx = p.getLocation().getBlockX();
int yy = p.getLocation().getBlockY();
int zz = p.getLocation().getBlockZ();

Location loc = new Location(p.getWorld(), xx, yy, zz);

if (direction.contains("E")) {
loc.setX(xx + x);
loc.setY(yy + y);
loc.setZ(zz + z);
}
else if (direction.contains("S")) {
loc.setX(xx - z);
loc.setY(yy + y);
loc.setZ(zz + x);
}
else if (direction.contains("W")) {
loc.setX(xx - x);
loc.setY(yy + y);
loc.setZ(zz - z);
}
else if (direction.contains("N")) {
loc.setX(xx + z);
loc.setY(yy + y);
loc.setZ(zz - x);
}

loc.getBlock().setType(m);
return loc.getBlock();
}```
With that method done, we can create a block like this:
Code:
```//This is an example

Player p = e.getPlayer();
String d = getCardinalDirection(p);
//Or
String d = OtherClassName.getCardinalDirection(p);

//Use it like this if you have the createBlockRelative method in another class
OtherClassName.createBlockRelative(p, d, 2, 0, -1, Material.getMaterial(17));

//Use it like this if you have it in the same class
createBlockRelative(p, d, 2, 0, -1, Material.getMaterial(17));
//Or
createBlockRelative(p, d, 2, 0, -1, Material.WOOD);```
Ok, so when we call this method, the first arg is the Player that the Structure will be built relative to him; the second arg is the direction that it will be facing. The 3rd, 4th and 5th args are respectively x, y and z axis (remember: x points forward if you're looking EAST, y points up or down and Z points forward if you're looking SOUTH) and the 6th arg is the Block's Material.

If we want to build a structure with the method I created, I suggest that you first create something like this to help you: http://imgur.com/Ecg3Yi6

The x-axis is pointing EAST, because the coordinates X get positive when heading that direction. Same happens to the coordinate Z, it gets positive when heading SOUTH. That's why I made these arrows: http://imgur.com/lO1Vupe

Now, if we want to create a simple Structure like this: http://imgur.com/9wS6JLr We would have to do something like this:
Code:
```Structure_Generator.createBlockRelative(p, d, 2, 0, -1, Material.WOOD);
Structure_Generator.createBlockRelative(p, d, 3, 0, -1, Material.WOOD);
Structure_Generator.createBlockRelative(p, d, 3, 0, 0, Material.WOOD);
Structure_Generator.createBlockRelative(p, d, 3, 0, 1, Material.WOOD);```
Build your Structure heading East. Then, stand in the blue wool and count the X, Y and Z coordinates relative to you standing in the blue wool and 1 by 1 (block) you'll build your Structure.

Now, if you want that Structure to appear in front of a Player when he right clicks a stick, do the following:
Code:
```@EventHandler
public void whenPlayerRightClicksAStick(PlayerInteractEvent e) {

if (e.getAction().equals(Action.RIGHT_CLICK_AIR)) {
if (e.getPlayer().getItemInHand().getType().equals(Material.STICK)) {

Player p = e.getPlayer();
String d = getCardinalDirection(p);

Structure_Generator.createBlockRelative(p, d, 2, 0, -1, Material.WOOD);
Structure_Generator.createBlockRelative(p, d, 3, 0, -1, Material.WOOD);
Structure_Generator.createBlockRelative(p, d, 3, 0, 0, Material.WOOD);
Structure_Generator.createBlockRelative(p, d, 3, 0, 1, Material.WOOD);
}
}
}```
You may copy the code.
WARNING: This will work on any sticks, do the rest of the verification by yourselfs.

Finally: If you stand in the blue wool and point in any direction, it will build your Structure according to the direction you are facing at. The final result: http://imgur.com/ZHabZ91

So here it is. I'm very proud of my little piece of code and hopefully I will help a lot of people with this.

Have a good day

Don't mind me, just having some fun
http://imgur.com/OmP2pJN
http://imgur.com/JOtKkMf

And once you get used to this, you can create pretty cool stuff!
http://imgur.com/Fz8F3EF

EDIT by Timtower: Don't mind me, just merging some posts

Last edited: Jun 21, 2015
#1
2. Offline

### Totom3

I have a few suggestions:
• Instead of returning and parsing strings, you could use Bukkit's BlockFace enum type. Not only it would be simpler, but also it would be easier to get the relative block, since Block has a "getRelative" method which takes as a parameter a BlockFace.
• To get the direction the player is facing, you could use a RangeMap instead of passing the yaw through multiple if checks.
• Currently, createBlockRelative() does not support the more precise directions, such as NE and SW. Any reasons why not?
• The Y coordinate of the block could be "computed" when creating the location.

#2
3. Offline

### BlackKnight625

1- I prefer using the String, as I will be able to use it for further development.
2- Well, I didn't do that part of the code, I just twicked it a bit.
3- If it did, then the structures that would come out if you pointed any of those directions, they would form in a very weird position. EDIT: for example, if you pointed NE, the wooden L wouldn't be an L anymore... but if you want you can make another method and call it createPreciseBlockRelative(p, d, x, y, z, m), but then you would have to do the maths by yourself.
4- What if you want to build a structure above you? You can compute it anyways and the replace the y arg for the y you want.

#3
4. Offline

### Totom3

I can understand #1 but I still don't get the reason not to use a RangeMap (#2).

#3 is a good reason but in this case you shouldn't bother showing how to make a more precise direction (in getAproximateCardinalDirection()).

What I meant with #4 is that no matter what is the direction the player is facing, you are going to end up with this instruction:
Code:
`loc.setY(yy + y);`
You could just do the addition when creating the location:
Code:
`Location loc =new Location(p.getWorld(), xx, yy + y, zz);`

#4
5. Offline

### BlackKnight625

Ohh well... that's true. If you want, you can edit that if you copy my code.

Well, I made that method in case I'll need it in another situation.

I'm going to be honest: I'm a Java Programming Beginner, I have never heard of RangeMaps before...

#5
6. Offline

#6
7. Offline

#7