fweo Posted October 29, 2021 Share Posted October 29, 2021 (edited) What is the preferred method for preventing a particular vanilla ConfiguredFeature from generating (e.g. preventing natural generation of coal ore)? My best guess is that you would do something when you receive a BiomeLoadingEvent, similarly to how you add your own configured features, but I can't think of a good way to do this. I suppose I could loop through the entire list, retrieve the object from each supplier, compare it to the particular vanilla feature, and then remove it if it's the same, but this seems a little clumsy, especially if I want to stop the generation of several features (which I do). If I want to remove the feature from all biomes, is there a way to prevent it from getting added to the list in the first place or replace it with a no-op so it doesn't need to be removed each time a biome loads? Is this any easier if you only wish to alter an existing feature, e.g. changing an ore vein size or changing what block generates in a vegetation patch? Edited October 31, 2021 by fweo Mark as solved Quote Link to comment Share on other sites More sharing options...
Luis_ST Posted October 29, 2021 Share Posted October 29, 2021 the BiomeLoadingEvent is the way to go Quote Link to comment Share on other sites More sharing options...
fweo Posted October 29, 2021 Author Share Posted October 29, 2021 Here's my current attempt, which runs with each BiomeLoadingEvent: List<Supplier<ConfiguredFeature<?,?>>> orefeatures = event.getGeneration().getFeatures(GenerationStep.Decoration.UNDERGROUND_ORES); List<Integer> indicesToRemove = new ArrayList<>(); for(int i = 0; i < orefeatures.size(); i++) { ConfiguredFeature<?,?> feature = orefeatures.get(i).get(); Main.LOGGER.info(feature.toString()); if(feature == Features.ORE_COAL || feature == Features.ORE_IRON) { indicesToRemove.add(i); Main.LOGGER.info("Removing!"); } } orefeatures.removeAll(indicesToRemove); The features all print in the first log, and the two I've picked to remove are included in that list, as expected (they toString into a json format, though, so it's a bit hard to look at). However, it never gets into the body of the if statement, so nothing changes with the generation. Features.ORE_COAL is the exact object put into the list by addDefaultOres in BiomeDefaultFeatures, and that just gets made directly into a Supplier which gets put straight into the list, so those should be the right objects that come out of the Supplier when you call getGeneration.getFeatures(step).get(index).get(). Any ideas about what's wrong? Something up with the ==? Quote Link to comment Share on other sites More sharing options...
Luis_ST Posted October 29, 2021 Share Posted October 29, 2021 you need to use ConfiguredFeature#getFeatures 1 Quote Link to comment Share on other sites More sharing options...
fweo Posted October 30, 2021 Author Share Posted October 30, 2021 That's helped a bit, but I'm still stuck. If I compare the the configured features in Features.ORE_COAL.getFeatures() to those in event.getGeneration().getFeatures(GenerationStep.Decoration.UNDERGROUND_ORES).get(i).get().getFeatures(); then for the i that corresponds to coal ore (which won't necessarily always be the same) those two streams both contain four configured features, and the final three of them match in terms of what they toString into, but don't compare as equal with .equals. Am I doing the wrong thing with getFeatures here? Surely there's a proper way to compare them without having to resort to comparing strings or comparing some other complicated properties of them. That is, if I do something like this then they match in the log but don't get into the if statement: List<Supplier<ConfiguredFeature<?,?>>> orefeatures = event.getGeneration().getFeatures(GenerationStep.Decoration.UNDERGROUND_ORES); for(int i = 0; i < orefeatures.size(); i++) { List<ConfiguredFeature<?, ?>> oneFeature = orefeatures.get(i).get().getFeatures().toList(); List<ConfiguredFeature<?, ?>> testAgainst = Features.ORE_COAL.getFeatures().toList(); for(int j = 0; j < oneFeature.size() && j < testAgainst.size(); j++) { Main.LOGGER.info(oneFeature.get(j)); Main.LOGGER.info(testAgainst.get(j)); if(oneFeature.get(j).equals(testAgainst.get(j))) { Main.LOGGER.info("Matched at " + i); break; } Main.LOGGER.info(""); } } Giving the following output: Spoiler (... similar output for deepslate ...) [16:11:44] [Netty Local Client IO #0/INFO]: DataResult[Left[{"config":{"feature":{"config":{"feature":{"config":{"feature":{"config":{"targets":[{"target":{"tag":"minecraft:stone_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:coal_ore"}},{"target":{"tag":"minecraft:deepslate_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:deepslate_coal_ore"}}],"size":17,"discard_chance_on_air_exposure":0.0},"type":"minecraft:ore"},"decorator":{"config":{"height":{"min_inclusive":{"above_bottom":0},"max_inclusive":{"absolute":127},"type":"minecraft:uniform"}},"type":"minecraft:range"}},"type":"minecraft:decorated"},"decorator":{"config":{},"type":"minecraft:square"}},"type":"minecraft:decorated"},"decorator":{"config":{"count":20},"type":"minecraft:count"}},"type":"minecraft:decorated"}]] [16:11:44] [Netty Local Client IO #0/INFO]: ResourceKey[minecraft:worldgen/configured_feature / minecraft:ore_coal] [16:11:44] [Netty Local Client IO #0/INFO]: [16:11:44] [Netty Local Client IO #0/INFO]: DataResult[Left[{"config":{"feature":{"config":{"feature":{"config":{"targets":[{"target":{"tag":"minecraft:stone_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:coal_ore"}},{"target":{"tag":"minecraft:deepslate_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:deepslate_coal_ore"}}],"size":17,"discard_chance_on_air_exposure":0.0},"type":"minecraft:ore"},"decorator":{"config":{"height":{"min_inclusive":{"above_bottom":0},"max_inclusive":{"absolute":127},"type":"minecraft:uniform"}},"type":"minecraft:range"}},"type":"minecraft:decorated"},"decorator":{"config":{},"type":"minecraft:square"}},"type":"minecraft:decorated"}]] [16:11:44] [Netty Local Client IO #0/INFO]: DataResult[Left[{"config":{"feature":{"config":{"feature":{"config":{"targets":[{"target":{"tag":"minecraft:stone_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:coal_ore"}},{"target":{"tag":"minecraft:deepslate_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:deepslate_coal_ore"}}],"size":17,"discard_chance_on_air_exposure":0.0},"type":"minecraft:ore"},"decorator":{"config":{"height":{"min_inclusive":{"above_bottom":0},"max_inclusive":{"absolute":127},"type":"minecraft:uniform"}},"type":"minecraft:range"}},"type":"minecraft:decorated"},"decorator":{"config":{},"type":"minecraft:square"}},"type":"minecraft:decorated"}]] [16:11:44] [Netty Local Client IO #0/INFO]: [16:11:44] [Netty Local Client IO #0/INFO]: DataResult[Left[{"config":{"feature":{"config":{"targets":[{"target":{"tag":"minecraft:stone_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:coal_ore"}},{"target":{"tag":"minecraft:deepslate_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:deepslate_coal_ore"}}],"size":17,"discard_chance_on_air_exposure":0.0},"type":"minecraft:ore"},"decorator":{"config":{"height":{"min_inclusive":{"above_bottom":0},"max_inclusive":{"absolute":127},"type":"minecraft:uniform"}},"type":"minecraft:range"}},"type":"minecraft:decorated"}]] [16:11:44] [Netty Local Client IO #0/INFO]: DataResult[Left[{"config":{"feature":{"config":{"targets":[{"target":{"tag":"minecraft:stone_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:coal_ore"}},{"target":{"tag":"minecraft:deepslate_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:deepslate_coal_ore"}}],"size":17,"discard_chance_on_air_exposure":0.0},"type":"minecraft:ore"},"decorator":{"config":{"height":{"min_inclusive":{"above_bottom":0},"max_inclusive":{"absolute":127},"type":"minecraft:uniform"}},"type":"minecraft:range"}},"type":"minecraft:decorated"}]] [16:11:44] [Netty Local Client IO #0/INFO]: [16:11:44] [Netty Local Client IO #0/INFO]: DataResult[Left[{"config":{"targets":[{"target":{"tag":"minecraft:stone_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:coal_ore"}},{"target":{"tag":"minecraft:deepslate_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:deepslate_coal_ore"}}],"size":17,"discard_chance_on_air_exposure":0.0},"type":"minecraft:ore"}]] [16:11:44] [Netty Local Client IO #0/INFO]: DataResult[Left[{"config":{"targets":[{"target":{"tag":"minecraft:stone_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:coal_ore"}},{"target":{"tag":"minecraft:deepslate_ore_replaceables","predicate_type":"minecraft:tag_match"},"state":{"Name":"minecraft:deepslate_coal_ore"}}],"size":17,"discard_chance_on_air_exposure":0.0},"type":"minecraft:ore"}]] [16:11:44] [Netty Local Client IO #0/INFO]: (... similar output for iron ore ...) Quote Link to comment Share on other sites More sharing options...
Luis_ST Posted October 30, 2021 Share Posted October 30, 2021 i would recommend you to use removeIf, something like this: event.getGeneration().getFeatures(GenerationStep.Decoration.UNDERGROUND_ORES).removeIf((supplier) -> { }); then you can loop inside the removeIf through the ConfiguredFeatures, after that check if the ConfiguredFeature.feature is an OreFeature, then get the OreConfiguration of the feature and from that you can get the targetStates which you can map to a List of Blocks. then return inside the removeIf if the List contains for example Blocks.COAL_ORE that was now very theoretical, you can look at this for a practical example 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.