From 50b486262ad7b91b797c4e08709033acebcf0af0 Mon Sep 17 00:00:00 2001 From: Peaches_MLG Date: Sat, 28 Dec 2024 15:21:35 +0000 Subject: [PATCH] Ocean generator (#741) * implementing the ocean generator * Cleanup * Updated Generators updated generators to allow server owners to set the default biome and whether they'd like their oceans to be decorated or not (includes ores, deposits, and geodes, no caves) * Update OceanGenerator.java cleaned up some residual das code * fixed the generator! uh so we basically create a duplicate of the world on first generation of an island that will then be used to copy and paste the terrain under the islands the first generation is slow because it has to create the worlds, but once this is done its exactly like the deleting blocks method except in reverse * refactored world generation to createWorld() - moved the cache world creation to the create world method so that the plugin does not lag on island creation - changed setting to GeneratorType enum - added vanilla generation option (takes advantage of null chunk generator) - deletes and regenerates cache world on bad seed comparison so that the cache world matches even on generator change * added generator type logging * Updated calls to regenerateTerrain to use .join() - moved the check for if the generator is a terrain generator to the methods that call regenerateTerrain * das suggested we format the enum differently so we did Co-authored-by: Daniel Scherf <35780068+dlsf@users.noreply.github.com> * Added flatlands generator (#845) * Added flatlands generator - also added some logging about the generator type to ensure that server admins know what the correct enum values are * forgot to import arrays, silly me * added a more explicit comment * made the delete world method a lil nicer (ty das) Co-authored-by: Daniel Scherf <35780068+dlsf@users.noreply.github.com> * removed generateChunkData * reverted deleteWorld method overhaul * remove imports * Re-implemented ChunkData method, cleaned up cache world creation * Removed shouldGenerateDecorations methods (temporarily) * Update IridiumSkyblock.java plugin would incorrectly report invalid generator type for VOID because i didnt add the case for void, so it would default * Fix imports --------- Co-authored-by: Shyanne Co-authored-by: Daniel Scherf <35780068+dlsf@users.noreply.github.com> Co-authored-by: Daniel Scherf --- .../iridiumskyblock/IridiumSkyblock.java | 37 +++- .../configs/Configuration.java | 2 + .../iridiumskyblock/configs/Generators.java | 160 +++++++++++++++++ .../generators/FlatGenerator.java | 134 ++++++++++++++ .../generators/OceanGenerator.java | 167 ++++++++++++++++++ .../generators/VoidGenerator.java | 26 ++- .../managers/GeneratorType.java | 15 ++ .../managers/IslandManager.java | 107 ++++++++++- 8 files changed, 641 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/iridium/iridiumskyblock/configs/Generators.java create mode 100644 src/main/java/com/iridium/iridiumskyblock/generators/FlatGenerator.java create mode 100644 src/main/java/com/iridium/iridiumskyblock/generators/OceanGenerator.java create mode 100644 src/main/java/com/iridium/iridiumskyblock/managers/GeneratorType.java diff --git a/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java b/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java index f22afa107..184e9f94f 100644 --- a/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java +++ b/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java @@ -5,6 +5,8 @@ import com.iridium.iridiumskyblock.configs.*; import com.iridium.iridiumskyblock.database.Island; import com.iridium.iridiumskyblock.database.User; +import com.iridium.iridiumskyblock.generators.FlatGenerator; +import com.iridium.iridiumskyblock.generators.OceanGenerator; import com.iridium.iridiumskyblock.generators.VoidGenerator; import com.iridium.iridiumskyblock.listeners.*; import com.iridium.iridiumskyblock.managers.*; @@ -34,6 +36,7 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.sql.SQLException; +import java.util.Arrays; import java.util.Comparator; import java.util.Objects; @@ -56,6 +59,7 @@ public class IridiumSkyblock extends IridiumTeams { private Shop shop; private Biomes biomes; private Settings settings; + private Generators generators; private IslandPlaceholderBuilder teamsPlaceholderBuilder; private UserPlaceholderBuilder userPlaceholderBuilder; @@ -87,7 +91,35 @@ public IridiumSkyblock() { @Override public void onLoad() { super.onLoad(); - this.chunkGenerator = new VoidGenerator(); + + getLogger().info("Loading world generator..."); + getLogger().info("Generator Type = " + IridiumSkyblock.getInstance().getConfiguration().generatorType); + + // This switch statement is here so that if we end up adding another generator type, we can throw it in this. + switch (IridiumSkyblock.getInstance().getConfiguration().generatorType) { + case OCEAN: { + this.chunkGenerator = new OceanGenerator(); + break; + } + case FLAT: { + this.chunkGenerator = new FlatGenerator(); + break; + } + case VANILLA: { + this.chunkGenerator = null; + break; + } + case VOID: { + this.chunkGenerator = new VoidGenerator(); + break; + } + default: { + getLogger().warning("Invalid generator type [" + IridiumSkyblock.getInstance().getConfiguration().generatorType + "], valid types are " + Arrays.toString(GeneratorType.values())); + getLogger().info("Generator Type = " + GeneratorType.VOID); + this.chunkGenerator = new VoidGenerator(); + break; + } + } } @Override @@ -173,6 +205,8 @@ public void loadConfigs() { this.shop = getPersist().load(Shop.class); this.biomes = getPersist().load(Biomes.class); this.settings = getPersist().load(Settings.class); + this.generators = getPersist().load(Generators.class); + getLogger().info("GENERATOR TYPE: " + IridiumSkyblock.getInstance().getConfiguration().generatorType); super.loadConfigs(); int maxSize = enhancements.sizeEnhancement.levels.values().stream() @@ -210,6 +244,7 @@ public void saveConfigs() { getPersist().save(shop); getPersist().save(biomes); getPersist().save(settings); + getPersist().save(generators); saveSchematics(); } diff --git a/src/main/java/com/iridium/iridiumskyblock/configs/Configuration.java b/src/main/java/com/iridium/iridiumskyblock/configs/Configuration.java index 87451e33a..d4d61da47 100644 --- a/src/main/java/com/iridium/iridiumskyblock/configs/Configuration.java +++ b/src/main/java/com/iridium/iridiumskyblock/configs/Configuration.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableMap; import com.iridium.iridiumcore.Color; import com.iridium.iridiumcore.Item; +import com.iridium.iridiumskyblock.managers.GeneratorType; import com.iridium.iridiumteams.Reward; import org.bukkit.World; @@ -43,6 +44,7 @@ public Configuration() { public String defaultDescription = "Default island description :c"; public String worldName = "IridiumSkyblock"; public String spawnWorldName = "world"; + public GeneratorType generatorType = GeneratorType.VOID; public String islandTitleTop = "&9%island_name%"; public String islandTitleBottom = "&7%island_description%"; public String paster = "worldedit"; diff --git a/src/main/java/com/iridium/iridiumskyblock/configs/Generators.java b/src/main/java/com/iridium/iridiumskyblock/configs/Generators.java new file mode 100644 index 000000000..18875b018 --- /dev/null +++ b/src/main/java/com/iridium/iridiumskyblock/configs/Generators.java @@ -0,0 +1,160 @@ +package com.iridium.iridiumskyblock.configs; + +import com.cryptomorin.xseries.XBiome; +import com.cryptomorin.xseries.XMaterial; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Generators { + + public Generators.SkyblockGeneratorConfig skyblockGenerator = new SkyblockGeneratorConfig( + new com.iridium.iridiumskyblock.configs.Generators.SkyblockGeneratorWorld( + XBiome.PLAINS, + true + ), + new com.iridium.iridiumskyblock.configs.Generators.SkyblockGeneratorWorld( + XBiome.NETHER_WASTES, + true + ), + new com.iridium.iridiumskyblock.configs.Generators.SkyblockGeneratorWorld( + XBiome.THE_END, + true + ) + ); + + public Generators.OceanGeneratorConfig oceanGenerator = new OceanGeneratorConfig( + new com.iridium.iridiumskyblock.configs.Generators.OceanGeneratorWorld( + XBiome.OCEAN, + XMaterial.SAND, + XMaterial.STONE, + XMaterial.WATER, + 63, 48, 53, + true, + true + ), + new com.iridium.iridiumskyblock.configs.Generators.OceanGeneratorWorld( + XBiome.NETHER_WASTES, + XMaterial.SOUL_SAND, + XMaterial.NETHERRACK, + XMaterial.LAVA, + 63, 48, 53, + true, + true + ), + new com.iridium.iridiumskyblock.configs.Generators.OceanGeneratorWorld( + XBiome.END_BARRENS, + XMaterial.END_STONE, + XMaterial.END_STONE, + XMaterial.VOID_AIR, + 63, 48, 53, + true, + true + )); + + public Generators.FlatGeneratorConfig flatGenerator = new FlatGeneratorConfig( + new com.iridium.iridiumskyblock.configs.Generators.FlatGeneratorWorld( + XBiome.PLAINS, + XMaterial.GRASS_BLOCK, + XMaterial.DIRT, + -59, + true, + true + ), + new com.iridium.iridiumskyblock.configs.Generators.FlatGeneratorWorld( + XBiome.NETHER_WASTES, + XMaterial.NETHERRACK, + XMaterial.NETHERRACK, + 5, + true, + true + ), + new com.iridium.iridiumskyblock.configs.Generators.FlatGeneratorWorld( + XBiome.END_BARRENS, + XMaterial.END_STONE, + XMaterial.END_STONE, + 5, + true, + true + )); + + @NoArgsConstructor + @AllArgsConstructor + public static class SkyblockGeneratorConfig { + public SkyblockGeneratorWorld overworld; + public SkyblockGeneratorWorld nether; + public SkyblockGeneratorWorld end; + } + + @NoArgsConstructor + @AllArgsConstructor + public static class OceanGeneratorConfig { + public OceanGeneratorWorld overworld; + public OceanGeneratorWorld nether; + public OceanGeneratorWorld end; + } + + @NoArgsConstructor + @AllArgsConstructor + public static class FlatGeneratorConfig { + public FlatGeneratorWorld overworld; + public FlatGeneratorWorld nether; + public FlatGeneratorWorld end; + } + + @NoArgsConstructor + public static class SkyblockGeneratorWorld { + public XBiome biome; + public boolean canSpawnEntities; + + public SkyblockGeneratorWorld(XBiome biome, boolean canSpawnEntities) { + this.biome = biome; + this.canSpawnEntities = canSpawnEntities; + } + } + + @NoArgsConstructor + public static class OceanGeneratorWorld { + public XBiome biome; + public XMaterial floor; + public XMaterial underFloor; + public XMaterial liquidType; + public int liquidHeight; + public int minFloorHeight; + public int maxFloorHeight; + public boolean decorate; + public boolean canSpawnEntities; + + public OceanGeneratorWorld(XBiome biome, XMaterial floor, XMaterial underFloor, XMaterial liquidType, int liquidHeight, int minFloorHeight, int maxFloorHeight, boolean decorate, boolean canSpawnEntities) { + this.biome = biome; + this.floor = floor; + this.underFloor = underFloor; + this.liquidType = liquidType; + this.liquidHeight = liquidHeight; + this.minFloorHeight = minFloorHeight; + this.maxFloorHeight = maxFloorHeight; + this.decorate = decorate; + this.canSpawnEntities = canSpawnEntities; + } + } + + @NoArgsConstructor + public static class FlatGeneratorWorld { + public XBiome biome; + public XMaterial floor; + public XMaterial underFloor; + public int floorHeight; + public boolean decorate; + public boolean canSpawnEntities; + + public FlatGeneratorWorld(XBiome biome, XMaterial floor, XMaterial underFloor, int floorHeight, boolean decorate, boolean canSpawnEntities) { + this.biome = biome; + this.floor = floor; + this.underFloor = underFloor; + this.floorHeight = floorHeight; + this.decorate = decorate; + this.canSpawnEntities = canSpawnEntities; + } + } +} diff --git a/src/main/java/com/iridium/iridiumskyblock/generators/FlatGenerator.java b/src/main/java/com/iridium/iridiumskyblock/generators/FlatGenerator.java new file mode 100644 index 000000000..570ae1dc4 --- /dev/null +++ b/src/main/java/com/iridium/iridiumskyblock/generators/FlatGenerator.java @@ -0,0 +1,134 @@ +package com.iridium.iridiumskyblock.generators; + +import com.cryptomorin.xseries.XMaterial; +import com.iridium.iridiumskyblock.IridiumSkyblock; +import com.iridium.iridiumskyblock.configs.Generators; +import com.iridium.iridiumskyblock.utils.LocationUtils; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.Block; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.NotNull; +import org.bukkit.generator.WorldInfo; + +import java.util.*; + +public class FlatGenerator extends ChunkGenerator { + + @Override + public @NotNull ChunkData generateChunkData( + @NotNull World world, @NotNull Random random, int chunkX, int chunkZ, @NotNull BiomeGrid biomeGrid) { + + final ChunkData chunkData = createChunkData(world); + int floorHeight = getFlatGenerator(world.getEnvironment()).floorHeight; + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + + // Generate layer of bedrock + chunkData.setBlock(x, LocationUtils.getMinHeight(world), z, + Objects.requireNonNull(XMaterial.BEDROCK.parseMaterial()) + ); + + // Generate dirt layer + for (int y = LocationUtils.getMinHeight(world) + 1; y < floorHeight; y++) { + chunkData.setBlock(x, y, z, + Objects.requireNonNull(getFlatGenerator(world.getEnvironment()).underFloor.parseMaterial()) + ); + } + + // Generate grass on top of dirt + chunkData.setBlock(x, floorHeight, z, + Objects.requireNonNull(getFlatGenerator(world.getEnvironment()).floor.parseMaterial()) + ); + + biomeGrid.setBiome(x, z, Objects.requireNonNull(getFlatGenerator(world.getEnvironment()).biome.getBiome())); + } + } + + return chunkData; + } + + public void generateFlatland(World world, int x, int z) { + + Random random = new Random((world.getSeed())); + + int floorHeight = getFlatGenerator(world.getEnvironment()).floorHeight; + int minFloorHeight = world.getMinHeight(); + + // Generate layer of bedrock + if (world.getBlockAt(x, minFloorHeight, z).getType() != XMaterial.BEDROCK.parseMaterial()) { + if (world.getBlockAt(x, minFloorHeight, z).getState() instanceof InventoryHolder) { + ((InventoryHolder) world.getBlockAt(x, minFloorHeight, z).getState()).getInventory().clear(); + } + world.getBlockAt(x, minFloorHeight, z).setType(Material.BEDROCK, false); + } + + // Generate dirt layer + for (int y = minFloorHeight + 1; y < floorHeight; y++) { + Block block = world.getBlockAt(x, y, z); + if (block.getType() != getFlatGenerator(world.getEnvironment()).underFloor.parseMaterial() + && getFlatGenerator(world.getEnvironment()).underFloor.parseMaterial() != null) { + + if (block.getState() instanceof InventoryHolder) { + ((InventoryHolder) block.getState()).getInventory().clear(); + } + block.setType(Objects.requireNonNull(getFlatGenerator(world.getEnvironment()).underFloor.parseMaterial()), false); + } + } + + // Generate grass on top of dirt + if (world.getBlockAt(x, floorHeight, z).getType() != getFlatGenerator(world.getEnvironment()).floor.parseMaterial() + && getFlatGenerator(world.getEnvironment()).floor.parseMaterial() != null) { + + if (world.getBlockAt(x, floorHeight, z).getState() instanceof InventoryHolder) { + ((InventoryHolder) world.getBlockAt(x, floorHeight, z).getState()).getInventory().clear(); + } + + world.getBlockAt(x, floorHeight, z) + .setType(Objects.requireNonNull(getFlatGenerator(world.getEnvironment()).floor.parseMaterial()), false); + + } + + // Replace everything else with air + for (int y = floorHeight + 1; y < world.getMaxHeight(); y++) { + Block block = world.getBlockAt(x, y, z); + if (block.getType() != Material.AIR) { + if (block.getState() instanceof InventoryHolder) { + ((InventoryHolder) block.getState()).getInventory().clear(); + } + block.setType(Material.AIR, false); + } + } + + // Generate kelp, ores, and mineral deposits + // BREAKS BELOW 1.18 + //shouldGenerateDecorations(world, random , x, z); + } + + @Override + public boolean shouldGenerateDecorations(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z) { + return getFlatGenerator(worldInfo.getEnvironment()).decorate; + } + + @Override + public boolean canSpawn(@NotNull World world, int x, int z) { + return getFlatGenerator(world.getEnvironment()).canSpawnEntities; + } + + private Generators.FlatGeneratorWorld getFlatGenerator(Environment environment) { + switch (environment) { + case NETHER: { + return IridiumSkyblock.getInstance().getGenerators().flatGenerator.nether; + } + case THE_END: { + return IridiumSkyblock.getInstance().getGenerators().flatGenerator.end; + } + default: { + return IridiumSkyblock.getInstance().getGenerators().flatGenerator.overworld; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/iridium/iridiumskyblock/generators/OceanGenerator.java b/src/main/java/com/iridium/iridiumskyblock/generators/OceanGenerator.java new file mode 100644 index 000000000..482ebaa03 --- /dev/null +++ b/src/main/java/com/iridium/iridiumskyblock/generators/OceanGenerator.java @@ -0,0 +1,167 @@ +package com.iridium.iridiumskyblock.generators; + +import com.cryptomorin.xseries.XMaterial; +import com.iridium.iridiumskyblock.IridiumSkyblock; +import com.iridium.iridiumskyblock.configs.Generators; +import com.iridium.iridiumskyblock.utils.LocationUtils; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.Block; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.util.noise.SimplexOctaveGenerator; +import org.jetbrains.annotations.NotNull; +import org.bukkit.generator.WorldInfo; + +import java.util.*; + +public class OceanGenerator extends ChunkGenerator { + + @Override + public @NotNull ChunkData generateChunkData( + @NotNull World world, @NotNull Random random, int chunkX, int chunkZ, @NotNull BiomeGrid biomeGrid) { + + SimplexOctaveGenerator generator = new SimplexOctaveGenerator(new Random(world.getSeed()), 8); + final ChunkData chunkData = createChunkData(world); + generator.setScale(0.005D); + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + int currentFloorHeight = (int) ((generator.noise( + chunkX * 16 + x, chunkZ * 16 + z, 1.5D, 0.5D, true) + 1) + * (getOceanGenerator(world.getEnvironment()).maxFloorHeight - getOceanGenerator(world.getEnvironment()).minFloorHeight) + + getOceanGenerator(world.getEnvironment()).minFloorHeight); + + // Generate layer of bedrock + chunkData.setBlock(x, LocationUtils.getMinHeight(world), z, + Objects.requireNonNull(XMaterial.BEDROCK.parseMaterial()) + ); + + // Generate gravel layer + for (int y = LocationUtils.getMinHeight(world) + 1; y < currentFloorHeight; y++) { + chunkData.setBlock(x, y, z, + Objects.requireNonNull(getOceanGenerator(world.getEnvironment()).underFloor.parseMaterial()) + ); + } + + // Generate sand on top of gravel + chunkData.setBlock(x, currentFloorHeight, z, + Objects.requireNonNull(getOceanGenerator(world.getEnvironment()).floor.parseMaterial()) + ); + + // Generate water or lava on top of the floor + for (int y = currentFloorHeight + 1; y <= getOceanGenerator(world.getEnvironment()).liquidHeight; y++) { + chunkData.setBlock(x, y, z, Objects.requireNonNull( + getOceanGenerator(world.getEnvironment()).liquidType.parseMaterial())); + } + + biomeGrid.setBiome(x, z, Objects.requireNonNull(getOceanGenerator(world.getEnvironment()).biome.getBiome())); + } + } + + return chunkData; + } + + public void generateOcean(World world, int x, int z) { + + Random random = new Random((world.getSeed())); + + SimplexOctaveGenerator generator = new SimplexOctaveGenerator(random, 8); + generator.setScale(0.005D); + + int currentFloorHeight = (int) ((generator.noise( + x, z, 1.5D, 0.5D, true) + 1) + * (getOceanGenerator(world.getEnvironment()).maxFloorHeight - getOceanGenerator(world.getEnvironment()).minFloorHeight) + + getOceanGenerator(world.getEnvironment()).minFloorHeight); + + int minHeightWorld = LocationUtils.getMinHeight(world); + + // Generate layer of bedrock + if (world.getBlockAt(x, minHeightWorld, z).getType() != XMaterial.BEDROCK.parseMaterial()) { + if (world.getBlockAt(x, minHeightWorld, z).getState() instanceof InventoryHolder) { + ((InventoryHolder) world.getBlockAt(x, minHeightWorld, z).getState()).getInventory().clear(); + } + world.getBlockAt(x, minHeightWorld, z).setType(Material.BEDROCK, false); + } + + // Generate gravel layer + for (int y = minHeightWorld + 1; y < currentFloorHeight; y++) { + Block block = world.getBlockAt(x, y, z); + if (block.getType() != getOceanGenerator(world.getEnvironment()).underFloor.parseMaterial() + && getOceanGenerator(world.getEnvironment()).underFloor.parseMaterial() != null) { + + if (block.getState() instanceof InventoryHolder) { + ((InventoryHolder) block.getState()).getInventory().clear(); + } + block.setType(Objects.requireNonNull(getOceanGenerator(world.getEnvironment()).underFloor.parseMaterial()), false); + } + } + + // Generate sand on top of gravel + if (world.getBlockAt(x, currentFloorHeight, z).getType() != getOceanGenerator(world.getEnvironment()).floor.parseMaterial() + && getOceanGenerator(world.getEnvironment()).floor.parseMaterial() != null) { + + if (world.getBlockAt(x, currentFloorHeight, z).getState() instanceof InventoryHolder) { + ((InventoryHolder) world.getBlockAt(x, currentFloorHeight, z).getState()).getInventory().clear(); + } + + for(int y = currentFloorHeight; y < currentFloorHeight + 5; y++) { + world.getBlockAt(x, currentFloorHeight, z) + .setType(Objects.requireNonNull(getOceanGenerator(world.getEnvironment()).floor.parseMaterial()), false); + currentFloorHeight++; + } + + } + + // Generate water or lava on top of the floor + for (int y = currentFloorHeight + 1; y <= getOceanGenerator(world.getEnvironment()).liquidHeight; y++) { + Block block = world.getBlockAt(x, y, z); + if (block.getType() != getOceanGenerator(world.getEnvironment()).liquidType.parseMaterial() && getOceanGenerator(world.getEnvironment()).liquidType.parseMaterial() != null) { + if (block.getState() instanceof InventoryHolder) { + ((InventoryHolder) block.getState()).getInventory().clear(); + } + block.setType(getOceanGenerator(world.getEnvironment()).liquidType.parseMaterial(), false); + } + } + + // Replace everything else with air + for (int y = getOceanGenerator(world.getEnvironment()).liquidHeight + 1; y < world.getMaxHeight(); y++) { + Block block = world.getBlockAt(x, y, z); + if (block.getType() != Material.AIR) { + if (block.getState() instanceof InventoryHolder) { + ((InventoryHolder) block.getState()).getInventory().clear(); + } + block.setType(Material.AIR, false); + } + } + + // Generate kelp, ores, and mineral deposits + // BREAKS BELOW 1.18 + //shouldGenerateDecorations(world, random , x, z); + } + + @Override + public boolean shouldGenerateDecorations(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z) { + return getOceanGenerator(worldInfo.getEnvironment()).decorate; + } + + @Override + public boolean canSpawn(@NotNull World world, int x, int z) { + return getOceanGenerator(world.getEnvironment()).canSpawnEntities; + } + + private Generators.OceanGeneratorWorld getOceanGenerator(Environment environment) { + switch (environment) { + case NETHER: { + return IridiumSkyblock.getInstance().getGenerators().oceanGenerator.nether; + } + case THE_END: { + return IridiumSkyblock.getInstance().getGenerators().oceanGenerator.end; + } + default: { + return IridiumSkyblock.getInstance().getGenerators().oceanGenerator.overworld; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/iridium/iridiumskyblock/generators/VoidGenerator.java b/src/main/java/com/iridium/iridiumskyblock/generators/VoidGenerator.java index beeb9af49..554032dea 100644 --- a/src/main/java/com/iridium/iridiumskyblock/generators/VoidGenerator.java +++ b/src/main/java/com/iridium/iridiumskyblock/generators/VoidGenerator.java @@ -1,5 +1,7 @@ package com.iridium.iridiumskyblock.generators; +import com.iridium.iridiumskyblock.IridiumSkyblock; +import com.iridium.iridiumskyblock.configs.Generators; import org.bukkit.World; import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; @@ -7,6 +9,7 @@ import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Random; public class VoidGenerator extends ChunkGenerator { @@ -15,7 +18,13 @@ public class VoidGenerator extends ChunkGenerator { @Override public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, @NotNull BiomeGrid biomeGrid) { - return createChunkData(world); + final ChunkData chunkData = createChunkData(world); + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + biomeGrid.setBiome(x, z, Objects.requireNonNull(getSkyblockGenerator(world.getEnvironment()).biome.getBiome())); + } + } + return chunkData; } public byte[][] generateBlockSections(World world, Random random, int x, int z, BiomeGrid biomeGrid) { @@ -27,7 +36,7 @@ public byte[][] generateBlockSections(World world, Random random, int x, int z, @Override public boolean canSpawn(@NotNull World world, int x, int z) { - return true; + return getSkyblockGenerator(world.getEnvironment()).canSpawnEntities; } @Override @@ -35,4 +44,17 @@ public boolean canSpawn(@NotNull World world, int x, int z) { return Collections.emptyList(); } + private Generators.SkyblockGeneratorWorld getSkyblockGenerator(World.Environment environment) { + switch (environment) { + case NETHER: { + return IridiumSkyblock.getInstance().getGenerators().skyblockGenerator.nether; + } + case THE_END: { + return IridiumSkyblock.getInstance().getGenerators().skyblockGenerator.end; + } + default: { + return IridiumSkyblock.getInstance().getGenerators().skyblockGenerator.overworld; + } + } + } } diff --git a/src/main/java/com/iridium/iridiumskyblock/managers/GeneratorType.java b/src/main/java/com/iridium/iridiumskyblock/managers/GeneratorType.java new file mode 100644 index 000000000..311aff57f --- /dev/null +++ b/src/main/java/com/iridium/iridiumskyblock/managers/GeneratorType.java @@ -0,0 +1,15 @@ +package com.iridium.iridiumskyblock.managers; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum GeneratorType { + VOID(false), + OCEAN(true), + FLAT(true), + VANILLA(true); + + private final boolean terrainGenerator; +} \ No newline at end of file diff --git a/src/main/java/com/iridium/iridiumskyblock/managers/IslandManager.java b/src/main/java/com/iridium/iridiumskyblock/managers/IslandManager.java index 5d7efa2bb..defc08a89 100644 --- a/src/main/java/com/iridium/iridiumskyblock/managers/IslandManager.java +++ b/src/main/java/com/iridium/iridiumskyblock/managers/IslandManager.java @@ -54,13 +54,37 @@ public IslandManager() { super(IridiumSkyblock.getInstance()); } + public boolean deleteWorld(File path) { + if(path.exists()) { + File files[] = path.listFiles(); + for(int i=0; i getIslandCreateEvent(@NotNull User public CompletableFuture generateIsland(Island island, Schematics.SchematicConfig schematicConfig) { return CompletableFuture.runAsync(() -> { setHome(island, schematicConfig); - deleteIslandBlocks(island).join(); clearEntities(island); + deleteIslandBlocks(island).join(); + if(IridiumSkyblock.getInstance().getConfiguration().generatorType.isTerrainGenerator()) + regenerateTerrain(island).join(); IridiumSkyblock.getInstance().getSchematicManager().pasteSchematic(island, schematicConfig).join(); - setIslandBiome(island, schematicConfig.overworld.biome); - setIslandBiome(island, schematicConfig.nether.biome); - setIslandBiome(island, schematicConfig.end.biome); + setIslandBiome(island, schematicConfig); }); } @@ -266,6 +308,12 @@ private void setHome(Island island, Schematics.SchematicConfig schematicConfig) island.setHome(location); } + public void setIslandBiome(Island island, Schematics.SchematicConfig schematicConfig) { + setIslandBiome(island, schematicConfig.overworld.biome); + setIslandBiome(island, schematicConfig.nether.biome); + setIslandBiome(island, schematicConfig.end.biome); + } + public CompletableFuture clearEntities(Island island) { return CompletableFuture.runAsync(() -> { List> completableFutures = Arrays.asList( @@ -347,6 +395,55 @@ private void deleteIslandBlocks(Island island, World world, int y, CompletableFu } } + public CompletableFuture regenerateTerrain(Island island) { + return CompletableFuture.runAsync(() -> { + List> completableFutures = Arrays.asList( + regenerateTerrain(island, getWorld(World.Environment.NORMAL)), + regenerateTerrain(island, getWorld(World.Environment.NETHER)), + regenerateTerrain(island, getWorld(World.Environment.THE_END)) + ); + completableFutures.forEach(CompletableFuture::join); + }); + } + + private CompletableFuture regenerateTerrain(Island island, World world) { + CompletableFuture completableFuture = new CompletableFuture<>(); + if (world == null) { + completableFuture.complete(null); + } else { + Bukkit.getScheduler().runTask(IridiumSkyblock.getInstance(), () -> regenerateTerrain(island, world, world.getMaxHeight(), completableFuture, 0)); + } + return completableFuture; + } + + public void regenerateTerrain (Island island, World world, int y, CompletableFuture completableFuture, int delay) { + + if(world == null) return; + + Location pos1 = island.getPosition1(world); + Location pos2 = island.getPosition2(world); + + World regenWorld = Bukkit.getWorld(getCacheWorldName(world)); + + for (int x = pos1.getBlockX(); x <= pos2.getBlockX(); x++) { + for (int z = pos1.getBlockZ(); z <= pos2.getBlockZ(); z++) { + Block blockA = regenWorld.getBlockAt(x, y, z); + Block blockB = world.getBlockAt(x, y, z); + blockB.setBlockData(blockA.getBlockData(), false); + } + } + + if (y <= LocationUtils.getMinHeight(world)) { + completableFuture.complete(null); + } else { + if (delay < 1) { + regenerateTerrain(island, world, y - 1, completableFuture, delay); + } else { + Bukkit.getScheduler().runTaskLater(IridiumSkyblock.getInstance(), () -> regenerateTerrain(island, world, y - 1, completableFuture, delay), delay); + } + } + } + @Override public boolean deleteTeam(Island island, User user) { IslandDeleteEvent islandDeleteEvent = new IslandDeleteEvent(island, user); @@ -355,6 +452,8 @@ public boolean deleteTeam(Island island, User user) { if (IridiumSkyblock.getInstance().getConfiguration().removeIslandBlocksOnDelete) { deleteIslandBlocks(island); + if(IridiumSkyblock.getInstance().getConfiguration().generatorType.isTerrainGenerator()) + regenerateTerrain(island).join(); } IridiumSkyblock.getInstance().getDatabaseManager().getIslandTableManager().delete(island);