package org.mctourney.autoreferee.regions; import java.util.Random; import org.bukkit.Location; import org.bukkit.World; import org.jdom2.Element; import org.mctourney.autoreferee.AutoRefMatch; import org.mctourney.autoreferee.util.LocationUtil; public class CuboidRegion extends AutoRefRegion { public double x1, y1, z1; public double x2, y2, z2; public World world; public CuboidRegion(Location v1, Location v2) { // if the two locations are from different worlds, quit assert v1.getWorld() == v2.getWorld(); world = v1.getWorld(); x1 = Math.min(v1.getX(), v2.getX()); x2 = Math.max(v1.getX(), v2.getX()); y1 = Math.min(v1.getY(), v2.getY()); y2 = Math.max(v1.getY(), v2.getY()); z1 = Math.min(v1.getZ(), v2.getZ()); z2 = Math.max(v1.getZ(), v2.getZ()); } public CuboidRegion(World world, double x1, double x2, double y1, double y2, double z1, double z2) { this.world = world; this.x1 = Math.min(x1, x2); this.x2 = Math.max(x1, x2); this.y1 = Math.min(y1, y2); this.y2 = Math.max(y1, y2); this.z1 = Math.min(z1, z2); this.z2 = Math.max(z1, z2); } public CuboidRegion(AutoRefMatch match, Element elt) { this(match.getWorld(), elt); } public CuboidRegion(World world, Element elt) { this( LocationUtil.fromCoords(world, elt.getAttributeValue("min")), LocationUtil.fromCoords(world, elt.getAttributeValue("max")) ); } public Element toElement() { return this.setRegionSettings(new Element("cuboid") .setAttribute("min", LocationUtil.toBlockCoords(this.getMinimumPoint())) .setAttribute("max", LocationUtil.toBlockCoords(this.getMaximumPoint()))); } @Override public int hashCode() { return getMinimumPoint().hashCode() ^ Integer.rotateLeft(getMaximumPoint().hashCode(), 16); } @Override public boolean equals(Object o) { return (o instanceof CuboidRegion) && hashCode() == o.hashCode(); } @Override public String toString() { return String.format("CUBOID(%s:%s), A=%d", LocationUtil.toBlockCoords(this.getMinimumPoint()), LocationUtil.toBlockCoords(this.getMaximumPoint()), (int)((x2-x1+1) * (y2-y1+1) * (z2-z1+1))); } public Location getMinimumPoint() { return new Location(world, x1, y1, z1); } public Location getMaximumPoint() { return new Location(world, x2, y2, z2); } public static CuboidRegion combine(CuboidRegion a, CuboidRegion b) { assert a.world == b.world; return new CuboidRegion(a.world, Math.min(a.x1, b.x1), Math.max(a.x2, b.x2), Math.min(a.y1, b.y1), Math.max(a.y2, b.y2), Math.min(a.z1, b.z1), Math.max(a.z2, b.z2)); } // distance from region, axially aligned (value less than actual distance, but // appropriate for measurements on cuboid regions) @Override public double distanceToRegion(Location v) { // garbage-in, garbage-out if (v == null || v.getWorld() != world) return Double.POSITIVE_INFINITY; double x = v.getX(), y = v.getY(), z = v.getZ(); Location mx = getMaximumPoint(), mn = getMinimumPoint(); // return maximum distance from this region // (max on all sides, axially-aligned) return CuboidRegion.multimax ( 0 , mn.getX() - x, x - mx.getX() - 1 , mn.getY() - y, y - mx.getY() - 1 , mn.getZ() - z, z - mx.getZ() - 1 ); } @Override public Location getRandomLocation(Random r) { return getMinimumPoint().add( (x2 - x1 + 1) * r.nextDouble(), (y2 - y1 + 1) * r.nextDouble(), (z2 - z1 + 1) * r.nextDouble()); } @Override public CuboidRegion getBoundingCuboid() { return this; } }