Some more changes to placements
This commit is contained in:
parent
d3b6fa7d80
commit
c4875b992a
10 changed files with 948 additions and 4 deletions
|
@ -16,7 +16,6 @@ import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.resources.RegistryOps;
|
import net.minecraft.resources.RegistryOps;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.BiomeTags;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
import net.minecraft.world.level.biome.Climate;
|
import net.minecraft.world.level.biome.Climate;
|
||||||
|
@ -148,9 +147,10 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
|
||||||
|
|
||||||
|
|
||||||
private static boolean isValidNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
private static boolean isValidNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
||||||
return NetherBiomes.canGenerateInNether(biome.unwrapKey().get()) ||
|
return biome.unwrapKey().get().location().toString().equals("betternether:bone_reef");
|
||||||
biome.is(BiomeTags.IS_NETHER) ||
|
// return NetherBiomes.canGenerateInNether(biome.unwrapKey().get()) ||
|
||||||
BiomeAPI.wasRegisteredAsNetherBiome(location);
|
// biome.is(BiomeTags.IS_NETHER) ||
|
||||||
|
// BiomeAPI.wasRegisteredAsNetherBiome(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isValidNonVanillaNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
private static boolean isValidNonVanillaNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
||||||
|
|
|
@ -595,6 +595,16 @@ public class BCLBiomeBuilder {
|
||||||
return feature(feature.getDecoration(), feature.getPlacedFeature());
|
return feature(feature.getDecoration(), feature.getPlacedFeature());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds new feature to the biome.
|
||||||
|
*
|
||||||
|
* @param feature {@link BCLFeature}.
|
||||||
|
* @return same {@link BCLBiomeBuilder} instance.
|
||||||
|
*/
|
||||||
|
public BCLBiomeBuilder feature(org.betterx.bclib.api.v3.levelgen.features.BCLFeature feature) {
|
||||||
|
return feature(feature.decoration, feature.placedFeature);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds new structure feature into the biome.
|
* Adds new structure feature into the biome.
|
||||||
*
|
*
|
||||||
|
|
|
@ -4,6 +4,8 @@ import org.betterx.bclib.api.v2.levelgen.features.config.PlaceFacingBlockConfig;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.features.ScatterFeature;
|
import org.betterx.bclib.api.v2.levelgen.features.features.ScatterFeature;
|
||||||
|
|
||||||
|
import net.minecraft.data.worldgen.features.FeatureUtils;
|
||||||
|
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.valueproviders.UniformInt;
|
import net.minecraft.util.valueproviders.UniformInt;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
@ -19,6 +21,12 @@ import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvi
|
||||||
import net.minecraft.world.level.levelgen.feature.stateproviders.RandomizedIntStateProvider;
|
import net.minecraft.world.level.levelgen.feature.stateproviders.RandomizedIntStateProvider;
|
||||||
|
|
||||||
public class FastFeatures {
|
public class FastFeatures {
|
||||||
|
public static RandomPatchConfiguration grassPatch(BlockStateProvider stateProvider, int tries) {
|
||||||
|
return FeatureUtils.simpleRandomPatchConfiguration(
|
||||||
|
tries,
|
||||||
|
PlacementUtils.onlyWhenEmpty(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(stateProvider))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static BCLFeature<ScatterFeature<ScatterFeatureConfig.OnSolid>, ScatterFeatureConfig.OnSolid> vine(
|
public static BCLFeature<ScatterFeature<ScatterFeatureConfig.OnSolid>, ScatterFeatureConfig.OnSolid> vine(
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||||
|
private static final Map<Holder<ConfiguredFeature<?, ?>>, BCLConfigureFeature<?, ?>> KNOWN = new HashMap<>();
|
||||||
|
|
||||||
|
public final ResourceLocation id;
|
||||||
|
public final Holder<ConfiguredFeature<FC, F>> configuredFeature;
|
||||||
|
public final boolean registered;
|
||||||
|
|
||||||
|
BCLConfigureFeature(ResourceLocation id, Holder<ConfiguredFeature<FC, F>> configuredFeature, boolean registered) {
|
||||||
|
this.id = id;
|
||||||
|
this.configuredFeature = configuredFeature;
|
||||||
|
this.registered = registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public F getFeature() {
|
||||||
|
return configuredFeature.value().feature();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FC getConfiguration() {
|
||||||
|
return configuredFeature.value().config();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BCLPlacedFeatureBuilder<F, FC> place() {
|
||||||
|
return place(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
BCLPlacedFeatureBuilder<F, FC> place(ResourceLocation id) {
|
||||||
|
return BCLPlacedFeatureBuilder.place(id, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static <F extends Feature<FC>, FC extends FeatureConfiguration> BCLConfigureFeature<F, FC> create(Holder<ConfiguredFeature<FC, F>> registeredFeature) {
|
||||||
|
return (BCLConfigureFeature<F, FC>) KNOWN.computeIfAbsent(
|
||||||
|
(Holder<ConfiguredFeature<?, ?>>) (Object) registeredFeature,
|
||||||
|
holder -> new BCLConfigureFeature<>(holder.unwrapKey().orElseThrow()
|
||||||
|
.location(), registeredFeature, false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.config.*;
|
||||||
|
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.RandomFeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
|
|
||||||
|
public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||||
|
public static final Feature<PlaceFacingBlockConfig> PLACE_BLOCK = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.PLACE_BLOCK;
|
||||||
|
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.SCATTER_ON_SOLID;
|
||||||
|
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.SCATTER_EXTEND_TOP;
|
||||||
|
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.SCATTER_EXTEND_BOTTOM;
|
||||||
|
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.RANDOM_SELECTOR;
|
||||||
|
public static final Feature<TemplateFeatureConfig> TEMPLATE = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.TEMPLATE;
|
||||||
|
public static final Feature<NoneFeatureConfiguration> MARK_POSTPROCESSING = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.MARK_POSTPROCESSING;
|
||||||
|
public static final Feature<SequenceFeatureConfig> SEQUENCE = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.SEQUENCE;
|
||||||
|
public static final Feature<ConditionFeatureConfig> CONDITION = org.betterx.bclib.api.v2.levelgen.features.BCLFeature.CONDITION;
|
||||||
|
public final BCLConfigureFeature<F, FC> configuredFeature;
|
||||||
|
public final Holder<PlacedFeature> placedFeature;
|
||||||
|
public final GenerationStep.Decoration decoration;
|
||||||
|
|
||||||
|
BCLFeature(
|
||||||
|
BCLConfigureFeature<F, FC> configuredFeature,
|
||||||
|
Holder<PlacedFeature> placed,
|
||||||
|
GenerationStep.Decoration decoration
|
||||||
|
) {
|
||||||
|
this.configuredFeature = configuredFeature;
|
||||||
|
this.placedFeature = placed;
|
||||||
|
this.decoration = decoration;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,289 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||||
|
import org.betterx.bclib.api.v2.poi.BCLPoiType;
|
||||||
|
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.data.BuiltinRegistries;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.*;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||||
|
public static class NetherForrestVegetation<FF extends Feature<NetherForestVegetationConfig>> extends BCLFeatureBuilder<FF, NetherForestVegetationConfig> {
|
||||||
|
private SimpleWeightedRandomList.Builder<BlockState> blocks;
|
||||||
|
private WeightedStateProvider stateProvider;
|
||||||
|
private int spreadWidth = 8;
|
||||||
|
private int spreadHeight = 4;
|
||||||
|
|
||||||
|
private NetherForrestVegetation(ResourceLocation featureID, FF feature) {
|
||||||
|
super(featureID, feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetherForrestVegetation spreadWidth(int v) {
|
||||||
|
spreadWidth = v;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetherForrestVegetation spreadHeight(int v) {
|
||||||
|
spreadHeight = v;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetherForrestVegetation addAllStates(Block block, int weight) {
|
||||||
|
Set<BlockState> states = BCLPoiType.getBlockStates(block);
|
||||||
|
states.forEach(s -> add(block.defaultBlockState(), Math.max(1, weight / states.size())));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetherForrestVegetation addAllStatesFor(IntegerProperty prop, Block block, int weight) {
|
||||||
|
Collection<Integer> values = prop.getPossibleValues();
|
||||||
|
values.forEach(s -> add(block.defaultBlockState().setValue(prop, s), Math.max(1, weight / values.size())));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetherForrestVegetation add(Block block, int weight) {
|
||||||
|
return add(block.defaultBlockState(), weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetherForrestVegetation add(BlockState state, int weight) {
|
||||||
|
if (stateProvider != null) {
|
||||||
|
throw new IllegalStateException("You can not add new state once a WeightedStateProvider was built. (" + state + ", " + weight + ")");
|
||||||
|
}
|
||||||
|
if (blocks == null) {
|
||||||
|
blocks = SimpleWeightedRandomList.<BlockState>builder();
|
||||||
|
}
|
||||||
|
blocks.add(state, weight);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetherForrestVegetation provider(WeightedStateProvider provider) {
|
||||||
|
if (blocks != null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"You can not set a WeightedStateProvider after states were added manually.");
|
||||||
|
}
|
||||||
|
stateProvider = provider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NetherForestVegetationConfig createConfiguration() {
|
||||||
|
if (stateProvider == null && blocks == null) {
|
||||||
|
throw new IllegalStateException("NetherForestVegetationConfig needs at least one BlockState");
|
||||||
|
}
|
||||||
|
if (stateProvider == null) stateProvider = new WeightedStateProvider(blocks.build());
|
||||||
|
return new NetherForestVegetationConfig(stateProvider, spreadWidth, spreadHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RandomPatch<FF extends Feature<RandomPatchConfiguration>> extends BCLFeatureBuilder<FF, RandomPatchConfiguration> {
|
||||||
|
private int tries = 96;
|
||||||
|
private int xzSpread = 7;
|
||||||
|
private int ySpread = 3;
|
||||||
|
private final Holder<PlacedFeature> featureToPlace;
|
||||||
|
|
||||||
|
private RandomPatch(
|
||||||
|
@NotNull ResourceLocation featureID,
|
||||||
|
@NotNull FF feature,
|
||||||
|
@NotNull Holder<PlacedFeature> featureToPlace
|
||||||
|
) {
|
||||||
|
super(featureID, feature);
|
||||||
|
this.featureToPlace = featureToPlace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RandomPatch tries(int v) {
|
||||||
|
tries = v;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RandomPatch spreadXZ(int v) {
|
||||||
|
xzSpread = v;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RandomPatch spreadY(int v) {
|
||||||
|
ySpread = v;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomPatchConfiguration createConfiguration() {
|
||||||
|
return new RandomPatchConfiguration(tries, xzSpread, ySpread, featureToPlace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WithConfiguration<F extends Feature<FC>, FC extends FeatureConfiguration> extends BCLFeatureBuilder<F, FC> {
|
||||||
|
private FC configuration;
|
||||||
|
|
||||||
|
private WithConfiguration(@NotNull ResourceLocation featureID, @NotNull F feature) {
|
||||||
|
super(featureID, feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WithConfiguration configuration(FC config) {
|
||||||
|
this.configuration = config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FC createConfiguration() {
|
||||||
|
if (configuration == null) return (FC) NoneFeatureConfiguration.NONE;
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ForSimpleBlock<FF extends Feature<SimpleBlockConfiguration>> extends BCLFeatureBuilder<FF, SimpleBlockConfiguration> {
|
||||||
|
private final BlockStateProvider provider;
|
||||||
|
|
||||||
|
private ForSimpleBlock(
|
||||||
|
@NotNull ResourceLocation featureID,
|
||||||
|
@NotNull FF feature,
|
||||||
|
@NotNull BlockStateProvider provider
|
||||||
|
) {
|
||||||
|
super(featureID, feature);
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SimpleBlockConfiguration createConfiguration() {
|
||||||
|
return new SimpleBlockConfiguration(provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ResourceLocation featureID;
|
||||||
|
private final F feature;
|
||||||
|
|
||||||
|
private BCLFeatureBuilder(ResourceLocation featureID, F feature) {
|
||||||
|
this.featureID = featureID;
|
||||||
|
this.feature = feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new {@link BCLFeature} builder.
|
||||||
|
*
|
||||||
|
* @param featureID {@link ResourceLocation} feature identifier.
|
||||||
|
* @param feature {@link Feature} to construct.
|
||||||
|
* @return {@link org.betterx.bclib.api.v2.levelgen.features.BCLFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public static <F extends Feature<FC>, FC extends FeatureConfiguration> WithConfiguration<F, FC> start(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
F feature
|
||||||
|
) {
|
||||||
|
return new WithConfiguration(featureID, feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ForSimpleBlock start(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
Block block
|
||||||
|
) {
|
||||||
|
return start(featureID, BlockStateProvider.simple(block));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ForSimpleBlock start(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
BlockState state
|
||||||
|
) {
|
||||||
|
return start(featureID, BlockStateProvider.simple(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ForSimpleBlock start(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
BlockStateProvider provider
|
||||||
|
) {
|
||||||
|
ForSimpleBlock builder = new ForSimpleBlock(
|
||||||
|
featureID,
|
||||||
|
Feature.SIMPLE_BLOCK,
|
||||||
|
provider
|
||||||
|
);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RandomPatch startRandomPatch(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
Holder<PlacedFeature> featureToPlace
|
||||||
|
) {
|
||||||
|
RandomPatch builder = new RandomPatch(
|
||||||
|
featureID,
|
||||||
|
Feature.RANDOM_PATCH,
|
||||||
|
featureToPlace
|
||||||
|
);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NetherForrestVegetation startNetherVegetation(
|
||||||
|
ResourceLocation featureID
|
||||||
|
) {
|
||||||
|
NetherForrestVegetation builder = new NetherForrestVegetation(
|
||||||
|
featureID,
|
||||||
|
Feature.NETHER_FOREST_VEGETATION
|
||||||
|
);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract FC createConfiguration();
|
||||||
|
|
||||||
|
protected BCLConfigureFeature<F, FC> buildAndRegister(BiFunction<ResourceLocation, ConfiguredFeature<FC, F>, Holder<ConfiguredFeature<FC, F>>> holderBuilder) {
|
||||||
|
FC config = createConfiguration();
|
||||||
|
if (config == null) {
|
||||||
|
throw new IllegalStateException("Feature configuration for " + featureID + " can not be null!");
|
||||||
|
}
|
||||||
|
ConfiguredFeature<FC, F> cFeature = new ConfiguredFeature<FC, F>(feature, config);
|
||||||
|
Holder<ConfiguredFeature<FC, F>> holder = holderBuilder.apply(featureID, cFeature);
|
||||||
|
return new BCLConfigureFeature<>(featureID, holder, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BCLConfigureFeature<F, FC> buildAndRegister() {
|
||||||
|
return buildAndRegister(BCLFeatureBuilder::register);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BCLConfigureFeature<F, FC> build() {
|
||||||
|
return buildAndRegister((id, cFeature) -> Holder.direct(cFeature));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BCLInlinePlacedBuilder<F, FC> inlinePlace() {
|
||||||
|
BCLConfigureFeature<F, FC> f = build();
|
||||||
|
return BCLInlinePlacedBuilder.place(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Holder<PlacedFeature> inlinePlace(BCLInlinePlacedBuilder<F, FC> placer) {
|
||||||
|
BCLConfigureFeature<F, FC> f = build();
|
||||||
|
return placer.build(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internally used by the builder. Normally you should not have to call this method directly as it is
|
||||||
|
* handled by {@link #buildAndRegister()}
|
||||||
|
*
|
||||||
|
* @param id The ID to register this feature with
|
||||||
|
* @param cFeature The configured Feature
|
||||||
|
* @param <F> The Feature Class
|
||||||
|
* @param <FC> The FeatureConfiguration Class
|
||||||
|
* @return The Holder for the new Feature
|
||||||
|
*/
|
||||||
|
public static <F extends Feature<FC>, FC extends FeatureConfiguration> Holder<ConfiguredFeature<FC, F>> register(
|
||||||
|
ResourceLocation id,
|
||||||
|
ConfiguredFeature<FC, F> cFeature
|
||||||
|
) {
|
||||||
|
return (Holder<ConfiguredFeature<FC, F>>) (Object) BuiltinRegistries.register(
|
||||||
|
BuiltinRegistries.CONFIGURED_FEATURE,
|
||||||
|
id,
|
||||||
|
cFeature
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
|
|
||||||
|
public class BCLInlinePlacedBuilder<F extends Feature<FC>, FC extends FeatureConfiguration> extends CommonPlacedFeatureBuilder<F, FC, BCLInlinePlacedBuilder<F, FC>> {
|
||||||
|
private final BCLConfigureFeature<F, FC> cFeature;
|
||||||
|
|
||||||
|
private BCLInlinePlacedBuilder(BCLConfigureFeature<F, FC> cFeature) {
|
||||||
|
this.cFeature = cFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new {@link BCLFeature} builder.
|
||||||
|
*
|
||||||
|
* @param holder {@link Feature} the configured Feature to start from.
|
||||||
|
* @return {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public static <F extends Feature<FC>, FC extends FeatureConfiguration> BCLInlinePlacedBuilder<F, FC> place(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
Holder<ConfiguredFeature<FC, F>> holder
|
||||||
|
) {
|
||||||
|
return place(BCLConfigureFeature.create(holder));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new {@link BCLFeature} builder.
|
||||||
|
*
|
||||||
|
* @param cFeature {@link Feature} the configured Feature to start from.
|
||||||
|
* @return {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
static <F extends Feature<FC>, FC extends FeatureConfiguration> BCLInlinePlacedBuilder<F, FC> place(
|
||||||
|
BCLConfigureFeature<F, FC> cFeature
|
||||||
|
) {
|
||||||
|
return new BCLInlinePlacedBuilder(cFeature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new inline (not registered) {@link PlacedFeature}.
|
||||||
|
*
|
||||||
|
* @return created {@link PlacedFeature} instance.
|
||||||
|
*/
|
||||||
|
public Holder<PlacedFeature> build() {
|
||||||
|
return build(cFeature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new inline (not registered) {@link PlacedFeature}.
|
||||||
|
*
|
||||||
|
* @return created {@link PlacedFeature} instance.
|
||||||
|
*/
|
||||||
|
public Holder<PlacedFeature> build(BCLConfigureFeature feature) {
|
||||||
|
return build(feature.configuredFeature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new inline (not registered) {@link PlacedFeature}.
|
||||||
|
*
|
||||||
|
* @return created {@link PlacedFeature} instance.
|
||||||
|
*/
|
||||||
|
public Holder<PlacedFeature> build(Holder<ConfiguredFeature<FC, F>> feature) {
|
||||||
|
PlacementModifier[] modifiers = modifications.toArray(new PlacementModifier[modifications.size()]);
|
||||||
|
return PlacementUtils.inlinePlaced(feature, modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new inline (not registered) {@link PlacedFeature}.
|
||||||
|
*
|
||||||
|
* @return created {@link PlacedFeature} instance.
|
||||||
|
*/
|
||||||
|
public Holder<PlacedFeature> build(F feature, FC configuration) {
|
||||||
|
PlacementModifier[] modifiers = modifications.toArray(new PlacementModifier[modifications.size()]);
|
||||||
|
return PlacementUtils.inlinePlaced(feature, configuration, modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
|
|
||||||
|
public class BCLPlacedFeatureBuilder<F extends Feature<FC>, FC extends FeatureConfiguration> extends CommonPlacedFeatureBuilder<F, FC, BCLPlacedFeatureBuilder<F, FC>> {
|
||||||
|
private final ResourceLocation featureID;
|
||||||
|
private GenerationStep.Decoration decoration = GenerationStep.Decoration.VEGETAL_DECORATION;
|
||||||
|
private final BCLConfigureFeature<F, FC> cFeature;
|
||||||
|
|
||||||
|
private BCLPlacedFeatureBuilder(ResourceLocation featureID, BCLConfigureFeature<F, FC> cFeature) {
|
||||||
|
this.featureID = featureID;
|
||||||
|
this.cFeature = cFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set generation step for the feature. Default is {@code VEGETAL_DECORATION}.
|
||||||
|
*
|
||||||
|
* @param decoration {@link GenerationStep.Decoration} step.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public BCLPlacedFeatureBuilder<F, FC> decoration(GenerationStep.Decoration decoration) {
|
||||||
|
this.decoration = decoration;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new {@link BCLFeature} builder.
|
||||||
|
*
|
||||||
|
* @param featureID {@link ResourceLocation} feature identifier.
|
||||||
|
* @param holder {@link Feature} the configured Feature to start from.
|
||||||
|
* @return {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public static <F extends Feature<FC>, FC extends FeatureConfiguration> BCLPlacedFeatureBuilder<F, FC> place(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
Holder<ConfiguredFeature<FC, F>> holder
|
||||||
|
) {
|
||||||
|
return place(featureID, BCLConfigureFeature.create(holder));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new {@link BCLFeature} builder.
|
||||||
|
*
|
||||||
|
* @param featureID {@link ResourceLocation} feature identifier.
|
||||||
|
* @param cFeature {@link Feature} the configured Feature to start from.
|
||||||
|
* @return {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
static <F extends Feature<FC>, FC extends FeatureConfiguration> BCLPlacedFeatureBuilder<F, FC> place(
|
||||||
|
ResourceLocation featureID,
|
||||||
|
BCLConfigureFeature<F, FC> cFeature
|
||||||
|
) {
|
||||||
|
return new BCLPlacedFeatureBuilder(featureID, cFeature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new {@link BCLFeature} instance.
|
||||||
|
*
|
||||||
|
* @return created {@link BCLFeature} instance.
|
||||||
|
*/
|
||||||
|
protected Holder<PlacedFeature> build() {
|
||||||
|
Holder<PlacedFeature> p = PlacementUtils.register(
|
||||||
|
featureID.toString(),
|
||||||
|
cFeature.configuredFeature,
|
||||||
|
modifications
|
||||||
|
);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new {@link BCLFeature} instance.
|
||||||
|
* Features will be registered during this process.
|
||||||
|
*
|
||||||
|
* @return created {@link BCLFeature} instance.
|
||||||
|
*/
|
||||||
|
public BCLFeature<F, FC> buildAndRegister() {
|
||||||
|
Holder<PlacedFeature> p = build();
|
||||||
|
return new BCLFeature(cFeature, p, decoration);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,375 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.config.PlaceFacingBlockConfig;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.placement.*;
|
||||||
|
import org.betterx.bclib.api.v2.tag.CommonBlockTags;
|
||||||
|
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
|
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.valueproviders.IntProvider;
|
||||||
|
import net.minecraft.util.valueproviders.UniformInt;
|
||||||
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.*;
|
||||||
|
import net.minecraft.world.level.material.Material;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends FeatureConfiguration, T extends CommonPlacedFeatureBuilder<F, FC, ?>> {
|
||||||
|
protected final List<PlacementModifier> modifications = new LinkedList<>();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feature placement modifier. Used as a condition for feature how to generate.
|
||||||
|
*
|
||||||
|
* @param modifiers {@link PlacementModifier}s to add.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T modifier(PlacementModifier... modifiers) {
|
||||||
|
for (var m : modifiers)
|
||||||
|
modifications.add(m);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feature placement modifier. Used as a condition for feature how to generate.
|
||||||
|
*
|
||||||
|
* @param modifiers {@link PlacementModifier}s to add.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T modifier(List<PlacementModifier> modifiers) {
|
||||||
|
modifications.addAll(modifiers);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate feature in certain iterations (per chunk).
|
||||||
|
*
|
||||||
|
* @param count how many times feature will be generated in chunk.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T count(int count) {
|
||||||
|
return modifier(CountPlacement.of(count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate feature in certain iterations (per chunk). Count can be between 0 and max value.
|
||||||
|
*
|
||||||
|
* @param count maximum amount of iterations per chunk.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T countMax(int count) {
|
||||||
|
return modifier(CountPlacement.of(UniformInt.of(0, count)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T countRange(int min, int max) {
|
||||||
|
return modifier(CountPlacement.of(UniformInt.of(min, max)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate points in a stencil pattern
|
||||||
|
*
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T stencil() {
|
||||||
|
return modifier(Stencil.all());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate points in a stencil pattern and selecting (on average) only every 4th
|
||||||
|
*
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T stencilOneIn4() {
|
||||||
|
return modifier(Stencil.oneIn4());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate points for every xz-Coordinate in a chunk. Be carefuller, this is quite expensive!
|
||||||
|
*
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T all() {
|
||||||
|
return modifier(All.simple());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate feature in certain iterations (per chunk).
|
||||||
|
* Feature will be generated on all layers (example - Nether plants).
|
||||||
|
*
|
||||||
|
* @param count how many times feature will be generated in chunk layers.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public T onEveryLayer(int count) {
|
||||||
|
return modifier(CountOnEveryLayerPlacement.of(count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate feature in certain iterations (per chunk). Count can be between 0 and max value.
|
||||||
|
* Feature will be generated on all layers (example - Nether plants).
|
||||||
|
*
|
||||||
|
* @param count maximum amount of iterations per chunk layers.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public T onEveryLayerMax(int count) {
|
||||||
|
return modifier(CountOnEveryLayerPlacement.of(UniformInt.of(0, count)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T onEveryLayer() {
|
||||||
|
return modifier(OnEveryLayer.simple());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T onEveryLayerMin4() {
|
||||||
|
return modifier(OnEveryLayer.min4());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T underEveryLayer() {
|
||||||
|
return modifier(UnderEveryLayer.simple());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T underEveryLayerMin4() {
|
||||||
|
return modifier(UnderEveryLayer.min4());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will place feature once every n-th attempts (in average).
|
||||||
|
*
|
||||||
|
* @param n amount of attempts.
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T onceEvery(int n) {
|
||||||
|
return modifier(RarityFilter.onAverageOnceEvery(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restricts feature generation only to biome where feature was added.
|
||||||
|
*
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T onlyInBiome() {
|
||||||
|
return modifier(BiomeFilter.biome());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Randomize the xz-Coordinates
|
||||||
|
*
|
||||||
|
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
||||||
|
*/
|
||||||
|
public T squarePlacement() {
|
||||||
|
return modifier(InSquarePlacement.spread());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select random height that is 10 above min Build height and 10 below max generation height
|
||||||
|
*
|
||||||
|
* @return The instance it was called on
|
||||||
|
*/
|
||||||
|
public T randomHeight10FromFloorCeil() {
|
||||||
|
return modifier(PlacementUtils.RANGE_10_10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select random height that is 4 above min Build height and 10 below max generation height
|
||||||
|
*
|
||||||
|
* @return The instance it was called on
|
||||||
|
*/
|
||||||
|
public T randomHeight4FromFloorCeil() {
|
||||||
|
return modifier(PlacementUtils.RANGE_4_4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select random height that is 8 above min Build height and 10 below max generation height
|
||||||
|
*
|
||||||
|
* @return The instance it was called on
|
||||||
|
*/
|
||||||
|
public T randomHeight8FromFloorCeil() {
|
||||||
|
return modifier(PlacementUtils.RANGE_8_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select random height that is above min Build height and 10 below max generation height
|
||||||
|
*
|
||||||
|
* @return The instance it was called on
|
||||||
|
*/
|
||||||
|
public T randomHeight() {
|
||||||
|
return modifier(PlacementUtils.FULL_RANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isEmptyAbove4() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove4());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isEmptyAbove2() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove2());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isEmptyAbove() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isEmptyBelow4() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow4());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isEmptyBelow2() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow2());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isEmptyBelow() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isEmptyAbove(int d1, int d2) {
|
||||||
|
return modifier(new IsEmptyAboveSampledFilter(d1, d2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T spreadHorizontal(IntProvider p) {
|
||||||
|
return modifier(RandomOffsetPlacement.horizontal(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T spreadVertical(IntProvider p) {
|
||||||
|
return modifier(RandomOffsetPlacement.horizontal(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T spread(IntProvider horizontal, IntProvider vertical) {
|
||||||
|
return modifier(RandomOffsetPlacement.of(horizontal, vertical));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T offset(Direction dir) {
|
||||||
|
return modifier(Offset.inDirection(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T offset(Vec3i dir) {
|
||||||
|
return modifier(new Offset(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast a downward ray with max {@code distance} length to find the next solid Block.
|
||||||
|
*
|
||||||
|
* @param distance The maximum search Distance
|
||||||
|
* @return The instance it was called on
|
||||||
|
* @see #findSolidSurface(Direction, int) for Details
|
||||||
|
*/
|
||||||
|
public T findSolidFloor(int distance) {
|
||||||
|
return modifier(FindSolidInDirection.down(distance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T noiseBasedCount(float noiseLevel, int belowNoiseCount, int aboveNoiseCount) {
|
||||||
|
return modifier(NoiseThresholdCountPlacement.of(noiseLevel, belowNoiseCount, aboveNoiseCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T extendDown(int min, int max) {
|
||||||
|
return modifier(new Extend(Direction.DOWN, UniformInt.of(min, max)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T inBasinOf(BlockPredicate... predicates) {
|
||||||
|
return modifier(new IsBasin(BlockPredicate.anyOf(predicates)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T inOpenBasinOf(BlockPredicate... predicates) {
|
||||||
|
return modifier(IsBasin.openTop(BlockPredicate.anyOf(predicates)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T is(BlockPredicate... predicates) {
|
||||||
|
return modifier(new Is(BlockPredicate.anyOf(predicates), Optional.empty()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isAbove(BlockPredicate... predicates) {
|
||||||
|
return modifier(new Is(BlockPredicate.anyOf(predicates), Optional.of(Direction.DOWN.getNormal())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T isUnder(BlockPredicate... predicates) {
|
||||||
|
return modifier(new Is(BlockPredicate.anyOf(predicates), Optional.of(Direction.UP.getNormal())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T findSolidCeil(int distance) {
|
||||||
|
return modifier(FindSolidInDirection.up(distance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T hasMinimumDownwardSpace() {
|
||||||
|
return modifier(MinEmptyFilter.down());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T hasMinimumUpwardSpace() {
|
||||||
|
return modifier(MinEmptyFilter.up());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast a ray with max {@code distance} length to find the next solid Block. The ray will travel through replaceable
|
||||||
|
* Blocks (see {@link Material#isReplaceable()}) and will be accepted if it hits a block with the
|
||||||
|
* {@link CommonBlockTags#TERRAIN}-tag
|
||||||
|
*
|
||||||
|
* @param dir The direction the ray is cast
|
||||||
|
* @param distance The maximum search Distance
|
||||||
|
* @return The instance it was called on
|
||||||
|
* @see #findSolidSurface(Direction, int) for Details
|
||||||
|
*/
|
||||||
|
public T findSolidSurface(Direction dir, int distance) {
|
||||||
|
return modifier(new FindSolidInDirection(dir, distance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T findSolidSurface(List<Direction> dir, int distance, boolean randomSelect) {
|
||||||
|
return modifier(new FindSolidInDirection(dir, distance, randomSelect));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T heightmap() {
|
||||||
|
return modifier(PlacementUtils.HEIGHTMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T heightmapTopSolid() {
|
||||||
|
return modifier(PlacementUtils.HEIGHTMAP_TOP_SOLID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T heightmapWorldSurface() {
|
||||||
|
return modifier(PlacementUtils.HEIGHTMAP_WORLD_SURFACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T onlyWhenEmpty() {
|
||||||
|
return modifier(BlockPredicateFilter.forPredicate(BlockPredicate.ONLY_IN_AIR_PREDICATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T filtered(BlockPredicate predicate) {
|
||||||
|
return modifier(BlockPredicateFilter.forPredicate(predicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T vanillaNetherGround(int countPerLayer) {
|
||||||
|
return (T) this.onEveryLayer(countPerLayer).onlyInBiome();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T betterNetherGround(int countPerLayer) {
|
||||||
|
return (T) this.count(countPerLayer).squarePlacement().onEveryLayerMin4().onlyInBiome();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T betterNetherCeiling(int countPerLayer) {
|
||||||
|
return (T) this.count(countPerLayer).squarePlacement().underEveryLayerMin4().onlyInBiome();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T betterNetherWall(int countPerLayer) {
|
||||||
|
return (T) this.count(countPerLayer)
|
||||||
|
.squarePlacement()
|
||||||
|
.randomHeight4FromFloorCeil()
|
||||||
|
.modifier(new FindSolidInDirection(PlaceFacingBlockConfig.HORIZONTAL, 12, false))
|
||||||
|
.onlyInBiome();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new inline (not registered) {@link PlacedFeature}.
|
||||||
|
*
|
||||||
|
* @return created {@link PlacedFeature} instance.
|
||||||
|
*/
|
||||||
|
abstract Holder<PlacedFeature> build();
|
||||||
|
|
||||||
|
public BCLFeatureBuilder.RandomPatch inRandomPatch(ResourceLocation id) {
|
||||||
|
return BCLFeatureBuilder.startRandomPatch(id, build());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
|
||||||
|
public interface UserGrowableFeature<FC extends FeatureConfiguration> extends org.betterx.bclib.api.v2.levelgen.features.UserGrowableFeature<FC> {
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue