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}