diff --git a/src/main/java/world/bentobox/caveblock/CaveBlock.java b/src/main/java/world/bentobox/caveblock/CaveBlock.java index 409654b..70dc5e9 100644 --- a/src/main/java/world/bentobox/caveblock/CaveBlock.java +++ b/src/main/java/world/bentobox/caveblock/CaveBlock.java @@ -34,7 +34,7 @@ public class CaveBlock extends GameModeAddon this.saveDefaultConfig(); this.loadSettings(); - this.chunkGenerator = new ChunkGeneratorWorld(); + this.chunkGenerator = new ChunkGeneratorWorld(this); // Player Command this.playerCommand = new DefaultPlayerCommand(this) diff --git a/src/main/java/world/bentobox/caveblock/generators/ChunkGeneratorWorld.java b/src/main/java/world/bentobox/caveblock/generators/ChunkGeneratorWorld.java index bac828f..180277b 100644 --- a/src/main/java/world/bentobox/caveblock/generators/ChunkGeneratorWorld.java +++ b/src/main/java/world/bentobox/caveblock/generators/ChunkGeneratorWorld.java @@ -1,17 +1,17 @@ package world.bentobox.caveblock.generators; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - import org.bukkit.Material; -import org.bukkit.World.Environment; -import org.bukkit.block.data.BlockData; +import org.bukkit.World; +import org.bukkit.generator.BiomeProvider; +import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.WorldInfo; +import world.bentobox.caveblock.CaveBlock; +import world.bentobox.caveblock.Settings; +import world.bentobox.caveblock.generators.populators.EntitiesPopulator; +import world.bentobox.caveblock.generators.populators.FlatBiomeProvider; +import world.bentobox.caveblock.generators.populators.MaterialPopulator; +import world.bentobox.caveblock.generators.populators.NewMaterialPopulator; import java.util.ArrayList; import java.util.List; @@ -20,115 +20,115 @@ import java.util.Random; /** * Class ChunkGeneratorWorld ... * - * @author tastybento + * @author BONNe + * Created on 27.01.2019 */ public class ChunkGeneratorWorld extends ChunkGenerator { - - private static final int BLOB_SIZE = 1; - private static final Map> ORES; - static { - Map> ores = new EnumMap<>(Environment.class); - // Source https://minecraft.fandom.com/wiki/Blob - List worldOres = new ArrayList<>(); - worldOres.add(new Ore(-64, 16, Material.DIAMOND_ORE, 1, 10, true)); - worldOres.add(new Ore(-64, 64, Material.LAPIS_ORE, 1, 7, true)); - worldOres.add(new Ore(-64, 30, Material.GOLD_ORE, 2, 9, true)); - worldOres.add(new Ore(0, 16, Material.TUFF, 2, 33, false)); - worldOres.add(new Ore(-64, 16, Material.REDSTONE_ORE, 8, 8, true)); - worldOres.add(new Ore(0, 16, Material.GRAVEL, 8 , 33, false)); - worldOres.add(new Ore(0, 79, Material.GRANITE, 5, 33, false)); - worldOres.add(new Ore(0, 79, Material.ANDESITE,5, 33, false)); - worldOres.add(new Ore(0, 79, Material.DIORITE,5, 33, false)); - worldOres.add(new Ore(32, 320, Material.EMERALD_ORE, 11, 1, true)); - worldOres.add(new Ore(95, 136, Material.COAL_ORE, 20, 17, false)); - worldOres.add(new Ore(0, 96, Material.COPPER_ORE, 20, 9, true)); - worldOres.add(new Ore(-64, 320, Material.IRON_ORE, 20, 9, true)); - worldOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8 , 33, false)); - ores.put(Environment.NORMAL, worldOres); - List netherOres = new ArrayList<>(); - netherOres.add(new Ore(1, 22, Material.ANCIENT_DEBRIS, 1, 5, true)); - netherOres.add(new Ore(-64, 30, Material.NETHER_GOLD_ORE, 2, 9, true)); - netherOres.add(new Ore(0, 16, Material.GRAVEL, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.BASALT, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.BLACKSTONE, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.FIRE, 8 , 33, false)); - netherOres.add(new Ore(200, 320, Material.GLOWSTONE, 8 , 33, false)); - netherOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8 , 33, false)); - netherOres.add(new Ore(-64, 320, Material.LAVA, 8 , 33, false)); - netherOres.add(new Ore(0, 16, Material.MAGMA_BLOCK, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.CRIMSON_FUNGUS, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.WARPED_FUNGUS, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.CRIMSON_NYLIUM, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.WARPED_NYLIUM, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.SHROOMLIGHT, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.CRIMSON_STEM, 8 , 33, false)); - netherOres.add(new Ore(0, 320, Material.WARPED_STEM, 8 , 33, false)); - netherOres.add(new Ore(-64, 34, Material.SOUL_SOIL, 20, 17, false)); - netherOres.add(new Ore(0, 96, Material.NETHER_QUARTZ_ORE, 20, 9, true)); - netherOres.add(new Ore(-64, 320, Material.BONE_BLOCK, 20, 9, true)); - ores.put(Environment.NETHER, netherOres); - List endOres = new ArrayList<>(); - endOres.add(new Ore(32, 320, Material.PURPUR_BLOCK, 11, 1, true)); - endOres.add(new Ore(95, 136, Material.OBSIDIAN, 20, 17, false)); - endOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8 , 33, false)); - ores.put(Environment.THE_END, endOres); - ORES = Collections.unmodifiableMap(ores); + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- + + private final CaveBlock addon; + private final Settings settings; + private final List blockPopulators; + private BiomeProvider biomeProvider; + private boolean isNewGenerator; + + // --------------------------------------------------------------------- + // Section: Constructor + // --------------------------------------------------------------------- + + /** + * @param addon - CaveBlock object + */ + public ChunkGeneratorWorld(CaveBlock addon) { + this.addon = addon; + this.settings = addon.getSettings(); + this.blockPopulators = new ArrayList<>(2); + + reload(); } // --------------------------------------------------------------------- // Section: Methods // --------------------------------------------------------------------- + private Material getGroundCeilMaterial(World.Environment environment) { + return switch (environment) { + case NETHER -> this.settings.isNetherRoof() ? Material.BEDROCK : this.settings.getNetherMainBlock(); + case THE_END -> this.settings.isEndFloor() ? Material.BEDROCK : this.settings.getEndMainBlock(); + default -> this.settings.isNormalFloor() ? Material.BEDROCK : this.settings.getNormalMainBlock(); + }; + } + + private Material getBaseMaterial(World.Environment environment) { + return switch (environment) { + case NETHER -> this.settings.getNetherMainBlock(); + case THE_END -> this.settings.getEndMainBlock(); + default -> this.settings.getNormalMainBlock(); + }; + } + @Override - public void generateNoise(WorldInfo worldInfo, Random r, int x, int z, ChunkData chunkData) { - switch(worldInfo.getEnvironment()) { - default: - chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, worldInfo.getMaxHeight(), 16, Material.STONE); - chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, 7, 16, Material.DEEPSLATE); - chunkData.setRegion(0, worldInfo.getMaxHeight() - 1, 0, 16, worldInfo.getMaxHeight(), 16, Material.BEDROCK); - break; - case NETHER: - chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, worldInfo.getMaxHeight(), 16, Material.NETHERRACK); - chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, 34, 16, Material.SOUL_SAND); - chunkData.setRegion(0, worldInfo.getMaxHeight() - 1, 0, 16, worldInfo.getMaxHeight(), 16, Material.BEDROCK); - break; - case THE_END: - chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, worldInfo.getMaxHeight(), 16, Material.END_STONE); - chunkData.setRegion(0, worldInfo.getMaxHeight() - 1, 0, 16, worldInfo.getMaxHeight(), 16, Material.BEDROCK); - break; - } + public void generateBedrock(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) { + final int minHeight = worldInfo.getMinHeight(); + Material material = getGroundCeilMaterial(worldInfo.getEnvironment()); + chunkData.setRegion(0, minHeight, 0, 16, minHeight + 1, 16, material); + } - // Generate ores - for (int y = worldInfo.getMinHeight(); y < worldInfo.getMaxHeight(); y++) { - for (Ore o: ORES.get(worldInfo.getEnvironment())) { - if (y > o.minY() && y < o.maxY() && r.nextInt(100) <= o.chance()) { - pasteBlob(chunkData, y, o, r); - if (o.cont()) { - break; + @Override + public void generateSurface(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) { + final int worldHeight = Math.min(worldInfo.getMaxHeight(), this.settings.getWorldDepth()); + Material material = getGroundCeilMaterial(worldInfo.getEnvironment()); + chunkData.setRegion(0, worldHeight - 1, 0, 16, worldHeight, 16, material); + } + + @Override + public void generateNoise(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) { + final int minHeight = worldInfo.getMinHeight(); + final int worldHeight = Math.min(worldInfo.getMaxHeight(), this.settings.getWorldDepth()); + final World.Environment environment = worldInfo.getEnvironment(); + if (isNewGenerator) { + switch (environment) { + case NETHER: + if (worldHeight + 1 > 34) { + chunkData.setRegion(0, minHeight + 1, 0, 16, 34, 16, Material.SOUL_SAND); + chunkData.setRegion(0, 34, 0, 16, worldHeight - 1, 16, Material.NETHERRACK); + } else { + chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, Material.NETHERRACK); } - } + break; + case THE_END: + chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, Material.END_STONE); + break; + default: + if (worldHeight + 1 > 7) { + chunkData.setRegion(0, minHeight + 1, 0, 16, 7, 16, Material.DEEPSLATE); + chunkData.setRegion(0, 7, 0, 16, worldHeight - 1, 16, Material.STONE); + } else { + chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, Material.STONE); + } + break; } - + } else { + Material material = getBaseMaterial(environment); + chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, material); } } - private void pasteBlob(ChunkData chunkData, int y, Ore o, Random r) { - int offset = r.nextInt(16); - for (int x = Math.max(0, offset - BLOB_SIZE); x < Math.min(16, offset + BLOB_SIZE); x++) { - for (int z = Math.max(0, offset - BLOB_SIZE); z < Math.min(16, offset + BLOB_SIZE); z++) { - for (int yy = Math.max(chunkData.getMinHeight(), y - BLOB_SIZE); yy < Math.min(chunkData.getMaxHeight(),y + BLOB_SIZE); yy++) { - BlockData bd = chunkData.getBlockData(x, yy, z); - if (bd.getMaterial().isSolid() && r.nextBoolean()) { - chunkData.setBlock(x, yy, z, o.material()); - } - } - } - } + @Override + public List getDefaultPopulators(final World world) { + return this.blockPopulators; + } + + @Override + public BiomeProvider getDefaultBiomeProvider(WorldInfo worldInfo) { + return biomeProvider; } @Override public boolean shouldGenerateSurface() { - return false; + return true; } @Override @@ -138,12 +138,23 @@ public class ChunkGeneratorWorld extends ChunkGenerator { @Override public boolean shouldGenerateCaves() { - return true; + return this.isNewGenerator; } - @Override - public boolean shouldGenerateDecorations() { - return true; - } + /** + * Called when config is reloaded + */ + public void reload() { + this.blockPopulators.clear(); + this.isNewGenerator = this.settings.isNewMaterialGenerator(); + if (this.isNewGenerator) { + this.blockPopulators.add(new NewMaterialPopulator(this.settings.getWorldDepth())); + this.biomeProvider = null; + } else { + this.blockPopulators.add(new MaterialPopulator(this.addon)); + this.blockPopulators.add(new EntitiesPopulator(this.addon)); + this.biomeProvider = new FlatBiomeProvider(this.addon); + } + } } diff --git a/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java b/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java index 8838939..cc3ef63 100644 --- a/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java +++ b/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java @@ -11,10 +11,15 @@ import world.bentobox.caveblock.generators.Ore; import java.util.*; +/** + * @author tastybento + */ public class NewMaterialPopulator extends BlockPopulator { - private final Map> ores = new EnumMap<>(World.Environment.class); + private static final int BLOB_SIZE = 1; + private static final Map> ORES; - public NewMaterialPopulator() { + static { + Map> ores = new EnumMap<>(World.Environment.class); // Source https://minecraft.fandom.com/wiki/Blob List worldOres = new ArrayList<>(); worldOres.add(new Ore(-64, 16, Material.DIAMOND_ORE, 1, 10, true)); @@ -59,12 +64,20 @@ public class NewMaterialPopulator extends BlockPopulator { endOres.add(new Ore(95, 136, Material.OBSIDIAN, 20, 17, false)); endOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8, 33, false)); ores.put(World.Environment.THE_END, endOres); + ORES = Collections.unmodifiableMap(ores); + } + + private final int worldDepth; + + public NewMaterialPopulator(int worldDepth) { + this.worldDepth = worldDepth; } @Override public void populate(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, LimitedRegion limitedRegion) { - for (int y = worldInfo.getMinHeight(); y < worldInfo.getMaxHeight(); y++) { - for (Ore o : ores.get(worldInfo.getEnvironment())) { + final int worldHeight = Math.min(worldInfo.getMaxHeight(), this.worldDepth); + for (int y = worldInfo.getMinHeight(); y < worldHeight - 1; y++) { + for (Ore o : ORES.get(worldInfo.getEnvironment())) { if (y > o.minY() && y < o.maxY() && random.nextInt(100) <= o.chance()) { pasteBlob(worldInfo, random, chunkX, chunkZ, limitedRegion, y, o); if (o.cont()) { @@ -76,12 +89,10 @@ public class NewMaterialPopulator extends BlockPopulator { } private void pasteBlob(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, LimitedRegion limitedRegion, int y, Ore o) { - //int blobSize = (int) (((double)random.nextInt(o.blob()) / 3) + 1); - int blobSize = 1; int offset = random.nextInt(16); - for (int x = Math.max(0, offset - blobSize); x < Math.min(16, offset + blobSize); x++) { - for (int z = Math.max(0, offset - blobSize); z < Math.min(16, offset + blobSize); z++) { - for (int yy = Math.max(worldInfo.getMinHeight(), y - blobSize); yy < Math.min(worldInfo.getMaxHeight(), y + blobSize); yy++) { + for (int x = Math.max(0, offset - BLOB_SIZE); x < Math.min(16, offset + BLOB_SIZE); x++) { + for (int z = Math.max(0, offset - BLOB_SIZE); z < Math.min(16, offset + BLOB_SIZE); z++) { + for (int yy = Math.max(worldInfo.getMinHeight(), y - BLOB_SIZE); yy < Math.min(worldInfo.getMaxHeight(), y + BLOB_SIZE); yy++) { Location location = Utils.getLocationFromChunkLocation(x, yy, z, chunkX, chunkZ); if (!limitedRegion.isInRegion(location)) { continue;