Updated all feature based sapling Growing
This commit is contained in:
parent
7285ada6d6
commit
72a707f456
8 changed files with 119 additions and 90 deletions
|
@ -17,6 +17,7 @@ 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.FeatureConfiguration;
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.RandomFeatureConfiguration;
|
import net.minecraft.world.level.levelgen.feature.configurations.RandomFeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.RandomPatchConfiguration;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
||||||
private final Decoration featureStep;
|
private final Decoration featureStep;
|
||||||
private final F feature;
|
private final F feature;
|
||||||
private final FC configuration;
|
private final FC configuration;
|
||||||
|
public final ResourceLocation id;
|
||||||
|
|
||||||
|
|
||||||
public BCLFeature(ResourceLocation id,
|
public BCLFeature(ResourceLocation id,
|
||||||
|
@ -81,6 +83,7 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
||||||
this.featureStep = featureStep;
|
this.featureStep = featureStep;
|
||||||
this.feature = feature;
|
this.feature = feature;
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
|
this.id = id;
|
||||||
|
|
||||||
if (!BuiltinRegistries.PLACED_FEATURE.containsKey(id)) {
|
if (!BuiltinRegistries.PLACED_FEATURE.containsKey(id)) {
|
||||||
Registry.register(BuiltinRegistries.PLACED_FEATURE, id, placedFeature.value());
|
Registry.register(BuiltinRegistries.PLACED_FEATURE, id, placedFeature.value());
|
||||||
|
@ -161,12 +164,22 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean place(ServerLevel level, BlockPos pos, RandomSource random) {
|
public boolean place(ServerLevel level, BlockPos pos, RandomSource random) {
|
||||||
return place(this.getFeature(), level, pos, random);
|
return place(this.getFeature(), this.getConfiguration(), level, pos, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean place(Feature<?> feature, ServerLevel level, BlockPos pos, RandomSource random) {
|
private static boolean placeUnbound(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) {
|
if (feature instanceof UserGrowableFeature growable) {
|
||||||
return growable.grow(level, pos, random);
|
return growable.grow(level, pos, random, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
FeaturePlaceContext context = new FeaturePlaceContext(
|
FeaturePlaceContext context = new FeaturePlaceContext(
|
||||||
|
@ -175,8 +188,23 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
||||||
level.getChunkSource().getGenerator(),
|
level.getChunkSource().getGenerator(),
|
||||||
random,
|
random,
|
||||||
pos,
|
pos,
|
||||||
null
|
config
|
||||||
);
|
);
|
||||||
return feature.place(context);
|
return feature.place(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean place(Feature<NoneFeatureConfiguration> feature,
|
||||||
|
ServerLevel level,
|
||||||
|
BlockPos pos,
|
||||||
|
RandomSource random) {
|
||||||
|
return placeUnbound(feature, FeatureConfiguration.NONE, level, pos, random);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <FC extends FeatureConfiguration> boolean place(Feature<FC> feature,
|
||||||
|
FC config,
|
||||||
|
ServerLevel level,
|
||||||
|
BlockPos pos,
|
||||||
|
RandomSource random) {
|
||||||
|
return placeUnbound(feature, config, level, pos, random);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,11 @@ import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
||||||
public class FastFeatures {
|
public class FastFeatures {
|
||||||
|
|
||||||
|
|
||||||
public static BCLFeature vine(ResourceLocation location,
|
public static BCLFeature<ScatterFeature<ScatterFeatureConfig.OnSolid>, ScatterFeatureConfig.OnSolid> vine(
|
||||||
boolean onFloor,
|
ResourceLocation location,
|
||||||
boolean sparse,
|
boolean onFloor,
|
||||||
ScatterFeatureConfig.Builder builder) {
|
boolean sparse,
|
||||||
|
ScatterFeatureConfig.Builder builder) {
|
||||||
return scatter(location, onFloor, sparse, builder, BCLFeature.SCATTER_ON_SOLID);
|
return scatter(location, onFloor, sparse, builder, BCLFeature.SCATTER_ON_SOLID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ public class FastFeatures {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static <FC extends FeatureConfiguration> BCLFeature
|
public static <FC extends FeatureConfiguration> BCLFeature<Feature<FC>, FC>
|
||||||
simple(ResourceLocation location,
|
simple(ResourceLocation location,
|
||||||
int searchDist,
|
int searchDist,
|
||||||
boolean rare,
|
boolean rare,
|
||||||
|
|
|
@ -2,73 +2,22 @@ package org.betterx.bclib.api.v2.levelgen.features;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
import net.minecraft.core.HolderSet;
|
|
||||||
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.util.valueproviders.ClampedNormalInt;
|
|
||||||
import net.minecraft.util.valueproviders.ConstantInt;
|
|
||||||
import net.minecraft.util.valueproviders.UniformInt;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.SimpleRandomFeatureConfiguration;
|
|
||||||
import net.minecraft.world.level.levelgen.placement.*;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
||||||
import org.betterx.bclib.api.v2.tag.CommonBlockTags;
|
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class ScatterFeature<FC extends ScatterFeatureConfig>
|
public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
extends Feature<FC> {
|
extends Feature<FC> implements UserGrowableFeature<FC> {
|
||||||
|
|
||||||
public static <T extends ScatterFeatureConfig> BCLFeature createAndRegister(ResourceLocation location,
|
|
||||||
int minPerChunk,
|
|
||||||
int maxPerChunk,
|
|
||||||
T cfg,
|
|
||||||
Feature<T> inlineFeature) {
|
|
||||||
List<Holder<PlacedFeature>> set = new ArrayList<>(2);
|
|
||||||
if (cfg.floorChance > 0) set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
|
||||||
cfg,
|
|
||||||
EnvironmentScanPlacement.scanningFor(Direction.DOWN,
|
|
||||||
BlockPredicate.matchesTag(CommonBlockTags.TERRAIN),
|
|
||||||
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
|
||||||
12),
|
|
||||||
RandomOffsetPlacement.vertical(ConstantInt.of(1))));
|
|
||||||
|
|
||||||
if (cfg.floorChance < 1) {
|
|
||||||
set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
|
||||||
cfg,
|
|
||||||
EnvironmentScanPlacement.scanningFor(Direction.UP,
|
|
||||||
BlockPredicate.matchesTag(CommonBlockTags.TERRAIN),
|
|
||||||
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
|
||||||
12),
|
|
||||||
RandomOffsetPlacement.vertical(ConstantInt.of(-1))));
|
|
||||||
}
|
|
||||||
SimpleRandomFeatureConfiguration configuration = new SimpleRandomFeatureConfiguration(HolderSet.direct(set));
|
|
||||||
|
|
||||||
return BCLFeatureBuilder.start(location, SIMPLE_RANDOM_SELECTOR)
|
|
||||||
.decoration(GenerationStep.Decoration.VEGETAL_DECORATION)
|
|
||||||
.modifier(CountPlacement.of(UniformInt.of(minPerChunk, maxPerChunk)))
|
|
||||||
.modifier(InSquarePlacement.spread())
|
|
||||||
.randomHeight4FromFloorCeil()
|
|
||||||
.modifier(CountPlacement.of(UniformInt.of(2, 5)))
|
|
||||||
.modifier(RandomOffsetPlacement.of(
|
|
||||||
ClampedNormalInt.of(0.0f, 2.0f, -6, 6),
|
|
||||||
ClampedNormalInt.of(0.0f, 0.6f, -2, 2)))
|
|
||||||
.onlyInBiome()
|
|
||||||
.buildAndRegister(configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScatterFeature(Codec<FC> configCodec) {
|
public ScatterFeature(Codec<FC> configCodec) {
|
||||||
super(configCodec);
|
super(configCodec);
|
||||||
|
@ -104,7 +53,8 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
if (config.isValidBase(level.getBlockState(basePos))) {
|
if (config.isValidBase(level.getBlockState(basePos))) {
|
||||||
final Direction surfaceDirection = direction.getOpposite();
|
final Direction surfaceDirection = direction.getOpposite();
|
||||||
BlockPos.MutableBlockPos POS = new BlockPos.MutableBlockPos();
|
BlockPos.MutableBlockPos POS = new BlockPos.MutableBlockPos();
|
||||||
buildPillarWithBase(level, origin, basePos, direction, centerHeight, config, random);
|
int adaptedHeight = freeHeight(level, direction, centerHeight, config, origin);
|
||||||
|
buildPillarWithBase(level, origin, basePos, direction, adaptedHeight, config, random, false);
|
||||||
|
|
||||||
final double distNormalizer = (config.maxSpread * Math.sqrt(2));
|
final double distNormalizer = (config.maxSpread * Math.sqrt(2));
|
||||||
final int tryCount = config.spreadCount.sample(random);
|
final int tryCount = config.spreadCount.sample(random);
|
||||||
|
@ -114,7 +64,11 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
POS.set(x, basePos.getY(), z);
|
POS.set(x, basePos.getY(), z);
|
||||||
|
|
||||||
if (BlocksHelper.findSurroundingSurface(level, POS, surfaceDirection, 4, config::isValidBase)) {
|
if (BlocksHelper.findSurroundingSurface(level, POS, surfaceDirection, 4, config::isValidBase)) {
|
||||||
int myHeight = freeHeight(level, direction, centerHeight, config, POS);
|
int myHeight = freeHeight(level,
|
||||||
|
direction,
|
||||||
|
centerHeight,
|
||||||
|
config,
|
||||||
|
POS);
|
||||||
|
|
||||||
int dx = x - POS.getX();
|
int dx = x - POS.getX();
|
||||||
int dz = z - POS.getZ();
|
int dz = z - POS.getZ();
|
||||||
|
@ -135,7 +89,7 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
direction,
|
direction,
|
||||||
myHeight,
|
myHeight,
|
||||||
config,
|
config,
|
||||||
random);
|
random, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,9 +97,9 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
|
|
||||||
private int freeHeight(LevelAccessor level,
|
private int freeHeight(LevelAccessor level,
|
||||||
Direction direction,
|
Direction direction,
|
||||||
int centerHeight,
|
int defaultHeight,
|
||||||
ScatterFeatureConfig config,
|
ScatterFeatureConfig config,
|
||||||
BlockPos.MutableBlockPos POS) {
|
BlockPos POS) {
|
||||||
int myHeight;
|
int myHeight;
|
||||||
if (config.growWhileFree) {
|
if (config.growWhileFree) {
|
||||||
myHeight = BlocksHelper.blockCount(level,
|
myHeight = BlocksHelper.blockCount(level,
|
||||||
|
@ -155,9 +109,9 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
BlocksHelper::isFree
|
BlocksHelper::isFree
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
myHeight = centerHeight;
|
myHeight = defaultHeight;
|
||||||
}
|
}
|
||||||
return myHeight;
|
return Math.max(config.minHeight, myHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildPillarWithBase(LevelAccessor level,
|
private void buildPillarWithBase(LevelAccessor level,
|
||||||
|
@ -166,8 +120,9 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
Direction direction,
|
Direction direction,
|
||||||
int height,
|
int height,
|
||||||
ScatterFeatureConfig config,
|
ScatterFeatureConfig config,
|
||||||
RandomSource random) {
|
RandomSource random,
|
||||||
if (BlocksHelper.isFreeSpace(level, origin, direction, height, BlocksHelper::isFree)) {
|
boolean force) {
|
||||||
|
if (force || BlocksHelper.isFreeSpace(level, origin, direction, height, BlocksHelper::isFree)) {
|
||||||
createPatchOfBaseBlocks(level, random, basePos, config);
|
createPatchOfBaseBlocks(level, random, basePos, config);
|
||||||
BlockState bottom = config.bottomBlock.getState(random, origin);
|
BlockState bottom = config.bottomBlock.getState(random, origin);
|
||||||
if (bottom.canSurvive(level, origin)) {
|
if (bottom.canSurvive(level, origin)) {
|
||||||
|
@ -185,11 +140,7 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
|
|
||||||
final BlockPos.MutableBlockPos POS = origin.mutable();
|
final BlockPos.MutableBlockPos POS = origin.mutable();
|
||||||
for (int size = 0; size < height; size++) {
|
for (int size = 0; size < height; size++) {
|
||||||
BlockState previous = level.getBlockState(POS);
|
|
||||||
BlockState state = config.createBlock(size, height - 1, random, POS);
|
BlockState state = config.createBlock(size, height - 1, random, POS);
|
||||||
if (!BlocksHelper.isFree(previous)) {
|
|
||||||
System.out.println("Replaced " + previous + " with " + state + " at " + POS);
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithoutUpdate(level, POS, state);
|
BlocksHelper.setWithoutUpdate(level, POS, state);
|
||||||
POS.move(direction);
|
POS.move(direction);
|
||||||
}
|
}
|
||||||
|
@ -246,4 +197,29 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
levelAccessor.setBlock(blockPos, baseState, 2);
|
levelAccessor.setBlock(blockPos, baseState, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean grow(ServerLevelAccessor level,
|
||||||
|
BlockPos origin,
|
||||||
|
RandomSource random,
|
||||||
|
FC config) {
|
||||||
|
Optional<Direction> oDirection = getTipDirection(level, origin, random, config);
|
||||||
|
if (oDirection.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Direction direction = oDirection.get();
|
||||||
|
BlockPos basePos = origin.relative(direction, -1);
|
||||||
|
|
||||||
|
if (config.isValidBase(level.getBlockState(basePos))) {
|
||||||
|
int centerHeight = (int) (random.nextFloat() * (1 + config.maxHeight - config.minHeight) + config.minHeight);
|
||||||
|
centerHeight = freeHeight(level,
|
||||||
|
direction,
|
||||||
|
centerHeight,
|
||||||
|
config,
|
||||||
|
origin.relative(direction, 1)) + 1;
|
||||||
|
buildPillarWithBase(level, origin, basePos, direction, centerHeight, config, random, true);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@ package org.betterx.bclib.api.v2.levelgen.features;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.level.ServerLevelAccessor;
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
|
||||||
public interface UserGrowableFeature {
|
public interface UserGrowableFeature<FC extends FeatureConfiguration> {
|
||||||
boolean grow(ServerLevelAccessor level,
|
boolean grow(ServerLevelAccessor level,
|
||||||
BlockPos pos,
|
BlockPos pos,
|
||||||
RandomSource random);
|
RandomSource random,
|
||||||
|
FC configuration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,6 +223,17 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder<T> tripleShapeCeil(Block s) {
|
||||||
|
return tripleShapeCeil(s.defaultBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> tripleShapeCeil(BlockState s) {
|
||||||
|
block(s.setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.MIDDLE));
|
||||||
|
tipBlock(s.setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.BOTTOM));
|
||||||
|
bottomBlock(s.setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.TOP));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder<T> block(BlockStateProvider s) {
|
public Builder<T> block(BlockStateProvider s) {
|
||||||
this.clusterBlock = s;
|
this.clusterBlock = s;
|
||||||
if (tipBlock == null) tipBlock = s;
|
if (tipBlock == null) tipBlock = s;
|
||||||
|
@ -297,6 +308,11 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder<T> noSpread() {
|
||||||
|
return spread(0, 0, ConstantInt.of(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Builder<T> spread(float maxSpread, float sizeVariation) {
|
public Builder<T> spread(float maxSpread, float sizeVariation) {
|
||||||
return spread(maxSpread, sizeVariation, ConstantInt.of((int) Math.min(16, 4 * maxSpread * maxSpread)));
|
return spread(maxSpread, sizeVariation, ConstantInt.of((int) Math.min(16, 4 * maxSpread * maxSpread)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,25 +6,27 @@ import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public abstract class FeatureHangingSaplingBlock extends FeatureSaplingBlock {
|
public abstract class FeatureHangingSaplingBlock extends FeatureSaplingBlock {
|
||||||
private static final VoxelShape SHAPE = Block.box(4, 2, 4, 12, 16, 12);
|
private static final VoxelShape SHAPE = Block.box(4, 2, 4, 12, 16, 12);
|
||||||
|
|
||||||
public FeatureHangingSaplingBlock(Function<BlockState, Feature<?>> featureSupplier) {
|
public FeatureHangingSaplingBlock(Function<BlockState, BCLFeature> featureSupplier) {
|
||||||
super(featureSupplier);
|
super(featureSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureHangingSaplingBlock(Function<BlockState, Feature<?>> featureSupplier, int light) {
|
public FeatureHangingSaplingBlock(Function<BlockState, BCLFeature> featureSupplier,
|
||||||
|
int light) {
|
||||||
super(light, featureSupplier);
|
super(light, featureSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureHangingSaplingBlock(BlockBehaviour.Properties properties,
|
public FeatureHangingSaplingBlock(BlockBehaviour.Properties properties,
|
||||||
Function<BlockState, Feature<?>> featureSupplier) {
|
Function<BlockState, BCLFeature> featureSupplier) {
|
||||||
super(properties, featureSupplier);
|
super(properties, featureSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ import net.minecraft.world.level.block.SaplingBlock;
|
||||||
import net.minecraft.world.level.block.SoundType;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.level.material.Material;
|
import net.minecraft.world.level.material.Material;
|
||||||
import net.minecraft.world.level.storage.loot.LootContext;
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
@ -42,9 +41,9 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProvider, BlockModelProvider {
|
public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProvider, BlockModelProvider {
|
||||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||||
private final Function<BlockState, Feature<?>> feature;
|
private final Function<BlockState, BCLFeature> feature;
|
||||||
|
|
||||||
public FeatureSaplingBlock(Function<BlockState, Feature<?>> featureSupplier) {
|
public FeatureSaplingBlock(Function<BlockState, BCLFeature> featureSupplier) {
|
||||||
this(FabricBlockSettings.of(Material.PLANT)
|
this(FabricBlockSettings.of(Material.PLANT)
|
||||||
.collidable(false)
|
.collidable(false)
|
||||||
.instabreak()
|
.instabreak()
|
||||||
|
@ -54,7 +53,7 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureSaplingBlock(int light, Function<BlockState, Feature<?>> featureSupplier) {
|
public FeatureSaplingBlock(int light, Function<BlockState, BCLFeature> featureSupplier) {
|
||||||
this(FabricBlockSettings.of(Material.PLANT)
|
this(FabricBlockSettings.of(Material.PLANT)
|
||||||
.collidable(false)
|
.collidable(false)
|
||||||
.luminance(light)
|
.luminance(light)
|
||||||
|
@ -65,12 +64,13 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureSaplingBlock(BlockBehaviour.Properties properties, Function<BlockState, Feature<?>> featureSupplier) {
|
public FeatureSaplingBlock(BlockBehaviour.Properties properties,
|
||||||
|
Function<BlockState, BCLFeature> featureSupplier) {
|
||||||
super(null, properties);
|
super(null, properties);
|
||||||
this.feature = featureSupplier;
|
this.feature = featureSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Feature<?> getFeature(BlockState state) {
|
protected BCLFeature getFeature(BlockState state) {
|
||||||
return feature.apply(state);
|
return feature.apply(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void advanceTree(ServerLevel world, BlockPos pos, BlockState blockState, RandomSource random) {
|
public void advanceTree(ServerLevel world, BlockPos pos, BlockState blockState, RandomSource random) {
|
||||||
BCLFeature.place(getFeature(blockState), world, pos, random);
|
getFeature(blockState).place(world, pos, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -332,6 +332,10 @@ public class BlocksHelper {
|
||||||
return state.isAir();
|
return state.isAir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isFreeOrReplaceable(BlockState state) {
|
||||||
|
return state.isAir() || state.getMaterial().isReplaceable();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isFreeOrFluid(BlockState state) {
|
public static boolean isFreeOrFluid(BlockState state) {
|
||||||
return state.isAir() || isFluid(state);
|
return state.isAir() || isFluid(state);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue