Add Bayou biome, GeneratorBayouTree and some adjustments to other generators
This commit is contained in:
parent
1d7217a78d
commit
56e5fbfaa8
20 changed files with 570 additions and 44 deletions
|
@ -18,6 +18,7 @@ public class BOPBiomes
|
|||
public static Optional<BiomeGenBase> alps = Optional.absent();
|
||||
public static Optional<BiomeGenBase> arctic = Optional.absent();
|
||||
public static Optional<BiomeGenBase> bamboo_forest = Optional.absent();
|
||||
public static Optional<BiomeGenBase> bayou = Optional.absent();
|
||||
public static Optional<BiomeGenBase> crag = Optional.absent();
|
||||
public static Optional<BiomeGenBase> chaparral = Optional.absent();
|
||||
public static Optional<BiomeGenBase> denseForest = Optional.absent();
|
||||
|
|
|
@ -28,6 +28,7 @@ public class BlockQueries
|
|||
public static IBlockPosQuery hellish;
|
||||
public static IBlockPosQuery litFertile;
|
||||
public static IBlockPosQuery litBeach;
|
||||
public static IBlockPosQuery litFertileWaterside;
|
||||
public static IBlockPosQuery litSand;
|
||||
public static IBlockPosQuery litDry;
|
||||
public static IBlockPosQuery litFertileOrDry;
|
||||
|
@ -35,5 +36,6 @@ public class BlockQueries
|
|||
public static IBlockPosQuery fertileSeaBed;
|
||||
public static IBlockPosQuery underwater;
|
||||
public static IBlockPosQuery suitableForReed;
|
||||
public static IBlockPosQuery rootsCanDigThrough;
|
||||
|
||||
}
|
|
@ -29,6 +29,7 @@ import biomesoplenty.common.block.BlockBOPCoral;
|
|||
import biomesoplenty.common.enums.BOPGems;
|
||||
import biomesoplenty.common.enums.BOPPlants;
|
||||
import biomesoplenty.common.enums.BOPTrees;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod;
|
||||
import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
|
||||
import biomesoplenty.common.world.feature.GeneratorColumns;
|
||||
import biomesoplenty.common.world.feature.GeneratorDoubleFlora;
|
||||
|
@ -79,8 +80,8 @@ public class BiomeGenBambooForest extends BOPBiome
|
|||
// other plants
|
||||
this.addGenerator("leaf_piles", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(3.0F).with(BOPPlants.LEAFPILE).create());
|
||||
this.addGenerator("ferns", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(4.0F).with(BlockTallGrass.EnumType.FERN).create());
|
||||
this.addGenerator("river_cane", GeneratorStage.FLOWERS,(new GeneratorColumns.Builder()).amountPerChunk(5.0F).generationAttempts(24).placeOn(BlockQueries.litBeach).with(BlockBOPPlant.paging.getVariantState(BOPPlants.RIVERCANE)).minHeight(1).maxHeight(3).create());
|
||||
this.addGenerator("algae", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(10.0F).replace(Blocks.water).with(BOPBlocks.coral.getDefaultState().withProperty(BlockBOPCoral.VARIANT, BlockBOPCoral.CoralType.ALGAE)).generationAttempts(32).create());
|
||||
this.addGenerator("river_cane", GeneratorStage.FLOWERS,(new GeneratorColumns.Builder()).amountPerChunk(5.0F).generationAttempts(24).placeOn(BlockQueries.litFertileWaterside).with(BlockBOPPlant.paging.getVariantState(BOPPlants.RIVERCANE)).minHeight(1).maxHeight(3).create());
|
||||
this.addGenerator("algae", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(4.0F).replace(Blocks.water).with(BOPBlocks.coral.getDefaultState().withProperty(BlockBOPCoral.VARIANT, BlockBOPCoral.CoralType.ALGAE)).scatterYMethod(ScatterYMethod.AT_GROUND).create());
|
||||
this.addGenerator("bushes", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(0.5F).with(BOPPlants.BUSH).create());
|
||||
|
||||
// gem
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*******************************************************************************
|
||||
* 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.entity.monster.EntitySlime;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.BlockPos;
|
||||
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.api.block.BlockQueries;
|
||||
import biomesoplenty.common.block.BlockBOPCoral;
|
||||
import biomesoplenty.common.block.BlockBOPDoublePlant;
|
||||
import biomesoplenty.common.block.BlockBOPLilypad;
|
||||
import biomesoplenty.common.enums.BOPPlants;
|
||||
import biomesoplenty.common.enums.BOPTrees;
|
||||
import biomesoplenty.common.enums.BOPWoods;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod;
|
||||
import biomesoplenty.common.util.block.BlockQuery;
|
||||
import biomesoplenty.common.util.block.BlockQuery.IBlockPosQuery;
|
||||
import biomesoplenty.common.world.feature.GeneratorColumns;
|
||||
import biomesoplenty.common.world.feature.GeneratorDoubleFlora;
|
||||
import biomesoplenty.common.world.feature.GeneratorFlora;
|
||||
import biomesoplenty.common.world.feature.GeneratorGrass;
|
||||
import biomesoplenty.common.world.feature.GeneratorSplatter;
|
||||
import biomesoplenty.common.world.feature.GeneratorWaterside;
|
||||
import biomesoplenty.common.world.feature.tree.GeneratorBayouTree;
|
||||
|
||||
public class BiomeGenBayou extends BOPBiome
|
||||
{
|
||||
|
||||
public BiomeGenBayou()
|
||||
{
|
||||
// terrain
|
||||
this.bopMinHeight = 54;
|
||||
this.bopMaxHeight = 65;
|
||||
this.sidewaysNoiseAmount = 0.0F;
|
||||
this.setOctaveWeights(1, 1, 1, 1, 0, 0);
|
||||
|
||||
this.setColor(0x8BAF6B);
|
||||
this.setTemperatureRainfall(0.8F, 0.9F);
|
||||
this.waterColorMultiplier = 0xFFD932;
|
||||
this.skyColor = 0xACC4BC;
|
||||
this.seaFloorBlock = BOPBlocks.mud.getDefaultState();
|
||||
|
||||
this.addWeight(BiomeType.WARM, 10);
|
||||
|
||||
this.spawnableWaterCreatureList.clear();
|
||||
this.spawnableMonsterList.add(new SpawnListEntry(EntitySlime.class, 10, 1, 3));
|
||||
|
||||
// mud
|
||||
IBlockPosQuery emptyGrassOrDirt = BlockQuery.buildAnd().withAirAbove().states(this.topBlock, this.fillerBlock).create();
|
||||
this.addGenerator("mud", GeneratorStage.SAND_PASS2, (new GeneratorWaterside.Builder()).amountPerChunk(8).maxRadius(7).with(BOPBlocks.mud.getDefaultState()).create());
|
||||
this.addGenerator("mud_splatter", GeneratorStage.SAND, (new GeneratorSplatter.Builder()).amountPerChunk(4.0F).replace(emptyGrassOrDirt).with(BOPBlocks.mud.getDefaultState()).create());
|
||||
|
||||
// trees & logs
|
||||
GeneratorWeighted treeGenerator = new GeneratorWeighted(8);
|
||||
this.addGenerator("trees", GeneratorStage.TREE, treeGenerator);
|
||||
treeGenerator.add("willow", 3, (new GeneratorBayouTree.Builder()).log(BOPWoods.WILLOW).leaves(BOPTrees.WILLOW).minHeight(6).maxHeight(12).minLeavesRadius(1).leavesGradient(2).create());
|
||||
treeGenerator.add("willow_large", 1, (new GeneratorBayouTree.Builder()).log(BOPWoods.WILLOW).leaves(BOPTrees.WILLOW).minHeight(10).maxHeight(18).minLeavesRadius(2).leavesGradient(3).create());
|
||||
|
||||
// grasses
|
||||
GeneratorWeighted grassGenerator = new GeneratorWeighted(10.0F);
|
||||
this.addGenerator("grass", GeneratorStage.GRASS, grassGenerator);
|
||||
grassGenerator.add("wheatgrass", 1, (new GeneratorGrass.Builder()).with(BOPPlants.WHEATGRASS).create());
|
||||
grassGenerator.add("dampgrass", 1, (new GeneratorGrass.Builder()).with(BOPPlants.DAMPGRASS).create());
|
||||
grassGenerator.add("tallgrass", 2, (new GeneratorGrass.Builder()).with(BlockTallGrass.EnumType.GRASS).create());
|
||||
grassGenerator.add("doublegrass", 1, (new GeneratorDoubleFlora.Builder()).with(BlockDoublePlant.EnumPlantType.GRASS).create());
|
||||
|
||||
// other plants
|
||||
this.addGenerator("koru", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(0.3F).with(BOPPlants.KORU).create());
|
||||
this.addGenerator("cattail", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(3.0F).with(BOPPlants.CATTAIL).create());
|
||||
this.addGenerator("double_cattail", GeneratorStage.FLOWERS, (new GeneratorDoubleFlora.Builder()).amountPerChunk(3.0F).with(BlockBOPDoublePlant.DoublePlantType.TALL_CATTAIL).create());
|
||||
this.addGenerator("leaf_piles", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(3.0F).with(BOPPlants.LEAFPILE).create());
|
||||
this.addGenerator("sugar_cane", GeneratorStage.FLOWERS,(new GeneratorColumns.Builder()).amountPerChunk(3.0F).generationAttempts(24).placeOn(BlockQueries.litFertileWaterside).with(Blocks.reeds.getDefaultState()).minHeight(1).maxHeight(3).create());
|
||||
|
||||
// water plants
|
||||
this.addGenerator("duckweed", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(1.5F).with(BlockBOPLilypad.LilypadType.DUCKWEED).create());
|
||||
this.addGenerator("lily", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(2.5F).with(Blocks.waterlily.getDefaultState()).create());
|
||||
this.addGenerator("medium_lily", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(2.0F).with(BlockBOPLilypad.LilypadType.MEDIUM).create());
|
||||
this.addGenerator("small_lily", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(1.5F).with(BlockBOPLilypad.LilypadType.SMALL).create());
|
||||
this.addGenerator("tiny_lily", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(1.5F).with(BlockBOPLilypad.LilypadType.TINY).create());
|
||||
this.addGenerator("algae", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(4.0F).replace(Blocks.water).with(BOPBlocks.coral.getDefaultState().withProperty(BlockBOPCoral.VARIANT, BlockBOPCoral.CoralType.ALGAE)).scatterYMethod(ScatterYMethod.AT_GROUND).create());
|
||||
this.addGenerator("water_reeds", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(4.0F).with(BOPPlants.REED).generationAttempts(32).create());
|
||||
|
||||
// shrooms
|
||||
this.addGenerator("red_mushrooms", GeneratorStage.SHROOM,(new GeneratorFlora.Builder()).amountPerChunk(0.3F).with(Blocks.red_mushroom.getDefaultState()).create());
|
||||
this.addGenerator("brown_mushrooms", GeneratorStage.SHROOM,(new GeneratorFlora.Builder()).amountPerChunk(0.3F).with(Blocks.brown_mushroom.getDefaultState()).create());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGrassColorAtPos(BlockPos pos)
|
||||
{
|
||||
return 0x8BAF6B;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFoliageColorAtPos(BlockPos pos)
|
||||
{
|
||||
return 0xB0E088;
|
||||
}
|
||||
|
||||
// TODO: These 2 are copied from 1.7 - but are they used ever?
|
||||
public int getFogColour(BlockPos pos)
|
||||
{
|
||||
return 0x90AF95;
|
||||
}
|
||||
public float getFogDensity(BlockPos pos)
|
||||
{
|
||||
return 0.99F;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -54,8 +54,8 @@ public class BiomeGenGrassland extends BOPBiome {
|
|||
this.addGenerator("gravel", GeneratorStage.SAND_PASS2, (new GeneratorWaterside.Builder()).amountPerChunk(4).maxRadius(7).with(Blocks.gravel.getDefaultState()).create());
|
||||
|
||||
// other plants
|
||||
this.addGenerator("river_cane", GeneratorStage.FLOWERS,(new GeneratorColumns.Builder()).amountPerChunk(1.0F).generationAttempts(24).placeOn(BlockQueries.litBeach).with(BlockBOPPlant.paging.getVariantState(BOPPlants.RIVERCANE)).minHeight(1).maxHeight(3).create());
|
||||
this.addGenerator("sugar_cane", GeneratorStage.FLOWERS,(new GeneratorColumns.Builder()).amountPerChunk(4.0F).generationAttempts(24).placeOn(BlockQueries.litBeach).with(Blocks.reeds.getDefaultState()).minHeight(1).maxHeight(3).create());
|
||||
this.addGenerator("river_cane", GeneratorStage.FLOWERS,(new GeneratorColumns.Builder()).amountPerChunk(1.0F).generationAttempts(24).placeOn(BlockQueries.litFertileWaterside).with(BlockBOPPlant.paging.getVariantState(BOPPlants.RIVERCANE)).minHeight(1).maxHeight(3).create());
|
||||
this.addGenerator("sugar_cane", GeneratorStage.FLOWERS,(new GeneratorColumns.Builder()).amountPerChunk(4.0F).generationAttempts(24).placeOn(BlockQueries.litFertileWaterside).with(Blocks.reeds.getDefaultState()).minHeight(1).maxHeight(3).create());
|
||||
this.addGenerator("flax", GeneratorStage.FLOWERS,(new GeneratorDoubleFlora.Builder()).amountPerChunk(0.1F).with(BlockBOPDoublePlant.DoublePlantType.FLAX).generationAttempts(6).create());
|
||||
|
||||
// water plants
|
||||
|
|
|
@ -69,7 +69,7 @@ public class BiomeGenMarsh extends BOPBiome
|
|||
|
||||
// water plants
|
||||
this.addGenerator("duckweed", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(0.5F).with(BlockBOPLilypad.LilypadType.DUCKWEED).generationAttempts(32).create());
|
||||
this.addGenerator("algae", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(10.0F).replace(Blocks.water).with(BOPBlocks.coral.getDefaultState().withProperty(BlockBOPCoral.VARIANT, BlockBOPCoral.CoralType.ALGAE)).generationAttempts(32).create());
|
||||
this.addGenerator("algae", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(10.0F).replace(Blocks.water).with(BOPBlocks.coral.getDefaultState().withProperty(BlockBOPCoral.VARIANT, BlockBOPCoral.CoralType.ALGAE)).generationAttempts(32).scatterYMethod(ScatterYMethod.AT_GROUND).create());
|
||||
this.addGenerator("water_reeds", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(5.0F).with(BOPPlants.REED).generationAttempts(32).create());
|
||||
|
||||
// grasses
|
||||
|
|
|
@ -23,6 +23,7 @@ import biomesoplenty.common.block.BlockBOPCoral;
|
|||
import biomesoplenty.common.enums.BOPFlowers;
|
||||
import biomesoplenty.common.enums.BOPGems;
|
||||
import biomesoplenty.common.enums.BOPPlants;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod;
|
||||
import biomesoplenty.common.world.feature.*;
|
||||
|
||||
public class BiomeGenMoor extends BOPBiome
|
||||
|
@ -75,7 +76,7 @@ public class BiomeGenMoor extends BOPBiome
|
|||
// other plants
|
||||
this.addGenerator("koru", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(0.6F).with(BOPPlants.KORU).create());
|
||||
this.addGenerator("flax", GeneratorStage.FLOWERS,(new GeneratorDoubleFlora.Builder()).amountPerChunk(0.1F).with(BlockBOPDoublePlant.DoublePlantType.FLAX).generationAttempts(6).create());
|
||||
this.addGenerator("algae", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(10.0F).replace(Blocks.water).with(BOPBlocks.coral.getDefaultState().withProperty(BlockBOPCoral.VARIANT, BlockBOPCoral.CoralType.ALGAE)).generationAttempts(32).create());
|
||||
this.addGenerator("algae", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(5.0F).replace(Blocks.water).with(BOPBlocks.coral.getDefaultState().withProperty(BlockBOPCoral.VARIANT, BlockBOPCoral.CoralType.ALGAE)).scatterYMethod(ScatterYMethod.AT_GROUND).create());
|
||||
|
||||
// gem
|
||||
this.addGenerator("malachite", GeneratorStage.SAND, (new GeneratorOreSingle.Builder()).amountPerChunk(12).with(BOPGems.MALACHITE).create());
|
||||
|
|
|
@ -171,7 +171,7 @@ public class BlockBOPDoublePlant extends BlockBOPDoubleDecoration implements ISh
|
|||
switch (plant)
|
||||
{
|
||||
case TALL_CATTAIL:
|
||||
return BlockQueries.litBeach.matches(world, lowerPos.down());
|
||||
return BlockQueries.litFertileWaterside.matches(world, lowerPos.down());
|
||||
case EYEBULB:
|
||||
return BlockQueries.hellish.matches(world, lowerPos.down());
|
||||
case FLAX: default:
|
||||
|
|
|
@ -371,10 +371,10 @@ public class BlockBOPPlant extends BlockBOPDecoration implements IShearable
|
|||
case THORN:
|
||||
return BlockQueries.litFertileOrDry.matches(world, pos.down());
|
||||
case CATTAIL:
|
||||
return BlockQueries.litBeach.matches(world, pos.down());
|
||||
return BlockQueries.litFertileWaterside.matches(world, pos.down());
|
||||
case RIVERCANE:
|
||||
// river cane can also be placed on top of itself
|
||||
return BlockQueries.litBeach.matches(world, pos.down()) || (world.getBlockState(pos.down()) == state);
|
||||
return BlockQueries.litFertileWaterside.matches(world, pos.down()) || (world.getBlockState(pos.down()) == state);
|
||||
case WITHERWART:
|
||||
return BlockQueries.sustainsNether.matches(world, pos.down());
|
||||
case REED:
|
||||
|
|
|
@ -143,6 +143,7 @@ public class ModBiomes
|
|||
alps = registerBOPBiome(new BiomeGenAlps(), "Alps");
|
||||
arctic = registerBOPBiome(new BiomeGenArctic(), "Arctic");
|
||||
bamboo_forest = registerBOPBiome(new BiomeGenBambooForest(), "Bamboo Forest");
|
||||
bayou = registerBOPBiome(new BiomeGenBayou(), "Bayou");
|
||||
crag = registerBOPBiome(new BiomeGenCrag(), "Crag");
|
||||
chaparral = registerBOPBiome(new BiomeGenChaparral(), "Chaparral");
|
||||
denseForest = registerBOPBiome(new BiomeGenDenseForest(), "Dense Forest");
|
||||
|
|
|
@ -69,6 +69,7 @@ public class ModBlockQueries
|
|||
endish = BlockQuery.buildOr().blocks(Blocks.end_stone).states(BOPBlocks.grass.getDefaultState().withProperty(BlockBOPGrass.VARIANT, BlockBOPGrass.BOPGrassType.SPECTRAL_MOSS)).create();
|
||||
hellish = BlockQuery.buildOr().blocks(Blocks.netherrack, BOPBlocks.flesh).states(BOPBlocks.grass.getDefaultState().withProperty(BlockBOPGrass.VARIANT, BlockBOPGrass.BOPGrassType.OVERGROWN_NETHERRACK)).create();
|
||||
litBeach = BlockQuery.buildAnd().sustainsPlant(EnumPlantType.Beach).withLightAtLeast(8).create();
|
||||
litFertileWaterside = BlockQuery.buildAnd().sustainsPlant(EnumPlantType.Plains).byWater().create();
|
||||
litFertile = BlockQuery.buildAnd().sustainsPlant(EnumPlantType.Plains).withLightAtLeast(8).create();
|
||||
litSand = BlockQuery.buildAnd().materials(Material.sand).withLightAtLeast(8).create();
|
||||
litDry = BlockQuery.buildAnd().sustainsPlant(EnumPlantType.Desert).withLightAtLeast(8).create();
|
||||
|
@ -82,6 +83,7 @@ public class ModBlockQueries
|
|||
return world.getBlockState(pos).getBlock() == Blocks.water && world.getBlockState(pos.down()).getBlock() != Blocks.water;
|
||||
}
|
||||
}).withLightAtLeast(8).create();
|
||||
rootsCanDigThrough = new BlockQueryMaterial(Material.air, Material.water, Material.ground, Material.grass, Material.sand, Material.clay);
|
||||
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ public class ModGenerators
|
|||
registerGenerator("twiglet_tree", GeneratorTwigletTree.class, new GeneratorTwigletTree.Builder());
|
||||
registerGenerator("pine_tree", GeneratorPineTree.class, new GeneratorPineTree.Builder());
|
||||
registerGenerator("bulb_tree", GeneratorBulbTree.class, new GeneratorBulbTree.Builder());
|
||||
registerGenerator("bayou_tree", GeneratorBayouTree.class, new GeneratorBayouTree.Builder());
|
||||
registerGenerator("flora", GeneratorFlora.class, new GeneratorFlora.Builder());
|
||||
registerGenerator("double_flora", GeneratorDoubleFlora.class, new GeneratorDoubleFlora.Builder());
|
||||
registerGenerator("grass", GeneratorGrass.class, new GeneratorGrass.Builder());
|
||||
|
|
|
@ -80,31 +80,34 @@ public class GeneratorUtils
|
|||
|
||||
public static enum ScatterYMethod
|
||||
{
|
||||
ANYWHERE, AT_SURFACE, AT_OR_BELOW_SURFACE, BELOW_SURFACE, AT_OR_ABOVE_SURFACE, ABOVE_SURFACE;
|
||||
ANYWHERE, AT_SURFACE, AT_GROUND, BELOW_SURFACE, BELOW_GROUND, ABOVE_SURFACE, ABOVE_GROUND;
|
||||
public BlockPos getBlockPos(World world, Random random, int x, int z)
|
||||
{
|
||||
int surfaceY;
|
||||
int tempY;
|
||||
switch(this)
|
||||
{
|
||||
case AT_SURFACE:
|
||||
// always at world surface
|
||||
// always at the 'surface level' - to be precise, the air block directly above land or sea
|
||||
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 AT_GROUND:
|
||||
// always at the 'ground level' - the air or water block directly above the land, or the bottom of the sea bed
|
||||
return world.getTopSolidOrLiquidBlock(new BlockPos(x, 0, 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);
|
||||
// random point below surface (but possibly in the sea)
|
||||
tempY = world.getHeight(new BlockPos(x, 0, z)).getY();
|
||||
return new BlockPos(x, nextIntBetween(random, 1, tempY - 1), z);
|
||||
case BELOW_GROUND:
|
||||
// random point below ground (and below sea)
|
||||
tempY = world.getTopSolidOrLiquidBlock(new BlockPos(x, 0, z)).getY();
|
||||
return new BlockPos(x, nextIntBetween(random, 1, tempY - 1), 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);
|
||||
// random point above surface (amd above the sea)
|
||||
tempY = world.getHeight(new BlockPos(x, 0, z)).getY();
|
||||
return new BlockPos(x, GeneratorUtils.nextIntBetween(random, tempY, 255), z);
|
||||
case ABOVE_GROUND:
|
||||
// random point above ground (but possibly in the sea)
|
||||
tempY = world.getTopSolidOrLiquidBlock(new BlockPos(x, 0, z)).getY();
|
||||
return new BlockPos(x, GeneratorUtils.nextIntBetween(random, tempY, 255), z);
|
||||
case ANYWHERE: default:
|
||||
// random y coord
|
||||
return new BlockPos(x, nextIntBetween(random, 1, 255), z);
|
||||
|
|
|
@ -38,7 +38,7 @@ public class GeneratorBlobs extends BOPGeneratorBase
|
|||
protected float maxRadius = 5.0F;
|
||||
protected float radiusFalloff = 0.5F;
|
||||
protected int numBalls = 3;
|
||||
protected ScatterYMethod scatterYMethod = ScatterYMethod.AT_OR_BELOW_SURFACE;
|
||||
protected ScatterYMethod scatterYMethod = ScatterYMethod.BELOW_SURFACE;
|
||||
|
||||
public Builder amountPerChunk(float a) {this.amountPerChunk = a; return this;}
|
||||
public Builder placeOn(IBlockPosQuery a) {this.placeOn = a; return this;}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class GeneratorDoubleFlora extends BOPGeneratorBase
|
|||
protected IBlockPosQuery replace = new BlockQueryMaterial(Material.air);
|
||||
protected IBlockState bottomState = BOPBlocks.double_plant.getDefaultState().withProperty(BlockBOPDoublePlant.VARIANT, BlockBOPDoublePlant.DoublePlantType.FLAX).withProperty(BlockBOPDoublePlant.HALF, BlockBOPDoubleDecoration.Half.LOWER);
|
||||
protected IBlockState topState = BOPBlocks.double_plant.getDefaultState().withProperty(BlockBOPDoublePlant.VARIANT, BlockBOPDoublePlant.DoublePlantType.FLAX).withProperty(BlockBOPDoublePlant.HALF, BlockBOPDoubleDecoration.Half.UPPER);
|
||||
protected int generationAttempts = 20;
|
||||
protected int generationAttempts = 32;
|
||||
|
||||
public Builder amountPerChunk(float a) {this.amountPerChunk = a; return this;}
|
||||
public Builder replace(IBlockPosQuery a) {this.replace = a; return this;}
|
||||
|
|
|
@ -28,7 +28,7 @@ import biomesoplenty.common.block.BlockBOPPlant;
|
|||
import biomesoplenty.common.block.BlockBOPDecoration;
|
||||
import biomesoplenty.common.enums.BOPFlowers;
|
||||
import biomesoplenty.common.enums.BOPPlants;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod;
|
||||
import biomesoplenty.common.util.block.BlockQuery;
|
||||
import biomesoplenty.common.util.block.BlockQuery.*;
|
||||
import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
|
||||
|
@ -41,7 +41,8 @@ public class GeneratorFlora extends BOPGeneratorBase
|
|||
protected float amountPerChunk = 1.0F;
|
||||
protected IBlockPosQuery replace = new BlockQueryMaterial(Material.air);
|
||||
protected IBlockState with = Blocks.red_flower.getDefaultState();
|
||||
protected int generationAttempts = 20;
|
||||
protected int generationAttempts = 32;
|
||||
protected ScatterYMethod scatterYMethod = ScatterYMethod.AT_SURFACE;
|
||||
|
||||
public Builder amountPerChunk(float a) {this.amountPerChunk = a; return this;}
|
||||
public Builder replace(IBlockPosQuery a) {this.replace = a; return this;}
|
||||
|
@ -61,11 +62,13 @@ public class GeneratorFlora extends BOPGeneratorBase
|
|||
}
|
||||
public Builder with(BlockTallGrass.EnumType a) {this.with = Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, a); return this;}
|
||||
public Builder generationAttempts(int a) {this.generationAttempts = a; return this;}
|
||||
public Builder scatterYMethod(ScatterYMethod a) {this.scatterYMethod = a; return this;}
|
||||
|
||||
|
||||
@Override
|
||||
public GeneratorFlora create()
|
||||
{
|
||||
return new GeneratorFlora(this.amountPerChunk, this.replace, this.with, this.generationAttempts);
|
||||
return new GeneratorFlora(this.amountPerChunk, this.replace, this.with, this.generationAttempts, this.scatterYMethod);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,20 +76,21 @@ public class GeneratorFlora extends BOPGeneratorBase
|
|||
protected IBlockPosQuery replace;
|
||||
protected IBlockState with;
|
||||
protected int generationAttempts;
|
||||
protected ScatterYMethod scatterYMethod;
|
||||
|
||||
public GeneratorFlora(float amountPerChunk, IBlockPosQuery replace, IBlockState with, int generationAttempts)
|
||||
public GeneratorFlora(float amountPerChunk, IBlockPosQuery replace, IBlockState with, int generationAttempts, ScatterYMethod scatterYMethod)
|
||||
{
|
||||
super(amountPerChunk);
|
||||
this.replace = replace;
|
||||
this.with = with;
|
||||
this.generationAttempts = generationAttempts;
|
||||
this.scatterYMethod = scatterYMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getScatterY(World world, Random random, int x, int z)
|
||||
{
|
||||
// always at world surface
|
||||
return GeneratorUtils.ScatterYMethod.AT_SURFACE.getBlockPos(world, random, x, z);
|
||||
return this.scatterYMethod.getBlockPos(world, random, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,6 +131,8 @@ public class GeneratorFlora extends BOPGeneratorBase
|
|||
this.replace = conf.getBlockPosQuery("replace", this.replace);
|
||||
this.with = conf.getBlockState("with", this.with);
|
||||
this.generationAttempts = conf.getInt("generationAttempts", this.generationAttempts);
|
||||
this.scatterYMethod = conf.getEnum("scatterYMethod", this.scatterYMethod, ScatterYMethod.class);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import net.minecraft.block.state.IBlockState;
|
|||
import net.minecraft.init.Blocks;
|
||||
import biomesoplenty.common.block.BlockBOPPlant;
|
||||
import biomesoplenty.common.enums.BOPPlants;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils.ScatterYMethod;
|
||||
import biomesoplenty.common.util.block.BlockQuery;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryBlock;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryMaterial;
|
||||
|
@ -32,6 +33,7 @@ public class GeneratorGrass extends GeneratorFlora
|
|||
protected int generationAttempts = 96;
|
||||
protected IBlockState with = Blocks.tallgrass.getDefaultState();
|
||||
protected IBlockPosQuery replace = new BlockQueryMaterial(Material.air);
|
||||
protected ScatterYMethod scatterYMethod = ScatterYMethod.AT_SURFACE;
|
||||
|
||||
public Builder amountPerChunk(float a) {this.amountPerChunk = a; return this;}
|
||||
public Builder replace(IBlockPosQuery a) {this.replace = a; return this;}
|
||||
|
@ -42,17 +44,18 @@ public class GeneratorGrass extends GeneratorFlora
|
|||
public Builder with(BOPPlants a) {this.with = BlockBOPPlant.paging.getVariantState(a); return this;}
|
||||
public Builder with(BlockTallGrass.EnumType a) {this.with = Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, a); return this;}
|
||||
public Builder generationAttempts(int a) {this.generationAttempts = a; return this;}
|
||||
public Builder scatterYMethod(ScatterYMethod a) {this.scatterYMethod = a; return this;}
|
||||
|
||||
@Override
|
||||
public GeneratorGrass create()
|
||||
{
|
||||
return new GeneratorGrass(this.amountPerChunk, this.replace, this.with, this.generationAttempts);
|
||||
return new GeneratorGrass(this.amountPerChunk, this.replace, this.with, this.generationAttempts, this.scatterYMethod);
|
||||
}
|
||||
}
|
||||
|
||||
public GeneratorGrass(float amountPerChunk, IBlockPosQuery replace, IBlockState with, int generationAttempts)
|
||||
public GeneratorGrass(float amountPerChunk, IBlockPosQuery replace, IBlockState with, int generationAttempts, ScatterYMethod scatterYMethod)
|
||||
{
|
||||
super(amountPerChunk, replace, with, generationAttempts);
|
||||
super(amountPerChunk, replace, with, generationAttempts, scatterYMethod);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public class GeneratorSplotches extends BOPGeneratorBase
|
|||
protected IBlockPosQuery replace = new BlockQueryMaterial(Material.grass, Material.ground);
|
||||
protected IBlockState with = Blocks.cobblestone.getDefaultState();
|
||||
protected int splotchSize = 8;
|
||||
protected ScatterYMethod scatterYMethod = ScatterYMethod.AT_OR_BELOW_SURFACE;
|
||||
protected ScatterYMethod scatterYMethod = ScatterYMethod.BELOW_SURFACE;
|
||||
|
||||
public Builder amountPerChunk(float a) {this.amountPerChunk = a; return this;}
|
||||
public Builder replace(IBlockPosQuery a) {this.replace = a; return this;}
|
||||
|
|
|
@ -0,0 +1,381 @@
|
|||
/*******************************************************************************
|
||||
* 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.world.feature.tree;
|
||||
import java.util.Random;
|
||||
|
||||
import biomesoplenty.api.biome.generation.BOPGeneratorBase;
|
||||
import biomesoplenty.api.block.BlockQueries;
|
||||
import biomesoplenty.common.block.BlockBOPLeaves;
|
||||
import biomesoplenty.common.block.BlockBOPLog;
|
||||
import biomesoplenty.common.enums.BOPTrees;
|
||||
import biomesoplenty.common.enums.BOPWoods;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils;
|
||||
import biomesoplenty.common.util.block.BlockQuery;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryBlock;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryParseException;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryState;
|
||||
import biomesoplenty.common.util.block.BlockQuery.IBlockPosQuery;
|
||||
import biomesoplenty.common.util.config.BOPConfig.IConfigObj;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockNewLeaf;
|
||||
import net.minecraft.block.BlockNewLog;
|
||||
import net.minecraft.block.BlockOldLeaf;
|
||||
import net.minecraft.block.BlockOldLog;
|
||||
import net.minecraft.block.BlockPlanks;
|
||||
import net.minecraft.block.BlockVine;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class GeneratorBayouTree extends BOPGeneratorBase
|
||||
{
|
||||
|
||||
public static class Builder implements IGeneratorBuilder<GeneratorBayouTree>
|
||||
{
|
||||
protected float amountPerChunk = 1.0F;
|
||||
protected int minHeight = 8;
|
||||
protected int maxHeight = 18;
|
||||
protected int minLeavesRadius = 2;
|
||||
protected int leavesGradient = 4;
|
||||
protected int vineAttempts = 10;
|
||||
protected int maxVineLength = 20;
|
||||
protected IBlockPosQuery placeOn = BlockQueries.fertile;
|
||||
protected IBlockPosQuery replace = BlockQueries.airOrLeaves;
|
||||
protected IBlockPosQuery rootsReplace = BlockQueries.rootsCanDigThrough;
|
||||
protected IBlockState log = Blocks.log.getDefaultState();
|
||||
protected IBlockState leaves = Blocks.leaves.getDefaultState();
|
||||
protected IBlockState vine = Blocks.vine.getDefaultState();
|
||||
|
||||
public Builder amountPerChunk(float a) {this.amountPerChunk = a; return this;}
|
||||
public Builder minHeight(int a) {this.minHeight = a; return this;}
|
||||
public Builder maxHeight(int a) {this.maxHeight = a; return this;}
|
||||
public Builder minLeavesRadius(int a) {this.minLeavesRadius = a; return this;}
|
||||
public Builder leavesGradient(int a) {this.leavesGradient = a; return this;}
|
||||
public Builder vineAttempts(int a) {this.vineAttempts = a; return this;}
|
||||
public Builder maxVineLength(int a) {this.maxVineLength = a; return this;}
|
||||
public Builder placeOn(IBlockPosQuery a) {this.placeOn = a; return this;}
|
||||
public Builder placeOn(String a) throws BlockQueryParseException {this.placeOn = BlockQuery.parseQueryString(a); return this;}
|
||||
public Builder placeOn(Block a) {this.placeOn = new BlockQueryBlock(a); return this;}
|
||||
public Builder placeOn(IBlockState a) {this.placeOn = new BlockQueryState(a); return this;}
|
||||
public Builder replace(IBlockPosQuery a) {this.replace = a; return this;}
|
||||
public Builder replace(String a) throws BlockQueryParseException {this.replace = BlockQuery.parseQueryString(a); return this;}
|
||||
public Builder replace(Block a) {this.replace = new BlockQueryBlock(a); return this;}
|
||||
public Builder replace(IBlockState a) {this.replace = new BlockQueryState(a); return this;}
|
||||
public Builder rootsReplace(IBlockPosQuery a) {this.replace = a; return this;}
|
||||
public Builder rootsReplace(String a) throws BlockQueryParseException {this.replace = BlockQuery.parseQueryString(a); return this;}
|
||||
public Builder rootsReplace(Block a) {this.replace = new BlockQueryBlock(a); return this;}
|
||||
public Builder rootsReplace(IBlockState a) {this.replace = new BlockQueryState(a); return this;}
|
||||
public Builder log(IBlockState a) {this.log = a; return this;}
|
||||
public Builder log(BOPWoods a) {this.log = BlockBOPLog.paging.getVariantState(a); return this;}
|
||||
public Builder log(BlockPlanks.EnumType a)
|
||||
{
|
||||
if (a.getMetadata() < 4)
|
||||
{
|
||||
this.log = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, a);
|
||||
} else {
|
||||
this.log = Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, a);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Builder leaves(IBlockState a) {this.leaves = a; return this;}
|
||||
public Builder leaves(BOPTrees a) {this.leaves = BlockBOPLeaves.paging.getVariantState(a); return this;}
|
||||
public Builder leaves(BlockPlanks.EnumType a)
|
||||
{
|
||||
if (a.getMetadata() < 4)
|
||||
{
|
||||
this.leaves = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, a);
|
||||
} else {
|
||||
this.leaves = Blocks.leaves2.getDefaultState().withProperty(BlockNewLeaf.VARIANT, a);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Builder vine(IBlockState a)
|
||||
{
|
||||
if (a.getBlock() instanceof BlockVine)
|
||||
{
|
||||
this.vine = a;
|
||||
} else {
|
||||
throw new IllegalArgumentException("vine must use a BlockVine block");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public GeneratorBayouTree create()
|
||||
{
|
||||
return new GeneratorBayouTree(this.amountPerChunk, this.minHeight, this.maxHeight, this.minLeavesRadius, this.leavesGradient, this.vineAttempts, this.maxVineLength, this.placeOn, this.replace, this.rootsReplace, this.log, this.leaves, this.vine);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int minHeight;
|
||||
private int maxHeight;
|
||||
private int minLeavesRadius;
|
||||
private int leavesGradient;
|
||||
private int vineAttempts;
|
||||
private int maxVineLength;
|
||||
private IBlockPosQuery placeOn;
|
||||
private IBlockPosQuery replace;
|
||||
private IBlockPosQuery rootsReplace;
|
||||
private IBlockState log;
|
||||
private IBlockState leaves;
|
||||
private IBlockState vine;
|
||||
|
||||
public GeneratorBayouTree(float amountPerChunk, int minHeight, int maxHeight, int minLeavesRadius, int leavesGradient, int vineAttempts, int maxVineLength, IBlockPosQuery placeOn, IBlockPosQuery replace, IBlockPosQuery rootsReplace, IBlockState log, IBlockState leaves, IBlockState vine)
|
||||
{
|
||||
super(amountPerChunk);
|
||||
|
||||
this.minHeight = minHeight;
|
||||
this.maxHeight = maxHeight;
|
||||
this.minLeavesRadius = minLeavesRadius;
|
||||
this.leavesGradient = leavesGradient;
|
||||
this.vineAttempts = vineAttempts;
|
||||
this.maxVineLength = maxVineLength;
|
||||
this.placeOn = placeOn;
|
||||
this.replace = replace;
|
||||
this.rootsReplace = rootsReplace;
|
||||
this.log = log;
|
||||
this.leaves = leaves;
|
||||
this.vine = vine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getScatterY(World world, Random random, int x, int z)
|
||||
{
|
||||
// always at world surface
|
||||
return GeneratorUtils.ScatterYMethod.AT_GROUND.getBlockPos(world, random, x, z);
|
||||
}
|
||||
|
||||
|
||||
public boolean setLeaves(World world, BlockPos pos)
|
||||
{
|
||||
if (this.replace.matches(world, pos))
|
||||
{
|
||||
world.setBlockState(pos, this.leaves, 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setLog(World world, BlockPos pos)
|
||||
{
|
||||
if (this.replace.matches(world, pos))
|
||||
{
|
||||
world.setBlockState(pos, this.log, 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setRoot(World world, BlockPos pos)
|
||||
{
|
||||
if (this.rootsReplace.matches(world, pos))
|
||||
{
|
||||
world.setBlockState(pos, this.log, 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setVine(World world, Random rand, BlockPos pos, EnumFacing side, int length)
|
||||
{
|
||||
IBlockState vineState = this.vine.withProperty(BlockVine.NORTH, Boolean.valueOf(side == EnumFacing.NORTH)).withProperty(BlockVine.EAST, Boolean.valueOf(side == EnumFacing.EAST)).withProperty(BlockVine.SOUTH, Boolean.valueOf(side == EnumFacing.SOUTH)).withProperty(BlockVine.WEST, Boolean.valueOf(side == EnumFacing.WEST));
|
||||
boolean setOne = false;
|
||||
while (this.replace.matches(world, pos) && length > 0 && rand.nextInt(12) > 0)
|
||||
{
|
||||
world.setBlockState(pos, vineState, 2);
|
||||
setOne = true;
|
||||
length--;
|
||||
pos = pos.down();
|
||||
}
|
||||
return setOne;
|
||||
}
|
||||
|
||||
public boolean checkRootViable(World world, BlockPos pos, int rootHeight, EnumFacing direction)
|
||||
{
|
||||
// a viable root has an path which roots can dig through from trunk to some fertile ground
|
||||
pos = pos.offset(direction).up(rootHeight - 1);
|
||||
for (int i = 0; i < rootHeight; i++)
|
||||
{
|
||||
if (!this.rootsReplace.matches(world, pos)) {return false;}
|
||||
pos = pos.down();
|
||||
if (this.placeOn.matches(world, pos)) {return true;}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkSpace(World world, BlockPos pos, int rootHeight, int middleHeight, int height)
|
||||
{
|
||||
|
||||
// we want at least 2 of the roots to be viable
|
||||
int rootsOk = 0;
|
||||
for (EnumFacing direction : EnumFacing.Plane.HORIZONTAL)
|
||||
{
|
||||
if (this.checkRootViable(world, pos, rootHeight, direction)) {rootsOk++;}
|
||||
}
|
||||
if (rootsOk < 2) {return false;}
|
||||
|
||||
// check there's some space for the trunk and leaves too
|
||||
for (int y = rootHeight; y <= height; y++)
|
||||
{
|
||||
// require 1x1 for the trunk, 3x3 for the leaves
|
||||
int radius = (y <= (rootHeight + middleHeight) ? 0 : 1);
|
||||
for (int x = -radius; x <= radius; x++)
|
||||
{
|
||||
for (int z = -radius; z <= radius; z++)
|
||||
{
|
||||
BlockPos pos1 = pos.add(x, y, z);
|
||||
// note, there may be a sapling on the first layer - make sure this.replace matches it!
|
||||
if (pos1.getY() >= 255 || !this.replace.matches(world, pos1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void generateTop(World world, Random random, BlockPos pos, int topHeight)
|
||||
{
|
||||
|
||||
for (int y = 0; y < topHeight; y++)
|
||||
{
|
||||
int radius = Math.min(3, this.minLeavesRadius + (topHeight - y) / this.leavesGradient);
|
||||
|
||||
for (int x = -radius; x <= radius; ++x)
|
||||
{
|
||||
for (int z = -radius; z <= radius; ++z)
|
||||
{
|
||||
// too far away and the leaves will decay
|
||||
int dist = Math.abs(x) + Math.abs(z);
|
||||
if (dist < 4 || (dist == 4 && random.nextInt(2) == 0))
|
||||
{
|
||||
this.setLeaves(world, pos.add(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (y < topHeight - 1)
|
||||
{
|
||||
// add the trunk in the middle
|
||||
this.setLog(world, pos.add(0, y, 0));
|
||||
} else {
|
||||
// add leaves on top for certain
|
||||
this.setLeaves(world, pos.add(0, y, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateRoots(World world, Random random, BlockPos pos, int rootHeight)
|
||||
{
|
||||
for (int i = 0; i < rootHeight; i++)
|
||||
{
|
||||
this.setRoot(world, pos.north());
|
||||
this.setRoot(world, pos.east());
|
||||
this.setRoot(world, pos.south());
|
||||
this.setRoot(world, pos.west());
|
||||
pos = pos.up();
|
||||
}
|
||||
this.setRoot(world, pos.down());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(World world, Random random, BlockPos startPos)
|
||||
{
|
||||
|
||||
if (!this.placeOn.matches(world, startPos.down()))
|
||||
{
|
||||
// Abandon if we can't place the tree on this block
|
||||
return false;
|
||||
}
|
||||
|
||||
// Choose heights
|
||||
int height = GeneratorUtils.nextIntBetween(random, this.minHeight, this.maxHeight);
|
||||
|
||||
int topHeight = Math.min(6, GeneratorUtils.nextIntBetween(random, height / 5, height / 3));
|
||||
int rootHeight = Math.min(5, GeneratorUtils.nextIntBetween(random, height / 4, height / 2));
|
||||
int middleHeight = height - topHeight - rootHeight;
|
||||
if (middleHeight < 1) {return false;}
|
||||
|
||||
// Start in the ground block
|
||||
BlockPos pos = startPos.down();
|
||||
|
||||
if (!this.checkSpace(world, pos, rootHeight, middleHeight, height))
|
||||
{
|
||||
// Abandon if there isn't enough room
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate roots
|
||||
this.generateRoots(world, random, pos, rootHeight);
|
||||
pos = pos.up(rootHeight);
|
||||
|
||||
// Generate middle of tree (trunk only)
|
||||
for(int i = 0; i < middleHeight; i++)
|
||||
{
|
||||
this.setLog(world, pos);
|
||||
pos = pos.up();
|
||||
}
|
||||
|
||||
// Generate the top of the tree
|
||||
this.generateTop(world, random, pos, topHeight);
|
||||
|
||||
// Add vines
|
||||
int maxLeavesRadius = this.minLeavesRadius + topHeight / this.leavesGradient;
|
||||
this.addVines(world, random, startPos, height, maxLeavesRadius, this.vineAttempts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void addVines(World world, Random rand, BlockPos startPos, int height, int leavesRadius, int generationAttempts)
|
||||
{
|
||||
for (int i = 0; i < generationAttempts; i++)
|
||||
{
|
||||
// choose a random direction
|
||||
EnumFacing direction = EnumFacing.Plane.HORIZONTAL.random(rand);
|
||||
EnumFacing back = direction.getOpposite();
|
||||
EnumFacing sideways = direction.rotateY();
|
||||
|
||||
// choose a random starting point somewhere just outside the boundary of the tree
|
||||
BlockPos pos = startPos.up(GeneratorUtils.nextIntBetween(rand, 2, height)).offset(direction, leavesRadius + 1).offset(sideways, GeneratorUtils.nextIntBetween(rand, -leavesRadius, leavesRadius));
|
||||
|
||||
// move back towards the center until we meet a leaf or log, then stick a vine on it
|
||||
IBlockState state;
|
||||
for (int l = 0; l < leavesRadius; l++)
|
||||
{
|
||||
state = world.getBlockState(pos.offset(back, 1 + l));
|
||||
if (state == this.leaves || state == this.log) {
|
||||
this.setVine(world, rand, pos.offset(back, l), back, this.maxVineLength);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void configure(IConfigObj conf)
|
||||
{
|
||||
this.amountPerChunk = conf.getFloat("amountPerChunk", this.amountPerChunk);
|
||||
this.minHeight = conf.getInt("minHeight", this.minHeight);
|
||||
this.minLeavesRadius = conf.getInt("minLeavesRadius", this.minLeavesRadius);
|
||||
this.leavesGradient = conf.getInt("leavesGradient", this.leavesGradient);
|
||||
this.vineAttempts = conf.getInt("vineAttempts", this.vineAttempts);
|
||||
this.maxVineLength = conf.getInt("maxVineLength", this.maxVineLength);
|
||||
this.placeOn = conf.getBlockPosQuery("placeOn", this.placeOn);
|
||||
this.replace = conf.getBlockPosQuery("replace", this.replace);
|
||||
this.rootsReplace = conf.getBlockPosQuery("rootsReplace", this.rootsReplace);
|
||||
this.log = conf.getBlockState("logState", this.log);
|
||||
this.leaves = conf.getBlockState("leavesState", this.leaves);
|
||||
this.vine = conf.getBlockState("vinesState", this.vine);
|
||||
}
|
||||
}
|
|
@ -10,15 +10,14 @@ package biomesoplenty.common.world.feature.tree;
|
|||
import java.util.Random;
|
||||
|
||||
import biomesoplenty.api.biome.generation.BOPGeneratorBase;
|
||||
import biomesoplenty.api.block.BlockQueries;
|
||||
import biomesoplenty.common.block.BlockBOPLeaves;
|
||||
import biomesoplenty.common.block.BlockBOPLog;
|
||||
import biomesoplenty.common.enums.BOPTrees;
|
||||
import biomesoplenty.common.enums.BOPWoods;
|
||||
import biomesoplenty.common.util.biome.GeneratorUtils;
|
||||
import biomesoplenty.common.util.block.BlockQuery;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockPosQueryOr;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryBlock;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryMaterial;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryParseException;
|
||||
import biomesoplenty.common.util.block.BlockQuery.BlockQueryState;
|
||||
import biomesoplenty.common.util.block.BlockQuery.IBlockPosQuery;
|
||||
|
@ -31,7 +30,6 @@ import net.minecraft.block.BlockOldLeaf;
|
|||
import net.minecraft.block.BlockOldLog;
|
||||
import net.minecraft.block.BlockPlanks;
|
||||
import net.minecraft.block.BlockVine;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.BlockPos;
|
||||
|
@ -46,8 +44,8 @@ public class GeneratorBulbTree extends BOPGeneratorBase
|
|||
protected float amountPerChunk = 1.0F;
|
||||
protected int minHeight = 6;
|
||||
protected int maxHeight = 12;
|
||||
protected IBlockPosQuery placeOn = new BlockPosQueryOr(new BlockQueryMaterial(Material.ground), new BlockQueryMaterial(Material.grass));
|
||||
protected IBlockPosQuery replace = new BlockPosQueryOr(new BlockQueryMaterial(Material.air), new BlockQueryMaterial(Material.leaves), new BlockQueryMaterial(Material.plants));
|
||||
protected IBlockPosQuery placeOn = BlockQueries.fertile;
|
||||
protected IBlockPosQuery replace = BlockQueries.airOrLeaves;
|
||||
protected IBlockState log = Blocks.log.getDefaultState();
|
||||
protected IBlockState leaves = Blocks.leaves.getDefaultState();
|
||||
protected IBlockState vine = Blocks.vine.getDefaultState();
|
||||
|
|
Loading…
Reference in a new issue