package net.minecraft.world.gen;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.util.IProgressUpdate;
import net.minecraft.world.ChunkPosition;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.gen.feature.MapGenScatteredFeature;
import net.minecraft.world.gen.feature.WorldGenDungeons;
import net.minecraft.world.gen.feature.WorldGenLakes;
import net.minecraft.world.gen.structure.MapGenMineshaft;
import net.minecraft.world.gen.structure.MapGenStronghold;
import net.minecraft.world.gen.structure.MapGenStructure;
import net.minecraft.world.gen.structure.MapGenVillage;
public class ChunkProviderFlat implements IChunkProvider
{
private World worldObj;
private Random random;
private final byte[] field_82700_c = new byte[256];
private final byte[] field_82698_d = new byte[256];
private final FlatGeneratorInfo field_82699_e;
private final List structureGenerators = new ArrayList();
private final boolean field_82697_g;
private final boolean field_82702_h;
private WorldGenLakes waterLakeGenerator;
private WorldGenLakes lavaLakeGenerator;
public ChunkProviderFlat(World par1World, long par2, boolean par4, String par5Str)
{
this.worldObj = par1World;
this.random = new Random(par2);
this.field_82699_e = FlatGeneratorInfo.createFlatGeneratorFromString(par5Str);
if (par4)
{
Map map = this.field_82699_e.getWorldFeatures();
if (map.containsKey("village"))
{
Map map1 = (Map)map.get("village");
if (!map1.containsKey("size"))
{
map1.put("size", "1");
}
this.structureGenerators.add(new MapGenVillage(map1));
}
if (map.containsKey("biome_1"))
{
this.structureGenerators.add(new MapGenScatteredFeature((Map)map.get("biome_1")));
}
if (map.containsKey("mineshaft"))
{
this.structureGenerators.add(new MapGenMineshaft((Map)map.get("mineshaft")));
}
if (map.containsKey("stronghold"))
{
this.structureGenerators.add(new MapGenStronghold((Map)map.get("stronghold")));
}
}
this.field_82697_g = this.field_82699_e.getWorldFeatures().containsKey("decoration");
if (this.field_82699_e.getWorldFeatures().containsKey("lake"))
{
this.waterLakeGenerator = new WorldGenLakes(Block.waterStill.blockID);
}
if (this.field_82699_e.getWorldFeatures().containsKey("lava_lake"))
{
this.lavaLakeGenerator = new WorldGenLakes(Block.lavaStill.blockID);
}
this.field_82702_h = this.field_82699_e.getWorldFeatures().containsKey("dungeon");
Iterator iterator = this.field_82699_e.getFlatLayers().iterator();
while (iterator.hasNext())
{
FlatLayerInfo flatlayerinfo = (FlatLayerInfo)iterator.next();
for (int j = flatlayerinfo.getMinY(); j < flatlayerinfo.getMinY() + flatlayerinfo.getLayerCount(); ++j)
{
this.field_82700_c[j] = (byte)(flatlayerinfo.getFillBlock() & 255);
this.field_82698_d[j] = (byte)flatlayerinfo.getFillBlockMeta();
}
}
}
/**
* loads or generates the chunk at the chunk location specified
*/
public Chunk loadChunk(int par1, int par2)
{
return this.provideChunk(par1, par2);
}
/**
* Will return back a chunk, if it doesn't exist and its not a MP client it will generates all the blocks for the
* specified chunk from the map seed and chunk seed
*/
public Chunk provideChunk(int par1, int par2)
{
Chunk chunk = new Chunk(this.worldObj, par1, par2);
for (int k = 0; k < this.field_82700_c.length; ++k)
{
int l = k >> 4;
ExtendedBlockStorage extendedblockstorage = chunk.getBlockStorageArray()[l];
if (extendedblockstorage == null)
{
extendedblockstorage = new ExtendedBlockStorage(k, !this.worldObj.provider.hasNoSky);
chunk.getBlockStorageArray()[l] = extendedblockstorage;
}
for (int i1 = 0; i1 < 16; ++i1)
{
for (int j1 = 0; j1 < 16; ++j1)
{
extendedblockstorage.setExtBlockID(i1, k & 15, j1, this.field_82700_c[k] & 255);
extendedblockstorage.setExtBlockMetadata(i1, k & 15, j1, this.field_82698_d[k]);
}
}
}
chunk.generateSkylightMap();
BiomeGenBase[] abiomegenbase = this.worldObj.getWorldChunkManager().loadBlockGeneratorData((BiomeGenBase[])null, par1 * 16, par2 * 16, 16, 16);
byte[] abyte = chunk.getBiomeArray();
for (int k1 = 0; k1 < abyte.length; ++k1)
{
abyte[k1] = (byte)abiomegenbase[k1].biomeID;
}
Iterator iterator = this.structureGenerators.iterator();
while (iterator.hasNext())
{
MapGenStructure mapgenstructure = (MapGenStructure)iterator.next();
mapgenstructure.generate(this, this.worldObj, par1, par2, (byte[])null);
}
chunk.generateSkylightMap();
return chunk;
}
/**
* Checks to see if a chunk exists at x, y
*/
public boolean chunkExists(int par1, int par2)
{
return true;
}
/**
* Populates chunk with ores etc etc
*/
public void populate(IChunkProvider par1IChunkProvider, int par2, int par3)
{
int k = par2 * 16;
int l = par3 * 16;
BiomeGenBase biomegenbase = this.worldObj.getBiomeGenForCoords(k + 16, l + 16);
boolean flag = false;
this.random.setSeed(this.worldObj.getSeed());
long i1 = this.random.nextLong() / 2L * 2L + 1L;
long j1 = this.random.nextLong() / 2L * 2L + 1L;
this.random.setSeed((long)par2 * i1 + (long)par3 * j1 ^ this.worldObj.getSeed());
Iterator iterator = this.structureGenerators.iterator();
while (iterator.hasNext())
{
MapGenStructure mapgenstructure = (MapGenStructure)iterator.next();
boolean flag1 = mapgenstructure.generateStructuresInChunk(this.worldObj, this.random, par2, par3);
if (mapgenstructure instanceof MapGenVillage)
{
flag |= flag1;
}
}
int k1;
int l1;
int i2;
if (this.waterLakeGenerator != null && !flag && this.random.nextInt(4) == 0)
{
l1 = k + this.random.nextInt(16) + 8;
k1 = this.random.nextInt(128);
i2 = l + this.random.nextInt(16) + 8;
this.waterLakeGenerator.generate(this.worldObj, this.random, l1, k1, i2);
}
if (this.lavaLakeGenerator != null && !flag && this.random.nextInt(8) == 0)
{
l1 = k + this.random.nextInt(16) + 8;
k1 = this.random.nextInt(this.random.nextInt(120) + 8);
i2 = l + this.random.nextInt(16) + 8;
if (k1 < 63 || this.random.nextInt(10) == 0)
{
this.lavaLakeGenerator.generate(this.worldObj, this.random, l1, k1, i2);
}
}
if (this.field_82702_h)
{
for (l1 = 0; l1 < 8; ++l1)
{
k1 = k + this.random.nextInt(16) + 8;
i2 = this.random.nextInt(128);
int j2 = l + this.random.nextInt(16) + 8;
(new WorldGenDungeons()).generate(this.worldObj, this.random, k1, i2, j2);
}
}
if (this.field_82697_g)
{
biomegenbase.decorate(this.worldObj, this.random, k, l);
}
}
/**
* Two modes of operation: if passed true, save all Chunks in one go. If passed false, save up to two chunks.
* Return true if all chunks have been saved.
*/
public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate)
{
return true;
}
public void func_104112_b() {}
/**
* Unloads chunks that are marked to be unloaded. This is not guaranteed to unload every such chunk.
*/
public boolean unloadQueuedChunks()
{
return false;
}
/**
* Returns if the IChunkProvider supports saving.
*/
public boolean canSave()
{
return true;
}
/**
* Converts the instance data to a readable string.
*/
public String makeString()
{
return "FlatLevelSource";
}
/**
* Returns a list of creatures of the specified type that can spawn at the given location.
*/
public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4)
{
BiomeGenBase biomegenbase = this.worldObj.getBiomeGenForCoords(par2, par4);
return biomegenbase == null ? null : biomegenbase.getSpawnableList(par1EnumCreatureType);
}
/**
* Returns the location of the closest structure of the specified type. If not found returns null.
*/
public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5)
{
if ("Stronghold".equals(par2Str))
{
Iterator iterator = this.structureGenerators.iterator();
while (iterator.hasNext())
{
MapGenStructure mapgenstructure = (MapGenStructure)iterator.next();
if (mapgenstructure instanceof MapGenStronghold)
{
return mapgenstructure.getNearestInstance(par1World, par3, par4, par5);
}
}
}
return null;
}
public int getLoadedChunkCount()
{
return 0;
}
public void recreateStructures(int par1, int par2)
{
Iterator iterator = this.structureGenerators.iterator();
while (iterator.hasNext())
{
MapGenStructure mapgenstructure = (MapGenStructure)iterator.next();
mapgenstructure.generate(this, this.worldObj, par1, par2, (byte[])null);
}
}
}