UpsideDownForest
This commit is contained in:
parent
56e63f3ce2
commit
2ac472f716
8 changed files with 252 additions and 20 deletions
|
@ -747,6 +747,11 @@ public class BiomeAPI {
|
|||
|
||||
public static void applyModifications(BiomeSource source, ResourceKey<LevelStem> dimension) {
|
||||
BCLib.LOGGER.info("Apply Modifications for " + dimension.location() + " BiomeSource " + source);
|
||||
/*if (dimension.location().equals(LevelStem.NETHER)){
|
||||
if (source instanceof BCLBiomeSource s) {
|
||||
NetherBiomes.useLegacyGeneration = s.biomeSourceVersion==BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE;
|
||||
}
|
||||
}*/
|
||||
final Set<Holder<Biome>> biomes = source.possibleBiomes();
|
||||
List<BiConsumer<ResourceLocation, Holder<Biome>>> modifications = MODIFICATIONS.get(dimension);
|
||||
for (Holder<Biome> biomeHolder : biomes) {
|
||||
|
|
|
@ -30,6 +30,14 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
|||
BCLib.makeID("scatter_on_solid"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC));
|
||||
|
||||
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = register(
|
||||
BCLib.makeID("scatter_extend_top"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendTop.CODEC));
|
||||
|
||||
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = register(
|
||||
BCLib.makeID("scatter_extend_bottom"),
|
||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendBottom.CODEC));
|
||||
|
||||
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = register(
|
||||
BCLib.makeID("random_select"),
|
||||
new WeightedRandomSelectorFeature());
|
||||
|
|
|
@ -245,6 +245,10 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
|||
return modifier(OnEveryLayer.simple());
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder underEveryLayer() {
|
||||
return modifier(UnderEveryLayer.simple());
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder spreadHorizontal(IntProvider p) {
|
||||
return modifier(RandomOffsetPlacement.horizontal(p));
|
||||
}
|
||||
|
@ -300,6 +304,10 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
|||
return modifier(new Is(BlockPredicate.anyOf(predicates), Optional.of(Direction.DOWN.getNormal())));
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder isUnder(BlockPredicate... predicates) {
|
||||
return modifier(new Is(BlockPredicate.anyOf(predicates), Optional.of(Direction.UP.getNormal())));
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder findSolidCeil(int distance) {
|
||||
return modifier(FindSolidInDirection.up(distance));
|
||||
}
|
||||
|
|
|
@ -145,6 +145,7 @@ public class FastFeatures {
|
|||
)));
|
||||
}
|
||||
|
||||
|
||||
public static <FC extends FeatureConfiguration> BCLFeature
|
||||
simple(ResourceLocation location,
|
||||
int searchDist,
|
||||
|
@ -166,6 +167,7 @@ public class FastFeatures {
|
|||
return patch(location, 96, 7, 3, feature, FeatureConfiguration.NONE);
|
||||
}
|
||||
|
||||
|
||||
public static BCLFeature
|
||||
patch(ResourceLocation location,
|
||||
int attempts,
|
||||
|
@ -175,6 +177,7 @@ public class FastFeatures {
|
|||
return patch(location, attempts, xzSpread, ySpread, feature, FeatureConfiguration.NONE);
|
||||
}
|
||||
|
||||
|
||||
public static <FC extends FeatureConfiguration> BCLFeature
|
||||
patch(ResourceLocation location,
|
||||
int attempts,
|
||||
|
@ -209,4 +212,6 @@ public class FastFeatures {
|
|||
.start(patchLocation, Feature.RANDOM_PATCH)
|
||||
.buildAndRegister(new RandomPatchConfiguration(attempts, xzSpread, ySpread, single.getPlacedFeature()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -344,10 +344,14 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
public static Builder<OnSolid> startOnSolid() {
|
||||
return Builder.start(OnSolid::new);
|
||||
}
|
||||
|
||||
public static class OnSolid extends ScatterFeatureConfig {
|
||||
public static final Codec<OnSolid> CODEC = buildCodec(OnSolid::new);
|
||||
|
||||
public OnSolid(BlockStateProvider clusterBlock,
|
||||
protected OnSolid(BlockStateProvider clusterBlock,
|
||||
Optional<BlockStateProvider> tipBlock,
|
||||
Optional<BlockStateProvider> bottomBlock,
|
||||
Optional<BlockState> baseState,
|
||||
|
@ -380,11 +384,6 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
|||
}
|
||||
|
||||
|
||||
public static Builder<OnSolid> startOnSolid() {
|
||||
return Builder.start(OnSolid::new);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isValidBase(BlockState state) {
|
||||
return BlocksHelper.isTerrain(state)
|
||||
|
@ -400,4 +399,113 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static Builder<ExtendTop> startExtendTop() {
|
||||
return Builder.start(ExtendTop::new);
|
||||
}
|
||||
|
||||
public static class ExtendTop extends ScatterFeatureConfig {
|
||||
public static final Codec<ExtendTop> CODEC = buildCodec(ExtendTop::new);
|
||||
|
||||
protected ExtendTop(BlockStateProvider clusterBlock,
|
||||
Optional<BlockStateProvider> tipBlock,
|
||||
Optional<BlockStateProvider> bottomBlock,
|
||||
Optional<BlockState> baseState,
|
||||
float baseReplaceChance,
|
||||
float chanceOfDirectionalSpread,
|
||||
float chanceOfSpreadRadius2,
|
||||
float chanceOfSpreadRadius3,
|
||||
int minHeight,
|
||||
int maxHeight,
|
||||
float maxSpread,
|
||||
float sizeVariation,
|
||||
float floorChance,
|
||||
boolean growWhileFree,
|
||||
IntProvider spreadCount) {
|
||||
super(clusterBlock,
|
||||
tipBlock,
|
||||
bottomBlock,
|
||||
baseState,
|
||||
baseReplaceChance,
|
||||
chanceOfDirectionalSpread,
|
||||
chanceOfSpreadRadius2,
|
||||
chanceOfSpreadRadius3,
|
||||
minHeight,
|
||||
maxHeight,
|
||||
maxSpread,
|
||||
sizeVariation,
|
||||
floorChance,
|
||||
growWhileFree,
|
||||
spreadCount);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isValidBase(BlockState state) {
|
||||
return BlocksHelper.isTerrain(state)
|
||||
|| baseState.map(s -> state.is(s.getBlock())).orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState createBlock(int height, int maxHeight, RandomSource random, BlockPos pos) {
|
||||
if (height == 0) return this.bottomBlock.getState(random, pos);
|
||||
if (height == 1) return this.clusterBlock.getState(random, pos);
|
||||
return this.tipBlock.getState(random, pos);
|
||||
}
|
||||
}
|
||||
|
||||
public static Builder<ExtendBottom> startExtendBottom() {
|
||||
return Builder.start(ExtendBottom::new);
|
||||
}
|
||||
|
||||
public static class ExtendBottom extends ScatterFeatureConfig {
|
||||
public static final Codec<ExtendBottom> CODEC = buildCodec(ExtendBottom::new);
|
||||
|
||||
protected ExtendBottom(BlockStateProvider clusterBlock,
|
||||
Optional<BlockStateProvider> tipBlock,
|
||||
Optional<BlockStateProvider> bottomBlock,
|
||||
Optional<BlockState> baseState,
|
||||
float baseReplaceChance,
|
||||
float chanceOfDirectionalSpread,
|
||||
float chanceOfSpreadRadius2,
|
||||
float chanceOfSpreadRadius3,
|
||||
int minHeight,
|
||||
int maxHeight,
|
||||
float maxSpread,
|
||||
float sizeVariation,
|
||||
float floorChance,
|
||||
boolean growWhileFree,
|
||||
IntProvider spreadCount) {
|
||||
super(clusterBlock,
|
||||
tipBlock,
|
||||
bottomBlock,
|
||||
baseState,
|
||||
baseReplaceChance,
|
||||
chanceOfDirectionalSpread,
|
||||
chanceOfSpreadRadius2,
|
||||
chanceOfSpreadRadius3,
|
||||
minHeight,
|
||||
maxHeight,
|
||||
maxSpread,
|
||||
sizeVariation,
|
||||
floorChance,
|
||||
growWhileFree,
|
||||
spreadCount);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isValidBase(BlockState state) {
|
||||
return BlocksHelper.isTerrain(state)
|
||||
|| baseState.map(s -> state.is(s.getBlock())).orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState createBlock(int height, int maxHeight, RandomSource random, BlockPos pos) {
|
||||
if (height == maxHeight) return this.tipBlock.getState(random, pos);
|
||||
if (height == maxHeight - 1) return this.clusterBlock.getState(random, pos);
|
||||
return this.bottomBlock.getState(random, pos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,6 +49,10 @@ public class PlacementModifiers {
|
|||
"on_every_layer",
|
||||
OnEveryLayer.CODEC);
|
||||
|
||||
public static final PlacementModifierType<UnderEveryLayer> UNDER_EVERY_LAYER = register(
|
||||
"under_every_layer",
|
||||
UnderEveryLayer.CODEC);
|
||||
|
||||
|
||||
private static <P extends PlacementModifier> PlacementModifierType<P> register(String path, Codec<P> codec) {
|
||||
return register(BCLib.makeID(path), codec);
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package org.betterx.bclib.api.features.placement;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||
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 UnderEveryLayer
|
||||
extends PlacementModifier {
|
||||
private static UnderEveryLayer INSTANCE = new UnderEveryLayer(Optional.empty(), Optional.empty());
|
||||
private static UnderEveryLayer INSTANCE_MIN_4 = new UnderEveryLayer(Optional.of(4), Optional.empty());
|
||||
public static final Codec<UnderEveryLayer> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
Codec.INT.optionalFieldOf("min").forGetter(o -> o.minHeight),
|
||||
Codec.INT.optionalFieldOf("max").forGetter(o -> o.maxHeight)
|
||||
).apply(instance, UnderEveryLayer::new));
|
||||
|
||||
|
||||
private final Optional<Integer> minHeight;
|
||||
private final Optional<Integer> maxHeight;
|
||||
|
||||
private UnderEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
|
||||
this.minHeight = minHeight;
|
||||
|
||||
this.maxHeight = maxHeight;
|
||||
}
|
||||
|
||||
public static UnderEveryLayer simple() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static UnderEveryLayer min4() {
|
||||
return INSTANCE_MIN_4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<BlockPos> getPositions(PlacementContext ctx,
|
||||
RandomSource random,
|
||||
BlockPos pos) {
|
||||
|
||||
Stream.Builder<BlockPos> builder = Stream.builder();
|
||||
|
||||
final int z = pos.getZ();
|
||||
final int x = pos.getX();
|
||||
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 = findUnderGroundYPosition(ctx, x, y, z, minHeight);
|
||||
if (layerY != Integer.MAX_VALUE) {
|
||||
builder.add(new BlockPos(x, layerY, z));
|
||||
y = layerY - 1;
|
||||
}
|
||||
|
||||
} while (layerY != Integer.MAX_VALUE);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementModifierType<UnderEveryLayer> type() {
|
||||
return PlacementModifiers.UNDER_EVERY_LAYER;
|
||||
}
|
||||
|
||||
private static int findUnderGroundYPosition(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 >= minHeight + 1; --y) {
|
||||
mPos.setY(y - 1);
|
||||
BlockState belowState = ctx.getBlockState(mPos);
|
||||
if (BlocksHelper.isTerrain(nowState) && BlocksHelper.isFreeOrFluid(belowState) && !nowState.is(Blocks.BEDROCK)) {
|
||||
return mPos.getY();
|
||||
}
|
||||
nowState = belowState;
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
|
@ -40,5 +40,8 @@ public class NamedBlockTags {
|
|||
|
||||
static {
|
||||
TagAPI.BLOCKS.add(BlockTags.NETHER_CARVER_REPLACEABLES, Blocks.RED_SAND, Blocks.MAGMA_BLOCK);
|
||||
TagAPI.BLOCKS.addOtherTags(BlockTags.NETHER_CARVER_REPLACEABLES,
|
||||
CommonBlockTags.NETHER_STONES,
|
||||
CommonBlockTags.NETHERRACK);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue