More Feature Refactoring

This commit is contained in:
Frank 2022-06-28 23:19:03 +02:00
parent c1d5ca7b9b
commit 5d85595c5a
19 changed files with 621 additions and 128 deletions

View file

@ -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) ||

View file

@ -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.

View file

@ -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) {

View file

@ -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);

View file

@ -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()

View file

@ -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

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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),

View file

@ -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);

View file

@ -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
*

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View 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));
}
}

View file

@ -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,