diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java b/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java index 6aee998..20c201d 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java @@ -731,17 +731,20 @@ public class Claim //not in the same world implies false if (!Objects.equals(location.getWorld(), this.lesserBoundaryCorner.getWorld())) return false; + BoundingBox boundingBox = new BoundingBox(this); int x = location.getBlockX(); int z = location.getBlockZ(); - int y; - if (ignoreHeight) { - y = location.getBlockY(); - } else { - y = getLesserBoundaryCorner().getBlockY(); - } - //main check - if (!new BoundingBox(this).contains(x, y, z)) return false; + // If we're ignoring height, use 2D containment check. + if (ignoreHeight && !boundingBox.contains2d(x, z)) + { + return false; + } + // Otherwise use full containment check. + else if (!ignoreHeight && !boundingBox.contains(x, location.getBlockY(), z)) + { + return false; + } //additional check for subdivisions //you're only in a subdivision when you're also in its parent claim diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/util/BoundingBox.java b/src/main/java/me/ryanhamshire/GriefPrevention/util/BoundingBox.java index c4a0794..501cd35 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/util/BoundingBox.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/util/BoundingBox.java @@ -143,7 +143,7 @@ public class BoundingBox implements Cloneable */ public BoundingBox(Claim claim) { - this(claim.getLesserBoundaryCorner(), claim.getGreaterBoundaryCorner().clone().add(0, 255, 0), false); + this(claim.getLesserBoundaryCorner(), claim.getGreaterBoundaryCorner().clone().add(0, 319, 0), false); } /** @@ -558,6 +558,109 @@ public class BoundingBox implements Cloneable this.maxZ = Math.max(this.maxZ, other.maxZ); } + /** + * Internal containment check ignoring vertical differences. + * + * @param minX the minimum X value to check for containment + * @param minZ the minimum Z value to check for containment + * @param maxX the maximum X value to check for containment + * @param maxZ the maximum X value to check for containment + * @return true if the specified values are inside the bounding box + */ + private boolean contains2dInternal(int minX, int minZ, int maxX, int maxZ) { + return minX >= this.minX && maxX <= this.maxX + && minZ >= this.minZ && maxZ <= this.maxZ; + } + + /** + * Checks if the bounding box contains the position specified. + * + * @param x the X coordinate of the position + * @param z the Z coordinate of the position + * @return true if the specified position is inside the bounding box + */ + public boolean contains2d(int x, int z) + { + return contains2dInternal(x, z, x, z); + } + + /** + * Checks if the bounding box contains the position specified. + * + * @param position the position + * @return true if the specified position is inside the bounding box + */ + public boolean contains2d(Vector position) + { + return contains2d(position.getBlockX(), position.getBlockZ()); + } + + /** + * Checks if the bounding box contains the position specified. + * + * @param position the position + * @return true if the specified position is inside the bounding box + */ + public boolean contains2d(Location position) + { + return contains2d(position.getBlockX(), position.getBlockZ()); + } + + /** + * Checks if the bounding box contains the position specified. + * + * @param position the position + * @return true if the specified position is inside the bounding box + */ + public boolean contains2d(Block position) + { + return contains2d(position.getX(), position.getZ()); + } + + /** + * Checks if the bounding box contains another bounding box consisting of the positions specified. + * + * @param x1 the X coordinate of the first position + * @param z1 the Z coordinate of the first position + * @param x2 the X coordinate of the second position + * @param z2 the Z coordinate of the second position + * @return true if the specified positions are inside the bounding box + */ + public boolean contains2d(int x1, int z1, int x2, int z2) + { + int minX; + int maxX; + if (x1 < x2) { + minX = x1; + maxX = x2; + } else { + minX = x2; + maxX = x1; + } + int minZ; + int maxZ; + if (z1 < z2) { + minZ = z1; + maxZ = z2; + } else { + minZ = z2; + maxZ = z1; + } + + return contains2dInternal(minX, minZ, maxX, maxZ); + } + + /** + * Checks if the bounding box contains another bounding box. + * + * @param other the other bounding box + * @return true if the specified positions are inside the bounding box + */ + public boolean contains2d(BoundingBox other) + { + return contains2dInternal(other.minX, other.minZ, other.maxX, other.maxZ); + } + /** * Internal containment check. * @@ -571,9 +674,8 @@ public class BoundingBox implements Cloneable */ private boolean containsInternal(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - return minX >= this.minX && maxX <= this.maxX - && minY >= this.minY && maxY <= this.maxY - && minZ >= this.minZ && maxZ <= this.maxZ; + return contains2dInternal(minX, minZ, maxX, maxZ) + && minY >= this.minY && maxY <= this.maxY; } /** diff --git a/src/test/java/me/ryanhamshire/GriefPrevention/util/BoundingBoxTest.java b/src/test/java/me/ryanhamshire/GriefPrevention/util/BoundingBoxTest.java index 008d82d..13b89fe 100644 --- a/src/test/java/me/ryanhamshire/GriefPrevention/util/BoundingBoxTest.java +++ b/src/test/java/me/ryanhamshire/GriefPrevention/util/BoundingBoxTest.java @@ -73,7 +73,7 @@ public class BoundingBoxTest assertEquals(boxB, boxA); } } - + private interface TriConsumer { void apply(T t, U u, V v); } @@ -123,7 +123,7 @@ public class BoundingBoxTest assertFalse(boxB.intersects(boxC)); assertFalse(boxC.intersects(boxB)); } - + @Test public void testIntersectCenter() { @@ -162,7 +162,18 @@ public class BoundingBoxTest assertTrue(boxA.intersects(boxC)); assertTrue(boxC.intersects(boxA)); } - + + @Test + void testContainment2d() { + // Vertical + BoundingBox boxA = new BoundingBox(0, 0, 0, 20, 10, 20); + BoundingBox boxB = boxA.clone(); + boxB.move(BlockFace.UP, 20); + + assertFalse(boxA.contains(boxB)); + assertTrue(boxA.contains2d(boxB)); + } + @Test public void testContainment() {