package hunternif.mc.atlas.client; import hunternif.mc.atlas.core.Tile; import hunternif.mc.atlas.util.Log; import hunternif.mc.atlas.util.SaveData; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.MathHelper; import net.minecraft.world.biome.Biome; import net.minecraftforge.common.BiomeDictionary; import net.minecraftforge.common.BiomeDictionary.Type; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.*; import java.util.Map.Entry; import static hunternif.mc.atlas.client.TextureSet.*; /** * Maps biome IDs (or pseudo IDs) to textures. <i>Not thread-safe!</i> * <p>If several textures are set for one ID, one will be chosen at random when * putting tile into Atlas.</p> * @author Hunternif */ @SideOnly(Side.CLIENT) public class BiomeTextureMap extends SaveData { private static final BiomeTextureMap INSTANCE = new BiomeTextureMap(); public static BiomeTextureMap instance() { return INSTANCE; } /** This map allows keys other than the 256 biome IDs to use for special tiles. */ final Map<Integer, TextureSet> textureMap = new HashMap<>(); public static final TextureSet defaultTexture = PLAINS; /** Assign texture set to biome. */ public void setTexture(int biomeID, TextureSet textureSet) { if (textureSet == null) { if (textureMap.remove(biomeID) != null) { Log.warn("Removing old texture for biome %s", biomeID); if (biomeID >= 0 && biomeID < 256) { markDirty(); } } return; } TextureSet previous = textureMap.put(biomeID, textureSet); if (biomeID >= 0 && biomeID < 256) { // The config only concerns itself with biomes 0-256. // If the old texture set is equal to the new one (i.e. has equal name // and equal texture files), then there's no need to update the config. if (previous == null) { markDirty(); } else if (!previous.equals(textureSet)) { Log.warn("Overwriting texture set for biome %d", biomeID); markDirty(); } } } /** Find the most appropriate standard texture set depending on * BiomeDictionary types. */ private void autoRegister(int biomeID) { if (biomeID < 0 || biomeID >= 256) { Log.warn("Biome ID %d is out of range. Auto-registering default texture set", biomeID); setTexture(biomeID, defaultTexture); return; } Biome biome = Biome.getBiomeForId(biomeID); if (biome == null) { Log.warn("Biome ID %d is null. Auto-registering default texture set", biomeID); setTexture(biomeID, defaultTexture); return; } Set<Type> types = BiomeDictionary.getTypes(biome); // 1. Swamp if (types.contains(Type.SWAMP)) { if (types.contains(Type.HILLS)) { setTexture(biomeID, SWAMP_HILLS); } else { setTexture(biomeID, SWAMP); } } // 2. Water else if (types.contains(Type.WATER) || types.contains(Type.RIVER)) { // Water + trees = swamp if (types.contains(Type.FOREST) || types.contains(Type.JUNGLE)) { if (types.contains(Type.HILLS)) { setTexture(biomeID, SWAMP_HILLS); } else { setTexture(biomeID, SWAMP); } } else if (types.contains(Type.SNOWY)){ setTexture(biomeID, ICE); } else { setTexture(biomeID, WATER); } } // 3. Shore else if (types.contains(Type.BEACH)){ if (types.contains(Type.MOUNTAIN)) { setTexture(biomeID, ROCK_SHORE); } else { setTexture(biomeID, SHORE); } } // 4. Jungle else if (types.contains(Type.JUNGLE)) { if (types.contains(Type.MOUNTAIN)) { setTexture(biomeID, JUNGLE_CLIFFS); } else if (types.contains(Type.HILLS)) { setTexture(biomeID, JUNGLE_HILLS); } else { setTexture(biomeID, JUNGLE); } } // 5. Savanna else if (types.contains(Type.SAVANNA)) { if (types.contains(Type.MOUNTAIN) || types.contains(Type.HILLS)) { setTexture(biomeID, SAVANNA_CLIFFS); } else { setTexture(biomeID, SAVANNA); } } // 6. Pines else if (types.contains(Type.CONIFEROUS)) { if (types.contains(Type.MOUNTAIN) || types.contains(Type.HILLS)) { setTexture(biomeID, PINES_HILLS); } else { setTexture(biomeID, PINES); } } // 7. Mesa - I suspect that by using this type people usually mean "Plateau" else if (types.contains(Type.MESA)) { if (types.contains(Type.FOREST)) { setTexture(biomeID, PLATEAU_MESA_TREES); } else { setTexture(biomeID, PLATEAU_MESA); } } // 8. General forest else if (types.contains(Type.FOREST)) { // Frozen forest automatically counts as pines: if (types.contains(Type.SNOWY)) { if (types.contains(Type.HILLS)) { setTexture(biomeID, SNOW_PINES_HILLS); } else { setTexture(biomeID, SNOW_PINES); } } else { // Segregate by density: if (types.contains(Type.SPARSE)) { if (types.contains(Type.HILLS)) { setTexture(biomeID, SPARSE_FOREST_HILLS); } else { setTexture(biomeID, SPARSE_FOREST); } } else if (types.contains(Type.DENSE)) { if (types.contains(Type.HILLS)) { setTexture(biomeID, DENSE_FOREST_HILLS); } else { setTexture(biomeID, DENSE_FOREST); } } else { if (types.contains(Type.HILLS)) { setTexture(biomeID, FOREST_HILLS); } else { setTexture(biomeID, FOREST); } } } } // 9. Various plains else if (types.contains(Type.PLAINS) || types.contains(Type.WASTELAND)) { if (types.contains(Type.SNOWY) || types.contains(Type.COLD)) { if (types.contains(Type.MOUNTAIN)) { setTexture(biomeID, MOUNTAINS_SNOW_CAPS); } else if (types.contains(Type.HILLS)) { setTexture(biomeID, SNOW_HILLS); } else { setTexture(biomeID, SNOW); } } else { if (types.contains(Type.HILLS) || types.contains(Type.MOUNTAIN)) { setTexture(biomeID, DESERT_HILLS); } else { setTexture(biomeID, DESERT); } } } // 10. General mountains else if (types.contains(Type.MOUNTAIN)) { setTexture(biomeID, MOUNTAINS_NAKED); } // 11. General hills else if (types.contains(Type.HILLS)) { if (types.contains(Type.SNOWY) || types.contains(Type.COLD)) { setTexture(biomeID, SNOW_HILLS); } else if (types.contains(Type.SANDY)) { setTexture(biomeID, DESERT_HILLS); } else { setTexture(biomeID, HILLS); } } else { setTexture(biomeID, defaultTexture); } Log.info("Auto-registered standard texture set for biome %d", biomeID); } /** Auto-registers the biome ID if it is not registered. */ private void checkRegistration(int biomeID) { if (!isRegistered(biomeID)) { autoRegister(biomeID); markDirty(); } } public boolean isRegistered(int biomeID) { return textureMap.containsKey(biomeID); } /** If unknown biome, auto-registers a texture set. If null, returns default set. */ public TextureSet getTextureSet(Tile tile) { if (tile == null) return defaultTexture; checkRegistration(tile.biomeID); return textureMap.get(tile.biomeID); } public ResourceLocation getTexture(Tile tile) { TextureSet set = getTextureSet(tile); int i = MathHelper.floor((float)(tile.getVariationNumber()) / (float)(Short.MAX_VALUE) * (float)(set.textures.length)); return set.textures[i]; } public List<ResourceLocation> getAllTextures() { List<ResourceLocation> list = new ArrayList<>(textureMap.size()); for (Entry<Integer, TextureSet> entry : textureMap.entrySet()) { list.addAll(Arrays.asList(entry.getValue().textures)); } return list; } }