Basic terrain shaping added.

World height shader "shades" the primitive island height giving variation to land and sea.

World layer shader "shades" the primitive islands with varying layers dependent on biomes.

Mapper values was changed to perform the more targetted task of generating island locations and masks.

Biome selector now takes a random at call to help with seed consistency (due to threading, this may still be problematic).

Chunk generator implements the new changes.

Tests implement new changes.
This commit is contained in:
Harrison Deng 2020-05-02 00:06:58 -05:00
parent a6cebe703b
commit 486a0f837f
8 changed files with 82 additions and 66 deletions

View File

@ -11,7 +11,6 @@ import ca.recrown.islandsurvivalcraft.Utilities;
public class BiomeSelector { public class BiomeSelector {
private boolean initialized = false; private boolean initialized = false;
private volatile Random random;
private final HashMap<Biome, Float> lands = new HashMap<>(); private final HashMap<Biome, Float> lands = new HashMap<>();
private HashMap<Float, ArrayList<Biome>> temperaturesForLand = new HashMap<>(); private HashMap<Float, ArrayList<Biome>> temperaturesForLand = new HashMap<>();
private final HashMap<Float, ArrayList<Biome>> temperaturePartitionedLandBiomes = new HashMap<>(); private final HashMap<Float, ArrayList<Biome>> temperaturePartitionedLandBiomes = new HashMap<>();
@ -20,9 +19,7 @@ public class BiomeSelector {
private final HashMap<Float, ArrayList<Biome>> temperaturePartitionedOceanBiomes = new HashMap<>(); private final HashMap<Float, ArrayList<Biome>> temperaturePartitionedOceanBiomes = new HashMap<>();
public BiomeSelector(Random random) { public BiomeSelector() {
this.random = random;
temperaturePartitionedLandBiomes.put(0.05f, new ArrayList<>()); temperaturePartitionedLandBiomes.put(0.05f, new ArrayList<>());
temperaturePartitionedLandBiomes.put(0.30f, new ArrayList<>()); temperaturePartitionedLandBiomes.put(0.30f, new ArrayList<>());
temperaturePartitionedLandBiomes.put(0.95f, new ArrayList<>()); temperaturePartitionedLandBiomes.put(0.95f, new ArrayList<>());
@ -32,10 +29,6 @@ public class BiomeSelector {
temperaturePartitionedOceanBiomes.put(0.5f, new ArrayList<>()); temperaturePartitionedOceanBiomes.put(0.5f, new ArrayList<>());
} }
public BiomeSelector() {
this(new Random());
}
public void initialize() { public void initialize() {
if (initialized) throw new IllegalStateException("Biome selector is already initialized."); if (initialized) throw new IllegalStateException("Biome selector is already initialized.");
@ -197,7 +190,7 @@ public class BiomeSelector {
* @param temperature Minecraft temperature to select biome from. * @param temperature Minecraft temperature to select biome from.
* @return The randomly selected biome. * @return The randomly selected biome.
*/ */
public Biome getLandBiome(float temperature) { public Biome getLandBiome(float temperature, Random random) {
if (!initialized) throw new IllegalStateException("Biome selector is not initialized."); if (!initialized) throw new IllegalStateException("Biome selector is not initialized.");
ArrayList<Biome> biomes = null; ArrayList<Biome> biomes = null;
if (temperature <= 0.05f) { if (temperature <= 0.05f) {
@ -218,7 +211,7 @@ public class BiomeSelector {
* @param temperature Minecraft temperature to select biome from. * @param temperature Minecraft temperature to select biome from.
* @return The randomly selected biome. * @return The randomly selected biome.
*/ */
public Biome getOceanBiome(float temperature) { public Biome getOceanBiome(float temperature, Random random) {
if (!initialized) throw new IllegalStateException("Biome selector is not initialized."); if (!initialized) throw new IllegalStateException("Biome selector is not initialized.");
ArrayList<Biome> biomes = null; ArrayList<Biome> biomes = null;
if (temperature <= 0.00f) { if (temperature <= 0.00f) {
@ -230,7 +223,4 @@ public class BiomeSelector {
return biomes.get((int) random.nextFloat() * biomes.size()); return biomes.get((int) random.nextFloat() * biomes.size());
} }
public void setBiome(Random random) {
this.random = random;
}
} }

View File

@ -13,14 +13,12 @@ public class IslandWorldMapper implements CoordinateValidatable {
private final Cache<Point2, Double> blockValueCache; private final Cache<Point2, Double> blockValueCache;
private final SimplexOctaveGenerator noiseGenerator; private final SimplexOctaveGenerator noiseGenerator;
private final int noiseOctaves = 8; private final int noiseOctaves = 4;
private final float islandBlockGenerationPercent = 15f; private final float islandBlockGenerationPercent = 15f;
private final float exaggerationFactor = 1f;
private final float islandExaggeration = 1f;
private final double noiseFrequency = 1.7D; private final double noiseFrequency = 1.7D;
private final double noiseAmplitude = 0.5D; private final double noiseAmplitude = 0.5D;
private final double scale = 0.004D; private final double scale = 0.004D;
private final float shoreFactor = 0.05f; private final float shoreFactor = 0.065f;
private final float shallowPortion = 0.01f; private final float shallowPortion = 0.01f;
private final DepthFirstSearch dfs; private final DepthFirstSearch dfs;
@ -117,20 +115,14 @@ public class IslandWorldMapper implements CoordinateValidatable {
Double res = blockValueCache.get(p); Double res = blockValueCache.get(p);
if (res == null) { if (res == null) {
double shift = 2 * (islandBlockGenerationPercent / 100f); double shift = 2 * (islandBlockGenerationPercent / 100f);
double rawNoise = noiseGenerator.noise(worldX, worldZ, noiseFrequency, noiseAmplitude, true); double rawNoise = noiseGenerator.noise(worldX, worldZ, noiseFrequency, noiseAmplitude, true) - shift;
double noise = 0;
if (rawNoise < 0) {
noise = ( - Math.pow(- rawNoise, exaggerationFactor) - shift);
} else {
noise = Math.pow(rawNoise, islandExaggeration) - shift;
}
double maxNeg = -1 - shift; double maxNeg = -1 - shift;
double maxPos = 1 - shift; double maxPos = 1 - shift;
if (noise < 0) { if (rawNoise < 0) {
res = - noise / maxNeg; res = - rawNoise / maxNeg;
} else { } else {
res = noise / maxPos; res = rawNoise / maxPos;
} }
blockValueCache.set(p, res); blockValueCache.set(p, res);
return res; return res;

View File

@ -1,5 +1,7 @@
package ca.recrown.islandsurvivalcraft.world.generation; package ca.recrown.islandsurvivalcraft.world.generation;
import java.util.Random;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
@ -26,6 +28,7 @@ public interface BiomeGenerator {
* @param tempGenerator The temperature generator to be used. * @param tempGenerator The temperature generator to be used.
* @param biomeCache Cache for biomes. * @param biomeCache Cache for biomes.
* @param chunkGenCache Cache for whether or not the chunk is generated. * @param chunkGenCache Cache for whether or not the chunk is generated.
* @param random A random that bukkit passes.
*/ */
public void generateBiomeColumn(Biome[][] biomesArray, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGenerator, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> chunkGenCache); public void generateBiomeColumn(Biome[][] biomesArray, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGenerator, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> chunkGenCache, Random random);
} }

View File

@ -46,10 +46,9 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene
int seaLevel = world.getSeaLevel(); int seaLevel = world.getSeaLevel();
IslandWorldMapper mapper = new IslandWorldMapper(seed, blockValueCache); IslandWorldMapper mapper = new IslandWorldMapper(seed, blockValueCache);
TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(seed); TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(seed);
WorldHeightShader heightShader = new WorldHeightShader(mapper, world.getSeaLevel(), world.getMaxHeight(), 3); WorldHeightShader heightShader = new WorldHeightShader(seed, mapper, seaLevel, world.getMaxHeight(), 3);
WorldLayerShader layerShader = new WorldLayerShader(seed, seaLevel, maxHeight, mapper); WorldLayerShader layerShader = new WorldLayerShader(seed, seaLevel, maxHeight, mapper);
BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator(); BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator();
biomeSelector.setBiome(random);
LinkedList<Future<Boolean>> tasks = new LinkedList<>(); LinkedList<Future<Boolean>> tasks = new LinkedList<>();
ChunkData chunkData = createChunkData(world); ChunkData chunkData = createChunkData(world);
@ -70,7 +69,7 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene
final int localZ = z; final int localZ = z;
if (biomes[localX][localZ] == null) { if (biomes[localX][localZ] == null) {
biomeGenerator.generateBiomeColumn(biomes, world, chunkX, chunkZ, localX, localZ, mapper, biomeSelector, biomeGenerator.generateBiomeColumn(biomes, world, chunkX, chunkZ, localX, localZ, mapper, biomeSelector,
temperatureMapGenerator, biomeCache, chunkExistenceCache); temperatureMapGenerator, biomeCache, chunkExistenceCache, random);
} }
if (biomes[localX][localZ] == null) throw new IllegalStateException("Biome was null."); if (biomes[localX][localZ] == null) throw new IllegalStateException("Biome was null.");
tasks.add(exBeta.submit(() -> { tasks.add(exBeta.submit(() -> {
@ -84,7 +83,7 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene
final int worldZ = Utilities.CHUNK_SIZE * chunkZ + localZ; final int worldZ = Utilities.CHUNK_SIZE * chunkZ + localZ;
Biome currentBiome = biomes[localX][localZ]; Biome currentBiome = biomes[localX][localZ];
int terrainHeight = heightShader.getTerrainHeight(worldX, worldZ, currentBiome); int terrainHeight = heightShader.getTerrainHeight(worldX, worldZ, currentBiome);
int currentTerrainHeight = terrainHeight - 1; int currentTerrainHeight = terrainHeight;
int bedrockHeight = random.nextInt(5) + 1; int bedrockHeight = random.nextInt(5) + 1;
if (layerShader.hasSpecialLayers(currentBiome)) { if (layerShader.hasSpecialLayers(currentBiome)) {
Material currentMaterial = layerShader.getMaterialForHeight(worldX, worldZ, currentTerrainHeight, currentBiome); Material currentMaterial = layerShader.getMaterialForHeight(worldX, worldZ, currentTerrainHeight, currentBiome);
@ -93,14 +92,17 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene
currentTerrainHeight --; currentTerrainHeight --;
} }
} else { } else {
chunkData.setBlock(localX, currentTerrainHeight, localZ, layerShader.getSurfaceMaterial(currentBiome)); int surfaceThickness = layerShader.getSurfaceThickness(worldX, worldZ, currentBiome);
int transitionHeight = layerShader.getTransitionMaterialThickness(worldX, worldZ, currentBiome); currentTerrainHeight -= surfaceThickness;
currentTerrainHeight -= transitionHeight; chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + surfaceThickness, localZ + 1, layerShader.getSurfaceMaterial(currentBiome));
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + transitionHeight, localZ + 1, layerShader.getTransitionMaterial(currentBiome)); int transitionThickness = layerShader.getTransitionMaterialThickness(worldX, worldZ, currentBiome);
currentTerrainHeight -= transitionThickness;
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + transitionThickness, localZ + 1, layerShader.getTransitionMaterial(currentBiome));
} }
chunkData.setRegion(localX, bedrockHeight, localZ, localX + 1, currentTerrainHeight + 1, localZ + 1, Material.STONE); chunkData.setRegion(localX, bedrockHeight, localZ, localX + 1, currentTerrainHeight + 1, localZ + 1, Material.STONE);
if (terrainHeight < seaLevel) { if (terrainHeight < seaLevel) {
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, seaLevel, localZ + 1, Material.WATER); chunkData.setRegion(localX, terrainHeight, localZ, localX + 1, seaLevel, localZ + 1, Material.WATER);
} }
chunkData.setRegion(localX, 0, localZ, localX + 1, bedrockHeight, localZ + 1, Material.BEDROCK); chunkData.setRegion(localX, 0, localZ, localX + 1, bedrockHeight, localZ + 1, Material.BEDROCK);
} }

View File

@ -1,5 +1,7 @@
package ca.recrown.islandsurvivalcraft.world.generation; package ca.recrown.islandsurvivalcraft.world.generation;
import java.util.Random;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
@ -15,7 +17,7 @@ import ca.recrown.islandsurvivalcraft.world.IslandWorldMapper;
public class UniBiomeIslandGenerator implements BiomeGenerator { public class UniBiomeIslandGenerator implements BiomeGenerator {
@Override @Override
public void generateBiomeColumn(Biome[][] biomes, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGen, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> chunkGenCache) { public void generateBiomeColumn(Biome[][] biomes, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMapper mapper, BiomeSelector biomeSelector, TemperatureMapGenerator tempGen, Cache<Point2, Biome[]> biomeCache, Cache<Point2, Boolean> chunkGenCache, Random random) {
int worldX = 16 * chunkX + localX; int worldX = 16 * chunkX + localX;
int worldZ = 16 * chunkZ + localZ; int worldZ = 16 * chunkZ + localZ;
Point2 chunkCoords = Utilities.worldToChunkCoordinates(new Point2(worldX, worldZ)); Point2 chunkCoords = Utilities.worldToChunkCoordinates(new Point2(worldX, worldZ));
@ -31,7 +33,7 @@ public class UniBiomeIslandGenerator implements BiomeGenerator {
//Fine, check if it's ocean. //Fine, check if it's ocean.
if (!mapper.isIsland(worldX, worldZ)) { if (!mapper.isIsland(worldX, worldZ)) {
biomeSet = new Biome[4]; biomeSet = new Biome[4];
biomeSet[0] = biomeSelector.getOceanBiome(tempGen.getTemperature(worldX, worldZ)); biomeSet[0] = biomeSelector.getOceanBiome(tempGen.getTemperature(worldX, worldZ), random);
setCacheBiome(worldX, worldZ, biomeSet, biomes, biomeCache); setCacheBiome(worldX, worldZ, biomeSet, biomes, biomeCache);
return; return;
} }
@ -44,9 +46,9 @@ public class UniBiomeIslandGenerator implements BiomeGenerator {
search.setStartPosition(worldX, worldZ); search.setStartPosition(worldX, worldZ);
if (!search.findTarget(islandInfo)) { if (!search.findTarget(islandInfo)) {
float temp = tempGen.getTemperature(worldX, worldZ); float temp = tempGen.getTemperature(worldX, worldZ);
if (islandInfo.main == null) islandInfo.main = biomeSelector.getLandBiome(temp); if (islandInfo.main == null) islandInfo.main = biomeSelector.getLandBiome(temp, random);
if (islandInfo.shore == null) islandInfo.shore = biomeSelector.getShoreBiome(islandInfo.main, temp); if (islandInfo.shore == null) islandInfo.shore = biomeSelector.getShoreBiome(islandInfo.main, temp);
if (islandInfo.shallow == null) islandInfo.shallow = biomeSelector.getOceanBiome(temp); if (islandInfo.shallow == null) islandInfo.shallow = biomeSelector.getOceanBiome(temp, random);
} }
PropagatorInfo propInfo = new PropagatorInfo(islandInfo, biomes, new Point2(chunkX, chunkZ), mapper, biomeCache); PropagatorInfo propInfo = new PropagatorInfo(islandInfo, biomes, new Point2(chunkX, chunkZ), mapper, biomeCache);

View File

@ -1,41 +1,49 @@
package ca.recrown.islandsurvivalcraft.world.shaders; package ca.recrown.islandsurvivalcraft.world.shaders;
import java.util.Random;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.util.noise.SimplexOctaveGenerator;
import ca.recrown.islandsurvivalcraft.world.IslandWorldMapper; import ca.recrown.islandsurvivalcraft.world.IslandWorldMapper;
public class WorldHeightShader { public class WorldHeightShader {
private final IslandWorldMapper islandLocator; private final IslandWorldMapper mapper;
private final SimplexOctaveGenerator shader;
private final int seaLevel; private final int seaLevel;
private final int worldHeight; private final int worldHeight;
private final int minimumHeight; private final int minimumHeight;
public WorldHeightShader(IslandWorldMapper islandLocator, int seaLevel, int worldHeight, int minimumHeight) { public WorldHeightShader(long seed, IslandWorldMapper islandLocator, int seaLevel, int worldHeight, int minimumHeight) {
this.islandLocator = islandLocator; this.mapper = islandLocator;
this.seaLevel = seaLevel; this.seaLevel = seaLevel;
this.worldHeight = worldHeight; this.worldHeight = worldHeight;
this.minimumHeight = minimumHeight; this.minimumHeight = minimumHeight;
this.shader = new SimplexOctaveGenerator(new Random(seed - 1), 8);
this.shader.setScale(0.05d);
} }
public int getTerrainHeight(int worldX, int worldZ, Biome biome) { public int getTerrainHeight(int worldX, int worldZ, Biome biome) {
int height = 0; int height = 0;
String biomeName = biome.name().toLowerCase(); String biomeName = biome.name().toLowerCase();
if (biomeName.contains("hills")) { if (biomeName.contains("hills")) {
height = calculateTerrainHeight(worldX, worldZ, 15); height = calculateTerrainHeight(worldX, worldZ, 30d);
} else if (biomeName.contains("mountains")) { } else if (biomeName.contains("mountains")) {
height = calculateTerrainHeight(worldX, worldZ, 120); height = calculateTerrainHeight(worldX, worldZ, 70d);
} else if (biomeName.contains("plateau")) { } else if (biomeName.contains("plateau")) {
height = Math.min(calculateTerrainHeight(worldX, worldZ, 50), 30); height = (int) Math.min(calculateTerrainHeight(worldX, worldZ, 50d), seaLevel + 30d);
} else if (biomeName.contains("modified")) { } else if (biomeName.contains("modified")) {
height = calculateTerrainHeight(worldX, worldZ, 45); height = calculateTerrainHeight(worldX, worldZ, 40d);
} else if (biomeName.contains("shattered")) { } else if (biomeName.contains("shattered")) {
height = calculateTerrainHeight(worldX, worldZ, 60); height = calculateTerrainHeight(worldX, worldZ, 40d);
} else if (biomeName.contains("tall")) { } else if (biomeName.contains("tall")) {
height = calculateTerrainHeight(worldX, worldZ, 45); height = calculateTerrainHeight(worldX, worldZ, 30d);
} else if (biomeName.contains("stone")) {
height = calculateTerrainHeight(worldX, worldZ, 70d);
} else if (!biomeName.contains("ocean")) { } else if (!biomeName.contains("ocean")) {
height = calculateTerrainHeight(worldX, worldZ, 15); height = calculateTerrainHeight(worldX, worldZ, 10d);
} else { } else {
height = calculateTerrainHeight(worldX, worldZ, seaLevel); height = calculateTerrainHeight(worldX, worldZ, seaLevel, 1d, 0.25d);
} }
if (height > worldHeight) throw new IllegalStateException("Resulting height is greater than world height! Biome this occurred on: " + biomeName); if (height > worldHeight) throw new IllegalStateException("Resulting height is greater than world height! Biome this occurred on: " + biomeName);
@ -43,14 +51,15 @@ public class WorldHeightShader {
return height; return height;
} }
private int calculateTerrainHeight(int worldX, int worldZ, int multiplier) { private int calculateTerrainHeight(int worldX, int worldZ, double heightFactor, double shift, double exaggerationFactor) {
int blockHeight = 0; int res = seaLevel;
double islandValue = islandLocator.getWorldValue(worldX, worldZ); double shapeValue = (shader.noise(worldX, worldZ, 1.5d, 0.05d, true) + shift) / (shift + 1d);
if (!islandLocator.isLand(worldX, worldZ)) { if (shift == 1d && exaggerationFactor != 1d) shapeValue = Math.pow(shapeValue, exaggerationFactor);
blockHeight = (int) ((1d + islandValue) * (double) multiplier); res += mapper.getWorldValue(worldX, worldZ) * (shapeValue * heightFactor);
} else { return res;
blockHeight += seaLevel + islandValue * multiplier;
} }
return blockHeight;
private int calculateTerrainHeight(int worldX, int worldZ, double heightFactor) {
return calculateTerrainHeight(worldX, worldZ, heightFactor, 0.75d, 1d);
} }
} }

View File

@ -38,7 +38,7 @@ public class WorldLayerShader {
/** /**
* Figures out the type of material to be placed at a given world coordinate set. * Figures out the type of material to be placed at a given world coordinate set.
* * Returns null when special layering is done and should return to normal generation.
* @param worldX The world x coordinate. * @param worldX The world x coordinate.
* @param worldZ The world z coordinate. * @param worldZ The world z coordinate.
* @param y The elevation. * @param y The elevation.
@ -74,7 +74,7 @@ public class WorldLayerShader {
String biomeName = biome.toString().toLowerCase(); String biomeName = biome.toString().toLowerCase();
if (biomeName.contains("beach") || biomeName.contains("desert") || biomeName.contains("warm_ocean")) { if (biomeName.contains("beach") || biomeName.contains("desert") || biomeName.contains("warm_ocean")) {
return Material.SAND; return Material.SAND;
} else if (biomeName.contains("deep_ocean")) { } else if (biomeName.contains("ocean")) {
return Material.GRAVEL; return Material.GRAVEL;
} else if (biomeName.contains("stone")) { } else if (biomeName.contains("stone")) {
return Material.STONE; return Material.STONE;
@ -83,6 +83,16 @@ public class WorldLayerShader {
return Material.GRASS_BLOCK; return Material.GRASS_BLOCK;
} }
public int getSurfaceThickness(int worldX, int worldZ, Biome biome) {
String biomeName = biome.toString().toLowerCase();
if (biomeName.contains("beach")) {
return (int) (Math.abs(mapper.getWorldValue(worldX, worldZ)) * 5) + 4;
}
return 1;
}
public Material getTransitionMaterial(Biome biome) { public Material getTransitionMaterial(Biome biome) {
String biomeName = biome.toString().toLowerCase(); String biomeName = biome.toString().toLowerCase();
if (biomeName.contains("beach") || biomeName.contains("desert")) { if (biomeName.contains("beach") || biomeName.contains("desert")) {

View File

@ -3,6 +3,7 @@ package ca.recrown.islandsurvivalcraft.world.generation;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -11,6 +12,7 @@ import java.util.concurrent.TimeUnit;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
@ -30,6 +32,9 @@ public class UniBiomeIslandGeneratorTest {
private volatile Cache<Point2, Double> blockValueCache; private volatile Cache<Point2, Double> blockValueCache;
private volatile Cache<Point2, Biome[]> biomeCache; private volatile Cache<Point2, Biome[]> biomeCache;
private volatile Cache<Point2, Boolean> chunkExistenceCache; private volatile Cache<Point2, Boolean> chunkExistenceCache;
private final BiomeSelector biomeSelector = new BiomeSelector();
private final Random random = new Random(SEED);
private class BiomeGenTask implements Runnable { private class BiomeGenTask implements Runnable {
private final int amount; private final int amount;
@ -51,8 +56,6 @@ public class UniBiomeIslandGeneratorTest {
public void generateBiome(int chunkX, int chunkZ) { public void generateBiome(int chunkX, int chunkZ) {
IslandWorldMapper mapper = new IslandWorldMapper(SEED, blockValueCache); IslandWorldMapper mapper = new IslandWorldMapper(SEED, blockValueCache);
TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(SEED); TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(SEED);
BiomeSelector biomeSelector = new BiomeSelector();
biomeSelector.initialize();
BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator(); BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator();
Biome[][] biomes = new Biome[Utilities.CHUNK_SIZE][Utilities.CHUNK_SIZE]; Biome[][] biomes = new Biome[Utilities.CHUNK_SIZE][Utilities.CHUNK_SIZE];
@ -60,7 +63,7 @@ public class UniBiomeIslandGeneratorTest {
for (int localZ = 0; localZ < Utilities.CHUNK_SIZE; localZ++) { for (int localZ = 0; localZ < Utilities.CHUNK_SIZE; localZ++) {
if (biomes[localX][localZ] == null) { if (biomes[localX][localZ] == null) {
biomeGenerator.generateBiomeColumn(biomes, dummyWorld, chunkX, chunkZ, localX, localZ, mapper, biomeGenerator.generateBiomeColumn(biomes, dummyWorld, chunkX, chunkZ, localX, localZ, mapper,
biomeSelector, temperatureMapGenerator, biomeCache, chunkExistenceCache); biomeSelector, temperatureMapGenerator, biomeCache, chunkExistenceCache, random);
} }
if (biomes[localX][localZ] == null) if (biomes[localX][localZ] == null)
throw new IllegalStateException("Biome was null."); throw new IllegalStateException("Biome was null.");
@ -69,6 +72,11 @@ public class UniBiomeIslandGeneratorTest {
} }
} }
@BeforeAll
public void setup() {
biomeSelector.initialize();
}
@BeforeEach @BeforeEach
public void individualSetup() { public void individualSetup() {
blockValueCache = new Cache<>(524288); blockValueCache = new Cache<>(524288);