001package net.minecraft.world.gen; 002 003import java.util.List; 004import java.util.Random; 005import net.minecraft.block.Block; 006import net.minecraft.block.BlockSand; 007import net.minecraft.entity.EnumCreatureType; 008import net.minecraft.util.IProgressUpdate; 009import net.minecraft.world.ChunkPosition; 010import net.minecraft.world.World; 011import net.minecraft.world.biome.BiomeGenBase; 012import net.minecraft.world.chunk.Chunk; 013import net.minecraft.world.chunk.IChunkProvider; 014import net.minecraft.world.gen.feature.WorldGenFire; 015import net.minecraft.world.gen.feature.WorldGenFlowers; 016import net.minecraft.world.gen.feature.WorldGenGlowStone1; 017import net.minecraft.world.gen.feature.WorldGenGlowStone2; 018import net.minecraft.world.gen.feature.WorldGenHellLava; 019import net.minecraft.world.gen.feature.WorldGenMinable; 020import net.minecraft.world.gen.structure.MapGenNetherBridge; 021 022import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.*; 023import static net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.*; 024import static net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.*; 025import net.minecraftforge.common.*; 026import net.minecraftforge.event.Event.*; 027import net.minecraftforge.event.terraingen.*; 028 029public class ChunkProviderHell implements IChunkProvider 030{ 031 private Random hellRNG; 032 033 /** A NoiseGeneratorOctaves used in generating nether terrain */ 034 private NoiseGeneratorOctaves netherNoiseGen1; 035 private NoiseGeneratorOctaves netherNoiseGen2; 036 private NoiseGeneratorOctaves netherNoiseGen3; 037 038 /** Determines whether slowsand or gravel can be generated at a location */ 039 private NoiseGeneratorOctaves slowsandGravelNoiseGen; 040 041 /** 042 * Determines whether something other than nettherack can be generated at a location 043 */ 044 private NoiseGeneratorOctaves netherrackExculsivityNoiseGen; 045 public NoiseGeneratorOctaves netherNoiseGen6; 046 public NoiseGeneratorOctaves netherNoiseGen7; 047 048 /** Is the world that the nether is getting generated. */ 049 private World worldObj; 050 private double[] noiseField; 051 public MapGenNetherBridge genNetherBridge = new MapGenNetherBridge(); 052 053 /** 054 * Holds the noise used to determine whether slowsand can be generated at a location 055 */ 056 private double[] slowsandNoise = new double[256]; 057 private double[] gravelNoise = new double[256]; 058 059 /** 060 * Holds the noise used to determine whether something other than netherrack can be generated at a location 061 */ 062 private double[] netherrackExclusivityNoise = new double[256]; 063 private MapGenBase netherCaveGenerator = new MapGenCavesHell(); 064 double[] noiseData1; 065 double[] noiseData2; 066 double[] noiseData3; 067 double[] noiseData4; 068 double[] noiseData5; 069 070 { 071 genNetherBridge = (MapGenNetherBridge) TerrainGen.getModdedMapGen(genNetherBridge, NETHER_BRIDGE); 072 netherCaveGenerator = TerrainGen.getModdedMapGen(netherCaveGenerator, NETHER_CAVE); 073 } 074 075 public ChunkProviderHell(World par1World, long par2) 076 { 077 this.worldObj = par1World; 078 this.hellRNG = new Random(par2); 079 this.netherNoiseGen1 = new NoiseGeneratorOctaves(this.hellRNG, 16); 080 this.netherNoiseGen2 = new NoiseGeneratorOctaves(this.hellRNG, 16); 081 this.netherNoiseGen3 = new NoiseGeneratorOctaves(this.hellRNG, 8); 082 this.slowsandGravelNoiseGen = new NoiseGeneratorOctaves(this.hellRNG, 4); 083 this.netherrackExculsivityNoiseGen = new NoiseGeneratorOctaves(this.hellRNG, 4); 084 this.netherNoiseGen6 = new NoiseGeneratorOctaves(this.hellRNG, 10); 085 this.netherNoiseGen7 = new NoiseGeneratorOctaves(this.hellRNG, 16); 086 087 NoiseGeneratorOctaves[] noiseGens = {netherNoiseGen1, netherNoiseGen2, netherNoiseGen3, slowsandGravelNoiseGen, netherrackExculsivityNoiseGen, netherNoiseGen6, netherNoiseGen7}; 088 noiseGens = TerrainGen.getModdedNoiseGenerators(par1World, this.hellRNG, noiseGens); 089 this.netherNoiseGen1 = noiseGens[0]; 090 this.netherNoiseGen2 = noiseGens[1]; 091 this.netherNoiseGen3 = noiseGens[2]; 092 this.slowsandGravelNoiseGen = noiseGens[3]; 093 this.netherrackExculsivityNoiseGen = noiseGens[4]; 094 this.netherNoiseGen6 = noiseGens[5]; 095 this.netherNoiseGen7 = noiseGens[6]; 096 } 097 098 /** 099 * Generates the shape of the terrain in the nether. 100 */ 101 public void generateNetherTerrain(int par1, int par2, byte[] par3ArrayOfByte) 102 { 103 byte b0 = 4; 104 byte b1 = 32; 105 int k = b0 + 1; 106 byte b2 = 17; 107 int l = b0 + 1; 108 this.noiseField = this.initializeNoiseField(this.noiseField, par1 * b0, 0, par2 * b0, k, b2, l); 109 110 for (int i1 = 0; i1 < b0; ++i1) 111 { 112 for (int j1 = 0; j1 < b0; ++j1) 113 { 114 for (int k1 = 0; k1 < 16; ++k1) 115 { 116 double d0 = 0.125D; 117 double d1 = this.noiseField[((i1 + 0) * l + j1 + 0) * b2 + k1 + 0]; 118 double d2 = this.noiseField[((i1 + 0) * l + j1 + 1) * b2 + k1 + 0]; 119 double d3 = this.noiseField[((i1 + 1) * l + j1 + 0) * b2 + k1 + 0]; 120 double d4 = this.noiseField[((i1 + 1) * l + j1 + 1) * b2 + k1 + 0]; 121 double d5 = (this.noiseField[((i1 + 0) * l + j1 + 0) * b2 + k1 + 1] - d1) * d0; 122 double d6 = (this.noiseField[((i1 + 0) * l + j1 + 1) * b2 + k1 + 1] - d2) * d0; 123 double d7 = (this.noiseField[((i1 + 1) * l + j1 + 0) * b2 + k1 + 1] - d3) * d0; 124 double d8 = (this.noiseField[((i1 + 1) * l + j1 + 1) * b2 + k1 + 1] - d4) * d0; 125 126 for (int l1 = 0; l1 < 8; ++l1) 127 { 128 double d9 = 0.25D; 129 double d10 = d1; 130 double d11 = d2; 131 double d12 = (d3 - d1) * d9; 132 double d13 = (d4 - d2) * d9; 133 134 for (int i2 = 0; i2 < 4; ++i2) 135 { 136 int j2 = i2 + i1 * 4 << 11 | 0 + j1 * 4 << 7 | k1 * 8 + l1; 137 short short1 = 128; 138 double d14 = 0.25D; 139 double d15 = d10; 140 double d16 = (d11 - d10) * d14; 141 142 for (int k2 = 0; k2 < 4; ++k2) 143 { 144 int l2 = 0; 145 146 if (k1 * 8 + l1 < b1) 147 { 148 l2 = Block.lavaStill.blockID; 149 } 150 151 if (d15 > 0.0D) 152 { 153 l2 = Block.netherrack.blockID; 154 } 155 156 par3ArrayOfByte[j2] = (byte)l2; 157 j2 += short1; 158 d15 += d16; 159 } 160 161 d10 += d12; 162 d11 += d13; 163 } 164 165 d1 += d5; 166 d2 += d6; 167 d3 += d7; 168 d4 += d8; 169 } 170 } 171 } 172 } 173 } 174 175 /** 176 * name based on ChunkProviderGenerate 177 */ 178 public void replaceBlocksForBiome(int par1, int par2, byte[] par3ArrayOfByte) 179 { 180 ChunkProviderEvent.ReplaceBiomeBlocks event = new ChunkProviderEvent.ReplaceBiomeBlocks(this, par1, par2, par3ArrayOfByte, null); 181 MinecraftForge.EVENT_BUS.post(event); 182 if (event.getResult() == Result.DENY) return; 183 184 byte b0 = 64; 185 double d0 = 0.03125D; 186 this.slowsandNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.slowsandNoise, par1 * 16, par2 * 16, 0, 16, 16, 1, d0, d0, 1.0D); 187 this.gravelNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.gravelNoise, par1 * 16, 109, par2 * 16, 16, 1, 16, d0, 1.0D, d0); 188 this.netherrackExclusivityNoise = this.netherrackExculsivityNoiseGen.generateNoiseOctaves(this.netherrackExclusivityNoise, par1 * 16, par2 * 16, 0, 16, 16, 1, d0 * 2.0D, d0 * 2.0D, d0 * 2.0D); 189 190 for (int k = 0; k < 16; ++k) 191 { 192 for (int l = 0; l < 16; ++l) 193 { 194 boolean flag = this.slowsandNoise[k + l * 16] + this.hellRNG.nextDouble() * 0.2D > 0.0D; 195 boolean flag1 = this.gravelNoise[k + l * 16] + this.hellRNG.nextDouble() * 0.2D > 0.0D; 196 int i1 = (int)(this.netherrackExclusivityNoise[k + l * 16] / 3.0D + 3.0D + this.hellRNG.nextDouble() * 0.25D); 197 int j1 = -1; 198 byte b1 = (byte)Block.netherrack.blockID; 199 byte b2 = (byte)Block.netherrack.blockID; 200 201 for (int k1 = 127; k1 >= 0; --k1) 202 { 203 int l1 = (l * 16 + k) * 128 + k1; 204 205 if (k1 < 127 - this.hellRNG.nextInt(5) && k1 > 0 + this.hellRNG.nextInt(5)) 206 { 207 byte b3 = par3ArrayOfByte[l1]; 208 209 if (b3 == 0) 210 { 211 j1 = -1; 212 } 213 else if (b3 == Block.netherrack.blockID) 214 { 215 if (j1 == -1) 216 { 217 if (i1 <= 0) 218 { 219 b1 = 0; 220 b2 = (byte)Block.netherrack.blockID; 221 } 222 else if (k1 >= b0 - 4 && k1 <= b0 + 1) 223 { 224 b1 = (byte)Block.netherrack.blockID; 225 b2 = (byte)Block.netherrack.blockID; 226 227 if (flag1) 228 { 229 b1 = (byte)Block.gravel.blockID; 230 } 231 232 if (flag1) 233 { 234 b2 = (byte)Block.netherrack.blockID; 235 } 236 237 if (flag) 238 { 239 b1 = (byte)Block.slowSand.blockID; 240 } 241 242 if (flag) 243 { 244 b2 = (byte)Block.slowSand.blockID; 245 } 246 } 247 248 if (k1 < b0 && b1 == 0) 249 { 250 b1 = (byte)Block.lavaStill.blockID; 251 } 252 253 j1 = i1; 254 255 if (k1 >= b0 - 1) 256 { 257 par3ArrayOfByte[l1] = b1; 258 } 259 else 260 { 261 par3ArrayOfByte[l1] = b2; 262 } 263 } 264 else if (j1 > 0) 265 { 266 --j1; 267 par3ArrayOfByte[l1] = b2; 268 } 269 } 270 } 271 else 272 { 273 par3ArrayOfByte[l1] = (byte)Block.bedrock.blockID; 274 } 275 } 276 } 277 } 278 } 279 280 /** 281 * loads or generates the chunk at the chunk location specified 282 */ 283 public Chunk loadChunk(int par1, int par2) 284 { 285 return this.provideChunk(par1, par2); 286 } 287 288 /** 289 * Will return back a chunk, if it doesn't exist and its not a MP client it will generates all the blocks for the 290 * specified chunk from the map seed and chunk seed 291 */ 292 public Chunk provideChunk(int par1, int par2) 293 { 294 this.hellRNG.setSeed((long)par1 * 341873128712L + (long)par2 * 132897987541L); 295 byte[] abyte = new byte[32768]; 296 this.generateNetherTerrain(par1, par2, abyte); 297 this.replaceBlocksForBiome(par1, par2, abyte); 298 this.netherCaveGenerator.generate(this, this.worldObj, par1, par2, abyte); 299 this.genNetherBridge.generate(this, this.worldObj, par1, par2, abyte); 300 Chunk chunk = new Chunk(this.worldObj, abyte, par1, par2); 301 BiomeGenBase[] abiomegenbase = this.worldObj.getWorldChunkManager().loadBlockGeneratorData((BiomeGenBase[])null, par1 * 16, par2 * 16, 16, 16); 302 byte[] abyte1 = chunk.getBiomeArray(); 303 304 for (int k = 0; k < abyte1.length; ++k) 305 { 306 abyte1[k] = (byte)abiomegenbase[k].biomeID; 307 } 308 309 chunk.resetRelightChecks(); 310 return chunk; 311 } 312 313 /** 314 * generates a subset of the level's terrain data. Takes 7 arguments: the [empty] noise array, the position, and the 315 * size. 316 */ 317 private double[] initializeNoiseField(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, int par6, int par7) 318 { 319 ChunkProviderEvent.InitNoiseField event = new ChunkProviderEvent.InitNoiseField(this, par1ArrayOfDouble, par2, par3, par4, par5, par6, par7); 320 MinecraftForge.EVENT_BUS.post(event); 321 if (event.getResult() == Result.DENY) return event.noisefield; 322 if (par1ArrayOfDouble == null) 323 { 324 par1ArrayOfDouble = new double[par5 * par6 * par7]; 325 } 326 327 double d0 = 684.412D; 328 double d1 = 2053.236D; 329 this.noiseData4 = this.netherNoiseGen6.generateNoiseOctaves(this.noiseData4, par2, par3, par4, par5, 1, par7, 1.0D, 0.0D, 1.0D); 330 this.noiseData5 = this.netherNoiseGen7.generateNoiseOctaves(this.noiseData5, par2, par3, par4, par5, 1, par7, 100.0D, 0.0D, 100.0D); 331 this.noiseData1 = this.netherNoiseGen3.generateNoiseOctaves(this.noiseData1, par2, par3, par4, par5, par6, par7, d0 / 80.0D, d1 / 60.0D, d0 / 80.0D); 332 this.noiseData2 = this.netherNoiseGen1.generateNoiseOctaves(this.noiseData2, par2, par3, par4, par5, par6, par7, d0, d1, d0); 333 this.noiseData3 = this.netherNoiseGen2.generateNoiseOctaves(this.noiseData3, par2, par3, par4, par5, par6, par7, d0, d1, d0); 334 int k1 = 0; 335 int l1 = 0; 336 double[] adouble1 = new double[par6]; 337 int i2; 338 339 for (i2 = 0; i2 < par6; ++i2) 340 { 341 adouble1[i2] = Math.cos((double)i2 * Math.PI * 6.0D / (double)par6) * 2.0D; 342 double d2 = (double)i2; 343 344 if (i2 > par6 / 2) 345 { 346 d2 = (double)(par6 - 1 - i2); 347 } 348 349 if (d2 < 4.0D) 350 { 351 d2 = 4.0D - d2; 352 adouble1[i2] -= d2 * d2 * d2 * 10.0D; 353 } 354 } 355 356 for (i2 = 0; i2 < par5; ++i2) 357 { 358 for (int j2 = 0; j2 < par7; ++j2) 359 { 360 double d3 = (this.noiseData4[l1] + 256.0D) / 512.0D; 361 362 if (d3 > 1.0D) 363 { 364 d3 = 1.0D; 365 } 366 367 double d4 = 0.0D; 368 double d5 = this.noiseData5[l1] / 8000.0D; 369 370 if (d5 < 0.0D) 371 { 372 d5 = -d5; 373 } 374 375 d5 = d5 * 3.0D - 3.0D; 376 377 if (d5 < 0.0D) 378 { 379 d5 /= 2.0D; 380 381 if (d5 < -1.0D) 382 { 383 d5 = -1.0D; 384 } 385 386 d5 /= 1.4D; 387 d5 /= 2.0D; 388 d3 = 0.0D; 389 } 390 else 391 { 392 if (d5 > 1.0D) 393 { 394 d5 = 1.0D; 395 } 396 397 d5 /= 6.0D; 398 } 399 400 d3 += 0.5D; 401 d5 = d5 * (double)par6 / 16.0D; 402 ++l1; 403 404 for (int k2 = 0; k2 < par6; ++k2) 405 { 406 double d6 = 0.0D; 407 double d7 = adouble1[k2]; 408 double d8 = this.noiseData2[k1] / 512.0D; 409 double d9 = this.noiseData3[k1] / 512.0D; 410 double d10 = (this.noiseData1[k1] / 10.0D + 1.0D) / 2.0D; 411 412 if (d10 < 0.0D) 413 { 414 d6 = d8; 415 } 416 else if (d10 > 1.0D) 417 { 418 d6 = d9; 419 } 420 else 421 { 422 d6 = d8 + (d9 - d8) * d10; 423 } 424 425 d6 -= d7; 426 double d11; 427 428 if (k2 > par6 - 4) 429 { 430 d11 = (double)((float)(k2 - (par6 - 4)) / 3.0F); 431 d6 = d6 * (1.0D - d11) + -10.0D * d11; 432 } 433 434 if ((double)k2 < d4) 435 { 436 d11 = (d4 - (double)k2) / 4.0D; 437 438 if (d11 < 0.0D) 439 { 440 d11 = 0.0D; 441 } 442 443 if (d11 > 1.0D) 444 { 445 d11 = 1.0D; 446 } 447 448 d6 = d6 * (1.0D - d11) + -10.0D * d11; 449 } 450 451 par1ArrayOfDouble[k1] = d6; 452 ++k1; 453 } 454 } 455 } 456 457 return par1ArrayOfDouble; 458 } 459 460 /** 461 * Checks to see if a chunk exists at x, y 462 */ 463 public boolean chunkExists(int par1, int par2) 464 { 465 return true; 466 } 467 468 /** 469 * Populates chunk with ores etc etc 470 */ 471 public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) 472 { 473 BlockSand.fallInstantly = true; 474 475 MinecraftForge.EVENT_BUS.post(new PopulateChunkEvent.Pre(par1IChunkProvider, worldObj, hellRNG, par2, par3, false)); 476 477 int k = par2 * 16; 478 int l = par3 * 16; 479 this.genNetherBridge.generateStructuresInChunk(this.worldObj, this.hellRNG, par2, par3); 480 int i1; 481 int j1; 482 int k1; 483 int l1; 484 485 boolean doGen = TerrainGen.populate(par1IChunkProvider, worldObj, hellRNG, par2, par3, false, NETHER_LAVA); 486 for (i1 = 0; doGen && i1 < 8; ++i1) 487 { 488 j1 = k + this.hellRNG.nextInt(16) + 8; 489 k1 = this.hellRNG.nextInt(120) + 4; 490 l1 = l + this.hellRNG.nextInt(16) + 8; 491 (new WorldGenHellLava(Block.lavaMoving.blockID, false)).generate(this.worldObj, this.hellRNG, j1, k1, l1); 492 } 493 494 i1 = this.hellRNG.nextInt(this.hellRNG.nextInt(10) + 1) + 1; 495 int i2; 496 497 doGen = TerrainGen.populate(par1IChunkProvider, worldObj, hellRNG, par2, par3, false, FIRE); 498 for (j1 = 0; doGen && j1 < i1; ++j1) 499 { 500 k1 = k + this.hellRNG.nextInt(16) + 8; 501 l1 = this.hellRNG.nextInt(120) + 4; 502 i2 = l + this.hellRNG.nextInt(16) + 8; 503 (new WorldGenFire()).generate(this.worldObj, this.hellRNG, k1, l1, i2); 504 } 505 506 i1 = this.hellRNG.nextInt(this.hellRNG.nextInt(10) + 1); 507 508 doGen = TerrainGen.populate(par1IChunkProvider, worldObj, hellRNG, par2, par3, false, GLOWSTONE); 509 for (j1 = 0; doGen && j1 < i1; ++j1) 510 { 511 k1 = k + this.hellRNG.nextInt(16) + 8; 512 l1 = this.hellRNG.nextInt(120) + 4; 513 i2 = l + this.hellRNG.nextInt(16) + 8; 514 (new WorldGenGlowStone1()).generate(this.worldObj, this.hellRNG, k1, l1, i2); 515 } 516 517 for (j1 = 0; doGen && j1 < 10; ++j1) 518 { 519 k1 = k + this.hellRNG.nextInt(16) + 8; 520 l1 = this.hellRNG.nextInt(128); 521 i2 = l + this.hellRNG.nextInt(16) + 8; 522 (new WorldGenGlowStone2()).generate(this.worldObj, this.hellRNG, k1, l1, i2); 523 } 524 525 MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Pre(worldObj, hellRNG, k, l)); 526 527 doGen = TerrainGen.decorate(worldObj, hellRNG, k, l, SHROOM); 528 if (doGen && this.hellRNG.nextInt(1) == 0) 529 { 530 j1 = k + this.hellRNG.nextInt(16) + 8; 531 k1 = this.hellRNG.nextInt(128); 532 l1 = l + this.hellRNG.nextInt(16) + 8; 533 (new WorldGenFlowers(Block.mushroomBrown.blockID)).generate(this.worldObj, this.hellRNG, j1, k1, l1); 534 } 535 536 if (doGen && this.hellRNG.nextInt(1) == 0) 537 { 538 j1 = k + this.hellRNG.nextInt(16) + 8; 539 k1 = this.hellRNG.nextInt(128); 540 l1 = l + this.hellRNG.nextInt(16) + 8; 541 (new WorldGenFlowers(Block.mushroomRed.blockID)).generate(this.worldObj, this.hellRNG, j1, k1, l1); 542 } 543 544 WorldGenMinable worldgenminable = new WorldGenMinable(Block.field_94342_cr.blockID, 13, Block.netherrack.blockID); 545 int j2; 546 547 for (k1 = 0; k1 < 16; ++k1) 548 { 549 l1 = k + this.hellRNG.nextInt(16); 550 i2 = this.hellRNG.nextInt(108) + 10; 551 j2 = l + this.hellRNG.nextInt(16); 552 worldgenminable.generate(this.worldObj, this.hellRNG, l1, i2, j2); 553 } 554 555 for (k1 = 0; k1 < 16; ++k1) 556 { 557 l1 = k + this.hellRNG.nextInt(16); 558 i2 = this.hellRNG.nextInt(108) + 10; 559 j2 = l + this.hellRNG.nextInt(16); 560 (new WorldGenHellLava(Block.lavaMoving.blockID, true)).generate(this.worldObj, this.hellRNG, l1, i2, j2); 561 } 562 563 MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(worldObj, hellRNG, k, l)); 564 MinecraftForge.EVENT_BUS.post(new PopulateChunkEvent.Post(par1IChunkProvider, worldObj, hellRNG, par2, par3, false)); 565 566 BlockSand.fallInstantly = false; 567 } 568 569 /** 570 * Two modes of operation: if passed true, save all Chunks in one go. If passed false, save up to two chunks. 571 * Return true if all chunks have been saved. 572 */ 573 public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) 574 { 575 return true; 576 } 577 578 /** 579 * Unloads chunks that are marked to be unloaded. This is not guaranteed to unload every such chunk. 580 */ 581 public boolean unloadQueuedChunks() 582 { 583 return false; 584 } 585 586 /** 587 * Returns if the IChunkProvider supports saving. 588 */ 589 public boolean canSave() 590 { 591 return true; 592 } 593 594 /** 595 * Converts the instance data to a readable string. 596 */ 597 public String makeString() 598 { 599 return "HellRandomLevelSource"; 600 } 601 602 /** 603 * Returns a list of creatures of the specified type that can spawn at the given location. 604 */ 605 public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) 606 { 607 if (par1EnumCreatureType == EnumCreatureType.monster && this.genNetherBridge.hasStructureAt(par2, par3, par4)) 608 { 609 return this.genNetherBridge.getSpawnList(); 610 } 611 else 612 { 613 BiomeGenBase biomegenbase = this.worldObj.getBiomeGenForCoords(par2, par4); 614 return biomegenbase == null ? null : biomegenbase.getSpawnableList(par1EnumCreatureType); 615 } 616 } 617 618 /** 619 * Returns the location of the closest structure of the specified type. If not found returns null. 620 */ 621 public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5) 622 { 623 return null; 624 } 625 626 public int getLoadedChunkCount() 627 { 628 return 0; 629 } 630 631 public void recreateStructures(int par1, int par2) 632 { 633 this.genNetherBridge.generate(this, this.worldObj, par1, par2, (byte[])null); 634 } 635}