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