From fb43712e78ec01441ba5e3d2c8685875fe6f2227 Mon Sep 17 00:00:00 2001 From: lbenav8095 Date: Sat, 18 Nov 2023 22:16:05 -0600 Subject: [PATCH] Adds Cuboid#drawEdges Allows PlayerUtil methods to use transparent set of materials Fixes Structrador simultaneousPlace rotation inside Block consumer --- ci-pom.xml | 2 +- local-pom.xml | 2 +- pom.xml | 2 +- .../us/mytheria/bloblib/entities/Cuboid.java | 25 ++++ .../exception/CardinalDirectionException.java | 25 ++++ .../bloblib/utilities/PlayerUtil.java | 38 ++++- .../bloblib/utilities/Structrador.java | 2 +- .../bloblib/utilities/Vectorator.java | 140 ++++++++++++++++++ 8 files changed, 225 insertions(+), 11 deletions(-) create mode 100644 src/main/java/us/mytheria/bloblib/exception/CardinalDirectionException.java create mode 100644 src/main/java/us/mytheria/bloblib/utilities/Vectorator.java diff --git a/ci-pom.xml b/ci-pom.xml index 98a762d3..db913b85 100644 --- a/ci-pom.xml +++ b/ci-pom.xml @@ -7,7 +7,7 @@ us.mytheria BlobLib - 1.697.25 + 1.697.27 pom.xml bloblib diff --git a/local-pom.xml b/local-pom.xml index 8aaf6d0c..d2e1c67d 100644 --- a/local-pom.xml +++ b/local-pom.xml @@ -5,7 +5,7 @@ us.mytheria BlobLib - 1.697.25 + 1.697.27 pom.xml bloblib diff --git a/pom.xml b/pom.xml index ea2b0e9b..7a702015 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 us.mytheria BlobLib - 1.697.25 + 1.697.27 pom diff --git a/src/main/java/us/mytheria/bloblib/entities/Cuboid.java b/src/main/java/us/mytheria/bloblib/entities/Cuboid.java index 16ffcb77..3a4dc404 100644 --- a/src/main/java/us/mytheria/bloblib/entities/Cuboid.java +++ b/src/main/java/us/mytheria/bloblib/entities/Cuboid.java @@ -238,4 +238,29 @@ public List getFaces() { public Vector getRelative(Location location) { return location.clone().subtract(getPoint1()).toVector(); } + + /** + * Will draw lines between connected edges. + * Each location represents a dot of a dotted line. + * + * @param distance The distance between each particle + * @return The list of locations + */ + public List drawEdges(double distance) { + List result = new ArrayList<>(); + for (double x = xMin; x <= xMax; x += distance) { + for (double y = yMin; y <= yMax; y += distance) { + for (double z = zMin; z <= zMax; z += distance) { + int components = 0; + if (x == xMin || x == xMax) components++; + if (y == yMin || y == yMax) components++; + if (z == zMin || z == zMax) components++; + if (components >= 2) { + result.add(new Location(world, x, y, z)); + } + } + } + } + return result; + } } \ No newline at end of file diff --git a/src/main/java/us/mytheria/bloblib/exception/CardinalDirectionException.java b/src/main/java/us/mytheria/bloblib/exception/CardinalDirectionException.java new file mode 100644 index 00000000..ea879b01 --- /dev/null +++ b/src/main/java/us/mytheria/bloblib/exception/CardinalDirectionException.java @@ -0,0 +1,25 @@ +package us.mytheria.bloblib.exception; + +import java.io.File; + +public class CardinalDirectionException extends RuntimeException { + public CardinalDirectionException(String message) { + super(message); + } + + public CardinalDirectionException(String message, File file) { + this(file == null ? message : message + " \n At: " + file.getPath()); + } + + public CardinalDirectionException(String message, Throwable cause) { + super(message, cause); + } + + public CardinalDirectionException(String message, File file, Throwable cause) { + this(file == null ? message : message + " \n At: " + file.getPath(), cause); + } + + public CardinalDirectionException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/us/mytheria/bloblib/utilities/PlayerUtil.java b/src/main/java/us/mytheria/bloblib/utilities/PlayerUtil.java index 9e5673d4..6c59d3ea 100644 --- a/src/main/java/us/mytheria/bloblib/utilities/PlayerUtil.java +++ b/src/main/java/us/mytheria/bloblib/utilities/PlayerUtil.java @@ -1,5 +1,6 @@ package us.mytheria.bloblib.utilities; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.command.CommandSender; @@ -9,6 +10,7 @@ import java.util.HashMap; import java.util.List; +import java.util.Set; public class PlayerUtil { @@ -62,7 +64,7 @@ public static Block getTargetBlock(Player player, int range) { /** * Gets the block the player is currently targeting. * - * @param player the player's who's targeted block is to be checked. + * @param player the player who's targeted block is to be checked. * @return the targeted block. */ public static Block getTargetBlock(Player player) { @@ -72,29 +74,51 @@ public static Block getTargetBlock(Player player) { /** * Gets the BlockFace of the block the player is currently targeting. * - * @param player the player's who's targeted blocks BlockFace is to be checked. + * @param player the player who's targeted blocks BlockFace is to be checked. + * @param transparent the set of transparent materials to be ignored when checking for the targeted block. * @return the BlockFace of the targeted block, or null if the targeted block is non-occluding. */ - public static BlockFace getBlockFace(Player player) { - List lastTwoTargetBlocks = player.getLastTwoTargetBlocks(null, 100); + public static BlockFace getBlockFace(Player player, @Nullable Set transparent) { + List lastTwoTargetBlocks = player.getLastTwoTargetBlocks(transparent, 100); if (lastTwoTargetBlocks.size() != 2) return null; Block targetBlock = lastTwoTargetBlocks.get(1); Block adjacentBlock = lastTwoTargetBlocks.get(0); return targetBlock.getFace(adjacentBlock); } + /** + * Gets the BlockFace of the block the player is currently targeting. + * + * @param player the player who's targeted blocks BlockFace is to be checked. + * @return the BlockFace of the targeted block, or null if the targeted block is non-occluding. + */ + public static BlockFace getBlockFace(Player player) { + return getBlockFace(player, null); + } + /** * Gets the block adjacent to the block the player is currently targeting. * - * @param player the player's who's targeted block is to be checked. + * @param player the player who's targeted block is to be checked. + * @param transparent the set of transparent materials to be ignored when checking for the targeted block. * @return the adjacent block, or null if the targeted block is non-occluding. */ - public static Block getAdjacentBlock(Player player) { - List lastTwoTargetBlocks = player.getLastTwoTargetBlocks(null, 100); + public static Block getAdjacentBlock(Player player, @Nullable Set transparent) { + List lastTwoTargetBlocks = player.getLastTwoTargetBlocks(transparent, 100); if (lastTwoTargetBlocks.size() != 2 || !lastTwoTargetBlocks.get(1).getType().isSolid()) return null; return lastTwoTargetBlocks.get(0); } + /** + * Gets the block adjacent to the block the player is currently targeting. + * + * @param player the player who's targeted block is to be checked. + * @return the adjacent block, or null if the targeted block is non-occluding. + */ + public static Block getAdjacentBlock(Player player) { + return getAdjacentBlock(player, null); + } + /** * Will break the block and play the sound of the block breaking. * diff --git a/src/main/java/us/mytheria/bloblib/utilities/Structrador.java b/src/main/java/us/mytheria/bloblib/utilities/Structrador.java index 21939c30..a18a8119 100644 --- a/src/main/java/us/mytheria/bloblib/utilities/Structrador.java +++ b/src/main/java/us/mytheria/bloblib/utilities/Structrador.java @@ -187,7 +187,7 @@ public void simultaneousPlace(Location location, boolean includeEntities, int x = state.getX(); int y = state.getY(); int z = state.getZ(); - Block block = location.clone().add(x, y, z).getBlock(); + Block block = location.clone().add(Vectorator.of(x, y, z).rotate(structureRotation)).getBlock(); consumer.accept(block); }); } diff --git a/src/main/java/us/mytheria/bloblib/utilities/Vectorator.java b/src/main/java/us/mytheria/bloblib/utilities/Vectorator.java new file mode 100644 index 00000000..6eeeb2fc --- /dev/null +++ b/src/main/java/us/mytheria/bloblib/utilities/Vectorator.java @@ -0,0 +1,140 @@ +package us.mytheria.bloblib.utilities; + +import org.bukkit.block.BlockFace; +import org.bukkit.block.structure.StructureRotation; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.exception.CardinalDirectionException; + +import java.util.Objects; + +/** + * A decorator for the Vector class + * + * @param vector + */ +public record Vectorator(Vector vector) { + /** + * Creates a new Vectorator from a Vector + * + * @param vector The vector to create the Vectorator from + * @return The new Vectorator + */ + @NotNull + public static Vectorator of(@NotNull Vector vector) { + Objects.requireNonNull(vector); + return new Vectorator(vector); + } + + /** + * Creates a new Vectorator from an x, y, and z coordinate + * + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @return The new Vectorator + */ + @NotNull + public static Vectorator of(int x, int y, int z) { + return new Vectorator(new Vector(x, y, z)); + } + + /** + * Creates a new Vectorator from an x, y, and z coordinate + * + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @return The new Vectorator + */ + @NotNull + public static Vectorator of(double x, double y, double z) { + return new Vectorator(new Vector(x, y, z)); + } + + /** + * Will get the minimum of the two vectors + * + * @param compare The vector to compare to + * @return The minimum of the two vectors + */ + @NotNull + public Vector minimum(Vector compare) { + return Vector.getMinimum(this.vector, compare); + } + + /** + * Will get the maximum of the two vectors + * + * @param compare The vector to compare to + * @return The maximum of the two vectors + */ + @NotNull + public Vector maximum(Vector compare) { + return Vector.getMaximum(this.vector, compare); + } + + /** + * Will rotate the vector by the given degree + * + * @param degree The degree to rotate the vector by + * @return The rotated vector + */ + public Vector rotate(int degree) { + if (degree == 0) + return vector; + return VectorUtil.rotateVector(vector, degree); + } + + /** + * Will rotate the vector by the given BlockFace + * as a cardinal direction. + * + * @param face The BlockFace to rotate the vector by + * @return The rotated vector + */ + public Vector rotate(BlockFace face) { + switch (face) { + case NORTH -> { + return rotate(0); + } + case EAST -> { + return rotate(270); + } + case SOUTH -> { + return rotate(180); + } + case WEST -> { + return rotate(90); + } + default -> { + throw new CardinalDirectionException("The BlockFace '" + face + "' is not a cardinal direction!"); + } + } + } + + /** + * Will rotate the vector by the given StructureRotation + * + * @param rotation The StructureRotation to rotate the vector by + * @return The rotated vector + */ + public Vector rotate(StructureRotation rotation) { + switch (rotation) { + case NONE -> { + return rotate(0); + } + case CLOCKWISE_90 -> { + return rotate(270); + } + case CLOCKWISE_180 -> { + return rotate(180); + } + case COUNTERCLOCKWISE_90 -> { + return rotate(90); + } + default -> + throw new CardinalDirectionException("The StructureRotation '" + rotation + "' is not a cardinal direction!"); + } + } +}