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}