From 19c4b5d598cdb0570456856945e0c64cfbfdac03 Mon Sep 17 00:00:00 2001 From: themode Date: Fri, 16 Aug 2024 23:17:14 +0200 Subject: [PATCH] I love generators --- .../instance/generator/GeneratorImpl.java | 17 +++--- .../instance/generator/GeneratorTest.java | 59 +++++++++++++++++++ 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/minestom/server/instance/generator/GeneratorImpl.java b/src/main/java/net/minestom/server/instance/generator/GeneratorImpl.java index 34026a5af..566095504 100644 --- a/src/main/java/net/minestom/server/instance/generator/GeneratorImpl.java +++ b/src/main/java/net/minestom/server/instance/generator/GeneratorImpl.java @@ -49,7 +49,7 @@ public final class GeneratorImpl { } public static UnitImpl chunk(DynamicRegistry biomeRegistry, GenSection[] chunkSections, int chunkX, int minSection, int chunkZ) { - final Vec start = new Vec(chunkX * 16, minSection * 16, chunkZ * 16); + final Vec start = SECTION_SIZE.mul(chunkX, minSection, chunkZ); return area(biomeRegistry, start, 1, chunkSections.length, 1, chunkSections); } @@ -119,7 +119,7 @@ public final class GeneratorImpl { final int sectionY = getChunkCoordinate(y); final int sectionZ = getChunkCoordinate(z); if (sections == null) { - this.minSection = new Vec(sectionX * 16, sectionY * 16, sectionZ * 16); + this.minSection = SECTION_SIZE.mul(sectionX, sectionY, sectionZ); this.width = 1; this.height = 1; this.depth = 1; @@ -190,16 +190,17 @@ public final class GeneratorImpl { GenerationUnit[] units = new GenerationUnit[width * height * depth]; int index = 0; - for (int sectionX = minSectionX; sectionX < maxSectionX; sectionX++) { + // Z -> Y -> X order is important for indexing + for (int sectionZ = minSectionZ; sectionZ < maxSectionZ; sectionZ++) { for (int sectionY = minSectionY; sectionY < maxSectionY; sectionY++) { - for (int sectionZ = minSectionZ; sectionZ < maxSectionZ; sectionZ++) { + for (int sectionX = minSectionX; sectionX < maxSectionX; sectionX++) { final GenerationUnit unit = section(biomeRegistry, new GenSection(), sectionX, sectionY, sectionZ, true); units[index++] = unit; } } } final List sections = List.of(units); - final Point startSection = new Vec(minSectionX * 16, minSectionY * 16, minSectionZ * 16); + final Point startSection = SECTION_SIZE.mul(minSectionX, minSectionY, minSectionZ); return registerFork(startSection, sections, width, height, depth); } @@ -294,7 +295,8 @@ public final class GeneratorImpl { } private int retrieveBlockId(Block block) { - return fork ? block.stateId() + 1 : block.stateId(); + final int stateId = block.stateId(); + return fork ? stateId + 1 : stateId; } private void handleCache(int x, int y, int z, Block block) { @@ -344,7 +346,7 @@ public final class GeneratorImpl { @Override public void setAll(@NotNull Supplier supplier) { for (GenerationUnit section : sections) { - final var start = section.absoluteStart(); + final Point start = section.absoluteStart(); final int startX = start.blockX(); final int startY = start.blockY(); final int startZ = start.blockZ(); @@ -532,6 +534,7 @@ public final class GeneratorImpl { private static int findIndex(int width, int height, int depth, int x, int y, int z) { + assert width > 0 && height > 0 && depth > 0; return (z * width * height) + (y * width) + x; } diff --git a/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java b/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java index 72546a679..8b3c626b5 100644 --- a/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java +++ b/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java @@ -309,6 +309,65 @@ public class GeneratorTest { assertEquals(Block.STONE.stateId(), value)); } + @Test + public void testForkAcrossBorders() { + final int minSection = -4; + final int maxSection = 4; + + final int sectionCount = maxSection - minSection; + GenSection[] sections = new GenSection[sectionCount]; + Arrays.setAll(sections, i -> new GenSection()); + var chunkUnits = GeneratorImpl.chunk(null, sections, 0, minSection, 0); + Generator generator = unit -> { + if (unit.absoluteStart().x() == 0 && unit.absoluteStart().z() == 0) { + var start = unit.absoluteStart().withY(0).add(0, 0, 8).sub(2, 2, 0); + var end = unit.absoluteStart().withY(0).add(0, 0, 8).add(2, 2, 1); + + var fork = unit.fork(start, end); + fork.modifier().fill(start, end, Block.STONE); + } + }; + generator.generate(chunkUnits); + + Set stones = new HashSet<>(); + + for (GeneratorImpl.UnitImpl fork : chunkUnits.forks()) { + GeneratorImpl.AreaModifierImpl impl = (GeneratorImpl.AreaModifierImpl) fork.modifier(); + + for (GenerationUnit section : impl.sections()) { + GeneratorImpl.UnitImpl unit = (GeneratorImpl.UnitImpl) section; + GeneratorImpl.SectionModifierImpl modifier = (GeneratorImpl.SectionModifierImpl) unit.modifier(); + + modifier.genSection().blocks().getAllPresent((x, y, z, state) -> { + final Point blockPos = modifier.start().add(x, y, z); + stones.add(blockPos); + }); + } + } + + var expectedStones = Set.of( + new Vec(-2, -2, 8), + new Vec(-2, -1, 8), + new Vec(-2, 0, 8), + new Vec(-2, 1, 8), + new Vec(-1, -2, 8), + new Vec(-1, -1, 8), + new Vec(-1, 0, 8), + new Vec(-1, 1, 8), + new Vec(0, -2, 8), + new Vec(0, -1, 8), + new Vec(0, 0, 8), + new Vec(0, 1, 8), + new Vec(1, -2, 8), + new Vec(1, -1, 8), + new Vec(1, 0, 8), + new Vec(1, 1, 8) + ); + + assertEquals(expectedStones.size(), stones.size()); + assertEquals(expectedStones, stones); + } + static GenerationUnit dummyUnit(Point start, Point end) { return unit(null, null, start, end, null); }