    001package net.minecraft.world.gen;
    002
    003import java.util.ArrayList;
    004import java.util.Iterator;
    005import java.util.List;
    006import java.util.Map;
    007import java.util.Random;
    008import net.minecraft.block.Block;
    009import net.minecraft.entity.EnumCreatureType;
    010import net.minecraft.util.IProgressUpdate;
    011import net.minecraft.world.ChunkPosition;
    012import net.minecraft.world.World;
    013import net.minecraft.world.biome.BiomeGenBase;
    014import net.minecraft.world.chunk.Chunk;
    015import net.minecraft.world.chunk.IChunkProvider;
    016import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
    017import net.minecraft.world.gen.feature.MapGenScatteredFeature;
    018import net.minecraft.world.gen.feature.WorldGenDungeons;
    019import net.minecraft.world.gen.feature.WorldGenLakes;
    020import net.minecraft.world.gen.structure.MapGenMineshaft;
    021import net.minecraft.world.gen.structure.MapGenStronghold;
    022import net.minecraft.world.gen.structure.MapGenStructure;
    023import net.minecraft.world.gen.structure.MapGenVillage;
    024
    025public 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 structureGenerators = new ArrayList();
    033    private final boolean field_82697_g;
    034    private final boolean field_82702_h;
    035    private WorldGenLakes waterLakeGenerator;
    036    private WorldGenLakes lavaLakeGenerator;
    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.structureGenerators.add(new MapGenVillage(var7));
    058            }
    059
    060            if (var6.containsKey("biome_1"))
    061            {
    062                this.structureGenerators.add(new MapGenScatteredFeature((Map)var6.get("biome_1")));
    063            }
    064
    065            if (var6.containsKey("mineshaft"))
    066            {
    067                this.structureGenerators.add(new MapGenMineshaft((Map)var6.get("mineshaft")));
    068            }
    069
    070            if (var6.containsKey("stronghold"))
    071            {
    072                this.structureGenerators.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.waterLakeGenerator = new WorldGenLakes(Block.waterStill.blockID);
    081        }
    082
    083        if (this.field_82699_e.getWorldFeatures().containsKey("lava_lake"))
    084        {
    085            this.lavaLakeGenerator = 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.structureGenerators.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.structureGenerators.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.waterLakeGenerator != 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.waterLakeGenerator.generate(this.worldObj, this.random, var16, var17, var18);
    205        }
    206
    207        if (this.lavaLakeGenerator != 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.lavaLakeGenerator.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.structureGenerators.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.structureGenerators.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}