1+ package com .ferreusveritas .dynamictrees .worldgen .biomemodifiers ;
2+
3+ import com .ferreusveritas .dynamictrees .DynamicTrees ;
4+ import com .ferreusveritas .dynamictrees .api .worldgen .BiomePropertySelectors ;
5+ import com .ferreusveritas .dynamictrees .api .worldgen .FeatureCanceller ;
6+ import com .ferreusveritas .dynamictrees .init .DTConfigs ;
7+ import com .ferreusveritas .dynamictrees .init .DTRegistries ;
8+ import com .ferreusveritas .dynamictrees .worldgen .BiomeDatabase ;
9+ import com .ferreusveritas .dynamictrees .worldgen .FeatureCancellationRegistry ;
10+ import com .mojang .serialization .Codec ;
11+ import net .minecraft .core .Holder ;
12+ import net .minecraft .core .Registry ;
13+ import net .minecraft .core .registries .Registries ;
14+ import net .minecraft .resources .ResourceKey ;
15+ import net .minecraft .resources .ResourceLocation ;
16+ import net .minecraft .tags .TagKey ;
17+ import net .minecraft .world .level .biome .Biome ;
18+ import net .minecraft .world .level .levelgen .placement .PlacedFeature ;
19+ import net .minecraftforge .common .world .BiomeGenerationSettingsBuilder ;
20+ import net .minecraftforge .common .world .BiomeModifier ;
21+ import net .minecraftforge .common .world .ModifiableBiomeInfo ;
22+
23+ public class RunFeatureCancellersBiomeModifier implements BiomeModifier {
24+ public static final TagKey <PlacedFeature > FEATURE_CANCELLER_EXCLUSIONS_KEY = TagKey .create (Registries .PLACED_FEATURE ,
25+ new ResourceLocation (DynamicTrees .MOD_ID , "feature_canceller_exclusions" ));
26+
27+ @ Override
28+ public void modify (Holder <Biome > biome , Phase phase , ModifiableBiomeInfo .BiomeInfo .Builder builder ) {
29+ if (phase == Phase .REMOVE && DTConfigs .WORLD_GEN .get ()) {
30+ ResourceKey <Biome > biomeKey = biome .unwrapKey ().orElseThrow ();
31+ BiomeGenerationSettingsBuilder generationSettings = builder .getGenerationSettings ();
32+
33+ BiomePropertySelectors .NormalFeatureCancellation featureCancellations = new BiomePropertySelectors .NormalFeatureCancellation ();
34+
35+ for (FeatureCancellationRegistry .Entry entry : FeatureCancellationRegistry .getCancellations ()) {
36+ if (entry .biomes ().containsKey (biomeKey )) {
37+ if (entry .operation () == BiomeDatabase .Operation .REPLACE )
38+ featureCancellations .reset ();
39+ featureCancellations .addFrom (entry .cancellations ());
40+ }
41+ }
42+
43+ // final ResourceLocation biomeName = biome.unwrapKey().map(ResourceKey::location).orElse(null);
44+ //
45+ // if (biomeName == null) {
46+ // return;
47+ // }
48+ //
49+
50+ featureCancellations .getDecorationSteps ().forEach (stage -> generationSettings .getFeatures (stage ).removeIf (placedFeatureHolder -> {
51+ // If you want a placed feature to be entirely excluded from cancellation by any feature cancellers,
52+ // add it to the dynamictrees:tags/worldgen/placed_feature/feature_canceller_exclusions tag.
53+ if (placedFeatureHolder .is (FEATURE_CANCELLER_EXCLUSIONS_KEY ))
54+ return false ;
55+
56+ PlacedFeature placedFeature = placedFeatureHolder .value ();
57+
58+ try {
59+ var features = placedFeature .getFeatures ();
60+ if (features == null ) {
61+ return false ;
62+ }
63+
64+ return features .filter (cf -> cf .config () != null ).anyMatch (configuredFeature -> {
65+ for (FeatureCanceller featureCanceller : featureCancellations .getCancellers ()) {
66+ try {
67+ if (featureCanceller .shouldCancel (configuredFeature , featureCancellations )) {
68+ return true ;
69+ }
70+ } catch (NullPointerException e ) {
71+ // This should be logged
72+ // In this case, we do not want a single FeatureCanceller to break the entire process.
73+ return false ;
74+ }
75+ }
76+ return false ;
77+ });
78+ } catch (NullPointerException e ) {
79+ // I don't know how to log this
80+ return false ;
81+ }
82+ }));
83+ }
84+ }
85+
86+ @ Override
87+ public Codec <? extends BiomeModifier > codec () {
88+ return DTRegistries .RUN_FEATURE_CANCELLERS_BIOME_MODIFIER .get ();
89+ }
90+ }
0 commit comments