    001package net.minecraft.client.multiplayer;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.ArrayList;
    006import java.util.List;
    007import net.minecraft.entity.EnumCreatureType;
    008import net.minecraft.util.IProgressUpdate;
    009import net.minecraft.util.LongHashMap;
    010import net.minecraft.world.ChunkCoordIntPair;
    011import net.minecraft.world.ChunkPosition;
    012import net.minecraft.world.World;
    013import net.minecraft.world.chunk.Chunk;
    014import net.minecraft.world.chunk.EmptyChunk;
    015import net.minecraft.world.chunk.IChunkProvider;
    016import net.minecraftforge.common.MinecraftForge;
    017import net.minecraftforge.event.world.ChunkEvent;
    018
    019@SideOnly(Side.CLIENT)
    020public class ChunkProviderClient implements IChunkProvider
    021{
    022    /**
    023     * The completely empty chunk used by ChunkProviderClient when chunkMapping doesn't contain the requested
    024     * coordinates.
    025     */
    026    private Chunk blankChunk;
    027
    028    /**
    029     * The mapping between ChunkCoordinates and Chunks that ChunkProviderClient maintains.
    030     */
    031    private LongHashMap chunkMapping = new LongHashMap();
    032
    033    /**
    034     * This may have been intended to be an iterable version of all currently loaded chunks (MultiplayerChunkCache),
    035     * with identical contents to chunkMapping's values. However it is never actually added to.
    036     */
    037    private List chunkListing = new ArrayList();
    038
    039    /** Reference to the World object. */
    040    private World worldObj;
    041
    042    public ChunkProviderClient(World par1World)
    043    {
    044        this.blankChunk = new EmptyChunk(par1World, 0, 0);
    045        this.worldObj = par1World;
    046    }
    047
    048    /**
    049     * Checks to see if a chunk exists at x, y
    050     */
    051    public boolean chunkExists(int par1, int par2)
    052    {
    053        return true;
    054    }
    055
    056    /**
    057     * Unload chunk from ChunkProviderClient's hashmap. Called in response to a Packet50PreChunk with its mode field set
    058     * to false
    059     */
    060    public void unloadChunk(int par1, int par2)
    061    {
    062        Chunk var3 = this.provideChunk(par1, par2);
    063
    064        if (!var3.isEmpty())
    065        {
    066            var3.onChunkUnload();
    067        }
    068
    069        this.chunkMapping.remove(ChunkCoordIntPair.chunkXZ2Int(par1, par2));
    070        this.chunkListing.remove(var3);
    071    }
    072
    073    /**
    074     * loads or generates the chunk at the chunk location specified
    075     */
    076    public Chunk loadChunk(int par1, int par2)
    077    {
    078        Chunk var3 = new Chunk(this.worldObj, par1, par2);
    079        this.chunkMapping.add(ChunkCoordIntPair.chunkXZ2Int(par1, par2), var3);
    080        MinecraftForge.EVENT_BUS.post(new ChunkEvent.Load(var3));
    081        var3.isChunkLoaded = true;
    082        return var3;
    083    }
    084
    085    /**
    086     * Will return back a chunk, if it doesn't exist and its not a MP client it will generates all the blocks for the
    087     * specified chunk from the map seed and chunk seed
    088     */
    089    public Chunk provideChunk(int par1, int par2)
    090    {
    091        Chunk var3 = (Chunk)this.chunkMapping.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(par1, par2));
    092        return var3 == null ? this.blankChunk : var3;
    093    }
    094
    095    /**
    096     * Two modes of operation: if passed true, save all Chunks in one go.  If passed false, save up to two chunks.
    097     * Return true if all chunks have been saved.
    098     */
    099    public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate)
    100    {
    101        return true;
    102    }
    103
    104    /**
    105     * Unloads the 100 oldest chunks from memory, due to a bug with chunkSet.add() never being called it thinks the list
    106     * is always empty and will not remove any chunks.
    107     */
    108    public boolean unload100OldestChunks()
    109    {
    110        return false;
    111    }
    112
    113    /**
    114     * Returns if the IChunkProvider supports saving.
    115     */
    116    public boolean canSave()
    117    {
    118        return false;
    119    }
    120
    121    /**
    122     * Populates chunk with ores etc etc
    123     */
    124    public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) {}
    125
    126    /**
    127     * Converts the instance data to a readable string.
    128     */
    129    public String makeString()
    130    {
    131        return "MultiplayerChunkCache: " + this.chunkMapping.getNumHashElements();
    132    }
    133
    134    /**
    135     * Returns a list of creatures of the specified type that can spawn at the given location.
    136     */
    137    public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4)
    138    {
    139        return null;
    140    }
    141
    142    /**
    143     * Returns the location of the closest structure of the specified type. If not found returns null.
    144     */
    145    public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5)
    146    {
    147        return null;
    148    }
    149
    150    public int getLoadedChunkCount()
    151    {
    152        return this.chunkListing.size();
    153    }
    154
    155    public void recreateStructures(int par1, int par2) {}
    156}