New Configurations for PillarFeature
This commit is contained in:
parent
cb5852b841
commit
f007bcfa31
3 changed files with 101 additions and 16 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue