diff --git a/src/main/java/biomesoplenty/api/biome/BOPBiomes.java b/src/main/java/biomesoplenty/api/biome/BOPBiomes.java index af87ae66b..56a285b48 100644 --- a/src/main/java/biomesoplenty/api/biome/BOPBiomes.java +++ b/src/main/java/biomesoplenty/api/biome/BOPBiomes.java @@ -26,4 +26,5 @@ public class BOPBiomes public static Optional shrubland = Optional.absent(); public static Optional steppe = Optional.absent(); public static Optional thicket = Optional.absent(); + public static Optional woodland = Optional.absent(); } diff --git a/src/main/java/biomesoplenty/api/biome/generation/GeneratorCustomizable.java b/src/main/java/biomesoplenty/api/biome/generation/BOPGeneratorBase.java similarity index 56% rename from src/main/java/biomesoplenty/api/biome/generation/GeneratorCustomizable.java rename to src/main/java/biomesoplenty/api/biome/generation/BOPGeneratorBase.java index cb28058cb..f3568724a 100644 --- a/src/main/java/biomesoplenty/api/biome/generation/GeneratorCustomizable.java +++ b/src/main/java/biomesoplenty/api/biome/generation/BOPGeneratorBase.java @@ -8,15 +8,20 @@ package biomesoplenty.api.biome.generation; -import biomesoplenty.common.util.config.BOPConfig.IConfigObj; +import java.util.Random; -public abstract class GeneratorCustomizable implements IGenerator +import net.minecraft.util.BlockPos; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +public abstract class BOPGeneratorBase implements IGenerator { private final String identifier; private String name; private GeneratorStage stage; + protected float amountPerChunk; - protected GeneratorCustomizable() + protected BOPGeneratorBase(float amountPerChunk) { this.identifier = GeneratorRegistry.getIdentifier((Class)this.getClass()); @@ -24,6 +29,8 @@ public abstract class GeneratorCustomizable implements IGenerator { throw new RuntimeException("The identifier for " + this.getClass().getCanonicalName() + " cannot be null!"); } + + this.amountPerChunk = amountPerChunk; } @Override @@ -56,9 +63,26 @@ public abstract class GeneratorCustomizable implements IGenerator return this.identifier; } - @Override - public void configure(IConfigObj conf) + public abstract BlockPos getScatterY(World world, Random random, int x, int z); + + public int getAmountToScatter(Random random) { - ; + int amount = MathHelper.floor_float(this.amountPerChunk); + float remainder = this.amountPerChunk - amount; + if (random.nextFloat() < remainder) {amount++;} + return amount; } + + @Override + public void scatter(World world, Random random, BlockPos pos) + { + int amount = this.getAmountToScatter(random); + for (int i = 0; i < amount; i++) + { + int x = pos.getX() + random.nextInt(16) + 8; + int z = pos.getZ() + random.nextInt(16) + 8; + generate(world, random, this.getScatterY(world, random, x, z)); + } + } + } diff --git a/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java b/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java index f666d84a0..2040f724b 100644 --- a/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java +++ b/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java @@ -16,9 +16,8 @@ import net.minecraft.util.BlockPos; import net.minecraft.world.World; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorWeighted extends GeneratorCustomizable +public class GeneratorWeighted extends BOPGeneratorBase { - private int amountPerChunk; private HashMap generators = new HashMap(); private HashMap weights = new HashMap(); @@ -28,9 +27,9 @@ public class GeneratorWeighted extends GeneratorCustomizable this(1); } - public GeneratorWeighted(int amountPerChunk) + public GeneratorWeighted(float amountPerChunk) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); } public void add(String name, int weight, IGenerator entry) @@ -83,12 +82,15 @@ public class GeneratorWeighted extends GeneratorCustomizable return null; } - + // never used - the scatter method is overriden + @Override + public BlockPos getScatterY(World world, Random random, int x, int z) {return null;} @Override public void scatter(World world, Random random, BlockPos pos) { - for (int i = 0; i < amountPerChunk; i++) + int amount = this.getAmountToScatter(random); + for (int i = 0; i < amount; i++) { this.getRandomGenerator(random).scatter(world, random, pos); } @@ -105,7 +107,7 @@ public class GeneratorWeighted extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); IConfigObj confGenerators = conf.getObject("generators"); if (confGenerators != null) { diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenChaparral.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenChaparral.java index 77b7ff904..a6f2631d0 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenChaparral.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenChaparral.java @@ -22,6 +22,7 @@ import biomesoplenty.common.block.BlockBOPPlant; import biomesoplenty.common.block.BlockGem; import biomesoplenty.common.enums.BOPGems; import biomesoplenty.common.enums.BOPPlants; +import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod; import biomesoplenty.common.world.feature.GeneratorDoubleFlora; import biomesoplenty.common.world.feature.GeneratorFlora; import biomesoplenty.common.world.feature.GeneratorGrass; @@ -46,7 +47,7 @@ public class BiomeGenChaparral extends BOPBiome // stone patches // TODO: make the generator only run at the surface? - this.addGenerator("stone_patches", GeneratorStage.SAND, new GeneratorSplotches(15, Blocks.stone.getDefaultState(), 32, Blocks.grass)); + this.addGenerator("stone_patches", GeneratorStage.SAND, new GeneratorSplotches(15, Blocks.stone.getDefaultState(), 32, Blocks.grass, ScatterYMethod.AT_OR_BELOW_SURFACE)); // flowers GeneratorWeighted flowerGenerator = new GeneratorWeighted(5); diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenHighland.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenHighland.java index d9e739ed7..9f50e93d6 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenHighland.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenHighland.java @@ -17,6 +17,7 @@ import biomesoplenty.api.biome.generation.GeneratorStage; import biomesoplenty.api.biome.generation.GeneratorWeighted; import biomesoplenty.common.block.BlockBOPPlant; import biomesoplenty.common.enums.BOPPlants; +import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod; import biomesoplenty.common.world.feature.GeneratorBlobs; import biomesoplenty.common.world.feature.GeneratorDoubleFlora; import biomesoplenty.common.world.feature.GeneratorFlora; @@ -41,8 +42,8 @@ public class BiomeGenHighland extends BOPBiome // boulders // TODO: make the generator only run at the surface? - this.addGenerator("boulders", GeneratorStage.SAND, new GeneratorBlobs(4, Blocks.cobblestone.getDefaultState(), 0.3F, 1.2F, 0.5F, 1, Blocks.grass)); - this.addGenerator("big_boulders", GeneratorStage.SAND, new GeneratorBlobs(1, Blocks.cobblestone.getDefaultState(), 0.3F, 4.0F, 0.5F, 3, Blocks.grass)); + this.addGenerator("boulders", GeneratorStage.SAND, new GeneratorBlobs(4, Blocks.cobblestone.getDefaultState(), 0.3F, 1.2F, 0.5F, 1, Blocks.grass, ScatterYMethod.AT_OR_BELOW_SURFACE)); + this.addGenerator("big_boulders", GeneratorStage.SAND, new GeneratorBlobs(1, Blocks.cobblestone.getDefaultState(), 0.3F, 4.0F, 0.5F, 3, Blocks.grass, ScatterYMethod.AT_OR_BELOW_SURFACE)); // grasses diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenWoodland.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenWoodland.java new file mode 100644 index 000000000..a19587f2b --- /dev/null +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenWoodland.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 2015, the Biomes O' Plenty Team + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. + ******************************************************************************/ + +package biomesoplenty.common.biome.overworld; + +import net.minecraft.block.BlockDoublePlant; +import net.minecraft.block.BlockTallGrass; +import net.minecraft.init.Blocks; +import net.minecraftforge.common.BiomeManager.BiomeType; +import biomesoplenty.api.biome.BOPBiome; +import biomesoplenty.api.biome.generation.GeneratorStage; +import biomesoplenty.api.biome.generation.GeneratorWeighted; +import biomesoplenty.api.block.BOPBlocks; +import biomesoplenty.common.block.BlockBOPDoublePlant; +import biomesoplenty.common.block.BlockBOPLilypad; +import biomesoplenty.common.block.BlockBOPMushroom; +import biomesoplenty.common.block.BlockBOPPlant; +import biomesoplenty.common.block.BlockGem; +import biomesoplenty.common.enums.BOPGems; +import biomesoplenty.common.enums.BOPPlants; +import biomesoplenty.common.world.feature.GeneratorBigMushroom; +import biomesoplenty.common.world.feature.GeneratorDoubleFlora; +import biomesoplenty.common.world.feature.GeneratorFlora; +import biomesoplenty.common.world.feature.GeneratorGrass; +import biomesoplenty.common.world.feature.GeneratorLogs; +import biomesoplenty.common.world.feature.GeneratorOreSingle; +import biomesoplenty.common.world.feature.GeneratorWaterside; +import biomesoplenty.common.world.feature.tree.GeneratorBasicTree; +import biomesoplenty.common.world.feature.tree.GeneratorBigTree; + +public class BiomeGenWoodland extends BOPBiome +{ + + private static final Height biomeHeight = new Height(0.1F, 0.2F); + + public BiomeGenWoodland() + { + this.setHeight(biomeHeight); + this.setColor(0x84A92D); + this.setTemperatureRainfall(0.6F, 0.4F); + + this.addWeight(BiomeType.COOL, 10); + + // trees + GeneratorWeighted treeGenerator = new GeneratorWeighted(9); + this.addGenerator("trees", GeneratorStage.TREE, treeGenerator); + treeGenerator.add("oak_large", 1, new GeneratorBigTree(1, false, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); + treeGenerator.add("oak", 9, new GeneratorBasicTree(1, false, 5, 8, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); + + // grasses + GeneratorWeighted grassGenerator = new GeneratorWeighted(14); + this.addGenerator("grass", GeneratorStage.GRASS, grassGenerator); + grassGenerator.add("wheatgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); + grassGenerator.add("dampgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.DAMPGRASS))); + grassGenerator.add("tallgrass", 2, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); + + // big mushrooms + GeneratorWeighted mushroomGenerator = new GeneratorWeighted(1); + this.addGenerator("big_mushrooms", GeneratorStage.TREE, mushroomGenerator); + mushroomGenerator.add("brown_mushroom", 1, new GeneratorBigMushroom(1, GeneratorBigMushroom.BigMushroomType.BROWN)); + mushroomGenerator.add("red_mushroom", 1, new GeneratorBigMushroom(1, GeneratorBigMushroom.BigMushroomType.RED)); + + // gravel + this.addGenerator("gravel", GeneratorStage.SAND_PASS2, new GeneratorWaterside(4, 7, Blocks.gravel.getDefaultState())); + + // flowers + GeneratorWeighted flowerGenerator = new GeneratorWeighted(5); + this.addGenerator("flowers", GeneratorStage.GRASS, flowerGenerator); + flowerGenerator.add("rose", 1, new GeneratorDoubleFlora(1, BlockDoublePlant.EnumPlantType.ROSE, 64)); + + // other plants + this.addGenerator("toadstools", GeneratorStage.FLOWERS, new GeneratorFlora(3, BOPBlocks.mushroom.getDefaultState().withProperty(BlockBOPMushroom.VARIANT, BlockBOPMushroom.MushroomType.TOADSTOOL))); + this.addGenerator("shrubs", GeneratorStage.FLOWERS, new GeneratorFlora(20, BlockBOPPlant.paging.getVariantState(BOPPlants.SHRUB))); + this.addGenerator("clover_patches", GeneratorStage.FLOWERS, new GeneratorFlora(10, BlockBOPPlant.paging.getVariantState(BOPPlants.CLOVERPATCH))); + this.addGenerator("leaf_piles", GeneratorStage.FLOWERS, new GeneratorFlora(10, BlockBOPPlant.paging.getVariantState(BOPPlants.LEAFPILE), 256)); + this.addGenerator("dead_leaf_piles", GeneratorStage.FLOWERS, new GeneratorFlora(10, BlockBOPPlant.paging.getVariantState(BOPPlants.DEADLEAFPILE), 256)); + this.addGenerator("flax", GeneratorStage.FLOWERS, new GeneratorDoubleFlora(1, BlockBOPDoublePlant.DoublePlantType.FLAX, 64)); + + // water plants + this.addGenerator("water_reeds", GeneratorStage.LILYPAD, new GeneratorFlora(5, BlockBOPPlant.paging.getVariantState(BOPPlants.REED), 128)); + this.addGenerator("duckweed", GeneratorStage.LILYPAD, new GeneratorFlora(5, BOPBlocks.waterlily.getDefaultState().withProperty(BlockBOPLilypad.VARIANT, BlockBOPLilypad.LilypadType.DUCKWEED), 128)); + + // logs + this.addGenerator("logs", GeneratorStage.TREE, new GeneratorLogs(8, Blocks.log.getDefaultState(), 3, 5, Blocks.grass)); + + // gem + this.addGenerator("amber", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, BOPGems.AMBER), 15, 4, 32)); + + } + +} \ No newline at end of file diff --git a/src/main/java/biomesoplenty/common/init/ModBiomes.java b/src/main/java/biomesoplenty/common/init/ModBiomes.java index 275491e91..9cd6a9067 100644 --- a/src/main/java/biomesoplenty/common/init/ModBiomes.java +++ b/src/main/java/biomesoplenty/common/init/ModBiomes.java @@ -84,6 +84,7 @@ public class ModBiomes shrubland = registerBOPBiome(new BiomeGenShrubland(), "Shrubland"); steppe = registerBOPBiome(new BiomeGenSteppe(), "Steppe"); thicket = registerBOPBiome(new BiomeGenThicket(), "Thicket"); + woodland = registerBOPBiome(new BiomeGenWoodland(), "Woodland"); } private static Optional registerBOPBiome(BOPBiome biome, String name) diff --git a/src/main/java/biomesoplenty/common/util/biome/GeneratorUtils.java b/src/main/java/biomesoplenty/common/util/biome/GeneratorUtils.java index 56ee71561..2cc3d05f1 100644 --- a/src/main/java/biomesoplenty/common/util/biome/GeneratorUtils.java +++ b/src/main/java/biomesoplenty/common/util/biome/GeneratorUtils.java @@ -45,6 +45,15 @@ public class GeneratorUtils return random.nextInt(i); } + // get a random number between 2 values (inclusive of end points) + public static int nextIntBetween(Random rand, int a, int b) + { + if (a == b) {return a;} + int min = a < b ? a : b; + int max = a > b ? a : b; + return min + rand.nextInt(1 + max - min); + } + public static IBlockState deserializeStateNonNull(JsonObject json, String memberName, JsonDeserializationContext context) { IBlockState state = context.deserialize(json.get(memberName), IBlockState.class); @@ -67,4 +76,41 @@ public class GeneratorUtils IBlockState state = world.getBlockState(pos); return state.getBlock().isAir(world, pos) || state.getBlock().isLeaves(world, pos) || state.getBlock().isWood(world, pos) || isBlockTreeReplacable(state.getBlock()); } + + + public static enum ScatterYMethod + { + ANYWHERE, AT_SURFACE, AT_OR_BELOW_SURFACE, BELOW_SURFACE, AT_OR_ABOVE_SURFACE, ABOVE_SURFACE; + public BlockPos getBlockPos(World world, Random random, int x, int z) + { + int surfaceY; + switch(this) + { + case AT_SURFACE: + // always at world surface + return world.getHeight(new BlockPos(x, 0, z)); + case AT_OR_BELOW_SURFACE: + // random point below or at surface + surfaceY = world.getHeight(new BlockPos(x, 0, z)).getY(); + return new BlockPos(x, nextIntBetween(random, 1, surfaceY), z); + case BELOW_SURFACE: + // random point below surface + surfaceY = world.getHeight(new BlockPos(x, 0, z)).getY(); + return new BlockPos(x, nextIntBetween(random, 1, surfaceY - 1), z); + case AT_OR_ABOVE_SURFACE: + // random point at or above surface + surfaceY = world.getHeight(new BlockPos(x, 0, z)).getY(); + return new BlockPos(x, GeneratorUtils.nextIntBetween(random, surfaceY, 255), z); + case ABOVE_SURFACE: + // random point above surface + surfaceY = world.getHeight(new BlockPos(x, 0, z)).getY(); + return new BlockPos(x, GeneratorUtils.nextIntBetween(random, surfaceY + 1, 255), z); + case ANYWHERE: default: + // random y coord + return new BlockPos(x, nextIntBetween(random, 1, 255), z); + } + } + } + + } diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorBigMushroom.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorBigMushroom.java index ffd267c3a..cb4ff7caa 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorBigMushroom.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorBigMushroom.java @@ -17,13 +17,14 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; +import biomesoplenty.common.util.biome.GeneratorUtils; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryAny; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryMaterial; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorBigMushroom extends GeneratorCustomizable +public class GeneratorBigMushroom extends BOPGeneratorBase { public static enum BigMushroomType @@ -76,7 +77,6 @@ public class GeneratorBigMushroom extends GeneratorCustomizable private static IBlockQuery isLeavesOrAir = new BlockQueryAny(new BlockQueryMaterial(Material.leaves), new BlockQueryMaterial(Material.air)); - protected int amountPerChunk; protected BigMushroomType mushroomType; protected IBlockState mushroomState; @@ -86,11 +86,11 @@ public class GeneratorBigMushroom extends GeneratorCustomizable this(4, BigMushroomType.BROWN); } - public GeneratorBigMushroom(int amountPerChunk, BigMushroomType mushroomType) + public GeneratorBigMushroom(float amountPerChunk, BigMushroomType mushroomType) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.setMushroomType(mushroomType); - } + } public void setMushroomType(BigMushroomType type) { @@ -100,16 +100,10 @@ public class GeneratorBigMushroom extends GeneratorCustomizable @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < this.amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - BlockPos genPos = world.getHeight(pos.add(x, 0, z)); - - generate(world, random, genPos); - } + // always at world surface + return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z); } protected void replaceWithMushroom(World world, BlockPos pos, BlockHugeMushroom.EnumType side) @@ -278,7 +272,7 @@ public class GeneratorBigMushroom extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.setMushroomType(conf.getEnum("type", this.mushroomType, BigMushroomType.class)); } diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorBlobs.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorBlobs.java index 0b6fd1406..bd3a6c6e6 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorBlobs.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorBlobs.java @@ -17,8 +17,8 @@ import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; -import biomesoplenty.common.util.biome.GeneratorUtils; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; +import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod; import biomesoplenty.common.util.block.BlockQueryUtils; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryAny; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryMaterial; @@ -27,58 +27,52 @@ import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorBlobs extends GeneratorCustomizable +public class GeneratorBlobs extends BOPGeneratorBase { - protected int amountPerChunk; protected IBlockQuery placeOn; protected IBlockState to; protected float minRadius; protected float maxRadius; protected float radiusFalloff; // should normally be between 0 and 1 so that balls get smaller - protected int numBalls; + protected int numBalls; + protected ScatterYMethod scatterYMethod; public GeneratorBlobs() { - this(1, Blocks.cobblestone.getDefaultState(), 2.0F, 5.0F, 0.5F, 3, new BlockQueryAny(new BlockQueryBlock(Blocks.stone), new BlockQueryMaterial(Material.ground), new BlockQueryMaterial(Material.grass))); + this(1, Blocks.cobblestone.getDefaultState(), 2.0F, 5.0F, 0.5F, 3, new BlockQueryAny(new BlockQueryBlock(Blocks.stone), new BlockQueryMaterial(Material.ground), new BlockQueryMaterial(Material.grass)), ScatterYMethod.AT_OR_BELOW_SURFACE); } - public GeneratorBlobs(int amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, String from) throws BlockQueryParseException + public GeneratorBlobs(float amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, String from, ScatterYMethod scatterYMethod) throws BlockQueryParseException { - this(amountPerChunk, to, minRadius, maxRadius, radiusFalloff, numBalls, BlockQueryUtils.parseQueryString(from)); + this(amountPerChunk, to, minRadius, maxRadius, radiusFalloff, numBalls, BlockQueryUtils.parseQueryString(from), scatterYMethod); } - public GeneratorBlobs(int amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, Block from) + public GeneratorBlobs(float amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, Block from, ScatterYMethod scatterYMethod) { - this(amountPerChunk, to, minRadius, maxRadius, radiusFalloff, numBalls, new BlockQueryUtils.BlockQueryBlock(from)); + this(amountPerChunk, to, minRadius, maxRadius, radiusFalloff, numBalls, new BlockQueryUtils.BlockQueryBlock(from), scatterYMethod); } - public GeneratorBlobs(int amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, IBlockState from) + public GeneratorBlobs(float amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, IBlockState from, ScatterYMethod scatterYMethod) { - this(amountPerChunk, to, minRadius, maxRadius, radiusFalloff, numBalls, new BlockQueryUtils.BlockQueryState(from)); + this(amountPerChunk, to, minRadius, maxRadius, radiusFalloff, numBalls, new BlockQueryUtils.BlockQueryState(from), scatterYMethod); } - public GeneratorBlobs(int amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, IBlockQuery placeOn) + public GeneratorBlobs(float amountPerChunk, IBlockState to, float minRadius, float maxRadius, float radiusFalloff, int numBalls, IBlockQuery placeOn, ScatterYMethod scatterYMethod) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.to = to; this.minRadius = minRadius; this.maxRadius = maxRadius; this.radiusFalloff = radiusFalloff; this.numBalls = numBalls; this.placeOn = placeOn; + this.scatterYMethod = scatterYMethod; } @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - // pick a random point in the chunk - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - int y = GeneratorUtils.safeNextInt(random, world.getHeight(pos.add(x, 0, z)).getY() + 32); - generate(world, random, pos.add(x, y, z)); - } + return this.scatterYMethod.getBlockPos(world, random, x, z); } @Override @@ -164,7 +158,7 @@ public class GeneratorBlobs extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.to = conf.getBlockState("to", this.to); this.minRadius = conf.getFloat("innerRadius", this.minRadius); this.radiusFalloff = conf.getFloat("radiusFalloff", this.radiusFalloff); @@ -179,6 +173,7 @@ public class GeneratorBlobs extends GeneratorCustomizable conf.addMessage("placeOn", e.getMessage()); } } + this.scatterYMethod = conf.getEnum("scatterYMethod", this.scatterYMethod, ScatterYMethod.class); } diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorDoubleFlora.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorDoubleFlora.java index f78e9ebc0..abb275c88 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorDoubleFlora.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorDoubleFlora.java @@ -10,7 +10,7 @@ package biomesoplenty.common.world.feature; import java.util.Random; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; import biomesoplenty.api.block.BOPBlocks; import biomesoplenty.common.block.BlockBOPDoublePlant; import biomesoplenty.common.block.BlockDecoration; @@ -24,9 +24,8 @@ import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; -public class GeneratorDoubleFlora extends GeneratorCustomizable +public class GeneratorDoubleFlora extends BOPGeneratorBase { - private int amountPerChunk; private IBlockState bottomState; private IBlockState topState; private int generationAttempts; @@ -38,43 +37,36 @@ public class GeneratorDoubleFlora extends GeneratorCustomizable } // convenient shortcut constructor for use with a BlockBOPDoublePlant variant - public GeneratorDoubleFlora(int amountPerChunk, BlockBOPDoublePlant.DoublePlantType type, int generationAttempts) + public GeneratorDoubleFlora(float amountPerChunk, BlockBOPDoublePlant.DoublePlantType type, int generationAttempts) { this(amountPerChunk, BOPBlocks.double_plant.getDefaultState().withProperty(BlockBOPDoublePlant.VARIANT, type).withProperty(BlockBOPDoublePlant.HALF, BlockDoubleDecoration.Half.LOWER), BOPBlocks.double_plant.getDefaultState().withProperty(BlockBOPDoublePlant.VARIANT, type).withProperty(BlockBOPDoublePlant.HALF, BlockDoubleDecoration.Half.UPPER), generationAttempts); } // convenient shortcut constructor for use with a vanilla BlockDoublePlant variant - public GeneratorDoubleFlora(int amountPerChunk, BlockDoublePlant.EnumPlantType type, int generationAttempts) + public GeneratorDoubleFlora(float amountPerChunk, BlockDoublePlant.EnumPlantType type, int generationAttempts) { this(amountPerChunk, Blocks.double_plant.getStateFromMeta(type.getMeta()), Blocks.double_plant.getStateFromMeta(8), generationAttempts); } - public GeneratorDoubleFlora(int amountPerChunk, IBlockState bottomState, IBlockState topState, int generationAttempts) + public GeneratorDoubleFlora(float amountPerChunk, IBlockState bottomState, IBlockState topState, int generationAttempts) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.bottomState = bottomState; this.topState = topState; this.generationAttempts = generationAttempts; } - public GeneratorDoubleFlora(int amountPerChunk, IBlockState bottomState, IBlockState topState) + public GeneratorDoubleFlora(float amountPerChunk, IBlockState bottomState, IBlockState topState) { this(amountPerChunk, bottomState, topState, 64); } - + + @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - BlockPos genPos = pos.add(x, 0, z); - int y = GeneratorUtils.safeNextInt(random, world.getHeight(genPos).getY() + 32); - genPos = genPos.add(0, y, 0); - - generate(world, random, genPos); - } + // always at world surface + return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z); } @Override @@ -101,7 +93,7 @@ public class GeneratorDoubleFlora extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.bottomState = conf.getBlockState("bottomState", this.bottomState); this.topState = conf.getBlockState("topState", this.topState); this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts); diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorFlora.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorFlora.java index 1b9c911d0..447810f26 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorFlora.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorFlora.java @@ -15,14 +15,13 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; import biomesoplenty.common.block.BlockDecoration; import biomesoplenty.common.util.biome.GeneratorUtils; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorFlora extends GeneratorCustomizable +public class GeneratorFlora extends BOPGeneratorBase { - protected int amountPerChunk; protected IBlockState state; protected int generationAttempts; @@ -32,31 +31,23 @@ public class GeneratorFlora extends GeneratorCustomizable this(1, Blocks.red_flower.getDefaultState(), 64); } - public GeneratorFlora(int amountPerChunk, IBlockState state, int generationAttempts) + public GeneratorFlora(float amountPerChunk, IBlockState state, int generationAttempts) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.state = state; this.generationAttempts = generationAttempts; } - public GeneratorFlora(int amountPerChunk, IBlockState state) + public GeneratorFlora(float amountPerChunk, IBlockState state) { this(amountPerChunk, state, 64); } - + @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - BlockPos genPos = pos.add(x, 0, z); - int y = GeneratorUtils.safeNextInt(random, world.getHeight(genPos).getY() + 32); - genPos = genPos.add(0, y, 0); - - generate(world, random, genPos); - } + // always at world surface + return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z); } @Override @@ -82,7 +73,7 @@ public class GeneratorFlora extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.state = conf.getBlockState("state", this.state); this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts); } diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorLogs.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorLogs.java index bb7e71356..a05d7553d 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorLogs.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorLogs.java @@ -19,8 +19,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; -import biomesoplenty.common.util.biome.GeneratorUtils; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; import biomesoplenty.common.util.block.BlockQueryUtils; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryAny; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryMaterial; @@ -28,10 +27,9 @@ import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorLogs extends GeneratorCustomizable +public class GeneratorLogs extends BOPGeneratorBase { - protected int amountPerChunk; protected IBlockState log; protected IProperty axisProperty; protected IBlockQuery placeOn; @@ -44,25 +42,25 @@ public class GeneratorLogs extends GeneratorCustomizable this(6, Blocks.log.getDefaultState(), 1, 5, new BlockQueryAny(new BlockQueryMaterial(Material.ground), new BlockQueryMaterial(Material.grass))); } - public GeneratorLogs(int amountPerChunk, IBlockState log, int minLength, int maxLength, String from) throws BlockQueryParseException + public GeneratorLogs(float amountPerChunk, IBlockState log, int minLength, int maxLength, String from) throws BlockQueryParseException { this(amountPerChunk, log, minLength, maxLength, BlockQueryUtils.parseQueryString(from)); } - public GeneratorLogs(int amountPerChunk, IBlockState log, int minLength, int maxLength, Block from) + public GeneratorLogs(float amountPerChunk, IBlockState log, int minLength, int maxLength, Block from) { this(amountPerChunk, log, minLength, maxLength, new BlockQueryUtils.BlockQueryBlock(from)); } - public GeneratorLogs(int amountPerChunk, IBlockState log, int minLength, int maxLength, IBlockState from) + public GeneratorLogs(float amountPerChunk, IBlockState log, int minLength, int maxLength, IBlockState from) { this(amountPerChunk, log, minLength, maxLength, new BlockQueryUtils.BlockQueryState(from)); } - public GeneratorLogs(int amountPerChunk, IBlockState log, int minLength, int maxLength, IBlockQuery placeOn) + public GeneratorLogs(float amountPerChunk, IBlockState log, int minLength, int maxLength, IBlockQuery placeOn) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.log = log; this.axisProperty = getAxisProperty(log); if (this.axisProperty == null) @@ -90,16 +88,10 @@ public class GeneratorLogs extends GeneratorCustomizable } @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - // pick a random point in the chunk - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - int y = GeneratorUtils.safeNextInt(random, world.getHeight(pos.add(x, 0, z)).getY()); - generate(world, random, pos.add(x, y, z)); - } + // always at world surface + return world.getHeight(new BlockPos(x, 0, z)); } @@ -131,7 +123,7 @@ public class GeneratorLogs extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); IBlockState log = conf.getBlockState("log", null); if (log != null) { diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorOreBase.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorOreBase.java index 4cde26e51..3e9b64a7e 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorOreBase.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorOreBase.java @@ -15,19 +15,18 @@ import net.minecraft.world.World; import org.apache.commons.lang3.tuple.Pair; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; import biomesoplenty.common.util.biome.GeneratorUtils; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public abstract class GeneratorOreBase extends GeneratorCustomizable +public abstract class GeneratorOreBase extends BOPGeneratorBase { - protected int amountPerChunk; protected int minHeight; protected int maxHeight; - protected GeneratorOreBase(int amountPerChunk, int minHeight, int maxHeight) + protected GeneratorOreBase(float amountPerChunk, int minHeight, int maxHeight) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); Pair heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight); this.minHeight = heights.getLeft(); @@ -35,20 +34,16 @@ public abstract class GeneratorOreBase extends GeneratorCustomizable } @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - BlockPos generatedPos = pos.add(random.nextInt(16), random.nextInt(maxHeight - minHeight) + minHeight, random.nextInt(16)); - - generate(world, random, generatedPos); - } + // between max and min + return world.getHeight(new BlockPos(x, GeneratorUtils.nextIntBetween(random, this.minHeight, this.maxHeight), z)); } @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); int minHeight = conf.getInt("minHeight", this.minHeight).intValue(); int maxHeight = conf.getInt("maxHeight", this.maxHeight).intValue(); diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorOreCluster.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorOreCluster.java index 70a5fb34e..fe51d16dc 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorOreCluster.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorOreCluster.java @@ -27,7 +27,7 @@ public class GeneratorOreCluster extends GeneratorOreBase this(Blocks.emerald_ore.getDefaultState(), 12, 4, 4, 32); } - public GeneratorOreCluster(IBlockState state, int amountPerChunk, int clusterSize, int minHeight, int maxHeight) + public GeneratorOreCluster(IBlockState state, float amountPerChunk, int clusterSize, int minHeight, int maxHeight) { super(amountPerChunk, minHeight, maxHeight); diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorOreSingle.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorOreSingle.java index 164aaba65..b65a2bdab 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorOreSingle.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorOreSingle.java @@ -30,7 +30,7 @@ public class GeneratorOreSingle extends GeneratorOreBase this(Blocks.emerald_ore.getDefaultState(), 12, 4, 32); } - public GeneratorOreSingle(IBlockState state, int amountPerChunk, int minHeight, int maxHeight) + public GeneratorOreSingle(IBlockState state, float amountPerChunk, int minHeight, int maxHeight) { super(amountPerChunk, minHeight, maxHeight); diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorSplatter.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorSplatter.java index badfa1272..1b01c5126 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorSplatter.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorSplatter.java @@ -10,7 +10,8 @@ package biomesoplenty.common.world.feature; import java.util.Random; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; +import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod; import biomesoplenty.common.util.block.BlockQueryUtils; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; @@ -26,55 +27,49 @@ import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; -public class GeneratorSplatter extends GeneratorCustomizable +public class GeneratorSplatter extends BOPGeneratorBase { private static IBlockQuery isLeavesOrAir = new BlockQueryAny(new BlockQueryMaterial(Material.leaves), new BlockQueryMaterial(Material.air)); - protected int amountPerChunk; protected IBlockQuery placeOn; protected int generationAttempts; protected IBlockState to; + protected ScatterYMethod scatterYMethod; public GeneratorSplatter() { // default - this(1, Blocks.stone.getDefaultState(), 64, Blocks.grass); + this(1, Blocks.stone.getDefaultState(), 64, Blocks.grass, ScatterYMethod.ANYWHERE); } - public GeneratorSplatter(int amountPerChunk, IBlockState to, int splotchSize, String placeOn) throws BlockQueryParseException + public GeneratorSplatter(float amountPerChunk, IBlockState to, int splotchSize, String placeOn, ScatterYMethod scatterYMethod) throws BlockQueryParseException { - this(amountPerChunk, to, splotchSize, BlockQueryUtils.parseQueryString(placeOn)); + this(amountPerChunk, to, splotchSize, BlockQueryUtils.parseQueryString(placeOn), scatterYMethod); } - public GeneratorSplatter(int amountPerChunk, IBlockState to, int splotchSize, Block placeOn) + public GeneratorSplatter(float amountPerChunk, IBlockState to, int splotchSize, Block placeOn, ScatterYMethod scatterYMethod) { - this(amountPerChunk, to, splotchSize, new BlockQueryBlock(placeOn)); + this(amountPerChunk, to, splotchSize, new BlockQueryBlock(placeOn), scatterYMethod); } - public GeneratorSplatter(int amountPerChunk, IBlockState to, int splotchSize, IBlockState placeOn) + public GeneratorSplatter(float amountPerChunk, IBlockState to, int splotchSize, IBlockState placeOn, ScatterYMethod scatterYMethod) { - this(amountPerChunk, to, splotchSize, new BlockQueryState(placeOn)); + this(amountPerChunk, to, splotchSize, new BlockQueryState(placeOn), scatterYMethod); } - public GeneratorSplatter(int amountPerChunk, IBlockState to, int generationAttempts, IBlockQuery placeOn) + public GeneratorSplatter(float amountPerChunk, IBlockState to, int generationAttempts, IBlockQuery placeOn, ScatterYMethod scatterYMethod) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.to = to; this.generationAttempts = generationAttempts; this.placeOn = placeOn; + this.scatterYMethod = scatterYMethod; } @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - int y = random.nextInt(256); - BlockPos genPos = pos.add(x, y, z); - generate(world, random, genPos); - } + return this.scatterYMethod.getBlockPos(world, random, x, z); } @Override @@ -102,7 +97,7 @@ public class GeneratorSplatter extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.to = conf.getBlockState("to", this.to); this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts); String placeOnString = conf.getString("placeOn", null); @@ -115,6 +110,7 @@ public class GeneratorSplatter extends GeneratorCustomizable conf.addMessage("placeOn", e.getMessage()); } } + this.scatterYMethod = conf.getEnum("scatterYMethod", this.scatterYMethod, ScatterYMethod.class); } diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorSplotches.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorSplotches.java index a6faa8759..f692652fc 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorSplotches.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorSplotches.java @@ -16,65 +16,55 @@ import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; -import biomesoplenty.common.util.biome.GeneratorUtils; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; +import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod; import biomesoplenty.common.util.block.BlockQueryUtils; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorSplotches extends GeneratorCustomizable +public class GeneratorSplotches extends BOPGeneratorBase { - protected int amountPerChunk; protected IBlockQuery from; protected IBlockState to; protected int splotchSize; + protected ScatterYMethod scatterYMethod; public GeneratorSplotches() { // default - this(1, Blocks.stone.getDefaultState(), 8, Blocks.grass); + this(1, Blocks.stone.getDefaultState(), 8, Blocks.grass, ScatterYMethod.AT_OR_BELOW_SURFACE); } - public GeneratorSplotches(int amountPerChunk, IBlockState to, int splotchSize, String from) throws BlockQueryParseException + public GeneratorSplotches(float amountPerChunk, IBlockState to, int splotchSize, String from, ScatterYMethod scatterYMethod) throws BlockQueryParseException { - this(amountPerChunk, to, splotchSize, BlockQueryUtils.parseQueryString(from)); + this(amountPerChunk, to, splotchSize, BlockQueryUtils.parseQueryString(from), scatterYMethod); } - public GeneratorSplotches(int amountPerChunk, IBlockState to, int splotchSize, Block from) + public GeneratorSplotches(float amountPerChunk, IBlockState to, int splotchSize, Block from, ScatterYMethod scatterYMethod) { - this(amountPerChunk, to, splotchSize, new BlockQueryUtils.BlockQueryBlock(from)); + this(amountPerChunk, to, splotchSize, new BlockQueryUtils.BlockQueryBlock(from), scatterYMethod); } - public GeneratorSplotches(int amountPerChunk, IBlockState to, int splotchSize, IBlockState from) + public GeneratorSplotches(float amountPerChunk, IBlockState to, int splotchSize, IBlockState from, ScatterYMethod scatterYMethod) { - this(amountPerChunk, to, splotchSize, new BlockQueryUtils.BlockQueryState(from)); + this(amountPerChunk, to, splotchSize, new BlockQueryUtils.BlockQueryState(from), scatterYMethod); } - public GeneratorSplotches(int amountPerChunk, IBlockState to, int splotchSize, IBlockQuery from) + public GeneratorSplotches(float amountPerChunk, IBlockState to, int splotchSize, IBlockQuery from, ScatterYMethod scatterYMethod) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.to = to; this.splotchSize = splotchSize; this.from = from; + this.scatterYMethod = scatterYMethod; } - @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - BlockPos genPos = pos.add(x, 0, z); - int y = GeneratorUtils.safeNextInt(random, world.getHeight(genPos).getY() + 32); - genPos = genPos.add(0, y, 0); - - generate(world, random, genPos); - } - } - + return this.scatterYMethod.getBlockPos(world, random, x, z); + } @Override public boolean generate(World world, Random random, BlockPos pos) @@ -112,12 +102,12 @@ public class GeneratorSplotches extends GeneratorCustomizable public void replaceInEllipsoid(World world, double centerX, double centerY, double centerZ, double radiusX, double radiusY, double radiusZ) { - int x0 = MathHelper.floor_double(centerX - radiusX); - int y0 = MathHelper.floor_double(centerY - radiusY); - int z0 = MathHelper.floor_double(centerZ - radiusZ); - int x1 = MathHelper.floor_double(centerX + radiusX); - int y1 = MathHelper.floor_double(centerY + radiusY); - int z1 = MathHelper.floor_double(centerZ + radiusZ); + int x0 = MathHelper.floor_double(centerX - radiusX + 0.5D); + int y0 = MathHelper.floor_double(centerY - radiusY + 0.5D); + int z0 = MathHelper.floor_double(centerZ - radiusZ + 0.5D); + int x1 = MathHelper.floor_double(centerX + radiusX + 0.5D); + int y1 = MathHelper.floor_double(centerY + radiusY + 0.5D); + int z1 = MathHelper.floor_double(centerZ + radiusZ + 0.5D); for (int x = x0; x <= x1; ++x) { @@ -158,7 +148,7 @@ public class GeneratorSplotches extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.to = conf.getBlockState("to", this.to); this.splotchSize = conf.getInt("splotchSize", this.splotchSize); String fromString = conf.getString("from", null); @@ -171,6 +161,7 @@ public class GeneratorSplotches extends GeneratorCustomizable conf.addMessage("from", e.getMessage()); } } + this.scatterYMethod = conf.getEnum("scatterYMethod", this.scatterYMethod, ScatterYMethod.class); } } diff --git a/src/main/java/biomesoplenty/common/world/feature/GeneratorWaterside.java b/src/main/java/biomesoplenty/common/world/feature/GeneratorWaterside.java index 1598ee48f..1739235e6 100644 --- a/src/main/java/biomesoplenty/common/world/feature/GeneratorWaterside.java +++ b/src/main/java/biomesoplenty/common/world/feature/GeneratorWaterside.java @@ -18,12 +18,11 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorWaterside extends GeneratorCustomizable +public class GeneratorWaterside extends BOPGeneratorBase { - private int amountPerChunk; private int maxRadius; private IBlockState state; private List replacedStates; @@ -34,29 +33,23 @@ public class GeneratorWaterside extends GeneratorCustomizable this(4, 7, Blocks.gravel.getDefaultState()); } - public GeneratorWaterside(int amountPerChunk, int maxRadius, IBlockState state, IBlockState... replacedStates) + public GeneratorWaterside(float amountPerChunk, int maxRadius, IBlockState state, IBlockState... replacedStates) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.maxRadius = maxRadius; this.state = state; this.replacedStates = Arrays.asList(replacedStates); } - public GeneratorWaterside(int amountPerChunk, int maxRadius, IBlockState state) + public GeneratorWaterside(float amountPerChunk, int maxRadius, IBlockState state) { this(amountPerChunk, maxRadius, state, Blocks.grass.getDefaultState(), Blocks.dirt.getDefaultState()); } @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < this.amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - - generate(world, random, world.getTopSolidOrLiquidBlock(pos.add(x, 0, z))); - } + return world.getTopSolidOrLiquidBlock(new BlockPos(x, 0, z)); } @Override @@ -108,7 +101,7 @@ public class GeneratorWaterside extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.maxRadius = conf.getInt("maxRadius", this.maxRadius); this.state = conf.getBlockState("state", this.state); this.replacedStates = conf.getBlockStateArray("replacedStates", new ArrayList(this.replacedStates) ); diff --git a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBasicTree.java b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBasicTree.java index 7f936c585..79b84b82a 100644 --- a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBasicTree.java +++ b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBasicTree.java @@ -22,13 +22,12 @@ import net.minecraft.world.World; import org.apache.commons.lang3.tuple.Pair; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; import biomesoplenty.common.util.biome.GeneratorUtils; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorBasicTree extends GeneratorCustomizable +public class GeneratorBasicTree extends BOPGeneratorBase { - private int amountPerChunk; private boolean updateNeighbours; private int minHeight; private int maxHeight; @@ -42,9 +41,9 @@ public class GeneratorBasicTree extends GeneratorCustomizable this(1, false, 4, 7, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState()); } - public GeneratorBasicTree(int amountPerChunk, boolean updateNeighbours, int minHeight, int maxHeight, IBlockState log, IBlockState leaves, IBlockState vine) + public GeneratorBasicTree(float amountPerChunk, boolean updateNeighbours, int minHeight, int maxHeight, IBlockState log, IBlockState leaves, IBlockState vine) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.updateNeighbours = updateNeighbours; Pair heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight); @@ -56,22 +55,16 @@ public class GeneratorBasicTree extends GeneratorCustomizable this.vine = vine; } - public GeneratorBasicTree(int amountPerChunk, boolean updateNeighbours, int minHeight, int maxHeight, IBlockState log, IBlockState leaves) + public GeneratorBasicTree(float amountPerChunk, boolean updateNeighbours, int minHeight, int maxHeight, IBlockState log, IBlockState leaves) { this(amountPerChunk, updateNeighbours, minHeight, maxHeight, log, leaves, null); } - + @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - BlockPos genPos = world.getHeight(pos.add(x, 0, z)); - - generate(world, random, genPos); - } + // always at world surface + return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z); } @Override @@ -304,7 +297,7 @@ public class GeneratorBasicTree extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.updateNeighbours = conf.getBool("updateNeighbours", this.updateNeighbours); int minHeight = conf.getInt("minHeight", this.minHeight); int maxHeight = conf.getInt("maxHeight", this.maxHeight); diff --git a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBigTree.java b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBigTree.java index 836fa8a21..1293526f6 100644 --- a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBigTree.java +++ b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBigTree.java @@ -21,7 +21,7 @@ import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; import biomesoplenty.common.util.biome.GeneratorUtils; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; @@ -30,7 +30,7 @@ import com.google.common.collect.Lists; /*This class is heavily based on https://gist.github.com/grum/62cfdec0537e8db24eb3#file-bigtreefeature-java additional information has been added from http://pastebin.com/XBLdGqXQ. This class has been cross-checked against WorldGenBigTree to ensure any subsequent changes from Forge/Mojang have been included.*/ -public class GeneratorBigTree extends GeneratorCustomizable +public class GeneratorBigTree extends BOPGeneratorBase { private Random random; private World world; @@ -47,7 +47,6 @@ public class GeneratorBigTree extends GeneratorCustomizable private int foliageHeight = 4; //Configurable fields - private int amountPerChunk; private boolean updateNeighbours; private int minHeight; private int maxHeight; @@ -62,9 +61,9 @@ public class GeneratorBigTree extends GeneratorCustomizable this(1, false, 4, 7, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState()); } - public GeneratorBigTree(int amountPerChunk, boolean updateNeighbours, int minHeight, int maxHeight, IBlockState log, IBlockState leaves) + public GeneratorBigTree(float amountPerChunk, boolean updateNeighbours, int minHeight, int maxHeight, IBlockState log, IBlockState leaves) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.updateNeighbours = updateNeighbours; Pair heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight); @@ -75,7 +74,7 @@ public class GeneratorBigTree extends GeneratorCustomizable this.leaves = leaves; } - public GeneratorBigTree(int amountPerChunk, boolean updateNeighbours, IBlockState log, IBlockState leaves) + public GeneratorBigTree(float amountPerChunk, boolean updateNeighbours, IBlockState log, IBlockState leaves) { this(amountPerChunk, updateNeighbours, 5, 17, log, leaves); } @@ -432,20 +431,13 @@ public class GeneratorBigTree extends GeneratorCustomizable return -1; } + + @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - int successes = 0; - - for (int i = 0; i < amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - BlockPos genPos = world.getHeight(pos.add(x, 0, z)); - - if (successes < 2 && generate(world, random, genPos)) - successes++; - } + // always at world surface + return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z); } @Override @@ -537,7 +529,7 @@ public class GeneratorBigTree extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.updateNeighbours = conf.getBool("updateNeighbours", this.updateNeighbours); int minHeight = conf.getInt("minHeight", this.minHeight); int maxHeight = conf.getInt("maxHeight", this.maxHeight); diff --git a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBush.java b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBush.java index c5114360a..1ce9814b8 100644 --- a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBush.java +++ b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorBush.java @@ -17,12 +17,12 @@ import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; -import biomesoplenty.api.biome.generation.GeneratorCustomizable; +import biomesoplenty.api.biome.generation.BOPGeneratorBase; +import biomesoplenty.common.util.biome.GeneratorUtils; import biomesoplenty.common.util.config.BOPConfig.IConfigObj; -public class GeneratorBush extends GeneratorCustomizable +public class GeneratorBush extends BOPGeneratorBase { - private int amountPerChunk; private IBlockState log; private IBlockState leaves; @@ -32,24 +32,18 @@ public class GeneratorBush extends GeneratorCustomizable this(1, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState()); } - public GeneratorBush(int amountPerChunk, IBlockState log, IBlockState leaves) + public GeneratorBush(float amountPerChunk, IBlockState log, IBlockState leaves) { - this.amountPerChunk = amountPerChunk; + super(amountPerChunk); this.log = log; this.leaves = leaves; } @Override - public void scatter(World world, Random random, BlockPos pos) + public BlockPos getScatterY(World world, Random random, int x, int z) { - for (int i = 0; i < amountPerChunk; i++) - { - int x = random.nextInt(16) + 8; - int z = random.nextInt(16) + 8; - BlockPos genPos = world.getHeight(pos.add(x, 0, z)); - - generate(world, random, genPos); - } + // always at world surface + return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z); } @Override @@ -111,7 +105,7 @@ public class GeneratorBush extends GeneratorCustomizable @Override public void configure(IConfigObj conf) { - this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); + this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk); this.log = conf.getBlockState("logState", this.log); this.leaves = conf.getBlockState("leavesState", this.leaves); }