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}