diff --git a/src/com/massivecraft/massivecore/util/ChunkUtil.java b/src/com/massivecraft/massivecore/util/ChunkUtil.java new file mode 100644 index 00000000..2495e0e7 --- /dev/null +++ b/src/com/massivecraft/massivecore/util/ChunkUtil.java @@ -0,0 +1,109 @@ +package com.massivecraft.massivecore.util; + +import com.massivecraft.massivecore.collections.MassiveSet; +import com.massivecraft.massivecore.predicate.Predicate; +import com.massivecraft.massivecore.ps.PS; + +import java.util.Set; + +public class ChunkUtil +{ + // -------------------------------------------- // + // GET AREAS + // -------------------------------------------- // + + public static Set getChunksCircle(PS center, int radius) + { + // Common Startup + final Set chunks = new MassiveSet<>(); + + chunks.add(center); // The center should come first for pretty messages + + int radiusZero = radius - 1; + double radiusSquared = radiusZero * radiusZero; + + for (int dx = -radiusZero; dx <= radiusZero; dx++) + { + for (int dz = -radiusZero; dz <= radiusZero; dz++) + { + if (dx*dx + dz*dz > radiusSquared) continue; + + int x = center.getChunkX() + dx; + int z = center.getChunkZ() + dz; + + chunks.add(center.withChunkX(x).withChunkZ(z)); + } + } + + return chunks; + } + + public static Set getChunksSquare(PS center, int radius) + { + // Common Startup + final Set chunks = new MassiveSet<>(); + + chunks.add(center); // The center should come first for pretty messages + + int radiusZero = radius - 1; + + for (int dx = -radiusZero; dx <= radiusZero; dx++) + { + for (int dz = -radiusZero; dz <= radiusZero; dz++) + { + int x = center.getChunkX() + dx; + int z = center.getChunkZ() + dz; + + chunks.add(center.withChunkX(x).withChunkZ(z)); + } + } + + return chunks; + } + + public static Set getChunkArea(PS startingPoint, Predicate matcher, int max) + { + Set set = new MassiveSet<>(); + set.add(startingPoint); + floodSearch(set, matcher, max); + return set; + } + + public static void floodSearch(Set set, Predicate matcher, int max) + { + // Clean + if (set == null) throw new NullPointerException("set"); + if (matcher == null) throw new NullPointerException("color"); + + // Expand + Set expansion = new MassiveSet<>(); + for (PS chunk : set) + { + Set neighbours = MUtil.set( + chunk.withChunkX(chunk.getChunkX() + 1), + chunk.withChunkX(chunk.getChunkX() - 1), + chunk.withChunkZ(chunk.getChunkZ() + 1), + chunk.withChunkZ(chunk.getChunkZ() - 1) + ); + + for (PS neighbour : neighbours) + { + if (set.contains(neighbour)) continue; + if ( ! matcher.apply(neighbour)) continue; + + expansion.add(neighbour); + } + } + set.addAll(expansion); + + // No Expansion? + if (expansion.isEmpty()) return; + + // Reached Max? + if (set.size() >= max) return; + + // Recurse + floodSearch(set, matcher, max); + } + +}