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.func_82651_a(par5Str);
027
028 if (par4)
029 {
030 Map var6 = this.field_82699_e.func_82644_b();
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.func_82644_b().containsKey("decoration");
061
062 if (this.field_82699_e.func_82644_b().containsKey("lake"))
063 {
064 this.field_82703_i = new WorldGenLakes(Block.waterStill.blockID);
065 }
066
067 if (this.field_82699_e.func_82644_b().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.func_82644_b().containsKey("dungeon");
073 Iterator var9 = this.field_82699_e.func_82650_c().iterator();
074
075 while (var9.hasNext())
076 {
077 FlatLayerInfo var10 = (FlatLayerInfo)var9.next();
078
079 for (int var8 = var10.func_82656_d(); var8 < var10.func_82656_d() + var10.func_82657_a(); ++var8)
080 {
081 this.field_82700_c[var8] = (byte)(var10.func_82659_b() & 255);
082 this.field_82698_d[var8] = (byte)var10.func_82658_c();
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 func_82695_e(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 }