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