diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java index 27fe8379..446f2aff 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java @@ -6,6 +6,7 @@ import org.betterx.worlds.together.world.event.WorldBootstrap; import com.mojang.serialization.Codec; import com.mojang.serialization.Lifecycle; +import net.minecraft.core.Holder; import net.minecraft.core.MappedRegistry; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; @@ -28,6 +29,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Stream; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class BCLBiomeRegistry { @@ -101,6 +103,25 @@ public class BCLBiomeRegistry { registerForDatagen(biome); } + public static BCLBiome registerIfUnknown(Holder biomeHolder, @NotNull BiomeAPI.BiomeType intendedType) { + if (biomeHolder == null) return null; + return registerIfUnknown(biomeHolder.unwrapKey().orElse(null), intendedType); + } + + public static BCLBiome registerIfUnknown(ResourceKey biomeKey, @NotNull BiomeAPI.BiomeType intendedType) { + if (biomeKey != null) { + if (!hasBiome(biomeKey, BCLBiomeRegistry.registryOrNull())) { + final var bclBiome = new BCLBiome( + biomeKey.location(), + intendedType + ); + BCLBiomeRegistry.register(bclBiome); + return bclBiome; + } + } + return null; + } + public static boolean hasBiome(ResourceKey key, Registry bclBiomes) { return hasBiome(key.location(), bclBiomes); } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index be306655..ac4b56ce 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -6,6 +6,7 @@ import org.betterx.bclib.interfaces.SurfaceMaterialProvider; import org.betterx.bclib.mixin.common.BiomeGenerationSettingsAccessor; import org.betterx.bclib.mixin.common.MobSpawnSettingsAccessor; import org.betterx.bclib.util.CollectionsUtil; +import org.betterx.worlds.together.tag.v3.CommonBiomeTags; import org.betterx.worlds.together.tag.v3.TagManager; import org.betterx.worlds.together.world.event.WorldBootstrap; @@ -301,8 +302,19 @@ public class BiomeAPI { TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome.getBiomeKey()); } else if (dim != null && dim.is(BiomeType.END)) { TagManager.BIOMES.add(BiomeTags.IS_END, bclbiome.getBiomeKey()); + + if (dim.is(BiomeType.END_VOID)) { + TagManager.BIOMES.add(CommonBiomeTags.IS_SMALL_END_ISLAND, bclbiome.getBiomeKey()); + } else if (dim.is(BiomeType.END_BARRENS)) { + TagManager.BIOMES.add(CommonBiomeTags.IS_END_BARRENS, bclbiome.getBiomeKey()); + } else if (dim.is(BiomeType.END_LAND)) { + TagManager.BIOMES.add(CommonBiomeTags.IS_END_HIGHLAND, bclbiome.getBiomeKey()); + } else if (dim.is(BiomeType.END_CENTER)) { + TagManager.BIOMES.add(CommonBiomeTags.IS_END_CENTER, bclbiome.getBiomeKey()); + } } + bclbiome.afterRegistration(); return bclbiome; diff --git a/src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java b/src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java index 0a0c0207..71a169cd 100644 --- a/src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java +++ b/src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java @@ -1,16 +1,20 @@ package org.betterx.worlds.together.levelgen; -import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; +import org.betterx.worlds.together.tag.v3.CommonBiomeTags; +import org.betterx.worlds.together.world.event.WorldBootstrap; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; +import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.BiomeTags; +import net.minecraft.tags.TagKey; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.dimension.LevelStem; @@ -24,7 +28,6 @@ class BiomeRepairHelper { RegistryAccess registryAccess, Registry dimensionRegistry ) { - Map, ChunkGenerator> dimensions = TogetherWorldPreset.loadWorldDimensions(); for (var entry : dimensionRegistry.entrySet()) { boolean didRepair = false; @@ -35,6 +38,10 @@ class BiomeRepairHelper { if (referenceGenerator instanceof EnforceableChunkGenerator enforcer) { final ChunkGenerator loadedChunkGenerator = loadedStem.generator(); + // we ensure that all biomes with a dimensional Tag are properly added to the correct biome source + // using the correct type + processBiomeTagsForDimension(key); + // if the loaded ChunkGenerator is not the one we expect from vanilla, we will load the vanilla // ones and mark all modded biomes with the respective dimension registerAllBiomesFromVanillaDimension(key); @@ -72,6 +79,33 @@ class BiomeRepairHelper { return dimensionRegistry; } + private void processBiomeTagsForDimension(ResourceKey key) { + if (key.equals(LevelStem.NETHER)) { + preprocessBiomeTags(BiomeTags.IS_NETHER, BiomeAPI.BiomeType.NETHER); + } else if (key.equals(LevelStem.END)) { + preprocessBiomeTags(CommonBiomeTags.IS_END_HIGHLAND, BiomeAPI.BiomeType.END_LAND); + preprocessBiomeTags(CommonBiomeTags.IS_END_MIDLAND, BiomeAPI.BiomeType.END_LAND); + preprocessBiomeTags(CommonBiomeTags.IS_END_BARRENS, BiomeAPI.BiomeType.END_BARRENS); + preprocessBiomeTags(CommonBiomeTags.IS_SMALL_END_ISLAND, BiomeAPI.BiomeType.END_VOID); + preprocessBiomeTags(CommonBiomeTags.IS_END_CENTER, BiomeAPI.BiomeType.END_CENTER); + preprocessBiomeTags(BiomeTags.IS_END, BiomeAPI.BiomeType.END_LAND); + } + } + + private void preprocessBiomeTags(TagKey tag, BiomeAPI.BiomeType targetType) { + if (WorldBootstrap.getLastRegistryAccess() != null) { + WorldBootstrap.getLastRegistryAccess() + .registry(tag.registry()) + .map(r -> r.getTagOrEmpty(tag)) + .ifPresent(iter -> { + for (Holder biomeHolder : iter) { + BCLBiomeRegistry.registerIfUnknown(biomeHolder, targetType); + } + }); + ; + } + } + private void registerAllBiomesFromVanillaDimension( ResourceKey key ) { @@ -81,25 +115,11 @@ class BiomeRepairHelper { if (vanillaDimensions == null) { vanillaDimensions = TogetherWorldPreset.getDimensionsMap(net.minecraft.world.level.levelgen.presets.WorldPresets.NORMAL); } - var vanillaDim = vanillaDimensions.getOrDefault(key, null); - if (vanillaDim != null && vanillaDim.getBiomeSource() != null) { - var vanillaBiomes = vanillaDim - .getBiomeSource() - .possibleBiomes(); - for (var holder : vanillaBiomes) { - ResourceKey biomeKey = holder.unwrapKey().orElse(null); - if (biomeKey != null) { - if (!BCLBiomeRegistry.hasBiome( - holder.unwrapKey().get(), - BCLBiomeRegistry.registryOrNull() - )) { - BCLBiomeRegistry.register(new BCLBiome( - biomeKey.location(), - type - )); - } - } + final ChunkGenerator vanillaDim = vanillaDimensions.getOrDefault(key, null); + if (vanillaDim != null && vanillaDim.getBiomeSource() != null) { + for (Holder biomeHolder : vanillaDim.getBiomeSource().possibleBiomes()) { + BCLBiomeRegistry.registerIfUnknown(biomeHolder, type); } } } diff --git a/src/main/java/org/betterx/worlds/together/tag/v3/CommonBiomeTags.java b/src/main/java/org/betterx/worlds/together/tag/v3/CommonBiomeTags.java new file mode 100644 index 00000000..361b2c0b --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/tag/v3/CommonBiomeTags.java @@ -0,0 +1,21 @@ +package org.betterx.worlds.together.tag.v3; + +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; + +public class CommonBiomeTags { + public static final TagKey IS_END_CENTER = TagManager.BIOMES.makeCommonTag("is_end_center"); + public static final TagKey IS_END_HIGHLAND = TagManager.BIOMES.makeCommonTag("is_end_highland"); + public static final TagKey IS_END_MIDLAND = TagManager.BIOMES.makeCommonTag("is_end_midland"); + public static final TagKey IS_END_BARRENS = TagManager.BIOMES.makeCommonTag("is_end_barrens"); + public static final TagKey IS_SMALL_END_ISLAND = TagManager.BIOMES.makeCommonTag("is_small_end_island"); + + static void prepareTags() { + TagManager.BIOMES.add(IS_END_CENTER, Biomes.THE_END); + TagManager.BIOMES.add(IS_END_HIGHLAND, Biomes.END_HIGHLANDS); + TagManager.BIOMES.add(IS_END_MIDLAND, Biomes.END_MIDLANDS); + TagManager.BIOMES.add(IS_END_BARRENS, Biomes.END_BARRENS); + TagManager.BIOMES.add(IS_SMALL_END_ISLAND, Biomes.SMALL_END_ISLANDS); + } +} diff --git a/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java b/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java index 87ad4f9b..f1c80306 100644 --- a/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java +++ b/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java @@ -85,6 +85,7 @@ public class TagManager { public static void ensureStaticallyLoaded() { CommonItemTags.prepareTags(); CommonBlockTags.prepareTags(); + CommonBiomeTags.prepareTags(); MineableTags.prepareTags(); ToolTags.prepareTags(); }