diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index f2991e75a..9b4203490 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -140,7 +140,7 @@ public class CommandDeveloper implements DecreeExecutor { public void packBenchmark( @Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld") IrisDimension dimension, - @Param(description = "Radius in regions", defaultValue = "5") + @Param(description = "Radius in regions", defaultValue = "2048") int radius, @Param(description = "Open GUI while benchmarking", defaultValue = "false") boolean gui diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java index e3ed1c844..6d7bc42a6 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java @@ -19,9 +19,7 @@ package com.volmit.iris.core.commands; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.gui.PregeneratorJob; -import com.volmit.iris.core.pregenerator.LazyPregenerator; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.decree.DecreeExecutor; @@ -29,12 +27,9 @@ import com.volmit.iris.util.decree.annotations.Decree; import com.volmit.iris.util.decree.annotations.Param; import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.Position2; -import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.util.Vector; -import java.io.File; - @Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!") public class CommandPregen implements DecreeExecutor { @Decree(description = "Pregenerate a world") @@ -52,13 +47,12 @@ public class CommandPregen implements DecreeExecutor { sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example."); } radius = Math.max(radius, 1024); - int w = (radius >> 9 + 1) * 2; IrisToolbelt.pregenerate(PregenTask .builder() - .center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9)) + .center(new Position2(center.getBlockX(), center.getBlockZ())) .gui(true) - .width(w) - .height(w) + .radiusX(radius) + .radiusZ(radius) .build(), world); String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ(); sender().sendMessage(msg); diff --git a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 35569f6f6..63b8919db 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -24,7 +24,6 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator; import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregeneratorMethod; -import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.Form; @@ -45,8 +44,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; -import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress; - public class PregeneratorJob implements PregenListener { private static final Color COLOR_EXISTS = parseColor("#4d7d5b"); private static final Color COLOR_BLACK = parseColor("#4d7d5b"); @@ -81,12 +78,12 @@ public class PregeneratorJob implements PregenListener { this.task = task; this.pregenerator = new IrisPregenerator(task, method, this); max = new Position2(0, 0); - min = new Position2(0, 0); - task.iterateRegions((xx, zz) -> { - min.setX(Math.min(xx << 5, min.getX())); - min.setZ(Math.min(zz << 5, min.getZ())); - max.setX(Math.max((xx << 5) + 31, max.getX())); - max.setZ(Math.max((zz << 5) + 31, max.getZ())); + min = new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE); + task.iterateAllChunks((xx, zz) -> { + min.setX(Math.min(xx, min.getX())); + min.setZ(Math.min(zz, min.getZ())); + max.setX(Math.max(xx, max.getX())); + max.setZ(Math.max(zz, max.getZ())); }); if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) { @@ -162,7 +159,7 @@ public class PregeneratorJob implements PregenListener { } public void drawRegion(int x, int z, Color color) { - J.a(() -> PregenTask.iterateRegion(x, z, (xx, zz) -> { + J.a(() -> task.iterateChunks(x, z, (xx, zz) -> { draw(xx, zz, color); J.sleep(3); })); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index e8c00d3df..cb8407272 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -165,8 +165,11 @@ public class ChunkUpdater { if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) { return; } + if (!new File(world.getWorldFolder(), "region" + File.separator + rX + "." + rZ + ".mca").exists()) { + return; + } - PregenTask.iterateRegion(rX, rZ, (x, z) -> { + task.iterateChunks(rX, rZ, (x, z) -> { while (paused.get() && !cancelled.get()) { J.sleep(50); } @@ -348,8 +351,8 @@ public class ChunkUpdater { int width = maxZ - minZ + 1; return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder() - .width((int) Math.ceil(width / 2d)) - .height((int) Math.ceil(height / 2d)) + .radiusZ((int) Math.ceil(width / 2d * 512)) + .radiusX((int) Math.ceil(height / 2d * 512)) .center(new Position2(oX, oZ)) .build()); } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index 56ee44b05..57aa8b0eb 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -19,7 +19,6 @@ package com.volmit.iris.core.pregenerator; import com.volmit.iris.Iris; -import com.volmit.iris.core.pack.IrisPack; import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KSet; @@ -83,7 +82,7 @@ public class IrisPregenerator { generatedLast = new AtomicInteger(0); generatedLastMinute = new AtomicInteger(0); totalChunks = new AtomicInteger(0); - task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024)); + task.iterateAllChunks((_a, _b) -> totalChunks.incrementAndGet()); startTime = new AtomicLong(M.ms()); ticker = new Looper() { @Override @@ -194,7 +193,7 @@ public class IrisPregenerator { } else if (!regions) { hit = true; listener.onRegionGenerating(x, z); - PregenTask.iterateRegion(x, z, (xx, zz) -> { + task.iterateChunks(x, z, (xx, zz) -> { while (paused.get() && !shutdown.get()) { J.sleep(50); } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java index 015a418a1..db8d76e7a 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -32,17 +32,26 @@ import java.util.Comparator; @Data public class PregenTask { private static final Position2 ZERO = new Position2(0, 0); - private static final KList ORDER_CENTER = computeChunkOrder(); private static final KMap> ORDERS = new KMap<>(); @Builder.Default - private boolean gui = false; + private final boolean gui = false; @Builder.Default - private Position2 center = new Position2(0, 0); + private final Position2 center = new Position2(0, 0); @Builder.Default - private int width = 1; + private final int radiusX = 1; @Builder.Default - private int height = 1; + private final int radiusZ = 1; + + private final Bounds bounds = new Bounds(); + + protected PregenTask(boolean gui, Position2 center, int radiusX, int radiusZ) { + this.gui = gui; + this.center = new ProxiedPos(center); + this.radiusX = radiusX; + this.radiusZ = radiusZ; + bounds.update(); + } public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) { for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) { @@ -70,29 +79,72 @@ public class PregenTask { return p; } - private static KList computeChunkOrder() { - Position2 center = new Position2(15, 15); - KList p = new KList<>(); - new Spiraler(33, 33, (x, z) -> { - int xx = x + 15; - int zz = z + 15; - if (xx < 0 || xx > 31 || zz < 0 || zz > 31) { - return; - } - - p.add(new Position2(xx, zz)); - }).drain(); - p.sort(Comparator.comparing((i) -> i.distance(center))); - return p; + public void iterateRegions(Spiraled s) { + var bound = bounds.region(); + new Spiraler(bound.sizeX, bound.sizeZ, ((x, z) -> { + if (bound.check(x, z)) s.on(x, z); + })).setOffset(center.getX() >> 9, center.getZ() >> 9).drain(); } - public void iterateRegions(Spiraled s) { - new Spiraler(getWidth() * 2, getHeight() * 2, s) - .setOffset(center.getX(), center.getZ()).drain(); + public void iterateChunks(int rX, int rZ, Spiraled s) { + var bound = bounds.chunk(); + iterateRegion(rX, rZ, ((x, z) -> { + if (bound.check(x, z)) s.on(x, z); + })); } public void iterateAllChunks(Spiraled s) { - new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s)) - .setOffset(center.getX(), center.getZ()).drain(); + iterateRegions(((rX, rZ) -> iterateChunks(rX, rZ, s))); + } + + private class Bounds { + private Bound chunk = null; + private Bound region = null; + + public void update() { + int maxX = center.getX() + radiusX; + int maxZ = center.getZ() + radiusZ; + int minX = center.getX() - radiusX; + int minZ = center.getZ() - radiusZ; + + chunk = new Bound(minX >> 4, minZ >> 4, Math.ceilDiv(maxX, 16), Math.ceilDiv(maxZ, 16)); + region = new Bound(minX >> 9, minZ >> 9, Math.ceilDiv(maxX, 512), Math.ceilDiv(maxZ, 512)); + } + + public Bound chunk() { + if (chunk == null) update(); + return chunk; + } + + public Bound region() { + if (region == null) update(); + return region; + } + } + + private record Bound(int minX, int maxX, int minZ, int maxZ, int sizeX, int sizeZ) { + private Bound(int minX, int minZ, int maxX, int maxZ) { + this(minX, maxX, minZ, maxZ, maxZ - minZ + 1, maxZ - minZ + 1); + } + + boolean check(int x, int z) { + return x >= minX && x <= maxX && z >= minZ && z <= maxZ; + } + } + + private static class ProxiedPos extends Position2 { + public ProxiedPos(Position2 p) { + super(p.getX(), p.getZ()); + } + + @Override + public void setX(int x) { + throw new IllegalStateException("This Position2 may not be modified"); + } + + @Override + public void setZ(int z) { + throw new IllegalStateException("This Position2 may not be modified"); + } } } diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java index 9d41279c9..8667542a9 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java @@ -146,8 +146,8 @@ public class IrisPackBenchmarking { IrisToolbelt.pregenerate(PregenTask .builder() .gui(gui) - .width(radius) - .height(radius) + .radiusX(radius) + .radiusZ(radius) .build(), Bukkit.getWorld("benchmark") ); }