Fix ignoring height (#1260)

This commit is contained in:
Adam 2021-04-07 22:33:44 -04:00 committed by GitHub
parent b3774efad8
commit e6d608bcb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 131 additions and 15 deletions

View File

@ -731,17 +731,20 @@ public class Claim
//not in the same world implies false //not in the same world implies false
if (!Objects.equals(location.getWorld(), this.lesserBoundaryCorner.getWorld())) return false; if (!Objects.equals(location.getWorld(), this.lesserBoundaryCorner.getWorld())) return false;
BoundingBox boundingBox = new BoundingBox(this);
int x = location.getBlockX(); int x = location.getBlockX();
int z = location.getBlockZ(); int z = location.getBlockZ();
int y;
if (ignoreHeight) {
y = location.getBlockY();
} else {
y = getLesserBoundaryCorner().getBlockY();
}
//main check // If we're ignoring height, use 2D containment check.
if (!new BoundingBox(this).contains(x, y, z)) return false; 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 //additional check for subdivisions
//you're only in a subdivision when you're also in its parent claim //you're only in a subdivision when you're also in its parent claim

View File

@ -143,7 +143,7 @@ public class BoundingBox implements Cloneable
*/ */
public BoundingBox(Claim claim) 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); 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. * 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) private boolean containsInternal(int minX, int minY, int minZ, int maxX, int maxY, int maxZ)
{ {
return minX >= this.minX && maxX <= this.maxX return contains2dInternal(minX, minZ, maxX, maxZ)
&& minY >= this.minY && maxY <= this.maxY && minY >= this.minY && maxY <= this.maxY;
&& minZ >= this.minZ && maxZ <= this.maxZ;
} }
/** /**

View File

@ -73,7 +73,7 @@ public class BoundingBoxTest
assertEquals(boxB, boxA); assertEquals(boxB, boxA);
} }
} }
private interface TriConsumer<T, U, V> { private interface TriConsumer<T, U, V> {
void apply(T t, U u, V v); void apply(T t, U u, V v);
} }
@ -123,7 +123,7 @@ public class BoundingBoxTest
assertFalse(boxB.intersects(boxC)); assertFalse(boxB.intersects(boxC));
assertFalse(boxC.intersects(boxB)); assertFalse(boxC.intersects(boxB));
} }
@Test @Test
public void testIntersectCenter() public void testIntersectCenter()
{ {
@ -162,7 +162,18 @@ public class BoundingBoxTest
assertTrue(boxA.intersects(boxC)); assertTrue(boxA.intersects(boxC));
assertTrue(boxC.intersects(boxA)); 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 @Test
public void testContainment() public void testContainment()
{ {