More Feature Refactoring
This commit is contained in:
parent
c1d5ca7b9b
commit
5d85595c5a
19 changed files with 621 additions and 128 deletions
|
@ -135,8 +135,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
|
||||
|
||||
private static boolean isValidNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
||||
return biome.unwrapKey().get().location().toString().contains("mushroom_forest")
|
||||
|| biome.unwrapKey().get().location().toString().contains("old_fungiwoods");
|
||||
return biome.unwrapKey().get().location().toString().contains("upside_down");
|
||||
|
||||
// return NetherBiomes.canGenerateInNether(biome.unwrapKey().get()) ||
|
||||
// biome.is(BiomeTags.IS_NETHER) ||
|
||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguratio
|
|||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockMatchTest;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public class BCLCommonFeatures {
|
||||
/**
|
||||
* Will create a basic plant feature.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package org.betterx.bclib.api.v2.levelgen.features;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.config.*;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.features.*;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
|
@ -25,7 +25,7 @@ import net.minecraft.world.level.levelgen.feature.configurations.RandomPatchConf
|
|||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
|
@ -35,62 +35,57 @@ import java.util.Optional;
|
|||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||
public static final Feature<PlaceFacingBlockConfig> PLACE_BLOCK = register(
|
||||
BCLib.makeID("place_block"),
|
||||
new PlaceBlockFeature<>(PlaceFacingBlockConfig.CODEC)
|
||||
);
|
||||
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = register(
|
||||
BCLib.makeID("scatter_on_solid"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
||||
);
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#PLACE_BLOCK}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<PlaceFacingBlockConfig> PLACE_BLOCK = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.PLACE_BLOCK;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#SCATTER_ON_SOLID}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_ON_SOLID;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#SCATTER_EXTEND_TOP}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_EXTEND_TOP;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#SCATTER_EXTEND_BOTTOM}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_EXTEND_BOTTOM;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#RANDOM_SELECTOR}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.RANDOM_SELECTOR;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#TEMPLATE}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<TemplateFeatureConfig> TEMPLATE = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#MARK_POSTPROCESSING}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<NoneFeatureConfiguration> MARK_POSTPROCESSING = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.MARK_POSTPROCESSING;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#SEQUENCE}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<SequenceFeatureConfig> SEQUENCE = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SEQUENCE;
|
||||
/**
|
||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#CONDITION}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Feature<ConditionFeatureConfig> CONDITION = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.CONDITION;
|
||||
|
||||
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = register(
|
||||
BCLib.makeID("scatter_extend_top"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendTop.CODEC)
|
||||
);
|
||||
|
||||
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = register(
|
||||
BCLib.makeID("scatter_extend_bottom"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendBottom.CODEC)
|
||||
);
|
||||
|
||||
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = register(
|
||||
BCLib.makeID("random_select"),
|
||||
new WeightedRandomSelectorFeature()
|
||||
);
|
||||
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(
|
||||
BCLib.makeID("template"),
|
||||
new TemplateFeature(
|
||||
TemplateFeatureConfig.CODEC)
|
||||
);
|
||||
|
||||
public static final Feature<NoneFeatureConfiguration> MARK_POSTPROCESSING = register(
|
||||
BCLib.makeID(
|
||||
"mark_postprocessing"),
|
||||
new MarkPostProcessingFeature()
|
||||
);
|
||||
|
||||
public static final Feature<SequenceFeatureConfig> SEQUENCE = register(
|
||||
BCLib.makeID("sequence"),
|
||||
new SequenceFeature()
|
||||
);
|
||||
|
||||
public static final Feature<ConditionFeatureConfig> CONDITION = register(
|
||||
BCLib.makeID("condition"),
|
||||
new ConditionFeature()
|
||||
);
|
||||
|
||||
public static final Feature<PillarFeatureConfig> PILLAR = register(
|
||||
BCLib.makeID("pillar"),
|
||||
new PillarFeature()
|
||||
);
|
||||
private final Holder<PlacedFeature> placedFeature;
|
||||
private final Decoration featureStep;
|
||||
private final F feature;
|
||||
private final FC configuration;
|
||||
public final ResourceLocation id;
|
||||
|
||||
org.betterx.bclib.api.v3.levelgen.features.BCLFeature<F, FC> proxy;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLFeature(
|
||||
ResourceLocation id,
|
||||
F feature,
|
||||
|
@ -101,6 +96,35 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
this(id, feature, featureStep, configuration, buildPlacedFeature(id, feature, configuration, modifiers));
|
||||
}
|
||||
|
||||
private static <E> boolean containsObj(Registry<E> registry, E obj) {
|
||||
Optional<Map.Entry<ResourceKey<E>, E>> optional = registry
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getValue() == obj)
|
||||
.findAny();
|
||||
return optional.isPresent();
|
||||
}
|
||||
|
||||
private static <F extends Feature<FC>, FC extends FeatureConfiguration> org.betterx.bclib.api.v3.levelgen.features.BCLFeature<F, FC> build(
|
||||
ResourceLocation id,
|
||||
F feature,
|
||||
Decoration featureStep,
|
||||
FC configuration,
|
||||
Holder<PlacedFeature> placedFeature
|
||||
) {
|
||||
BCLConfigureFeature<F, FC> cfg = BCLFeatureBuilder.start(id, feature)
|
||||
.configuration(configuration)
|
||||
.build();
|
||||
if (!BuiltinRegistries.PLACED_FEATURE.containsKey(id)) {
|
||||
Registry.register(BuiltinRegistries.PLACED_FEATURE, id, placedFeature.value());
|
||||
}
|
||||
if (!Registry.FEATURE.containsKey(id) && !containsObj(Registry.FEATURE, feature)) {
|
||||
Registry.register(Registry.FEATURE, id, feature);
|
||||
}
|
||||
return new org.betterx.bclib.api.v3.levelgen.features.BCLFeature<>(cfg, placedFeature, featureStep);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLFeature(
|
||||
ResourceLocation id,
|
||||
F feature,
|
||||
|
@ -108,18 +132,13 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
FC configuration,
|
||||
Holder<PlacedFeature> placedFeature
|
||||
) {
|
||||
this.placedFeature = placedFeature;
|
||||
this.featureStep = featureStep;
|
||||
this.feature = feature;
|
||||
this.configuration = configuration;
|
||||
this.id = id;
|
||||
this(build(id, feature, featureStep, configuration, placedFeature));
|
||||
}
|
||||
|
||||
if (!BuiltinRegistries.PLACED_FEATURE.containsKey(id)) {
|
||||
Registry.register(BuiltinRegistries.PLACED_FEATURE, id, placedFeature.value());
|
||||
}
|
||||
if (!Registry.FEATURE.containsKey(id) && !containsObj(Registry.FEATURE, feature)) {
|
||||
Registry.register(Registry.FEATURE, id, feature);
|
||||
}
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLFeature(org.betterx.bclib.api.v3.levelgen.features.BCLFeature proxy) {
|
||||
this.proxy = proxy;
|
||||
this.id = proxy.configuredFeature.id;
|
||||
}
|
||||
|
||||
private static <FC extends FeatureConfiguration, F extends Feature<FC>> Holder<PlacedFeature> buildPlacedFeature(
|
||||
|
@ -154,20 +173,20 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
}
|
||||
}
|
||||
|
||||
private static <E> boolean containsObj(Registry<E> registry, E obj) {
|
||||
Optional<Entry<ResourceKey<E>, E>> optional = registry
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getValue() == obj)
|
||||
.findAny();
|
||||
return optional.isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @param feature
|
||||
* @param <C>
|
||||
* @param <F>
|
||||
* @return
|
||||
* @deprecated Use {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#register(ResourceLocation, Feature)} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static <C extends FeatureConfiguration, F extends Feature<C>> F register(
|
||||
ResourceLocation string,
|
||||
F feature
|
||||
) {
|
||||
return Registry.register(Registry.FEATURE, string, feature);
|
||||
return org.betterx.bclib.api.v3.levelgen.features.BCLFeature.register(string, feature);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,7 +195,11 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
* @return {@link Feature}.
|
||||
*/
|
||||
public F getFeature() {
|
||||
return feature;
|
||||
return proxy.getFeature();
|
||||
}
|
||||
|
||||
public BCLConfigureFeature<F, FC> getConfFeature() {
|
||||
return proxy.configuredFeature;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,7 +208,7 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
* @return {@link PlacedFeature}.
|
||||
*/
|
||||
public Holder<PlacedFeature> getPlacedFeature() {
|
||||
return placedFeature;
|
||||
return proxy.getPlacedFeature();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,11 +217,11 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
* @return {@link Decoration}.
|
||||
*/
|
||||
public Decoration getDecoration() {
|
||||
return featureStep;
|
||||
return proxy.getDecoration();
|
||||
}
|
||||
|
||||
public FC getConfiguration() {
|
||||
return configuration;
|
||||
return proxy.getConfiguration();
|
||||
}
|
||||
|
||||
public boolean place(ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
|
|
|
@ -35,7 +35,9 @@ public class FastFeatures {
|
|||
boolean sparse,
|
||||
ScatterFeatureConfig.Builder builder
|
||||
) {
|
||||
return scatter(location, onFloor, sparse, builder, BCLFeature.SCATTER_ON_SOLID);
|
||||
return scatter(location, onFloor, sparse, builder,
|
||||
org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_ON_SOLID
|
||||
);
|
||||
}
|
||||
|
||||
public static BCLFeature scatter(
|
||||
|
@ -229,7 +231,8 @@ public class FastFeatures {
|
|||
int xzSpread,
|
||||
int ySpread
|
||||
) {
|
||||
final BCLFeature SINGLE = simple(location, ySpread, false, BCLFeature.PLACE_BLOCK,
|
||||
final BCLFeature SINGLE = simple(location, ySpread, false,
|
||||
org.betterx.bclib.api.v3.levelgen.features.BCLFeature.PLACE_BLOCK,
|
||||
new PlaceFacingBlockConfig(block, PlaceFacingBlockConfig.HORIZONTAL)
|
||||
);
|
||||
return patch(location, attempts, xzSpread, ySpread, SINGLE);
|
||||
|
|
|
@ -23,7 +23,7 @@ public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<F
|
|||
|
||||
|
||||
return BCLFeatureBuilder
|
||||
.start(location, BCLFeature.TEMPLATE)
|
||||
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
||||
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
||||
.onceEvery(onceEveryChunk) //discard neighboring chunks
|
||||
.count(16) //try 16 placements in chunk
|
||||
|
@ -42,7 +42,7 @@ public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<F
|
|||
int count
|
||||
) {
|
||||
return BCLFeatureBuilder
|
||||
.start(location, BCLFeature.TEMPLATE)
|
||||
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
||||
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
||||
.count(count)
|
||||
.squarePlacement()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.placement.NoiseFilter;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.core.Registry;
|
||||
|
@ -9,6 +10,10 @@ import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
|||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||
|
||||
public class PlacementModifiers {
|
||||
public static final PlacementModifierType<NoiseFilter> NOISE_FILTER = register(
|
||||
"noise_filter",
|
||||
NoiseFilter.CODEC
|
||||
);
|
||||
public static final PlacementModifierType<Debug> DEBUG = register(
|
||||
"debug",
|
||||
Debug.CODEC
|
||||
|
|
|
@ -83,5 +83,6 @@ public class Conditions {
|
|||
registerNumeric(BCLib.makeID("nether_noise"), NetherNoiseCondition.CODEC);
|
||||
register(BCLib.makeID("threshold_condition"), ThresholdCondition.CODEC);
|
||||
register(BCLib.makeID("volume_threshold_condition"), VolumeThresholdCondition.CODEC);
|
||||
register(BCLib.makeID("rough_noise_condition"), RoughNoiseCondition.CODEC);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
package org.betterx.bclib.api.v2.levelgen.surface.rules;
|
||||
|
||||
|
||||
import org.betterx.bclib.mixin.common.SurfaceRulesContextAccessor;
|
||||
import org.betterx.bclib.noise.Noises;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.KeyDispatchDataCodec;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.valueproviders.FloatProvider;
|
||||
import net.minecraft.util.valueproviders.UniformFloat;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
|
||||
public class RoughNoiseCondition implements SurfaceRules.ConditionSource {
|
||||
public static final Codec<RoughNoiseCondition> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
ResourceKey.codec(Registry.NOISE_REGISTRY).fieldOf("noise").forGetter(o -> o.noise),
|
||||
Codec.DOUBLE.fieldOf("min_threshold").forGetter(o -> o.minThreshold),
|
||||
Codec.DOUBLE.fieldOf("max_threshold").forGetter(o -> o.maxThreshold),
|
||||
FloatProvider.CODEC.fieldOf("roughness").forGetter(o -> o.roughness)
|
||||
)
|
||||
.apply(
|
||||
instance,
|
||||
(noise1, minThreshold1, maxThreshold1, roughness1) -> new RoughNoiseCondition(
|
||||
noise1,
|
||||
roughness1,
|
||||
minThreshold1,
|
||||
maxThreshold1
|
||||
)
|
||||
));
|
||||
|
||||
public static final KeyDispatchDataCodec<RoughNoiseCondition> KEY_CODEC = KeyDispatchDataCodec.of(CODEC);
|
||||
|
||||
private final ResourceKey<NormalNoise.NoiseParameters> noise;
|
||||
private final double minThreshold;
|
||||
private final double maxThreshold;
|
||||
private final FloatProvider roughness;
|
||||
|
||||
public RoughNoiseCondition(
|
||||
ResourceKey<NormalNoise.NoiseParameters> noise,
|
||||
FloatProvider roughness,
|
||||
double minThreshold,
|
||||
double maxThreshold
|
||||
) {
|
||||
this.noise = noise;
|
||||
this.minThreshold = minThreshold;
|
||||
|
||||
this.maxThreshold = maxThreshold;
|
||||
this.roughness = roughness;
|
||||
}
|
||||
|
||||
public RoughNoiseCondition(
|
||||
ResourceKey<NormalNoise.NoiseParameters> noise,
|
||||
FloatProvider roughness,
|
||||
double minThreshold
|
||||
) {
|
||||
this(noise, roughness, minThreshold, Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
public RoughNoiseCondition(
|
||||
ResourceKey<NormalNoise.NoiseParameters> noise,
|
||||
double minThreshold
|
||||
) {
|
||||
this(noise, UniformFloat.of(-0.2f, 0.4f), minThreshold, Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
public RoughNoiseCondition(
|
||||
ResourceKey<NormalNoise.NoiseParameters> noise,
|
||||
double minThreshold,
|
||||
double maxThreshold
|
||||
) {
|
||||
this(noise, UniformFloat.of(-0.1f, 0.4f), minThreshold, maxThreshold);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDispatchDataCodec<? extends SurfaceRules.ConditionSource> codec() {
|
||||
return KEY_CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceRules.Condition apply(final SurfaceRules.Context context2) {
|
||||
final SurfaceRulesContextAccessor ctx = SurfaceRulesContextAccessor.class.cast(context2);
|
||||
final NormalNoise normalNoise = ctx.getRandomState().getOrCreateNoise(this.noise);
|
||||
final RandomSource roughnessSource = ctx.getRandomState()
|
||||
.getOrCreateRandomFactory(Noises.ROUGHNESS_NOISE.location())
|
||||
.fromHashOf(Noises.ROUGHNESS_NOISE.location());
|
||||
|
||||
class NoiseThresholdCondition extends SurfaceRules.LazyCondition {
|
||||
NoiseThresholdCondition() {
|
||||
super(context2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getContextLastUpdate() {
|
||||
final SurfaceRulesContextAccessor ctx = SurfaceRulesContextAccessor.class.cast(this.context);
|
||||
return ctx.getLastUpdateY() + ctx.getLastUpdateXZ();
|
||||
}
|
||||
|
||||
protected boolean compute() {
|
||||
double d = normalNoise
|
||||
.getValue(
|
||||
ctx.getBlockX(),
|
||||
ctx.getBlockZ(),
|
||||
ctx.getBlockZ()
|
||||
) + roughness.sample(roughnessSource);
|
||||
return d >= minThreshold && d <= maxThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
return new NoiseThresholdCondition();
|
||||
}
|
||||
}
|
|
@ -1,13 +1,22 @@
|
|||
package org.betterx.bclib.api.v3.levelgen.features;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.features.UserGrowableFeature;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
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.RandomPatchConfiguration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||
private static final Map<Holder<ConfiguredFeature<?, ?>>, BCLConfigureFeature<?, ?>> KNOWN = new HashMap<>();
|
||||
|
@ -46,4 +55,55 @@ public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfig
|
|||
.location(), registeredFeature, false)
|
||||
);
|
||||
}
|
||||
|
||||
public boolean placeInWorld(ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
return placeInWorld(getFeature(), getConfiguration(), level, pos, random);
|
||||
}
|
||||
|
||||
private static boolean placeUnboundInWorld(
|
||||
Feature<?> feature,
|
||||
FeatureConfiguration config,
|
||||
ServerLevel level,
|
||||
BlockPos pos,
|
||||
RandomSource random
|
||||
) {
|
||||
if (config instanceof RandomPatchConfiguration rnd) {
|
||||
var configured = rnd.feature().value().feature().value();
|
||||
feature = configured.feature();
|
||||
config = configured.config();
|
||||
}
|
||||
|
||||
if (feature instanceof UserGrowableFeature growable) {
|
||||
return growable.grow(level, pos, random, config);
|
||||
}
|
||||
|
||||
FeaturePlaceContext context = new FeaturePlaceContext(
|
||||
Optional.empty(),
|
||||
level,
|
||||
level.getChunkSource().getGenerator(),
|
||||
random,
|
||||
pos,
|
||||
config
|
||||
);
|
||||
return feature.place(context);
|
||||
}
|
||||
|
||||
public static boolean placeInWorld(
|
||||
Feature<NoneFeatureConfiguration> feature,
|
||||
ServerLevel level,
|
||||
BlockPos pos,
|
||||
RandomSource random
|
||||
) {
|
||||
return placeUnboundInWorld(feature, FeatureConfiguration.NONE, level, pos, random);
|
||||
}
|
||||
|
||||
public static <FC extends FeatureConfiguration> boolean placeInWorld(
|
||||
Feature<FC> feature,
|
||||
FC config,
|
||||
ServerLevel level,
|
||||
BlockPos pos,
|
||||
RandomSource random
|
||||
) {
|
||||
return placeUnboundInWorld(feature, config, level, pos, random);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package org.betterx.bclib.api.v3.levelgen.features;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.config.*;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.features.*;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
|
@ -10,21 +14,65 @@ import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConf
|
|||
import net.minecraft.world.level.levelgen.feature.configurations.RandomFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
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 static final Feature<PlaceFacingBlockConfig> PLACE_BLOCK = register(
|
||||
BCLib.makeID("place_block"),
|
||||
new PlaceBlockFeature<>(PlaceFacingBlockConfig.CODEC)
|
||||
);
|
||||
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = register(
|
||||
BCLib.makeID("scatter_on_solid"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
||||
);
|
||||
|
||||
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = register(
|
||||
BCLib.makeID("scatter_extend_top"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendTop.CODEC)
|
||||
);
|
||||
|
||||
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = register(
|
||||
BCLib.makeID("scatter_extend_bottom"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendBottom.CODEC)
|
||||
);
|
||||
|
||||
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = register(
|
||||
BCLib.makeID("random_select"),
|
||||
new WeightedRandomSelectorFeature()
|
||||
);
|
||||
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(
|
||||
BCLib.makeID("template"),
|
||||
new TemplateFeature(
|
||||
TemplateFeatureConfig.CODEC)
|
||||
);
|
||||
|
||||
public static final Feature<NoneFeatureConfiguration> MARK_POSTPROCESSING = register(
|
||||
BCLib.makeID(
|
||||
"mark_postprocessing"),
|
||||
new MarkPostProcessingFeature()
|
||||
);
|
||||
|
||||
public static final Feature<SequenceFeatureConfig> SEQUENCE = register(
|
||||
BCLib.makeID("sequence"),
|
||||
new SequenceFeature()
|
||||
);
|
||||
|
||||
public static final Feature<ConditionFeatureConfig> CONDITION = register(
|
||||
BCLib.makeID("condition"),
|
||||
new ConditionFeature()
|
||||
);
|
||||
|
||||
public static final Feature<PillarFeatureConfig> PILLAR = register(
|
||||
BCLib.makeID("pillar"),
|
||||
new PillarFeature()
|
||||
);
|
||||
public final BCLConfigureFeature<F, FC> configuredFeature;
|
||||
public final Holder<PlacedFeature> placedFeature;
|
||||
public final GenerationStep.Decoration decoration;
|
||||
|
||||
BCLFeature(
|
||||
@ApiStatus.Internal
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLFeature(
|
||||
BCLConfigureFeature<F, FC> configuredFeature,
|
||||
Holder<PlacedFeature> placed,
|
||||
GenerationStep.Decoration decoration
|
||||
|
@ -34,11 +82,42 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
this.decoration = decoration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw feature.
|
||||
*
|
||||
* @return {@link Feature}.
|
||||
*/
|
||||
public F getFeature() {
|
||||
return configuredFeature.getFeature();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get configured feature.
|
||||
*
|
||||
* @return {@link PlacedFeature}.
|
||||
*/
|
||||
public Holder<PlacedFeature> getPlacedFeature() {
|
||||
return placedFeature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get feature decoration step.
|
||||
*
|
||||
* @return {@link GenerationStep.Decoration}.
|
||||
*/
|
||||
public GenerationStep.Decoration getDecoration() {
|
||||
return decoration;
|
||||
}
|
||||
|
||||
public FC getConfiguration() {
|
||||
return configuredFeature.getConfiguration();
|
||||
}
|
||||
|
||||
|
||||
public static <C extends FeatureConfiguration, F extends Feature<C>> F register(
|
||||
ResourceLocation location,
|
||||
F feature
|
||||
) {
|
||||
return Registry.register(Registry.FEATURE, location, feature);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.betterx.bclib.api.v3.levelgen.features;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.config.PillarFeatureConfig;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.config.PlaceFacingBlockConfig;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.config.SequenceFeatureConfig;
|
||||
|
@ -43,6 +42,7 @@ import java.util.Set;
|
|||
import java.util.function.BiFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||
private final ResourceLocation featureID;
|
||||
private final F feature;
|
||||
|
@ -122,7 +122,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
|
||||
public static AsMultiPlaceRandomSelect startRandomSelect(
|
||||
ResourceLocation featureID,
|
||||
BiFunction<BCLInlinePlacedBuilder<SimpleBlockFeature, SimpleBlockConfiguration>, Integer, Holder<PlacedFeature>> placementModFunction
|
||||
AsMultiPlaceRandomSelect.Placer placementModFunction
|
||||
) {
|
||||
return new AsMultiPlaceRandomSelect(
|
||||
featureID,
|
||||
|
@ -146,7 +146,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
) {
|
||||
return new WithTemplates(
|
||||
featureID,
|
||||
(TemplateFeature<TemplateFeatureConfig>) BCLFeature.TEMPLATE
|
||||
(TemplateFeature<TemplateFeatureConfig>) org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
}
|
||||
|
||||
|
||||
public AsSequence add(org.betterx.bclib.api.v3.levelgen.features.BCLFeature p) {
|
||||
public AsSequence add(org.betterx.bclib.api.v3.levelgen.features.BCLFeature<?, ?> p) {
|
||||
return add(p.placedFeature);
|
||||
}
|
||||
|
||||
|
@ -427,12 +427,10 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
.build();
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public final AsBlockColumn<FF> addRandom(int height, BlockState... states) {
|
||||
return this.addRandom(ConstantInt.of(height), states);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public final AsBlockColumn<FF> addRandom(IntProvider height, BlockState... states) {
|
||||
var builder = SimpleWeightedRandomList.<BlockState>builder();
|
||||
for (BlockState state : states) builder.add(state, 1);
|
||||
|
@ -659,7 +657,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
super(featureID, feature);
|
||||
}
|
||||
|
||||
public WithConfiguration configuration(FC config) {
|
||||
public WithConfiguration<F, FC> configuration(FC config) {
|
||||
this.configuration = config;
|
||||
return this;
|
||||
}
|
||||
|
@ -673,7 +671,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
}
|
||||
|
||||
public static class FacingBlock extends BCLFeatureBuilder<PlaceBlockFeature<PlaceFacingBlockConfig>, PlaceFacingBlockConfig> {
|
||||
private SimpleWeightedRandomList.Builder<BlockState> stateBuilder = SimpleWeightedRandomList.builder();
|
||||
private final SimpleWeightedRandomList.Builder<BlockState> stateBuilder = SimpleWeightedRandomList.builder();
|
||||
BlockState firstState;
|
||||
private int count = 0;
|
||||
private List<Direction> directions = PlaceFacingBlockConfig.HORIZONTAL;
|
||||
|
@ -805,7 +803,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
}
|
||||
|
||||
public static class AsRandomSelect extends BCLFeatureBuilder<RandomSelectorFeature, RandomFeatureConfiguration> {
|
||||
private List<WeightedPlacedFeature> features = new LinkedList<>();
|
||||
private final List<WeightedPlacedFeature> features = new LinkedList<>();
|
||||
private Holder<PlacedFeature> defaultFeature;
|
||||
|
||||
private AsRandomSelect(ResourceLocation featureID, RandomSelectorFeature feature) {
|
||||
|
@ -830,14 +828,21 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
}
|
||||
|
||||
public static class AsMultiPlaceRandomSelect extends BCLFeatureBuilder<RandomSelectorFeature, RandomFeatureConfiguration> {
|
||||
private List<Triple<BlockStateProvider, Float, Integer>> features = new LinkedList<>();
|
||||
public interface Placer {
|
||||
Holder<PlacedFeature> place(
|
||||
BCLInlinePlacedBuilder<SimpleBlockFeature, SimpleBlockConfiguration> placer,
|
||||
int id
|
||||
);
|
||||
}
|
||||
|
||||
private final BiFunction<BCLInlinePlacedBuilder<SimpleBlockFeature, SimpleBlockConfiguration>, Integer, Holder<PlacedFeature>> modFunction;
|
||||
private final List<Triple<BlockStateProvider, Float, Integer>> features = new LinkedList<>();
|
||||
|
||||
private final Placer modFunction;
|
||||
|
||||
private AsMultiPlaceRandomSelect(
|
||||
ResourceLocation featureID,
|
||||
RandomSelectorFeature feature,
|
||||
BiFunction<BCLInlinePlacedBuilder<SimpleBlockFeature, SimpleBlockConfiguration>, Integer, Holder<PlacedFeature>> mod
|
||||
Placer mod
|
||||
) {
|
||||
super(featureID, feature);
|
||||
this.modFunction = mod;
|
||||
|
@ -916,7 +921,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
var builder = BCLFeatureBuilder
|
||||
.start(BCLib.makeID("temp_select_feature" + (featureCounter++)), p)
|
||||
.inlinePlace();
|
||||
return modFunction.apply(builder, id);
|
||||
return modFunction.place(builder, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -924,7 +929,7 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
if (modFunction == null) {
|
||||
throw new IllegalStateException("AsMultiPlaceRandomSelect needs a placement.modification Function");
|
||||
}
|
||||
float sum = this.features.stream().map(p -> p.second).reduce(0.0f, (p, v) -> p + v);
|
||||
float sum = this.features.stream().map(p -> p.second).reduce(0.0f, Float::sum);
|
||||
List<WeightedPlacedFeature> features = this.features.stream()
|
||||
.map(p -> new WeightedPlacedFeature(
|
||||
this.place(p.first, p.third),
|
||||
|
|
|
@ -15,6 +15,7 @@ public class BlockPredicates {
|
|||
Blocks.SAND,
|
||||
Blocks.RED_SAND
|
||||
);
|
||||
public static final BlockPredicate ONLY_SOUL_GROUND = BlockPredicate.matchesTag(CommonBlockTags.SOUL_GROUND);
|
||||
public static final BlockPredicate ONLY_NETHER_GROUND = BlockPredicate.matchesTag(CommonBlockTags.NETHER_TERRAIN);
|
||||
public static final BlockPredicate ONLY_GROUND = BlockPredicate.matchesTag(CommonBlockTags.TERRAIN);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ 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.v3.levelgen.features.placement.NoiseFilter;
|
||||
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
|
@ -11,6 +12,7 @@ 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.Noises;
|
||||
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;
|
||||
|
@ -158,6 +160,18 @@ abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends Feat
|
|||
return modifier(BiomeFilter.biome());
|
||||
}
|
||||
|
||||
public T noiseIn(double min, double max, float scaleXZ, float scaleY) {
|
||||
return modifier(new NoiseFilter(Noises.GRAVEL, min, max, scaleXZ, scaleY));
|
||||
}
|
||||
|
||||
public T noiseAbove(double value, float scaleXZ, float scaleY) {
|
||||
return modifier(new NoiseFilter(Noises.GRAVEL, value, Double.MAX_VALUE, scaleXZ, scaleY));
|
||||
}
|
||||
|
||||
public T noiseBelow(double value, float scaleXZ, float scaleY) {
|
||||
return modifier(new NoiseFilter(Noises.GRAVEL, -Double.MAX_VALUE, value, scaleXZ, scaleY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Randomize the xz-Coordinates
|
||||
*
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.features.placement.PlacementModifiers;
|
||||
import org.betterx.bclib.noise.Noises;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
|
||||
public class NoiseFilter extends PlacementFilter {
|
||||
public static final Codec<NoiseFilter> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
ResourceKey.codec(Registry.NOISE_REGISTRY).fieldOf("noise").forGetter(o -> o.noise),
|
||||
Codec.DOUBLE.fieldOf("min_noise_level").forGetter(o -> o.minNoiseLevel),
|
||||
Codec.DOUBLE.fieldOf("max_noise_level").orElse(Double.MAX_VALUE).forGetter(o -> o.maxNoiseLevel),
|
||||
Codec.FLOAT.fieldOf("scale_xz").orElse(1f).forGetter(o -> o.scaleXZ),
|
||||
Codec.FLOAT.fieldOf("scale_y").orElse(1f).forGetter(o -> o.scaleY)
|
||||
)
|
||||
.apply(instance, NoiseFilter::new));
|
||||
|
||||
private final ResourceKey<NormalNoise.NoiseParameters> noise;
|
||||
|
||||
private final double minNoiseLevel;
|
||||
private final double maxNoiseLevel;
|
||||
private final float scaleXZ;
|
||||
private final float scaleY;
|
||||
|
||||
|
||||
public NoiseFilter(
|
||||
ResourceKey<NormalNoise.NoiseParameters> noise,
|
||||
double minNoiseLevel,
|
||||
double maxNoiseLevel,
|
||||
float scaleXZ,
|
||||
float scaleY
|
||||
) {
|
||||
this.noise = noise;
|
||||
this.minNoiseLevel = minNoiseLevel;
|
||||
this.maxNoiseLevel = maxNoiseLevel;
|
||||
this.scaleXZ = scaleXZ;
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
||||
final NormalNoise normalNoise = Noises.getOrCreateNoise(ctx.getLevel().registryAccess(), random, this.noise);
|
||||
final double v = normalNoise.getValue(pos.getX() * scaleXZ, pos.getY() * scaleY, pos.getZ() * scaleXZ);
|
||||
return v > minNoiseLevel && v < maxNoiseLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementModifierType<?> type() {
|
||||
return PlacementModifiers.NOISE_FILTER;
|
||||
}
|
||||
}
|
|
@ -1,27 +1,28 @@
|
|||
package org.betterx.bclib.blocks;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class FeatureHangingSaplingBlock extends FeatureSaplingBlock {
|
||||
public abstract class FeatureHangingSaplingBlock<F extends Feature<FC>, FC extends FeatureConfiguration> extends FeatureSaplingBlock {
|
||||
|
||||
private static final VoxelShape SHAPE = Block.box(4, 2, 4, 12, 16, 12);
|
||||
|
||||
public FeatureHangingSaplingBlock(Function<BlockState, BCLFeature> featureSupplier) {
|
||||
public FeatureHangingSaplingBlock(FeatureSupplier<F, FC> featureSupplier) {
|
||||
super(featureSupplier);
|
||||
}
|
||||
|
||||
public FeatureHangingSaplingBlock(
|
||||
Function<BlockState, BCLFeature> featureSupplier,
|
||||
FeatureSupplier<F, FC> featureSupplier,
|
||||
int light
|
||||
) {
|
||||
super(light, featureSupplier);
|
||||
|
@ -29,7 +30,28 @@ public abstract class FeatureHangingSaplingBlock extends FeatureSaplingBlock {
|
|||
|
||||
public FeatureHangingSaplingBlock(
|
||||
BlockBehaviour.Properties properties,
|
||||
Function<BlockState, BCLFeature> featureSupplier
|
||||
FeatureSupplier<F, FC> featureSupplier
|
||||
) {
|
||||
super(properties, featureSupplier);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public FeatureHangingSaplingBlock(Function<BlockState, org.betterx.bclib.api.v2.levelgen.features.BCLFeature> featureSupplier) {
|
||||
super(featureSupplier);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public FeatureHangingSaplingBlock(
|
||||
Function<BlockState, org.betterx.bclib.api.v2.levelgen.features.BCLFeature> featureSupplier,
|
||||
int light
|
||||
) {
|
||||
super(light, featureSupplier);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public FeatureHangingSaplingBlock(
|
||||
BlockBehaviour.Properties properties,
|
||||
Function<BlockState, org.betterx.bclib.api.v2.levelgen.features.BCLFeature> featureSupplier
|
||||
) {
|
||||
super(properties, featureSupplier);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.betterx.bclib.blocks;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.BCLFeature;
|
||||
import org.betterx.bclib.client.models.BasePatterns;
|
||||
import org.betterx.bclib.client.models.ModelsHelper;
|
||||
import org.betterx.bclib.client.models.PatternsHelper;
|
||||
|
@ -24,6 +25,9 @@ import net.minecraft.world.level.block.SaplingBlock;
|
|||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
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.material.Material;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
|
@ -39,11 +43,17 @@ import java.util.Optional;
|
|||
import java.util.function.Function;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProvider, BlockModelProvider {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||
private final Function<BlockState, BCLFeature> feature;
|
||||
public class FeatureSaplingBlock<F extends Feature<FC>, FC extends FeatureConfiguration> extends SaplingBlock implements RenderLayerProvider, BlockModelProvider {
|
||||
|
||||
public FeatureSaplingBlock(Function<BlockState, BCLFeature> featureSupplier) {
|
||||
@FunctionalInterface
|
||||
public interface FeatureSupplier<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||
BCLConfigureFeature<F, FC> get(BlockState state);
|
||||
}
|
||||
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||
private final FeatureSupplier<F, FC> feature;
|
||||
|
||||
public FeatureSaplingBlock(FeatureSupplier<F, FC> featureSupplier) {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.collidable(false)
|
||||
|
@ -54,7 +64,7 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
|||
);
|
||||
}
|
||||
|
||||
public FeatureSaplingBlock(int light, Function<BlockState, BCLFeature> featureSupplier) {
|
||||
public FeatureSaplingBlock(int light, FeatureSupplier<F, FC> featureSupplier) {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.collidable(false)
|
||||
|
@ -68,14 +78,60 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
|||
|
||||
public FeatureSaplingBlock(
|
||||
BlockBehaviour.Properties properties,
|
||||
Function<BlockState, BCLFeature> featureSupplier
|
||||
FeatureSupplier<F, FC> featureSupplier
|
||||
) {
|
||||
super(null, properties);
|
||||
this.feature = featureSupplier;
|
||||
}
|
||||
|
||||
protected BCLFeature getFeature(BlockState state) {
|
||||
return feature.apply(state);
|
||||
@Deprecated(forRemoval = true)
|
||||
public FeatureSaplingBlock(Function<BlockState, org.betterx.bclib.api.v2.levelgen.features.BCLFeature> featureSupplier) {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.collidable(false)
|
||||
.instabreak()
|
||||
.sound(SoundType.GRASS)
|
||||
.randomTicks(),
|
||||
featureSupplier
|
||||
);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public FeatureSaplingBlock(
|
||||
int light,
|
||||
Function<BlockState, org.betterx.bclib.api.v2.levelgen.features.BCLFeature> featureSupplier
|
||||
) {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.collidable(false)
|
||||
.luminance(light)
|
||||
.instabreak()
|
||||
.sound(SoundType.GRASS)
|
||||
.randomTicks(),
|
||||
featureSupplier
|
||||
);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public FeatureSaplingBlock(
|
||||
BlockBehaviour.Properties properties,
|
||||
Function<BlockState, org.betterx.bclib.api.v2.levelgen.features.BCLFeature> featureSupplier
|
||||
) {
|
||||
super(null, properties);
|
||||
this.feature = (s) -> featureSupplier.apply(s).getConfFeature();
|
||||
}
|
||||
|
||||
protected BCLConfigureFeature<F, FC> getConfiguredFeature(BlockState state) {
|
||||
return feature != null ? feature.get(state) : null;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
protected org.betterx.bclib.api.v2.levelgen.features.BCLFeature getFeature(BlockState state) {
|
||||
return new org.betterx.bclib.api.v2.levelgen.features.BCLFeature(new BCLFeature<>(
|
||||
getConfiguredFeature(state),
|
||||
null,
|
||||
GenerationStep.Decoration.TOP_LAYER_MODIFICATION
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,7 +159,9 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
|||
|
||||
@Override
|
||||
public void advanceTree(ServerLevel world, BlockPos pos, BlockState blockState, RandomSource random) {
|
||||
getFeature(blockState).place(world, pos, random);
|
||||
var conf = getConfiguredFeature(blockState);
|
||||
if (conf == null) getFeature(blockState).place(world, pos, random);
|
||||
else conf.placeInWorld(world, pos, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -64,6 +64,7 @@ public abstract class ModIntegration {
|
|||
return FabricLoader.getInstance().isModLoaded(modID);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLFeature getFeature(String featureID, String placedFeatureID, GenerationStep.Decoration featureStep) {
|
||||
ResourceLocation id = getID(featureID);
|
||||
Feature<?> feature = Registry.FEATURE.get(id);
|
||||
|
@ -78,6 +79,7 @@ public abstract class ModIntegration {
|
|||
);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLFeature getFeature(String name, GenerationStep.Decoration featureStep) {
|
||||
return getFeature(name, name, featureStep);
|
||||
}
|
||||
|
|
42
src/main/java/org/betterx/bclib/noise/Noises.java
Normal file
42
src/main/java/org/betterx/bclib/noise/Noises.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package org.betterx.bclib.noise;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Noises {
|
||||
private static final Map<ResourceKey<NormalNoise.NoiseParameters>, NormalNoise> noiseIntances = new HashMap<>();
|
||||
public static final ResourceKey<NormalNoise.NoiseParameters> ROUGHNESS_NOISE = createKey(BCLib.makeID(
|
||||
"roughness_noise"));
|
||||
|
||||
public static ResourceKey<NormalNoise.NoiseParameters> createKey(ResourceLocation loc) {
|
||||
return ResourceKey.create(Registry.NOISE_REGISTRY, loc);
|
||||
}
|
||||
|
||||
public static NormalNoise createNoise(
|
||||
Registry<NormalNoise.NoiseParameters> registry,
|
||||
RandomSource randomSource,
|
||||
ResourceKey<NormalNoise.NoiseParameters> resourceKey
|
||||
) {
|
||||
Holder<NormalNoise.NoiseParameters> holder = registry.getHolderOrThrow(resourceKey);
|
||||
return NormalNoise.create(randomSource, holder.value());
|
||||
}
|
||||
|
||||
public static NormalNoise getOrCreateNoise(
|
||||
RegistryAccess registryAccess,
|
||||
RandomSource randomSource,
|
||||
ResourceKey<NormalNoise.NoiseParameters> noise
|
||||
) {
|
||||
final Registry<NormalNoise.NoiseParameters> registry = registryAccess.registryOrThrow(Registry.NOISE_REGISTRY);
|
||||
return noiseIntances.computeIfAbsent(noise, (key) -> createNoise(registry, randomSource, noise));
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ public class CommonBlockTags {
|
|||
public static final TagKey<Block> END_ORES = TagManager.BLOCKS.makeCommonTag("end_ores");
|
||||
public static final TagKey<Block> SAPLINGS = TagManager.BLOCKS.makeCommonTag("saplings");
|
||||
public static final TagKey<Block> SOUL_GROUND = TagManager.BLOCKS.makeCommonTag("soul_ground");
|
||||
public static final TagKey<Block> SCULK_LIKE = TagManager.BLOCKS.makeCommonTag("sculk_like");
|
||||
public static final TagKey<Block> WOODEN_BARREL = TagManager.BLOCKS.makeCommonTag("wooden_barrels");
|
||||
public static final TagKey<Block> WOODEN_CHEST = TagManager.BLOCKS.makeCommonTag("wooden_chests");
|
||||
public static final TagKey<Block> WORKBENCHES = TagManager.BLOCKS.makeCommonTag("workbench");
|
||||
|
@ -35,6 +36,7 @@ public class CommonBlockTags {
|
|||
public static final TagKey<Block> NETHER_TERRAIN = TagManager.BLOCKS.makeCommonTag("nether_terrain");
|
||||
|
||||
static void prepareTags() {
|
||||
TagManager.BLOCKS.add(SCULK_LIKE, Blocks.SCULK);
|
||||
TagManager.BLOCKS.addOtherTags(DRAGON_IMMUNE, BlockTags.DRAGON_IMMUNE);
|
||||
|
||||
TagManager.BLOCKS.add(END_STONES, Blocks.END_STONE);
|
||||
|
@ -84,8 +86,7 @@ public class CommonBlockTags {
|
|||
Blocks.GRAVEL,
|
||||
Blocks.RED_SAND,
|
||||
Blocks.GLOWSTONE,
|
||||
Blocks.BONE_BLOCK,
|
||||
Blocks.SCULK
|
||||
Blocks.BONE_BLOCK
|
||||
);
|
||||
TagManager.BLOCKS.addOtherTags(
|
||||
NETHER_TERRAIN,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue