001 package net.minecraft.world.biome; 002 003 import cpw.mods.fml.relauncher.Side; 004 import cpw.mods.fml.relauncher.SideOnly; 005 import java.util.ArrayList; 006 import java.util.Arrays; 007 import java.util.List; 008 import java.util.Random; 009 import net.minecraft.world.ChunkPosition; 010 import net.minecraft.world.World; 011 import net.minecraft.world.WorldType; 012 import net.minecraft.world.gen.layer.GenLayer; 013 import net.minecraft.world.gen.layer.IntCache; 014 015 import net.minecraftforge.common.*; 016 import net.minecraftforge.event.terraingen.*; 017 import static net.minecraft.world.biome.BiomeGenBase.*; 018 019 public class WorldChunkManager 020 { 021 public static ArrayList<BiomeGenBase> allowedBiomes = new ArrayList<BiomeGenBase>(Arrays.asList(forest, plains, taiga, taigaHills, forestHills, jungle. jungleHills)); 022 private GenLayer genBiomes; 023 024 /** A GenLayer containing the indices into BiomeGenBase.biomeList[] */ 025 private GenLayer biomeIndexLayer; 026 027 /** The BiomeCache object for this world. */ 028 private BiomeCache biomeCache; 029 030 /** A list of biomes that the player can spawn in. */ 031 private List biomesToSpawnIn; 032 033 protected WorldChunkManager() 034 { 035 this.biomeCache = new BiomeCache(this); 036 this.biomesToSpawnIn = new ArrayList(); 037 this.biomesToSpawnIn.addAll(allowedBiomes); 038 } 039 040 public WorldChunkManager(long par1, WorldType par3WorldType) 041 { 042 this(); 043 GenLayer[] var4 = GenLayer.initializeAllBiomeGenerators(par1, par3WorldType); 044 var4 = getModdedBiomeGenerators(par3WorldType, par1, var4); 045 this.genBiomes = var4[0]; 046 this.biomeIndexLayer = var4[1]; 047 } 048 049 public WorldChunkManager(World par1World) 050 { 051 this(par1World.getSeed(), par1World.getWorldInfo().getTerrainType()); 052 } 053 054 /** 055 * Gets the list of valid biomes for the player to spawn in. 056 */ 057 public List getBiomesToSpawnIn() 058 { 059 return this.biomesToSpawnIn; 060 } 061 062 /** 063 * Returns the BiomeGenBase related to the x, z position on the world. 064 */ 065 public BiomeGenBase getBiomeGenAt(int par1, int par2) 066 { 067 return this.biomeCache.getBiomeGenAt(par1, par2); 068 } 069 070 /** 071 * Returns a list of rainfall values for the specified blocks. Args: listToReuse, x, z, width, length. 072 */ 073 public float[] getRainfall(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5) 074 { 075 IntCache.resetIntCache(); 076 077 if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) 078 { 079 par1ArrayOfFloat = new float[par4 * par5]; 080 } 081 082 int[] var6 = this.biomeIndexLayer.getInts(par2, par3, par4, par5); 083 084 for (int var7 = 0; var7 < par4 * par5; ++var7) 085 { 086 float var8 = (float)BiomeGenBase.biomeList[var6[var7]].getIntRainfall() / 65536.0F; 087 088 if (var8 > 1.0F) 089 { 090 var8 = 1.0F; 091 } 092 093 par1ArrayOfFloat[var7] = var8; 094 } 095 096 return par1ArrayOfFloat; 097 } 098 099 @SideOnly(Side.CLIENT) 100 101 /** 102 * Return an adjusted version of a given temperature based on the y height 103 */ 104 public float getTemperatureAtHeight(float par1, int par2) 105 { 106 return par1; 107 } 108 109 /** 110 * Returns a list of temperatures to use for the specified blocks. Args: listToReuse, x, y, width, length 111 */ 112 public float[] getTemperatures(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5) 113 { 114 IntCache.resetIntCache(); 115 116 if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) 117 { 118 par1ArrayOfFloat = new float[par4 * par5]; 119 } 120 121 int[] var6 = this.biomeIndexLayer.getInts(par2, par3, par4, par5); 122 123 for (int var7 = 0; var7 < par4 * par5; ++var7) 124 { 125 float var8 = (float)BiomeGenBase.biomeList[var6[var7]].getIntTemperature() / 65536.0F; 126 127 if (var8 > 1.0F) 128 { 129 var8 = 1.0F; 130 } 131 132 par1ArrayOfFloat[var7] = var8; 133 } 134 135 return par1ArrayOfFloat; 136 } 137 138 /** 139 * Returns an array of biomes for the location input. 140 */ 141 public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5) 142 { 143 IntCache.resetIntCache(); 144 145 if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) 146 { 147 par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5]; 148 } 149 150 int[] var6 = this.genBiomes.getInts(par2, par3, par4, par5); 151 152 for (int var7 = 0; var7 < par4 * par5; ++var7) 153 { 154 par1ArrayOfBiomeGenBase[var7] = BiomeGenBase.biomeList[var6[var7]]; 155 } 156 157 return par1ArrayOfBiomeGenBase; 158 } 159 160 /** 161 * Returns biomes to use for the blocks and loads the other data like temperature and humidity onto the 162 * WorldChunkManager Args: oldBiomeList, x, z, width, depth 163 */ 164 public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5) 165 { 166 return this.getBiomeGenAt(par1ArrayOfBiomeGenBase, par2, par3, par4, par5, true); 167 } 168 169 /** 170 * Return a list of biomes for the specified blocks. Args: listToReuse, x, y, width, length, cacheFlag (if false, 171 * don't check biomeCache to avoid infinite loop in BiomeCacheBlock) 172 */ 173 public BiomeGenBase[] getBiomeGenAt(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5, boolean par6) 174 { 175 IntCache.resetIntCache(); 176 177 if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) 178 { 179 par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5]; 180 } 181 182 if (par6 && par4 == 16 && par5 == 16 && (par2 & 15) == 0 && (par3 & 15) == 0) 183 { 184 BiomeGenBase[] var9 = this.biomeCache.getCachedBiomes(par2, par3); 185 System.arraycopy(var9, 0, par1ArrayOfBiomeGenBase, 0, par4 * par5); 186 return par1ArrayOfBiomeGenBase; 187 } 188 else 189 { 190 int[] var7 = this.biomeIndexLayer.getInts(par2, par3, par4, par5); 191 192 for (int var8 = 0; var8 < par4 * par5; ++var8) 193 { 194 par1ArrayOfBiomeGenBase[var8] = BiomeGenBase.biomeList[var7[var8]]; 195 } 196 197 return par1ArrayOfBiomeGenBase; 198 } 199 } 200 201 /** 202 * checks given Chunk's Biomes against List of allowed ones 203 */ 204 public boolean areBiomesViable(int par1, int par2, int par3, List par4List) 205 { 206 IntCache.resetIntCache(); 207 int var5 = par1 - par3 >> 2; 208 int var6 = par2 - par3 >> 2; 209 int var7 = par1 + par3 >> 2; 210 int var8 = par2 + par3 >> 2; 211 int var9 = var7 - var5 + 1; 212 int var10 = var8 - var6 + 1; 213 int[] var11 = this.genBiomes.getInts(var5, var6, var9, var10); 214 215 for (int var12 = 0; var12 < var9 * var10; ++var12) 216 { 217 BiomeGenBase var13 = BiomeGenBase.biomeList[var11[var12]]; 218 219 if (!par4List.contains(var13)) 220 { 221 return false; 222 } 223 } 224 225 return true; 226 } 227 228 /** 229 * Finds a valid position within a range, that is in one of the listed biomes. Searches {par1,par2} +-par3 blocks. 230 * Strongly favors positive y positions. 231 */ 232 public ChunkPosition findBiomePosition(int par1, int par2, int par3, List par4List, Random par5Random) 233 { 234 IntCache.resetIntCache(); 235 int var6 = par1 - par3 >> 2; 236 int var7 = par2 - par3 >> 2; 237 int var8 = par1 + par3 >> 2; 238 int var9 = par2 + par3 >> 2; 239 int var10 = var8 - var6 + 1; 240 int var11 = var9 - var7 + 1; 241 int[] var12 = this.genBiomes.getInts(var6, var7, var10, var11); 242 ChunkPosition var13 = null; 243 int var14 = 0; 244 245 for (int var15 = 0; var15 < var10 * var11; ++var15) 246 { 247 int var16 = var6 + var15 % var10 << 2; 248 int var17 = var7 + var15 / var10 << 2; 249 BiomeGenBase var18 = BiomeGenBase.biomeList[var12[var15]]; 250 251 if (par4List.contains(var18) && (var13 == null || par5Random.nextInt(var14 + 1) == 0)) 252 { 253 var13 = new ChunkPosition(var16, 0, var17); 254 ++var14; 255 } 256 } 257 258 return var13; 259 } 260 261 /** 262 * Calls the WorldChunkManager's biomeCache.cleanupCache() 263 */ 264 public void cleanupCache() 265 { 266 this.biomeCache.cleanupCache(); 267 } 268 269 public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original) 270 { 271 WorldTypeEvent.InitBiomeGens event = new WorldTypeEvent.InitBiomeGens(worldType, seed, original); 272 MinecraftForge.TERRAIN_GEN_BUS.post(event); 273 return event.newBiomeGens; 274 } 275 }