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 }