Refactoring with different heavy changes to biome generator.
Attempt at making it my async compatible.
This commit is contained in:
parent
0886412cfb
commit
6ac686b86c
@ -3,15 +3,15 @@ package ca.recrown.islandsurvivalcraft;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.world.IslandSurvivalCraftChunkGenerator;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.BiomePerIslandGenerator;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.alternation.AlternatingChunkGenerator;
|
||||
|
||||
public class IslandSurvivalCraft extends JavaPlugin {
|
||||
IslandSurvivalCraftChunkGenerator generator;
|
||||
AlternatingChunkGenerator generator;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
generator = new IslandSurvivalCraftChunkGenerator(this, new BiomePerIslandGenerator());
|
||||
generator = new AlternatingChunkGenerator(this, new BiomePerIslandGenerator());
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
package ca.recrown.islandsurvivalcraft.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.IslandBiomeGenerator;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.IslandWorldGenerator;
|
||||
|
||||
public class IslandSurvivalCraftChunkGenerator extends ChunkGenerator {
|
||||
private final IslandWorldGeneratorAlternator alternator;
|
||||
|
||||
public IslandSurvivalCraftChunkGenerator(JavaPlugin plugin, IslandBiomeGenerator biomeGenerator) {
|
||||
alternator = new IslandWorldGeneratorAlternator(plugin, biomeGenerator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biome) {
|
||||
IslandWorldGenerator worldGenerator = alternator.getIslandChunkGeneratorSystem(world, random);
|
||||
ChunkData chunk = createChunkData(world);
|
||||
|
||||
for (int localX = 0; localX < 16; localX++) {
|
||||
for (int localZ = 0; localZ < 16; localZ++) {
|
||||
worldGenerator.GenerateChunk(chunkX, chunkZ, localX, localZ, chunk, biome);
|
||||
}
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@ import org.bukkit.event.Listener;
|
||||
import ca.recrown.islandsurvivalcraft.world.BiomeSelector;
|
||||
import ca.recrown.islandsurvivalcraft.world.IslandWorldMapper;
|
||||
|
||||
public interface IslandBiomeGenerator extends Listener {
|
||||
public interface BiomeGenerator extends Listener {
|
||||
public void initialize(World world, IslandWorldMapper mapGenerator, BiomeSelector biomeSelector);
|
||||
public Biome GenerateBiome(int chunkX, int chunkZ, int localX, int localZ);
|
||||
public IslandBiomeGenerator getInstance();
|
||||
public BiomeGenerator getInstance();
|
||||
}
|
@ -17,7 +17,7 @@ import ca.recrown.islandsurvivalcraft.world.BiomeSelector;
|
||||
import ca.recrown.islandsurvivalcraft.world.IslandWorldMapper;
|
||||
|
||||
//Note: technically, the validators have to be run on land, and so, some condition checks may not be nessecary.
|
||||
public class BiomePerIslandGenerator implements IslandBiomeGenerator {
|
||||
public class BiomePerIslandGenerator implements BiomeGenerator {
|
||||
private volatile boolean initialized;
|
||||
private final TemperatureMapGenerator temperatureMapGenerator;
|
||||
private final Cache<Point2, Biome> chunkBiomesCache;
|
||||
@ -25,16 +25,11 @@ public class BiomePerIslandGenerator implements IslandBiomeGenerator {
|
||||
private volatile IslandWorldMapper worldIslandMap;
|
||||
private volatile BiomeSelector biomeSelector;
|
||||
private volatile World world;
|
||||
private volatile Point2 currChunkCoords;
|
||||
private volatile Biome[][] localChunkCache;
|
||||
|
||||
float temperature;
|
||||
|
||||
public BiomePerIslandGenerator() {
|
||||
this.temperatureMapGenerator = new TemperatureMapGenerator();
|
||||
chunkBiomesCache = new Cache<>(65536);
|
||||
chunkGenStatusCache = new Cache<>(16384);
|
||||
localChunkCache = new Biome[16][16];
|
||||
chunkGenStatusCache = new Cache<>(65536);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -47,7 +42,7 @@ public class BiomePerIslandGenerator implements IslandBiomeGenerator {
|
||||
this.temperatureMapGenerator.setSeed(world.getSeed());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onChunkLoaded(ChunkLoadEvent event) {
|
||||
if (event.isNewChunk()) {
|
||||
Chunk chunk = event.getChunk();
|
||||
@ -58,25 +53,23 @@ public class BiomePerIslandGenerator implements IslandBiomeGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IslandBiomeGenerator getInstance() {
|
||||
public BiomeGenerator getInstance() {
|
||||
return new BiomePerIslandGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome GenerateBiome(int chunkX, int chunkZ, int localX, int localZ) {
|
||||
if (currChunkCoords == null || chunkX != currChunkCoords.x || chunkZ != currChunkCoords.y) {
|
||||
currChunkCoords = new Point2(chunkX, chunkZ);
|
||||
localChunkCache = new Biome[16][16];
|
||||
}
|
||||
int worldX = Utilities.addMagnitude(16 * chunkX, localX);
|
||||
int worldZ = Utilities.addMagnitude(16 * chunkZ, localZ);
|
||||
Point2 currChunkCoords = new Point2(chunkX, chunkZ);
|
||||
|
||||
int worldX = 16 * chunkX + localX;
|
||||
int worldZ = 16 * chunkZ + localZ;
|
||||
|
||||
Point2 worldCoords = new Point2(worldX, worldZ);
|
||||
|
||||
Biome cachedBiome = getBiome(worldCoords);
|
||||
Biome cachedBiome = getStoredBiome(worldCoords);
|
||||
if (cachedBiome != null) return cachedBiome;
|
||||
|
||||
temperature = temperatureMapGenerator.getTemperature(worldX, worldZ);
|
||||
float temperature = temperatureMapGenerator.getTemperature(worldX, worldZ);
|
||||
if (!worldIslandMap.isIsland(worldX, worldZ)) {
|
||||
return biomeSelector.getOceanBiome(temperature);
|
||||
}
|
||||
@ -89,28 +82,30 @@ public class BiomePerIslandGenerator implements IslandBiomeGenerator {
|
||||
if (biomeInfo.shore == null) biomeInfo.shore = biomeSelector.getShoreBiome(biomeInfo.main, temperature);
|
||||
if (biomeInfo.shallow == null) biomeInfo.shallow = biomeSelector.getOceanBiome(temperature);
|
||||
}
|
||||
FreshCachePropagationInfo propInfo = new FreshCachePropagationInfo(biomeInfo.main, biomeInfo.shore, biomeInfo.shallow);
|
||||
PropagatorInfo propInfo = new PropagatorInfo(biomeInfo.main, biomeInfo.shore, biomeInfo.shallow, currChunkCoords);
|
||||
DepthFirstSearch prop = new DepthFirstSearch(propInfo);
|
||||
prop.setStartPosition(worldX, worldZ);
|
||||
prop.findTarget(propInfo);
|
||||
return getBiome(worldCoords);
|
||||
|
||||
if (worldIslandMap.isLand(worldX, worldZ)) {
|
||||
if (worldIslandMap.isShore(worldX, worldZ)) {
|
||||
return biomeInfo.shore;
|
||||
} else {
|
||||
return biomeInfo.main;
|
||||
}
|
||||
} else {
|
||||
return biomeInfo.shallow;
|
||||
}
|
||||
}
|
||||
|
||||
private Biome getBiome(Point2 worldCoords) {
|
||||
int localX = Math.abs(worldCoords.x % 16);
|
||||
int localZ = Math.abs(worldCoords.y % 16);
|
||||
Point2 chunkCoords = new Point2(worldCoords.x / 16, worldCoords.y / 16);
|
||||
private Biome getStoredBiome(Point2 worldCoords) {
|
||||
Point2 chunkCoords = Utilities.worldToChunkCoordinates(worldCoords);
|
||||
|
||||
//chunk local
|
||||
if (chunkCoords.fastEquals(this.currChunkCoords) && localChunkCache[localX][localZ] != null) {
|
||||
return localChunkCache[localX][localZ];
|
||||
}
|
||||
|
||||
//cache local
|
||||
//Search our cache first.
|
||||
Biome biome = chunkBiomesCache.getValue(worldCoords);
|
||||
if (biome != null) return biome;
|
||||
|
||||
//files local
|
||||
//Check to see if bukkit has anything to say about it.
|
||||
Boolean chunkGenStat = chunkGenStatusCache.getValue(chunkCoords);
|
||||
if (chunkGenStat == null) {
|
||||
chunkGenStat = world.isChunkGenerated(chunkCoords.x, chunkCoords.y);
|
||||
@ -122,49 +117,52 @@ public class BiomePerIslandGenerator implements IslandBiomeGenerator {
|
||||
chunkBiomesCache.setValue(worldCoords, biome);
|
||||
return biome;
|
||||
}
|
||||
|
||||
//Guess it's not cached or created.
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setCacheBiome(Point2 worldCoords, Biome biome) {
|
||||
int localX = Math.abs(worldCoords.x % 16);
|
||||
int localZ = Math.abs(worldCoords.y % 16);
|
||||
Point2 chunkCoords = new Point2(worldCoords.x / 16, worldCoords.y / 16);
|
||||
|
||||
//If local, set it locally.
|
||||
if (chunkCoords.fastEquals(this.currChunkCoords)) localChunkCache[localX][localZ] = biome;
|
||||
|
||||
//Set it cache wide.
|
||||
//Set it in cache.
|
||||
chunkBiomesCache.setValue(worldCoords, biome);
|
||||
}
|
||||
|
||||
private class FreshCachePropagationInfo implements CoordinateTargetValidatable, CoordinateValidatable {
|
||||
private class PropagatorInfo implements CoordinateTargetValidatable, CoordinateValidatable {
|
||||
public final Biome main, shore, shallow;
|
||||
private final Point2 currentChunkCoords;
|
||||
private boolean hasSet;
|
||||
|
||||
@Override
|
||||
public boolean isCoordinateTarget(int x, int y) {
|
||||
hasSet = false;
|
||||
Point2 worldCoords = new Point2(x, y);
|
||||
if (worldIslandMap.isLand(x, y)) {
|
||||
if (worldIslandMap.isShore(x, y)) {
|
||||
setCacheBiome(worldCoords, shore);
|
||||
hasSet = true;
|
||||
} else {
|
||||
setCacheBiome(worldCoords, main);
|
||||
hasSet = true;
|
||||
}
|
||||
} else {
|
||||
setCacheBiome(worldCoords, shallow);
|
||||
hasSet = true;
|
||||
}
|
||||
if (!hasSet) throw new IllegalStateException();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(int x, int y) {
|
||||
Point2 chunkCoords = new Point2(x / 16, y / 16);
|
||||
return chunkCoords.fastEquals(currChunkCoords) && worldIslandMap.isIsland(x, y);
|
||||
Point2 chunkCoords = Utilities.worldToChunkCoordinates(x, y);
|
||||
return chunkCoords.fastEquals(currentChunkCoords) && worldIslandMap.isIsland(x, y);
|
||||
}
|
||||
|
||||
public FreshCachePropagationInfo(Biome main, Biome shore, Biome shallow) {
|
||||
public PropagatorInfo(Biome main, Biome shore, Biome shallow, Point2 currentChunkCoords) {
|
||||
this.main = main;
|
||||
this.shore = shore;
|
||||
this.shallow = shallow;
|
||||
this.currentChunkCoords = currentChunkCoords;
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,13 +189,13 @@ public class BiomePerIslandGenerator implements IslandBiomeGenerator {
|
||||
}
|
||||
|
||||
if (main == null && isLand && !isShore) {
|
||||
main = getBiome(worldCoords);
|
||||
main = getStoredBiome(worldCoords);
|
||||
} else
|
||||
if (shore == null && isShore) {
|
||||
shore = getBiome(worldCoords);
|
||||
shore = getStoredBiome(worldCoords);
|
||||
} else
|
||||
if (shallow == null && isShallow) {
|
||||
shallow = getBiome(worldCoords);
|
||||
shallow = getStoredBiome(worldCoords);
|
||||
}
|
||||
return allBiomesAcquired();
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.Utilities;
|
||||
import ca.recrown.islandsurvivalcraft.world.BiomeSelector;
|
||||
import ca.recrown.islandsurvivalcraft.world.IslandWorldMapper;
|
||||
import ca.recrown.islandsurvivalcraft.world.shaders.WorldHeightShader;
|
||||
@ -18,17 +17,17 @@ import ca.recrown.islandsurvivalcraft.world.shaders.WorldHeightShader;
|
||||
/**
|
||||
* A world generator.
|
||||
*/
|
||||
public class IslandWorldGenerator {
|
||||
public class WorldGenerator {
|
||||
private final int maxHeight;
|
||||
private final BedrockGenerator bedrockGenerator;
|
||||
private final BiomeSelector biomeSelector;
|
||||
private final IslandBiomeGenerator biomeGenerator;
|
||||
private final BiomeGenerator biomeGenerator;
|
||||
private final WorldHeightShader heightShader;
|
||||
public final World world;
|
||||
public final IslandWorldMapper islandMapGenerator;
|
||||
public final Random random;
|
||||
|
||||
public IslandWorldGenerator(JavaPlugin plugin, World world, IslandBiomeGenerator islandBiomeGenerator, Random random) {
|
||||
public WorldGenerator(JavaPlugin plugin, World world, BiomeGenerator islandBiomeGenerator, Random random) {
|
||||
this.world = world;
|
||||
this.maxHeight = world.getMaxHeight();
|
||||
this.random = random;
|
||||
@ -46,19 +45,18 @@ public class IslandWorldGenerator {
|
||||
}
|
||||
|
||||
public void GenerateChunk(int chunkX, int chunkZ, int localX, int localZ, ChunkData chunk, BiomeGrid biomeGrid) {
|
||||
int worldX = Utilities.addMagnitude(16 * chunkX, localX);
|
||||
int worldZ = Utilities.addMagnitude(16 * chunkZ, localZ);
|
||||
int worldX = 16 * chunkX + localX;
|
||||
int worldZ = 16 * chunkZ + localZ;
|
||||
|
||||
|
||||
// gets the bedrock.
|
||||
int bedrockHeight = bedrockGenerator.getBedrockHeight(worldX, worldZ);
|
||||
|
||||
//Sets the biome.
|
||||
Biome currentBiome = biomeGenerator.GenerateBiome(chunkX, chunkZ, localX, localZ);
|
||||
if (currentBiome == null) throw new IllegalStateException("Biome generated was null!");
|
||||
for (int y = 0; y < maxHeight; y++) {
|
||||
biomeGrid.setBiome(localX, y, localZ, currentBiome);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//get height shader.
|
||||
int height = 0;
|
||||
try {
|
||||
@ -69,8 +67,12 @@ public class IslandWorldGenerator {
|
||||
}
|
||||
if (height == 0) throw new IllegalStateException("Height generated was null!");
|
||||
|
||||
|
||||
// gets the bedrock height.
|
||||
int bedrockHeight = bedrockGenerator.getBedrockHeight(worldX, worldZ);
|
||||
|
||||
//set general shape
|
||||
chunk.setRegion(localX, 0, localZ, localX + 1, height, localZ + 1, Material.STONE);
|
||||
chunk.setRegion(localX, bedrockHeight, localZ, localX + 1, height, localZ + 1, Material.STONE);
|
||||
|
||||
//set bedrock last
|
||||
chunk.setRegion(localX, 0, localZ, localX + 1, bedrockHeight, localZ + 1, Material.BEDROCK);
|
@ -0,0 +1,32 @@
|
||||
package ca.recrown.islandsurvivalcraft.world.generation.alternation;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.BiomeGenerator;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.WorldGenerator;
|
||||
|
||||
public class AlternatingChunkGenerator extends ChunkGenerator {
|
||||
private final WorldGeneratorAlternator alternator;
|
||||
|
||||
public AlternatingChunkGenerator(JavaPlugin plugin, BiomeGenerator biomeGenerator) {
|
||||
alternator = new WorldGeneratorAlternator(plugin, biomeGenerator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biome) {
|
||||
WorldGenerator worldGenerator = alternator.getGenerator(world, random);
|
||||
ChunkData chunk = createChunkData(world);
|
||||
|
||||
for (int localX = 0; localX < 16; localX++) {
|
||||
for (int localZ = 0; localZ < 16; localZ++) {
|
||||
worldGenerator.GenerateChunk(chunkX, chunkZ, localX, localZ, chunk, biome);
|
||||
}
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package ca.recrown.islandsurvivalcraft.world;
|
||||
package ca.recrown.islandsurvivalcraft.world.generation.alternation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
@ -10,30 +10,30 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.IslandBiomeGenerator;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.IslandWorldGenerator;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.BiomeGenerator;
|
||||
import ca.recrown.islandsurvivalcraft.world.generation.WorldGenerator;
|
||||
|
||||
/**
|
||||
* Alternates the data used on a per world basis.
|
||||
* Uses IslandWorldGenerator as the container for each world.
|
||||
*/
|
||||
public class IslandWorldGeneratorAlternator {
|
||||
private final HashMap<UUID, IslandWorldGenerator> chunkGenerators;
|
||||
private volatile IslandWorldGenerator lastGenerator;
|
||||
public class WorldGeneratorAlternator {
|
||||
private final HashMap<UUID, WorldGenerator> chunkGenerators;
|
||||
private volatile WorldGenerator lastGenerator;
|
||||
private volatile UUID lastUUID;
|
||||
private final IslandBiomeGenerator islandBiomeGenerator;
|
||||
private final BiomeGenerator islandBiomeGenerator;
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
|
||||
private final ReadLock readLock = lock.readLock();
|
||||
private final WriteLock writeLock = lock.writeLock();
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
public IslandWorldGeneratorAlternator(JavaPlugin plugin, IslandBiomeGenerator biomeGenerator) {
|
||||
public WorldGeneratorAlternator(JavaPlugin plugin, BiomeGenerator biomeGenerator) {
|
||||
this.chunkGenerators = new HashMap<>();
|
||||
this.islandBiomeGenerator = biomeGenerator;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public IslandWorldGenerator getIslandChunkGeneratorSystem(World world, Random random) {
|
||||
public WorldGenerator getGenerator(World world, Random random) {
|
||||
if (lastUUID == null || (lastUUID.hashCode() != world.getUID().hashCode() && lastUUID.equals(world.getUID()))) {
|
||||
System.out.println("Alternating generator for world: " + world.getName());
|
||||
lastUUID = world.getUID();
|
||||
@ -44,7 +44,7 @@ public class IslandWorldGeneratorAlternator {
|
||||
readLock.unlock();
|
||||
}
|
||||
if (lastGenerator == null) {
|
||||
lastGenerator = new IslandWorldGenerator(plugin, world, islandBiomeGenerator, random);
|
||||
lastGenerator = new WorldGenerator(plugin, world, islandBiomeGenerator, random);
|
||||
writeLock.lock();
|
||||
try {
|
||||
chunkGenerators.put(lastUUID, lastGenerator);
|
Loading…
Reference in New Issue
Block a user