diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/IslandSurvivalCraft.java b/src/main/java/ca/recrown/islandsurvivalcraft/IslandSurvivalCraft.java index 9745902..7711dd0 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/IslandSurvivalCraft.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/IslandSurvivalCraft.java @@ -1,9 +1,9 @@ package ca.recrown.islandsurvivalcraft; -import org.bukkit.World; import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.java.JavaPlugin; +import ca.recrown.islandsurvivalcraft.worldgeneration.BiomePerIslandGenerator; import ca.recrown.islandsurvivalcraft.worldgeneration.IslandSurvivalCraftWorldGenerator; public class IslandSurvivalCraft extends JavaPlugin { @@ -11,6 +11,8 @@ public class IslandSurvivalCraft extends JavaPlugin { @Override public void onEnable() { + generator = new IslandSurvivalCraftWorldGenerator(new BiomePerIslandGenerator()); + generator.initialize(); super.onEnable(); } @@ -21,10 +23,6 @@ public class IslandSurvivalCraft extends JavaPlugin { @Override public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { - if (generator == null) { - World world = getServer().getWorld(worldName); - generator = new IslandSurvivalCraftWorldGenerator(this, world, true); - } return generator; } } diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearch.java b/src/main/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearch.java index f5edc1b..344c3ba 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearch.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearch.java @@ -82,7 +82,7 @@ public class DepthFirstSearch { * @param targetValidator * @return */ - public boolean findEndNode(CoordinateTargetValidatable targetValidator) { + public boolean findTarget(CoordinateTargetValidatable targetValidator) { queue = new LinkedList<>(); checkedNodes.clear(); Node begin = startNode; diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BedrockGenerator.java b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BedrockGenerator.java index 587d78e..ddfb72e 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BedrockGenerator.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BedrockGenerator.java @@ -5,10 +5,14 @@ import java.util.Random; import org.bukkit.util.noise.SimplexOctaveGenerator; public class BedrockGenerator { + private Random random; private SimplexOctaveGenerator noiseGenerator; private final int maxBedrockHeight = 5; private final int minBedrockHeight = 1; - public BedrockGenerator(Random random) { + + public void setRandom(Random random) { + if (random.equals(this.random)) return; + this.random = random; noiseGenerator = new SimplexOctaveGenerator(random, 8); noiseGenerator.setScale(0.1D); } diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomePerIslandGenerator.java b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomePerIslandGenerator.java index 25939ce..3a86e5c 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomePerIslandGenerator.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomePerIslandGenerator.java @@ -1,157 +1,85 @@ package ca.recrown.islandsurvivalcraft.worldgeneration; -import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.generator.ChunkGenerator.BiomeGrid; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandMetadataType; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandOwnerMetadata; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandShoreBiomeMetadata; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandTUIDMetadata; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandTemperatureMetadata; import ca.recrown.islandsurvivalcraft.pathfinding.CoordinateTargetValidatable; -import ca.recrown.islandsurvivalcraft.IslandSurvivalCraft; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandBedrockMetadataHelper; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandMainBiomeMetadata; -import ca.recrown.islandsurvivalcraft.islandbedrockmetadata.IslandMetadataPack; +import ca.recrown.islandsurvivalcraft.pathfinding.DepthFirstSearch; public class BiomePerIslandGenerator implements IslandBiomeGenerator, CoordinateTargetValidatable { - private IslandMapGenerator mapGenerator; - private Biome currentIslandBiome; - private float currentIslandTemperature; - private Biome currentIslandShoreBiome; + private IslandMapGenerator islandMapGenerator; private BiomeSelector biomeSelector; - private int worldHeight; - private World world; - private IslandBedrockMetadataHelper metadataHelper; private TemperatureMapGenerator temperatureMapGenerator; - private String currentTUID; - private IslandSurvivalCraft plugin; - - public BiomePerIslandGenerator(IslandSurvivalCraft plugin, World world, IslandMapGenerator mapGenerator, BiomeSelector biomeSelector, TemperatureMapGenerator temperatureMapGenerator) { - this.plugin = plugin; - this.temperatureMapGenerator = temperatureMapGenerator; - this.worldHeight = world.getMaxHeight(); - this.mapGenerator = mapGenerator; + private int buildHeight; + private World world; + private DepthFirstSearch dfs; + private Biome mainBiome; + private Biome shoreBiome; + private float temperature; + + public BiomePerIslandGenerator() { + this.temperatureMapGenerator = new TemperatureMapGenerator(); + dfs = new DepthFirstSearch(islandMapGenerator); + } + + @Override + public void initialize(IslandMapGenerator mapGenerator, BiomeSelector biomeSelector) { + this.islandMapGenerator = mapGenerator; this.biomeSelector = biomeSelector; + } + + @Override + public void setWorld(World world) { + if (world.equals(this.world)) return; this.world = world; - this.metadataHelper = new IslandBedrockMetadataHelper(plugin, world); - } - - public void GenerateBiome(int chunkX, int chunkZ, int localX, int localZ, BiomeGrid biome) { - int worldX = chunkX * 16 + localX; - int worldZ = chunkZ * 16 + localZ; - - if (mapGenerator.isIsland(worldX, worldZ)) { - IslandMetadataPack sameIslandPack = getSurroundingIslandData(worldX, worldZ); - if (sameIslandPack != null) { - //Old island - currentIslandBiome = sameIslandPack.mainBiomeMetadata.getMainBiome(); - currentIslandShoreBiome = sameIslandPack.shoreBiomeMetadata.getShoreBiome(); - currentIslandTemperature = sameIslandPack.temperatureMetadata.getTemperature(); - currentTUID = sameIslandPack.islandTIUDMetadata.getIUID(); - } else { - - - //New island - currentIslandTemperature = temperatureMapGenerator.getTemperature(worldX, worldZ); - currentIslandBiome = biomeSelector.getLandBiome(currentIslandTemperature); - currentIslandShoreBiome = biomeSelector.getShoreBiome(currentIslandBiome, currentIslandTemperature); - if (currentIslandShoreBiome == null) { - currentIslandShoreBiome = currentIslandBiome; - } - currentTUID = String.valueOf(worldX) + String.valueOf(worldZ); - } - //saving information - IslandMetadataPack current = new IslandMetadataPack(); - current.setMainBiome(currentIslandBiome, plugin); - current.setTemperature(currentIslandTemperature, plugin); - current.setShoreBiome(currentIslandShoreBiome, plugin); - current.setTUID(currentTUID, plugin); - metadataHelper.setIslandBedrockMetadataPack(worldX, worldZ, current); - - //Set the biome information for the chunk - if (mapGenerator.isShore(worldX, worldZ)) { - setBiome(localX, localZ, biome, currentIslandShoreBiome); - } else { - setBiome(localX, localZ, biome, currentIslandBiome); - } - - //Check if island besides this one need to be generated. - if (localX == 0 && mapGenerator.isSameIsland(worldX, worldZ, worldX - 1, worldZ)) { - if (!world.isChunkGenerated(chunkX - 1, chunkZ)) { - Chunk chunk = world.getChunkAt(chunkX - 1, chunkZ); - chunk.load(true); - chunk.unload(true); - } - } else if (localX == 15 && mapGenerator.isSameIsland(worldX, worldZ, worldX + 1, worldZ)) { - if (!world.isChunkGenerated(chunkX + 1, chunkZ)) { - Chunk chunk = world.getChunkAt(chunkX + 1, chunkZ); - chunk.load(true); - chunk.unload(true); - } - } - - if (localZ == 0 && mapGenerator.isSameIsland(worldX, worldZ, worldX, worldZ - 1)) { - if (!world.isChunkGenerated(chunkX, chunkZ - 1)) { - Chunk chunk = world.getChunkAt(chunkX, chunkZ - 1); - chunk.load(true); - chunk.unload(true); - } - } else if (localZ == 15 && mapGenerator.isSameIsland(worldX, worldZ, worldX, worldZ + 1)) { - if (!world.isChunkGenerated(chunkX, chunkZ + 1)) { - Chunk chunk = world.getChunkAt(chunkX, chunkZ + 1); - chunk.load(true); - chunk.unload(true); - } - } - } - - } - - private IslandMetadataPack getSurroundingIslandData(int worldX, int worldZ) { - IslandMetadataPack data = null; - if (mapGenerator.isSameIsland(worldX, worldZ, worldX + 1, worldZ)) { - data = getMetadataPackAt(worldX + 1, worldZ, world); - - } else if (mapGenerator.isSameIsland(worldX, worldZ, worldX - 1, worldZ)) { - data = getMetadataPackAt(worldX - 1, worldZ, world); - - } else if (mapGenerator.isSameIsland(worldX, worldZ, worldX, worldZ + 1)) { - data = getMetadataPackAt(worldX, worldZ + 1, world); - - } else if (mapGenerator.isSameIsland(worldX, worldZ, worldX, worldZ - 1)) { - data = getMetadataPackAt(worldX, worldZ - 1, world); - - } - return data; - } - - private IslandMetadataPack getMetadataPackAt(int worldX, int worldZ, World world) { - IslandMetadataPack data = new IslandMetadataPack(); - data.mainBiomeMetadata = (IslandMainBiomeMetadata) metadataHelper.getIslandBedrockMetadata(worldX, worldZ, - IslandMetadataType.mainBiome); - data.shoreBiomeMetadata = (IslandShoreBiomeMetadata) metadataHelper.getIslandBedrockMetadata(worldX, worldZ, - IslandMetadataType.shoreBiome); - data.temperatureMetadata = (IslandTemperatureMetadata) metadataHelper.getIslandBedrockMetadata(worldX, worldZ, - IslandMetadataType.temperature); - data.ownerMetadata = (IslandOwnerMetadata) metadataHelper.getIslandBedrockMetadata(worldX, worldZ, - IslandMetadataType.ownerUUID); - data.islandTIUDMetadata = (IslandTUIDMetadata) metadataHelper.getIslandBedrockMetadata(worldX, worldZ, - IslandMetadataType.TIUD); - return data; - } - - private void setBiome(int localX, int localZ, BiomeGrid biomeGrid, Biome biome) { - for (int y = 0; y < worldHeight; y++) { - biomeGrid.setBiome(localX, y, localZ, biome); - } + this.temperatureMapGenerator.setSeed(world.getSeed()); + this.buildHeight = world.getMaxHeight(); } @Override public boolean isCoordinateTarget(int x, int y) { - + if (world.isChunkGenerated(x/16, y/16)) { + Biome foundBiome = world.getBiome(x, 0, y); + if (islandMapGenerator.isShore(x, y)) { + shoreBiome = foundBiome; + } else { + mainBiome = foundBiome; + } + if (mainBiome != null && shoreBiome != null) { + return true; + } + } return false; } + + @Override + public void GenerateBiome(int chunkX, int chunkZ, int localX, int localZ, BiomeGrid biome) { + int worldX = chunkX * 16 + localX; + int worldZ = chunkZ * 16 + localZ; + + if (islandMapGenerator.isIsland(worldX, worldZ)) { + if (mainBiome == null && shoreBiome == null) { + if (!dfs.findTarget(this)) { + temperature = temperatureMapGenerator.getTemperature(worldX, worldZ); + mainBiome = biomeSelector.getLandBiome(temperature); + shoreBiome = biomeSelector.getShoreBiome(mainBiome, temperature); + } + } + + } else { + mainBiome = null; + shoreBiome = null; + } + for (int y = 0; y < buildHeight; y++) { + Biome designatedBiome = mainBiome; + if (mainBiome == null) { + designatedBiome = Biome.OCEAN; + } else if (islandMapGenerator.isShore(worldX, worldZ)) { + designatedBiome = shoreBiome; + } + + biome.setBiome(localX, y, localZ, designatedBiome); + } + } } \ No newline at end of file diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelector.java b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelector.java index 33b4918..95eb460 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelector.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelector.java @@ -11,7 +11,7 @@ import ca.recrown.islandsurvivalcraft.Utilities; public class BiomeSelector { private boolean initialized = false; - private final Random random; + private Random random; private final HashMap lands; private HashMap> temperaturesForLand; private final HashMap> temperaturePartitionedLandBiomes; @@ -20,9 +20,7 @@ public class BiomeSelector { private final HashMap> temperaturePartitionedOceanBiomes; - public BiomeSelector(Random random) { - this.random = random; - + public BiomeSelector() { lands = new HashMap<>(); oceans = new HashMap<>(); temperaturePartitionedLandBiomes = new HashMap<>(); @@ -35,6 +33,10 @@ public class BiomeSelector { temperaturePartitionedOceanBiomes.put(0.5f, new ArrayList<>()); } + public void setRandom(Random random) { + this.random = random; + } + public void initialize() { if (initialized) throw new IllegalStateException("Biome selector is already initialized."); diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandBiomeGenerator.java b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandBiomeGenerator.java index 6c84e39..c660afa 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandBiomeGenerator.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandBiomeGenerator.java @@ -1,8 +1,10 @@ package ca.recrown.islandsurvivalcraft.worldgeneration; +import org.bukkit.World; import org.bukkit.generator.ChunkGenerator.BiomeGrid; public interface IslandBiomeGenerator { - + public void initialize(IslandMapGenerator mapGenerator, BiomeSelector biome); + public void setWorld(World world); public void GenerateBiome(int chunkX, int chunkZ, int localX, int localZ, BiomeGrid biome); } diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandMapGenerator.java b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandMapGenerator.java index 00d6cef..a099007 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandMapGenerator.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandMapGenerator.java @@ -8,6 +8,7 @@ import ca.recrown.islandsurvivalcraft.pathfinding.CoordinateValidatable; import ca.recrown.islandsurvivalcraft.pathfinding.DepthFirstSearch; public class IslandMapGenerator implements CoordinateValidatable { + private Random random; private SimplexOctaveGenerator noiseGenerator; private final int noiseOctaves = 8; private final int islandGenerationPercent = 47; @@ -17,16 +18,23 @@ public class IslandMapGenerator implements CoordinateValidatable { private final float shoreFactor = 0.065f; private final int maxHeightAboveSea = 8; private final int lowestSeaFloor = 16; - private final int seaLevel; - private final int shallowDepth; + private int seaLevel; + private int shallowDepth; private final DepthFirstSearch dfs; - public IslandMapGenerator(Random random, int seaLevel, int shallowDepth) { - - this.noiseGenerator = new SimplexOctaveGenerator(random, noiseOctaves); + public IslandMapGenerator() { + dfs = new DepthFirstSearch(this); + } + + public void updateParameters(Random random, int seaLevel, int shallowDepth) { + this.seaLevel = seaLevel; + this.shallowDepth = shallowDepth; + if (!random.equals(this.random)) { + this.random = random; + this.noiseGenerator = new SimplexOctaveGenerator(random, noiseOctaves); + } this.seaLevel = seaLevel; this.shallowDepth = shallowDepth; - dfs = new DepthFirstSearch(this); } /** @@ -59,7 +67,7 @@ public class IslandMapGenerator implements CoordinateValidatable { /** * These coordinates are considered to be the shore if: * It is a part of an island, - * within a square radius of shoreSize, there is an edge of the island. + * the island value is less than the shore factor. * @param worldX the X coordinate of location in world. * @param worldZ the Z coordinate of location in world. * @return diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandSurvivalCraftWorldGenerator.java b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandSurvivalCraftWorldGenerator.java index d69ba8f..9ffa7eb 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandSurvivalCraftWorldGenerator.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/IslandSurvivalCraftWorldGenerator.java @@ -2,37 +2,35 @@ package ca.recrown.islandsurvivalcraft.worldgeneration; import java.util.Random; -import org.apache.commons.lang.NotImplementedException; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.generator.ChunkGenerator; -import ca.recrown.islandsurvivalcraft.IslandSurvivalCraft; - public class IslandSurvivalCraftWorldGenerator extends ChunkGenerator { + private final BedrockGenerator bedrockGenerator; private final BiomeSelector biomeSelector; private final IslandBiomeGenerator biomeGenerator; private final IslandMapGenerator islandMapGenerator; - private final TemperatureMapGenerator temperatureMapGenerator; - private final BedrockGenerator bedrockGenerator; - private final Random random; - public IslandSurvivalCraftWorldGenerator(IslandSurvivalCraft plugin, World world, boolean biomePerIsland) { - random = new Random(world.getSeed()); - this.biomeSelector = new BiomeSelector(random); - this.bedrockGenerator = new BedrockGenerator(random); - this.islandMapGenerator = new IslandMapGenerator(random, world.getSeaLevel(), 3); - this.temperatureMapGenerator = new TemperatureMapGenerator(world.getSeed()); - if (biomePerIsland) { - this.biomeGenerator = new BiomePerIslandGenerator(plugin, world, islandMapGenerator, biomeSelector, temperatureMapGenerator); - } else { - throw new NotImplementedException(); - } + public IslandSurvivalCraftWorldGenerator(IslandBiomeGenerator generator) { + this.biomeSelector = new BiomeSelector(); + this.bedrockGenerator = new BedrockGenerator(); + this.islandMapGenerator = new IslandMapGenerator(); + this.biomeGenerator = generator; + } + + public void initialize() { biomeSelector.initialize(); + biomeGenerator.initialize(islandMapGenerator, biomeSelector); } @Override public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) { + bedrockGenerator.setRandom(random); + biomeSelector.setRandom(random); + biomeGenerator.setWorld(world); + islandMapGenerator.updateParameters(random, world.getSeaLevel(), 4); + ChunkData chunk = createChunkData(world); for (int localX = 0; localX < 16; localX++) { for (int localZ = 0; localZ < 16; localZ++) { diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/TemperatureMapGenerator.java b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/TemperatureMapGenerator.java index 5428d45..b043872 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/TemperatureMapGenerator.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/worldgeneration/TemperatureMapGenerator.java @@ -9,7 +9,8 @@ class TemperatureMapGenerator { private final double amplitude = 0.22D; private SimplexOctaveGenerator noiseGenerator; - public TemperatureMapGenerator(long seed) { + + public void setSeed(long seed) { noiseGenerator = new SimplexOctaveGenerator(new Random(seed), 4); noiseGenerator.setScale(0.0008D); } diff --git a/src/test/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearchTest.java b/src/test/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearchTest.java index 71eac7d..52271d3 100644 --- a/src/test/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearchTest.java +++ b/src/test/java/ca/recrown/islandsurvivalcraft/pathfinding/DepthFirstSearchTest.java @@ -131,7 +131,7 @@ public class DepthFirstSearchTest { dfs.setValidatable(validator); dfs.setStartPosition(3, 0); - assertTrue(dfs.findEndNode(validator)); + assertTrue(dfs.findTarget(validator)); assertEquals(1, dfs.getEndX()); assertEquals(2, dfs.getEndY()); } @@ -142,7 +142,7 @@ public class DepthFirstSearchTest { dfs.setValidatable(validator); dfs.setStartPosition(0, 0); - assertTrue(dfs.findEndNode(validator)); + assertTrue(dfs.findTarget(validator)); assertEquals(0, dfs.getEndX()); assertEquals(3, dfs.getEndY()); } @@ -153,6 +153,6 @@ public class DepthFirstSearchTest { dfs.setValidatable(validator); dfs.setStartPosition(0, 0); - assertFalse(dfs.findEndNode(validator)); + assertFalse(dfs.findTarget(validator)); } } diff --git a/src/test/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelectorTest.java b/src/test/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelectorTest.java index 59cef21..aec59dc 100644 --- a/src/test/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelectorTest.java +++ b/src/test/java/ca/recrown/islandsurvivalcraft/worldgeneration/BiomeSelectorTest.java @@ -18,7 +18,8 @@ public class BiomeSelectorTest { @BeforeAll public void setUp() { - biomeSelector = new BiomeSelector(new Random()); + biomeSelector = new BiomeSelector(); + biomeSelector.setRandom(new Random()); biomeSelector.initialize(); }