Features for Crimson Glowing Woods
This commit is contained in:
parent
4f4ac722b1
commit
90921451dd
5 changed files with 47 additions and 14 deletions
|
@ -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"),
|
||||
|
|
|
@ -26,14 +26,13 @@ public class WeightedRandomSelectorFeature extends Feature<RandomFeatureConfigur
|
|||
if (!cfg.features.isEmpty()) {
|
||||
final float totalWeight = cfg.features.stream().map(w -> w.chance).reduce(0.0f, (p, c) -> p + c);
|
||||
float bar = random.nextFloat() * totalWeight;
|
||||
|
||||
|
||||
for (WeightedPlacedFeature f : cfg.features) {
|
||||
selected = f.feature.value();
|
||||
bar -= f.chance;
|
||||
if (bar < 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
return selected.place(level, generator, random, pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue