From 2ac472f7165caaa89b8c8c470edceecd258fcb60 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 7 Jun 2022 02:39:12 +0200 Subject: [PATCH] UpsideDownForest --- .../betterx/bclib/api/biomes/BiomeAPI.java | 5 + .../bclib/api/features/BCLFeature.java | 8 + .../bclib/api/features/BCLFeatureBuilder.java | 8 + .../bclib/api/features/FastFeatures.java | 5 + .../features/config/ScatterFeatureConfig.java | 148 +++++++++++++++--- .../placement/PlacementModifiers.java | 4 + .../features/placement/UnderEveryLayer.java | 91 +++++++++++ .../betterx/bclib/api/tag/NamedBlockTags.java | 3 + 8 files changed, 252 insertions(+), 20 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/api/features/placement/UnderEveryLayer.java diff --git a/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java index 8de08777..5fe73391 100644 --- a/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/biomes/BiomeAPI.java @@ -747,6 +747,11 @@ public class BiomeAPI { public static void applyModifications(BiomeSource source, ResourceKey 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> biomes = source.possibleBiomes(); List>> modifications = MODIFICATIONS.get(dimension); for (Holder biomeHolder : biomes) { diff --git a/src/main/java/org/betterx/bclib/api/features/BCLFeature.java b/src/main/java/org/betterx/bclib/api/features/BCLFeature.java index f0d51ab0..1cc14473 100644 --- a/src/main/java/org/betterx/bclib/api/features/BCLFeature.java +++ b/src/main/java/org/betterx/bclib/api/features/BCLFeature.java @@ -30,6 +30,14 @@ public class BCLFeature, FC extends FeatureConfiguration> BCLib.makeID("scatter_on_solid"), new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)); + public static final Feature SCATTER_EXTEND_TOP = register( + BCLib.makeID("scatter_extend_top"), + new ScatterFeature<>(ScatterFeatureConfig.ExtendTop.CODEC)); + + public static final Feature SCATTER_EXTEND_BOTTOM = register( + BCLib.makeID("scatter_extend_bottom"), + new ScatterFeature<>(ScatterFeatureConfig.ExtendBottom.CODEC)); + public static final Feature RANDOM_SELECTOR = register( BCLib.makeID("random_select"), new WeightedRandomSelectorFeature()); diff --git a/src/main/java/org/betterx/bclib/api/features/BCLFeatureBuilder.java b/src/main/java/org/betterx/bclib/api/features/BCLFeatureBuilder.java index 90cb3380..8f91daee 100644 --- a/src/main/java/org/betterx/bclib/api/features/BCLFeatureBuilder.java +++ b/src/main/java/org/betterx/bclib/api/features/BCLFeatureBuilder.java @@ -245,6 +245,10 @@ public class BCLFeatureBuilder 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 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())); } + + } diff --git a/src/main/java/org/betterx/bclib/api/features/config/ScatterFeatureConfig.java b/src/main/java/org/betterx/bclib/api/features/config/ScatterFeatureConfig.java index fa21ca6a..060ebdb2 100644 --- a/src/main/java/org/betterx/bclib/api/features/config/ScatterFeatureConfig.java +++ b/src/main/java/org/betterx/bclib/api/features/config/ScatterFeatureConfig.java @@ -344,24 +344,28 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration { } } + public static Builder startOnSolid() { + return Builder.start(OnSolid::new); + } + public static class OnSolid extends ScatterFeatureConfig { public static final Codec CODEC = buildCodec(OnSolid::new); - public OnSolid(BlockStateProvider clusterBlock, - Optional tipBlock, - Optional bottomBlock, - Optional baseState, - float baseReplaceChance, - float chanceOfDirectionalSpread, - float chanceOfSpreadRadius2, - float chanceOfSpreadRadius3, - int minHeight, - int maxHeight, - float maxSpread, - float sizeVariation, - float floorChance, - boolean growWhileFree, - IntProvider spreadCount) { + protected OnSolid(BlockStateProvider clusterBlock, + Optional tipBlock, + Optional bottomBlock, + Optional 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, @@ -380,11 +384,6 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration { } - public static Builder 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 startExtendTop() { + return Builder.start(ExtendTop::new); + } + + public static class ExtendTop extends ScatterFeatureConfig { + public static final Codec CODEC = buildCodec(ExtendTop::new); + + protected ExtendTop(BlockStateProvider clusterBlock, + Optional tipBlock, + Optional bottomBlock, + Optional 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 startExtendBottom() { + return Builder.start(ExtendBottom::new); + } + + public static class ExtendBottom extends ScatterFeatureConfig { + public static final Codec CODEC = buildCodec(ExtendBottom::new); + + protected ExtendBottom(BlockStateProvider clusterBlock, + Optional tipBlock, + Optional bottomBlock, + Optional 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); + } + } + } diff --git a/src/main/java/org/betterx/bclib/api/features/placement/PlacementModifiers.java b/src/main/java/org/betterx/bclib/api/features/placement/PlacementModifiers.java index 01713db6..1470038a 100644 --- a/src/main/java/org/betterx/bclib/api/features/placement/PlacementModifiers.java +++ b/src/main/java/org/betterx/bclib/api/features/placement/PlacementModifiers.java @@ -49,6 +49,10 @@ public class PlacementModifiers { "on_every_layer", OnEveryLayer.CODEC); + public static final PlacementModifierType UNDER_EVERY_LAYER = register( + "under_every_layer", + UnderEveryLayer.CODEC); + private static

PlacementModifierType

register(String path, Codec

codec) { return register(BCLib.makeID(path), codec); diff --git a/src/main/java/org/betterx/bclib/api/features/placement/UnderEveryLayer.java b/src/main/java/org/betterx/bclib/api/features/placement/UnderEveryLayer.java new file mode 100644 index 00000000..25b01690 --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/features/placement/UnderEveryLayer.java @@ -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 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 minHeight; + private final Optional maxHeight; + + private UnderEveryLayer(Optional minHeight, Optional maxHeight) { + this.minHeight = minHeight; + + this.maxHeight = maxHeight; + } + + public static UnderEveryLayer simple() { + return INSTANCE; + } + + public static UnderEveryLayer min4() { + return INSTANCE_MIN_4; + } + + @Override + public Stream getPositions(PlacementContext ctx, + RandomSource random, + BlockPos pos) { + + Stream.Builder 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 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; + } +} diff --git a/src/main/java/org/betterx/bclib/api/tag/NamedBlockTags.java b/src/main/java/org/betterx/bclib/api/tag/NamedBlockTags.java index a42cc700..230c4726 100644 --- a/src/main/java/org/betterx/bclib/api/tag/NamedBlockTags.java +++ b/src/main/java/org/betterx/bclib/api/tag/NamedBlockTags.java @@ -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); } }