package de.fanta.challengeutils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.util.BoundingBox;
import java.util.List;
import java.util.Random;
public class LocationUtils {
private static final int MAX_ATTEMPTS = 10; // Maximale Versuche, um eine sichere Location zu finden
public static Location getRandomLocationAroundPlayer(Player player, double radius) {
return getRandomLocationAroundLocation(player.getLocation(), radius, false);
}
public static Location getRandomLocationAroundPlayer(Player player, double radius, boolean findSafeLocation) {
return getRandomLocationAroundLocation(player.getLocation(), radius, findSafeLocation);
}
public static Location getRandomLocationAroundLocation(Location location, double radius) {
return getRandomLocationAroundLocation(location, radius, false);
}
public static Location getRandomLocationAroundLocation(Location location, double radius, boolean findSafeLocation) {
Random random = new Random();
World world = location.getWorld();
int maxHeight = world.getMaxHeight();
int minHeight = world.getMinHeight() + 5; //+5 Weil Bedrock
if (world.getEnvironment() == World.Environment.NETHER) {
maxHeight = 122; //Max Logical height in Nether
}
if (findSafeLocation) {
for (int attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
double angle = random.nextDouble() * 2 * Math.PI;
double distance = random.nextDouble() * radius;
double xOffset = Math.cos(angle) * distance;
double zOffset = Math.sin(angle) * distance;
double newX = location.getX() + xOffset;
double newZ = location.getZ() + zOffset;
double newY = random.nextDouble() * (maxHeight - minHeight) + minHeight;
Location newLocation = new Location(world, newX, newY, newZ);
if (isSafeLocation(newLocation)) {
return newLocation;
}
}
}
double finalAngle = random.nextDouble() * 2 * Math.PI;
double finalDistance = random.nextDouble() * radius;
double finalXOffset = Math.cos(finalAngle) * finalDistance;
double finalZOffset = Math.sin(finalAngle) * finalDistance;
double finalX = location.getX() + finalXOffset;
double finalZ = location.getZ() + finalZOffset;
double finalY = random.nextDouble() * (maxHeight - minHeight) + minHeight;
return new Location(location.getWorld(), finalX, finalY, finalZ);
}
private static boolean isSafeLocation(Location location) {
World world = location.getWorld();
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
if (world.getBlockAt(x, y - 1, z).getType().isSolid()) {
return world.getBlockAt(x, y, z).getType() == Material.AIR && world.getBlockAt(x, y + 1, z).getType() == Material.AIR;
}
return false;
}
public static BoundingBox calculateEnclosingBoundingBox(List<BoundingBox> boxes) {
if (boxes == null || boxes.isEmpty()) {
throw new IllegalArgumentException("Error while the bounding box list is null or Empty");
}
double minX = boxes.getFirst().getMinX();
double minY = boxes.getFirst().getMinY();
double minZ = boxes.getFirst().getMinZ();
double maxX = boxes.getFirst().getMaxX();
double maxY = boxes.getFirst().getMaxY();
double maxZ = boxes.getFirst().getMaxZ();
for (BoundingBox box : boxes) {
if (box.getMinX() < minX) {
minX = box.getMinX();
}
if (box.getMinY() < minY) {
minY = box.getMinY();
}
if (box.getMinZ() < minZ) {
minZ = box.getMinZ();
}
if (box.getMaxX() > maxX) {
maxX = box.getMaxX();
}
if (box.getMaxY() > maxY) {
maxY = box.getMaxY();
}
if (box.getMaxZ() > maxZ) {
maxZ = box.getMaxZ();
}
}
return new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
}
}