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    }