From 492e1e9eced8da576ca6d460c8d5ae5bb3e75c43 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 27 May 2014 20:15:58 +0200 Subject: [PATCH] Generalize biome decorator --- .../universe_factory/minecraft/test/Test.java | 47 ++- .../minecraft/test/TestBiomeDecorator.java | 229 -------------- .../minecraft/test/generic/GenericCrops.java | 5 - .../minecraft/test/generic/GenericWood.java | 7 +- .../test/generic/WorldGenGenericTrees.java | 21 +- .../test/world/ExtensibleBiomeDecorator.java | 283 ++++++++++++++++++ 6 files changed, 338 insertions(+), 254 deletions(-) delete mode 100644 java/net/universe_factory/minecraft/test/TestBiomeDecorator.java create mode 100644 java/net/universe_factory/minecraft/test/world/ExtensibleBiomeDecorator.java diff --git a/java/net/universe_factory/minecraft/test/Test.java b/java/net/universe_factory/minecraft/test/Test.java index 06de7ad..32566a9 100644 --- a/java/net/universe_factory/minecraft/test/Test.java +++ b/java/net/universe_factory/minecraft/test/Test.java @@ -1,6 +1,9 @@ package net.universe_factory.minecraft.test; +import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.Random; import net.minecraft.init.Blocks; import net.minecraft.item.Item; @@ -8,10 +11,15 @@ import net.minecraft.item.ItemFood; import net.minecraft.item.ItemSeeds; import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; +import net.minecraft.world.gen.feature.WorldGenTrees; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.terraingen.BiomeEvent.CreateDecorator; import net.universe_factory.minecraft.test.generic.GenericCrops; import net.universe_factory.minecraft.test.generic.GenericWood; +import net.universe_factory.minecraft.test.generic.WorldGenGenericTrees; +import net.universe_factory.minecraft.test.world.ExtensibleBiomeDecorator; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; @@ -59,6 +67,9 @@ public class Test { } }; + WorldGenGenericTrees cherryTreeGenerator = WorldGenGenericTrees.newInstance(false, false, cherryTree); + WorldGenGenericTrees cherryTreeGeneratorBig = WorldGenGenericTrees.newInstance(false, true, cherryTree); + public static final GenericCrops saladField = new GenericCrops() { @Override public String getName() { @@ -74,11 +85,18 @@ public class Test { public Item itemSeeds() { return saladSeeds; } + + @Override + public int getRenderType() { + return 1; + } }; public static final Item saladSeeds = new ItemSeeds(saladField, Blocks.farmland).setTextureName(MODID + ":seeds_salad") .setUnlocalizedName("seedsSalad"); public static final Item salad = new ItemFood(3, 0.8f, false).setTextureName(MODID + ":salad").setUnlocalizedName("salad"); + public static final ExtensibleBiomeDecorator biomeDecorator = new ExtensibleBiomeDecorator(); + @EventHandler public void preInit(FMLInitializationEvent event) { MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenHandler()); @@ -89,26 +107,25 @@ public class Test { GameRegistry.registerItem(saladSeeds, "seeds_salad"); GameRegistry.registerItem(salad, "salad"); GameRegistry.registerBlock(saladField, null, "salad"); + + biomeDecorator.registerTree(new ExtensibleBiomeDecorator.Tree() { + @Override + public Entry replaceTree(World world, BiomeGenBase biome, Random random, int x, int y, int z, + WorldGenAbstractTree orig) { + if (!(orig instanceof WorldGenTrees) || biome.getTempCategory() != BiomeGenBase.TempCategory.MEDIUM) + return null; + + WorldGenAbstractTree generator = (random.nextInt(3) == 0) ? cherryTreeGenerator : cherryTreeGeneratorBig; + + return new AbstractMap.SimpleEntry(generator, 0.5f); + } + }); } public class TerrainGenHandler { @SubscribeEvent public void handleCreateDecorator(CreateDecorator event) { - event.newBiomeDecorator = new TestBiomeDecorator(cherryTree); - - event.newBiomeDecorator.bigMushroomsPerChunk = event.originalBiomeDecorator.bigMushroomsPerChunk; - event.newBiomeDecorator.cactiPerChunk = event.originalBiomeDecorator.cactiPerChunk; - event.newBiomeDecorator.clayPerChunk = event.originalBiomeDecorator.clayPerChunk; - event.newBiomeDecorator.deadBushPerChunk = event.originalBiomeDecorator.deadBushPerChunk; - event.newBiomeDecorator.flowersPerChunk = event.originalBiomeDecorator.flowersPerChunk; - event.newBiomeDecorator.generateLakes = event.originalBiomeDecorator.generateLakes; - event.newBiomeDecorator.grassPerChunk = event.originalBiomeDecorator.grassPerChunk; - event.newBiomeDecorator.mushroomsPerChunk = event.originalBiomeDecorator.mushroomsPerChunk; - event.newBiomeDecorator.reedsPerChunk = event.originalBiomeDecorator.reedsPerChunk; - event.newBiomeDecorator.sandPerChunk = event.originalBiomeDecorator.sandPerChunk; - event.newBiomeDecorator.sandPerChunk2 = event.originalBiomeDecorator.sandPerChunk2; - event.newBiomeDecorator.treesPerChunk = event.originalBiomeDecorator.treesPerChunk; - event.newBiomeDecorator.waterlilyPerChunk = event.originalBiomeDecorator.waterlilyPerChunk; + event.newBiomeDecorator = biomeDecorator.getInstance(event.originalBiomeDecorator); } } } diff --git a/java/net/universe_factory/minecraft/test/TestBiomeDecorator.java b/java/net/universe_factory/minecraft/test/TestBiomeDecorator.java deleted file mode 100644 index f25e83e..0000000 --- a/java/net/universe_factory/minecraft/test/TestBiomeDecorator.java +++ /dev/null @@ -1,229 +0,0 @@ -package net.universe_factory.minecraft.test; - -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CACTUS; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CLAY; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DEAD_BUSH; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LILYPAD; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.REED; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND_PASS2; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM; -import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE; -import net.minecraft.block.BlockFlower; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.world.biome.BiomeDecorator; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.gen.feature.WorldGenAbstractTree; -import net.minecraft.world.gen.feature.WorldGenDeadBush; -import net.minecraft.world.gen.feature.WorldGenLiquids; -import net.minecraft.world.gen.feature.WorldGenPumpkin; -import net.minecraft.world.gen.feature.WorldGenTrees; -import net.minecraft.world.gen.feature.WorldGenerator; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.terraingen.DecorateBiomeEvent; -import net.minecraftforge.event.terraingen.TerrainGen; -import net.universe_factory.minecraft.test.generic.GenericWood; -import net.universe_factory.minecraft.test.generic.WorldGenGenericTrees; - -public class TestBiomeDecorator extends BiomeDecorator { - protected WorldGenGenericTrees worldGenGenericTrees; - - public TestBiomeDecorator(GenericWood genericWood) { - worldGenGenericTrees = new WorldGenGenericTrees(false, genericWood); - } - - protected void genDecorations(BiomeGenBase biome) { - MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z)); - this.generateOres(); - int i; - int j; - int k; - - boolean doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND); - for (i = 0; doGen && i < this.sandPerChunk2; ++i) { - j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - this.sandGen.generate(this.currentWorld, this.randomGenerator, j, this.currentWorld.getTopSolidOrLiquidBlock(j, k), k); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CLAY); - for (i = 0; doGen && i < this.clayPerChunk; ++i) { - j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - this.clayGen.generate(this.currentWorld, this.randomGenerator, j, this.currentWorld.getTopSolidOrLiquidBlock(j, k), k); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND_PASS2); - for (i = 0; doGen && i < this.sandPerChunk; ++i) { - j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - this.gravelAsSandGen.generate(this.currentWorld, this.randomGenerator, j, this.currentWorld.getTopSolidOrLiquidBlock(j, k), k); - } - - i = this.treesPerChunk; - - if (this.randomGenerator.nextInt(10) == 0) { - ++i; - } - - int l; - int i1; - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, TREE); - for (j = 0; doGen && j < i; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.currentWorld.getHeightValue(k, l); - WorldGenAbstractTree worldgenabstracttree = biome.func_150567_a(this.randomGenerator); - - if (worldgenabstracttree instanceof WorldGenTrees && biome.getTempCategory() == BiomeGenBase.TempCategory.MEDIUM - && this.randomGenerator.nextDouble() < 0.5f) { - worldgenabstracttree = this.worldGenGenericTrees; - } - - worldgenabstracttree.setScale(1.0D, 1.0D, 1.0D); - - if (worldgenabstracttree.generate(this.currentWorld, this.randomGenerator, k, i1, l)) { - worldgenabstracttree.func_150524_b(this.currentWorld, this.randomGenerator, k, i1, l); - } - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, BIG_SHROOM); - for (j = 0; doGen && j < this.bigMushroomsPerChunk; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - this.bigMushroomGen.generate(this.currentWorld, this.randomGenerator, k, this.currentWorld.getHeightValue(k, l), l); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, FLOWERS); - for (j = 0; doGen && j < this.flowersPerChunk; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) + 32); - String s = biome.func_150572_a(this.randomGenerator, k, i1, l); - BlockFlower blockflower = BlockFlower.func_149857_e(s); - - if (blockflower.getMaterial() != Material.air) { - this.yellowFlowerGen.func_150550_a(blockflower, BlockFlower.func_149856_f(s)); - this.yellowFlowerGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, GRASS); - for (j = 0; doGen && j < this.grassPerChunk; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); - WorldGenerator worldgenerator = biome.getRandomWorldGenForGrass(this.randomGenerator); - worldgenerator.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, DEAD_BUSH); - for (j = 0; doGen && j < this.deadBushPerChunk; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); - (new WorldGenDeadBush(Blocks.deadbush)).generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LILYPAD); - for (j = 0; doGen && j < this.waterlilyPerChunk; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - - for (i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); i1 > 0 - && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1) { - ; - } - - this.waterlilyGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SHROOM); - for (j = 0; doGen && j < this.mushroomsPerChunk; ++j) { - if (this.randomGenerator.nextInt(4) == 0) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.currentWorld.getHeightValue(k, l); - this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - - if (this.randomGenerator.nextInt(8) == 0) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); - this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - } - - if (doGen && this.randomGenerator.nextInt(4) == 0) { - j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - l = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(j, k) * 2); - this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, j, l, k); - } - - if (doGen && this.randomGenerator.nextInt(8) == 0) { - j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - l = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(j, k) * 2); - this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, j, l, k); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, REED); - for (j = 0; doGen && j < this.reedsPerChunk; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); - this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - - for (j = 0; doGen && j < 10; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); - this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, PUMPKIN); - if (doGen && this.randomGenerator.nextInt(32) == 0) { - j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - l = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(j, k) * 2); - (new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, j, l, k); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CACTUS); - for (j = 0; doGen && j < this.cactiPerChunk; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); - this.cactusGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); - } - - doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LAKE); - if (doGen && this.generateLakes) { - for (j = 0; j < 50; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.randomGenerator.nextInt(this.randomGenerator.nextInt(248) + 8); - i1 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - (new WorldGenLiquids(Blocks.flowing_water)).generate(this.currentWorld, this.randomGenerator, k, l, i1); - } - - for (j = 0; j < 20; ++j) { - k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; - l = this.randomGenerator.nextInt(this.randomGenerator.nextInt(this.randomGenerator.nextInt(240) + 8) + 8); - i1 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; - (new WorldGenLiquids(Blocks.flowing_lava)).generate(this.currentWorld, this.randomGenerator, k, l, i1); - } - } - - MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z)); - } -} diff --git a/java/net/universe_factory/minecraft/test/generic/GenericCrops.java b/java/net/universe_factory/minecraft/test/generic/GenericCrops.java index 0ed2107..384dae3 100644 --- a/java/net/universe_factory/minecraft/test/generic/GenericCrops.java +++ b/java/net/universe_factory/minecraft/test/generic/GenericCrops.java @@ -47,11 +47,6 @@ public abstract class GenericCrops extends BlockCrops { } } - @Override - public int getRenderType() { - return 1; - } - public abstract String getName(); public abstract Item itemCrops(); diff --git a/java/net/universe_factory/minecraft/test/generic/GenericWood.java b/java/net/universe_factory/minecraft/test/generic/GenericWood.java index 0bb4639..6a04729 100644 --- a/java/net/universe_factory/minecraft/test/generic/GenericWood.java +++ b/java/net/universe_factory/minecraft/test/generic/GenericWood.java @@ -229,6 +229,9 @@ public abstract class GenericWood { } private class Sapling extends BlockSapling { + WorldGenerator generator = WorldGenGenericTrees.newInstance(true, false, GenericWood.this); + WorldGenerator generatorBig = WorldGenGenericTrees.newInstance(true, true, GenericWood.this); + public Sapling() { setBlockName("sapling" + getName()); @@ -262,11 +265,11 @@ public abstract class GenericWood { if (!TerrainGen.saplingGrowTree(world, random, x, y, z)) return; - WorldGenerator generator = new WorldGenGenericTrees(true, GenericWood.this); + WorldGenerator treeGenerator = (random.nextInt(10) == 0) ? generatorBig : generator; world.setBlock(x, y, z, Blocks.air, 0, 4); - if (!generator.generate(world, random, x, y, z)) + if (!treeGenerator.generate(world, random, x, y, z)) world.setBlock(x, y, z, this, 0, 4); } } diff --git a/java/net/universe_factory/minecraft/test/generic/WorldGenGenericTrees.java b/java/net/universe_factory/minecraft/test/generic/WorldGenGenericTrees.java index e7614fa..3726ef4 100644 --- a/java/net/universe_factory/minecraft/test/generic/WorldGenGenericTrees.java +++ b/java/net/universe_factory/minecraft/test/generic/WorldGenGenericTrees.java @@ -9,18 +9,33 @@ import net.minecraftforge.common.util.ForgeDirection; public class WorldGenGenericTrees extends WorldGenAbstractTree { private final GenericWood genericWood; + private final int minHeight; + private final boolean big; - public WorldGenGenericTrees(boolean b, GenericWood genericWood) { - super(b); + public static WorldGenGenericTrees newInstance(boolean notify, boolean big, GenericWood genericWood) { + return new WorldGenGenericTrees(notify, big, genericWood, genericWood.getMinTreeHeight()); + } + + public static WorldGenGenericTrees newForestInstance(boolean notify, boolean big, GenericWood genericWood) { + return new WorldGenGenericTrees(notify, big, genericWood, 5); + } + + protected WorldGenGenericTrees(boolean notify, boolean big, GenericWood genericWood, int minHeight) { + super(notify); this.genericWood = genericWood; + this.minHeight = minHeight; + this.big = big; } @Override public boolean generate(World world, Random random, int x, int y, int z) { - int height = random.nextInt(3) + genericWood.getMinTreeHeight(); + int height = random.nextInt(3) + minHeight; boolean flag = true; + if (big) + height += random.nextInt(7); + if (y >= 1 && y + height + 1 <= 256) { byte b0; int k1; diff --git a/java/net/universe_factory/minecraft/test/world/ExtensibleBiomeDecorator.java b/java/net/universe_factory/minecraft/test/world/ExtensibleBiomeDecorator.java new file mode 100644 index 0000000..57f0a8f --- /dev/null +++ b/java/net/universe_factory/minecraft/test/world/ExtensibleBiomeDecorator.java @@ -0,0 +1,283 @@ +package net.universe_factory.minecraft.test.world; + +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CACTUS; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CLAY; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DEAD_BUSH; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LILYPAD; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.REED; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND_PASS2; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM; +import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import net.minecraft.block.BlockFlower; +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeDecorator; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; +import net.minecraft.world.gen.feature.WorldGenDeadBush; +import net.minecraft.world.gen.feature.WorldGenLiquids; +import net.minecraft.world.gen.feature.WorldGenPumpkin; +import net.minecraft.world.gen.feature.WorldGenerator; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.terraingen.DecorateBiomeEvent; +import net.minecraftforge.event.terraingen.TerrainGen; + +public class ExtensibleBiomeDecorator { + private ArrayList trees = new ArrayList(); + + public void registerTree(Tree tree) { + trees.add(tree); + } + + public BiomeDecorator getInstance(BiomeDecorator base) { + BiomeDecorator decorator = new Decorator(); + + if (base != null) { + decorator.bigMushroomsPerChunk = base.bigMushroomsPerChunk; + decorator.cactiPerChunk = base.cactiPerChunk; + decorator.clayPerChunk = base.clayPerChunk; + decorator.deadBushPerChunk = base.deadBushPerChunk; + decorator.flowersPerChunk = base.flowersPerChunk; + decorator.generateLakes = base.generateLakes; + decorator.grassPerChunk = base.grassPerChunk; + decorator.mushroomsPerChunk = base.mushroomsPerChunk; + decorator.reedsPerChunk = base.reedsPerChunk; + decorator.sandPerChunk = base.sandPerChunk; + decorator.sandPerChunk2 = base.sandPerChunk2; + decorator.treesPerChunk = base.treesPerChunk; + decorator.waterlilyPerChunk = base.waterlilyPerChunk; + } + + return decorator; + } + + public interface Tree { + public Map.Entry replaceTree(World world, BiomeGenBase biome, Random random, int x, int y, int z, + WorldGenAbstractTree orig); + } + + protected class Decorator extends BiomeDecorator { + protected void genDecorations(BiomeGenBase biome) { + MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z)); + this.generateOres(); + int i; + int j; + int k; + + boolean doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND); + for (i = 0; doGen && i < this.sandPerChunk2; ++i) { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.sandGen.generate(this.currentWorld, this.randomGenerator, j, this.currentWorld.getTopSolidOrLiquidBlock(j, k), k); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CLAY); + for (i = 0; doGen && i < this.clayPerChunk; ++i) { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.clayGen.generate(this.currentWorld, this.randomGenerator, j, this.currentWorld.getTopSolidOrLiquidBlock(j, k), k); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND_PASS2); + for (i = 0; doGen && i < this.sandPerChunk; ++i) { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.gravelAsSandGen.generate(this.currentWorld, this.randomGenerator, j, this.currentWorld.getTopSolidOrLiquidBlock(j, k), k); + } + + i = this.treesPerChunk; + + if (this.randomGenerator.nextInt(10) == 0) { + ++i; + } + + int l; + int i1; + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, TREE); + for (j = 0; doGen && j < i; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.currentWorld.getHeightValue(k, l); + + WorldGenAbstractTree defaultTreeGen = biome.func_150567_a(this.randomGenerator); + + float weight = 1.0f; + Map treeWeights = new HashMap(); + treeWeights.put(defaultTreeGen, 1.0f); + + for (Tree tree : trees) { + Map.Entry entry = tree.replaceTree(currentWorld, biome, randomGenerator, k, i1, l, + defaultTreeGen); + + if (entry != null) { + weight += entry.getValue(); + treeWeights.put(entry.getKey(), entry.getValue()); + } + } + + WorldGenAbstractTree treeGen = null; + float p = randomGenerator.nextFloat() * weight; + + for (Map.Entry entry : treeWeights.entrySet()) { + p -= entry.getValue(); + + if (p < 0) { + treeGen = entry.getKey(); + break; + } + } + + treeGen.setScale(1.0D, 1.0D, 1.0D); + + if (treeGen.generate(this.currentWorld, this.randomGenerator, k, i1, l)) + treeGen.func_150524_b(this.currentWorld, this.randomGenerator, k, i1, l); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, BIG_SHROOM); + for (j = 0; doGen && j < this.bigMushroomsPerChunk; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.bigMushroomGen.generate(this.currentWorld, this.randomGenerator, k, this.currentWorld.getHeightValue(k, l), l); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, FLOWERS); + for (j = 0; doGen && j < this.flowersPerChunk; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) + 32); + String s = biome.func_150572_a(this.randomGenerator, k, i1, l); + BlockFlower blockflower = BlockFlower.func_149857_e(s); + + if (blockflower.getMaterial() != Material.air) { + this.yellowFlowerGen.func_150550_a(blockflower, BlockFlower.func_149856_f(s)); + this.yellowFlowerGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, GRASS); + for (j = 0; doGen && j < this.grassPerChunk; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); + WorldGenerator worldgenerator = biome.getRandomWorldGenForGrass(this.randomGenerator); + worldgenerator.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, DEAD_BUSH); + for (j = 0; doGen && j < this.deadBushPerChunk; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); + (new WorldGenDeadBush(Blocks.deadbush)).generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LILYPAD); + for (j = 0; doGen && j < this.waterlilyPerChunk; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + + for (i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); i1 > 0 + && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1) { + ; + } + + this.waterlilyGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SHROOM); + for (j = 0; doGen && j < this.mushroomsPerChunk; ++j) { + if (this.randomGenerator.nextInt(4) == 0) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.currentWorld.getHeightValue(k, l); + this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + + if (this.randomGenerator.nextInt(8) == 0) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); + this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + } + + if (doGen && this.randomGenerator.nextInt(4) == 0) { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + l = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(j, k) * 2); + this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, j, l, k); + } + + if (doGen && this.randomGenerator.nextInt(8) == 0) { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + l = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(j, k) * 2); + this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, j, l, k); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, REED); + for (j = 0; doGen && j < this.reedsPerChunk; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); + this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + + for (j = 0; doGen && j < 10; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); + this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, PUMPKIN); + if (doGen && this.randomGenerator.nextInt(32) == 0) { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + l = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(j, k) * 2); + (new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, j, l, k); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CACTUS); + for (j = 0; doGen && j < this.cactiPerChunk; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + i1 = this.randomGenerator.nextInt(this.currentWorld.getHeightValue(k, l) * 2); + this.cactusGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + + doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LAKE); + if (doGen && this.generateLakes) { + for (j = 0; j < 50; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.randomGenerator.nextInt(this.randomGenerator.nextInt(248) + 8); + i1 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + (new WorldGenLiquids(Blocks.flowing_water)).generate(this.currentWorld, this.randomGenerator, k, l, i1); + } + + for (j = 0; j < 20; ++j) { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.randomGenerator.nextInt(this.randomGenerator.nextInt(this.randomGenerator.nextInt(240) + 8) + 8); + i1 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + (new WorldGenLiquids(Blocks.flowing_lava)).generate(this.currentWorld, this.randomGenerator, k, l, i1); + } + } + + MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z)); + } + } +}