Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package net.minestom.server.coordinate;
import org.jetbrains.annotations.NotNull;
/**
* Helper class to iterate over chunks within a range.
*/
public final class ChunkRangeUtils {
/**
* Get the amount of chunks in a square range.
*
* @param range the range
* @return the amount of chunks in the square range
*/
public static int chunkCountFromRange(int range) {
if (range < 0) {
throw new IllegalArgumentException("Range cannot be negative");
}
final int square = range * 2 + 1;
return square * square;
}
public static void forDifferingChunksInRange(int newChunkX, int newChunkZ,
int oldChunkX, int oldChunkZ,
int range, @NotNull ChunkConsumer callback) {
for (int x = newChunkX - range; x <= newChunkX + range; x++) {
for (int z = newChunkZ - range; z <= newChunkZ + range; z++) {
if (Math.abs(x - oldChunkX) > range || Math.abs(z - oldChunkZ) > range) {
callback.accept(x, z);
}
}
}
}
public static void forDifferingChunksInRange(int newChunkX, int newChunkZ,
int oldChunkX, int oldChunkZ,
int range,
@NotNull ChunkConsumer newCallback, @NotNull ChunkConsumer oldCallback) {
// Find the new chunks
forDifferingChunksInRange(newChunkX, newChunkZ, oldChunkX, oldChunkZ, range, newCallback);
// Find the old chunks
forDifferingChunksInRange(oldChunkX, oldChunkZ, newChunkX, newChunkZ, range, oldCallback);
}
/**
* New implementation comes from Krypton
* which comes from kotlin port by Esophose, which comes from a stackoverflow answer.
*/
public static void forChunksInRange(int chunkX, int chunkZ, int range, ChunkConsumer consumer) {
// Send in spiral around the center chunk
// Note: its not really required to start at the center anymore since the chunk queue is sorted by distance,
// however we still should send a circle so this method is still fine, and good for any other case a
// spiral might be needed.
consumer.accept(chunkX, chunkZ);
for (int id = 1; id < (range * 2 + 1) * (range * 2 + 1); id++) {
var index = id - 1;
// compute radius (inverse arithmetic sum of 8 + 16 + 24 + ...)
var radius = (int) Math.floor((Math.sqrt(index + 1.0) - 1) / 2) + 1;
// compute total point on radius -1 (arithmetic sum of 8 + 16 + 24 + ...)
var p = 8 * radius * (radius - 1) / 2;
// points by face
var en = radius * 2;
// compute de position and shift it so the first is (-r, -r) but (-r + 1, -r)
// so the square can connect
var a = (1 + index - p) % (radius * 8);
switch (a / (radius * 2)) {
// find the face (0 = top, 1 = right, 2 = bottom, 3 = left)
case 0 -> consumer.accept(a - radius + chunkX, -radius + chunkZ);
case 1 -> consumer.accept(radius + chunkX, a % en - radius + chunkZ);
case 2 -> consumer.accept(radius - a % en + chunkX, radius + chunkZ);
case 3 -> consumer.accept(-radius + chunkX, radius - a % en + chunkZ);
default -> throw new IllegalStateException("unreachable");
}
}
}
public static void forChunksInRange(@NotNull Point point, int range, ChunkConsumer consumer) {
forChunksInRange(point.chunkX(), point.chunkZ(), range, consumer);
}
@FunctionalInterface
public interface ChunkConsumer {
void accept(int v1, int v2);
}
}