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 }