diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index 94c29ef7..58feb4f9 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -30,7 +30,6 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeGenerationSettings; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.Biomes; -import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -50,6 +49,7 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature; import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.Nullable; import ru.bclib.BCLib; +import ru.bclib.api.tag.CommonBiomeTags; import ru.bclib.api.tag.TagAPI; import ru.bclib.entity.BCLEntityWrapper; import ru.bclib.interfaces.BiomeSourceAccessor; @@ -60,12 +60,10 @@ import ru.bclib.interfaces.SurfaceRuleProvider; import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor; import ru.bclib.mixin.common.MobSpawnSettingsAccessor; import ru.bclib.util.CollectionsUtil; -import ru.bclib.util.MHelper; import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.biomes.FabricBiomesData; import ru.bclib.world.biomes.VanillaBiomeSettings; import ru.bclib.world.features.BCLFeature; -import ru.bclib.world.generator.BiomePicker; import java.util.HashSet; import java.util.List; @@ -73,13 +71,14 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; -import java.util.Random;import net.minecraft.util.RandomSource; + import net.minecraft.world.level.levelgen.structure.Structure; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Collectors; +import java.util.stream.Stream; public class BiomeAPI { enum Dimension {OVERWORLD, NETHER, END_LAND, END_VOID, UNDEFINED}; @@ -98,6 +97,7 @@ public class BiomeAPI { private static final MutableInt FEATURE_ORDER_ID = new MutableInt(0); private static final Map>>> MODIFICATIONS = Maps.newHashMap(); + private static final Map>>> TAG_ADDERS = Maps.newHashMap(); private static final Map SURFACE_RULES = Maps.newHashMap(); private static final Set MODIFIED_SURFACE_PROVIDERS = new HashSet<>(8); @@ -171,7 +171,17 @@ public class BiomeAPI { } ID_MAP.put(bclbiome.getID(), bclbiome); DIMENSION_MAP.put(bclbiome.getID(), dim); + + if (dim==Dimension.NETHER) { + + TagAPI.addBiomeTag(BiomeTags.IS_NETHER, bclbiome.getBiome()); + TagAPI.addBiomeTag(CommonBiomeTags.IN_NETHER, bclbiome.getBiome()); + } else if (dim==Dimension.END_LAND || dim==Dimension.END_VOID) { + TagAPI.addBiomeTag(BiomeTags.IS_END, bclbiome.getBiome()); + } + bclbiome.afterRegistration(); + return bclbiome; } @@ -180,11 +190,7 @@ public class BiomeAPI { registerBiome(subBiome, dim); parent.addSubBiome(subBiome); - if (dim==Dimension.NETHER) { - TagAPI.addBiomeTag(BiomeTags.IS_NETHER, subBiome.getBiome()); - } else if (dim==Dimension.END_LAND || dim==Dimension.END_VOID) { - TagAPI.addBiomeTag(BiomeTags.IS_END, subBiome.getBiome()); - } + return subBiome; } @@ -204,7 +210,6 @@ public class BiomeAPI { ResourceKey key = BiomeAPI.getBiomeKeyOrThrow(bclBiome.getBiomeHolder()); bclBiome.forEachClimateParameter(p -> NetherBiomeData.addNetherBiome(key, p)); - TagAPI.addBiomeTag(BiomeTags.IS_NETHER, bclBiome.getBiome()); return bclBiome; } @@ -217,7 +222,6 @@ public class BiomeAPI { public static BCLBiome registerNetherBiome(Biome biome) { BCLBiome bclBiome = new BCLBiome(biome, null); registerBiome(bclBiome, Dimension.NETHER); - TagAPI.addBiomeTag(BiomeTags.IS_NETHER, bclBiome.getBiome()); return bclBiome; } @@ -502,6 +506,52 @@ public class BiomeAPI { public static void registerEndBiomeModification(BiConsumer> modification) { registerBiomeModification(Level.END, modification); } + + /** + * For internal use only + */ + public static void _runTagAdders(){ + for (var mod:TAG_ADDERS.entrySet()) { + Stream s = null; + if (mod.getKey()==Level.NETHER) s = DIMENSION_MAP.entrySet().stream().filter(e ->e.getValue() == Dimension.NETHER).map(e -> e.getKey()); + else if (mod.getKey()==Level.END) s = DIMENSION_MAP.entrySet().stream().filter(e ->e.getValue() == Dimension.END_VOID || e.getValue()==Dimension.END_LAND).map(e -> e.getKey()); + if (s!=null) { + s.forEach(id -> { + BCLBiome b = BiomeAPI.getBiome(id); + Holder biomeHolder = b.getBiomeHolder(); + if (biomeHolder.isBound()) { + mod.getValue().forEach(c -> c.accept(id, biomeHolder)); + } + }); + } + } + } + + /** + * Registers new biome modification for specified dimension. Will work both for mod and datapack biomes. + * @param dimensionID {@link ResourceLocation} dimension ID, example: Level.OVERWORLD or "minecraft:overworld". + * @param modification {@link BiConsumer} with {@link ResourceKey} biome ID and {@link Biome} parameters. + */ + public static void onFinishingBiomeTags(ResourceKey dimensionID, BiConsumer> modification) { + List>> modifications = TAG_ADDERS.computeIfAbsent(dimensionID, k -> Lists.newArrayList()); + modifications.add(modification); + } + + /** + * Registers new biome modification for the Nether. Will work both for mod and datapack biomes. + * @param modification {@link BiConsumer} with {@link ResourceLocation} biome ID and {@link Biome} parameters. + */ + public static void onFinishingNetherBiomeTags(BiConsumer> modification) { + onFinishingBiomeTags(Level.NETHER, modification); + } + + /** + * Registers new biome modification for the End. Will work both for mod and datapack biomes. + * @param modification {@link BiConsumer} with {@link ResourceLocation} biome ID and {@link Biome} parameters. + */ + public static void onFinishingEndBiomeTags(BiConsumer> modification) { + onFinishingBiomeTags(Level.END, modification); + } /** * Will apply biome modifications to world, internal usage only. diff --git a/src/main/java/ru/bclib/api/tag/CommonBiomeTags.java b/src/main/java/ru/bclib/api/tag/CommonBiomeTags.java new file mode 100644 index 00000000..4635bc4e --- /dev/null +++ b/src/main/java/ru/bclib/api/tag/CommonBiomeTags.java @@ -0,0 +1,9 @@ +package ru.bclib.api.tag; + +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; + +public class CommonBiomeTags { + public static final TagKey IN_NETHER = TagAPI.makeCommonBiomeTag("in_nether"); +} diff --git a/src/main/java/ru/bclib/api/tag/TagAPI.java b/src/main/java/ru/bclib/api/tag/TagAPI.java index 03b7b3f6..ad0667df 100644 --- a/src/main/java/ru/bclib/api/tag/TagAPI.java +++ b/src/main/java/ru/bclib/api/tag/TagAPI.java @@ -139,6 +139,10 @@ public class TagAPI { public static TagKey makeCommonItemTag(String name) { return ITEMS.makeCommonTag(name); } + + public static TagKey makeCommonBiomeTag(String name) { + return BIOMES.makeCommonTag(name); + } /** * Initializes basic tags. Should be called only in BCLib main class. @@ -265,7 +269,9 @@ public class TagAPI { public static void addItemTag(TagKey tagID, Item... items) { ITEMS.add(tagID, items); } - + + + /** * Automatically called in {@link net.minecraft.tags.TagLoader#loadAndBuild(ResourceManager)}. *

@@ -277,9 +283,10 @@ public class TagAPI { * @return The {@code tagsMap} Parameter. */ public static Map apply(String directory, Map tagsMap) { + TagType type = TYPES.get(directory); if (type!=null){ - type.forEach((id, ids) -> apply(tagsMap.computeIfAbsent(id, key -> Tag.Builder.tag()), ids)); + type.apply(tagsMap); } // final BiConsumer> consumer; diff --git a/src/main/java/ru/bclib/api/tag/TagType.java b/src/main/java/ru/bclib/api/tag/TagType.java index 8ab76b96..735db4ce 100644 --- a/src/main/java/ru/bclib/api/tag/TagType.java +++ b/src/main/java/ru/bclib/api/tag/TagType.java @@ -4,12 +4,15 @@ import net.minecraft.core.DefaultedRegistry; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.Tag; import net.minecraft.tags.TagKey; import net.minecraft.tags.TagManager; import net.minecraft.world.level.biome.Biome; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import ru.bclib.BCLib; +import ru.bclib.api.biomes.BiomeAPI; import java.util.Map; import java.util.Set; @@ -17,6 +20,7 @@ import java.util.function.BiConsumer; import java.util.function.Function; public class TagType { + boolean isFrozen = false; public static class RegistryBacked extends Simple{ private final DefaultedRegistry registry; @@ -121,6 +125,7 @@ public class TagType { } public void addUntyped(TagKey tagID, ResourceLocation... elements) { + if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (ResourceLocation id : elements) { if (id != null) { @@ -141,6 +146,7 @@ public class TagType { * @param elements array of Elements to add into tag. */ protected void add(TagKey tagID, T... elements) { + if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (T element : elements) { ResourceLocation id = locationProvider.apply(element); @@ -158,6 +164,7 @@ public class TagType { @Deprecated(forRemoval = true) protected void add(ResourceLocation tagID, T... elements) { + if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (T element : elements) { ResourceLocation id = locationProvider.apply(element); @@ -177,4 +184,10 @@ public class TagType { public void forEach(BiConsumer> consumer) { tags.forEach(consumer); } + public void apply(Map tagsMap){ + if (Registry.BIOME_REGISTRY.equals(registryKey)) BiomeAPI._runTagAdders(); + + this.isFrozen = true; + this.forEach((id, ids) -> TagAPI.apply(tagsMap.computeIfAbsent(id, key -> Tag.Builder.tag()), ids)); + } }