    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    }