This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
package net.therosegarden.firefighter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
import me.ryanhamshire.GriefPrevention.Claim;
|
||||
import me.ryanhamshire.GriefPrevention.GriefPrevention;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.HeightMap;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
|
||||
final class GriefPreventionLocationProvider implements EmergencyLocationProvider {
|
||||
@Override
|
||||
public EmergencySite randomClaimSite(Random random, Predicate<World> worldAllowed, int maxRadius, int minClaimArea) {
|
||||
List<Claim> eligible = new ArrayList<>();
|
||||
for (Claim claim : GriefPrevention.instance.dataStore.getClaims()) {
|
||||
if (claim == null || claim.parent != null || claim.getOwnerID() == null || claim.getArea() < minClaimArea) {
|
||||
continue;
|
||||
}
|
||||
Location lesser = claim.getLesserBoundaryCorner();
|
||||
Location greater = claim.getGreaterBoundaryCorner();
|
||||
World world = lesser == null ? null : lesser.getWorld();
|
||||
if (world == null || greater == null || greater.getWorld() == null || !worldAllowed.test(world)) {
|
||||
continue;
|
||||
}
|
||||
eligible.add(claim);
|
||||
}
|
||||
|
||||
if (eligible.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Claim claim = eligible.get(random.nextInt(eligible.size()));
|
||||
Location lesser = claim.getLesserBoundaryCorner();
|
||||
Location greater = claim.getGreaterBoundaryCorner();
|
||||
World world = lesser.getWorld();
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int minX = Math.min(lesser.getBlockX(), greater.getBlockX());
|
||||
int maxX = Math.max(lesser.getBlockX(), greater.getBlockX());
|
||||
int minZ = Math.min(lesser.getBlockZ(), greater.getBlockZ());
|
||||
int maxZ = Math.max(lesser.getBlockZ(), greater.getBlockZ());
|
||||
int centerX = minX + ((maxX - minX) / 2);
|
||||
int centerZ = minZ + ((maxZ - minZ) / 2);
|
||||
int y = world.getHighestBlockAt(centerX, centerZ, HeightMap.MOTION_BLOCKING).getY() + 1;
|
||||
|
||||
int halfWidth = Math.max(2, (maxX - minX) / 2);
|
||||
int halfDepth = Math.max(2, (maxZ - minZ) / 2);
|
||||
int radius = Math.max(2, Math.min(Math.max(2, maxRadius), Math.min(halfWidth, halfDepth)));
|
||||
|
||||
String owner = ownerName(claim);
|
||||
return new EmergencySite(owner + "'s home", world.getName(), centerX, y, centerZ, radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nearbyClaims(Location location, int radius, int maxResults) {
|
||||
if (location == null || location.getWorld() == null) {
|
||||
return "none";
|
||||
}
|
||||
|
||||
List<NearbyClaim> nearby = new ArrayList<>();
|
||||
for (Claim claim : GriefPrevention.instance.dataStore.getClaims()) {
|
||||
if (claim == null || claim.parent != null) {
|
||||
continue;
|
||||
}
|
||||
Location lesser = claim.getLesserBoundaryCorner();
|
||||
Location greater = claim.getGreaterBoundaryCorner();
|
||||
if (lesser == null || greater == null || lesser.getWorld() == null
|
||||
|| !lesser.getWorld().equals(location.getWorld())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double distance = distanceToClaim(location, lesser, greater);
|
||||
if (distance <= radius) {
|
||||
nearby.add(new NearbyClaim(ownerName(claim), distance));
|
||||
}
|
||||
}
|
||||
|
||||
nearby.sort(Comparator.comparingDouble(NearbyClaim::distance));
|
||||
if (nearby.isEmpty()) {
|
||||
return "none within " + radius + " blocks";
|
||||
}
|
||||
|
||||
int limit = Math.max(1, maxResults);
|
||||
List<String> descriptions = new ArrayList<>();
|
||||
for (int i = 0; i < nearby.size() && i < limit; i++) {
|
||||
NearbyClaim entry = nearby.get(i);
|
||||
String distance = entry.distance() < 1.0 ? "inside" : Math.round(entry.distance()) + "m";
|
||||
descriptions.add(entry.owner() + " (" + distance + ")");
|
||||
}
|
||||
if (nearby.size() > limit) {
|
||||
descriptions.add("+" + (nearby.size() - limit) + " more");
|
||||
}
|
||||
return String.join(", ", descriptions);
|
||||
}
|
||||
|
||||
private String ownerName(Claim claim) {
|
||||
UUID ownerId = claim.getOwnerID();
|
||||
if (ownerId == null) {
|
||||
return "Admin claim";
|
||||
}
|
||||
OfflinePlayer offline = Bukkit.getOfflinePlayer(ownerId);
|
||||
String name = offline.getName();
|
||||
if (name == null || name.isBlank()) {
|
||||
name = claim.getOwnerName();
|
||||
}
|
||||
if (name == null || name.isBlank()) {
|
||||
name = ownerId.toString().substring(0, 8).toLowerCase(Locale.ROOT);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private double distanceToClaim(Location location, Location lesser, Location greater) {
|
||||
int minX = Math.min(lesser.getBlockX(), greater.getBlockX());
|
||||
int maxX = Math.max(lesser.getBlockX(), greater.getBlockX());
|
||||
int minZ = Math.min(lesser.getBlockZ(), greater.getBlockZ());
|
||||
int maxZ = Math.max(lesser.getBlockZ(), greater.getBlockZ());
|
||||
|
||||
double x = location.getX();
|
||||
double z = location.getZ();
|
||||
double dx = x < minX ? minX - x : (x > maxX ? x - maxX : 0.0);
|
||||
double dz = z < minZ ? minZ - z : (z > maxZ ? z - maxZ : 0.0);
|
||||
return Math.sqrt((dx * dx) + (dz * dz));
|
||||
}
|
||||
|
||||
private record NearbyClaim(String owner, double distance) {}
|
||||
}
|
||||
Reference in New Issue
Block a user