diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index f46e3a5a..8f479d08 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -40,9 +40,9 @@ import ru.bclib.config.Configs; import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor; import ru.bclib.mixin.common.MobSpawnSettingsAccessor; import ru.bclib.mixin.common.StructureSettingsAccessor; +import ru.bclib.util.CollectionsUtil; import ru.bclib.util.MHelper; import ru.bclib.world.biomes.BCLBiome; -import ru.bclib.world.biomes.BCLBiomeDef; import ru.bclib.world.biomes.FabricBiomesData; import ru.bclib.world.features.BCLFeature; import ru.bclib.world.generator.BiomePicker; @@ -425,7 +425,7 @@ public class BiomeAPI { Set biomes = source.possibleBiomes(); biomes.forEach(biome -> { - ResourceLocation biomeID = getBiomeID(biome); + ResourceLocation biomeID = getBiomeID(biome); boolean modify = isDatapackBiome(biomeID); if (biome != BuiltinRegistries.BIOME.get(biomeID)) { modify = true; @@ -459,13 +459,24 @@ public class BiomeAPI { * @param step a {@link Decoration} step for the feature. */ public static void addBiomeFeature(Biome biome, PlacedFeature feature, Decoration step) { -// BiomeModificationContextImpl ctx = new BiomeModificationContextImpl(,,biome); -// ctx.getGenerationSettings().addFeature(step, feature.); BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings(); - List>> biomeFeatures = getMutableList(accessor.bcl_getFeatures()); - List> list = getList(step, biomeFeatures); - list.add(() -> feature); - accessor.bcl_setFeatures(biomeFeatures); + List>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); + Set set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet()); + List> features = getFeaturesList(allFeatures, step); + features.add(() -> feature); + set.add(feature); + accessor.bclib_setFeatures(allFeatures); + accessor.bclib_setFeatureSet(set); + } + + /** + * Adds new features to existing biome. + * @param biomeID {@link ResourceLocation} of the {@link Biome} to add features in. + * @param feature {@link ConfiguredFeature} to add. + * @param step a {@link Decoration} step for the feature. + */ + private static void addBiomeFeature(ResourceLocation biomeID, PlacedFeature feature, Decoration step) { + addBiomeFeature(BuiltinRegistries.BIOME.get(biomeID), feature, step); } /** @@ -474,9 +485,16 @@ public class BiomeAPI { * @param features array of {@link BCLFeature} to add. */ public static void addBiomeFeatures(Biome biome, BCLFeature... features) { + BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings(); + List>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); + Set set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet()); for (BCLFeature feature: features) { - addBiomeFeature(biome, feature.getPlacedFeature(), feature.getDecoration()); + List> featureList = getFeaturesList(allFeatures, feature.getDecoration()); + featureList.add(() -> feature.getPlacedFeature()); + set.add(feature.getPlacedFeature()); } + accessor.bclib_setFeatures(allFeatures); + accessor.bclib_setFeatureSet(set); } /** @@ -603,6 +621,16 @@ public class BiomeAPI { return input; } + private static List> getFeaturesList(List>> features, Decoration step) { + int index = step.ordinal(); + while (features.size() <= index) { + features.add(Lists.newArrayList()); + } + List> mutable = CollectionsUtil.getMutable(features.get(index)); + features.set(index, mutable); + return mutable; + } + private static Map getMutableMap(Map input) { if (/*input instanceof ImmutableMap*/ !(input instanceof HashMap ||input instanceof EnumMap)) { return Maps.newHashMap(input); diff --git a/src/main/java/ru/bclib/mixin/common/BiomeGenerationSettingsAccessor.java b/src/main/java/ru/bclib/mixin/common/BiomeGenerationSettingsAccessor.java index f8037293..b31f859e 100644 --- a/src/main/java/ru/bclib/mixin/common/BiomeGenerationSettingsAccessor.java +++ b/src/main/java/ru/bclib/mixin/common/BiomeGenerationSettingsAccessor.java @@ -7,15 +7,21 @@ import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; import java.util.List; +import java.util.Set; import java.util.function.Supplier; @Mixin(BiomeGenerationSettings.class) public interface BiomeGenerationSettingsAccessor { @Accessor("features") - List>> bcl_getFeatures(); + List>> bclib_getFeatures(); @Accessor("features") @Mutable - void bcl_setFeatures(List>> value); + void bclib_setFeatures(List>> value); + + @Accessor("featureSet") + Set bclib_getFeatureSet(); + + @Accessor("featureSet") + void bclib_setFeatureSet(Set features); } - diff --git a/src/main/java/ru/bclib/util/CollectionsUtil.java b/src/main/java/ru/bclib/util/CollectionsUtil.java new file mode 100644 index 00000000..609d392a --- /dev/null +++ b/src/main/java/ru/bclib/util/CollectionsUtil.java @@ -0,0 +1,46 @@ +package ru.bclib.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class CollectionsUtil { + /** + * Will return mutable copy of list. + * @param list {@link List} to make mutable. + * @return {@link ArrayList} or original {@link List} if it is mutable. + */ + public static List getMutable(List list) { + if (list instanceof ArrayList) { + return list; + } + return new ArrayList<>(list); + } + + /** + * Will return mutable copy of set. + * @param set {@link Set} to make mutable. + * @return {@link HashSet} or original {@link Set} if it is mutable. + */ + public static Set getMutable(Set set) { + if (set instanceof HashSet) { + return set; + } + return new HashSet<>(set); + } + + /** + * Will return mutable copy of map. + * @param map {@link Map} to make mutable. + * @return {@link HashMap} or original {@link Map} if it is mutable. + */ + public static Map getMutable(Map map) { + if (map instanceof HashMap) { + return map; + } + return new HashMap<>(map); + } +}