    001package net.minecraftforge.common;
    002
    003import java.util.*;
    004import net.minecraft.world.biome.*;
    005import static net.minecraft.world.biome.BiomeGenBase.*;
    006import static net.minecraftforge.common.BiomeDictionary.Type.*;
    007
    008public class BiomeDictionary
    009{
    010    public enum Type
    011    {
    012        FOREST,
    013        PLAINS,
    014        MOUNTAIN,
    015        HILLS,
    016        SWAMP,
    017        WATER,
    018        DESERT,
    019        FROZEN,
    020        JUNGLE,
    021        WASTELAND,
    022        BEACH,
    023        NETHER,
    024        END,
    025        MUSHROOM,
    026        MAGICAL;
    027    }
    028
    029    private static final int BIOME_LIST_SIZE = 256;
    030    private static BiomeInfo[] biomeList = new BiomeInfo[BIOME_LIST_SIZE];
    031    private static ArrayList<BiomeGenBase>[] typeInfoList = new ArrayList[Type.values().length];
    032
    033    private static class BiomeInfo
    034    {
    035        public EnumSet<Type> typeList;
    036
    037        public BiomeInfo(Type[] types)
    038        {
    039            typeList = EnumSet.noneOf(Type.class);
    040            for(Type t : types)
    041            {
    042                typeList.add(t);
    043            }
    044        }
    045    }
    046
    047    static
    048    {
    049        registerVanillaBiomes();
    050    }
    051
    052    /**
    053     * Registers a biome with a specific biome type
    054     *
    055     * @param biome the biome to be registered
    056     * @param type the type to register the biome as
    057     * @return returns true if the biome was registered successfully
    058     */
    059    public static boolean registerBiomeType(BiomeGenBase biome, Type ... types)
    060    {
    061        if(BiomeGenBase.biomeList[biome.biomeID] != null)
    062        {
    063            for(Type type : types)
    064            {
    065                if(typeInfoList[type.ordinal()] == null)
    066                {
    067                    typeInfoList[type.ordinal()] = new ArrayList<BiomeGenBase>();
    068                }
    069
    070                typeInfoList[type.ordinal()].add(biome);
    071            }
    072
    073            if(biomeList[biome.biomeID] == null)
    074            {
    075                biomeList[biome.biomeID] = new BiomeInfo(types);
    076            }
    077            else
    078            {
    079                for(Type type : types)
    080                {
    081                    biomeList[biome.biomeID].typeList.add(type);
    082                }
    083            }
    084
    085            return true;
    086        }
    087
    088        return false;
    089    }
    090
    091    /**
    092     * Returns a list of biomes registered with a specific type
    093     *
    094     * @param type the Type to look for
    095     * @return a list of biomes of the specified type, null if there are none
    096     */
    097    public static BiomeGenBase[] getBiomesForType(Type type)
    098    {
    099        if(typeInfoList[type.ordinal()] != null)
    100        {
    101            return (BiomeGenBase[])typeInfoList[type.ordinal()].toArray(new BiomeGenBase[0]);
    102        }
    103
    104        return new BiomeGenBase[0];
    105    }
    106
    107    /**
    108     * Gets a list of Types that a specific biome is registered with
    109     *
    110     * @param biome the biome to check
    111     * @return the list of types, null if there are none
    112     */
    113    public static Type[] getTypesForBiome(BiomeGenBase biome)
    114    {
    115        checkRegistration(biome);
    116
    117        if(biomeList[biome.biomeID] != null)
    118        {
    119            return (Type[])biomeList[biome.biomeID].typeList.toArray(new Type[0]);
    120        }
    121
    122        return new Type[0];
    123    }
    124
    125    /**
    126     * Checks to see if two biomes are registered as having the same type
    127     *
    128     * @param biomeA
    129     * @param biomeB
    130     * @return returns true if a common type is found, false otherwise
    131     */
    132    public static boolean areBiomesEquivalent(BiomeGenBase biomeA, BiomeGenBase biomeB)
    133    {
    134        int a = biomeA.biomeID;
    135        int b = biomeB.biomeID;
    136
    137        checkRegistration(biomeA);
    138        checkRegistration(biomeB);
    139
    140        if(biomeList[a] != null && biomeList[b] != null)
    141        {
    142            for(Type type : biomeList[a].typeList)
    143            {
    144                if(containsType(biomeList[b], type))
    145                {
    146                    return true;
    147                }
    148            }
    149        }
    150
    151        return false;
    152    }
    153
    154    /**
    155     * Checks to see if the given biome is registered as being a specific type
    156     *
    157     * @param biome the biome to be considered
    158     * @param type the type to check for
    159     * @return returns true if the biome is registered as being of type type, false otherwise
    160     */
    161    public static boolean isBiomeOfType(BiomeGenBase biome, Type type)
    162    {
    163        checkRegistration(biome);
    164
    165        if(biomeList[biome.biomeID] != null)
    166        {
    167            return containsType(biomeList[biome.biomeID], type);
    168        }
    169
    170        return false;
    171    }
    172
    173    /**
    174     * Checks to see if the given biome has been registered as being of any type
    175     * @param biome the biome to consider
    176     * @return returns true if the biome has been registered, false otherwise
    177     */
    178    public static boolean isBiomeRegistered(BiomeGenBase biome)
    179    {
    180        return biomeList[biome.biomeID] != null;
    181    }
    182
    183    public static boolean isBiomeRegistered(int biomeID)
    184    {
    185        return biomeList[biomeID] != null;
    186    }
    187
    188    /**
    189     * Loops through the biome list and automatically adds tags to any biome that does not have any
    190     * This should be called in postInit to make sure all biomes have been registered
    191     *
    192     * DO NOT call this during world generation
    193     */
    194    public static void registerAllBiomes()
    195    {
    196        for(int i = 0; i < BIOME_LIST_SIZE; i++)
    197        {
    198            if(BiomeGenBase.biomeList[i] != null)
    199            {
    200                checkRegistration(BiomeGenBase.biomeList[i]);
    201            }
    202        }
    203    }
    204
    205    /**
    206     * Automatically looks for and registers a given biome with appropriate tags
    207     * This method is called automatically if a biome has not been registered with any tags,
    208     * And another method requests information about it
    209     *
    210     * NOTE: You can opt out of having your biome registered by registering it as type NULL
    211     *
    212     * @param biome the biome to be considered
    213     */
    214    public static void makeBestGuess(BiomeGenBase biome)
    215    {
    216        if(biome.theBiomeDecorator.treesPerChunk >= 3)
    217        {
    218            if(biome.isHighHumidity() && biome.temperature >= 1.0F)
    219            {
    220                BiomeDictionary.registerBiomeType(biome, JUNGLE);
    221            }
    222            else if(!biome.isHighHumidity())
    223            {
    224                BiomeDictionary.registerBiomeType(biome, FOREST);
    225            }
    226        }
    227        else if(biome.maxHeight <= 0.3F && biome.maxHeight >= 0.0F)
    228        {
    229            if(!biome.isHighHumidity() || biome.minHeight >= 0.0F)
    230            {
    231                BiomeDictionary.registerBiomeType(biome, PLAINS);
    232            }
    233        }
    234
    235        if(biome.isHighHumidity() && biome.minHeight < 0.0F && (biome.maxHeight <= 0.3F && biome.maxHeight >= 0.0F))
    236        {
    237            BiomeDictionary.registerBiomeType(biome, SWAMP);
    238        }
    239
    240        if(biome.minHeight <= -0.5F)
    241        {
    242            BiomeDictionary.registerBiomeType(biome, WATER);
    243        }
    244
    245        if(biome.maxHeight >= 1.5F)
    246        {
    247            BiomeDictionary.registerBiomeType(biome, MOUNTAIN);
    248        }
    249
    250        if(biome.getEnableSnow() || biome.temperature < 0.2F)
    251        {
    252            BiomeDictionary.registerBiomeType(biome, FROZEN);
    253        }
    254
    255        if(!biome.isHighHumidity() && biome.temperature >= 1.0F)
    256        {
    257            BiomeDictionary.registerBiomeType(biome, DESERT);
    258        }
    259    }
    260
    261    //Internal implementation
    262    private static void checkRegistration(BiomeGenBase biome)
    263    {
    264        if(!isBiomeRegistered(biome))
    265        {
    266            makeBestGuess(biome);
    267        }
    268    }
    269
    270    private static boolean containsType(BiomeInfo info, Type type)
    271    {
    272        return info.typeList.contains(type);
    273    }
    274
    275    private static void registerVanillaBiomes()
    276    {
    277        registerBiomeType(ocean,               WATER          );
    278        registerBiomeType(plains,              PLAINS         );
    279        registerBiomeType(desert,              DESERT         );
    280        registerBiomeType(extremeHills,        MOUNTAIN       );
    281        registerBiomeType(forest,              FOREST         );
    282        registerBiomeType(taiga,               FOREST,  FROZEN);
    283        registerBiomeType(taigaHills,          FOREST,  FROZEN);
    284        registerBiomeType(swampland,           SWAMP          );
    285        registerBiomeType(river,               WATER          );
    286        registerBiomeType(frozenOcean,         WATER,   FROZEN);
    287        registerBiomeType(frozenRiver,         WATER,   FROZEN);
    288        registerBiomeType(icePlains,           FROZEN         );
    289        registerBiomeType(iceMountains,        FROZEN         );
    290        registerBiomeType(beach,               BEACH          );
    291        registerBiomeType(desertHills,         DESERT         );
    292        registerBiomeType(jungle,              JUNGLE         );
    293        registerBiomeType(jungleHills,         JUNGLE         );
    294        registerBiomeType(forestHills,         FOREST         );
    295        registerBiomeType(sky,                 END            );
    296        registerBiomeType(hell,                NETHER         );
    297        registerBiomeType(mushroomIsland,      MUSHROOM       );
    298        registerBiomeType(extremeHillsEdge,    MOUNTAIN       );
    299        registerBiomeType(mushroomIslandShore, MUSHROOM, BEACH);
    300    }
    301}