diff --git a/common/src/main/java/dev/architectury/hooks/level/biome/BiomeHooks.java b/common/src/main/java/dev/architectury/hooks/level/biome/BiomeHooks.java index 9c7f612a..2c792f58 100644 --- a/common/src/main/java/dev/architectury/hooks/level/biome/BiomeHooks.java +++ b/common/src/main/java/dev/architectury/hooks/level/biome/BiomeHooks.java @@ -362,6 +362,11 @@ public final class BiomeHooks { return settings.getCarvers(carving); } + @Override + public List> getFeatures(GenerationStep.Decoration decoration) { + return settings.features().get(decoration.ordinal()); + } + @Override public List>> getFeatures() { return settings.features(); diff --git a/common/src/main/java/dev/architectury/hooks/level/biome/GenerationProperties.java b/common/src/main/java/dev/architectury/hooks/level/biome/GenerationProperties.java index 73625b74..98eb7155 100644 --- a/common/src/main/java/dev/architectury/hooks/level/biome/GenerationProperties.java +++ b/common/src/main/java/dev/architectury/hooks/level/biome/GenerationProperties.java @@ -30,6 +30,8 @@ import java.util.function.Supplier; public interface GenerationProperties { List>> getCarvers(GenerationStep.Carving carving); + List> getFeatures(GenerationStep.Decoration decoration); + List>> getFeatures(); interface Mutable extends GenerationProperties { diff --git a/common/src/main/java/dev/architectury/registry/level/biome/BiomeModifications.java b/common/src/main/java/dev/architectury/registry/level/biome/BiomeModifications.java index 661d2267..4f0c2fcf 100644 --- a/common/src/main/java/dev/architectury/registry/level/biome/BiomeModifications.java +++ b/common/src/main/java/dev/architectury/registry/level/biome/BiomeModifications.java @@ -27,6 +27,27 @@ import net.minecraft.resources.ResourceLocation; import java.util.function.BiConsumer; import java.util.function.Predicate; +/** + * This class provides a cross-platform API to modify Biome features and properties. + * + *

Changes to the biomes are hereby done in four distinct "phases", akin to Fabric API's + * {@link net.fabricmc.fabric.api.biome.v1.ModificationPhase} enum. + * + *

The order in which these phases get processed is as follows, + * with the corresponding Forge EventPriority shown in brackets: + * + *

    + *
  1. {@linkplain #addProperties(Predicate, BiConsumer) Adding} new features to biomes. [HIGH]
  2. + *
  3. {@linkplain #removeProperties(Predicate, BiConsumer) Removing} existing features from biomes. [NORMAL]
  4. + *
  5. {@linkplain #replaceProperties(Predicate, BiConsumer) Replacing} existing features with new ones. [LOW]
  6. + *
  7. Generic {@linkplain #postProcessProperties(Predicate, BiConsumer) Post-Processing} of already modified biome features. [LOWEST]
  8. + *
+ * + * Keep in mind that it isn't strictly required that you use these phases accordingly + * (i.e., you may also add features during Post-Processing, for example); they mostly serve to + * add a predictable order to biome modifications. + */ +@SuppressWarnings("JavadocReference") public final class BiomeModifications { public static void addProperties(BiConsumer modifier) { BiomeModifications.addProperties(Predicates.alwaysTrue(), modifier); diff --git a/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java b/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java index 1f127d98..59a465e5 100644 --- a/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java +++ b/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java @@ -153,7 +153,12 @@ public class BiomeModificationsImpl { public @NotNull List>> getCarvers(GenerationStep.Carving carving) { return generation.getCarvers(carving); } - + + @Override + public List> getFeatures(GenerationStep.Decoration decoration) { + return generation.getFeatures(decoration); + } + @Override public @NotNull List>> getFeatures() { return generation.features; @@ -372,29 +377,29 @@ public class BiomeModificationsImpl { } @SubscribeEvent(priority = EventPriority.HIGH) - public static void applyAdditions(BiomeLoadingEvent event) { - modifyForPhase(event, ADDITIONS); + public static void processAdditions(BiomeLoadingEvent event) { + modifyBiome(event, ADDITIONS); } @SubscribeEvent(priority = EventPriority.NORMAL) - public static void applyRemovals(BiomeLoadingEvent event) { - modifyForPhase(event, REMOVALS); + public static void processRemovals(BiomeLoadingEvent event) { + modifyBiome(event, REMOVALS); } @SubscribeEvent(priority = EventPriority.LOW) - public static void applyReplacements(BiomeLoadingEvent event) { - modifyForPhase(event, REPLACEMENTS); + public static void processReplacements(BiomeLoadingEvent event) { + modifyBiome(event, REPLACEMENTS); } @SubscribeEvent(priority = EventPriority.LOWEST) - public static void applyPostProcessing(BiomeLoadingEvent event) { - modifyForPhase(event, POST_PROCESSING); + public static void postProcessBiomes(BiomeLoadingEvent event) { + modifyBiome(event, POST_PROCESSING); } - private static void modifyForPhase(BiomeLoadingEvent event, List, BiConsumer>> phase) { + private static void modifyBiome(BiomeLoadingEvent event, List, BiConsumer>> list) { BiomeContext biomeContext = wrapSelectionContext(event); BiomeProperties.Mutable mutableBiome = new MutableBiomeWrapped(event); - for (var pair : phase) { + for (var pair : list) { if (pair.getLeft().test(biomeContext)) { pair.getRight().accept(biomeContext, mutableBiome); }