    001    package net.minecraft.world.gen;
    002
    003    import java.util.ArrayList;
    004    import java.util.Iterator;
    005    import java.util.List;
    006    import java.util.Map;
    007    import java.util.Random;
    008    import net.minecraft.block.Block;
    009    import net.minecraft.entity.EnumCreatureType;
    010    import net.minecraft.util.IProgressUpdate;
    011    import net.minecraft.world.ChunkPosition;
    012    import net.minecraft.world.World;
    013    import net.minecraft.world.biome.BiomeGenBase;
    014    import net.minecraft.world.chunk.Chunk;
    015    import net.minecraft.world.chunk.IChunkProvider;
    016    import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
    017    import net.minecraft.world.gen.feature.MapGenScatteredFeature;
    018    import net.minecraft.world.gen.feature.WorldGenDungeons;
    019    import net.minecraft.world.gen.feature.WorldGenLakes;
    020    import net.minecraft.world.gen.structure.MapGenMineshaft;
    021    import net.minecraft.world.gen.structure.MapGenStronghold;
    022    import net.minecraft.world.gen.structure.MapGenStructure;
    023    import net.minecraft.world.gen.structure.MapGenVillage;
    024
    025    public class ChunkProviderFlat implements IChunkProvider
    026    {
    027        private World worldObj;
    028        private Random random;
    029        private final byte[] field_82700_c = new byte[256];
    030        private final byte[] field_82698_d = new byte[256];
    031        private final FlatGeneratorInfo field_82699_e;
    032        private final List field_82696_f = new ArrayList();
    033        private final boolean field_82697_g;
    034        private final boolean field_82702_h;
    035        private WorldGenLakes field_82703_i;
    036        private WorldGenLakes field_82701_j;
    037
    038        public ChunkProviderFlat(World par1World, long par2, boolean par4, String par5Str)
    039        {
    040            this.worldObj = par1World;
    041            this.random = new Random(par2);
    042            this.field_82699_e = FlatGeneratorInfo.createFlatGeneratorFromString(par5Str);
    043
    044            if (par4)
    045            {
    046                Map var6 = this.field_82699_e.getWorldFeatures();
    047
    048                if (var6.containsKey("village"))
    049                {
    050                    Map var7 = (Map)var6.get("village");
    051
    052                    if (!var7.containsKey("size"))
    053                    {
    054                        var7.put("size", "1");
    055                    }
    056
    057                    this.field_82696_f.add(new MapGenVillage(var7));
    058                }
    059
    060                if (var6.containsKey("biome_1"))
    061                {
    062                    this.field_82696_f.add(new MapGenScatteredFeature((Map)var6.get("biome_1")));
    063                }
    064
    065                if (var6.containsKey("mineshaft"))
    066                {
    067                    this.field_82696_f.add(new MapGenMineshaft((Map)var6.get("mineshaft")));
    068                }
    069
    070                if (var6.containsKey("stronghold"))
    071                {
    072                    this.field_82696_f.add(new MapGenStronghold((Map)var6.get("stronghold")));
    073                }
    074            }
    075
    076            this.field_82697_g = this.field_82699_e.getWorldFeatures().containsKey("decoration");
    077
    078            if (this.field_82699_e.getWorldFeatures().containsKey("lake"))
    079            {
    080                this.field_82703_i = new WorldGenLakes(Block.waterStill.blockID);
    081            }
    082
    083            if (this.field_82699_e.getWorldFeatures().containsKey("lava_lake"))
    084            {
    085                this.field_82701_j = new WorldGenLakes(Block.lavaStill.blockID);
    086            }
    087
    088            this.field_82702_h = this.field_82699_e.getWorldFeatures().containsKey("dungeon");
    089            Iterator var9 = this.field_82699_e.getFlatLayers().iterator();
    090
    091            while (var9.hasNext())
    092            {
    093                FlatLayerInfo var10 = (FlatLayerInfo)var9.next();
    094
    095                for (int var8 = var10.getMinY(); var8 < var10.getMinY() + var10.getLayerCount(); ++var8)
    096                {
    097                    this.field_82700_c[var8] = (byte)(var10.getFillBlock() & 255);
    098                    this.field_82698_d[var8] = (byte)var10.getFillBlockMeta();
    099                }
    100            }
    101        }
    102
    103        /**
    104         * loads or generates the chunk at the chunk location specified
    105         */
    106        public Chunk loadChunk(int par1, int par2)
    107        {
    108            return this.provideChunk(par1, par2);
    109        }
    110
    111        /**
    112         * Will return back a chunk, if it doesn't exist and its not a MP client it will generates all the blocks for the
    113         * specified chunk from the map seed and chunk seed
    114         */
    115        public Chunk provideChunk(int par1, int par2)
    116        {
    117            Chunk var3 = new Chunk(this.worldObj, par1, par2);
    118
    119            for (int var4 = 0; var4 < this.field_82700_c.length; ++var4)
    120            {
    121                int var5 = var4 >> 4;
    122                ExtendedBlockStorage var6 = var3.getBlockStorageArray()[var5];
    123
    124                if (var6 == null)
    125                {
    126                    var6 = new ExtendedBlockStorage(var4, !this.worldObj.provider.hasNoSky);
    127                    var3.getBlockStorageArray()[var5] = var6;
    128                }
    129
    130                for (int var7 = 0; var7 < 16; ++var7)
    131                {
    132                    for (int var8 = 0; var8 < 16; ++var8)
    133                    {
    134                        var6.setExtBlockID(var7, var4 & 15, var8, this.field_82700_c[var4] & 255);
    135                        var6.setExtBlockMetadata(var7, var4 & 15, var8, this.field_82698_d[var4]);
    136                    }
    137                }
    138            }
    139
    140            var3.generateSkylightMap();
    141            BiomeGenBase[] var9 = this.worldObj.getWorldChunkManager().loadBlockGeneratorData((BiomeGenBase[])null, par1 * 16, par2 * 16, 16, 16);
    142            byte[] var10 = var3.getBiomeArray();
    143
    144            for (int var11 = 0; var11 < var10.length; ++var11)
    145            {
    146                var10[var11] = (byte)var9[var11].biomeID;
    147            }
    148
    149            Iterator var12 = this.field_82696_f.iterator();
    150
    151            while (var12.hasNext())
    152            {
    153                MapGenStructure var13 = (MapGenStructure)var12.next();
    154                var13.generate(this, this.worldObj, par1, par2, (byte[])null);
    155            }
    156
    157            var3.generateSkylightMap();
    158            return var3;
    159        }
    160
    161        /**
    162         * Checks to see if a chunk exists at x, y
    163         */
    164        public boolean chunkExists(int par1, int par2)
    165        {
    166            return true;
    167        }
    168
    169        /**
    170         * Populates chunk with ores etc etc
    171         */
    172        public void populate(IChunkProvider par1IChunkProvider, int par2, int par3)
    173        {
    174            int var4 = par2 * 16;
    175            int var5 = par3 * 16;
    176            BiomeGenBase var6 = this.worldObj.getBiomeGenForCoords(var4 + 16, var5 + 16);
    177            boolean var7 = false;
    178            this.random.setSeed(this.worldObj.getSeed());
    179            long var8 = this.random.nextLong() / 2L * 2L + 1L;
    180            long var10 = this.random.nextLong() / 2L * 2L + 1L;
    181            this.random.setSeed((long)par2 * var8 + (long)par3 * var10 ^ this.worldObj.getSeed());
    182            Iterator var12 = this.field_82696_f.iterator();
    183
    184            while (var12.hasNext())
    185            {
    186                MapGenStructure var13 = (MapGenStructure)var12.next();
    187                boolean var14 = var13.generateStructuresInChunk(this.worldObj, this.random, par2, par3);
    188
    189                if (var13 instanceof MapGenVillage)
    190                {
    191                    var7 |= var14;
    192                }
    193            }
    194
    195            int var17;
    196            int var16;
    197            int var18;
    198
    199            if (this.field_82703_i != null && !var7 && this.random.nextInt(4) == 0)
    200            {
    201                var16 = var4 + this.random.nextInt(16) + 8;
    202                var17 = this.random.nextInt(128);
    203                var18 = var5 + this.random.nextInt(16) + 8;
    204                this.field_82703_i.generate(this.worldObj, this.random, var16, var17, var18);
    205            }
    206
    207            if (this.field_82701_j != null && !var7 && this.random.nextInt(8) == 0)
    208            {
    209                var16 = var4 + this.random.nextInt(16) + 8;
    210                var17 = this.random.nextInt(this.random.nextInt(120) + 8);
    211                var18 = var5 + this.random.nextInt(16) + 8;
    212
    213                if (var17 < 63 || this.random.nextInt(10) == 0)
    214                {
    215                    this.field_82701_j.generate(this.worldObj, this.random, var16, var17, var18);
    216                }
    217            }
    218
    219            if (this.field_82702_h)
    220            {
    221                for (var16 = 0; var16 < 8; ++var16)
    222                {
    223                    var17 = var4 + this.random.nextInt(16) + 8;
    224                    var18 = this.random.nextInt(128);
    225                    int var15 = var5 + this.random.nextInt(16) + 8;
    226                    (new WorldGenDungeons()).generate(this.worldObj, this.random, var17, var18, var15);
    227                }
    228            }
    229
    230            if (this.field_82697_g)
    231            {
    232                var6.decorate(this.worldObj, this.random, var4, var5);
    233            }
    234        }
    235
    236        /**
    237         * Two modes of operation: if passed true, save all Chunks in one go.  If passed false, save up to two chunks.
    238         * Return true if all chunks have been saved.
    239         */
    240        public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate)
    241        {
    242            return true;
    243        }
    244
    245        /**
    246         * Unloads the 100 oldest chunks from memory, due to a bug with chunkSet.add() never being called it thinks the list
    247         * is always empty and will not remove any chunks.
    248         */
    249        public boolean unload100OldestChunks()
    250        {
    251            return false;
    252        }
    253
    254        /**
    255         * Returns if the IChunkProvider supports saving.
    256         */
    257        public boolean canSave()
    258        {
    259            return true;
    260        }
    261
    262        /**
    263         * Converts the instance data to a readable string.
    264         */
    265        public String makeString()
    266        {
    267            return "FlatLevelSource";
    268        }
    269
    270        /**
    271         * Returns a list of creatures of the specified type that can spawn at the given location.
    272         */
    273        public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4)
    274        {
    275            BiomeGenBase var5 = this.worldObj.getBiomeGenForCoords(par2, par4);
    276            return var5 == null ? null : var5.getSpawnableList(par1EnumCreatureType);
    277        }
    278
    279        /**
    280         * Returns the location of the closest structure of the specified type. If not found returns null.
    281         */
    282        public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5)
    283        {
    284            if ("Stronghold".equals(par2Str))
    285            {
    286                Iterator var6 = this.field_82696_f.iterator();
    287
    288                while (var6.hasNext())
    289                {
    290                    MapGenStructure var7 = (MapGenStructure)var6.next();
    291
    292                    if (var7 instanceof MapGenStronghold)
    293                    {
    294                        return var7.getNearestInstance(par1World, par3, par4, par5);
    295                    }
    296                }
    297            }
    298
    299            return null;
    300        }
    301
    302        public int getLoadedChunkCount()
    303        {
    304            return 0;
    305        }
    306
    307        public void recreateStructures(int par1, int par2)
    308        {
    309            Iterator var3 = this.field_82696_f.iterator();
    310
    311            while (var3.hasNext())
    312            {
    313                MapGenStructure var4 = (MapGenStructure)var3.next();
    314                var4.generate(this, this.worldObj, par1, par2, (byte[])null);
    315            }
    316        }
    317    }