2013-04-04 17:55:35 -07:00
package net.minecraftforge.common ;
import java.util.* ;
2013-09-05 10:08:02 -04:00
2014-11-25 19:56:35 -08:00
import net.minecraftforge.fml.common.FMLLog ;
2014-07-01 12:46:00 +10:00
import net.minecraft.init.Blocks ;
2013-04-04 17:55:35 -07:00
import net.minecraft.world.biome.* ;
2014-07-07 21:29:37 -07:00
import net.minecraftforge.common.util.EnumHelper ;
2013-09-05 10:08:02 -04:00
import net.minecraftforge.event.terraingen.DeferredBiomeDecorator ;
2013-04-04 17:55:35 -07:00
import static net.minecraft.world.biome.BiomeGenBase.* ;
import static net.minecraftforge.common.BiomeDictionary.Type.* ;
public class BiomeDictionary
{
public enum Type
{
2014-07-01 12:46:00 +10:00
/*Temperature-based tags. Specifying neither implies a biome is temperate*/
HOT ,
COLD ,
/*Tags specifying the amount of vegetation a biome has. Specifying neither implies a biome to have moderate amounts*/
SPARSE ,
DENSE ,
/*Tags specifying how moist a biome is. Specifying neither implies the biome as having moderate humidity*/
WET ,
DRY ,
/*Tree-based tags, SAVANNA refers to dry, desert-like trees (Such as Acacia), CONIFEROUS refers to snowy trees (Such as Spruce) and JUNGLE refers to jungle trees.
* Specifying no tag implies a biome has temperate trees (Such as Oak)*/
SAVANNA ,
CONIFEROUS ,
JUNGLE ,
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
/*Tags specifying the nature of a biome*/
SPOOKY ,
DEAD ,
LUSH ,
NETHER ,
END ,
MUSHROOM ,
MAGICAL ,
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
OCEAN ,
RIVER ,
/**A general tag for all water-based biomes. Shown as present if OCEAN or RIVER are.**/
WATER ( OCEAN , RIVER ),
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
/*Generic types which a biome can be*/
MESA ,
2013-04-04 17:55:35 -07:00
FOREST ,
PLAINS ,
MOUNTAIN ,
HILLS ,
SWAMP ,
2014-07-01 12:46:00 +10:00
SANDY ,
SNOWY ,
2013-04-04 17:55:35 -07:00
WASTELAND ,
BEACH ,
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
/*Deprecated tags, kept for compatibility*/
@Deprecated
/**Replaced by SANDY**/
DESERT ( SANDY ),
@Deprecated
/**Replaced by SNOWY**/
FROZEN ( SNOWY );
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
private List < Type > subTags ;
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
private Type ( Type ... subTags )
{
this . subTags = Arrays . asList ( subTags );
}
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
private boolean hasSubTags ()
{
return subTags != null && ! subTags . isEmpty ();
}
2014-07-07 21:29:37 -07:00
/**
* Retrieves a Type value by name,
* if one does not exist already it creates one.
* This can be used as interm measure for modders to
* add there own category of Biome.
*
* There are NO naming conventions besides:
* MUST be all upper case (enforced by name.toUpper())
* NO Special characters. {Unenforced, just don't be a pain, if it becomes a issue I WILL
* make this RTE with no worry about backwards compatibility}
*
* Note: For performance sake, the return value of this function SHOULD be cached.
* Two calls with the same name SHOULD return the same value.
*
*
* @param name The name of this Type
* @return An instance of Type for this name.
*/
public static Type getType ( String name , Type ... subTypes )
{
name = name . toUpperCase ();
for ( Type t : values ())
{
if ( t . name (). equals ( name ))
return t ;
}
2014-08-14 20:33:23 -07:00
Type ret = EnumHelper . addEnum ( Type . class , name , new Class [] { Type [] . class }, new Object [] { subTypes });
if ( ret . ordinal () >= typeInfoList . length )
{
typeInfoList = Arrays . copyOf ( typeInfoList , ret . ordinal ());
}
return ret ;
2014-07-07 21:29:37 -07:00
}
2013-04-04 17:55:35 -07:00
}
2014-04-02 23:46:52 -07:00
private static final int BIOME_LIST_SIZE = BiomeGenBase . getBiomeGenArray (). length ;
2013-04-04 17:55:35 -07:00
private static BiomeInfo [] biomeList = new BiomeInfo [ BIOME_LIST_SIZE ] ;
2014-01-17 21:55:48 -08:00
@SuppressWarnings ( "unchecked" )
2013-04-04 17:55:35 -07:00
private static ArrayList < BiomeGenBase >[] typeInfoList = new ArrayList [ Type . values (). length ] ;
private static class BiomeInfo
{
public EnumSet < Type > typeList ;
public BiomeInfo ( Type [] types )
{
typeList = EnumSet . noneOf ( Type . class );
for ( Type t : types )
{
typeList . add ( t );
}
}
}
static
{
registerVanillaBiomes ();
}
/**
* Registers a biome with a specific biome type
2014-07-07 21:29:37 -07:00
*
2013-04-04 17:55:35 -07:00
* @param biome the biome to be registered
* @param type the type to register the biome as
* @return returns true if the biome was registered successfully
*/
public static boolean registerBiomeType ( BiomeGenBase biome , Type ... types )
2014-07-07 21:29:37 -07:00
{
2014-07-01 12:46:00 +10:00
types = listSubTags ( types );
2014-07-07 21:29:37 -07:00
2014-02-05 00:05:37 -08:00
if ( BiomeGenBase . getBiomeGenArray () [ biome . biomeID ] != null )
2013-04-04 17:55:35 -07:00
{
for ( Type type : types )
{
if ( typeInfoList [ type . ordinal () ] == null )
{
typeInfoList [ type . ordinal () ] = new ArrayList < BiomeGenBase > ();
}
typeInfoList [ type . ordinal () ] . add ( biome );
}
if ( biomeList [ biome . biomeID ] == null )
{
biomeList [ biome . biomeID ] = new BiomeInfo ( types );
}
else
{
for ( Type type : types )
{
biomeList [ biome . biomeID ] . typeList . add ( type );
}
}
return true ;
}
return false ;
}
/**
* Returns a list of biomes registered with a specific type
2014-07-07 21:29:37 -07:00
*
2013-04-04 17:55:35 -07:00
* @param type the Type to look for
* @return a list of biomes of the specified type, null if there are none
*/
public static BiomeGenBase [] getBiomesForType ( Type type )
{
if ( typeInfoList [ type . ordinal () ] != null )
{
2013-04-19 14:29:07 +03:00
return ( BiomeGenBase [] ) typeInfoList [ type . ordinal () ] . toArray ( new BiomeGenBase [ 0 ] );
2013-04-04 17:55:35 -07:00
}
return new BiomeGenBase [ 0 ] ;
}
/**
* Gets a list of Types that a specific biome is registered with
2014-07-07 21:29:37 -07:00
*
2013-04-04 17:55:35 -07:00
* @param biome the biome to check
* @return the list of types, null if there are none
*/
public static Type [] getTypesForBiome ( BiomeGenBase biome )
{
checkRegistration ( biome );
if ( biomeList [ biome . biomeID ] != null )
{
2013-04-19 14:08:53 +03:00
return ( Type [] ) biomeList [ biome . biomeID ] . typeList . toArray ( new Type [ 0 ] );
2013-04-04 17:55:35 -07:00
}
return new Type [ 0 ] ;
}
/**
* Checks to see if two biomes are registered as having the same type
2014-07-07 21:29:37 -07:00
*
2013-04-04 17:55:35 -07:00
* @param biomeA
* @param biomeB
* @return returns true if a common type is found, false otherwise
*/
public static boolean areBiomesEquivalent ( BiomeGenBase biomeA , BiomeGenBase biomeB )
{
int a = biomeA . biomeID ;
int b = biomeB . biomeID ;
checkRegistration ( biomeA );
checkRegistration ( biomeB );
if ( biomeList [ a ] != null && biomeList [ b ] != null )
{
for ( Type type : biomeList [ a ] . typeList )
{
if ( containsType ( biomeList [ b ] , type ))
{
return true ;
}
}
}
return false ;
}
/**
* Checks to see if the given biome is registered as being a specific type
2014-07-07 21:29:37 -07:00
*
2013-04-04 17:55:35 -07:00
* @param biome the biome to be considered
* @param type the type to check for
* @return returns true if the biome is registered as being of type type, false otherwise
*/
public static boolean isBiomeOfType ( BiomeGenBase biome , Type type )
{
checkRegistration ( biome );
if ( biomeList [ biome . biomeID ] != null )
{
return containsType ( biomeList [ biome . biomeID ] , type );
}
return false ;
}
/**
* Checks to see if the given biome has been registered as being of any type
* @param biome the biome to consider
* @return returns true if the biome has been registered, false otherwise
*/
public static boolean isBiomeRegistered ( BiomeGenBase biome )
2014-07-07 21:29:37 -07:00
{
2013-04-04 17:55:35 -07:00
return biomeList [ biome . biomeID ] != null ;
}
public static boolean isBiomeRegistered ( int biomeID )
{
return biomeList [ biomeID ] != null ;
}
2013-09-05 10:08:02 -04:00
public static void registerAllBiomes ()
{
FMLLog . warning ( "Redundant call to BiomeDictionary.registerAllBiomes ignored" );
}
2013-04-04 17:55:35 -07:00
/**
* Loops through the biome list and automatically adds tags to any biome that does not have any
2013-09-05 10:08:02 -04:00
* This is called by Forge at postinit time. It will additionally dispatch any deferred decorator
* creation events.
2014-07-07 21:29:37 -07:00
*
2013-04-04 17:55:35 -07:00
* DO NOT call this during world generation
*/
2013-09-05 10:08:02 -04:00
public static void registerAllBiomesAndGenerateEvents ()
2013-04-04 17:55:35 -07:00
{
2014-02-05 00:05:37 -08:00
for ( int i = 0 ; i < BiomeGenBase . getBiomeGenArray (). length ; i ++ )
2013-04-04 17:55:35 -07:00
{
2014-02-05 00:05:37 -08:00
BiomeGenBase biome = BiomeGenBase . getBiomeGenArray () [ i ] ;
2013-10-19 18:31:32 -07:00
if ( biome == null )
{
continue ;
}
2013-09-05 10:08:02 -04:00
if ( biome . theBiomeDecorator instanceof DeferredBiomeDecorator )
{
DeferredBiomeDecorator decorator = ( DeferredBiomeDecorator ) biome . theBiomeDecorator ;
2013-12-21 00:10:35 -08:00
decorator . fireCreateEventAndReplace ( biome );
2013-09-05 10:08:02 -04:00
}
2013-10-19 18:31:32 -07:00
checkRegistration ( biome );
2013-04-04 17:55:35 -07:00
}
}
/**
* Automatically looks for and registers a given biome with appropriate tags
* This method is called automatically if a biome has not been registered with any tags,
* And another method requests information about it
2014-07-07 21:29:37 -07:00
*
2013-04-04 17:55:35 -07:00
* @param biome the biome to be considered
*/
public static void makeBestGuess ( BiomeGenBase biome )
2014-07-07 21:29:37 -07:00
{
2014-07-01 12:46:00 +10:00
if ( biome . theBiomeDecorator . treesPerChunk >= 3 )
2013-04-04 17:55:35 -07:00
{
2014-07-01 12:46:00 +10:00
if ( biome . isHighHumidity () && biome . temperature >= 0 . 9F )
2013-04-04 17:55:35 -07:00
{
BiomeDictionary . registerBiomeType ( biome , JUNGLE );
}
2014-07-01 12:46:00 +10:00
else if ( ! biome . isHighHumidity ())
2013-04-04 17:55:35 -07:00
{
BiomeDictionary . registerBiomeType ( biome , FOREST );
2014-07-01 12:46:00 +10:00
2014-07-07 21:29:37 -07:00
if ( biome . temperature <= 0 . 2f )
2014-07-01 12:46:00 +10:00
{
BiomeDictionary . registerBiomeType ( biome , CONIFEROUS );
}
2013-04-04 17:55:35 -07:00
}
}
2014-11-25 19:56:35 -08:00
else if ( biome . maxHeight <= 0 . 3F && biome . maxHeight >= 0 . 0F )
2013-04-04 17:55:35 -07:00
{
2014-11-25 19:56:35 -08:00
if ( ! biome . isHighHumidity () || biome . minHeight >= 0 . 0F )
2013-04-04 17:55:35 -07:00
{
BiomeDictionary . registerBiomeType ( biome , PLAINS );
}
}
2014-07-01 12:46:00 +10:00
if ( biome . rainfall > 0 . 85f )
{
BiomeDictionary . registerBiomeType ( biome , WET );
}
if ( biome . rainfall < 0 . 15f )
{
BiomeDictionary . registerBiomeType ( biome , DRY );
}
if ( biome . temperature > 0 . 85f )
{
BiomeDictionary . registerBiomeType ( biome , HOT );
}
if ( biome . temperature < 0 . 15f )
{
BiomeDictionary . registerBiomeType ( biome , COLD );
}
if ( biome . theBiomeDecorator . treesPerChunk > 0 && biome . theBiomeDecorator . treesPerChunk < 3 )
{
BiomeDictionary . registerBiomeType ( biome , SPARSE );
}
else if ( biome . theBiomeDecorator . treesPerChunk >= 10 )
{
BiomeDictionary . registerBiomeType ( biome , DENSE );
}
2014-11-25 19:56:35 -08:00
if ( biome . isHighHumidity () && biome . minHeight < 0 . 0F && ( biome . maxHeight <= 0 . 3F && biome . maxHeight >= 0 . 0F ))
2013-04-04 17:55:35 -07:00
{
BiomeDictionary . registerBiomeType ( biome , SWAMP );
}
2014-11-25 19:56:35 -08:00
if ( biome . minHeight <= - 0 . 5F )
2013-04-04 17:55:35 -07:00
{
2014-11-25 19:56:35 -08:00
if ( biome . maxHeight == 0 . 0F )
2014-07-01 12:46:00 +10:00
{
BiomeDictionary . registerBiomeType ( biome , RIVER );
}
else
{
BiomeDictionary . registerBiomeType ( biome , OCEAN );
}
2013-04-04 17:55:35 -07:00
}
2014-11-25 19:56:35 -08:00
if ( biome . maxHeight >= 0 . 4F && biome . maxHeight < 1 . 5F )
2014-07-01 12:46:00 +10:00
{
BiomeDictionary . registerBiomeType ( biome , HILLS );
}
2014-11-25 19:56:35 -08:00
if ( biome . maxHeight >= 1 . 5F )
2013-04-04 17:55:35 -07:00
{
BiomeDictionary . registerBiomeType ( biome , MOUNTAIN );
}
2014-07-01 12:46:00 +10:00
if ( biome . getEnableSnow ())
2013-04-04 17:55:35 -07:00
{
2014-07-01 12:46:00 +10:00
BiomeDictionary . registerBiomeType ( biome , SNOWY );
2013-04-04 17:55:35 -07:00
}
2014-07-01 12:46:00 +10:00
if ( biome . topBlock != Blocks . sand && biome . temperature >= 1 . 0f && biome . rainfall < 0 . 2f )
{
BiomeDictionary . registerBiomeType ( biome , SAVANNA );
}
if ( biome . topBlock == Blocks . sand )
2013-04-04 17:55:35 -07:00
{
2014-07-01 12:46:00 +10:00
BiomeDictionary . registerBiomeType ( biome , SANDY );
}
else if ( biome . topBlock == Blocks . hardened_clay )
{
BiomeDictionary . registerBiomeType ( biome , MESA );
}
else if ( biome . topBlock == Blocks . mycelium )
{
BiomeDictionary . registerBiomeType ( biome , MUSHROOM );
2013-04-04 17:55:35 -07:00
}
}
2014-07-07 21:29:37 -07:00
//Internal implementation
2013-04-04 17:55:35 -07:00
private static void checkRegistration ( BiomeGenBase biome )
{
if ( ! isBiomeRegistered ( biome ))
{
makeBestGuess ( biome );
}
}
private static boolean containsType ( BiomeInfo info , Type type )
{
2014-07-01 12:46:00 +10:00
if ( type . hasSubTags ())
{
for ( Type remappedType : listSubTags ( type ))
{
if ( info . typeList . contains ( remappedType )) return true ;
}
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
return false ;
}
2014-07-07 21:29:37 -07:00
2013-04-04 17:55:35 -07:00
return info . typeList . contains ( type );
}
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
private static Type [] listSubTags ( Type ... types )
{
List < Type > subTags = new ArrayList < Type > ();
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
for ( Type type : types )
{
if ( type . hasSubTags ()) subTags . addAll ( type . subTags );
else subTags . add ( type );
}
2014-07-07 21:29:37 -07:00
2014-07-01 12:46:00 +10:00
return subTags . toArray ( new Type [ subTags . size () ] );
}
2013-04-04 17:55:35 -07:00
private static void registerVanillaBiomes ()
{
2014-07-01 12:46:00 +10:00
registerBiomeType ( ocean , OCEAN );
registerBiomeType ( plains , PLAINS );
registerBiomeType ( desert , HOT , DRY , SANDY );
registerBiomeType ( extremeHills , MOUNTAIN , HILLS );
registerBiomeType ( forest , FOREST );
registerBiomeType ( taiga , COLD , CONIFEROUS , FOREST );
registerBiomeType ( taigaHills , COLD , CONIFEROUS , FOREST , HILLS );
registerBiomeType ( swampland , WET , SWAMP );
registerBiomeType ( river , RIVER );
registerBiomeType ( frozenOcean , COLD , OCEAN , SNOWY );
registerBiomeType ( frozenRiver , COLD , RIVER , SNOWY );
registerBiomeType ( icePlains , COLD , SNOWY , WASTELAND );
registerBiomeType ( iceMountains , COLD , SNOWY , MOUNTAIN );
registerBiomeType ( beach , BEACH );
registerBiomeType ( desertHills , HOT , DRY , SANDY , HILLS );
registerBiomeType ( jungle , HOT , WET , DENSE , JUNGLE );
registerBiomeType ( jungleHills , HOT , WET , DENSE , JUNGLE , HILLS );
registerBiomeType ( forestHills , FOREST , HILLS );
registerBiomeType ( sky , COLD , DRY , END );
registerBiomeType ( hell , HOT , DRY , NETHER );
registerBiomeType ( mushroomIsland , MUSHROOM );
registerBiomeType ( extremeHillsEdge , MOUNTAIN );
registerBiomeType ( mushroomIslandShore , MUSHROOM , BEACH );
registerBiomeType ( jungleEdge , HOT , WET , JUNGLE , FOREST );
registerBiomeType ( deepOcean , OCEAN );
registerBiomeType ( stoneBeach , BEACH );
registerBiomeType ( coldBeach , COLD , BEACH , SNOWY );
registerBiomeType ( birchForest , FOREST );
registerBiomeType ( birchForestHills , FOREST , HILLS );
registerBiomeType ( roofedForest , SPOOKY , DENSE , FOREST );
registerBiomeType ( coldTaiga , COLD , CONIFEROUS , FOREST , SNOWY );
registerBiomeType ( coldTaigaHills , COLD , CONIFEROUS , FOREST , SNOWY , HILLS );
registerBiomeType ( megaTaiga , COLD , CONIFEROUS , FOREST );
registerBiomeType ( megaTaigaHills , COLD , CONIFEROUS , FOREST , HILLS );
registerBiomeType ( extremeHillsPlus , MOUNTAIN , FOREST , SPARSE );
registerBiomeType ( savanna , HOT , SAVANNA , PLAINS , SPARSE );
registerBiomeType ( savannaPlateau , HOT , SAVANNA , PLAINS , SPARSE );
registerBiomeType ( mesa , MESA , SANDY );
registerBiomeType ( mesaPlateau_F , MESA , SPARSE , SANDY );
registerBiomeType ( mesaPlateau , MESA , SANDY );
2013-04-04 17:55:35 -07:00
}
2013-04-19 14:08:53 +03:00
}