New Configurations for PillarFeature

This commit is contained in:
Frank 2022-06-25 11:49:49 +02:00
parent cb5852b841
commit f007bcfa31
3 changed files with 101 additions and 16 deletions

View file

@ -9,6 +9,7 @@ import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource;
import net.minecraft.util.StringRepresentable;
import net.minecraft.util.valueproviders.IntProvider;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
@ -20,6 +21,20 @@ public class PillarFeatureConfig implements FeatureConfiguration {
BlockState apply(int height, int maxHeight, BlockState inputState, BlockPos pos, RandomSource rnd);
}
@FunctionalInterface
public interface PlacePredicate {
PlacePredicate ALLWAYS = (min, max, start, above, level, allow, rnd) -> true;
boolean at(
int minHeight,
int maxHeight,
BlockPos startPos,
BlockPos abovePos,
WorldGenLevel level,
BlockPredicate allowedPlacement,
RandomSource rnd
);
}
public enum KnownTransformers implements StringRepresentable {
SIZE_DECREASE(
"size_decrease",
@ -35,6 +50,17 @@ public class PillarFeatureConfig implements FeatureConfiguration {
"bottom_grow",
(height, maxHeight, state, pos, rnd) -> state
.setValue(BlockProperties.BOTTOM, height == maxHeight)
),
TRIPLE_SHAPE_FILL(
"triple_shape_fill",
(height, maxHeight, state, pos, rnd) -> {
if (height == 0)
return state.setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.BOTTOM);
if (height == maxHeight)
return state.setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.TOP);
return state.setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.MIDDLE);
},
(minHeight, maxHeight, startPos, abovePos, level, allow, rnd) -> !allow.test(level, abovePos)
);
@ -44,10 +70,16 @@ public class PillarFeatureConfig implements FeatureConfiguration {
public final String name;
public final StateTransform stateTransform;
public final PlacePredicate canPlace;
KnownTransformers(String name, StateTransform stateTransform) {
this(name, stateTransform, PlacePredicate.ALLWAYS);
}
KnownTransformers(String name, StateTransform stateTransform, PlacePredicate canPlace) {
this.name = name;
this.stateTransform = stateTransform;
this.canPlace = canPlace;
}
@Override
@ -63,7 +95,8 @@ public class PillarFeatureConfig implements FeatureConfiguration {
public static final Codec<PillarFeatureConfig> CODEC = RecordCodecBuilder.create(instance -> instance
.group(
IntProvider.CODEC.fieldOf("height").forGetter(o -> o.height),
IntProvider.CODEC.fieldOf("min_height").forGetter(o -> o.minHeight),
IntProvider.CODEC.fieldOf("max_height").forGetter(o -> o.maxHeight),
Direction.CODEC.fieldOf("direction").orElse(Direction.UP).forGetter(o -> o.direction),
BlockPredicate.CODEC.fieldOf("allowed_placement").forGetter(o -> o.allowedPlacement),
BlockStateProvider.CODEC.fieldOf("state").forGetter(o -> o.stateProvider),
@ -71,7 +104,8 @@ public class PillarFeatureConfig implements FeatureConfiguration {
)
.apply(instance, PillarFeatureConfig::new));
public final IntProvider height;
public final IntProvider maxHeight;
public final IntProvider minHeight;
public final BlockStateProvider stateProvider;
public final KnownTransformers transformer;
@ -80,13 +114,15 @@ public class PillarFeatureConfig implements FeatureConfiguration {
public PillarFeatureConfig(
IntProvider height,
IntProvider minHeight,
IntProvider maxHeight,
Direction direction,
BlockPredicate allowedPlacement,
BlockStateProvider stateProvider,
KnownTransformers transformer
) {
this.height = height;
this.minHeight = minHeight;
this.maxHeight = maxHeight;
this.stateProvider = stateProvider;
this.transformer = transformer;
this.direction = direction;

View file

@ -22,22 +22,33 @@ public class PillarFeature extends Feature<PillarFeatureConfig> {
final WorldGenLevel level = featurePlaceContext.level();
final PillarFeatureConfig config = featurePlaceContext.config();
final RandomSource rnd = featurePlaceContext.random();
int maxHeight = config.height.sample(rnd);
int maxHeight = config.maxHeight.sample(rnd);
int minHeight = config.minHeight.sample(rnd);
BlockPos.MutableBlockPos posnow = featurePlaceContext.origin().mutable();
for (height = 0; height < maxHeight; ++height) {
if (!config.allowedPlacement.test(level, posnow)) {
maxHeight = height - 1;
maxHeight = height;
break;
}
posnow.move(config.direction);
}
if (maxHeight < 0) return false;
if (maxHeight < minHeight) return false;
if (!config.transformer.canPlace.at(
minHeight,
maxHeight,
featurePlaceContext.origin(),
posnow,
level,
config.allowedPlacement,
rnd
)) {
return false;
}
posnow = featurePlaceContext.origin().mutable();
for (height = 0; height < maxHeight; ++height) {
BlockState state = config.transform(height, maxHeight, posnow, rnd);
BlockState state = config.transform(height, maxHeight - 1, posnow, rnd);
BlocksHelper.setWithoutUpdate(level, posnow, state);
posnow.move(config.direction);
}

View file

@ -272,7 +272,8 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
}
public static class AsPillar extends BCLFeatureBuilder<PillarFeature, PillarFeatureConfig> {
private IntProvider height;
private IntProvider maxHeight;
private IntProvider minHeight;
private BlockStateProvider stateProvider;
private final PillarFeatureConfig.KnownTransformers transformer;
@ -311,13 +312,23 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
return this;
}
public AsPillar height(int v) {
this.height = ConstantInt.of(v);
public AsPillar maxHeight(int v) {
this.maxHeight = ConstantInt.of(v);
return this;
}
public AsPillar height(IntProvider v) {
this.height = v;
public AsPillar maxHeight(IntProvider v) {
this.maxHeight = v;
return this;
}
public AsPillar minHeight(int v) {
this.minHeight = ConstantInt.of(v);
return this;
}
public AsPillar minHeight(IntProvider v) {
this.minHeight = v;
return this;
}
@ -327,10 +338,18 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
if (stateProvider == null) {
throw new IllegalStateException("A Pillar Features need a stateProvider");
}
if (height == null) {
if (maxHeight == null) {
throw new IllegalStateException("A Pillar Features need a height");
}
return new PillarFeatureConfig(height, direction, allowedPlacement, stateProvider, transformer);
if (minHeight == null) minHeight = ConstantInt.of(0);
return new PillarFeatureConfig(
minHeight,
maxHeight,
direction,
allowedPlacement,
stateProvider,
transformer
);
}
}
@ -379,6 +398,25 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
return add(ConstantInt.of(height), state);
}
protected static SimpleWeightedRandomList<BlockState> buildWeightedList(BlockState state) {
return SimpleWeightedRandomList
.<BlockState>builder()
.add(state, 1)
.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);
return add(height, new WeightedStateProvider(builder.build()));
}
public AsBlockColumn<FF> add(IntProvider height, Block block) {
return add(height, BlockStateProvider.simple(block));
}