001 package net.minecraft.src; 002 003 import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.*; 004 import static net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.*; 005 006 import java.util.Random; 007 008 import net.minecraftforge.common.*; 009 import net.minecraftforge.event.terraingen.*; 010 011 public class BiomeDecorator 012 { 013 /** The world the BiomeDecorator is currently decorating */ 014 public World currentWorld; 015 016 /** The Biome Decorator's random number generator. */ 017 public Random randomGenerator; 018 019 /** The X-coordinate of the chunk currently being decorated */ 020 public int chunk_X; 021 022 /** The Z-coordinate of the chunk currently being decorated */ 023 public int chunk_Z; 024 025 /** The biome generator object. */ 026 public BiomeGenBase biome; 027 028 /** The clay generator. */ 029 public WorldGenerator clayGen = new WorldGenClay(4); 030 031 /** The sand generator. */ 032 public WorldGenerator sandGen; 033 034 /** The gravel generator. */ 035 public WorldGenerator gravelAsSandGen; 036 037 /** The dirt generator. */ 038 public WorldGenerator dirtGen; 039 public WorldGenerator gravelGen; 040 public WorldGenerator coalGen; 041 public WorldGenerator ironGen; 042 043 /** Field that holds gold WorldGenMinable */ 044 public WorldGenerator goldGen; 045 046 /** Field that holds redstone WorldGenMinable */ 047 public WorldGenerator redstoneGen; 048 049 /** Field that holds diamond WorldGenMinable */ 050 public WorldGenerator diamondGen; 051 052 /** Field that holds Lapis WorldGenMinable */ 053 public WorldGenerator lapisGen; 054 055 /** Field that holds one of the plantYellow WorldGenFlowers */ 056 public WorldGenerator plantYellowGen; 057 058 /** Field that holds one of the plantRed WorldGenFlowers */ 059 public WorldGenerator plantRedGen; 060 061 /** Field that holds mushroomBrown WorldGenFlowers */ 062 public WorldGenerator mushroomBrownGen; 063 064 /** Field that holds mushroomRed WorldGenFlowers */ 065 public WorldGenerator mushroomRedGen; 066 067 /** Field that holds big mushroom generator */ 068 public WorldGenerator bigMushroomGen; 069 070 /** Field that holds WorldGenReed */ 071 public WorldGenerator reedGen; 072 073 /** Field that holds WorldGenCactus */ 074 public WorldGenerator cactusGen; 075 076 /** The water lily generation! */ 077 public WorldGenerator waterlilyGen; 078 079 /** Amount of waterlilys per chunk. */ 080 public int waterlilyPerChunk; 081 082 /** 083 * The number of trees to attempt to generate per chunk. Up to 10 in forests, none in deserts. 084 */ 085 public int treesPerChunk; 086 087 /** 088 * The number of yellow flower patches to generate per chunk. The game generates much less than this number, since 089 * it attempts to generate them at a random altitude. 090 */ 091 public int flowersPerChunk; 092 093 /** The amount of tall grass to generate per chunk. */ 094 public int grassPerChunk; 095 096 /** 097 * The number of dead bushes to generate per chunk. Used in deserts and swamps. 098 */ 099 public int deadBushPerChunk; 100 101 /** 102 * The number of extra mushroom patches per chunk. It generates 1/4 this number in brown mushroom patches, and 1/8 103 * this number in red mushroom patches. These mushrooms go beyond the default base number of mushrooms. 104 */ 105 public int mushroomsPerChunk; 106 107 /** 108 * The number of reeds to generate per chunk. Reeds won't generate if the randomly selected placement is unsuitable. 109 */ 110 public int reedsPerChunk; 111 112 /** 113 * The number of cactus plants to generate per chunk. Cacti only work on sand. 114 */ 115 public int cactiPerChunk; 116 117 /** 118 * The number of sand patches to generate per chunk. Sand patches only generate when part of it is underwater. 119 */ 120 public int sandPerChunk; 121 122 /** 123 * The number of sand patches to generate per chunk. Sand patches only generate when part of it is underwater. There 124 * appear to be two separate fields for this. 125 */ 126 public int sandPerChunk2; 127 128 /** 129 * The number of clay patches to generate per chunk. Only generates when part of it is underwater. 130 */ 131 public int clayPerChunk; 132 133 /** Amount of big mushrooms per chunk */ 134 public int bigMushroomsPerChunk; 135 136 /** True if decorator should generate surface lava & water */ 137 public boolean generateLakes; 138 139 public BiomeDecorator(BiomeGenBase par1BiomeGenBase) 140 { 141 this.sandGen = new WorldGenSand(7, Block.sand.blockID); 142 this.gravelAsSandGen = new WorldGenSand(6, Block.gravel.blockID); 143 this.dirtGen = new WorldGenMinable(Block.dirt.blockID, 32); 144 this.gravelGen = new WorldGenMinable(Block.gravel.blockID, 32); 145 this.coalGen = new WorldGenMinable(Block.oreCoal.blockID, 16); 146 this.ironGen = new WorldGenMinable(Block.oreIron.blockID, 8); 147 this.goldGen = new WorldGenMinable(Block.oreGold.blockID, 8); 148 this.redstoneGen = new WorldGenMinable(Block.oreRedstone.blockID, 7); 149 this.diamondGen = new WorldGenMinable(Block.oreDiamond.blockID, 7); 150 this.lapisGen = new WorldGenMinable(Block.oreLapis.blockID, 6); 151 this.plantYellowGen = new WorldGenFlowers(Block.plantYellow.blockID); 152 this.plantRedGen = new WorldGenFlowers(Block.plantRed.blockID); 153 this.mushroomBrownGen = new WorldGenFlowers(Block.mushroomBrown.blockID); 154 this.mushroomRedGen = new WorldGenFlowers(Block.mushroomRed.blockID); 155 this.bigMushroomGen = new WorldGenBigMushroom(); 156 this.reedGen = new WorldGenReed(); 157 this.cactusGen = new WorldGenCactus(); 158 this.waterlilyGen = new WorldGenWaterlily(); 159 this.waterlilyPerChunk = 0; 160 this.treesPerChunk = 0; 161 this.flowersPerChunk = 2; 162 this.grassPerChunk = 1; 163 this.deadBushPerChunk = 0; 164 this.mushroomsPerChunk = 0; 165 this.reedsPerChunk = 0; 166 this.cactiPerChunk = 0; 167 this.sandPerChunk = 1; 168 this.sandPerChunk2 = 3; 169 this.clayPerChunk = 1; 170 this.bigMushroomsPerChunk = 0; 171 this.generateLakes = true; 172 this.biome = par1BiomeGenBase; 173 } 174 175 /** 176 * Decorates the world. Calls code that was formerly (pre-1.8) in ChunkProviderGenerate.populate 177 */ 178 public void decorate(World par1World, Random par2Random, int par3, int par4) 179 { 180 if (this.currentWorld != null) 181 { 182 throw new RuntimeException("Already decorating!!"); 183 } 184 else 185 { 186 this.currentWorld = par1World; 187 this.randomGenerator = par2Random; 188 this.chunk_X = par3; 189 this.chunk_Z = par4; 190 this.decorate(); 191 this.currentWorld = null; 192 this.randomGenerator = null; 193 } 194 } 195 196 /** 197 * The method that does the work of actually decorating chunks 198 */ 199 protected void decorate() 200 { 201 MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z)); 202 203 this.generateOres(); 204 int var1; 205 int var2; 206 int var3; 207 208 boolean doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND); 209 for (var1 = 0; doGen && var1 < this.sandPerChunk2; ++var1) 210 { 211 var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 212 var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 213 this.sandGen.generate(this.currentWorld, this.randomGenerator, var2, this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3); 214 } 215 216 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CLAY); 217 for (var1 = 0; doGen && var1 < this.clayPerChunk; ++var1) 218 { 219 var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 220 var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 221 this.clayGen.generate(this.currentWorld, this.randomGenerator, var2, this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3); 222 } 223 224 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND_PASS2); 225 for (var1 = 0; doGen && var1 < this.sandPerChunk; ++var1) 226 { 227 var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 228 var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 229 this.sandGen.generate(this.currentWorld, this.randomGenerator, var2, this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3); 230 } 231 232 var1 = this.treesPerChunk; 233 234 if (this.randomGenerator.nextInt(10) == 0) 235 { 236 ++var1; 237 } 238 239 int var4; 240 241 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, TREE); 242 for (var2 = 0; doGen && var2 < var1; ++var2) 243 { 244 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 245 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 246 WorldGenerator var5 = this.biome.getRandomWorldGenForTrees(this.randomGenerator); 247 var5.setScale(1.0D, 1.0D, 1.0D); 248 var5.generate(this.currentWorld, this.randomGenerator, var3, this.currentWorld.getHeightValue(var3, var4), var4); 249 } 250 251 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, BIG_SHROOM); 252 for (var2 = 0; doGen && var2 < this.bigMushroomsPerChunk; ++var2) 253 { 254 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 255 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 256 this.bigMushroomGen.generate(this.currentWorld, this.randomGenerator, var3, this.currentWorld.getHeightValue(var3, var4), var4); 257 } 258 259 int var7; 260 261 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, FLOWERS); 262 for (var2 = 0; doGen && var2 < this.flowersPerChunk; ++var2) 263 { 264 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 265 var4 = this.randomGenerator.nextInt(128); 266 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 267 this.plantYellowGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 268 269 if (this.randomGenerator.nextInt(4) == 0) 270 { 271 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 272 var4 = this.randomGenerator.nextInt(128); 273 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 274 this.plantRedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 275 } 276 } 277 278 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, GRASS); 279 for (var2 = 0; doGen && var2 < this.grassPerChunk; ++var2) 280 { 281 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 282 var4 = this.randomGenerator.nextInt(128); 283 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 284 WorldGenerator var6 = this.biome.getRandomWorldGenForGrass(this.randomGenerator); 285 var6.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 286 } 287 288 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, DEAD_BUSH); 289 for (var2 = 0; doGen && var2 < this.deadBushPerChunk; ++var2) 290 { 291 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 292 var4 = this.randomGenerator.nextInt(128); 293 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 294 (new WorldGenDeadBush(Block.deadBush.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 295 } 296 297 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LILYPAD); 298 for (var2 = 0; doGen && var2 < this.waterlilyPerChunk; ++var2) 299 { 300 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 301 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 302 303 for (var7 = this.randomGenerator.nextInt(128); var7 > 0 && this.currentWorld.getBlockId(var3, var7 - 1, var4) == 0; --var7) 304 { 305 ; 306 } 307 308 this.waterlilyGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); 309 } 310 311 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SHROOM); 312 for (var2 = 0; doGen && var2 < this.mushroomsPerChunk; ++var2) 313 { 314 if (this.randomGenerator.nextInt(4) == 0) 315 { 316 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 317 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 318 var7 = this.currentWorld.getHeightValue(var3, var4); 319 this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); 320 } 321 322 if (this.randomGenerator.nextInt(8) == 0) 323 { 324 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 325 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 326 var7 = this.randomGenerator.nextInt(128); 327 this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); 328 } 329 } 330 331 if (doGen && this.randomGenerator.nextInt(4) == 0) 332 { 333 var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 334 var3 = this.randomGenerator.nextInt(128); 335 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 336 this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4); 337 } 338 339 if (doGen && this.randomGenerator.nextInt(8) == 0) 340 { 341 var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 342 var3 = this.randomGenerator.nextInt(128); 343 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 344 this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4); 345 } 346 347 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, REED); 348 for (var2 = 0; doGen && var2 < this.reedsPerChunk; ++var2) 349 { 350 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 351 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 352 var7 = this.randomGenerator.nextInt(128); 353 this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); 354 } 355 356 for (var2 = 0; doGen && var2 < 10; ++var2) 357 { 358 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 359 var4 = this.randomGenerator.nextInt(128); 360 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 361 this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 362 } 363 364 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, PUMPKIN); 365 if (doGen && this.randomGenerator.nextInt(32) == 0) 366 { 367 var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 368 var3 = this.randomGenerator.nextInt(128); 369 var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 370 (new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, var2, var3, var4); 371 } 372 373 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CACTUS); 374 for (var2 = 0; doGen && var2 < this.cactiPerChunk; ++var2) 375 { 376 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 377 var4 = this.randomGenerator.nextInt(128); 378 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 379 this.cactusGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 380 } 381 382 doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LAKE); 383 if (doGen && this.generateLakes) 384 { 385 for (var2 = 0; var2 < 50; ++var2) 386 { 387 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 388 var4 = this.randomGenerator.nextInt(this.randomGenerator.nextInt(120) + 8); 389 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 390 (new WorldGenLiquids(Block.waterMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 391 } 392 393 for (var2 = 0; var2 < 20; ++var2) 394 { 395 var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; 396 var4 = this.randomGenerator.nextInt(this.randomGenerator.nextInt(this.randomGenerator.nextInt(112) + 8) + 8); 397 var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; 398 (new WorldGenLiquids(Block.lavaMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4, var7); 399 } 400 } 401 402 MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z)); 403 } 404 405 /** 406 * Standard ore generation helper. Generates most ores. 407 */ 408 protected void genStandardOre1(int par1, WorldGenerator par2WorldGenerator, int par3, int par4) 409 { 410 for (int var5 = 0; var5 < par1; ++var5) 411 { 412 int var6 = this.chunk_X + this.randomGenerator.nextInt(16); 413 int var7 = this.randomGenerator.nextInt(par4 - par3) + par3; 414 int var8 = this.chunk_Z + this.randomGenerator.nextInt(16); 415 par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8); 416 } 417 } 418 419 /** 420 * Standard ore generation helper. Generates Lapis Lazuli. 421 */ 422 protected void genStandardOre2(int par1, WorldGenerator par2WorldGenerator, int par3, int par4) 423 { 424 for (int var5 = 0; var5 < par1; ++var5) 425 { 426 int var6 = this.chunk_X + this.randomGenerator.nextInt(16); 427 int var7 = this.randomGenerator.nextInt(par4) + this.randomGenerator.nextInt(par4) + (par3 - par4); 428 int var8 = this.chunk_Z + this.randomGenerator.nextInt(16); 429 par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8); 430 } 431 } 432 433 /** 434 * Generates ores in the current chunk 435 */ 436 protected void generateOres() 437 { 438 MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z)); 439 if (TerrainGen.generateOre(currentWorld, randomGenerator, dirtGen, chunk_X, chunk_Z, DIRT)) 440 this.genStandardOre1(20, this.dirtGen, 0, 128); 441 if (TerrainGen.generateOre(currentWorld, randomGenerator, gravelGen, chunk_X, chunk_Z, GRAVEL)) 442 this.genStandardOre1(10, this.gravelGen, 0, 128); 443 if (TerrainGen.generateOre(currentWorld, randomGenerator, coalGen, chunk_X, chunk_Z, COAL)) 444 this.genStandardOre1(20, this.coalGen, 0, 128); 445 if (TerrainGen.generateOre(currentWorld, randomGenerator, ironGen, chunk_X, chunk_Z, IRON)) 446 this.genStandardOre1(20, this.ironGen, 0, 64); 447 if (TerrainGen.generateOre(currentWorld, randomGenerator, goldGen, chunk_X, chunk_Z, GOLD)) 448 this.genStandardOre1(2, this.goldGen, 0, 32); 449 if (TerrainGen.generateOre(currentWorld, randomGenerator, redstoneGen, chunk_X, chunk_Z, REDSTONE)) 450 this.genStandardOre1(8, this.redstoneGen, 0, 16); 451 if (TerrainGen.generateOre(currentWorld, randomGenerator, diamondGen, chunk_X, chunk_Z, DIAMOND)) 452 this.genStandardOre1(1, this.diamondGen, 0, 16); 453 if (TerrainGen.generateOre(currentWorld, randomGenerator, lapisGen, chunk_X, chunk_Z, LAPIS)) 454 this.genStandardOre2(1, this.lapisGen, 16, 16); 455 MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z)); 456 } 457 }