Preliminary new unique biome generator.
This commit is contained in:
parent
a5cf40913b
commit
dd89266b4e
@ -0,0 +1,8 @@
|
||||
package ca.recrown.islandsurvivalcraft.utilities.biomes;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
public interface BiomeInfo {
|
||||
public Biome getMainBiome();
|
||||
public Biome getTransitionBiome();
|
||||
}
|
@ -4,7 +4,7 @@ import org.bukkit.block.Biome;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.utilities.weighting.Weightable;
|
||||
|
||||
public class LandBiomeInfo implements Weightable {
|
||||
public class LandBiomeInfo implements Weightable, BiomeInfo {
|
||||
private final Biome biome;
|
||||
private final float weight;
|
||||
private final Biome hillBiome;
|
||||
@ -47,14 +47,15 @@ public class LandBiomeInfo implements Weightable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hill biome. May be null.
|
||||
* @return the hill biome. Will return the normal biome if there is no special hill biome for this biome.
|
||||
*/
|
||||
public Biome getHillBiome() {
|
||||
if (hillBiome == null) return getBiome();
|
||||
return hillBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the shore biome.
|
||||
* @return the shore biome. Should not have shore if null is returned.
|
||||
*/
|
||||
public Biome getPreferredShore() {
|
||||
return preferredShore;
|
||||
@ -66,4 +67,9 @@ public class LandBiomeInfo implements Weightable {
|
||||
public Biome getTransitionBiome() {
|
||||
return transitionBiome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getMainBiome() {
|
||||
return biome;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package ca.recrown.islandsurvivalcraft.utilities.biomes;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
public class OceanBiomeInfo {
|
||||
public class OceanBiomeInfo implements BiomeInfo {
|
||||
private final Biome ocean;
|
||||
private final Biome transitionOcean;
|
||||
private final Biome deepAlternative;
|
||||
@ -22,9 +22,10 @@ public class OceanBiomeInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the transition ocean. May be null.
|
||||
* @return the transition ocean. Will return the normal biome if no transitional biome is designated.
|
||||
*/
|
||||
public Biome getTransitionOcean() {
|
||||
if (transitionOcean == null) return getOcean();
|
||||
return transitionOcean;
|
||||
}
|
||||
|
||||
@ -34,4 +35,14 @@ public class OceanBiomeInfo {
|
||||
public Biome getDeepAlternative() {
|
||||
return deepAlternative;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getMainBiome() {
|
||||
return getOcean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getTransitionBiome() {
|
||||
return getTransitionBiome();
|
||||
}
|
||||
}
|
@ -169,21 +169,20 @@ public class IslandWorldMap {
|
||||
if (!isIsland(worldX, worldZ)) throw new IllegalArgumentException("The given coordinates are not part is an island.");
|
||||
dfs.setStartPosition(worldX, worldZ);
|
||||
final Point2 goal = new Point2(0, 0);
|
||||
dfs.setEndPosition(goal);
|
||||
|
||||
Reference<Point2> closest = new Reference<>();
|
||||
dfs.findTarget(new CoordinateTargetValidatable(){
|
||||
Double closestDistance = null;
|
||||
@Override
|
||||
public boolean isCoordinateTarget(int x, int y) {
|
||||
if (coordinateTargetValidatable != null && coordinateTargetValidatable.isCoordinateTarget(x, y)) {
|
||||
closest.value = null;
|
||||
return true;
|
||||
}
|
||||
Point2 current = new Point2(x, y);
|
||||
double currentDistance = current.distance(goal);
|
||||
if (closestDistance == null || (currentDistance) < closestDistance) {
|
||||
closestDistance = currentDistance;
|
||||
closest.value = current;
|
||||
if (coordinateTargetValidatable != null) {
|
||||
return coordinateTargetValidatable.isCoordinateTarget(x, y);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package ca.recrown.islandsurvivalcraft.world.generation.biomes;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import ca.recrown.islandsurvivalcraft.world.BiomeMap;
|
||||
@ -17,16 +15,15 @@ public interface BiomeGenerator {
|
||||
* It doesn't need to be populated on the first call as this method will be called once for every column in the chunk.
|
||||
* However, if some biomes can be set without repetative calls, doing so will prevent this method from being called for those locals.
|
||||
*
|
||||
* @param chunkBiomeSets The array of biomes that are to be saturated. First two arrays represent the x and y values, and the third represents the biome set.
|
||||
* @param world The current world.
|
||||
* @param localBiomeInfo The array of biomes that are to be saturated. First two arrays represent the x and y values, and the third represents the biome set.
|
||||
* @param chunkX The X coordinate of the chunk.
|
||||
* @param chunkZ The Z coordinate of the chunk.
|
||||
* @param localX The X coordinate of the column within the chunk.
|
||||
* @param localZ The Z coordinate of the column within the chunk.
|
||||
* @param mapper The island mapper to be used.
|
||||
* @param islandMap The island mapper to be used.
|
||||
* @param tempGenerator The temperature generator to be used.
|
||||
* @param biomeCache Cache for biomes.
|
||||
* @param chunkGenCache Cache for whether or not the chunk is generated.
|
||||
*/
|
||||
public void generateBiomeColumn(Biome[][][] chunkBiomeSets, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMap mapper, BiomeMap biomeSelector, TemperatureMap tempGenerator, Cache<Point2, Biome[]> biomeCache);
|
||||
public void generateBiomeColumn(BiomeInfo[][] localBiomeInfo, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMap islandMap, BiomeMap biomeSelector, TemperatureMap tempGenerator, Cache<Point2, BiomeInfo> biomeCache);
|
||||
}
|
@ -1,157 +1,64 @@
|
||||
package ca.recrown.islandsurvivalcraft.world.generation.biomes;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.LandBiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.OceanBiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.datatypes.Reference;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.floodfill.Floodable;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.floodfill.Flooder;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.pathfinding.CoordinateTargetValidatable;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.pathfinding.CoordinateValidatable;
|
||||
import ca.recrown.islandsurvivalcraft.world.BiomeMap;
|
||||
import ca.recrown.islandsurvivalcraft.world.IslandWorldMap;
|
||||
import ca.recrown.islandsurvivalcraft.world.TemperatureMap;
|
||||
|
||||
public class UniqueBiomeGenerator implements BiomeGenerator {
|
||||
private final double DEEP_OCEAN_PORTION = 0.5d;
|
||||
private final double HILL_PORTION = 0.4;
|
||||
|
||||
@Override
|
||||
public void generateBiomeColumn(Biome[][][] chunkBiomeSets, World world, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMap islandMap, BiomeMap biomeSelector, TemperatureMap tempGen, Cache<Point2, Biome[]> biomeCache) {
|
||||
public void generateBiomeColumn(BiomeInfo[][] localBiomeInfo, int chunkX, int chunkZ, int localX, int localZ,
|
||||
IslandWorldMap islandMap, BiomeMap biomeSelector, TemperatureMap tempGenerator,
|
||||
Cache<Point2, BiomeInfo> biomeCache) {
|
||||
int worldX = 16 * chunkX + localX;
|
||||
int worldZ = 16 * chunkZ + localZ;
|
||||
Point2 worldCoords = new Point2(worldX, worldZ);
|
||||
|
||||
//Check if we can just give it something in cache.
|
||||
Biome[] biomeSet = attemptGetBiomeSet(world, worldX, worldZ, biomeCache, null);
|
||||
if (biomeSet != null) {
|
||||
chunkBiomeSets[localX][localZ] = biomeSet;
|
||||
return;
|
||||
}
|
||||
localBiomeInfo[localX][localZ] = biomeCache.get(worldCoords);
|
||||
if (localBiomeInfo[localX][localZ] != null) return;
|
||||
|
||||
//Fine, check if it's ocean.
|
||||
float temperature = tempGenerator.getTemperature(worldX, worldZ);
|
||||
if (!islandMap.isIsland(worldX, worldZ)) {
|
||||
biomeSet = chunkBiomeSets[localX][localZ];
|
||||
OceanBiomeInfo ocean = biomeSelector.getOceanBiome(tempGen.getTemperature(worldX, worldZ));
|
||||
biomeSet[0] = islandMap.getWorldValue(worldX, worldZ) >= -DEEP_OCEAN_PORTION ? ocean.getOcean() : ocean.getDeepAlternative();
|
||||
setCacheBiome(worldX, worldZ, biomeSet, chunkBiomeSets, biomeCache);
|
||||
BiomeInfo oceanInfo = biomeSelector.getOceanBiome(temperature);
|
||||
localBiomeInfo[localX][localZ] = oceanInfo;
|
||||
biomeCache.set(worldCoords, oceanInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
//Shoot, looks like it's actually an island.
|
||||
IslandInfo islandInfo = new IslandInfo(islandMap, world, biomeCache);
|
||||
Point2 islandOrigin = islandMap.findIslandOrigin(worldX, worldZ, islandInfo);
|
||||
if (!islandInfo.isComplete()) {
|
||||
float temp = tempGen.getTemperature(islandOrigin.x, islandOrigin.y);
|
||||
LandBiomeInfo biomeInfo = biomeSelector.getLandBiomeInfo(temp, islandOrigin.x, islandOrigin.y);
|
||||
islandInfo.biomeset = new Biome[5];
|
||||
islandInfo.biomeset[1] = biomeInfo.getBiome();
|
||||
islandInfo.biomeset[2] = biomeInfo.getPreferredShore() == null ? Biome.BEACH : biomeInfo.getPreferredShore();
|
||||
islandInfo.biomeset[4] = biomeInfo.getHillBiome() == null ? islandInfo.biomeset[1] : biomeInfo.getHillBiome();
|
||||
islandInfo.biomeset[3] = islandInfo.biomeset[2];
|
||||
}
|
||||
|
||||
PropagatorInfo propInfo = new PropagatorInfo(islandInfo.biomeset, chunkBiomeSets, new Point2(chunkX, chunkZ), islandMap, biomeCache);
|
||||
Flooder flooder = new Flooder(new Point2(worldX, worldZ), propInfo);
|
||||
flooder.start();
|
||||
}
|
||||
|
||||
private Biome[] attemptGetBiomeSet(World world, int worldX, int worldZ, Cache<Point2, Biome[]> biomeCache, Biome[][][] chunkBiomeSets) {
|
||||
Point2 worldCoords = new Point2(worldX, worldZ);
|
||||
Biome[] res = null;
|
||||
|
||||
if (chunkBiomeSets != null) {
|
||||
Point2 localCoords = GeneralUtilities.worldToLocalChunkCoordinates(worldCoords);
|
||||
return chunkBiomeSets[localCoords.x][localCoords.y];
|
||||
}
|
||||
|
||||
res = biomeCache.get(worldCoords);
|
||||
return res;
|
||||
}
|
||||
|
||||
private void setCacheBiome(int worldX, int worldZ, Biome[] biomeSet, Biome[][][] localBiomes, Cache<Point2, Biome[]> biomeCache) {
|
||||
Point2 worldCoords = new Point2(worldX, worldZ);
|
||||
if (localBiomes != null) {
|
||||
Point2 localCoords = GeneralUtilities.worldToLocalChunkCoordinates(worldCoords);
|
||||
localBiomes[localCoords.x][localCoords.y] = biomeSet;
|
||||
}
|
||||
biomeCache.set(worldCoords, biomeSet);
|
||||
}
|
||||
|
||||
private class IslandInfo implements CoordinateTargetValidatable, CoordinateValidatable {
|
||||
public final IslandWorldMap mapper;
|
||||
public final World world;
|
||||
private final Cache<Point2, Biome[]> biomeCache;
|
||||
private Biome[] biomeset;
|
||||
|
||||
public IslandInfo(IslandWorldMap mapper, World world, Cache<Point2, Biome[]> biomeCache) {
|
||||
this.mapper = mapper;
|
||||
this.world = world;
|
||||
this.biomeCache = biomeCache;
|
||||
}
|
||||
|
||||
Reference<BiomeInfo> currentIslandInfo = new Reference<>();
|
||||
Point2 islandOrigin = islandMap.findIslandOrigin(worldX, worldZ, new CoordinateTargetValidatable() {
|
||||
@Override
|
||||
public boolean isCoordinateTarget(int x, int y) {
|
||||
biomeset = attemptGetBiomeSet(world, x, y, biomeCache, null);
|
||||
if (biomeset != null) {
|
||||
if (!isComplete()) throw new IllegalStateException("There was an incomplete biome set.");
|
||||
Point2 coord = new Point2(x, y);
|
||||
BiomeInfo info = biomeCache.get(coord);
|
||||
if (info == null) return false;
|
||||
currentIslandInfo.value = info;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (currentIslandInfo.value == null) {
|
||||
currentIslandInfo.value = biomeSelector.getLandBiomeInfo(temperature, islandOrigin.x, islandOrigin.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(int x, int y) {
|
||||
return mapper.isIsland(x, y);
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return !(biomeset == null || biomeset[1] == null || biomeset[2] == null || biomeset[3] == null || biomeset[4] == null);
|
||||
}
|
||||
}
|
||||
|
||||
private class PropagatorInfo implements Floodable {
|
||||
private final Biome[] biomeset;
|
||||
private final Biome[][][] biomes;
|
||||
private final Point2 chunkCoords;
|
||||
private final IslandWorldMap mapper;
|
||||
private final Cache<Point2, Biome[]> biomeCache;
|
||||
|
||||
public PropagatorInfo(Biome[] biomeset, Biome[][][] biomes, Point2 chunkCoords, IslandWorldMap mapper, Cache<Point2, Biome[]> biomeCache) {
|
||||
this.biomeset = biomeset;
|
||||
this.biomes = biomes;
|
||||
this.chunkCoords = chunkCoords;
|
||||
this.mapper = mapper;
|
||||
this.biomeCache = biomeCache;
|
||||
}
|
||||
|
||||
Flooder flooder = new Flooder(worldCoords, new Floodable() {
|
||||
@Override
|
||||
public boolean flood(Point2 point) {
|
||||
Point2 chunkCoords = GeneralUtilities.worldToChunkCoordinates(point);
|
||||
if (!this.chunkCoords.fastEquals(chunkCoords) || !mapper.isIsland(point.x, point.y)) return false;
|
||||
int x = point.x;
|
||||
int y = point.y;
|
||||
Biome[] biomeSet = Arrays.copyOf(biomeset, biomeset.length);
|
||||
if (mapper.isLand(x, y)) {
|
||||
if (mapper.isShore(x, y)) {
|
||||
biomeSet[0] = biomeset[2];
|
||||
} else if (mapper.getWorldValue(x, y) >= HILL_PORTION) {
|
||||
biomeSet[0] = biomeset[4];
|
||||
} else {
|
||||
biomeSet[0] = biomeset[1];
|
||||
}
|
||||
} else {
|
||||
biomeSet[0] = biomeset[3];
|
||||
}
|
||||
|
||||
setCacheBiome(x, y, biomeSet, biomes, biomeCache);
|
||||
if (chunkCoords.x != chunkX || chunkCoords.y != chunkZ || !islandMap.isIsland(point.x, point.y)) return false;
|
||||
biomeCache.set(point, currentIslandInfo.value);
|
||||
Point2 localCoords = GeneralUtilities.worldToLocalChunkCoordinates(point);
|
||||
localBiomeInfo[localCoords.x][localCoords.y] = currentIslandInfo.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
flooder.start();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -14,6 +14,9 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.LandBiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.OceanBiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import ca.recrown.islandsurvivalcraft.world.BiomeMap;
|
||||
@ -27,6 +30,9 @@ import ca.recrown.islandsurvivalcraft.world.generation.shaders.WorldHeightShader
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.shaders.WorldLayerShader;
|
||||
|
||||
public class IslandWorldChunkGenerator extends ChunkGenerator implements Listener {
|
||||
private final float TRANSITION_DEPTH_PORTION = 0.1f;
|
||||
private final float DEEP_OCEAN_PORTION = 0.5f;
|
||||
private final float HILL_BIOME_PORTION = 0.4f;
|
||||
private final int BEDROCK_HEIGHT = 5;
|
||||
private volatile GeneratorModes generatorType;
|
||||
private volatile boolean initialized = false;
|
||||
@ -37,7 +43,7 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene
|
||||
private volatile BiomeGenerator biomeGenerator;
|
||||
private volatile WorldHeightShader heightShader;
|
||||
private volatile WorldLayerShader layerShader;
|
||||
private volatile Cache<Point2, Biome[]> biomeCache = new Cache<>(131072);
|
||||
private volatile Cache<Point2, BiomeInfo> biomeCache = new Cache<>(131072);
|
||||
private final ExecutorService exAlpha = GeneralUtilities.ISC_EXECUTOR_ALPHA;
|
||||
|
||||
public void initialize() {
|
||||
@ -86,40 +92,72 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene
|
||||
|
||||
ChunkData chunkData = createChunkData(world);
|
||||
|
||||
Biome[][][] biomeArraySet = new Biome[GeneralUtilities.CHUNK_SIZE][GeneralUtilities.CHUNK_SIZE][5];
|
||||
BiomeInfo[][] localBiomeInfos = new BiomeInfo[GeneralUtilities.CHUNK_SIZE][GeneralUtilities.CHUNK_SIZE];
|
||||
for (int x = 0; x < GeneralUtilities.CHUNK_SIZE; x++) {
|
||||
for (int z = 0; z < GeneralUtilities.CHUNK_SIZE; z++) {
|
||||
final int localX = x;
|
||||
final int localZ = z;
|
||||
final int worldX = GeneralUtilities.CHUNK_SIZE * chunkX + localX;
|
||||
final int worldZ = GeneralUtilities.CHUNK_SIZE * chunkZ + localZ;
|
||||
if (biomeArraySet[localX][localZ][0] == null) {
|
||||
biomeGenerator.generateBiomeColumn(biomeArraySet, world, chunkX, chunkZ, localX, localZ, islandMap, biomeMap,
|
||||
if (localBiomeInfos[localX][localZ] == null) {
|
||||
biomeGenerator.generateBiomeColumn(localBiomeInfos, chunkX, chunkZ, localX, localZ, islandMap, biomeMap,
|
||||
temperatureMap, biomeCache);
|
||||
}
|
||||
|
||||
if (localBiomeInfos[localX][localZ] == null) throw new IllegalStateException("Biome column produced was null.");
|
||||
Biome currentBiome = null;
|
||||
if (islandMap.isIsland(worldX, worldZ)) {
|
||||
LandBiomeInfo biomeInfo = (LandBiomeInfo) localBiomeInfos[localX][localZ];
|
||||
double islandVal = islandMap.getWorldValue(worldX, worldZ);
|
||||
if (islandVal >= HILL_BIOME_PORTION) {
|
||||
currentBiome = biomeInfo.getHillBiome();
|
||||
for (int y = 0; y < worldInfo.getWorldHeight(); y++) {
|
||||
biomeGrid.setBiome(localX, y, localZ, biomeArraySet[localX][localZ][0]);
|
||||
biomeGrid.setBiome(localX, y, localZ, biomeInfo.getHillBiome());
|
||||
}
|
||||
} else {
|
||||
currentBiome = biomeInfo.getBiome();
|
||||
for (int y = 0; y < worldInfo.getWorldHeight(); y++) {
|
||||
biomeGrid.setBiome(localX, y, localZ, biomeInfo.getBiome());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OceanBiomeInfo biomeInfo = (OceanBiomeInfo) localBiomeInfos[localX][localZ];
|
||||
double oceanVal = islandMap.getWorldValue(worldX, worldZ);
|
||||
if (oceanVal >= TRANSITION_DEPTH_PORTION) {
|
||||
currentBiome = biomeInfo.getTransitionOcean();
|
||||
for (int y = 0; y < worldInfo.getWorldHeight(); y++) {
|
||||
biomeGrid.setBiome(localX, y, localZ, biomeInfo.getTransitionOcean());
|
||||
}
|
||||
} else if (oceanVal >= DEEP_OCEAN_PORTION) {
|
||||
currentBiome = biomeInfo.getOcean();
|
||||
for (int y = 0; y < worldInfo.getWorldHeight(); y++) {
|
||||
biomeGrid.setBiome(localX, y, localZ, biomeInfo.getOcean());
|
||||
}
|
||||
} else {
|
||||
currentBiome = biomeInfo.getDeepAlternative();
|
||||
for (int y = 0; y < worldInfo.getWorldHeight(); y++) {
|
||||
biomeGrid.setBiome(localX, y, localZ, biomeInfo.getDeepAlternative());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Biome[] currentBiomeSet = biomeArraySet[localX][localZ];
|
||||
int terrainHeight = heightShader.getTerrainHeight(worldX, worldZ, currentBiomeSet);
|
||||
BiomeInfo currentBiomeInfo = localBiomeInfos[localX][localZ];
|
||||
int terrainHeight = heightShader.getTerrainHeight(worldX, worldZ, currentBiomeInfo);
|
||||
int currentTerrainHeight = terrainHeight - 1;
|
||||
int bedrockHeight = random.nextInt(5) + 1;
|
||||
if (layerShader.hasSpecialLayers(currentBiomeSet[0])) {
|
||||
BlockData currentMaterial = layerShader.getMaterialForHeight(worldInfo.getSeed(), worldX, worldZ, currentTerrainHeight, terrainHeight - 1, currentBiomeSet);
|
||||
if (layerShader.hasSpecialLayers(currentBiome)) {
|
||||
BlockData currentMaterial = layerShader.getMaterialForHeight(worldInfo.getSeed(), worldX, worldZ, currentTerrainHeight, terrainHeight - 1, currentBiome);
|
||||
while (currentMaterial != null) {
|
||||
chunkData.setBlock(localX, currentTerrainHeight, localZ, currentMaterial);
|
||||
currentTerrainHeight--;
|
||||
currentMaterial = layerShader.getMaterialForHeight(worldInfo.getSeed(), worldX, worldZ, currentTerrainHeight, terrainHeight - 1, currentBiomeSet);
|
||||
currentMaterial = layerShader.getMaterialForHeight(worldInfo.getSeed(), worldX, worldZ, currentTerrainHeight, terrainHeight - 1, currentBiome);
|
||||
}
|
||||
} else {
|
||||
int surfaceThickness = layerShader.getSurfaceThickness(worldX, worldZ, currentBiomeSet[0]);
|
||||
int surfaceThickness = layerShader.getSurfaceThickness(worldX, worldZ, currentBiome);
|
||||
currentTerrainHeight = currentTerrainHeight - surfaceThickness;
|
||||
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + surfaceThickness + 1, localZ + 1, layerShader.getSurfaceMaterial(currentBiomeSet[0]));
|
||||
int transitionThickness = layerShader.getTransitionMaterialThickness(worldX, worldZ, currentBiomeSet[0]);
|
||||
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + surfaceThickness + 1, localZ + 1, layerShader.getSurfaceMaterial(currentBiome));
|
||||
int transitionThickness = layerShader.getTransitionMaterialThickness(worldX, worldZ, currentBiome);
|
||||
currentTerrainHeight = currentTerrainHeight - transitionThickness;
|
||||
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + transitionThickness + 1, localZ + 1, layerShader.getTransitionMaterial(currentBiomeSet[0]));
|
||||
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + transitionThickness + 1, localZ + 1, layerShader.getTransitionMaterial(currentBiome));
|
||||
}
|
||||
chunkData.setRegion(localX, bedrockHeight, localZ, localX + 1, currentTerrainHeight + 1, localZ + 1, Material.STONE);
|
||||
if (terrainHeight < worldInfo.getSeaLevel()) {
|
||||
|
@ -5,6 +5,7 @@ import java.util.Random;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.util.noise.SimplexOctaveGenerator;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.world.IslandWorldMap;
|
||||
|
||||
public class WorldHeightShader {
|
||||
@ -23,25 +24,16 @@ public class WorldHeightShader {
|
||||
this.noiseGenerator.setScale(0.0225d);
|
||||
}
|
||||
|
||||
public int getTerrainHeight(int worldX, int worldZ, Biome[] biomeSet) {
|
||||
public int getTerrainHeight(int worldX, int worldZ, BiomeInfo biomeInfo) {
|
||||
int height = 0;
|
||||
String biomeName = biomeSet[0].name().toLowerCase();
|
||||
if (!mapper.isLand(worldX, worldZ)) {
|
||||
height = (int) Math.floor(calculateTerrainFactor(worldX, worldZ, seaLevel * 0.8d, 1.7d, 0.5d, 1d, 0.09d));
|
||||
} else if (biomeName.contains("beach")) {
|
||||
if (biomeSet[1].name().toLowerCase().contains("mountains")) {
|
||||
height = (int) (getIslandBiomeHeight(worldX, worldZ, biomeSet[1], -15d));
|
||||
} else {
|
||||
height = (int) (getIslandBiomeHeight(worldX, worldZ, biomeSet[1], 0d));
|
||||
}
|
||||
} else if (biomeName.contains("shore")) {
|
||||
height = (int) (getIslandBiomeHeight(worldX, worldZ, biomeSet[1], -15d));
|
||||
} else {
|
||||
height = getIslandBiomeHeight(worldX, worldZ, biomeSet[0], 0d) + 1;
|
||||
height = getIslandBiomeHeight(worldX, worldZ, biomeInfo.getMainBiome(), 0d);
|
||||
}
|
||||
|
||||
height = Math.max(minimumHeight, height);
|
||||
if (height > worldHeight) throw new IllegalStateException(String.format("Resulting height is greater than world height! Current biome set: %s, maximum height: %d, minimum height %d", biomeSet, worldHeight, minimumHeight));
|
||||
if (height > worldHeight) throw new IllegalStateException(String.format("Resulting height is greater than world height! Current biome info: %s, maximum height: %d, minimum height %d", biomeInfo, worldHeight, minimumHeight));
|
||||
return height;
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,8 @@ public class WorldLayerShader {
|
||||
* @param biomeSet The biomeset for the current column.
|
||||
* @return The block data for the material, or null if there are no further special materials.
|
||||
*/
|
||||
public BlockData getMaterialForHeight(long seed, int worldX, int worldZ, int y, int highestPoint, Biome[] biomeSet) {
|
||||
Biome mainBiome = biomeSet[0];
|
||||
public BlockData getMaterialForHeight(long seed, int worldX, int worldZ, int y, int highestPoint, Biome currentBiome) {
|
||||
Biome mainBiome = currentBiome;
|
||||
String mainBiomeName = mainBiome.toString().toLowerCase();
|
||||
BlockData res = null;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,6 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -20,19 +19,17 @@ import org.junit.jupiter.api.Timeout;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import ca.recrown.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import ca.recrown.islandsurvivalcraft.world.BiomeMap;
|
||||
import ca.recrown.islandsurvivalcraft.world.IslandWorldMap;
|
||||
import ca.recrown.islandsurvivalcraft.world.TemperatureMap;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.DummyWorld;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class UniqueBiomeGeneratorTest {
|
||||
private final int SEED = 249398015;
|
||||
private final DummyWorld dummyWorld = new DummyWorld();
|
||||
private volatile Cache<Point2, Double> blockValueCache;
|
||||
private volatile Cache<Point2, Biome[]> biomeCache;
|
||||
private volatile Cache<Point2, BiomeInfo> biomeCache;
|
||||
private final BiomeMap biomeSelector = new BiomeMap(new Random(SEED));
|
||||
|
||||
|
||||
@ -59,11 +56,11 @@ public class UniqueBiomeGeneratorTest {
|
||||
TemperatureMap temperatureMapGenerator = new TemperatureMap(random);
|
||||
BiomeGenerator biomeGenerator = new UniqueBiomeGenerator();
|
||||
|
||||
Biome[][][] biomes = new Biome[GeneralUtilities.CHUNK_SIZE][GeneralUtilities.CHUNK_SIZE][4];
|
||||
BiomeInfo[][] biomes = new BiomeInfo[GeneralUtilities.CHUNK_SIZE][GeneralUtilities.CHUNK_SIZE];
|
||||
for (int localX = 0; localX < GeneralUtilities.CHUNK_SIZE; localX++) {
|
||||
for (int localZ = 0; localZ < GeneralUtilities.CHUNK_SIZE; localZ++) {
|
||||
if (biomes[localX][localZ] == null) {
|
||||
biomeGenerator.generateBiomeColumn(biomes, dummyWorld, chunkX, chunkZ, localX, localZ, mapper,
|
||||
biomeGenerator.generateBiomeColumn(biomes, chunkX, chunkZ, localX, localZ, mapper,
|
||||
biomeSelector, temperatureMapGenerator, biomeCache);
|
||||
}
|
||||
if (biomes[localX][localZ] == null)
|
||||
@ -79,13 +76,11 @@ public class UniqueBiomeGeneratorTest {
|
||||
|
||||
@BeforeEach
|
||||
public void individualSetup() {
|
||||
blockValueCache = new Cache<>(524288);
|
||||
biomeCache = new Cache<>(524288);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void individualCleanup() {
|
||||
blockValueCache.clearCache();
|
||||
biomeCache.clearCache();
|
||||
}
|
||||
|
||||
@ -122,7 +117,6 @@ public class UniqueBiomeGeneratorTest {
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread1608ChunksSmallCache() {
|
||||
this.blockValueCache = new Cache<>(1024);
|
||||
this.biomeCache = new Cache<>(1024);
|
||||
|
||||
int chunksToDoEach = 268;
|
||||
@ -192,7 +186,6 @@ public class UniqueBiomeGeneratorTest {
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread1608ChunksScatteredColumnsSmallCache() {
|
||||
this.blockValueCache = new Cache<>(1024);
|
||||
this.biomeCache = new Cache<>(1024);
|
||||
int chunksToDoEach = 268;
|
||||
Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
|
||||
@ -254,7 +247,6 @@ public class UniqueBiomeGeneratorTest {
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread6000ChunksScatteredColumnsSmallCache() {
|
||||
this.blockValueCache = new Cache<>(1024);
|
||||
this.biomeCache = new Cache<>(1024);
|
||||
|
||||
int chunksToDoEach = 1000;
|
||||
|
Loading…
Reference in New Issue
Block a user