diff --git a/src/main/java/biomesoplenty/api/biome/BOPBiomes.java b/src/main/java/biomesoplenty/api/biome/BOPBiomes.java index 99de9e783..6ae82d37b 100644 --- a/src/main/java/biomesoplenty/api/biome/BOPBiomes.java +++ b/src/main/java/biomesoplenty/api/biome/BOPBiomes.java @@ -26,6 +26,7 @@ public class BOPBiomes public static Optional crag = Optional.absent(); public static Optional chaparral = Optional.absent(); public static Optional cherry_blossom_grove = Optional.absent(); + public static Optional coniferous_forest = Optional.absent(); public static Optional denseForest = Optional.absent(); public static Optional flowerField = Optional.absent(); public static Optional grassland = Optional.absent(); diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenConiferousForest.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenConiferousForest.java new file mode 100644 index 000000000..0a201762b --- /dev/null +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenConiferousForest.java @@ -0,0 +1,102 @@ +package biomesoplenty.common.biome.overworld; + +import net.minecraft.block.BlockTallGrass; +import net.minecraft.entity.passive.EntityWolf; +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.BlockBOPDirt; +import biomesoplenty.common.block.BlockBOPDoublePlant; +import biomesoplenty.common.block.BlockBOPGrass; +import biomesoplenty.common.block.BlockBOPLilypad; +import biomesoplenty.common.block.BlockBOPMushroom; +import biomesoplenty.common.enums.BOPFlowers; +import biomesoplenty.common.enums.BOPGems; +import biomesoplenty.common.enums.BOPPlants; +import biomesoplenty.common.enums.BOPTrees; +import biomesoplenty.common.enums.BOPWoods; +import biomesoplenty.common.world.BOPWorldSettings; +import biomesoplenty.common.world.feature.GeneratorDoubleFlora; +import biomesoplenty.common.world.feature.GeneratorFlora; +import biomesoplenty.common.world.feature.GeneratorGrass; +import biomesoplenty.common.world.feature.GeneratorOreSingle; +import biomesoplenty.common.world.feature.GeneratorWaterside; +import biomesoplenty.common.world.feature.tree.GeneratorTaigaTree; + +public class BiomeGenConiferousForest extends BOPBiome +{ + + public BiomeGenConiferousForest() + { + + // terrain + this.terrainSettings.avgHeight(68).heightVariation(10, 20); + + this.setColor(0x528F60); + this.setTemperatureRainfall(0.5F, 0.5F); + + this.addWeight(BiomeType.COOL, 10); + + this.topBlock = BOPBlocks.grass.getDefaultState().withProperty(BlockBOPGrass.VARIANT, BlockBOPGrass.BOPGrassType.LOAMY); + this.fillerBlock = BOPBlocks.dirt.getDefaultState().withProperty(BlockBOPDirt.VARIANT, BlockBOPDirt.BOPDirtType.LOAMY); + + this.spawnableCreatureList.add(new SpawnListEntry(EntityWolf.class, 8, 4, 4)); + + // gravel + this.addGenerator("gravel", GeneratorStage.SAND_PASS2, (new GeneratorWaterside.Builder()).amountPerChunk(4).maxRadius(7).with(Blocks.gravel.getDefaultState()).create()); + + // trees + // + GeneratorWeighted treeGenerator = new GeneratorWeighted(8.0F); + this.addGenerator("trees", GeneratorStage.TREE, treeGenerator); + treeGenerator.add("fir", 5, (new GeneratorTaigaTree.Builder()).log(BOPWoods.FIR).leaves(BOPTrees.FIR).minHeight(5).maxHeight(28).create()); + treeGenerator.add("mega_fir", 3, (new GeneratorTaigaTree.Builder()).log(BOPWoods.FIR).leaves(BOPTrees.FIR).minHeight(20).maxHeight(40).trunkWidth(2).create()); + + // other plants + this.addGenerator("shrubs", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(1.0F).with(BOPPlants.SHRUB).create()); + this.addGenerator("dead_leaf_piles", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(1.0F).with(BOPPlants.DEADLEAFPILE).create()); + this.addGenerator("leaf_piles", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(0.5F).with(BOPPlants.LEAFPILE).generationAttempts(64).create()); + this.addGenerator("flax", GeneratorStage.FLOWERS, (new GeneratorDoubleFlora.Builder()).amountPerChunk(0.2F).with(BlockBOPDoublePlant.DoublePlantType.FLAX).create()); + this.addGenerator("clover_patches", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(1.0F).with(BOPPlants.CLOVERPATCH).create()); + this.addGenerator("berry_bushes", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(0.5F).with(BOPPlants.BERRYBUSH).create()); + this.addGenerator("poison_ivy", GeneratorStage.FLOWERS,(new GeneratorFlora.Builder()).amountPerChunk(0.5F).with(BOPPlants.POISONIVY).create()); + + // shrooms + this.addGenerator("toadstools", GeneratorStage.SHROOM,(new GeneratorFlora.Builder()).amountPerChunk(0.4F).with(BlockBOPMushroom.MushroomType.TOADSTOOL).create()); + this.addGenerator("blue_milk_caps", GeneratorStage.SHROOM,(new GeneratorFlora.Builder()).amountPerChunk(0.1F).with(BlockBOPMushroom.MushroomType.BLUE_MILK_CAP).create()); + this.addGenerator("brown_mushrooms", GeneratorStage.SHROOM,(new GeneratorFlora.Builder()).amountPerChunk(0.2F).with(Blocks.brown_mushroom.getDefaultState()).create()); + this.addGenerator("red_mushrooms", GeneratorStage.SHROOM,(new GeneratorFlora.Builder()).amountPerChunk(0.1F).with(Blocks.red_mushroom.getDefaultState()).create()); + + // water plants + this.addGenerator("duckweed", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(1.0F).with(BlockBOPLilypad.LilypadType.DUCKWEED).generationAttempts(32).create()); + this.addGenerator("water_reeds", GeneratorStage.LILYPAD, (new GeneratorFlora.Builder()).amountPerChunk(0.5F).with(BOPPlants.REED).generationAttempts(32).create()); + + // flowers + GeneratorWeighted flowerGenerator = new GeneratorWeighted(0.6F); + this.addGenerator("flowers", GeneratorStage.GRASS, flowerGenerator); + flowerGenerator.add("bluebells", 1, (new GeneratorFlora.Builder().with(BOPFlowers.BLUEBELLS)).generationAttempts(128).create()); + + // grasses + GeneratorWeighted grassGenerator = new GeneratorWeighted(10.0F); + this.addGenerator("grass", GeneratorStage.GRASS, grassGenerator); + grassGenerator.add("tallgrass", 2, (new GeneratorGrass.Builder()).with(BlockTallGrass.EnumType.GRASS).generationAttempts(128).create()); + grassGenerator.add("mediumgrass", 2, (new GeneratorGrass.Builder()).with(BOPPlants.MEDIUMGRASS).generationAttempts(128).create()); + grassGenerator.add("wheatgrass", 1, (new GeneratorGrass.Builder()).with(BOPPlants.WHEATGRASS).generationAttempts(128).create()); + grassGenerator.add("dampgrass", 1, (new GeneratorGrass.Builder()).with(BOPPlants.DAMPGRASS).generationAttempts(128).create()); + grassGenerator.add("fern", 4, (new GeneratorGrass.Builder()).with(BlockTallGrass.EnumType.FERN).create()); + + // gem + this.addGenerator("amber", GeneratorStage.SAND, (new GeneratorOreSingle.Builder()).amountPerChunk(12).with(BOPGems.AMBER).create()); + + } + + @Override + public void applySettings(BOPWorldSettings settings) + { + if (!settings.generateBopGems) {this.removeGenerator("amber");} + } + +} diff --git a/src/main/java/biomesoplenty/common/init/ModBiomes.java b/src/main/java/biomesoplenty/common/init/ModBiomes.java index 311495ed7..c9143f061 100644 --- a/src/main/java/biomesoplenty/common/init/ModBiomes.java +++ b/src/main/java/biomesoplenty/common/init/ModBiomes.java @@ -151,6 +151,7 @@ public class ModBiomes crag = registerBOPBiome(new BiomeGenCrag(), "Crag"); chaparral = registerBOPBiome(new BiomeGenChaparral(), "Chaparral"); cherry_blossom_grove = registerBOPBiome(new BiomeGenCherryBlossomGrove(), "Cherry Blossom Grove"); + coniferous_forest = registerBOPBiome(new BiomeGenConiferousForest(), "Coniferous Forest"); denseForest = registerBOPBiome(new BiomeGenDenseForest(), "Dense Forest"); flowerField = registerBOPBiome(new BiomeGenFlowerField(), "Flower Field"); grassland = registerBOPBiome(new BiomeGenGrassland(), "Grassland"); diff --git a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorTaigaTree.java b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorTaigaTree.java index 7bc9a23f1..7edc659a7 100644 --- a/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorTaigaTree.java +++ b/src/main/java/biomesoplenty/common/world/feature/tree/GeneratorTaigaTree.java @@ -19,6 +19,7 @@ import net.minecraft.block.BlockPlanks; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; public class GeneratorTaigaTree extends GeneratorTreeBase @@ -26,6 +27,10 @@ public class GeneratorTaigaTree extends GeneratorTreeBase // TODO: fruit public static class Builder extends GeneratorTreeBase.InnerBuilder implements IGeneratorBuilder { + protected int trunkWidth; + + public Builder trunkWidth(int a) {this.trunkWidth = a; return this.self();} + public Builder() { this.amountPerChunk = 1.0F; @@ -35,31 +40,44 @@ public class GeneratorTaigaTree extends GeneratorTreeBase this.replace = BlockQueries.airOrLeaves; this.log = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.SPRUCE); this.leaves = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.SPRUCE); - this.vine = Blocks.vine.getDefaultState(); + this.vine = Blocks.vine.getDefaultState(); + this.trunkWidth = 1; } @Override public GeneratorTaigaTree create() { - return new GeneratorTaigaTree(this.amountPerChunk, this.placeOn, this.replace, this.log, this.leaves, this.vine, this.minHeight, this.maxHeight); + return new GeneratorTaigaTree(this.amountPerChunk, this.placeOn, this.replace, this.log, this.leaves, this.vine, this.minHeight, this.maxHeight, this.trunkWidth); } - } + } - public GeneratorTaigaTree(float amountPerChunk, IBlockPosQuery placeOn, IBlockPosQuery replace, IBlockState log, IBlockState leaves, IBlockState vine, int minHeight, int maxHeight) + private int trunkStart; + private int trunkEnd; + + public GeneratorTaigaTree(float amountPerChunk, IBlockPosQuery placeOn, IBlockPosQuery replace, IBlockState log, IBlockState leaves, IBlockState vine, int minHeight, int maxHeight, int trunkWidth) { super(amountPerChunk, placeOn, replace, log, leaves, vine, minHeight, maxHeight); + this.setTrunkWidth(trunkWidth); + } + + private void setTrunkWidth(int trunkWidth) + { + this.trunkStart = MathHelper.ceiling_double_int(0.25D - trunkWidth / 2.0D); + this.trunkEnd = MathHelper.floor_double(0.25D + trunkWidth / 2.0D); } public boolean checkSpace(World world, BlockPos pos, int baseHeight, int height) { for (int y = 0; y <= height; y++) { - // require 3x3 for the leaves, 1x1 for the trunk - int radius = (y <= baseHeight ? 0 : 1); - for (int x = -radius; x <= radius; x++) + // require 3x3 for the leaves, 1x1 for the trunk + int start = (y <= baseHeight ? this.trunkStart : this.trunkStart - 1); + int end = (y <= baseHeight ? this.trunkEnd : this.trunkEnd + 1); + + for (int x = start; x <= end; x++) { - for (int z = -radius; z <= radius; z++) + for (int z = start; z <= end; z++) { BlockPos pos1 = pos.add(x, y, z); // note, there may be a sapling on the first layer - make sure this.replace matches it! @@ -74,17 +92,21 @@ public class GeneratorTaigaTree extends GeneratorTreeBase } // generates a layer of leafs - public void generateLeafLayer(World world, Random rand, BlockPos pos, int radius) + public void generateLeafLayer(World world, Random rand, BlockPos pos, int leavesRadius) { - for (int x = -radius; x <= radius; x++) + int start = this.trunkStart - leavesRadius; + int end = this.trunkEnd + leavesRadius; + + for (int x = start; x <= end; x++) { - for (int z = -radius; z <= radius; z++) + for (int z = start; z <= end; z++) { // skip corners - if (Math.abs(x) < radius || Math.abs(z) < radius || radius == 0) - { - this.setLeaves(world, pos.add(x, 0, z)); - } + if ((leavesRadius > 0 ) && (x == start || x == end) && (z == start || z == end)) {continue;} + int distFromTrunk = (x < 0 ? this.trunkStart - x : x - this.trunkEnd) + (z < 0 ? this.trunkStart - z : z - this.trunkEnd); + + // set leaves as long as it's not too far from the trunk to survive + if (distFromTrunk <=4) {this.setLeaves(world, pos.add(x, 0, z));} } } } @@ -108,7 +130,7 @@ public class GeneratorTaigaTree extends GeneratorTreeBase int baseHeight = GeneratorUtils.nextIntBetween(random, height / 6, height / 3); int leavesHeight = height - baseHeight; if (leavesHeight < 3) {return false;} - int leavesMaxRadius = 2 + random.nextInt(2); + int leavesMaxRadius = (leavesHeight > 6 ? 3 : 2); if (!this.checkSpace(world, startPos.up(), baseHeight, height)) { @@ -119,9 +141,13 @@ public class GeneratorTaigaTree extends GeneratorTreeBase // Start at the top of the tree BlockPos pos = startPos.up(height); + // Leaves at the top + this.setLeaves(world, pos); + pos.down(); + // Add layers of leaves int localMinRadius = 0; - int radius = random.nextInt(2); + int radius = 0; int localMaxRadius = 1; for (int i = 0; i < leavesHeight; i++) { @@ -137,12 +163,16 @@ public class GeneratorTaigaTree extends GeneratorTreeBase pos = pos.down(); } - // Go back to the top of the tree and generate the trunk - pos = startPos.up(height - 1); - for(int i = 0; i < height - 1; i++) + // Generate the trunk + for (int y = 0; y < height - 1; y++) { - this.setLog(world, pos); - pos = pos.down(); + for (int x = this.trunkStart; x <= this.trunkEnd; x++) + { + for (int z = this.trunkStart; z <= this.trunkEnd; z++) + { + this.setLog(world, startPos.add(x, y, z)); + } + } } return true; @@ -160,6 +190,7 @@ public class GeneratorTaigaTree extends GeneratorTreeBase this.log = conf.getBlockState("logState", this.log); this.leaves = conf.getBlockState("leavesState", this.leaves); this.vine = conf.getBlockState("vinesState", this.vine); + this.setTrunkWidth(conf.getInt("trunkWidth", this.trunkEnd - this.trunkStart)); } } \ No newline at end of file