diff --git a/src/main/java/net/knarcraft/stargate/config/Permission.java b/src/main/java/net/knarcraft/stargate/config/Permission.java index 2d3f6c2..fc4e7a2 100644 --- a/src/main/java/net/knarcraft/stargate/config/Permission.java +++ b/src/main/java/net/knarcraft/stargate/config/Permission.java @@ -15,7 +15,7 @@ public enum Permission { SEE_HIDDEN("admin.hidden"), USE_PRIVATE("admin.private"), - + FREE_USAGE("free.use"), FREE_DESTRUCTION("free.destroy"), FREE_CREATION("free.create"), diff --git a/src/main/java/net/knarcraft/stargate/config/formatting/Message.java b/src/main/java/net/knarcraft/stargate/config/formatting/Message.java index aed78c4..28deae4 100644 --- a/src/main/java/net/knarcraft/stargate/config/formatting/Message.java +++ b/src/main/java/net/knarcraft/stargate/config/formatting/Message.java @@ -202,6 +202,11 @@ public enum Message { * The author that created the loaded translation */ AUTHOR("author"), + + /** + * The error message to display when a teleportation fails for whatever reason + */ + TELEPORTATION_FAILED("teleportationFailed"), ; private final String key; diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 9b9f02e..498f3ff 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -1,6 +1,5 @@ package net.knarcraft.stargate.container; -import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,28 +21,6 @@ import org.jetbrains.annotations.Nullable; */ public record RelativeBlockVector(int right, int down, int out) { - /** - * Adds the given value to this relative block vector's "right" property - * - * @param valueToAdd

The value to add

- * @return

The new resulting vector

- */ - @NotNull - public RelativeBlockVector addRight(int valueToAdd) { - return new RelativeBlockVector(this.right + valueToAdd, this.down, this.out); - } - - /** - * Adds the given value to this relative block vector's "down" property - * - * @param valueToAdd

The value to add

- * @return

The new resulting vector

- */ - @NotNull - public RelativeBlockVector addDown(int valueToAdd) { - return new RelativeBlockVector(this.right, this.down + valueToAdd, this.out); - } - /** * Adds the given value to this relative block vector's "out" property * @@ -55,15 +32,6 @@ public record RelativeBlockVector(int right, int down, int out) { return new RelativeBlockVector(this.right, this.down, this.out + valueToAdd); } - /** - * Gets a relative vector in the real space representing this relative block vector - * - * @return

A vector representing this relative block vector

- */ - public Vector toVector() { - return new Vector(this.right, -this.down, this.out); - } - /** * Gets a relative block vector which is this inverted (pointing in the opposite direction) * diff --git a/src/main/java/net/knarcraft/stargate/listener/StargateTeleportListener.java b/src/main/java/net/knarcraft/stargate/listener/StargateTeleportListener.java index d58a3b8..499be26 100644 --- a/src/main/java/net/knarcraft/stargate/listener/StargateTeleportListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/StargateTeleportListener.java @@ -388,6 +388,7 @@ public class StargateTeleportListener implements Listener { */ private void teleportPlayer(@Nullable Entity playerVehicle, @NotNull Player player, @NotNull Portal entrancePortal, @NotNull Portal destination, @NotNull PlayerMoveEvent event) { + boolean success = true; if (playerVehicle instanceof LivingEntity) { //Make sure any horses are properly tamed if (playerVehicle instanceof AbstractHorse horse && !horse.isTamed()) { @@ -399,10 +400,12 @@ public class StargateTeleportListener implements Listener { new VehicleTeleporter(destination, (Vehicle) playerVehicle).teleportEntity(entrancePortal); } else { //Just teleport the player like normal - new PlayerTeleporter(destination, player).teleportPlayer(entrancePortal, event); + success = new PlayerTeleporter(destination, player).teleportPlayer(entrancePortal, event); } - if (!entrancePortal.getOptions().isQuiet()) { + if (success && !entrancePortal.getOptions().isQuiet()) { new SGFormatBuilder(Message.TELEPORTED).success(player); + } else if (!success) { + new SGFormatBuilder(Message.TELEPORTATION_FAILED); } entrancePortal.getPortalOpener().closePortal(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 3a8e2ba..666da46 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -9,8 +9,6 @@ import net.knarcraft.stargate.portal.property.PortalOwner; import net.knarcraft.stargate.portal.property.PortalStrings; import net.knarcraft.stargate.portal.property.PortalStructure; import net.knarcraft.stargate.portal.property.gate.Gate; -import net.knarcraft.stargate.transformation.SimpleVectorOperation; -import net.knarcraft.stargate.utility.DirectionHelper; import net.md_5.bungee.api.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; @@ -28,7 +26,6 @@ public class Portal { private final String cleanName; private final String network; private final String cleanNetwork; - private final SimpleVectorOperation vectorOperation; private final PortalOwner portalOwner; private boolean isRegistered; @@ -64,7 +61,6 @@ public class Portal { this.portalActivator = portalOpener.getPortalActivator(); this.cleanName = cleanString(name); this.cleanNetwork = cleanString(network); - this.vectorOperation = new SimpleVectorOperation(DirectionHelper.getBlockFaceFromYaw(portalLocation.getYaw())); } /** @@ -317,7 +313,7 @@ public class Portal { */ @NotNull public BlockLocation getBlockAt(@NotNull RelativeBlockVector vector) { - return (BlockLocation) getTopLeft().clone().add(vectorOperation.performToRealSpaceOperation(vector.toVector())); + return getTopLeft().getRelativeLocation(vector, this.getYaw()); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index e5bebf9..80a480e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -71,15 +71,18 @@ public class PortalHandler { List destinations = new ArrayList<>(); List portalsInNetwork = PortalRegistry.getNetwork(network); if (portalsInNetwork == null) { + Stargate.debug("PortalHandler::getDestinations", "Portal network " + network + " is null"); return List.of(); } for (String destination : portalsInNetwork) { Portal portal = getByName(destination, network); if (portal == null) { + Stargate.debug("PortalHandler::getDestinations", "Invalid portal with name " + destination); continue; } if (isDestinationAvailable(entrancePortal, portal, player)) { + Stargate.debug("PortalHandler::getDestinations", "Found available destination " + portal.getName()); destinations.add(portal.getName()); } } @@ -120,6 +123,7 @@ public class PortalHandler { //Check if this player can access the destination world if (destinationPortal.getWorld() != null && PermissionHelper.cannotAccessWorld(player, destinationPortal.getWorld().getName())) { + Stargate.debug("PortalHandler::isDestinationAvailable", "Missing permission for destination world"); return false; } //The portal is visible to the player @@ -473,7 +477,8 @@ public class PortalHandler { if (!MaterialHelper.specifiersToMaterials(portal.getGate().getControlBlockMaterials()).contains( block.getType())) { Stargate.debug("PortalHandler::unregisterInvalidPortal", "Control Block Type == " + - block.getType().name()); + block.getType().name() + " at " + control + " real: " + block + " facing " + + portal.getLocation().getYaw()); } } PortalRegistry.unregisterPortal(portal, false); diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java index e34a68c..d743bab 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java @@ -39,7 +39,8 @@ public class PlayerTeleporter extends Teleporter { * @param origin

The portal the player teleports from

* @param event

The player move event triggering the event

*/ - public void teleportPlayer(@NotNull Portal origin, @Nullable PlayerMoveEvent event) { + public boolean teleportPlayer(@NotNull Portal origin, @Nullable PlayerMoveEvent event) { + boolean success = true; double velocity = player.getVelocity().length(); List passengers = player.getPassengers(); @@ -47,7 +48,7 @@ public class PlayerTeleporter extends Teleporter { if (!origin.equals(portal)) { exit = triggerPortalEvent(origin, new StargatePlayerPortalEvent(player, origin, portal, exit)); if (exit == null) { - return; + return false; } } @@ -67,14 +68,16 @@ public class PlayerTeleporter extends Teleporter { //If no event is passed in, assume it's a teleport, and act as such if (event == null) { - player.teleport(exit); + success &= player.teleport(exit); } else { //Set the exit location of the event + success &= !event.isCancelled(); event.setTo(exit); } //Set the velocity of the teleported player after the teleportation is finished Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> player.setVelocity(newVelocity), 1); + return success; } } diff --git a/src/main/java/net/knarcraft/stargate/transformation/SimpleVectorOperation.java b/src/main/java/net/knarcraft/stargate/transformation/SimpleVectorOperation.java deleted file mode 100644 index bc2bcc9..0000000 --- a/src/main/java/net/knarcraft/stargate/transformation/SimpleVectorOperation.java +++ /dev/null @@ -1,185 +0,0 @@ -package net.knarcraft.stargate.transformation; - -import org.bukkit.Axis; -import org.bukkit.block.BlockFace; -import org.bukkit.util.BlockVector; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; -import java.util.Map; - -/** - * A class for performing rotational operations on vectors - * - * @author Kristian Knarvik - */ -@SuppressWarnings("unused") -public class SimpleVectorOperation { - - private static final Map rotationAngles = new HashMap<>(); - private static final Map rotationAxes = new HashMap<>(); - private static final Map normalAxes = new HashMap<>(); - private static final BlockFace defaultDirection = BlockFace.SOUTH; - private static final Axis defaultVerticalAxis = Axis.Y; - - private final Axis normalAxis; - private boolean flipZAxis = false; - private final BlockFace facing; - - /** - * Instantiates a vector operation to rotate vectors in the direction of a sign face - * - * @param signFace

The sign face of a gate's sign

- */ - public SimpleVectorOperation(@NotNull BlockFace signFace) { - if (normalAxes.isEmpty()) { - initializeIrisNormalAxes(); - initializeOperations(); - } - - this.facing = signFace; - this.normalAxis = normalAxes.get(signFace); - } - - /** - * Gets the block face of a sign given upon instantiation - * - * @return

The block face of a sign given upon instantiation

- */ - @NotNull - public BlockFace getFacing() { - return facing; - } - - /** - * Gets the normal axis orthogonal to the opening plane - * - *

Said another way, get the axis going directly towards or away from a stargate's entrance.

- * - * @return

The normal axis orthogonal to the opening plane

- */ - @NotNull - public Axis getNormalAxis() { - return normalAxis; - } - - /** - * Sets whether to flip the Z- axis - * - * @param flipZAxis

Whether to flip the z-axis

- */ - public void setFlipZAxis(boolean flipZAxis) { - this.flipZAxis = flipZAxis; - } - - /** - * Performs an operation from the real space to the vector space - * - * @param vector

The vector to perform the operation on

- * @return vector

A new vector with the operation applied

- */ - @NotNull - public Vector performToAbstractSpaceOperation(@NotNull Vector vector) { - Vector clone = vector.clone(); - clone.rotateAroundAxis(rotationAxes.get(facing), rotationAngles.get(facing)); - if (flipZAxis) { - clone.setZ(-clone.getZ()); - } - return clone; - } - - /** - * Performs an operation from the vector space to the real space - * - * @param vector

The vector to perform the inverse operation on

- * @return vector

A new vector with the operation applied

- */ - @NotNull - public Vector performToRealSpaceOperation(@NotNull Vector vector) { - Vector clone = vector.clone(); - if (flipZAxis) { - clone.setZ(-clone.getZ()); - } - return clone.rotateAroundAxis(rotationAxes.get(facing), -rotationAngles.get(facing)); - } - - /** - * Performs an operation from the vector space to the real space - * - * @param vector

The vector to perform the inverse operation on

- * @return vector

A new vector with the operation applied

- */ - @NotNull - public BlockVector performToRealSpaceOperation(@NotNull BlockVector vector) { - return performToRealSpaceOperation((Vector) vector).toBlockVector(); - } - - /** - * Initializes the operations used for rotating to each block-face - */ - private static void initializeOperations() { - Map axisVectors = new HashMap<>(); - axisVectors.put(Axis.Y, new Vector(0, 1, 0)); - axisVectors.put(Axis.X, new Vector(1, 0, 0)); - axisVectors.put(Axis.Z, new Vector(0, 0, 1)); - - //Use the cross product to find the correct axis - for (BlockFace face : normalAxes.keySet()) { - Vector crossProduct = face.getDirection().crossProduct(defaultDirection.getDirection()); - if (face == defaultDirection || face == defaultDirection.getOppositeFace()) { - rotationAxes.put(face, axisVectors.get(defaultVerticalAxis)); - } else if (Math.abs(crossProduct.getZ()) > 0) { - rotationAxes.put(face, axisVectors.get(Axis.Z)); - } else if (Math.abs(crossProduct.getY()) > 0) { - rotationAxes.put(face, axisVectors.get(Axis.Y)); - } else { - rotationAxes.put(face, axisVectors.get(Axis.X)); - } - } - - calculateRotations(); - } - - /** - * Calculates the required rotations based on the default rotation - */ - private static void calculateRotations() { - double halfRotation = Math.PI; - double quarterRotation = halfRotation / 2; - - Vector defaultDirectionVector = defaultDirection.getDirection(); - boolean defaultDirectionPositive = defaultDirectionVector.getX() + defaultDirectionVector.getY() + - defaultDirectionVector.getZ() > 0; - - for (BlockFace blockFace : normalAxes.keySet()) { - if (defaultDirection == blockFace) { - //The default direction requires no rotation - rotationAngles.put(blockFace, 0d); - } else if (defaultDirection.getOppositeFace() == blockFace) { - //The opposite direction requires a half rotation - rotationAngles.put(blockFace, halfRotation); - } else { - //All the other used directions require a quarter rotation - Vector faceDirectionVector = blockFace.getDirection(); - boolean faceDirectionPositive = faceDirectionVector.getX() + faceDirectionVector.getY() + - faceDirectionVector.getZ() > 0; - double rotation = defaultDirectionPositive && faceDirectionPositive ? quarterRotation : -quarterRotation; - rotationAngles.put(blockFace, rotation); - } - } - } - - /** - * Initializes the iris normal axes corresponding to each block face - */ - private static void initializeIrisNormalAxes() { - normalAxes.put(BlockFace.EAST, Axis.Z); - normalAxes.put(BlockFace.WEST, Axis.Z); - normalAxes.put(BlockFace.NORTH, Axis.X); - normalAxes.put(BlockFace.SOUTH, Axis.X); - normalAxes.put(BlockFace.UP, Axis.Y); - normalAxes.put(BlockFace.DOWN, Axis.Y); - } - -} \ No newline at end of file diff --git a/src/main/resources/lang/en.txt b/src/main/resources/lang/en.txt index 6f00056..200e958 100644 --- a/src/main/resources/lang/en.txt +++ b/src/main/resources/lang/en.txt @@ -38,4 +38,5 @@ signRightClick=Right click signToUse=to use gate teleportMsg=Teleported vaultLoadError=Economy is enabled but Vault could not be loaded. Economy disabled -vaultLoaded=Vault v%version% found \ No newline at end of file +vaultLoaded=Vault v%version% found +teleportationFailed=Teleportation was cancelled or denied \ No newline at end of file diff --git a/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java deleted file mode 100644 index 5406053..0000000 --- a/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.knarcraft.stargate.container; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class RelativeBlockVectorTest { - - @Test - public void addToVectorTest() { - int right = 5; - int down = 5; - int out = 3; - - RelativeBlockVector relativeBlockVector = new RelativeBlockVector(right, down, out); - - for (int i = 0; i < 1000; i++) { - int randomValue = getRandomNumber(); - RelativeBlockVector newVector = relativeBlockVector.addRight(randomValue); - assertEquals(new RelativeBlockVector(right + randomValue, down, out), newVector); - - newVector = relativeBlockVector.addOut(randomValue); - assertEquals(new RelativeBlockVector(right, down, out + randomValue), newVector); - - newVector = relativeBlockVector.addDown(randomValue); - assertEquals(new RelativeBlockVector(right, down + randomValue, out), newVector); - } - } - - @Test - public void invertTest() { - for (int i = 0; i < 1000; i++) { - int randomNumber1 = getRandomNumber(); - int randomNumber2 = getRandomNumber(); - int randomNumber3 = getRandomNumber(); - - RelativeBlockVector relativeBlockVector = new RelativeBlockVector(randomNumber1, randomNumber2, - randomNumber3); - RelativeBlockVector invertedBlockVector = new RelativeBlockVector(-randomNumber1, -randomNumber2, - -randomNumber3); - assertEquals(invertedBlockVector, relativeBlockVector.invert()); - } - } - - /** - * Gets a random number between -500 and 500 - * - * @return

A random number between -500 and 500

- */ - private int getRandomNumber() { - return (int) ((Math.random() - 0.5) * 1000); - } - -}