Allow fractional amountPerChunk in generators, reduce code duplication by moving scatter() method into a base class

This commit is contained in:
Cheeserolls 2015-05-31 22:52:41 +01:00
parent 7107c2d0f1
commit 10ed5d64e6
22 changed files with 342 additions and 252 deletions

View File

@ -26,4 +26,5 @@ public class BOPBiomes
public static Optional<BiomeGenBase> shrubland = Optional.absent(); public static Optional<BiomeGenBase> shrubland = Optional.absent();
public static Optional<BiomeGenBase> steppe = Optional.absent(); public static Optional<BiomeGenBase> steppe = Optional.absent();
public static Optional<BiomeGenBase> thicket = Optional.absent(); public static Optional<BiomeGenBase> thicket = Optional.absent();
public static Optional<BiomeGenBase> woodland = Optional.absent();
} }

View File

@ -8,15 +8,20 @@
package biomesoplenty.api.biome.generation; 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 final String identifier;
private String name; private String name;
private GeneratorStage stage; private GeneratorStage stage;
protected float amountPerChunk;
protected GeneratorCustomizable() protected BOPGeneratorBase(float amountPerChunk)
{ {
this.identifier = GeneratorRegistry.getIdentifier((Class<? extends IGenerator>)this.getClass()); this.identifier = GeneratorRegistry.getIdentifier((Class<? extends IGenerator>)this.getClass());
@ -24,6 +29,8 @@ public abstract class GeneratorCustomizable implements IGenerator
{ {
throw new RuntimeException("The identifier for " + this.getClass().getCanonicalName() + " cannot be null!"); throw new RuntimeException("The identifier for " + this.getClass().getCanonicalName() + " cannot be null!");
} }
this.amountPerChunk = amountPerChunk;
} }
@Override @Override
@ -56,9 +63,26 @@ public abstract class GeneratorCustomizable implements IGenerator
return this.identifier; return this.identifier;
} }
@Override public abstract BlockPos getScatterY(World world, Random random, int x, int z);
public void configure(IConfigObj conf)
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));
}
}
} }

View File

@ -16,9 +16,8 @@ import net.minecraft.util.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorWeighted extends GeneratorCustomizable public class GeneratorWeighted extends BOPGeneratorBase
{ {
private int amountPerChunk;
private HashMap<String, IGenerator> generators = new HashMap<String, IGenerator>(); private HashMap<String, IGenerator> generators = new HashMap<String, IGenerator>();
private HashMap<IGenerator, Integer> weights = new HashMap<IGenerator, Integer>(); private HashMap<IGenerator, Integer> weights = new HashMap<IGenerator, Integer>();
@ -28,9 +27,9 @@ public class GeneratorWeighted extends GeneratorCustomizable
this(1); this(1);
} }
public GeneratorWeighted(int amountPerChunk) public GeneratorWeighted(float amountPerChunk)
{ {
this.amountPerChunk = amountPerChunk; super(amountPerChunk);
} }
public void add(String name, int weight, IGenerator entry) public void add(String name, int weight, IGenerator entry)
@ -83,12 +82,15 @@ public class GeneratorWeighted extends GeneratorCustomizable
return null; return null;
} }
// never used - the scatter method is overriden
@Override
public BlockPos getScatterY(World world, Random random, int x, int z) {return null;}
@Override @Override
public void scatter(World world, Random random, BlockPos pos) 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); this.getRandomGenerator(random).scatter(world, random, pos);
} }
@ -105,7 +107,7 @@ public class GeneratorWeighted extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) public void configure(IConfigObj conf)
{ {
this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk);
IConfigObj confGenerators = conf.getObject("generators"); IConfigObj confGenerators = conf.getObject("generators");
if (confGenerators != null) if (confGenerators != null)
{ {

View File

@ -22,6 +22,7 @@ import biomesoplenty.common.block.BlockBOPPlant;
import biomesoplenty.common.block.BlockGem; import biomesoplenty.common.block.BlockGem;
import biomesoplenty.common.enums.BOPGems; import biomesoplenty.common.enums.BOPGems;
import biomesoplenty.common.enums.BOPPlants; import biomesoplenty.common.enums.BOPPlants;
import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod;
import biomesoplenty.common.world.feature.GeneratorDoubleFlora; import biomesoplenty.common.world.feature.GeneratorDoubleFlora;
import biomesoplenty.common.world.feature.GeneratorFlora; import biomesoplenty.common.world.feature.GeneratorFlora;
import biomesoplenty.common.world.feature.GeneratorGrass; import biomesoplenty.common.world.feature.GeneratorGrass;
@ -46,7 +47,7 @@ public class BiomeGenChaparral extends BOPBiome
// stone patches // stone patches
// TODO: make the generator only run at the surface? // 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 // flowers
GeneratorWeighted flowerGenerator = new GeneratorWeighted(5); GeneratorWeighted flowerGenerator = new GeneratorWeighted(5);

View File

@ -17,6 +17,7 @@ import biomesoplenty.api.biome.generation.GeneratorStage;
import biomesoplenty.api.biome.generation.GeneratorWeighted; import biomesoplenty.api.biome.generation.GeneratorWeighted;
import biomesoplenty.common.block.BlockBOPPlant; import biomesoplenty.common.block.BlockBOPPlant;
import biomesoplenty.common.enums.BOPPlants; import biomesoplenty.common.enums.BOPPlants;
import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod;
import biomesoplenty.common.world.feature.GeneratorBlobs; import biomesoplenty.common.world.feature.GeneratorBlobs;
import biomesoplenty.common.world.feature.GeneratorDoubleFlora; import biomesoplenty.common.world.feature.GeneratorDoubleFlora;
import biomesoplenty.common.world.feature.GeneratorFlora; import biomesoplenty.common.world.feature.GeneratorFlora;
@ -41,8 +42,8 @@ public class BiomeGenHighland extends BOPBiome
// boulders // boulders
// TODO: make the generator only run at the surface? // 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("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)); 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 // grasses

View File

@ -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));
}
}

View File

@ -84,6 +84,7 @@ public class ModBiomes
shrubland = registerBOPBiome(new BiomeGenShrubland(), "Shrubland"); shrubland = registerBOPBiome(new BiomeGenShrubland(), "Shrubland");
steppe = registerBOPBiome(new BiomeGenSteppe(), "Steppe"); steppe = registerBOPBiome(new BiomeGenSteppe(), "Steppe");
thicket = registerBOPBiome(new BiomeGenThicket(), "Thicket"); thicket = registerBOPBiome(new BiomeGenThicket(), "Thicket");
woodland = registerBOPBiome(new BiomeGenWoodland(), "Woodland");
} }
private static Optional<BiomeGenBase> registerBOPBiome(BOPBiome biome, String name) private static Optional<BiomeGenBase> registerBOPBiome(BOPBiome biome, String name)

View File

@ -45,6 +45,15 @@ public class GeneratorUtils
return random.nextInt(i); 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) public static IBlockState deserializeStateNonNull(JsonObject json, String memberName, JsonDeserializationContext context)
{ {
IBlockState state = context.deserialize(json.get(memberName), IBlockState.class); IBlockState state = context.deserialize(json.get(memberName), IBlockState.class);
@ -67,4 +76,41 @@ public class GeneratorUtils
IBlockState state = world.getBlockState(pos); IBlockState state = world.getBlockState(pos);
return state.getBlock().isAir(world, pos) || state.getBlock().isLeaves(world, pos) || state.getBlock().isWood(world, pos) || isBlockTreeReplacable(state.getBlock()); 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);
}
}
}
} }

View File

@ -17,13 +17,14 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.world.World; 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.BlockQueryAny;
import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryMaterial; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryMaterial;
import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorBigMushroom extends GeneratorCustomizable public class GeneratorBigMushroom extends BOPGeneratorBase
{ {
public static enum BigMushroomType 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)); private static IBlockQuery isLeavesOrAir = new BlockQueryAny(new BlockQueryMaterial(Material.leaves), new BlockQueryMaterial(Material.air));
protected int amountPerChunk;
protected BigMushroomType mushroomType; protected BigMushroomType mushroomType;
protected IBlockState mushroomState; protected IBlockState mushroomState;
@ -86,11 +86,11 @@ public class GeneratorBigMushroom extends GeneratorCustomizable
this(4, BigMushroomType.BROWN); this(4, BigMushroomType.BROWN);
} }
public GeneratorBigMushroom(int amountPerChunk, BigMushroomType mushroomType) public GeneratorBigMushroom(float amountPerChunk, BigMushroomType mushroomType)
{ {
this.amountPerChunk = amountPerChunk; super(amountPerChunk);
this.setMushroomType(mushroomType); this.setMushroomType(mushroomType);
} }
public void setMushroomType(BigMushroomType type) public void setMushroomType(BigMushroomType type)
{ {
@ -100,16 +100,10 @@ public class GeneratorBigMushroom extends GeneratorCustomizable
@Override @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++) // always at world surface
{ return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z);
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);
}
} }
protected void replaceWithMushroom(World world, BlockPos pos, BlockHugeMushroom.EnumType side) protected void replaceWithMushroom(World world, BlockPos pos, BlockHugeMushroom.EnumType side)
@ -278,7 +272,7 @@ public class GeneratorBigMushroom extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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)); this.setMushroomType(conf.getEnum("type", this.mushroomType, BigMushroomType.class));
} }

View File

@ -17,8 +17,8 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.World; 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.biome.GeneratorUtils.ScatterYMethod;
import biomesoplenty.common.util.block.BlockQueryUtils; import biomesoplenty.common.util.block.BlockQueryUtils;
import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryAny; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryAny;
import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryMaterial; 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.block.BlockQueryUtils.IBlockQuery;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorBlobs extends GeneratorCustomizable public class GeneratorBlobs extends BOPGeneratorBase
{ {
protected int amountPerChunk;
protected IBlockQuery placeOn; protected IBlockQuery placeOn;
protected IBlockState to; protected IBlockState to;
protected float minRadius; protected float minRadius;
protected float maxRadius; protected float maxRadius;
protected float radiusFalloff; // should normally be between 0 and 1 so that balls get smaller 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() 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.to = to;
this.minRadius = minRadius; this.minRadius = minRadius;
this.maxRadius = maxRadius; this.maxRadius = maxRadius;
this.radiusFalloff = radiusFalloff; this.radiusFalloff = radiusFalloff;
this.numBalls = numBalls; this.numBalls = numBalls;
this.placeOn = placeOn; this.placeOn = placeOn;
this.scatterYMethod = scatterYMethod;
} }
@Override @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++) return this.scatterYMethod.getBlockPos(world, random, x, z);
{
// 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));
}
} }
@Override @Override
@ -164,7 +158,7 @@ public class GeneratorBlobs extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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.to = conf.getBlockState("to", this.to);
this.minRadius = conf.getFloat("innerRadius", this.minRadius); this.minRadius = conf.getFloat("innerRadius", this.minRadius);
this.radiusFalloff = conf.getFloat("radiusFalloff", this.radiusFalloff); this.radiusFalloff = conf.getFloat("radiusFalloff", this.radiusFalloff);
@ -179,6 +173,7 @@ public class GeneratorBlobs extends GeneratorCustomizable
conf.addMessage("placeOn", e.getMessage()); conf.addMessage("placeOn", e.getMessage());
} }
} }
this.scatterYMethod = conf.getEnum("scatterYMethod", this.scatterYMethod, ScatterYMethod.class);
} }

View File

@ -10,7 +10,7 @@ package biomesoplenty.common.world.feature;
import java.util.Random; import java.util.Random;
import biomesoplenty.api.biome.generation.GeneratorCustomizable; import biomesoplenty.api.biome.generation.BOPGeneratorBase;
import biomesoplenty.api.block.BOPBlocks; import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.common.block.BlockBOPDoublePlant; import biomesoplenty.common.block.BlockBOPDoublePlant;
import biomesoplenty.common.block.BlockDecoration; import biomesoplenty.common.block.BlockDecoration;
@ -24,9 +24,8 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public class GeneratorDoubleFlora extends GeneratorCustomizable public class GeneratorDoubleFlora extends BOPGeneratorBase
{ {
private int amountPerChunk;
private IBlockState bottomState; private IBlockState bottomState;
private IBlockState topState; private IBlockState topState;
private int generationAttempts; private int generationAttempts;
@ -38,43 +37,36 @@ public class GeneratorDoubleFlora extends GeneratorCustomizable
} }
// convenient shortcut constructor for use with a BlockBOPDoublePlant variant // 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); 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 // 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); 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.bottomState = bottomState;
this.topState = topState; this.topState = topState;
this.generationAttempts = generationAttempts; this.generationAttempts = generationAttempts;
} }
public GeneratorDoubleFlora(int amountPerChunk, IBlockState bottomState, IBlockState topState) public GeneratorDoubleFlora(float amountPerChunk, IBlockState bottomState, IBlockState topState)
{ {
this(amountPerChunk, bottomState, topState, 64); this(amountPerChunk, bottomState, topState, 64);
} }
@Override @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++) // always at world surface
{ return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z);
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);
}
} }
@Override @Override
@ -101,7 +93,7 @@ public class GeneratorDoubleFlora extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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.bottomState = conf.getBlockState("bottomState", this.bottomState);
this.topState = conf.getBlockState("topState", this.topState); this.topState = conf.getBlockState("topState", this.topState);
this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts); this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts);

View File

@ -15,14 +15,13 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.world.World; 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.block.BlockDecoration;
import biomesoplenty.common.util.biome.GeneratorUtils; import biomesoplenty.common.util.biome.GeneratorUtils;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorFlora extends GeneratorCustomizable public class GeneratorFlora extends BOPGeneratorBase
{ {
protected int amountPerChunk;
protected IBlockState state; protected IBlockState state;
protected int generationAttempts; protected int generationAttempts;
@ -32,31 +31,23 @@ public class GeneratorFlora extends GeneratorCustomizable
this(1, Blocks.red_flower.getDefaultState(), 64); 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.state = state;
this.generationAttempts = generationAttempts; this.generationAttempts = generationAttempts;
} }
public GeneratorFlora(int amountPerChunk, IBlockState state) public GeneratorFlora(float amountPerChunk, IBlockState state)
{ {
this(amountPerChunk, state, 64); this(amountPerChunk, state, 64);
} }
@Override @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++) // always at world surface
{ return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z);
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);
}
} }
@Override @Override
@ -82,7 +73,7 @@ public class GeneratorFlora extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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.state = conf.getBlockState("state", this.state);
this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts); this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts);
} }

View File

@ -19,8 +19,7 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.world.World; 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; import biomesoplenty.common.util.block.BlockQueryUtils;
import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryAny; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryAny;
import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryMaterial; 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.block.BlockQueryUtils.IBlockQuery;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorLogs extends GeneratorCustomizable public class GeneratorLogs extends BOPGeneratorBase
{ {
protected int amountPerChunk;
protected IBlockState log; protected IBlockState log;
protected IProperty axisProperty; protected IProperty axisProperty;
protected IBlockQuery placeOn; 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))); 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)); 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)); 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)); 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.log = log;
this.axisProperty = getAxisProperty(log); this.axisProperty = getAxisProperty(log);
if (this.axisProperty == null) if (this.axisProperty == null)
@ -90,16 +88,10 @@ public class GeneratorLogs extends GeneratorCustomizable
} }
@Override @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++) // always at world surface
{ return world.getHeight(new BlockPos(x, 0, z));
// 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));
}
} }
@ -131,7 +123,7 @@ public class GeneratorLogs extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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); IBlockState log = conf.getBlockState("log", null);
if (log != null) if (log != null)
{ {

View File

@ -15,19 +15,18 @@ import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair; 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.biome.GeneratorUtils;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; 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 minHeight;
protected int maxHeight; 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<Integer, Integer> heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight); Pair<Integer, Integer> heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight);
this.minHeight = heights.getLeft(); this.minHeight = heights.getLeft();
@ -35,20 +34,16 @@ public abstract class GeneratorOreBase extends GeneratorCustomizable
} }
@Override @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++) // between max and min
{ return world.getHeight(new BlockPos(x, GeneratorUtils.nextIntBetween(random, this.minHeight, this.maxHeight), z));
BlockPos generatedPos = pos.add(random.nextInt(16), random.nextInt(maxHeight - minHeight) + minHeight, random.nextInt(16));
generate(world, random, generatedPos);
}
} }
@Override @Override
public void configure(IConfigObj conf) 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 minHeight = conf.getInt("minHeight", this.minHeight).intValue();
int maxHeight = conf.getInt("maxHeight", this.maxHeight).intValue(); int maxHeight = conf.getInt("maxHeight", this.maxHeight).intValue();

View File

@ -27,7 +27,7 @@ public class GeneratorOreCluster extends GeneratorOreBase
this(Blocks.emerald_ore.getDefaultState(), 12, 4, 4, 32); 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); super(amountPerChunk, minHeight, maxHeight);

View File

@ -30,7 +30,7 @@ public class GeneratorOreSingle extends GeneratorOreBase
this(Blocks.emerald_ore.getDefaultState(), 12, 4, 32); 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); super(amountPerChunk, minHeight, maxHeight);

View File

@ -10,7 +10,8 @@ package biomesoplenty.common.world.feature;
import java.util.Random; 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;
import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException;
import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery;
@ -26,55 +27,49 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.world.World; 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)); private static IBlockQuery isLeavesOrAir = new BlockQueryAny(new BlockQueryMaterial(Material.leaves), new BlockQueryMaterial(Material.air));
protected int amountPerChunk;
protected IBlockQuery placeOn; protected IBlockQuery placeOn;
protected int generationAttempts; protected int generationAttempts;
protected IBlockState to; protected IBlockState to;
protected ScatterYMethod scatterYMethod;
public GeneratorSplatter() public GeneratorSplatter()
{ {
// default // 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.to = to;
this.generationAttempts = generationAttempts; this.generationAttempts = generationAttempts;
this.placeOn = placeOn; this.placeOn = placeOn;
this.scatterYMethod = scatterYMethod;
} }
@Override @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++) return this.scatterYMethod.getBlockPos(world, random, x, z);
{
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);
}
} }
@Override @Override
@ -102,7 +97,7 @@ public class GeneratorSplatter extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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.to = conf.getBlockState("to", this.to);
this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts); this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts);
String placeOnString = conf.getString("placeOn", null); String placeOnString = conf.getString("placeOn", null);
@ -115,6 +110,7 @@ public class GeneratorSplatter extends GeneratorCustomizable
conf.addMessage("placeOn", e.getMessage()); conf.addMessage("placeOn", e.getMessage());
} }
} }
this.scatterYMethod = conf.getEnum("scatterYMethod", this.scatterYMethod, ScatterYMethod.class);
} }

View File

@ -16,65 +16,55 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.World; 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.biome.GeneratorUtils.ScatterYMethod;
import biomesoplenty.common.util.block.BlockQueryUtils; import biomesoplenty.common.util.block.BlockQueryUtils;
import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException; import biomesoplenty.common.util.block.BlockQueryUtils.BlockQueryParseException;
import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery; import biomesoplenty.common.util.block.BlockQueryUtils.IBlockQuery;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorSplotches extends GeneratorCustomizable public class GeneratorSplotches extends BOPGeneratorBase
{ {
protected int amountPerChunk;
protected IBlockQuery from; protected IBlockQuery from;
protected IBlockState to; protected IBlockState to;
protected int splotchSize; protected int splotchSize;
protected ScatterYMethod scatterYMethod;
public GeneratorSplotches() public GeneratorSplotches()
{ {
// default // 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.to = to;
this.splotchSize = splotchSize; this.splotchSize = splotchSize;
this.from = from; this.from = from;
this.scatterYMethod = scatterYMethod;
} }
@Override @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++) return this.scatterYMethod.getBlockPos(world, random, x, z);
{ }
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);
}
}
@Override @Override
public boolean generate(World world, Random random, BlockPos pos) 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) 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 x0 = MathHelper.floor_double(centerX - radiusX + 0.5D);
int y0 = MathHelper.floor_double(centerY - radiusY); int y0 = MathHelper.floor_double(centerY - radiusY + 0.5D);
int z0 = MathHelper.floor_double(centerZ - radiusZ); int z0 = MathHelper.floor_double(centerZ - radiusZ + 0.5D);
int x1 = MathHelper.floor_double(centerX + radiusX); int x1 = MathHelper.floor_double(centerX + radiusX + 0.5D);
int y1 = MathHelper.floor_double(centerY + radiusY); int y1 = MathHelper.floor_double(centerY + radiusY + 0.5D);
int z1 = MathHelper.floor_double(centerZ + radiusZ); int z1 = MathHelper.floor_double(centerZ + radiusZ + 0.5D);
for (int x = x0; x <= x1; ++x) for (int x = x0; x <= x1; ++x)
{ {
@ -158,7 +148,7 @@ public class GeneratorSplotches extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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.to = conf.getBlockState("to", this.to);
this.splotchSize = conf.getInt("splotchSize", this.splotchSize); this.splotchSize = conf.getInt("splotchSize", this.splotchSize);
String fromString = conf.getString("from", null); String fromString = conf.getString("from", null);
@ -171,6 +161,7 @@ public class GeneratorSplotches extends GeneratorCustomizable
conf.addMessage("from", e.getMessage()); conf.addMessage("from", e.getMessage());
} }
} }
this.scatterYMethod = conf.getEnum("scatterYMethod", this.scatterYMethod, ScatterYMethod.class);
} }
} }

View File

@ -18,12 +18,11 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import biomesoplenty.api.biome.generation.GeneratorCustomizable; import biomesoplenty.api.biome.generation.BOPGeneratorBase;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorWaterside extends GeneratorCustomizable public class GeneratorWaterside extends BOPGeneratorBase
{ {
private int amountPerChunk;
private int maxRadius; private int maxRadius;
private IBlockState state; private IBlockState state;
private List<IBlockState> replacedStates; private List<IBlockState> replacedStates;
@ -34,29 +33,23 @@ public class GeneratorWaterside extends GeneratorCustomizable
this(4, 7, Blocks.gravel.getDefaultState()); 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.maxRadius = maxRadius;
this.state = state; this.state = state;
this.replacedStates = Arrays.asList(replacedStates); 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()); this(amountPerChunk, maxRadius, state, Blocks.grass.getDefaultState(), Blocks.dirt.getDefaultState());
} }
@Override @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++) return world.getTopSolidOrLiquidBlock(new BlockPos(x, 0, z));
{
int x = random.nextInt(16) + 8;
int z = random.nextInt(16) + 8;
generate(world, random, world.getTopSolidOrLiquidBlock(pos.add(x, 0, z)));
}
} }
@Override @Override
@ -108,7 +101,7 @@ public class GeneratorWaterside extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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.maxRadius = conf.getInt("maxRadius", this.maxRadius);
this.state = conf.getBlockState("state", this.state); this.state = conf.getBlockState("state", this.state);
this.replacedStates = conf.getBlockStateArray("replacedStates", new ArrayList(this.replacedStates) ); this.replacedStates = conf.getBlockStateArray("replacedStates", new ArrayList(this.replacedStates) );

View File

@ -22,13 +22,12 @@ import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair; 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.biome.GeneratorUtils;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
public class GeneratorBasicTree extends GeneratorCustomizable public class GeneratorBasicTree extends BOPGeneratorBase
{ {
private int amountPerChunk;
private boolean updateNeighbours; private boolean updateNeighbours;
private int minHeight; private int minHeight;
private int maxHeight; private int maxHeight;
@ -42,9 +41,9 @@ public class GeneratorBasicTree extends GeneratorCustomizable
this(1, false, 4, 7, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState()); 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; this.updateNeighbours = updateNeighbours;
Pair<Integer, Integer> heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight); Pair<Integer, Integer> heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight);
@ -56,22 +55,16 @@ public class GeneratorBasicTree extends GeneratorCustomizable
this.vine = vine; 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); this(amountPerChunk, updateNeighbours, minHeight, maxHeight, log, leaves, null);
} }
@Override @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++) // always at world surface
{ return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z);
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);
}
} }
@Override @Override
@ -304,7 +297,7 @@ public class GeneratorBasicTree extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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); this.updateNeighbours = conf.getBool("updateNeighbours", this.updateNeighbours);
int minHeight = conf.getInt("minHeight", this.minHeight); int minHeight = conf.getInt("minHeight", this.minHeight);
int maxHeight = conf.getInt("maxHeight", this.maxHeight); int maxHeight = conf.getInt("maxHeight", this.maxHeight);

View File

@ -21,7 +21,7 @@ import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.World; 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.biome.GeneratorUtils;
import biomesoplenty.common.util.config.BOPConfig.IConfigObj; 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 /*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 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.*/ 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 Random random;
private World world; private World world;
@ -47,7 +47,6 @@ public class GeneratorBigTree extends GeneratorCustomizable
private int foliageHeight = 4; private int foliageHeight = 4;
//Configurable fields //Configurable fields
private int amountPerChunk;
private boolean updateNeighbours; private boolean updateNeighbours;
private int minHeight; private int minHeight;
private int maxHeight; private int maxHeight;
@ -62,9 +61,9 @@ public class GeneratorBigTree extends GeneratorCustomizable
this(1, false, 4, 7, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState()); 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; this.updateNeighbours = updateNeighbours;
Pair<Integer, Integer> heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight); Pair<Integer, Integer> heights = GeneratorUtils.validateMinMaxHeight(minHeight, maxHeight);
@ -75,7 +74,7 @@ public class GeneratorBigTree extends GeneratorCustomizable
this.leaves = leaves; 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); this(amountPerChunk, updateNeighbours, 5, 17, log, leaves);
} }
@ -432,20 +431,13 @@ public class GeneratorBigTree extends GeneratorCustomizable
return -1; return -1;
} }
@Override @Override
public void scatter(World world, Random random, BlockPos pos) public BlockPos getScatterY(World world, Random random, int x, int z)
{ {
int successes = 0; // always at world surface
return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, 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));
if (successes < 2 && generate(world, random, genPos))
successes++;
}
} }
@Override @Override
@ -537,7 +529,7 @@ public class GeneratorBigTree extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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); this.updateNeighbours = conf.getBool("updateNeighbours", this.updateNeighbours);
int minHeight = conf.getInt("minHeight", this.minHeight); int minHeight = conf.getInt("minHeight", this.minHeight);
int maxHeight = conf.getInt("maxHeight", this.maxHeight); int maxHeight = conf.getInt("maxHeight", this.maxHeight);

View File

@ -17,12 +17,12 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.world.World; 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; 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 log;
private IBlockState leaves; private IBlockState leaves;
@ -32,24 +32,18 @@ public class GeneratorBush extends GeneratorCustomizable
this(1, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState()); 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.log = log;
this.leaves = leaves; this.leaves = leaves;
} }
@Override @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++) // always at world surface
{ return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z);
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);
}
} }
@Override @Override
@ -111,7 +105,7 @@ public class GeneratorBush extends GeneratorCustomizable
@Override @Override
public void configure(IConfigObj conf) 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.log = conf.getBlockState("logState", this.log);
this.leaves = conf.getBlockState("leavesState", this.leaves); this.leaves = conf.getBlockState("leavesState", this.leaves);
} }