Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.16.4] [Solved] Removing specific features from a biome


Recommended Posts

The end goal is to disable certain aspects of vanilla ore/feature generation so I can replace them with my own features with custom values.

 

To disable vanilla ore generation, I've created an event handler for BiomeLoadingEvent. This allows me to get the BiomeGenerationSettingsBuilder which allows me to get the list of ConfiguredFeature's for the biome associated with the event call:

 

@SubscribeEvent(priority = EventPriority.LOWEST)
public static void BiomeLoadingIntercept(final BiomeLoadingEvent event) {
    BiomeGenerationSettingsBuilder gen = event.getGeneration();
    List<Supplier<ConfiguredFeature<?, ?>>> features = gen.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES);
    
    ...
}

 

I know this list is *probably* what I need, since if I just call features.clear(), all ore generation is successfully removed from the game. However, I want to be able to remove specific ores via config file, so I need some way to either remove by registry ID, or remove by object (ex. using the objects in net.minecraft.world.gen.feature.Features).

 

I've tried a number of things that don't seem to work:

  • Looping through the features list, feature.get().getFeature().getRegistryName() always returns minecraft:decorated and never anything more specific.
  • Looping through the features list, calling ForgeRegistries.getKey(feature) always returns minecraft:decorated.
  • Looping through the features list, calling net.minecraft.util.registry.WorldGenRegistries.CONFIGURED_FEATURE.getKey(feature) always returns NULL (presumably because vanilla registries aren't used by Forge, or something).
  • Calling features.contains(Features.ORE_COAL) (for example) is always false, like the biomes never contain the coal ore feature (but they do).

 

I think the way features are applied and stacked causes the features to lose their original registry values. Is there any way I can remove specific features from biomes?

 

Thanks

Edited by noahc3
Solved
Link to post
Share on other sites

You need to check if ConfiguredFeature#getFeature is a DecoratedFeature. If it is, you need to use ConfiguredFeature#getConfig, which will then be a DecoratedFeatureConfig. That has DecoratedFeatureConfig#feature, which is the original feature and its configuration.

  • Like 1
Link to post
Share on other sites
36 minutes ago, diesieben07 said:

You need to check if ConfiguredFeature#getFeature is a DecoratedFeature. If it is, you need to use ConfiguredFeature#getConfig, which will then be a DecoratedFeatureConfig. That has DecoratedFeatureConfig#feature, which is the original feature and its configuration.

Thanks, that worked. I had to dig through the features recursively since they weren't always one level deep:

 

    @SubscribeEvent(priority = EventPriority.LOWEST)
    public static void BiomeLoadingIntercept(final BiomeLoadingEvent event) {
        BiomeGenerationSettingsBuilder gen = event.getGeneration();

        for(Supplier<ConfiguredFeature<?, ?>> f : gen.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES)) {
            ConfiguredFeature<?, ?> resolved = resolve(f.get());
            if (resolved.feature instanceof OreFeature) {
                OreFeatureConfig oreConfig = (OreFeatureConfig) resolved.config;
                Logger.info(oreConfig.state.getBlock().getRegistryName());
                
                ... compare blockstates ...
            }
        }
    }

    private static ConfiguredFeature<?, ?> resolve(ConfiguredFeature<?, ?> f) {
        if (f.getFeature() instanceof DecoratedFeature) {
            ConfiguredFeature<?, ?> subFeature = ((DecoratedFeatureConfig)f.getConfig()).feature.get();
            return resolve(subFeature);
        } else {
            return f;
        }
    }

 

This seems inefficient, is this the simplest way?

Link to post
Share on other sites
  • 3 months later...
10 minutes ago, killerjdog51 said:

How did you remove/prevent the generation? Because when I use f.remove() I get a ConcurrentModificationException.

make your own thread, explain your issue further, and post the full log

Link to post
Share on other sites
19 hours ago, killerjdog51 said:

How did you remove/prevent the generation? Because when I use f.remove() I get a ConcurrentModificationException.

This is basic java knowledge. Don't modify collections while iterating...

Link to post
Share on other sites
On 4/18/2021 at 8:19 AM, DietmarKracht said:

This is basic java knowledge. Don't modify collections while iterating...

Thanks, I switched it to an iterator and it worked. I was able to remove the features after the game had loaded but before they generated. 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.