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