Skip to content

Instantly share code, notes, and snippets.

@Scarsz
Last active April 29, 2020 00:33
Show Gist options
  • Save Scarsz/31ebbe75e2490d55b46e068a209d8892 to your computer and use it in GitHub Desktop.
Save Scarsz/31ebbe75e2490d55b46e068a209d8892 to your computer and use it in GitHub Desktop.
Class for handling 2D rectangles in Minecraft
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
public class RectangleBound {
@Getter private final World world;
@Getter private final Location locationTopLeft;
@Getter private final Location locationTopRight;
@Getter private final Location locationBottomLeft;
@Getter private final Location locationBottomRight;
public RectangleBound(Location location1, Location location2) {
if (location1.getWorld() == null || !location1.getWorld().equals(location2.getWorld())) throw new IllegalArgumentException("Locations have different worlds");
if (location1.getBlockX() == location2.getBlockX()) throw new IllegalArgumentException("1-dimensional rectangles aren't a thing");
if (location1.getBlockZ() == location2.getBlockZ()) throw new IllegalArgumentException("1-dimensional rectangles aren't a thing");
this.world = location1.getWorld();
location1.setY(1);
location2.setY(1);
Location location3 = new Location(world, location1.getBlockX(), 1, location2.getBlockZ());
Location location4 = new Location(world, location2.getBlockX(), 1, location1.getBlockZ());
Location[] points = Stream.of(location1, location2, location3, location4)
.sorted(Comparator.comparingInt(l -> (l.getBlockX() + l.getBlockZ())))
.toArray(Location[]::new);
int topZ = Stream.of(location1, location2, location3, location4)
.mapToInt(Location::getBlockZ)
.max().getAsInt();
int topX = Stream.of(location1, location2, location3, location4)
.mapToInt(Location::getBlockX)
.max().getAsInt();
locationBottomLeft = points[0];
locationTopRight = points[3];
locationTopLeft = Stream.of(location1, location2, location3, location4)
.filter(location -> location.getBlockZ() == topZ)
.min(Comparator.comparingInt(Location::getBlockX)).get();
locationBottomRight = Stream.of(location1, location2, location3, location4)
.filter(location -> location.getBlockX() == topX)
.min(Comparator.comparingInt(Location::getBlockZ)).get();
}
public boolean isInside(Location location) {
if (location == null || location.getWorld() == null || !location.getWorld().equals(world)) return false;
boolean withinX = (location.getBlockX() >= getLocationTopLeft().getBlockX() && location.getBlockX() <= getLocationBottomRight().getBlockX())
|| (location.getBlockX() <= getLocationTopLeft().getBlockX() && location.getBlockX() >= getLocationBottomRight().getBlockX());
boolean withinY = (location.getBlockZ() >= getLocationTopLeft().getBlockZ() && location.getBlockZ() <= getLocationBottomRight().getBlockZ())
|| (location.getBlockZ() <= getLocationTopLeft().getBlockZ() && location.getBlockZ() >= getLocationBottomRight().getBlockZ());
return withinX && withinY;
}
public Location getTopLeftOutsideCorner() {
return locationTopLeft.clone().add(-1, 0, 1);
}
public Location getTopRightOutsideCorner() {
return locationTopRight.clone().add(1, 0, 1);
}
public Location getBottomLeftOutsideCorner() {
return locationBottomLeft.clone().add(-1, 0, -1);
}
public Location getBottomRightOutsideCorner() {
return locationBottomRight.clone().add(1, 0, -1);
}
public Set<Location> getTopOuterWall() {
Location from = getTopLeftOutsideCorner();
Location to = getTopRightOutsideCorner();
Set<Location> locations = new HashSet<>();
for (int i = 1; i < to.getBlockX() - from.getBlockX(); i++) {
locations.add(from.clone().add(i, 0, 0));
}
return locations;
}
public Set<Location> getBottomOuterWall() {
Location from = getBottomLeftOutsideCorner();
Location to = getBottomRightOutsideCorner();
Set<Location> locations = new HashSet<>();
for (int i = 1; i < to.getBlockX() - from.getBlockX(); i++) {
locations.add(from.clone().add(i, 0, 0));
}
return locations;
}
public Set<Location> getLeftOuterWall() {
Location from = getBottomLeftOutsideCorner();
Location to = getTopLeftOutsideCorner();
Set<Location> locations = new HashSet<>();
for (int i = 1; i < to.getBlockZ() - from.getBlockZ(); i++) {
locations.add(from.clone().add(0, 0, i));
}
return locations;
}
public Set<Location> getRightOuterWall() {
Location from = getBottomRightOutsideCorner();
Location to = getTopRightOutsideCorner();
Set<Location> locations = new HashSet<>();
for (int i = 1; i < to.getBlockZ() - from.getBlockZ(); i++) {
locations.add(from.clone().add(0, 0, i));
}
return locations;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment