From 2de681996df26cb4d0f3a7e1dfce16366821d687 Mon Sep 17 00:00:00 2001 From: Adubbz Date: Thu, 15 May 2014 21:46:37 +1000 Subject: [PATCH] Completed Nether biomes. Closes #221 --- .../biomes/nether/BiomeGenBoneyard.java | 2 +- .../biomes/nether/BiomeGenCorruptedSands.java | 2 +- .../nether/BiomeGenPhantasmagoricInferno.java | 2 +- .../biomes/nether/BiomeGenUndergarden.java | 19 +- .../biomes/nether/BiomeGenVisceralHeap.java | 2 +- .../common/world/ChunkProviderBOPHell.java | 24 ++ .../world/decoration/BOPWorldFeatures.java | 2 + .../features/WorldGenBOPBigMushroom.java | 230 ++++++++++++++++++ .../world/features/nether/WorldGenGrave.java | 69 ++++++ .../features/trees/WorldGenMiniShrub.java | 6 +- .../nether/ForcedDecoratorHell.java | 2 +- .../generation/WorldGenFieldAssociation.java | 4 + 12 files changed, 351 insertions(+), 13 deletions(-) create mode 100644 src/main/java/biomesoplenty/common/world/features/WorldGenBOPBigMushroom.java create mode 100644 src/main/java/biomesoplenty/common/world/features/nether/WorldGenGrave.java diff --git a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenBoneyard.java b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenBoneyard.java index a6d9b2283..e5d4d3a50 100644 --- a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenBoneyard.java +++ b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenBoneyard.java @@ -17,7 +17,7 @@ public class BiomeGenBoneyard extends BOPNetherBiome this.bopWorldFeatures.setFeature("boneSpinesUpPerChunk", 9); this.bopWorldFeatures.setFeature("boneSpinesDownPerChunk", 12); - //customBiomeDecorator.gravesPerChunk = 1; + this.bopWorldFeatures.setFeature("gravesPerChunk", 1); this.bopWorldFeatures.setFeature("waspHivesPerChunk", 1); } } diff --git a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenCorruptedSands.java b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenCorruptedSands.java index 7386b3b1a..b08c8398d 100644 --- a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenCorruptedSands.java +++ b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenCorruptedSands.java @@ -16,7 +16,7 @@ public class BiomeGenCorruptedSands extends BOPNetherBiome this.fillerBlock = Blocks.soul_sand; this.bopWorldFeatures.setFeature("thornsPerChunk", 10); - //customBiomeDecorator.gravesPerChunk = 1; + this.bopWorldFeatures.setFeature("gravesPerChunk", 1); this.bopWorldFeatures.setFeature("waspHivesPerChunk", 1); } } diff --git a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenPhantasmagoricInferno.java b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenPhantasmagoricInferno.java index 1792e883c..c2ea6e70f 100644 --- a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenPhantasmagoricInferno.java +++ b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenPhantasmagoricInferno.java @@ -18,7 +18,7 @@ public class BiomeGenPhantasmagoricInferno extends BOPNetherBiome this.bopWorldFeatures.setFeature("netherLavaLakesPerChunk", 20); this.bopWorldFeatures.setFeature("smolderingGrassPerChunk", 8); - //customBiomeDecorator.gravesPerChunk = 1; + this.bopWorldFeatures.setFeature("gravesPerChunk", 1); this.bopWorldFeatures.setFeature("waspHivesPerChunk", 1); this.bopWorldFeatures.setFeature("generateAsh", true); diff --git a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenUndergarden.java b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenUndergarden.java index 1aba25516..b65c6ac2b 100644 --- a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenUndergarden.java +++ b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenUndergarden.java @@ -1,9 +1,15 @@ package biomesoplenty.common.biomes.nether; +import java.util.Random; + import net.minecraft.init.Blocks; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; import biomesoplenty.api.BOPBlockHelper; import biomesoplenty.common.biomes.BOPNetherBiome; import biomesoplenty.common.world.features.WorldGenBOPTallGrass; +import biomesoplenty.common.world.features.trees.WorldGenBrush1; +import biomesoplenty.common.world.features.trees.WorldGenBrush2; +import biomesoplenty.common.world.features.trees.WorldGenMiniShrub; public class BiomeGenUndergarden extends BOPNetherBiome { @@ -16,12 +22,12 @@ public class BiomeGenUndergarden extends BOPNetherBiome this.topBlock = BOPBlockHelper.get("overgrownNetherrack"); this.fillerBlock = Blocks.netherrack; - this.theBiomeDecorator.mushroomsPerChunk = 60; - this.theBiomeDecorator.bigMushroomsPerChunk = 30; + this.theBiomeDecorator.treesPerChunk = 10; this.bopWorldFeatures.setFeature("netherVinesPerChunk", 20); this.bopWorldFeatures.setFeature("netherrackSplatterPerChunk", 45); - //customBiomeDecorator.gravesPerChunk = 1; + this.bopWorldFeatures.setFeature("bopBigMushroomsPerChunk", 30); + this.bopWorldFeatures.setFeature("gravesPerChunk", 1); this.bopWorldFeatures.setFeature("waspHivesPerChunk", 1); this.bopWorldFeatures.setFeature("toadstoolsPerChunk", 3); this.bopWorldFeatures.setFeature("glowshroomsPerChunk", 1); @@ -35,4 +41,11 @@ public class BiomeGenUndergarden extends BOPNetherBiome this.bopWorldFeatures.weightedGrassGen.put(new WorldGenBOPTallGrass(BOPBlockHelper.get("foliage"), 10), 0.5D); this.bopWorldFeatures.weightedGrassGen.put(new WorldGenBOPTallGrass(BOPBlockHelper.get("foliage"), 11), 0.5D); } + + @Override + //TODO: getRandomWorldGenForTrees() + public WorldGenAbstractTree func_150567_a(Random random) + { + return new WorldGenMiniShrub(BOPBlockHelper.get("logs4"), BOPBlockHelper.get("leaves4"), 1, 0, BOPBlockHelper.get("overgrownNetherrack")); + } } diff --git a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenVisceralHeap.java b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenVisceralHeap.java index ac6c522e6..e4a1f2e0f 100644 --- a/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenVisceralHeap.java +++ b/src/main/java/biomesoplenty/common/biomes/nether/BiomeGenVisceralHeap.java @@ -14,7 +14,7 @@ public class BiomeGenVisceralHeap extends BOPNetherBiome this.topBlock = BOPBlockHelper.get("flesh"); this.fillerBlock = BOPBlockHelper.get("flesh"); - //customBiomeDecorator.gravesPerChunk = 1; + this.bopWorldFeatures.setFeature("gravesPerChunk", 1); this.bopWorldFeatures.setFeature("waspHivesPerChunk", 1); } } diff --git a/src/main/java/biomesoplenty/common/world/ChunkProviderBOPHell.java b/src/main/java/biomesoplenty/common/world/ChunkProviderBOPHell.java index 1d8a5471d..29da7f50e 100644 --- a/src/main/java/biomesoplenty/common/world/ChunkProviderBOPHell.java +++ b/src/main/java/biomesoplenty/common/world/ChunkProviderBOPHell.java @@ -1,6 +1,7 @@ package biomesoplenty.common.world; import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE; import static net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_BRIDGE; import static net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_CAVE; import static net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.FIRE; @@ -23,6 +24,8 @@ import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.MapGenBase; import net.minecraft.world.gen.MapGenCavesHell; import net.minecraft.world.gen.NoiseGeneratorOctaves; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; +import net.minecraft.world.gen.feature.WorldGenBigMushroom; import net.minecraft.world.gen.feature.WorldGenFire; import net.minecraft.world.gen.feature.WorldGenFlowers; import net.minecraft.world.gen.feature.WorldGenGlowStone1; @@ -563,6 +566,27 @@ public class ChunkProviderBOPHell implements IChunkProvider (new WorldGenHellLava(Blocks.flowing_lava, true)).generate(worldObj, hellRNG, l1, i2, j2); } + i1 = var6.theBiomeDecorator.treesPerChunk; + + if (this.hellRNG.nextInt(10) == 0) + { + ++i1; + } + + for (j1 = 0; j1 < i1; ++j1) + { + k1 = k + this.hellRNG.nextInt(16) + 8; + l1 = l + this.hellRNG.nextInt(16) + 8; + i2 = this.hellRNG.nextInt(128); + WorldGenAbstractTree worldgenabstracttree = var6.func_150567_a(this.hellRNG); + worldgenabstracttree.setScale(1.0D, 1.0D, 1.0D); + + if (worldgenabstracttree.generate(this.worldObj, this.hellRNG, k1, i2, l1)) + { + worldgenabstracttree.func_150524_b(this.worldObj, this.hellRNG, k1, i2, l1); + } + } + MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(worldObj, hellRNG, k, l)); //var6.decorate(worldObj, hellRNG, k, l); diff --git a/src/main/java/biomesoplenty/common/world/decoration/BOPWorldFeatures.java b/src/main/java/biomesoplenty/common/world/decoration/BOPWorldFeatures.java index da17d3a8b..87c482035 100644 --- a/src/main/java/biomesoplenty/common/world/decoration/BOPWorldFeatures.java +++ b/src/main/java/biomesoplenty/common/world/decoration/BOPWorldFeatures.java @@ -88,6 +88,7 @@ public class BOPWorldFeatures addFeature("dirtSplatterPerChunk", 0); addFeature("sandstoneSpikesPerChunk", 0); addFeature("glowshroomsPerChunk", 0); + addFeature("bopBigMushroomsPerChunk", 0); //Nether Features addFeature("waspHivesPerChunk", 0); @@ -96,6 +97,7 @@ public class BOPWorldFeatures addFeature("netherLavaLakesPerChunk", 0); addFeature("netherVinesPerChunk", 0); addFeature("netherrackSplatterPerChunk", 0); + addFeature("gravesPerChunk", 0); addFeature("bopFlowersPerChunk", 0); addFeature("bopGrassPerChunk", 0); diff --git a/src/main/java/biomesoplenty/common/world/features/WorldGenBOPBigMushroom.java b/src/main/java/biomesoplenty/common/world/features/WorldGenBOPBigMushroom.java new file mode 100644 index 000000000..61f3bba0b --- /dev/null +++ b/src/main/java/biomesoplenty/common/world/features/WorldGenBOPBigMushroom.java @@ -0,0 +1,230 @@ +package biomesoplenty.common.world.features; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import biomesoplenty.common.world.decoration.BOPDecorationManager; +import biomesoplenty.common.world.generation.WorldGeneratorBOP; +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +public class WorldGenBOPBigMushroom extends WorldGeneratorBOP +{ + private List soilBlocks; + + /** The mushroom type. 0 for brown, 1 for red. */ + private int mushroomType = -1; + + public WorldGenBOPBigMushroom(Block... soilBlocks) + { + super(false); + + this.soilBlocks = Arrays.asList(soilBlocks); + } + + @Override + public boolean generate(World world, Random random, int x, int y, int z) + { + int mushroomType = random.nextInt(2); + + if (this.mushroomType >= 0) + { + mushroomType = this.mushroomType; + } + + int height = random.nextInt(3) + 4; + boolean flag = true; + + if (y >= 1 && y + height + 1 < 256) + { + int k1; + int l1; + + for (int yItr = y; yItr <= y + 1 + height; ++yItr) + { + byte radius = 3; + + if (yItr <= y + 3) + { + radius = 0; + } + + for (k1 = x - radius; k1 <= x + radius && flag; ++k1) + { + for (l1 = z - radius; l1 <= z + radius && flag; ++l1) + { + if (yItr >= 0 && yItr < 256) + { + Block block = world.getBlock(k1, yItr, l1); + + if (!block.isAir(world, k1, yItr, l1) && !block.isLeaves(world, k1, yItr, l1)) + { + flag = false; + } + } + else + { + flag = false; + } + } + } + } + + if (!flag) + { + return false; + } + else + { + Block soilBlock = world.getBlock(x, y - 1, z); + + if (!soilBlocks.contains(soilBlock)) + { + return false; + } + else + { + int topY = y + height; + + if (mushroomType == 1) + { + topY = y + height - 3; + } + + for (k1 = topY; k1 <= y + height; ++k1) + { + l1 = 1; + + if (k1 < y + height) + { + ++l1; + } + + if (mushroomType == 0) + { + l1 = 3; + } + + for (int l2 = x - l1; l2 <= x + l1; ++l2) + { + for (int i2 = z - l1; i2 <= z + l1; ++i2) + { + int j2 = 5; + + if (l2 == x - l1) + { + --j2; + } + + if (l2 == x + l1) + { + ++j2; + } + + if (i2 == z - l1) + { + j2 -= 3; + } + + if (i2 == z + l1) + { + j2 += 3; + } + + if (mushroomType == 0 || k1 < y + height) + { + if ((l2 == x - l1 || l2 == x + l1) && (i2 == z - l1 || i2 == z + l1)) + { + continue; + } + + if (l2 == x - (l1 - 1) && i2 == z - l1) + { + j2 = 1; + } + + if (l2 == x - l1 && i2 == z - (l1 - 1)) + { + j2 = 1; + } + + if (l2 == x + (l1 - 1) && i2 == z - l1) + { + j2 = 3; + } + + if (l2 == x + l1 && i2 == z - (l1 - 1)) + { + j2 = 3; + } + + if (l2 == x - (l1 - 1) && i2 == z + l1) + { + j2 = 7; + } + + if (l2 == x - l1 && i2 == z + (l1 - 1)) + { + j2 = 7; + } + + if (l2 == x + (l1 - 1) && i2 == z + l1) + { + j2 = 9; + } + + if (l2 == x + l1 && i2 == z + (l1 - 1)) + { + j2 = 9; + } + } + + if (j2 == 5 && k1 < y + height) + { + j2 = 0; + } + + if ((j2 != 0 || y >= y + height - 1) && world.getBlock(l2, k1, i2).canBeReplacedByLeaves(world, l2, k1, i2)) + { + this.setBlockAndNotifyAdequately(world, l2, k1, i2, Block.getBlockById(Block.getIdFromBlock(Blocks.brown_mushroom_block) + mushroomType), j2); + } + } + } + } + + for (k1 = 0; k1 < height; ++k1) + { + Block block2 = world.getBlock(x, y + k1, z); + + if (block2.canBeReplacedByLeaves(world, x, y + k1, z)) + { + this.setBlockAndNotifyAdequately(world, x, y + k1, z, Block.getBlockById(Block.getIdFromBlock(Blocks.brown_mushroom_block) + mushroomType), 10); + } + } + + return true; + } + } + } + else + { + return false; + } + } + + @Override + public void setupGeneration(World world, Random random, BiomeGenBase biome, String featureName, int x, int z) + { + for (int i = 0; i < (Integer)BOPDecorationManager.getBiomeFeatures(biome.biomeID).getFeature(featureName); i++) + { + int randX = x + random.nextInt(16) + 8; + int randZ = z + random.nextInt(16) + 8; + int randY = random.nextInt(256); + + this.generate(world, random, randX, randY, randZ); + } + } +} \ No newline at end of file diff --git a/src/main/java/biomesoplenty/common/world/features/nether/WorldGenGrave.java b/src/main/java/biomesoplenty/common/world/features/nether/WorldGenGrave.java new file mode 100644 index 000000000..26ee94542 --- /dev/null +++ b/src/main/java/biomesoplenty/common/world/features/nether/WorldGenGrave.java @@ -0,0 +1,69 @@ +package biomesoplenty.common.world.features.nether; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import biomesoplenty.api.BOPBlockHelper; +import biomesoplenty.common.world.decoration.BOPDecorationManager; +import biomesoplenty.common.world.generation.WorldGeneratorBOP; + +public class WorldGenGrave extends WorldGeneratorBOP +{ + @Override + public boolean generate(World world, Random random, int x, int y, int z) + { + while (world.isAirBlock(x, y, z) && y > 2) + { + --y; + } + + Block block = world.getBlock(x, y, z); + + if (block != Blocks.netherrack && block != Blocks.soul_sand) + { + return false; + } + else + { + for (int var7 = -2; var7 <= 2; ++var7) + { + for (int var8 = -2; var8 <= 2; ++var8) + { + if (world.isAirBlock(x + var7, y - 1, z + var8) && world.isAirBlock(x + var7, y - 2, z + var8) && !world.isAirBlock(x + var7, y, z + var8)) + return false; + } + } + + int orientation = random.nextInt(4); + + if (orientation == 0 || orientation == 1) + { + world.setBlock(x, y + 1, z, BOPBlockHelper.get("grave"), 0, 2); + world.setBlock(x, y + 2, z, BOPBlockHelper.get("grave"), 1, 2); + } + else + { + world.setBlock(x, y + 1, z, BOPBlockHelper.get("grave"), 2, 2); + world.setBlock(x, y + 2, z, BOPBlockHelper.get("grave"), 3, 2); + } + + return true; + } + } + + @Override + public void setupGeneration(World world, Random random, BiomeGenBase biome, String featureName, int x, int z) + { + for (int i = 0; i < (Integer)BOPDecorationManager.getBiomeFeatures(biome.biomeID).getFeature(featureName); i++) + { + int randX = x + random.nextInt(16) + 8; + int randZ = z + random.nextInt(16) + 8; + int randY = random.nextInt(256); + + this.generate(world, random, randX, randY, randZ); + } + } +} diff --git a/src/main/java/biomesoplenty/common/world/features/trees/WorldGenMiniShrub.java b/src/main/java/biomesoplenty/common/world/features/trees/WorldGenMiniShrub.java index 6114eb497..18006171b 100644 --- a/src/main/java/biomesoplenty/common/world/features/trees/WorldGenMiniShrub.java +++ b/src/main/java/biomesoplenty/common/world/features/trees/WorldGenMiniShrub.java @@ -35,13 +35,11 @@ public class WorldGenMiniShrub extends WorldGenAbstractTree @Override public boolean generate(World world, Random random, int x, int y, int z) { - //TODO: isAirBlock() while (world.isAirBlock(x, y, z) && y > 2) { --y; } - //TODO: getBlock() Block block = world.getBlock(x, y, z); if (!soilBlocks.contains(block)) @@ -54,15 +52,13 @@ public class WorldGenMiniShrub extends WorldGenAbstractTree { for (int var8 = -2; var8 <= 2; ++var8) { - //TODO: isAirBlock() isAirBlock() if (world.isAirBlock(x + var7, y - 1, z + var8) && world.isAirBlock(x + var7, y - 2, z + var8)) return false; } } - //TODO: getBlock() world.getBlock(x, y, z).onPlantGrow(world, x, y, z, x, y, z); - //TODO: setBlock() + world.setBlock(x, y + 1, z, wood, woodMeta, 2); world.setBlock(x, y + 2, z, wood, woodMeta, 2); world.setBlock(x + 1, y + 2, z, leaves, leavesMeta, 2); diff --git a/src/main/java/biomesoplenty/common/world/forceddecorators/nether/ForcedDecoratorHell.java b/src/main/java/biomesoplenty/common/world/forceddecorators/nether/ForcedDecoratorHell.java index 677baf80d..93faf2799 100644 --- a/src/main/java/biomesoplenty/common/world/forceddecorators/nether/ForcedDecoratorHell.java +++ b/src/main/java/biomesoplenty/common/world/forceddecorators/nether/ForcedDecoratorHell.java @@ -10,7 +10,7 @@ public class ForcedDecoratorHell extends ForcedDecorator { super(id); - //customBiomeDecorator.gravesPerChunk = 1; + this.bopWorldFeatures.setFeature("gravesPerChunk", 1); this.bopWorldFeatures.setFeature("waspHivesPerChunk", 1); this.bopWorldFeatures.setFeature("bopFlowersPerChunk", 4); diff --git a/src/main/java/biomesoplenty/common/world/generation/WorldGenFieldAssociation.java b/src/main/java/biomesoplenty/common/world/generation/WorldGenFieldAssociation.java index f1e865ac5..4dc6f165d 100644 --- a/src/main/java/biomesoplenty/common/world/generation/WorldGenFieldAssociation.java +++ b/src/main/java/biomesoplenty/common/world/generation/WorldGenFieldAssociation.java @@ -8,6 +8,7 @@ import net.minecraft.world.gen.feature.WorldGenLiquids; import net.minecraft.world.gen.feature.WorldGenMelon; import net.minecraft.world.gen.feature.WorldGenerator; import biomesoplenty.api.BOPBlockHelper; +import biomesoplenty.common.world.features.WorldGenBOPBigMushroom; import biomesoplenty.common.world.features.WorldGenBOPBlob; import biomesoplenty.common.world.features.WorldGenBOPCoral; import biomesoplenty.common.world.features.WorldGenBOPDoubleFlora; @@ -31,6 +32,7 @@ import biomesoplenty.common.world.features.WorldGenWaterside; import biomesoplenty.common.world.features.managers.WorldGenBOPFlowerManager; import biomesoplenty.common.world.features.managers.WorldGenBOPGrassManager; import biomesoplenty.common.world.features.nether.WorldGenBoneSpine; +import biomesoplenty.common.world.features.nether.WorldGenGrave; import biomesoplenty.common.world.features.nether.WorldGenLakesNether; import biomesoplenty.common.world.features.nether.WorldGenWaspHive; import biomesoplenty.common.world.forcedgenerators.LakesForcedGenerator; @@ -107,6 +109,7 @@ public class WorldGenFieldAssociation associateFeature("dirtSplatterPerChunk", new WorldGenSplatter(Blocks.dirt, 1, Blocks.grass)); associateFeature("sandstoneSpikesPerChunk", new WorldGenSandstoneSpike()); associateFeature("glowshroomsPerChunk", new WorldGenBOPFlora(BOPBlockHelper.get("mushrooms"), 3)); + associateFeature("bopBigMushroomsPerChunk", new WorldGenBOPBigMushroom(Blocks.dirt, Blocks.grass, Blocks.mycelium, BOPBlockHelper.get("overgrownNetherrack"))); //Nether Features associateFeature("waspHivesPerChunk", new WorldGenWaspHive()); @@ -115,6 +118,7 @@ public class WorldGenFieldAssociation associateFeature("netherLavaLakesPerChunk", new WorldGenLakesNether()); associateFeature("netherVinesPerChunk", new WorldGenLongVine(BOPBlockHelper.get("ivy"), 15, 45)); associateFeature("netherrackSplatterPerChunk", new WorldGenSplatter(Blocks.netherrack, BOPBlockHelper.get("overgrownNetherrack"))); + associateFeature("gravesPerChunk", new WorldGenGrave()); associateFeature("bopFlowersPerChunk", new WorldGenBOPFlowerManager()); associateFeature("bopGrassPerChunk", new WorldGenBOPGrassManager());