diff --git a/src/main/java/twilightforest/world/components/structures/HedgeMazeComponent.java b/src/main/java/twilightforest/world/components/structures/HedgeMazeComponent.java index 3fd64a2d80..42df9ac9bf 100644 --- a/src/main/java/twilightforest/world/components/structures/HedgeMazeComponent.java +++ b/src/main/java/twilightforest/world/components/structures/HedgeMazeComponent.java @@ -49,6 +49,7 @@ public HedgeMazeComponent(int i, int x, int y, int z) { @Override public void postProcess(WorldGenLevel world, StructureManager manager, ChunkGenerator generator, RandomSource rand, BoundingBox sbb, ChunkPos chunkPosIn, BlockPos blockPos) { + rand.setSeed(getMazeSeed(world)); TFMaze maze = new TFMaze(MSIZE, MSIZE, rand); maze.oddBias = 2; @@ -59,7 +60,6 @@ public void postProcess(WorldGenLevel world, StructureManager manager, ChunkGene maze.roots = 3; // set the seed to a fixed value based on this maze's x and z - maze.setSeed(world.getSeed() + (long) this.boundingBox.minX() * this.boundingBox.minZ()); // just add grass below the maze for now // grass underneath @@ -93,8 +93,8 @@ public void postProcess(WorldGenLevel world, StructureManager manager, ChunkGene for (int i = 0; i < nrooms; i++) { int rx, rz; do { - rx = maze.rand.nextInt(MSIZE - 2) + 1; - rz = maze.rand.nextInt(MSIZE - 2) + 1; + rx = rand.nextInt(MSIZE - 2) + 1; + rz = rand.nextInt(MSIZE - 2) + 1; } while (isNearRoom(rx, rz, rcoords)); maze.carveRoom1(rx, rz); @@ -103,16 +103,20 @@ public void postProcess(WorldGenLevel world, StructureManager manager, ChunkGene rcoords[i * 2 + 1] = rz; } - maze.generateRecursiveBacktracker(0, 0); + maze.generateRecursiveBacktracker(0, 0, rand); } maze.add4Exits(); - maze.copyToStructure(world, manager, generator, 1, FLOOR_LEVEL, 1, this, sbb); + maze.copyToStructure(world, manager, generator, 1, FLOOR_LEVEL, 1, this, sbb, rand); decorate3x3Rooms(world, rcoords, sbb); } + private long getMazeSeed(WorldGenLevel world) { + return world.getSeed() + (long) this.boundingBox.minX() * this.boundingBox.minZ(); + } + /** * @return true if the specified dx and dz are within 3 of a room specified in rcoords */ diff --git a/src/main/java/twilightforest/world/components/structures/TFMaze.java b/src/main/java/twilightforest/world/components/structures/TFMaze.java index 4508a89157..b4111fdd06 100644 --- a/src/main/java/twilightforest/world/components/structures/TFMaze.java +++ b/src/main/java/twilightforest/world/components/structures/TFMaze.java @@ -65,8 +65,6 @@ public class TFMaze { public static final int ROOM = 5; public static final int DOOR = 6; - public final RandomSource rand; - public TFMaze(int cellsWidth, int cellsDepth, RandomSource random) { // default values oddBias = 3; @@ -90,8 +88,6 @@ public TFMaze(int cellsWidth, int cellsDepth, RandomSource random) { this.rawWidth = width * 2 + 1; this.rawDepth = depth * 2 + 1; storage = new int[rawWidth * rawDepth]; - - this.rand = random; } /** @@ -192,17 +188,10 @@ public void resetCells() { .forEach(z -> putCell(x, z, 0))); } - /** - * Sets the random seed to a specific value - */ - public void setSeed(long newSeed) { - rand.setSeed(newSeed); - } - /** * Copy the maze into a StructureTFComponentOld */ - public void copyToStructure(WorldGenLevel world, StructureManager manager, ChunkGenerator generator, int dx, int dy, int dz, TFStructureComponentOld component, BoundingBox sbb) { + public void copyToStructure(WorldGenLevel world, StructureManager manager, ChunkGenerator generator, int dx, int dy, int dz, TFStructureComponentOld component, BoundingBox sbb, RandomSource rand) { for (int x = 0; x < rawWidth; x++) { for (int z = 0; z < rawDepth; z++) { // only draw walls. if the data is 0 the there's a wall @@ -216,7 +205,7 @@ public void copyToStructure(WorldGenLevel world, StructureManager manager, Chunk } if (isEven(x) && isEven(z)) { - if (type == 4 && shouldTree(x, z)) { + if (type == 4 && shouldTree(x, z, rand)) { // occasionally make a tree putCanopyTree(world, generator, mdx, dy, mdz, component, sbb); } else { @@ -310,7 +299,7 @@ public void copyToStructure(WorldGenLevel world, StructureManager manager, Chunk int mdz = dz + (z / 2 * (evenBias + oddBias)); if (isEven(x) && isEven(z)) { - if (shouldTorch(x, z) && component.getBlock(world, mdx, mdy, mdz, sbb).getBlock() == wallBlockState.getBlock()) { + if (shouldTorch(x, z, rand) && component.getBlock(world, mdx, mdy, mdz, sbb).getBlock() == wallBlockState.getBlock()) { component.placeBlock(world, torchBlockState, mdx, mdy, mdz, sbb); } } @@ -396,7 +385,7 @@ private boolean isEven(int n) { /** * Should we put a torch here? Intended to be called on the in-between spots where x and y are even. */ - public boolean shouldTorch(int rx, int rz) { + public boolean shouldTorch(int rx, int rz, RandomSource rand) { // if there is out of bounds in any direction, no if (getRaw(rx + 1, rz) == OOB || getRaw(rx - 1, rz) == OOB || getRaw(rx, rz + 1) == OOB || getRaw(rx, rz - 1) == OOB) { return false; @@ -437,7 +426,7 @@ public boolean shouldPillar(int rx, int rz) { * Should we put a tree instead of a post? * Essentially the answer is yes for the corners and the exits. */ - public boolean shouldTree(int rx, int rz) { + public boolean shouldTree(int rx, int rz, RandomSource rand) { if ((rx == 0 || rx == rawWidth - 1) && (getRaw(rx, rz + 1) != 0 || getRaw(rx, rz - 1) != 0)) { return true; } @@ -501,15 +490,16 @@ public void add4Exits() { * * @param sx The starting x coordinate * @param sz The starting y coordinate + * @param rand */ - public void generateRecursiveBacktracker(int sx, int sz) { - rbGen(sx, sz); + public void generateRecursiveBacktracker(int sx, int sz, RandomSource rand) { + rbGen(sx, sz, rand); } /** * Mark the cell as visited. If we have any unvisited neighbors, pick one randomly, carve the wall between them, then call this function on that neighbor. */ - public void rbGen(int sx, int sz) { + public void rbGen(int sx, int sz, RandomSource rand) { // mark cell as visited putCell(sx, sz, 1); @@ -574,10 +564,10 @@ public void rbGen(int sx, int sz) { } // call function recursively at the destination - rbGen(dx, dz); + rbGen(dx, dz, rand); // the destination has run out of free spaces, let's try this square again, up to 2 more times - rbGen(sx, sz); - rbGen(sx, sz); + rbGen(sx, sz, rand); + rbGen(sx, sz, rand); } } diff --git a/src/main/java/twilightforest/world/components/structures/darktower/DarkTowerMainComponent.java b/src/main/java/twilightforest/world/components/structures/darktower/DarkTowerMainComponent.java index ae970c01e8..64ad8153e6 100644 --- a/src/main/java/twilightforest/world/components/structures/darktower/DarkTowerMainComponent.java +++ b/src/main/java/twilightforest/world/components/structures/darktower/DarkTowerMainComponent.java @@ -489,10 +489,10 @@ protected void makeLargeStairsUp(WorldGenLevel world, BoundingBox sbb, Rotation private void decorateReappearingMaze(WorldGenLevel world, StructureManager manager, ChunkGenerator generator, RandomSource decoRNG, BoundingBox sbb, Rotation rotation, int y) { // make maze object int mazeSize = 6; + decoRNG.setSeed(world.getSeed() + this.boundingBox.minX() * 90342903L + y * 90342903L ^ this.boundingBox.minZ()); TFMaze maze = new TFMaze(mazeSize, mazeSize, decoRNG); // set the seed to a fixed value based on this maze's x and z - maze.setSeed(world.getSeed() + this.boundingBox.minX() * 90342903L + y * 90342903L ^ this.boundingBox.minZ()); // tell it not to make outside walls by making them "ROOMS" for (int i = 0; i < 13; i++) { @@ -521,7 +521,7 @@ private void decorateReappearingMaze(WorldGenLevel world, StructureManager manag maze.putRaw(6, 1, TFMaze.ROOM); maze.putRaw(7, 1, TFMaze.ROOM); maze.putRaw(8, 1, TFMaze.DOOR); - maze.generateRecursiveBacktracker(0, 5); + maze.generateRecursiveBacktracker(0, 5, decoRNG); } case CLOCKWISE_90 -> { for (int x = 7; x < 12; x++) { @@ -537,7 +537,7 @@ private void decorateReappearingMaze(WorldGenLevel world, StructureManager manag maze.putRaw(11, 6, TFMaze.ROOM); maze.putRaw(11, 7, TFMaze.ROOM); maze.putRaw(11, 8, TFMaze.DOOR); - maze.generateRecursiveBacktracker(0, 0); + maze.generateRecursiveBacktracker(0, 0, decoRNG); } case CLOCKWISE_180 -> { for (int x = 7; x < 12; x++) { @@ -553,7 +553,7 @@ private void decorateReappearingMaze(WorldGenLevel world, StructureManager manag maze.putRaw(6, 11, TFMaze.ROOM); maze.putRaw(5, 11, TFMaze.ROOM); maze.putRaw(4, 11, TFMaze.DOOR); - maze.generateRecursiveBacktracker(5, 0); + maze.generateRecursiveBacktracker(5, 0, decoRNG); } case COUNTERCLOCKWISE_90 -> { for (int x = 1; x < 6; x++) { @@ -569,7 +569,7 @@ private void decorateReappearingMaze(WorldGenLevel world, StructureManager manag maze.putRaw(1, 6, TFMaze.ROOM); maze.putRaw(1, 5, TFMaze.ROOM); maze.putRaw(1, 4, TFMaze.DOOR); - maze.generateRecursiveBacktracker(5, 5); + maze.generateRecursiveBacktracker(5, 5, decoRNG); } } @@ -584,7 +584,7 @@ private void decorateReappearingMaze(WorldGenLevel world, StructureManager manag maze.head = 1; maze.oddBias = 2; - maze.copyToStructure(world, manager, generator, 0, y + 1, 0, this, sbb); + maze.copyToStructure(world, manager, generator, 0, y + 1, 0, this, sbb, decoRNG); decorateMazeDeadEnds(world, decoRNG, maze, y, rotation, sbb); } diff --git a/src/main/java/twilightforest/world/components/structures/minotaurmaze/MinotaurMazeComponent.java b/src/main/java/twilightforest/world/components/structures/minotaurmaze/MinotaurMazeComponent.java index 01e1759fd9..345edfff1a 100644 --- a/src/main/java/twilightforest/world/components/structures/minotaurmaze/MinotaurMazeComponent.java +++ b/src/main/java/twilightforest/world/components/structures/minotaurmaze/MinotaurMazeComponent.java @@ -38,8 +38,8 @@ public MinotaurMazeComponent(StructurePieceSerializationContext ctx, CompoundTag this.rcoords = nbt.getIntArray("roomCoords"); // recreate maze object - maze = new TFMaze(getMazeSize(), getMazeSize(), RandomSource.create()); - setFixedMazeSeed(); + RandomSource random = RandomSource.create(getSeed()); + maze = new TFMaze(getMazeSize(), getMazeSize(), random); configureMaze(); // blank out rcoords above 1 so that the room generation works properly @@ -49,10 +49,10 @@ public MinotaurMazeComponent(StructurePieceSerializationContext ctx, CompoundTag } // recreate rooms - this.addRoomsToMaze(this.rcoords[0], this.rcoords[1], (this.rcoords.length + 1) / 2); + this.addRoomsToMaze(this.rcoords[0], this.rcoords[1], (this.rcoords.length + 1) / 2, random); // regenerate maze - maze.generateRecursiveBacktracker(0, 0); + maze.generateRecursiveBacktracker(0, 0, random); } @SuppressWarnings("this-escape") @@ -63,23 +63,23 @@ public MinotaurMazeComponent(int index, int x, int y, int z, int entranceX, int this.boundingBox = BoundingBoxUtils.getComponentToAddBoundingBox(x, y, z, -getRadius(), 0, -getRadius(), getRadius() * 2 + 2, 5, getRadius() * 2 + 2, Direction.SOUTH, false); // make maze object + random.setSeed(getSeed()); maze = new TFMaze(getMazeSize(), getMazeSize(), random); // set the seed to a fixed value based on this maze's x and z - setFixedMazeSeed(); configureMaze(); // rooms int nrooms = 7; rcoords = new int[nrooms * 2]; - addRoomsToMaze(entranceX, entranceZ, nrooms); + addRoomsToMaze(entranceX, entranceZ, nrooms, random); // make actual maze - maze.generateRecursiveBacktracker(0, 0); + maze.generateRecursiveBacktracker(0, 0, random); } - private void addRoomsToMaze(int entranceX, int entranceZ, int nrooms) { + private void addRoomsToMaze(int entranceX, int entranceZ, int nrooms, RandomSource rand) { // make one entrance room always rcoords[0] = entranceX; rcoords[1] = entranceZ; @@ -89,8 +89,8 @@ private void addRoomsToMaze(int entranceX, int entranceZ, int nrooms) { for (int i = 1; i < nrooms; i++) { int rx, rz; do { - rx = maze.rand.nextInt(getMazeSize() - 2) + 1; - rz = maze.rand.nextInt(getMazeSize() - 2) + 1; + rx = rand.nextInt(getMazeSize() - 2) + 1; + rz = rand.nextInt(getMazeSize() - 2) + 1; } while (isNearRoom(rx, rz, rcoords, i == 1 ? 7 : 4)); maze.carveRoom1(rx, rz); @@ -100,8 +100,8 @@ private void addRoomsToMaze(int entranceX, int entranceZ, int nrooms) { } } - private void setFixedMazeSeed() { - maze.setSeed(this.boundingBox.minX() * 90342903L + this.boundingBox.minY() * 90342903L ^ this.boundingBox.minZ()); + private long getSeed() { + return this.boundingBox.minX() * 90342903L + this.boundingBox.minY() * 90342903L ^ this.boundingBox.minZ(); } public MinotaurMazeComponent(int index, int x, int y, int z, int level, RandomSource random) { @@ -287,7 +287,7 @@ public void postProcess(WorldGenLevel world, StructureManager manager, ChunkGene generateBox(world, sbb, 1, 5, 1, getDiameter() + 1, 5, getDiameter() + 1, TFBlocks.MAZESTONE.get().defaultBlockState(), stone, onlyReplaceCeiling); generateBox(world, sbb, 1, 0, 1, getDiameter() + 1, 0, getDiameter() + 1, TFBlocks.MAZESTONE_MOSAIC.get().defaultBlockState(), stone, false); - maze.copyToStructure(world, manager, generator, 1, 2, 1, this, sbb); + maze.copyToStructure(world, manager, generator, 1, 2, 1, this, sbb, rand); } private void configureMaze() {