Features for Crimson Glowing Woods

This commit is contained in:
Frank 2022-06-04 14:05:02 +02:00
parent 4f4ac722b1
commit 90921451dd
5 changed files with 47 additions and 14 deletions

View file

@ -27,7 +27,7 @@ public class BCLFeature {
BCLib.makeID("scatter_on_solid"),
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC));
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECT = register(
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = register(
BCLib.makeID("random_select"),
new WeightedRandomSelectorFeature());
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(BCLib.makeID("template"),

View file

@ -33,7 +33,6 @@ public class WeightedRandomSelectorFeature extends Feature<RandomFeatureConfigur
if (bar < 0) break;
}
}
return selected.place(level, generator, random, pos);
}
}

View file

@ -1,6 +1,8 @@
package org.betterx.bclib.api.features.placement;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
@ -11,29 +13,40 @@ import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.Optional;
public class Is extends PlacementFilter {
public static final Codec<Is> CODEC = RecordCodecBuilder.create((instance) -> instance
.group(
BlockPredicate.CODEC
.fieldOf("predicate")
.forGetter(cfg -> cfg.predicate)
.forGetter(cfg -> cfg.predicate),
Vec3i.CODEC
.optionalFieldOf("offset")
.forGetter(cfg -> cfg.offset)
)
.apply(instance, Is::new));
private final BlockPredicate predicate;
private final Optional<Vec3i> offset;
public Is(BlockPredicate predicate) {
public Is(BlockPredicate predicate, Optional<Vec3i> offset) {
this.predicate = predicate;
this.offset = offset;
}
public static Is simple(BlockPredicate predicate) {
return new Is(predicate);
return new Is(predicate, Optional.empty());
}
public static Is below(BlockPredicate predicate) {
return new Is(predicate, Optional.of(Direction.DOWN.getNormal()));
}
@Override
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
WorldGenLevel level = ctx.getLevel();
return predicate.test(level, pos);
return predicate.test(level, offset.map(v -> pos.offset(v.getX(), v.getY(), v.getZ())).orElse(pos));
}
@Override

View file

@ -10,24 +10,40 @@ import net.minecraft.world.level.levelgen.placement.PlacementModifier;
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import org.betterx.bclib.util.BlocksHelper;
import java.util.Optional;
import java.util.stream.Stream;
public class OnEveryLayer
extends PlacementModifier {
private static OnEveryLayer INSTANCE = new OnEveryLayer();
public static final Codec<OnEveryLayer> CODEC = Codec.unit(() -> INSTANCE);
private static OnEveryLayer INSTANCE = new OnEveryLayer(Optional.empty(), Optional.empty());
private static OnEveryLayer INSTANCE_MIN_4 = new OnEveryLayer(Optional.of(4), Optional.empty());
public static final Codec<OnEveryLayer> CODEC = RecordCodecBuilder.create(instance -> instance
.group(
Codec.INT.optionalFieldOf("min").forGetter(o -> o.minHeight),
Codec.INT.optionalFieldOf("max").forGetter(o -> o.maxHeight)
).apply(instance, OnEveryLayer::new));
private OnEveryLayer() {
private final Optional<Integer> minHeight;
private final Optional<Integer> maxHeight;
private OnEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
this.minHeight = minHeight;
this.maxHeight = maxHeight;
}
public static OnEveryLayer simple() {
return INSTANCE;
}
public static OnEveryLayer min4() {
return INSTANCE_MIN_4;
}
@Override
public Stream<BlockPos> getPositions(PlacementContext ctx,
RandomSource random,
@ -37,10 +53,14 @@ public class OnEveryLayer
final int z = pos.getZ();
final int x = pos.getX();
int y = ctx.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z);
final int levelHeight = ctx.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z);
final int minLevelHeight = ctx.getMinBuildHeight();
int y = maxHeight.map(h -> Math.min(levelHeight, h)).orElse(levelHeight);
final int minHeight = this.minHeight.map(h -> Math.max(minLevelHeight, h)).orElse(minLevelHeight);
int layerY;
do {
layerY = OnEveryLayer.findOnGroundYPosition(ctx, x, y, z);
layerY = OnEveryLayer.findOnGroundYPosition(ctx, x, y, z, minHeight);
if (layerY != Integer.MAX_VALUE) {
builder.add(new BlockPos(x, layerY, z));
y = layerY - 1;
@ -55,10 +75,10 @@ public class OnEveryLayer
return PlacementModifiers.ON_EVERY_LAYER;
}
private static int findOnGroundYPosition(PlacementContext ctx, int x, int startY, int z) {
private static int findOnGroundYPosition(PlacementContext ctx, int x, int startY, int z, int minHeight) {
BlockPos.MutableBlockPos mPos = new BlockPos.MutableBlockPos(x, startY, z);
BlockState nowState = ctx.getBlockState(mPos);
for (int y = startY; y >= ctx.getMinBuildHeight() + 1; --y) {
for (int y = startY; y >= minHeight + 1; --y) {
mPos.setY(y - 1);
BlockState belowState = ctx.getBlockState(mPos);
if (BlocksHelper.isTerrain(belowState) && BlocksHelper.isFreeOrFluid(nowState) && !belowState.is(Blocks.BEDROCK)) {

View file

@ -58,6 +58,7 @@ public class CommonBlockTags {
TagAPI.BLOCKS.addOtherTags(TERRAIN,
BlockTags.DRIPSTONE_REPLACEABLE,
BlockTags.BASE_STONE_OVERWORLD,
BlockTags.NYLIUM,
NETHER_STONES,
NETHER_ORES,
SOUL_GROUND,