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