1 package asia.tcrs.ccnp.chemicraftnext.core.other;
3 import static net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.*;
4 import static net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.*;
7 import java.util.Random;
9 import net.minecraft.block.Block;
10 import net.minecraft.block.BlockSand;
11 import net.minecraft.entity.EnumCreatureType;
12 import net.minecraft.util.IProgressUpdate;
13 import net.minecraft.util.MathHelper;
14 import net.minecraft.world.ChunkPosition;
15 import net.minecraft.world.SpawnerAnimals;
16 import net.minecraft.world.World;
17 import net.minecraft.world.biome.BiomeGenBase;
18 import net.minecraft.world.chunk.Chunk;
19 import net.minecraft.world.chunk.IChunkProvider;
20 import net.minecraft.world.gen.MapGenBase;
21 import net.minecraft.world.gen.MapGenCaves;
22 import net.minecraft.world.gen.MapGenRavine;
23 import net.minecraft.world.gen.NoiseGeneratorOctaves;
24 import net.minecraft.world.gen.feature.MapGenScatteredFeature;
25 import net.minecraft.world.gen.feature.WorldGenDungeons;
26 import net.minecraft.world.gen.feature.WorldGenLakes;
27 import net.minecraft.world.gen.structure.MapGenMineshaft;
28 import net.minecraft.world.gen.structure.MapGenStronghold;
29 import net.minecraft.world.gen.structure.MapGenVillage;
30 import net.minecraftforge.common.MinecraftForge;
31 import net.minecraftforge.event.Event.Result;
32 import net.minecraftforge.event.terraingen.ChunkProviderEvent;
33 import net.minecraftforge.event.terraingen.PopulateChunkEvent;
34 import net.minecraftforge.event.terraingen.TerrainGen;
36 public class ChunkProviderChemical implements IChunkProvider
41 /** A NoiseGeneratorOctaves used in generating terrain */
42 private NoiseGeneratorOctaves noiseGen1;
44 /** A NoiseGeneratorOctaves used in generating terrain */
45 private NoiseGeneratorOctaves noiseGen2;
47 /** A NoiseGeneratorOctaves used in generating terrain */
48 private NoiseGeneratorOctaves noiseGen3;
50 /** A NoiseGeneratorOctaves used in generating terrain */
51 private NoiseGeneratorOctaves noiseGen4;
53 /** A NoiseGeneratorOctaves used in generating terrain */
54 public NoiseGeneratorOctaves noiseGen5;
56 /** A NoiseGeneratorOctaves used in generating terrain */
57 public NoiseGeneratorOctaves noiseGen6;
58 public NoiseGeneratorOctaves mobSpawnerNoise;
60 /** Reference to the World object. */
61 private World worldObj;
63 /** are map structures going to be generated (e.g. strongholds) */
64 private final boolean mapFeaturesEnabled;
66 /** Holds the overall noise array used in chunk generation */
67 private double[] noiseArray;
68 private double[] stoneNoise = new double[256];
69 private MapGenBase caveGenerator = new MapGenCaves();
71 /** Holds Stronghold Generator */
72 private MapGenStronghold strongholdGenerator = new MapGenStronghold();
74 /** Holds Village Generator */
75 private MapGenVillage villageGenerator = new MapGenVillage();
77 /** Holds Mineshaft Generator */
78 private MapGenMineshaft mineshaftGenerator = new MapGenMineshaft();
79 private MapGenScatteredFeature scatteredFeatureGenerator = new MapGenScatteredFeature();
81 /** Holds ravine generator */
82 private MapGenBase ravineGenerator = new MapGenRavine();
84 /** The biomes that are used to generate the chunk */
85 private BiomeGenBase[] biomesForGeneration;
87 /** A double array that hold terrain noise from noiseGen3 */
90 /** A double array that hold terrain noise */
93 /** A double array that hold terrain noise from noiseGen2 */
96 /** A double array that hold terrain noise from noiseGen5 */
99 /** A double array that holds terrain noise from noiseGen6 */
103 * Used to store the 5x5 parabolic field that is used during terrain generation.
105 float[] parabolicField;
106 int[][] field_73219_j = new int[32][32];
109 caveGenerator = TerrainGen.getModdedMapGen(caveGenerator, CAVE);
110 strongholdGenerator = (MapGenStronghold) TerrainGen.getModdedMapGen(strongholdGenerator, STRONGHOLD);
111 villageGenerator = (MapGenVillage) TerrainGen.getModdedMapGen(villageGenerator, VILLAGE);
112 mineshaftGenerator = (MapGenMineshaft) TerrainGen.getModdedMapGen(mineshaftGenerator, MINESHAFT);
113 scatteredFeatureGenerator = (MapGenScatteredFeature) TerrainGen.getModdedMapGen(scatteredFeatureGenerator, SCATTERED_FEATURE);
114 ravineGenerator = TerrainGen.getModdedMapGen(ravineGenerator, RAVINE);
117 public ChunkProviderChemical(World par1World, long par2, boolean par4)
119 this.worldObj = par1World;
120 this.mapFeaturesEnabled = par4;
121 this.rand = new Random(par2);
122 this.noiseGen1 = new NoiseGeneratorOctaves(this.rand, 16);
123 this.noiseGen2 = new NoiseGeneratorOctaves(this.rand, 16);
124 this.noiseGen3 = new NoiseGeneratorOctaves(this.rand, 8);
125 this.noiseGen4 = new NoiseGeneratorOctaves(this.rand, 4);
126 this.noiseGen5 = new NoiseGeneratorOctaves(this.rand, 10);
127 this.noiseGen6 = new NoiseGeneratorOctaves(this.rand, 16);
128 this.mobSpawnerNoise = new NoiseGeneratorOctaves(this.rand, 8);
130 NoiseGeneratorOctaves[] noiseGens = {noiseGen1, noiseGen2, noiseGen3, noiseGen4, noiseGen5, noiseGen6, mobSpawnerNoise};
131 noiseGens = TerrainGen.getModdedNoiseGenerators(par1World, this.rand, noiseGens);
132 this.noiseGen1 = noiseGens[0];
133 this.noiseGen2 = noiseGens[1];
134 this.noiseGen3 = noiseGens[2];
135 this.noiseGen4 = noiseGens[3];
136 this.noiseGen5 = noiseGens[4];
137 this.noiseGen6 = noiseGens[5];
138 this.mobSpawnerNoise = noiseGens[6];
142 * Generates the shape of the terrain for the chunk though its all stone though the water is frozen if the
143 * temperature is low enough
145 public void generateTerrain(int par1, int par2, byte[] par3ArrayOfByte)
153 this.biomesForGeneration = this.worldObj.getWorldChunkManager().getBiomesForGeneration(this.biomesForGeneration, par1 * 4 - 2, par2 * 4 - 2, var7 + 5, var9 + 5);
154 this.noiseArray = this.initializeNoiseField(this.noiseArray, par1 * var4, 0, par2 * var4, var7, var8, var9);
156 for (int var10 = 0; var10 < var4; ++var10)
158 for (int var11 = 0; var11 < var4; ++var11)
160 for (int var12 = 0; var12 < var5; ++var12)
162 double var13 = 0.125D;
163 double var15 = this.noiseArray[((var10 + 0) * var9 + var11 + 0) * var8 + var12 + 0];
164 double var17 = this.noiseArray[((var10 + 0) * var9 + var11 + 1) * var8 + var12 + 0];
165 double var19 = this.noiseArray[((var10 + 1) * var9 + var11 + 0) * var8 + var12 + 0];
166 double var21 = this.noiseArray[((var10 + 1) * var9 + var11 + 1) * var8 + var12 + 0];
167 double var23 = (this.noiseArray[((var10 + 0) * var9 + var11 + 0) * var8 + var12 + 1] - var15) * var13;
168 double var25 = (this.noiseArray[((var10 + 0) * var9 + var11 + 1) * var8 + var12 + 1] - var17) * var13;
169 double var27 = (this.noiseArray[((var10 + 1) * var9 + var11 + 0) * var8 + var12 + 1] - var19) * var13;
170 double var29 = (this.noiseArray[((var10 + 1) * var9 + var11 + 1) * var8 + var12 + 1] - var21) * var13;
172 for (int var31 = 0; var31 < 8; ++var31)
174 double var32 = 0.25D;
175 double var34 = var15;
176 double var36 = var17;
177 double var38 = (var19 - var15) * var32;
178 double var40 = (var21 - var17) * var32;
180 for (int var42 = 0; var42 < 4; ++var42)
182 int var43 = var42 + var10 * 4 << 11 | 0 + var11 * 4 << 7 | var12 * 8 + var31;
185 double var45 = 0.25D;
186 double var49 = (var36 - var34) * var45;
187 double var47 = var34 - var49;
189 for (int var51 = 0; var51 < 4; ++var51)
191 if ((var47 += var49) > 0.0D)
193 par3ArrayOfByte[var43 += var44] = (byte)Block.stone.blockID;
195 else if (var12 * 8 + var31 < var6)
197 //par3ArrayOfByte[var43 += var44] = (byte)Block.waterStill.blockID;
201 par3ArrayOfByte[var43 += var44] = 0;
220 * Replaces the stone that was placed in with blocks that match the biome
222 public void replaceBlocksForBiome(int par1, int par2, byte[] par3ArrayOfByte, BiomeGenBase[] par4ArrayOfBiomeGenBase)
224 ChunkProviderEvent.ReplaceBiomeBlocks event = new ChunkProviderEvent.ReplaceBiomeBlocks(this, par1, par2, par3ArrayOfByte, par4ArrayOfBiomeGenBase);
225 MinecraftForge.EVENT_BUS.post(event);
226 if (event.getResult() == Result.DENY) return;
229 double var6 = 0.03125D;
230 this.stoneNoise = this.noiseGen4.generateNoiseOctaves(this.stoneNoise, par1 * 16, par2 * 16, 0, 16, 16, 1, var6 * 2.0D, var6 * 2.0D, var6 * 2.0D);
232 for (int var8 = 0; var8 < 16; ++var8)
234 for (int var9 = 0; var9 < 16; ++var9)
236 BiomeGenBase var10 = par4ArrayOfBiomeGenBase[var9 + var8 * 16];
237 float var11 = var10.getFloatTemperature();
238 int var12 = (int)(this.stoneNoise[var8 + var9 * 16] / 3.0D + 3.0D + this.rand.nextDouble() * 0.25D);
240 byte var14 = var10.topBlock;
241 byte var15 = var10.fillerBlock;
243 for (int var16 = 127; var16 >= 0; --var16)
245 int var17 = (var9 * 16 + var8) * 128 + var16;
247 if (var16 <= 0 + this.rand.nextInt(5))
249 par3ArrayOfByte[var17] = (byte)Block.bedrock.blockID;
253 byte var18 = par3ArrayOfByte[var17];
259 else if (var18 == Block.stone.blockID)
266 var15 = (byte)Block.stone.blockID;
268 else if (var16 >= var5 - 4 && var16 <= var5 + 1)
270 var14 = var10.topBlock;
271 var15 = var10.fillerBlock;
274 if (var16 < var5 && var14 == 0)
278 //var14 = (byte)Block.ice.blockID;
282 //var14 = (byte)Block.waterStill.blockID;
288 if (var16 >= var5 - 1)
290 par3ArrayOfByte[var17] = var14;
294 par3ArrayOfByte[var17] = var15;
300 par3ArrayOfByte[var17] = var15;
302 if (var13 == 0 && var15 == Block.sand.blockID)
304 var13 = this.rand.nextInt(4);
305 var15 = (byte)Block.sandStone.blockID;
316 * loads or generates the chunk at the chunk location specified
318 public Chunk loadChunk(int par1, int par2)
320 return this.provideChunk(par1, par2);
324 * Will return back a chunk, if it doesn't exist and its not a MP client it will generates all the blocks for the
325 * specified chunk from the map seed and chunk seed
327 public Chunk provideChunk(int par1, int par2)
329 this.rand.setSeed((long)par1 * 341873128712L + (long)par2 * 132897987541L);
330 byte[] var3 = new byte[32768];
331 this.generateTerrain(par1, par2, var3);
332 this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, par1 * 16, par2 * 16, 16, 16);
333 this.replaceBlocksForBiome(par1, par2, var3, this.biomesForGeneration);
334 this.caveGenerator.generate(this, this.worldObj, par1, par2, var3);
335 this.ravineGenerator.generate(this, this.worldObj, par1, par2, var3);
337 if (this.mapFeaturesEnabled)
339 this.mineshaftGenerator.generate(this, this.worldObj, par1, par2, var3);
340 this.villageGenerator.generate(this, this.worldObj, par1, par2, var3);
341 this.strongholdGenerator.generate(this, this.worldObj, par1, par2, var3);
342 this.scatteredFeatureGenerator.generate(this, this.worldObj, par1, par2, var3);
345 Chunk var4 = new Chunk(this.worldObj, var3, par1, par2);
346 byte[] var5 = var4.getBiomeArray();
348 for (int var6 = 0; var6 < var5.length; ++var6)
350 var5[var6] = (byte)this.biomesForGeneration[var6].biomeID;
353 var4.generateSkylightMap();
358 * generates a subset of the level's terrain data. Takes 7 arguments: the [empty] noise array, the position, and the
361 private double[] initializeNoiseField(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, int par6, int par7)
363 ChunkProviderEvent.InitNoiseField event = new ChunkProviderEvent.InitNoiseField(this, par1ArrayOfDouble, par2, par3, par4, par5, par6, par7);
364 MinecraftForge.EVENT_BUS.post(event);
365 if (event.getResult() == Result.DENY) return event.noisefield;
367 if (par1ArrayOfDouble == null)
369 par1ArrayOfDouble = new double[par5 * par6 * par7];
372 if (this.parabolicField == null)
374 this.parabolicField = new float[25];
376 for (int var8 = -2; var8 <= 2; ++var8)
378 for (int var9 = -2; var9 <= 2; ++var9)
380 float var10 = 10.0F / MathHelper.sqrt_float((float)(var8 * var8 + var9 * var9) + 0.2F);
381 this.parabolicField[var8 + 2 + (var9 + 2) * 5] = var10;
386 double var44 = 684.412D;
387 double var45 = 684.412D;
388 this.noise5 = this.noiseGen5.generateNoiseOctaves(this.noise5, par2, par4, par5, par7, 1.121D, 1.121D, 0.5D);
389 this.noise6 = this.noiseGen6.generateNoiseOctaves(this.noise6, par2, par4, par5, par7, 200.0D, 200.0D, 0.5D);
390 this.noise3 = this.noiseGen3.generateNoiseOctaves(this.noise3, par2, par3, par4, par5, par6, par7, var44 / 80.0D, var45 / 160.0D, var44 / 80.0D);
391 this.noise1 = this.noiseGen1.generateNoiseOctaves(this.noise1, par2, par3, par4, par5, par6, par7, var44, var45, var44);
392 this.noise2 = this.noiseGen2.generateNoiseOctaves(this.noise2, par2, par3, par4, par5, par6, par7, var44, var45, var44);
393 boolean var43 = false;
394 boolean var42 = false;
398 for (int var14 = 0; var14 < par5; ++var14)
400 for (int var15 = 0; var15 < par7; ++var15)
406 BiomeGenBase var20 = this.biomesForGeneration[var14 + 2 + (var15 + 2) * (par5 + 5)];
408 for (int var21 = -var19; var21 <= var19; ++var21)
410 for (int var22 = -var19; var22 <= var19; ++var22)
412 BiomeGenBase var23 = this.biomesForGeneration[var14 + var21 + 2 + (var15 + var22 + 2) * (par5 + 5)];
413 float var24 = this.parabolicField[var21 + 2 + (var22 + 2) * 5] / (var23.minHeight + 2.0F);
415 if (var23.minHeight > var20.minHeight)
420 var16 += var23.maxHeight * var24;
421 var17 += var23.minHeight * var24;
428 var16 = var16 * 0.9F + 0.1F;
429 var17 = (var17 * 4.0F - 1.0F) / 8.0F;
430 double var47 = this.noise6[var13] / 8000.0D;
434 var47 = -var47 * 0.3D;
437 var47 = var47 * 3.0D - 2.0D;
463 for (int var46 = 0; var46 < par6; ++var46)
465 double var48 = (double)var17;
466 double var26 = (double)var16;
467 var48 += var47 * 0.2D;
468 var48 = var48 * (double)par6 / 16.0D;
469 double var28 = (double)par6 / 2.0D + var48 * 4.0D;
471 double var32 = ((double)var46 - var28) * 12.0D * 128.0D / 128.0D / var26;
478 double var34 = this.noise1[var12] / 512.0D;
479 double var36 = this.noise2[var12] / 512.0D;
480 double var38 = (this.noise3[var12] / 10.0D + 1.0D) / 2.0D;
486 else if (var38 > 1.0D)
492 var30 = var34 + (var36 - var34) * var38;
497 if (var46 > par6 - 4)
499 double var40 = (double)((float)(var46 - (par6 - 4)) / 3.0F);
500 var30 = var30 * (1.0D - var40) + -10.0D * var40;
503 par1ArrayOfDouble[var12] = var30;
509 return par1ArrayOfDouble;
513 * Checks to see if a chunk exists at x, y
515 public boolean chunkExists(int par1, int par2)
521 * Populates chunk with ores etc etc
523 public void populate(IChunkProvider par1IChunkProvider, int par2, int par3)
525 BlockSand.fallInstantly = true;
526 int var4 = par2 * 16;
527 int var5 = par3 * 16;
528 BiomeGenBase var6 = this.worldObj.getBiomeGenForCoords(var4 + 16, var5 + 16);
529 this.rand.setSeed(this.worldObj.getSeed());
530 long var7 = this.rand.nextLong() / 2L * 2L + 1L;
531 long var9 = this.rand.nextLong() / 2L * 2L + 1L;
532 this.rand.setSeed((long)par2 * var7 + (long)par3 * var9 ^ this.worldObj.getSeed());
533 boolean var11 = false;
535 MinecraftForge.EVENT_BUS.post(new PopulateChunkEvent.Pre(par1IChunkProvider, worldObj, rand, par2, par3, var11));
537 if (this.mapFeaturesEnabled)
539 this.mineshaftGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3);
540 var11 = this.villageGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3);
541 this.strongholdGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3);
542 this.scatteredFeatureGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3);
549 if (TerrainGen.populate(par1IChunkProvider, worldObj, rand, par2, par3, var11, LAKE) &&
550 !var11 && this.rand.nextInt(4) == 0)
552 var12 = var4 + this.rand.nextInt(16) + 8;
553 var13 = this.rand.nextInt(128);
554 var14 = var5 + this.rand.nextInt(16) + 8;
555 //(new WorldGenLakes(Block.waterStill.blockID)).generate(this.worldObj, this.rand, var12, var13, var14);
558 if (TerrainGen.populate(par1IChunkProvider, worldObj, rand, par2, par3, var11, LAVA) &&
559 !var11 && this.rand.nextInt(8) == 0)
561 var12 = var4 + this.rand.nextInt(16) + 8;
562 var13 = this.rand.nextInt(this.rand.nextInt(120) + 8);
563 var14 = var5 + this.rand.nextInt(16) + 8;
565 if (var13 < 63 || this.rand.nextInt(10) == 0)
567 (new WorldGenLakes(Block.lavaStill.blockID)).generate(this.worldObj, this.rand, var12, var13, var14);
571 boolean doGen = TerrainGen.populate(par1IChunkProvider, worldObj, rand, par2, par3, var11, DUNGEON);
572 for (var12 = 0; doGen && var12 < 8; ++var12)
574 var13 = var4 + this.rand.nextInt(16) + 8;
575 var14 = this.rand.nextInt(128);
576 int var15 = var5 + this.rand.nextInt(16) + 8;
578 if ((new WorldGenDungeons()).generate(this.worldObj, this.rand, var13, var14, var15))
584 var6.decorate(this.worldObj, this.rand, var4, var5);
585 SpawnerAnimals.performWorldGenSpawning(this.worldObj, var6, var4 + 8, var5 + 8, 16, 16, this.rand);
589 doGen = TerrainGen.populate(par1IChunkProvider, worldObj, rand, par2, par3, var11, ICE);
590 for (var12 = 0; doGen && var12 < 16; ++var12)
592 for (var13 = 0; var13 < 16; ++var13)
594 var14 = this.worldObj.getPrecipitationHeight(var4 + var12, var5 + var13);
596 if (this.worldObj.isBlockFreezable(var12 + var4, var14 - 1, var13 + var5))
598 this.worldObj.setBlock(var12 + var4, var14 - 1, var13 + var5, Block.ice.blockID);
601 if (this.worldObj.canSnowAt(var12 + var4, var14, var13 + var5))
603 this.worldObj.setBlock(var12 + var4, var14, var13 + var5, Block.snow.blockID);
608 MinecraftForge.EVENT_BUS.post(new PopulateChunkEvent.Post(par1IChunkProvider, worldObj, rand, par2, par3, var11));
610 BlockSand.fallInstantly = false;
614 * Two modes of operation: if passed true, save all Chunks in one go. If passed false, save up to two chunks.
615 * Return true if all chunks have been saved.
617 public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate)
623 * Unloads the 100 oldest chunks from memory, due to a bug with chunkSet.add() never being called it thinks the list
624 * is always empty and will not remove any chunks.
626 public boolean unload100OldestChunks()
632 * Returns if the IChunkProvider supports saving.
634 public boolean canSave()
640 * Converts the instance data to a readable string.
642 public String makeString()
644 return "RandomLevelSource";
648 * Returns a list of creatures of the specified type that can spawn at the given location.
650 public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4)
652 BiomeGenBase var5 = this.worldObj.getBiomeGenForCoords(par2, par4);
653 return var5 == null ? null : (var5 == BiomeGenBase.swampland && par1EnumCreatureType == EnumCreatureType.monster && this.scatteredFeatureGenerator.hasStructureAt(par2, par3, par4) ? this.scatteredFeatureGenerator.getScatteredFeatureSpawnList() : var5.getSpawnableList(par1EnumCreatureType));
657 * Returns the location of the closest structure of the specified type. If not found returns null.
659 public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5)
661 return "Stronghold".equals(par2Str) && this.strongholdGenerator != null ? this.strongholdGenerator.getNearestInstance(par1World, par3, par4, par5) : null;
664 public int getLoadedChunkCount()
669 public void recreateStructures(int par1, int par2)
671 if (this.mapFeaturesEnabled)
673 this.mineshaftGenerator.generate(this, this.worldObj, par1, par2, (byte[])null);
674 this.villageGenerator.generate(this, this.worldObj, par1, par2, (byte[])null);
675 this.strongholdGenerator.generate(this, this.worldObj, par1, par2, (byte[])null);
676 this.scatteredFeatureGenerator.generate(this, this.worldObj, par1, par2, (byte[])null);
681 public boolean unloadQueuedChunks() {
686 public void func_104112_b() {
687 // TODO Auto-generated method stub