I love generators

This commit is contained in:
themode 2024-08-16 23:17:14 +02:00
parent 6c5cd6544e
commit 19c4b5d598
2 changed files with 69 additions and 7 deletions

View File

@ -49,7 +49,7 @@ public final class GeneratorImpl {
}
public static UnitImpl chunk(DynamicRegistry<Biome> 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++) {
for (int sectionY = minSectionY; sectionY < maxSectionY; sectionY++) {
// Z -> Y -> X order is important for indexing
for (int sectionZ = minSectionZ; sectionZ < maxSectionZ; sectionZ++) {
for (int sectionY = minSectionY; sectionY < maxSectionY; sectionY++) {
for (int sectionX = minSectionX; sectionX < maxSectionX; sectionX++) {
final GenerationUnit unit = section(biomeRegistry, new GenSection(), sectionX, sectionY, sectionZ, true);
units[index++] = unit;
}
}
}
final List<GenerationUnit> 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;
}

View File

@ -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<Point> 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);
}