diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/world/generation/IslandWorldChunkGenerator.java b/src/main/java/ca/recrown/islandsurvivalcraft/world/generation/IslandWorldChunkGenerator.java index ec61a5e..86107b9 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/world/generation/IslandWorldChunkGenerator.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/world/generation/IslandWorldChunkGenerator.java @@ -1,6 +1,11 @@ package ca.recrown.islandsurvivalcraft.world.generation; +import java.util.LinkedList; import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import org.bukkit.Chunk; import org.bukkit.Material; @@ -23,39 +28,57 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene private final Cache blockValueCache = new Cache<>(102400); private final Cache biomeCache = new Cache<>(102400); private final Cache chunkExistenceCache = new Cache<>(16384); + private final ExecutorService executor = Executors.newFixedThreadPool(2); private volatile World currentWorld; @Override - public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) { + public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biomeGrid) { this.currentWorld = world; IslandWorldMapper mapper = new IslandWorldMapper(random, blockValueCache); TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(world.getSeed()); BiomeSelector biomeSelector = new BiomeSelector(random); biomeSelector.initialize(); - WorldHeightShader heightShader = new WorldHeightShader(world.getSeed(), mapper, world.getSeaLevel(), world.getMaxHeight(), 3); + WorldHeightShader heightShader = new WorldHeightShader(world.getSeed(), mapper, world.getSeaLevel(), + world.getMaxHeight(), 3); BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator(); int maxHeight = world.getMaxHeight(); + LinkedList> biomeColumns = new LinkedList<>(); ChunkData chunkData = createChunkData(world); Biome[][] biomes = new Biome[Utilities.CHUNK_SIZE][Utilities.CHUNK_SIZE]; for (int localX = 0; localX < Utilities.CHUNK_SIZE; localX++) { for (int localZ = 0; localZ < Utilities.CHUNK_SIZE; localZ++) { if (biomes[localX][localZ] == null) { - biomeGenerator.generateBiomeColumn(biomes, world, x, z, localX, localZ, mapper, biomeSelector, temperatureMapGenerator, biomeCache, chunkExistenceCache); + biomeGenerator.generateBiomeColumn(biomes, world, chunkX, chunkZ, localX, localZ, mapper, biomeSelector, + temperatureMapGenerator, biomeCache, chunkExistenceCache); } if (biomes[localX][localZ] == null) throw new IllegalStateException("Biome was null."); - for (int y = 0; y < maxHeight; y++) { - biome.setBiome(x, y, z, biomes[localX][localZ]); - } - int worldX = 16 * x + localX; - int worldZ = 16 * z + localZ; + + final int biomeX = localX; + final int biomeZ = localZ; + biomeColumns.add(executor.submit(() -> { + for (int y = 0; y < maxHeight; y++) { + biomeGrid.setBiome(biomeX, y, biomeZ, biomes[biomeX][biomeZ]); + } + return true; + })); + + int worldX = 16 * chunkX + localX; + int worldZ = 16 * chunkZ + localZ; int height = heightShader.getAltitude(worldX, worldZ, biomes[localX][localZ]); - chunkData.setRegion(localX, 1, localZ, localX+1, height, localZ+1, Material.DIAMOND_BLOCK); + chunkData.setRegion(localX, 1, localZ, localX + 1, height, localZ + 1, Material.DIAMOND_BLOCK); } } chunkData.setRegion(0, 0, 0, 16, 1, 16, Material.BEDROCK); - + while (!biomeColumns.isEmpty()) { + try { + biomeColumns.poll().get(); + } catch (ExecutionException | InterruptedException e) { + e.printStackTrace(); + throw new IllegalStateException(e.getCause().getMessage()); + } + } return chunkData; }