Adds some helper functions to make getting direction-related values easier

Adds a function for getting the yaw given two locations
Adds a function for getting a block face given a yaw
This commit is contained in:
Kristian Knarvik 2021-09-11 15:04:55 +02:00
parent 93f8f715e5
commit 87735e4935
4 changed files with 128 additions and 47 deletions

View File

@ -711,7 +711,7 @@ public class Portal {
vehicle.setVelocity(new Vector()); vehicle.setVelocity(new Vector());
//Get new velocity //Get new velocity
Vector newVelocityDirection = getVectorFromYaw(this.getRotation()); Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(this.getRotation());
Vector newVelocity = newVelocityDirection.multiply(velocity); Vector newVelocity = newVelocityDirection.multiply(velocity);
adjustRotation(exit, origin); adjustRotation(exit, origin);
@ -737,30 +737,6 @@ public class Portal {
} }
} }
/**
* Gets a direction vector given a yaw
* @param yaw <p>The yaw to use</p>
* @return <p>The direction vector of the yaw</p>
*/
private Vector getVectorFromYaw(double yaw) {
while (yaw < 0) {
yaw += 360;
}
yaw = yaw % 360;
if (yaw == 0) {
return new Vector(0, 0, 1);
} else if (yaw == 90) {
return new Vector(-1, 0, 0);
} else if (yaw == 180) {
return new Vector(0, 0, -1);
} else if (yaw == 270) {
return new Vector(1, 0, 0);
} else {
throw new IllegalArgumentException("Invalid yaw given");
}
}
/** /**
* Teleport a vehicle which is not a minecart or a boat * Teleport a vehicle which is not a minecart or a boat
* *

View File

@ -5,6 +5,7 @@ import net.knarcraft.stargate.RelativeBlockVector;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.TwoTuple; import net.knarcraft.stargate.TwoTuple;
import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.event.StargateCreateEvent;
import net.knarcraft.stargate.utility.DirectionHelper;
import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EconomyHelper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -17,6 +18,7 @@ import org.bukkit.block.data.Directional;
import org.bukkit.block.data.type.WallSign; import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.util.Vector;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
@ -234,29 +236,16 @@ public class PortalHandler {
Map<PortalOption, Boolean> portalOptions = getPortalOptions(player, destinationName, options); Map<PortalOption, Boolean> portalOptions = getPortalOptions(player, destinationName, options);
// Moved the layout check so as to avoid invalid messages when not making a gate //Get the yaw
int modX = 0; float yaw = DirectionHelper.getYawFromLocationDifference(idParent.getLocation(), id.getLocation());
int modZ = 0;
float yaw = 0f;
BlockFace buttonFacing = BlockFace.DOWN;
if (idParent.getX() > id.getBlock().getX()) { //Get the direction the button should be facing
modZ -= 1; BlockFace buttonFacing = DirectionHelper.getBlockFaceFromYaw(yaw);
yaw = 90f;
buttonFacing = BlockFace.WEST; //Get the x and z modifiers
} else if (idParent.getX() < id.getBlock().getX()) { Vector direction = DirectionHelper.getDirectionVectorFromYaw(yaw);
modZ += 1; int modX = -direction.getBlockZ();
yaw = 270f; int modZ = direction.getBlockX();
buttonFacing = BlockFace.EAST;
} else if (idParent.getZ() > id.getBlock().getZ()) {
modX += 1;
yaw = 180f;
buttonFacing = BlockFace.NORTH;
} else if (idParent.getZ() < id.getBlock().getZ()) {
modX -= 1;
yaw = 0f;
buttonFacing = BlockFace.SOUTH;
}
Gate[] possibleGates = GateHandler.getGatesByControlBlock(idParent); Gate[] possibleGates = GateHandler.getGatesByControlBlock(idParent);
Gate gate = null; Gate gate = null;

View File

@ -3,6 +3,8 @@ package net.knarcraft.stargate.utility;
import net.knarcraft.stargate.BlockLocation; import net.knarcraft.stargate.BlockLocation;
import net.knarcraft.stargate.RelativeBlockVector; import net.knarcraft.stargate.RelativeBlockVector;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.util.Vector;
/** /**
* This class helps with direction-dependent (modX, modZ) calculations * This class helps with direction-dependent (modX, modZ) calculations
@ -13,6 +15,74 @@ public final class DirectionHelper {
} }
/**
* Gets a yaw by comparing two locations
*
* <p>The yaw here is the direction an observer a the first location has to look to face the second location.
* The yaw is only meant to be calculated for locations with equal x or equal z.</p>
*
* @param location1 <p>The first location, which works as the origin</p>
* @param location2 <p>The second location, which the yaw will point at</p>
* @return <p>The yaw</p>
*/
public static float getYawFromLocationDifference(Location location1, Location location2) {
Location difference = location1.clone().subtract(location2.clone());
if (difference.getX() > 0) {
return 90;
} else if (difference.getX() < 0) {
return 270;
} else if (difference.getZ() > 0) {
return 180;
} else if (difference.getZ() < 0) {
return 0;
}
throw new IllegalArgumentException("Locations given are equal or at the same x and y axis");
}
/**
* Gets a block face given a yaw
* @param yaw <p>The yaw to use</p>
* @return <p>The block face the yaw corresponds to</p>
*/
public static BlockFace getBlockFaceFromYaw(double yaw) {
//Make sure the yaw is between 0 and 360
yaw = normalizeYaw(yaw);
if (yaw == 0) {
return BlockFace.SOUTH;
} else if (yaw == 90) {
return BlockFace.WEST;
} else if (yaw == 180) {
return BlockFace.NORTH;
} else if (yaw == 270) {
return BlockFace.EAST;
} else {
throw new IllegalArgumentException("Invalid yaw given");
}
}
/**
* Gets a direction vector given a yaw
* @param yaw <p>The yaw to use</p>
* @return <p>The direction vector of the yaw</p>
*/
public static Vector getDirectionVectorFromYaw(double yaw) {
//Make sure the yaw is between 0 and 360
yaw = normalizeYaw(yaw);
if (yaw == 0) {
return new Vector(0, 0, 1);
} else if (yaw == 90) {
return new Vector(-1, 0, 0);
} else if (yaw == 180) {
return new Vector(0, 0, -1);
} else if (yaw == 270) {
return new Vector(1, 0, 0);
} else {
throw new IllegalArgumentException("Invalid yaw given");
}
}
/** /**
* Gets the block at a relative block vector location * Gets the block at a relative block vector location
* *
@ -38,4 +108,17 @@ public final class DirectionHelper {
return location.add(-right * modX + distance * modZ, depth, -right * modZ + -distance * modX); return location.add(-right * modX + distance * modZ, depth, -right * modZ + -distance * modX);
} }
/**
* Normalizes a yaw to make it positive and no larger than 360 degrees
* @param yaw <p>The yaw to normalize</p>
* @return <p>The normalized yaw</p>
*/
private static double normalizeYaw(double yaw) {
while (yaw < 0) {
yaw += 360;
}
yaw = yaw % 360;
return yaw;
}
} }

View File

@ -0,0 +1,33 @@
package net.knarcraft.stargate.utility;
import be.seeseemelk.mockbukkit.WorldMock;
import org.bukkit.Location;
import org.bukkit.World;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class DirectionHelperTest {
@Test
public void getYawFromLocationTest() {
World world = new WorldMock();
Location location1 = new Location(world, 100, 0, 100);
Location location2 = new Location(world, 100, 0, 101);
double yaw = DirectionHelper.getYawFromLocationDifference(location1, location2);
Assertions.assertEquals(0, yaw);
location2 = new Location(world, 100, 0, 99);
yaw = DirectionHelper.getYawFromLocationDifference(location1, location2);
Assertions.assertEquals(180, yaw);
location2 = new Location(world, 101, 0, 100);
yaw = DirectionHelper.getYawFromLocationDifference(location1, location2);
Assertions.assertEquals(270, yaw);
location2 = new Location(world, 99, 0, 100);
yaw = DirectionHelper.getYawFromLocationDifference(location1, location2);
Assertions.assertEquals(90, yaw);
}
}