84 lines
3.3 KiB
Java
84 lines
3.3 KiB
Java
package games.dmg.spigotbase;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.UUID;
|
|
import java.util.function.Predicate;
|
|
|
|
public final class PocketPortalGeometry {
|
|
private PocketPortalGeometry() {
|
|
}
|
|
|
|
public static Optional<PocketPortalLocation> findFrame(
|
|
BlockPosition clicked,
|
|
UUID worldId,
|
|
String worldName,
|
|
Predicate<BlockPosition> isFrameMaterial,
|
|
Predicate<BlockPosition> isOpenInterior
|
|
) {
|
|
for (PocketPortalAxis axis : PocketPortalAxis.values()) {
|
|
int clickedHorizontal = axis == PocketPortalAxis.X ? clicked.x() : clicked.z();
|
|
for (int horizontalOffset = 0; horizontalOffset < 4; horizontalOffset++) {
|
|
for (int verticalOffset = 0; verticalOffset < 5; verticalOffset++) {
|
|
int originHorizontal = clickedHorizontal - horizontalOffset;
|
|
int originY = clicked.y() - verticalOffset;
|
|
PocketPortalLocation candidate = axis == PocketPortalAxis.X
|
|
? new PocketPortalLocation(
|
|
worldId, worldName, originHorizontal, originY, clicked.z(), axis
|
|
)
|
|
: new PocketPortalLocation(
|
|
worldId, worldName, clicked.x(), originY, originHorizontal, axis
|
|
);
|
|
if (frameBlocks(candidate).stream().allMatch(isFrameMaterial)
|
|
&& interiorBlocks(candidate).stream().allMatch(isOpenInterior)) {
|
|
return Optional.of(candidate);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return Optional.empty();
|
|
}
|
|
|
|
public static List<BlockPosition> frameBlocks(PocketPortalLocation portal) {
|
|
List<BlockPosition> blocks = new ArrayList<>(14);
|
|
for (int horizontal = 0; horizontal < 4; horizontal++) {
|
|
blocks.add(position(portal, horizontal, 0));
|
|
blocks.add(position(portal, horizontal, 4));
|
|
}
|
|
for (int vertical = 1; vertical < 4; vertical++) {
|
|
blocks.add(position(portal, 0, vertical));
|
|
blocks.add(position(portal, 3, vertical));
|
|
}
|
|
return List.copyOf(blocks);
|
|
}
|
|
|
|
public static List<BlockPosition> interiorBlocks(PocketPortalLocation portal) {
|
|
List<BlockPosition> blocks = new ArrayList<>(6);
|
|
for (int horizontal = 1; horizontal < 3; horizontal++) {
|
|
for (int vertical = 1; vertical < 4; vertical++) {
|
|
blocks.add(position(portal, horizontal, vertical));
|
|
}
|
|
}
|
|
return List.copyOf(blocks);
|
|
}
|
|
|
|
public static boolean isFrame(PocketPortalLocation portal, BlockPosition position) {
|
|
return frameBlocks(portal).contains(position);
|
|
}
|
|
|
|
public static boolean isInterior(PocketPortalLocation portal, BlockPosition position) {
|
|
return interiorBlocks(portal).contains(position);
|
|
}
|
|
|
|
private static BlockPosition position(
|
|
PocketPortalLocation portal,
|
|
int horizontal,
|
|
int vertical
|
|
) {
|
|
return portal.axis() == PocketPortalAxis.X
|
|
? new BlockPosition(portal.x() + horizontal, portal.y() + vertical, portal.z())
|
|
: new BlockPosition(portal.x(), portal.y() + vertical, portal.z() + horizontal);
|
|
}
|
|
}
|