package ru.betterend.registry; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.util.Identifier; import net.minecraft.util.registry.BuiltinRegistries; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryKey; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome.Category; import net.minecraft.world.biome.BiomeKeys; import ru.betterend.world.biome.BiomeChorusForest; import ru.betterend.world.biome.BiomeCrystalMountains; import ru.betterend.world.biome.BiomeDustWastelands; import ru.betterend.world.biome.BiomeFoggyMushroomland; import ru.betterend.world.biome.BiomeMegalake; import ru.betterend.world.biome.BiomeMegalakeGrove; import ru.betterend.world.biome.BiomePaintedMountains; import ru.betterend.world.biome.BiomeShadowForest; import ru.betterend.world.biome.EndBiome; import ru.betterend.world.generator.BiomePicker; import ru.betterend.world.generator.BiomeType; public class EndBiomes { private static final Map> KEYS = Maps.newHashMap(); private static final HashMap ID_MAP = Maps.newHashMap(); private static final HashMap MUTABLE = Maps.newHashMap(); private static final HashMap CLIENT = Maps.newHashMap(); public static final BiomePicker LAND_BIOMES = new BiomePicker(); public static final BiomePicker VOID_BIOMES = new BiomePicker(); public static final List SUBBIOMES = Lists.newArrayList(); private static Registry biomeRegistry; // Vanilla Land public static final EndBiome END = registerBiome(BiomeKeys.THE_END, BiomeType.LAND, 1F); public static final EndBiome END_MIDLANDS = registerSubBiome(BiomeKeys.END_MIDLANDS, END, 0.5F); public static final EndBiome END_HIGHLANDS = registerSubBiome(BiomeKeys.END_HIGHLANDS, END, 0.5F); // Vanilla Void public static final EndBiome END_BARRENS = registerBiome(BiomeKeys.END_BARRENS, BiomeType.VOID, 1F); public static final EndBiome SMALL_END_ISLANDS = registerBiome(BiomeKeys.SMALL_END_ISLANDS, BiomeType.VOID, 1); // Better End Land public static final EndBiome FOGGY_MUSHROOMLAND = registerBiome(new BiomeFoggyMushroomland(), BiomeType.LAND); public static final EndBiome CHORUS_FOREST = registerBiome(new BiomeChorusForest(), BiomeType.LAND); public static final EndBiome DUST_WASTELANDS = registerBiome(new BiomeDustWastelands(), BiomeType.LAND); public static final EndBiome MEGALAKE = registerBiome(new BiomeMegalake(), BiomeType.LAND); public static final EndBiome MEGALAKE_GROVE = registerSubBiome(new BiomeMegalakeGrove(), MEGALAKE); public static final EndBiome CRYSTAL_MOUNTAINS = registerBiome(new BiomeCrystalMountains(), BiomeType.LAND); public static final EndBiome PAINTED_MOUNTAINS = registerSubBiome(new BiomePaintedMountains(), DUST_WASTELANDS); public static final EndBiome SHADOW_FOREST = registerBiome(new BiomeShadowForest(), BiomeType.LAND); public static void register() {} public static void mutateRegistry(Registry biomeRegistry) { EndBiomes.biomeRegistry = biomeRegistry; EndBiomes.MUTABLE.clear(); LAND_BIOMES.clearMutables(); for (EndBiome biome : EndBiomes.LAND_BIOMES.getBiomes()) EndBiomes.MUTABLE.put(biomeRegistry.getOrThrow(EndBiomes.getBiomeKey(biome)), biome); for (EndBiome biome : EndBiomes.VOID_BIOMES.getBiomes()) EndBiomes.MUTABLE.put(biomeRegistry.getOrThrow(EndBiomes.getBiomeKey(biome)), biome); biomeRegistry.forEach((biome) -> { if (biome.getCategory() == Category.THEEND) { if (!MUTABLE.containsKey(biome) && !biomeRegistry.getId(biome).getNamespace().equals("minecraft")) { EndBiome endBiome = new EndBiome(biome, 1, 1); LAND_BIOMES.addBiomeMutable(endBiome); KEYS.put(endBiome, biomeRegistry.getKey(biome).get()); } } }); CLIENT.clear(); } /** * Registers new {@link EndBiome} and adds it to picker, can be used to add existing mod biomes into the End. * @param biome - {@link Biome} instance * @param type - {@link BiomeType} * @param genChance - generation chance [0.0F - Infinity] * @return registered {@link EndBiome} */ public static EndBiome registerBiome(Biome biome, BiomeType type, float genChance) { return registerBiome(biome, type, 1, genChance); } /** * Registers new {@link EndBiome} and adds it to picker, can be used to add existing mod biomes into the End. * @param biome - {@link Biome} instance * @param type - {@link BiomeType} * @param fogDensity - density of fog (def: 1F) [0.0F - Infinity] * @param genChance - generation chance [0.0F - Infinity] * @return registered {@link EndBiome} */ public static EndBiome registerBiome(Biome biome, BiomeType type, float fogDensity, float genChance) { EndBiome endBiome = new EndBiome(biome, fogDensity, genChance); addToPicker(endBiome, type); makeLink(endBiome); return endBiome; } /** * Registers new {@link EndBiome} from existed {@link Biome} and put as a sub-biome into selected parent. * @param biome - {@link Biome} instance * @param parent - {@link EndBiome} to be linked with * @param genChance - generation chance [0.0F - Infinity] * @return registered {@link EndBiome} */ public static EndBiome registerSubBiome(Biome biome, EndBiome parent, float genChance) { return registerSubBiome(biome, parent, 1, genChance); } /** * Registers new {@link EndBiome} from existed {@link Biome} and put as a sub-biome into selected parent. * @param biome - {@link Biome} instance * @param parent - {@link EndBiome} to be linked with * @param fogDensity - density of fog (def: 1F) [0.0F - Infinity] * @param genChance - generation chance [0.0F - Infinity] * @return registered {@link EndBiome} */ public static EndBiome registerSubBiome(Biome biome, EndBiome parent, float fogDensity, float genChance) { EndBiome endBiome = new EndBiome(biome, fogDensity, genChance); parent.addSubBiome(endBiome); makeLink(endBiome); SUBBIOMES.add(endBiome); return endBiome; } /** * Put existing {@link EndBiome} as a sub-biome into selected parent. * @param biome - {@link EndBiome} instance * @param parent - {@link EndBiome} to be linked with * @return registered {@link EndBiome} */ public static EndBiome registerSubBiome(EndBiome biome, EndBiome parent) { registerBiomeDirect(biome); parent.addSubBiome(biome); makeLink(biome); SUBBIOMES.add(biome); return biome; } /** * Registers {@link EndBiome} and adds it into worldgen. * @param biome - {@link EndBiome} instance * @param type - {@link BiomeType} * @return registered {@link EndBiome} */ public static EndBiome registerBiome(EndBiome biome, BiomeType type) { registerBiomeDirect(biome); addToPicker(biome, type); ID_MAP.put(biome.getID(), biome); return biome; } private static EndBiome registerBiome(RegistryKey key, BiomeType type, float genChance) { return registerBiome(BuiltinRegistries.BIOME.get(key), type, genChance); } private static EndBiome registerSubBiome(RegistryKey key, EndBiome parent, float genChance) { return registerSubBiome(BuiltinRegistries.BIOME.get(key), parent, genChance); } private static void addToPicker(EndBiome biome, BiomeType type) { if (type == BiomeType.LAND) LAND_BIOMES.addBiome(biome); else VOID_BIOMES.addBiome(biome); } private static void registerBiomeDirect(EndBiome biome) { Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome()); makeLink(biome); } private static void makeLink(EndBiome biome) { Optional> optional = BuiltinRegistries.BIOME.getKey(biome.getBiome()); RegistryKey key = optional.isPresent() ? optional.get() : RegistryKey.of(Registry.BIOME_KEY, biome.getID()); KEYS.put(biome, key); } public static RegistryKey getBiomeKey(EndBiome biome) { return KEYS.get(biome); } public static EndBiome getFromBiome(Biome biome) { return ID_MAP.getOrDefault(biomeRegistry.getId(biome), END); } @Environment(EnvType.CLIENT) public static EndBiome getRenderBiome(Biome biome) { EndBiome endBiome = CLIENT.get(biome); if (endBiome == null) { Identifier id = MinecraftClient.getInstance().world.getRegistryManager().get(Registry.BIOME_KEY).getId(biome); endBiome = id == null ? END : ID_MAP.getOrDefault(id, END); CLIENT.put(biome, endBiome); } return endBiome; } public static Identifier getBiomeID(Biome biome) { Identifier id = biomeRegistry.getId(biome); return id == null ? END.getID() : id; } public static EndBiome getBiome(Identifier biomeID) { return ID_MAP.getOrDefault(biomeID, END); } public static List getModBiomes() { List result = Lists.newArrayList(); result.addAll(EndBiomes.LAND_BIOMES.getBiomes()); result.addAll(EndBiomes.VOID_BIOMES.getBiomes()); result.addAll(SUBBIOMES); return result; } }