From e35fe997c1852421b3df28a1f6c9c233337bc762 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 14:33:52 +0200 Subject: [PATCH] [Change] Change handling of End Biomes once more. (EndSource will consider Barrens and MainIsland biomes as well now) --- .../api/v2/generator/BCLibEndBiomeSource.java | 198 ++++++------ .../api/v2/generator/GeneratorOptions.java | 10 +- .../api/v2/generator/TheEndBiomesHelper.java | 121 ++++--- .../config/BCLEndBiomeSourceConfig.java | 73 ++++- .../bclib/api/v2/levelgen/LevelGenEvents.java | 6 +- .../api/v2/levelgen/biomes/BCLBiome.java | 16 + .../api/v2/levelgen/biomes/BiomeAPI.java | 296 +++++++++++------- .../v2/levelgen/biomes/InternalBiomeAPI.java | 110 +++++++ .../client/gui/screens/WorldSetupScreen.java | 6 +- .../betterx/bclib/config/BiomesConfig.java | 101 ++++++ .../org/betterx/bclib/config/Configs.java | 3 +- ...ccessor.java => TheEndBiomesAccessor.java} | 2 +- .../mixin/common/TheEndBiomeDataMixin.java | 40 --- .../bclib/mixin/common/TheEndBiomesMixin.java | 64 ++++ src/main/resources/bclib.mixins.common.json | 2 +- 15 files changed, 714 insertions(+), 334 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/config/BiomesConfig.java rename src/main/java/org/betterx/bclib/interfaces/{TheEndBiomeDataAccessor.java => TheEndBiomesAccessor.java} (94%) delete mode 100644 src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java create mode 100644 src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 51fd7155..8680c39d 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -4,7 +4,6 @@ import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; -import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry; import org.betterx.bclib.config.Configs; import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; @@ -26,9 +25,8 @@ import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.levelgen.DensityFunction; import java.awt.*; -import java.util.ArrayList; import java.util.List; -import java.util.Set; +import java.util.*; import java.util.function.BiFunction; import org.jetbrains.annotations.NotNull; @@ -54,15 +52,17 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi instance.stable(BCLibEndBiomeSource::new) ) ); - private final Holder centerBiome; - private final Holder barrens; private final Point pos; private final BiFunction endLandFunction; private BiomeMap mapLand; private BiomeMap mapVoid; + private BiomeMap mapCenter; + private BiomeMap mapBarrens; private final BiomePicker endLandBiomePicker; private final BiomePicker endVoidBiomePicker; + private final BiomePicker endCenterBiomePicker; + private final BiomePicker endBarrensBiomePicker; private BCLEndBiomeSourceConfig config; @@ -92,81 +92,79 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi ) { super(biomeRegistry, list, seed); this.config = config; + var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap(); + var excludeList = Configs.BIOMES_CONFIG.getBiomeExcludeMap().get(BiomeAPI.BiomeType.END); endLandBiomePicker = new BiomePicker(biomeRegistry); endVoidBiomePicker = new BiomePicker(biomeRegistry); + endCenterBiomePicker = new BiomePicker(biomeRegistry); + endBarrensBiomePicker = new BiomePicker(biomeRegistry); + Map pickerMap = new HashMap<>(); + pickerMap.put(BiomeAPI.BiomeType.END_LAND, endLandBiomePicker); + pickerMap.put(BiomeAPI.BiomeType.END_VOID, endVoidBiomePicker); + pickerMap.put(BiomeAPI.BiomeType.END_CENTER, endCenterBiomePicker); + pickerMap.put(BiomeAPI.BiomeType.END_BARRENS, endBarrensBiomePicker); - List includeVoid = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_void_biomes", - StringArrayEntry.class - ).getValue(); - List includeLand = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_land_biomes", - StringArrayEntry.class - ).getValue(); this.possibleBiomes().forEach(biome -> { ResourceKey key = biome.unwrapKey().orElseThrow(); ResourceLocation biomeID = key.location(); + String biomeStr = biomeID.toString(); + //exclude everything that was listed + if (excludeList != null && excludeList.contains(biomeStr)) return; - + final BCLBiome bclBiome; if (!BiomeAPI.hasBiome(biomeID)) { - BCLBiome bclBiome = new BCLBiome(biomeID, biome.value()); - - if (includeVoid.contains(biomeID.toString())) { - endVoidBiomePicker.addBiome(bclBiome); - } else { - endLandBiomePicker.addBiome(bclBiome); - } + bclBiome = new BCLBiome(biomeID, biome.value()); } else { - BCLBiome bclBiome = BiomeAPI.getBiome(biomeID); - if (bclBiome != BiomeAPI.EMPTY_BIOME) { - if (bclBiome.getParentBiome() == null) { - if (config.withVoidBiomes) { - if (biomeID.equals(Biomes.THE_END.location())) { - //we discard those Biomes - } else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) - || biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) - || TheEndBiomesHelper.isIntendedForEndBarrens(key) - || includeVoid.contains(biomeID.toString()) - ) { - endVoidBiomePicker.addBiome(bclBiome); - } else if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID) - || TheEndBiomesHelper.isIntendedForEndLand(key) - || includeLand.contains(biomeID.toString()) - ) { - endLandBiomePicker.addBiome(bclBiome); - } - } else { - if (biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) - || biomeID.equals(Biomes.THE_END.location()) - ) { - //we discard those Biomes - } else if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID) - || TheEndBiomesHelper.isIntendedForEndLand(key) - || includeLand.contains(biomeID.toString()) - ) { - endLandBiomePicker.addBiome(bclBiome); - endVoidBiomePicker.addBiome(bclBiome); - } else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) || includeVoid.contains(biomeID.toString())) { - endVoidBiomePicker.addBiome(bclBiome); - } + bclBiome = BiomeAPI.getBiome(biomeID); + } + + if (bclBiome != null || bclBiome != BiomeAPI.EMPTY_BIOME) { + if (bclBiome.getParentBiome() == null) { + //ignore small islands when void biomes are disabled + if (!config.withVoidBiomes) { + if (biomeID.equals(Biomes.SMALL_END_ISLANDS.location())) { + return; + } + } + + //force include biomes + boolean didForceAdd = false; + for (var entry : pickerMap.entrySet()) { + var includeList = includeMap == null ? null : includeMap.get(entry.getKey()); + if (includeList != null && includeList.contains(biomeStr)) { + entry.getValue().addBiome(bclBiome); + didForceAdd = true; + } + } + + if (!didForceAdd) { + if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_CENTER) + || TheEndBiomesHelper.canGenerateAsMainIslandBiome(key)) { + endCenterBiomePicker.addBiome(bclBiome); + } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_LAND) + || TheEndBiomesHelper.canGenerateAsHighlandsBiome(key)) { + if (!config.withVoidBiomes) endVoidBiomePicker.addBiome(bclBiome); + endLandBiomePicker.addBiome(bclBiome); + } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_BARRENS) + || TheEndBiomesHelper.canGenerateAsEndBarrens(key)) { + endBarrensBiomePicker.addBiome(bclBiome); + } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_VOID) + || TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(key)) { + endVoidBiomePicker.addBiome(bclBiome); } } } } - }); + }); endLandBiomePicker.rebuild(); endVoidBiomePicker.rebuild(); - - - this.centerBiome = biomeRegistry.getOrCreateHolderOrThrow(Biomes.THE_END); - this.barrens = biomeRegistry.getOrCreateHolderOrThrow(Biomes.END_BARRENS); + endBarrensBiomePicker.rebuild(); + endCenterBiomePicker.rebuild(); this.endLandFunction = GeneratorOptions.getEndLandFunction(); this.pos = new Point(); @@ -188,51 +186,37 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi } private static List> getBclBiomes(Registry biomeRegistry) { - List include = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_land_biomes", - StringArrayEntry.class - ).getValue(); - include.addAll(Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_void_biomes", - StringArrayEntry.class - ).getValue()); return getBiomes( biomeRegistry, new ArrayList<>(0), - include, + Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END), BCLibEndBiomeSource::isValidNonVanillaEndBiome ); } private static List> getBiomes(Registry biomeRegistry) { - List include = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_land_biomes", - StringArrayEntry.class - ).getValue(); - include.addAll(Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_void_biomes", - StringArrayEntry.class - ).getValue()); - - return getBiomes(biomeRegistry, new ArrayList<>(0), include, BCLibEndBiomeSource::isValidEndBiome); + return getBiomes( + biomeRegistry, + new ArrayList<>(0), + Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END), + BCLibEndBiomeSource::isValidEndBiome + ); } private static boolean isValidEndBiome(Holder biome, ResourceLocation location) { return biome.is(BiomeTags.IS_END) || BiomeAPI.wasRegisteredAsEndBiome(location) || - TheEndBiomesHelper.isIntendedForAny(biome.unwrapKey().orElse(null)); + TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null)); } private static boolean isValidNonVanillaEndBiome(Holder biome, ResourceLocation location) { return biome.is(BiomeTags.IS_END) || BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_LAND) || BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_VOID) || - TheEndBiomesHelper.isIntendedForAny(biome.unwrapKey().orElse(null)); + BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_CENTER) || + BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_BARRENS) || + TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null)); } public static void register() { @@ -243,15 +227,27 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi protected void onInitMap(long seed) { this.mapLand = config.mapVersion.mapBuilder.apply( seed, - GeneratorOptions.getBiomeSizeEndLand(), + config.landBiomesSize, endLandBiomePicker ); this.mapVoid = config.mapVersion.mapBuilder.apply( seed, - GeneratorOptions.getBiomeSizeEndVoid(), + config.voidBiomesSize, endVoidBiomePicker ); + + this.mapCenter = config.mapVersion.mapBuilder.apply( + seed, + config.centerBiomesSize, + endCenterBiomePicker + ); + + this.mapBarrens = config.mapVersion.mapBuilder.apply( + seed, + config.barrensBiomesSize, + endBarrensBiomePicker + ); } @Override @@ -261,7 +257,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi @Override public Holder getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.@NotNull Sampler sampler) { - if (mapLand == null || mapVoid == null) + if (mapLand == null || mapVoid == null || mapCenter == null || mapBarrens == null) return this.possibleBiomes().stream().findFirst().orElseThrow(); int posX = QuartPos.toBlock(biomeX); @@ -275,32 +271,38 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) { mapLand.clearCache(); mapVoid.clearCache(); + mapCenter.clearCache(); + mapVoid.clearCache(); } + if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA || endLandFunction == null) { if (dist <= (long) config.innerVoidRadiusSquared) { - return this.centerBiome; + return mapCenter.getBiome(posX, biomeY << 2, posZ).biome; } int x = (SectionPos.blockToSectionCoord(posX) * 2 + 1) * 8; int z = (SectionPos.blockToSectionCoord(posZ) * 2 + 1) * 8; double d = sampler.erosion().compute(new DensityFunction.SinglePointContext(x, posY, z)); if (d > 0.25) { - return mapLand.getBiome(posX, biomeY << 2, posZ).biome; + return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //highlands } else if (d >= -0.0625) { - return mapLand.getBiome(posX, biomeY << 2, posZ).biome; + return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //midlands } else { return d < -0.21875 - ? mapVoid.getBiome(posX, biomeY << 2, posZ).biome - : config.withVoidBiomes ? this.barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).biome; + ? mapVoid.getBiome(posX, biomeY << 2, posZ).biome //small islands + : (config.withVoidBiomes ? mapBarrens : mapLand).getBiome( + posX, + biomeY << 2, + posZ + ).biome; //barrens } } else { pos.setLocation(biomeX, biomeZ); if (endLandFunction.apply(pos, maxHeight)) { - return dist <= (long) config.innerVoidRadiusSquared - ? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).biome; + return (dist <= (long) config.innerVoidRadiusSquared ? mapCenter : mapLand) + .getBiome(posX, biomeY << 2, posZ).biome; } else { - return dist <= (long) config.innerVoidRadiusSquared - ? barrens - : mapVoid.getBiome(posX, biomeY << 2, posZ).biome; + return (dist <= (long) config.innerVoidRadiusSquared ? mapBarrens : mapVoid) + .getBiome(posX, biomeY << 2, posZ).biome; } } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java index d7dac883..fc1ba549 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java @@ -11,8 +11,6 @@ import java.util.function.Function; public class GeneratorOptions { private static int biomeSizeNether; private static int biomeVSizeNether; - private static int biomeSizeEndLand; - private static int biomeSizeEndVoid; private static BiFunction endLandFunction; private static boolean customNetherBiomeSource = true; private static boolean customEndBiomeSource = true; @@ -28,8 +26,6 @@ public class GeneratorOptions { "biomeVerticalSize(onlyInTallNether)", 86 ); - biomeSizeEndLand = Configs.GENERATOR_CONFIG.getInt("end.biomeMap", "biomeSizeLand", 256); - biomeSizeEndVoid = Configs.GENERATOR_CONFIG.getInt("end.biomeMap", "biomeSizeVoid", 256); customNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customNetherBiomeSource", true); customEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customEndBiomeSource", true); verticalBiomes = Configs.GENERATOR_CONFIG.getBoolean("options", "verticalBiomesInTallNether", true); @@ -45,12 +41,14 @@ public class GeneratorOptions { return Mth.clamp(biomeVSizeNether, 1, 8192); } + @Deprecated(forRemoval = true) public static int getBiomeSizeEndLand() { - return Mth.clamp(biomeSizeEndLand, 1, 8192); + return 256; } + @Deprecated(forRemoval = true) public static int getBiomeSizeEndVoid() { - return Mth.clamp(biomeSizeEndVoid, 1, 8192); + return 256; } /** diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java index f3337abd..07dffc7a 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java @@ -1,97 +1,92 @@ package org.betterx.bclib.api.v2.generator; -import org.betterx.bclib.BCLib; -import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; -import net.fabricmc.fabric.impl.biome.TheEndBiomeData; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.jetbrains.annotations.ApiStatus; /** - * Helper class until FAPI integrates https://github.com/FabricMC/fabric/pull/2369 + * Helper class until FAPI integrates this PR */ public class TheEndBiomesHelper { - public static TheEndBiomeDataAccessor INSTANCE; + @ApiStatus.Internal + public static Map>> END_BIOMES = new HashMap<>(); - private static TheEndBiomeDataAccessor get() { - if (INSTANCE == null) { - try { - Class cl = TheEndBiomeData.class; - Constructor constr = Arrays.stream(cl.getDeclaredConstructors()) - .filter(c -> c.getParameterCount() == 0) - .findFirst() - .orElseThrow(); - constr.setAccessible(true); - INSTANCE = (TheEndBiomeDataAccessor) constr.newInstance(); - } catch (NoClassDefFoundError cnf) { - - } catch (InstantiationException e) { - - } catch (IllegalAccessException e) { - - } catch (InvocationTargetException e) { - - } - if (INSTANCE == null) { - BCLib.LOGGER.warning("Unable to access internal End-Biome API from Fabric. Using Fallback behaviour."); - INSTANCE = new TheEndBiomeDataAccessor() { - @Override - public boolean bcl_canGenerateAsEndBiome(ResourceKey key) { - return true; - } - - @Override - public boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey key) { - return false; - } - - @Override - public boolean bcl_canGenerateAsEndBarrensBiome(ResourceKey key) { - return false; - } - }; - } - } - return INSTANCE; + @ApiStatus.Internal + public static void add(BiomeAPI.BiomeType type, ResourceKey biome) { + if (biome == null) return; + END_BIOMES.computeIfAbsent(type, t -> new HashSet<>()).add(biome); } + private static boolean has(BiomeAPI.BiomeType type, ResourceKey biome) { + if (biome == null) return false; + Set> set = END_BIOMES.get(type); + if (set == null) return false; + return set.contains(biome); + } /** - * Returns true if the given biome was added in the end, considering the Vanilla end biomes, + * Returns true if the given biome was added as a main end Biome in the end, considering the Vanilla end biomes, * and any biomes added to the End by mods. + * + * @param biome The biome to search for */ - public static boolean isIntendedForEndBiome(ResourceKey biome) { - return get().bcl_canGenerateAsEndBiome(biome); + public static boolean canGenerateAsMainIslandBiome(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_CENTER, biome); + } + + /** + * Returns true if the given biome was added as a small end islands Biome in the end, considering the Vanilla end biomes, + * and any biomes added to the End by mods. + * + * @param biome The biome to search for + */ + public static boolean canGenerateAsSmallIslandsBiome(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_VOID, biome); + } + + /** + * Returns true if the given biome was added as a Highland Biome in the end, considering the Vanilla end biomes, + * and any biomes added to the End by mods. + * + * @param biome The biome to search for + */ + public static boolean canGenerateAsHighlandsBiome(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_LAND, biome); } /** * Returns true if the given biome was added as midland biome in the end, considering the Vanilla end biomes, * and any biomes added to the End as midland biome by mods. + * + * @param biome The biome to search for */ - public static boolean isIntendedForEndMidlands(ResourceKey biome) { - return get().bcl_canGenerateAsEndMidlandBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome); + public static boolean canGenerateAsEndMidlands(ResourceKey biome) { + return false; } /** * Returns true if the given biome was added as barrens biome in the end, considering the Vanilla end biomes, * and any biomes added to the End as barrens biome by mods. + * + * @param biome The biome to search for */ - public static boolean isIntendedForEndBarrens(ResourceKey biome) { - return get().bcl_canGenerateAsEndBarrensBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome) && !get().bcl_canGenerateAsEndMidlandBiome( - biome); + public static boolean canGenerateAsEndBarrens(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_BARRENS, biome); } - public static boolean isIntendedForEndLand(ResourceKey biome) { - return isIntendedForEndBiome(biome) || isIntendedForEndMidlands(biome); - } - - public static boolean isIntendedForAny(ResourceKey biome) { - return isIntendedForEndBiome(biome) || isIntendedForEndMidlands(biome) || isIntendedForEndBarrens(biome); + public static boolean canGenerateInEnd(ResourceKey biome) { + return canGenerateAsHighlandsBiome(biome) + || canGenerateAsEndBarrens(biome) + || canGenerateAsEndMidlands(biome) + || canGenerateAsSmallIslandsBiome(biome) + || canGenerateAsMainIslandBiome(biome); } } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java index af8ab01b..8ab7a7db 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java @@ -10,6 +10,7 @@ import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.Mth; import net.minecraft.util.StringRepresentable; import java.util.Objects; @@ -20,19 +21,31 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig o.innerVoidRadiusSquared) + .forGetter(o -> o.innerVoidRadiusSquared), + Codec.INT + .fieldOf("center_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.centerBiomesSize), + Codec.INT + .fieldOf("void_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.voidBiomesSize), + Codec.INT + .fieldOf("land_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.landBiomesSize), + Codec.INT + .fieldOf("barrens_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.barrensBiomesSize) ) .apply(instance, BCLEndBiomeSourceConfig::new)); @@ -61,12 +90,20 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig BIOME_TYPE_MAP = Maps.newHashMap(); public final BiomeType parentOrNull; - private final String debugName; + private final String name; - public BiomeType(String debugName) { - this(debugName, null); + public BiomeType(String name) { + this(name, null); } - public BiomeType(String debugName, BiomeType parentOrNull) { + public BiomeType(String name, BiomeType parentOrNull) { this.parentOrNull = parentOrNull; - this.debugName = debugName; + this.name = name; } public boolean is(BiomeType d) { @@ -93,9 +93,13 @@ public class BiomeAPI { return false; } + public String getName() { + return name; + } + @Override public String toString() { - String str = debugName; + String str = name; if (parentOrNull != null) str += " -> " + parentOrNull; return str; } @@ -109,28 +113,58 @@ public class BiomeAPI { private static final Map ID_MAP = Maps.newHashMap(); - public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES).value()); - public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST).value()); - public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST).value()); - public static final BCLBiome SOUL_SAND_VALLEY_BIOME = registerNetherBiome(getFromRegistry(Biomes.SOUL_SAND_VALLEY).value()); - public static final BCLBiome BASALT_DELTAS_BIOME = registerNetherBiome(getFromRegistry(Biomes.BASALT_DELTAS).value()); - - - public static final BCLBiome THE_END = registerCenterBiome(getFromRegistry(Biomes.THE_END)); - - public static final BCLBiome END_HIGHLANDS = registerEndLandBiome( - getFromRegistry(Biomes.END_HIGHLANDS), - 0.5F + public static final BCLBiome NETHER_WASTES_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.NETHER_WASTES, + InternalBiomeAPI.OTHER_NETHER ); - public static final BCLBiome END_MIDLANDS = registerSubBiome( - END_HIGHLANDS, - getFromRegistry(Biomes.END_MIDLANDS).value(), - 0.5F + public static final BCLBiome CRIMSON_FOREST_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.CRIMSON_FOREST, + InternalBiomeAPI.OTHER_NETHER + ); + public static final BCLBiome WARPED_FOREST_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.WARPED_FOREST, + InternalBiomeAPI.OTHER_NETHER + ); + public static final BCLBiome SOUL_SAND_VALLEY_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.SOUL_SAND_VALLEY, + InternalBiomeAPI.OTHER_NETHER + ); + public static final BCLBiome BASALT_DELTAS_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.BASALT_DELTAS, + InternalBiomeAPI.OTHER_NETHER ); - public static final BCLBiome END_BARRENS = registerEndBiome(getFromRegistry(new ResourceLocation("end_barrens"))); - public static final BCLBiome SMALL_END_ISLANDS = registerEndVoidBiome(getFromRegistry(new ResourceLocation( - "small_end_islands"))); + + public static final BCLBiome THE_END = InternalBiomeAPI.wrapNativeBiome( + Biomes.THE_END, + 0.5F, + InternalBiomeAPI.OTHER_END_CENTER + ); + + public static final BCLBiome END_MIDLANDS = InternalBiomeAPI.wrapNativeBiome( + Biomes.END_MIDLANDS, + 0.5F, + InternalBiomeAPI.OTHER_END_LAND + ); + + public static final BCLBiome END_HIGHLANDS = InternalBiomeAPI.wrapNativeBiome( + Biomes.END_HIGHLANDS, + END_MIDLANDS, + 8, + 0.5F, + InternalBiomeAPI.OTHER_END_LAND + ); + + + public static final BCLBiome END_BARRENS = InternalBiomeAPI.wrapNativeBiome( + Biomes.END_BARRENS, + InternalBiomeAPI.OTHER_END_BARRENS + ); + + public static final BCLBiome SMALL_END_ISLANDS = InternalBiomeAPI.wrapNativeBiome( + Biomes.SMALL_END_ISLANDS, + InternalBiomeAPI.OTHER_END_VOID + ); /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. @@ -189,36 +223,6 @@ public class BiomeAPI { return registerSubBiome(parent, subBiome, dim); } - /** - * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. - * - * @param bclBiome {@link BCLBiome} - * @return {@link BCLBiome} - */ - public static BCLBiome registerNetherBiome(BCLBiome bclBiome) { - registerBiome(bclBiome, BiomeType.BCL_NETHER); - - ResourceKey key = getBiomeKey(bclBiome.getBiome()); - if (bclBiome.allowFabricRegistration()) { - bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); - } - return bclBiome; - } - - /** - * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. - * - * @param biome {@link BCLBiome} - * @return {@link BCLBiome} - */ - public static BCLBiome registerNetherBiome(Biome biome) { - BCLBiome bclBiome = new BCLBiome(biome, null); - registerBiome(bclBiome, BiomeType.OTHER_NETHER); - return bclBiome; - } - /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). @@ -232,47 +236,16 @@ public class BiomeAPI { float weight = biome.getGenChance(); ResourceKey key = getBiomeKey(biome.getBiome()); if (biome.allowFabricRegistration()) { - TheEndBiomes.addHighlandsBiome(key, weight); - TheEndBiomes.addMidlandsBiome(key, key, weight); if (biome.isEdgeBiome()) { ResourceKey parentKey = getBiomeKey(biome.getParentBiome().getBiome()); TheEndBiomes.addMidlandsBiome(parentKey, key, weight); + } else { + TheEndBiomes.addHighlandsBiome(key, weight); } } return biome; } - /** - * Register {@link BCLBiome} wrapper for {@link Biome}. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). - * - * @param biome {@link BCLBiome} - * @return {@link BCLBiome} - */ - public static BCLBiome registerEndLandBiome(Holder biome) { - BCLBiome bclBiome = new BCLBiome(biome.value(), null); - - registerBiome(bclBiome, BiomeType.OTHER_END_LAND); - return bclBiome; - } - - /** - * Register {@link BCLBiome} wrapper for {@link Biome}. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). - * - * @param biome {@link BCLBiome}; - * @param genChance float generation chance. - * @return {@link BCLBiome} - */ - public static BCLBiome registerEndLandBiome(Holder biome, float genChance) { - BCLBiome bclBiome = new BCLBiome( - biome.value(), - VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() - ); - - registerBiome(bclBiome, BiomeType.OTHER_END_LAND); - return bclBiome; - } /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. @@ -294,18 +267,44 @@ public class BiomeAPI { /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a center island + * biome (will generate only on the center island). * * @param biome {@link BCLBiome} * @return {@link BCLBiome} */ - public static BCLBiome registerEndVoidBiome(Holder biome) { - BCLBiome bclBiome = new BCLBiome(biome.value(), null); + public static BCLBiome registerEndCenterBiome(BCLBiome biome) { + registerBiome(biome, BiomeType.BCL_END_CENTER); - registerBiome(bclBiome, BiomeType.OTHER_END_VOID); - return bclBiome; + float weight = biome.getGenChance(); + ResourceKey key = getBiomeKey(biome.getBiome()); + if (biome.allowFabricRegistration()) { + TheEndBiomes.addMainIslandBiome(key, weight); + } + return biome; } + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a barrens island + * biome (will generate on the edge of midland biomes on the larger islands). + * + * @param biome {@link BCLBiome} + * @return {@link BCLBiome} + */ + public static BCLBiome registerEndBarrensBiome(BCLBiome highlandBiome, BCLBiome biome) { + registerBiome(biome, BiomeType.BCL_END_BARRENS); + + float weight = biome.getGenChance(); + ResourceKey key = getBiomeKey(biome.getBiome()); + if (biome.allowFabricRegistration()) { + ResourceKey parentKey = getBiomeKey(highlandBiome.getBiome()); + TheEndBiomes.addBarrensBiome(parentKey, key, weight); + } + return biome; + } + + public static BCLBiome registerEndBiome(Holder biome) { BCLBiome bclBiome = new BCLBiome(biome.value(), null); @@ -320,23 +319,6 @@ public class BiomeAPI { return bclBiome; } - /** - * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). - * - * @param biome {@link BCLBiome}. - * @param genChance float generation chance. - * @return {@link BCLBiome} - */ - public static BCLBiome registerEndVoidBiome(Holder biome, float genChance) { - BCLBiome bclBiome = new BCLBiome( - biome.value(), - VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() - ); - - registerBiome(bclBiome, BiomeType.OTHER_END_VOID); - return bclBiome; - } /** * Get {@link BCLBiome} from {@link Biome} instance on server. Used to convert world biomes to BCLBiomes. @@ -532,6 +514,14 @@ public class BiomeAPI { return wasRegisteredAs(biomeID, BiomeType.END_VOID); } + public static boolean wasRegisteredAsEndCenterBiome(ResourceLocation biomeID) { + return wasRegisteredAs(biomeID, BiomeType.END_CENTER); + } + + public static boolean wasRegisteredAsEndBarrensBiome(ResourceLocation biomeID) { + return wasRegisteredAs(biomeID, BiomeType.END_BARRENS); + } + /** * Registers new biome modification for specified dimension. Will work both for mod and datapack biomes. * @@ -845,4 +835,84 @@ public class BiomeAPI { } return features.get(index).stream().collect(Collectors.toList()); } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. + * + * @param bclBiome {@link BCLBiome} + * @return {@link BCLBiome} + */ + public static BCLBiome registerNetherBiome(BCLBiome bclBiome) { + registerBiome(bclBiome, BiomeType.BCL_NETHER); + + ResourceKey key = getBiomeKey(bclBiome.getBiome()); + if (bclBiome.allowFabricRegistration()) { + bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); + } + return bclBiome; + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. + * + * @param biome {@link BCLBiome} + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerNetherBiome(Biome biome) { + return InternalBiomeAPI.wrapNativeBiome(biome, -1, InternalBiomeAPI.OTHER_NETHER); + } + + @Deprecated(forRemoval = true) + public static BCLBiome registerEndLandBiome(Holder biome) { + return InternalBiomeAPI.wrapNativeBiome(biome.unwrapKey().orElseThrow(), InternalBiomeAPI.OTHER_END_LAND); + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). + * + * @param biome {@link BCLBiome} + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerEndVoidBiome(Holder biome) { + return InternalBiomeAPI.wrapNativeBiome(biome.unwrapKey().orElseThrow(), InternalBiomeAPI.OTHER_END_VOID); + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome {@link BCLBiome}; + * @param genChance float generation chance. + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerEndLandBiome(Holder biome, float genChance) { + return InternalBiomeAPI.wrapNativeBiome( + biome.unwrapKey().orElseThrow(), + genChance, + InternalBiomeAPI.OTHER_END_LAND + ); + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). + * + * @param biome {@link BCLBiome}. + * @param genChance float generation chance. + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerEndVoidBiome(Holder biome, float genChance) { + return InternalBiomeAPI.wrapNativeBiome( + biome.unwrapKey().orElseThrow(), + genChance, + InternalBiomeAPI.OTHER_END_VOID + ); + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java index a1b273e4..2f0cffcd 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java @@ -34,8 +34,30 @@ import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; import java.util.stream.Stream; +import org.jetbrains.annotations.ApiStatus; +@ApiStatus.Internal public class InternalBiomeAPI { + public static final BiomeAPI.BiomeType OTHER_NETHER = new BiomeAPI.BiomeType( + "OTHER_NETHER", + BiomeAPI.BiomeType.NETHER + ); + public static final BiomeAPI.BiomeType OTHER_END_LAND = new BiomeAPI.BiomeType( + "OTHER_END_LAND", + BiomeAPI.BiomeType.END_LAND + ); + public static final BiomeAPI.BiomeType OTHER_END_VOID = new BiomeAPI.BiomeType( + "OTHER_END_VOID", + BiomeAPI.BiomeType.END_VOID + ); + public static final BiomeAPI.BiomeType OTHER_END_CENTER = new BiomeAPI.BiomeType( + "OTHER_END_CENTER", + BiomeAPI.BiomeType.END_CENTER + ); + public static final BiomeAPI.BiomeType OTHER_END_BARRENS = new BiomeAPI.BiomeType( + "OTHER_END_BARRENS", + BiomeAPI.BiomeType.END_BARRENS + ); static final Map CLIENT = Maps.newHashMap(); static final Map, Integer> FEATURE_ORDER = Maps.newHashMap(); static final MutableInt FEATURE_ORDER_ID = new MutableInt(0); @@ -246,6 +268,94 @@ public class InternalBiomeAPI { private static final Set BIOMES_TO_SORT = Sets.newHashSet(); + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @return {@link BCLBiome} + */ + public static BCLBiome wrapNativeBiome(ResourceKey biome, BiomeAPI.BiomeType type) { + return wrapNativeBiome(biome, -1, type); + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @param genChance generation chance. If <0 the default genChance is used + * @return {@link BCLBiome} + */ + public static BCLBiome wrapNativeBiome(ResourceKey biome, float genChance, BiomeAPI.BiomeType type) { + return wrapNativeBiome( + biome, + genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build(), + type + ); + } + + public static BCLBiome wrapNativeBiome( + ResourceKey biome, + BCLBiome edgeBiome, + int edgeBiomeSize, + float genChance, + BiomeAPI.BiomeType type + ) { + VanillaBiomeSettings.Builder settings = VanillaBiomeSettings.createVanilla(); + if (genChance >= 0) settings.setGenChance(genChance); + settings.setEdge(edgeBiome); + settings.setEdgeSize(edgeBiomeSize); + return wrapNativeBiome(biome, settings.build(), type); + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @param setings the {@link VanillaBiomeSettings} to use + * @return {@link BCLBiome} + */ + private static BCLBiome wrapNativeBiome( + ResourceKey biome, + VanillaBiomeSettings setings, + BiomeAPI.BiomeType type + ) { + BCLBiome bclBiome = BiomeAPI.getBiome(biome.location()); + if (bclBiome == BiomeAPI.EMPTY_BIOME) { + bclBiome = new BCLBiome( + BiomeAPI.getFromRegistry(biome).value(), + setings + ); + } + + BiomeAPI.registerBiome(bclBiome, type); + return bclBiome; + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @param genChance generation chance. + * @return {@link BCLBiome} + */ + static BCLBiome wrapNativeBiome(Biome biome, float genChance, BiomeAPI.BiomeType type) { + BCLBiome bclBiome = BiomeAPI.getBiome(biome); + if (bclBiome == BiomeAPI.EMPTY_BIOME) { + bclBiome = new BCLBiome( + biome, + genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() + ); + } + + BiomeAPI.registerBiome(bclBiome, type); + return bclBiome; + } + static { DynamicRegistrySetupCallback.EVENT.register(registryManager -> { Optional> oBiomeRegistry = registryManager.registry(Registry.BIOME_REGISTRY); diff --git a/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java b/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java index 29a988f2..65916b23 100644 --- a/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java +++ b/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java @@ -187,7 +187,11 @@ public class WorldSetupScreen extends BCLibScreen { ? BCLEndBiomeSourceConfig.EndBiomeGeneratorType.PAULEVS : BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA, generateEndVoid.isChecked(), - BCLEndBiomeSourceConfig.DEFAULT.innerVoidRadiusSquared + BCLEndBiomeSourceConfig.DEFAULT.innerVoidRadiusSquared, + BCLEndBiomeSourceConfig.DEFAULT.centerBiomesSize, + BCLEndBiomeSourceConfig.DEFAULT.voidBiomesSize, + BCLEndBiomeSourceConfig.DEFAULT.landBiomesSize, + BCLEndBiomeSourceConfig.DEFAULT.barrensBiomesSize ); ChunkGenerator endGenerator = betterxDimensions.get(LevelStem.END); diff --git a/src/main/java/org/betterx/bclib/config/BiomesConfig.java b/src/main/java/org/betterx/bclib/config/BiomesConfig.java new file mode 100644 index 00000000..c096b86e --- /dev/null +++ b/src/main/java/org/betterx/bclib/config/BiomesConfig.java @@ -0,0 +1,101 @@ +package org.betterx.bclib.config; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; + +import java.util.*; + +public class BiomesConfig extends PathConfig { + + private Map> BIOME_INCLUDE_LIST = null; + private Map> BIOME_EXCLUDE_LIST = null; + + + public static final BiomeAPI.BiomeType[] endTypes = { + BiomeAPI.BiomeType.END_LAND, + BiomeAPI.BiomeType.END_VOID, + BiomeAPI.BiomeType.END_CENTER, + BiomeAPI.BiomeType.END_BARRENS + }; + + public static final BiomeAPI.BiomeType[] netherTypes = { + BiomeAPI.BiomeType.NETHER + }; + + private static final BiomeAPI.BiomeType[] includeTypes = all(); + private static final BiomeAPI.BiomeType[] excludeTypes = {BiomeAPI.BiomeType.NETHER, BiomeAPI.BiomeType.END}; + + public BiomesConfig() { + super(BCLib.MOD_ID, "biomes", false); + for (var type : includeTypes) { + keeper.registerEntry( + new ConfigKey(type.getName(), "force_include"), + new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) + ); + } + for (var type : excludeTypes) { + keeper.registerEntry( + new ConfigKey(type.getName(), "force_exclude"), + new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) + ); + } + } + + private static BiomeAPI.BiomeType[] all() { + BiomeAPI.BiomeType[] res = new BiomeAPI.BiomeType[endTypes.length + netherTypes.length]; + System.arraycopy(netherTypes, 0, res, 0, netherTypes.length); + System.arraycopy(endTypes, 0, res, netherTypes.length, endTypes.length); + return res; + } + + private List getBiomeIncludeList(BiomeAPI.BiomeType type) { + var entry = getEntry( + "force_include", + type.getName(), + ConfigKeeper.StringArrayEntry.class + ); + if (entry == null) + return List.of(); + return entry.getValue(); + } + + private List getBiomeExcludeList(BiomeAPI.BiomeType type) { + var entry = getEntry( + "force_exclude", + type.getName(), + ConfigKeeper.StringArrayEntry.class + ); + if (entry == null) + return List.of(); + return entry.getValue(); + } + + public List getIncludeMatching(BiomeAPI.BiomeType type) { + return getBiomeIncludeMap().entrySet() + .stream() + .filter(e -> e.getKey().is(type)) + .map(e -> e.getValue()) + .flatMap(Collection::stream) + .toList(); + } + + public Map> getBiomeIncludeMap() { + if (BIOME_INCLUDE_LIST == null) { + BIOME_INCLUDE_LIST = new HashMap<>(); + for (BiomeAPI.BiomeType type : includeTypes) { + BIOME_INCLUDE_LIST.put(type, getBiomeIncludeList(type)); + } + } + return BIOME_INCLUDE_LIST; + } + + public Map> getBiomeExcludeMap() { + if (BIOME_EXCLUDE_LIST == null) { + BIOME_EXCLUDE_LIST = new HashMap<>(); + for (BiomeAPI.BiomeType type : excludeTypes) { + BIOME_EXCLUDE_LIST.put(type, getBiomeExcludeList(type)); + } + } + return BIOME_EXCLUDE_LIST; + } +} diff --git a/src/main/java/org/betterx/bclib/config/Configs.java b/src/main/java/org/betterx/bclib/config/Configs.java index ac54aa55..cb099f8a 100644 --- a/src/main/java/org/betterx/bclib/config/Configs.java +++ b/src/main/java/org/betterx/bclib/config/Configs.java @@ -18,7 +18,7 @@ public class Configs { public static final MainConfig MAIN_CONFIG = new MainConfig(); public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes"); - public static final PathConfig BIOMES_CONFIG = new PathConfig(BCLib.MOD_ID, "biomes", false); + public static final BiomesConfig BIOMES_CONFIG = new BiomesConfig(); public static final String MAIN_PATCH_CATEGORY = "patches"; @@ -29,6 +29,7 @@ public class Configs { BIOMES_CONFIG.saveChanges(); } + static { BIOMES_CONFIG.keeper.registerEntry( new ConfigKey("end_land_biomes", "force_include"), diff --git a/src/main/java/org/betterx/bclib/interfaces/TheEndBiomeDataAccessor.java b/src/main/java/org/betterx/bclib/interfaces/TheEndBiomesAccessor.java similarity index 94% rename from src/main/java/org/betterx/bclib/interfaces/TheEndBiomeDataAccessor.java rename to src/main/java/org/betterx/bclib/interfaces/TheEndBiomesAccessor.java index c18ae9cd..aa39ebb6 100644 --- a/src/main/java/org/betterx/bclib/interfaces/TheEndBiomeDataAccessor.java +++ b/src/main/java/org/betterx/bclib/interfaces/TheEndBiomesAccessor.java @@ -3,7 +3,7 @@ package org.betterx.bclib.interfaces; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; -public interface TheEndBiomeDataAccessor { +public interface TheEndBiomesAccessor { boolean bcl_canGenerateAsEndBiome(ResourceKey key); boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey key); diff --git a/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java b/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java deleted file mode 100644 index 1fc7b9c8..00000000 --- a/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.betterx.bclib.mixin.common; - -import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - -import net.fabricmc.fabric.impl.biome.TheEndBiomeData; -import net.fabricmc.fabric.impl.biome.WeightedPicker; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.Map; - -@Mixin(value = TheEndBiomeData.class, remap = false) -public class TheEndBiomeDataMixin implements TheEndBiomeDataAccessor { - @Shadow - @Final - private static Map, WeightedPicker>> END_BIOMES_MAP; - @Shadow - @Final - private static Map, WeightedPicker>> END_MIDLANDS_MAP; - @Shadow - @Final - private static Map, WeightedPicker>> END_BARRENS_MAP; - - public boolean bcl_canGenerateAsEndBiome(ResourceKey key) { - return END_BIOMES_MAP != null && END_BIOMES_MAP.containsKey(key); - } - - public boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey key) { - return END_MIDLANDS_MAP != null && END_MIDLANDS_MAP.containsKey(key); - } - - public boolean bcl_canGenerateAsEndBarrensBiome(ResourceKey key) { - return END_BARRENS_MAP != null && END_BARRENS_MAP.containsKey(key); - } -} diff --git a/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java b/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java new file mode 100644 index 00000000..7a3aa38b --- /dev/null +++ b/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java @@ -0,0 +1,64 @@ +package org.betterx.bclib.mixin.common; + +import org.betterx.bclib.api.v2.generator.TheEndBiomesHelper; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.Biome; + +import net.fabricmc.fabric.api.biome.v1.TheEndBiomes; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = TheEndBiomes.class, remap = false) +public class TheEndBiomesMixin { + @Inject(method = "addBarrensBiome", at = @At("HEAD")) + private static void bcl_registerBarrens( + ResourceKey highlands, + ResourceKey barrens, + double weight, + CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_BARRENS, barrens); + } + + @Inject(method = "addMidlandsBiome", at = @At("HEAD")) + private static void bcl_registerMidlands( + ResourceKey highlands, + ResourceKey midlands, + double weight, + CallbackInfo ci + ) { + BCLBiome highland = InternalBiomeAPI.wrapNativeBiome(highlands, InternalBiomeAPI.OTHER_END_LAND); + BCLBiome midland = InternalBiomeAPI.wrapNativeBiome(midlands, InternalBiomeAPI.OTHER_END_LAND); + if (highland != null) { + highland.addEdge(midland); + } + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_LAND, midlands); + } + + @Inject(method = "addSmallIslandsBiome", at = @At("HEAD")) + private static void bcl_registerSmallIslands( + ResourceKey biome, double weight, CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_VOID, biome); + } + + @Inject(method = "addHighlandsBiome", at = @At("HEAD")) + private static void bcl_registerHighlands( + ResourceKey biome, double weight, CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_LAND, biome); + } + + @Inject(method = "addMainIslandBiome", at = @At("HEAD")) + private static void bcl_registerMainIsnalnd( + ResourceKey biome, double weight, CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_CENTER, biome); + } +} diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 29267b7d..7e1f5ebb 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -33,7 +33,7 @@ "ShovelItemAccessor", "StructuresAccessor", "SurfaceRulesContextAccessor", - "TheEndBiomeDataMixin", + "TheEndBiomesMixin", "WorldGenRegionMixin", "elytra.LivingEntityMixin", "shears.BeehiveBlockMixin",