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