UpsideDownForest

This commit is contained in:
Frank 2022-06-07 02:39:12 +02:00
parent 56e63f3ce2
commit 2ac472f716
8 changed files with 252 additions and 20 deletions

View file

@ -747,6 +747,11 @@ public class BiomeAPI {
public static void applyModifications(BiomeSource source, ResourceKey<LevelStem> dimension) { public static void applyModifications(BiomeSource source, ResourceKey<LevelStem> dimension) {
BCLib.LOGGER.info("Apply Modifications for " + dimension.location() + " BiomeSource " + source); 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(); final Set<Holder<Biome>> biomes = source.possibleBiomes();
List<BiConsumer<ResourceLocation, Holder<Biome>>> modifications = MODIFICATIONS.get(dimension); List<BiConsumer<ResourceLocation, Holder<Biome>>> modifications = MODIFICATIONS.get(dimension);
for (Holder<Biome> biomeHolder : biomes) { for (Holder<Biome> biomeHolder : biomes) {

View file

@ -30,6 +30,14 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
BCLib.makeID("scatter_on_solid"), BCLib.makeID("scatter_on_solid"),
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)); 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( public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = register(
BCLib.makeID("random_select"), BCLib.makeID("random_select"),
new WeightedRandomSelectorFeature()); new WeightedRandomSelectorFeature());

View file

@ -245,6 +245,10 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
return modifier(OnEveryLayer.simple()); return modifier(OnEveryLayer.simple());
} }
public BCLFeatureBuilder underEveryLayer() {
return modifier(UnderEveryLayer.simple());
}
public BCLFeatureBuilder spreadHorizontal(IntProvider p) { public BCLFeatureBuilder spreadHorizontal(IntProvider p) {
return modifier(RandomOffsetPlacement.horizontal(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()))); 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) { public BCLFeatureBuilder findSolidCeil(int distance) {
return modifier(FindSolidInDirection.up(distance)); return modifier(FindSolidInDirection.up(distance));
} }

View file

@ -145,6 +145,7 @@ public class FastFeatures {
))); )));
} }
public static <FC extends FeatureConfiguration> BCLFeature public static <FC extends FeatureConfiguration> BCLFeature
simple(ResourceLocation location, simple(ResourceLocation location,
int searchDist, int searchDist,
@ -166,6 +167,7 @@ public class FastFeatures {
return patch(location, 96, 7, 3, feature, FeatureConfiguration.NONE); return patch(location, 96, 7, 3, feature, FeatureConfiguration.NONE);
} }
public static BCLFeature public static BCLFeature
patch(ResourceLocation location, patch(ResourceLocation location,
int attempts, int attempts,
@ -175,6 +177,7 @@ public class FastFeatures {
return patch(location, attempts, xzSpread, ySpread, feature, FeatureConfiguration.NONE); return patch(location, attempts, xzSpread, ySpread, feature, FeatureConfiguration.NONE);
} }
public static <FC extends FeatureConfiguration> BCLFeature public static <FC extends FeatureConfiguration> BCLFeature
patch(ResourceLocation location, patch(ResourceLocation location,
int attempts, int attempts,
@ -209,4 +212,6 @@ public class FastFeatures {
.start(patchLocation, Feature.RANDOM_PATCH) .start(patchLocation, Feature.RANDOM_PATCH)
.buildAndRegister(new RandomPatchConfiguration(attempts, xzSpread, ySpread, single.getPlacedFeature())); .buildAndRegister(new RandomPatchConfiguration(attempts, xzSpread, ySpread, single.getPlacedFeature()));
} }
} }

View file

@ -344,24 +344,28 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
} }
} }
public static Builder<OnSolid> startOnSolid() {
return Builder.start(OnSolid::new);
}
public static class OnSolid extends ScatterFeatureConfig { public static class OnSolid extends ScatterFeatureConfig {
public static final Codec<OnSolid> CODEC = buildCodec(OnSolid::new); public static final Codec<OnSolid> CODEC = buildCodec(OnSolid::new);
public OnSolid(BlockStateProvider clusterBlock, protected OnSolid(BlockStateProvider clusterBlock,
Optional<BlockStateProvider> tipBlock, Optional<BlockStateProvider> tipBlock,
Optional<BlockStateProvider> bottomBlock, Optional<BlockStateProvider> bottomBlock,
Optional<BlockState> baseState, Optional<BlockState> baseState,
float baseReplaceChance, float baseReplaceChance,
float chanceOfDirectionalSpread, float chanceOfDirectionalSpread,
float chanceOfSpreadRadius2, float chanceOfSpreadRadius2,
float chanceOfSpreadRadius3, float chanceOfSpreadRadius3,
int minHeight, int minHeight,
int maxHeight, int maxHeight,
float maxSpread, float maxSpread,
float sizeVariation, float sizeVariation,
float floorChance, float floorChance,
boolean growWhileFree, boolean growWhileFree,
IntProvider spreadCount) { IntProvider spreadCount) {
super(clusterBlock, super(clusterBlock,
tipBlock, tipBlock,
bottomBlock, bottomBlock,
@ -380,11 +384,6 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
} }
public static Builder<OnSolid> startOnSolid() {
return Builder.start(OnSolid::new);
}
@Override @Override
public boolean isValidBase(BlockState state) { public boolean isValidBase(BlockState state) {
return BlocksHelper.isTerrain(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);
}
}
} }

View file

@ -49,6 +49,10 @@ public class PlacementModifiers {
"on_every_layer", "on_every_layer",
OnEveryLayer.CODEC); 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) { private static <P extends PlacementModifier> PlacementModifierType<P> register(String path, Codec<P> codec) {
return register(BCLib.makeID(path), codec); return register(BCLib.makeID(path), codec);

View file

@ -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;
}
}

View file

@ -40,5 +40,8 @@ public class NamedBlockTags {
static { static {
TagAPI.BLOCKS.add(BlockTags.NETHER_CARVER_REPLACEABLES, Blocks.RED_SAND, Blocks.MAGMA_BLOCK); 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);
} }
} }