    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    }