More Feature Updates
This commit is contained in:
parent
f82d8b6178
commit
e7486c8aa4
7 changed files with 150 additions and 198 deletions
|
@ -15,7 +15,6 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
|
|
||||||
import org.betterx.bclib.BCLib;
|
import org.betterx.bclib.BCLib;
|
||||||
import org.betterx.bclib.api.features.config.BlockPlaceFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
@ -26,10 +25,6 @@ public class BCLFeature {
|
||||||
BCLib.makeID("scatter_on_solid"),
|
BCLib.makeID("scatter_on_solid"),
|
||||||
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
||||||
);
|
);
|
||||||
public static final Feature<BlockPlaceFeatureConfig> PLACE_BLOCK = register(
|
|
||||||
BCLib.makeID("place_block"),
|
|
||||||
new BlockPlaceFeature<>(BlockPlaceFeatureConfig.CODEC)
|
|
||||||
);
|
|
||||||
private final Holder<PlacedFeature> placedFeature;
|
private final Holder<PlacedFeature> placedFeature;
|
||||||
private final Decoration featureStep;
|
private final Decoration featureStep;
|
||||||
private final Feature<?> feature;
|
private final Feature<?> feature;
|
||||||
|
|
|
@ -189,10 +189,26 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyAbove4());
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove4());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyAbove2() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove2());
|
||||||
|
}
|
||||||
|
|
||||||
public BCLFeatureBuilder isEmptyAbove() {
|
public BCLFeatureBuilder isEmptyAbove() {
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyAbove());
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyBelow4() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow4());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyBelow2() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow2());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyBelow() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow());
|
||||||
|
}
|
||||||
|
|
||||||
public BCLFeatureBuilder isEmptyAbove(int d1, int d2) {
|
public BCLFeatureBuilder isEmptyAbove(int d1, int d2) {
|
||||||
return modifier(new IsEmptyAboveSampledFilter(d1, d2));
|
return modifier(new IsEmptyAboveSampledFilter(d1, d2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package org.betterx.bclib.api.features;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import org.betterx.bclib.api.features.config.BlockPlaceFeatureConfig;
|
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class BlockPlaceFeature<FC extends BlockPlaceFeatureConfig> extends Feature<FC> {
|
|
||||||
public BlockPlaceFeature(Codec<FC> codec) {
|
|
||||||
super(codec);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean place(FeaturePlaceContext<FC> ctx) {
|
|
||||||
Optional<BlockState> state = ctx.config().getRandomBlock(ctx.random());
|
|
||||||
if (state.isPresent())
|
|
||||||
BlocksHelper.setWithoutUpdate(ctx.level(), ctx.origin(), state.get());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -68,7 +68,7 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
.modifier(RandomOffsetPlacement.of(
|
.modifier(RandomOffsetPlacement.of(
|
||||||
ClampedNormalInt.of(0.0f, 2.0f, -6, 6),
|
ClampedNormalInt.of(0.0f, 2.0f, -6, 6),
|
||||||
ClampedNormalInt.of(0.0f, 0.6f, -2, 2)))
|
ClampedNormalInt.of(0.0f, 0.6f, -2, 2)))
|
||||||
.modifier(BiomeFilter.biome())
|
.onlyInBiome()
|
||||||
.buildAndRegister(configuration);
|
.buildAndRegister(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
package org.betterx.bclib.api.features.config;
|
|
||||||
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.util.random.SimpleWeightedRandomList;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.DataResult;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class BlockPlaceFeatureConfig implements FeatureConfiguration {
|
|
||||||
public static final Codec<BlockPlaceFeatureConfig> CODEC = SimpleWeightedRandomList
|
|
||||||
.wrappedCodec(BlockState.CODEC)
|
|
||||||
.comapFlatMap(BlockPlaceFeatureConfig::create, cfg -> cfg.weightedList)
|
|
||||||
.fieldOf("entries").codec();
|
|
||||||
|
|
||||||
private final SimpleWeightedRandomList<BlockState> weightedList;
|
|
||||||
|
|
||||||
private static DataResult<BlockPlaceFeatureConfig> create(SimpleWeightedRandomList<BlockState> simpleWeightedRandomList) {
|
|
||||||
if (simpleWeightedRandomList.isEmpty()) {
|
|
||||||
return DataResult.error("BlockPlaceFeatureConfig with no states");
|
|
||||||
}
|
|
||||||
return DataResult.success(new BlockPlaceFeatureConfig(simpleWeightedRandomList));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static SimpleWeightedRandomList<BlockState> convert(List<BlockState> states) {
|
|
||||||
var builder = SimpleWeightedRandomList.<BlockState>builder();
|
|
||||||
for (BlockState s : states) builder.add(s, 1);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(Block block) {
|
|
||||||
this(block.defaultBlockState());
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(BlockState state) {
|
|
||||||
this(SimpleWeightedRandomList
|
|
||||||
.<BlockState>builder()
|
|
||||||
.add(state, 1)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(List<BlockState> states) {
|
|
||||||
this(convert(states));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(SimpleWeightedRandomList<BlockState> blocks) {
|
|
||||||
this.weightedList = blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<BlockState> getRandomBlock(RandomSource random) {
|
|
||||||
return this.weightedList.getRandomValue(random);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@ import org.betterx.bclib.api.tag.CommonBlockTags;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public interface Instancer<T extends ScatterFeatureConfig> extends Function15<BlockState, BlockState, BlockState, Optional<BlockState>, Float, Float, Float, Float, Integer, Integer, Float, Float, Float, Boolean, IntProvider, T> {
|
public interface Instancer<T extends ScatterFeatureConfig> extends Function15<BlockState, Optional<BlockState>, Optional<BlockState>, Optional<BlockState>, Float, Float, Float, Float, Integer, Integer, Float, Float, Float, Boolean, IntProvider, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final BlockState clusterBlock;
|
public final BlockState clusterBlock;
|
||||||
|
@ -39,8 +39,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public final boolean growWhileFree;
|
public final boolean growWhileFree;
|
||||||
|
|
||||||
public ScatterFeatureConfig(BlockState clusterBlock,
|
public ScatterFeatureConfig(BlockState clusterBlock,
|
||||||
BlockState tipBlock,
|
Optional<BlockState> tipBlock,
|
||||||
BlockState bottomBlock,
|
Optional<BlockState> bottomBlock,
|
||||||
Optional<BlockState> baseState,
|
Optional<BlockState> baseState,
|
||||||
float baseReplaceChance,
|
float baseReplaceChance,
|
||||||
float chanceOfDirectionalSpread,
|
float chanceOfDirectionalSpread,
|
||||||
|
@ -54,8 +54,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
boolean growWhileFree,
|
boolean growWhileFree,
|
||||||
IntProvider spreadCount) {
|
IntProvider spreadCount) {
|
||||||
this.clusterBlock = clusterBlock;
|
this.clusterBlock = clusterBlock;
|
||||||
this.tipBlock = tipBlock == null ? clusterBlock : tipBlock;
|
this.tipBlock = tipBlock.orElse(clusterBlock);
|
||||||
this.bottomBlock = bottomBlock == null ? clusterBlock : bottomBlock;
|
this.bottomBlock = bottomBlock.orElse(clusterBlock);
|
||||||
this.baseState = baseState;
|
this.baseState = baseState;
|
||||||
this.baseReplaceChance = baseReplaceChance;
|
this.baseReplaceChance = baseReplaceChance;
|
||||||
this.chanceOfDirectionalSpread = chanceOfDirectionalSpread;
|
this.chanceOfDirectionalSpread = chanceOfDirectionalSpread;
|
||||||
|
@ -85,13 +85,17 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
.fieldOf("cluster_block")
|
.fieldOf("cluster_block")
|
||||||
.forGetter((T cfg) -> cfg.clusterBlock),
|
.forGetter((T cfg) -> cfg.clusterBlock),
|
||||||
BlockState.CODEC
|
BlockState.CODEC
|
||||||
.fieldOf("tip_block")
|
.optionalFieldOf("tip_block")
|
||||||
.orElse(null)
|
.orElse(Optional.empty())
|
||||||
.forGetter((T cfg) -> cfg.tipBlock),
|
.forGetter((T cfg) -> cfg.tipBlock == cfg.clusterBlock
|
||||||
|
? Optional.empty()
|
||||||
|
: Optional.of(cfg.tipBlock)),
|
||||||
BlockState.CODEC
|
BlockState.CODEC
|
||||||
.fieldOf("bottom_block")
|
.optionalFieldOf("bottom_block")
|
||||||
.orElse(null)
|
.orElse(Optional.empty())
|
||||||
.forGetter((T cfg) -> cfg.bottomBlock),
|
.forGetter((T cfg) -> cfg.bottomBlock == cfg.clusterBlock
|
||||||
|
? Optional.empty()
|
||||||
|
: Optional.of(cfg.bottomBlock)),
|
||||||
BlockState.CODEC
|
BlockState.CODEC
|
||||||
.optionalFieldOf("base_state")
|
.optionalFieldOf("base_state")
|
||||||
.forGetter((T cfg) -> cfg.baseState),
|
.forGetter((T cfg) -> cfg.baseState),
|
||||||
|
@ -291,8 +295,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public T build() {
|
public T build() {
|
||||||
return instancer.apply(
|
return instancer.apply(
|
||||||
this.clusterBlock,
|
this.clusterBlock,
|
||||||
this.tipBlock,
|
Optional.of(this.tipBlock),
|
||||||
this.bottomBlock,
|
Optional.of(this.bottomBlock),
|
||||||
this.baseState,
|
this.baseState,
|
||||||
this.baseReplaceChance,
|
this.baseReplaceChance,
|
||||||
this.chanceOfDirectionalSpread,
|
this.chanceOfDirectionalSpread,
|
||||||
|
@ -313,8 +317,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public static final Codec<OnSolid> CODEC = buildCodec(OnSolid::new);
|
public static final Codec<OnSolid> CODEC = buildCodec(OnSolid::new);
|
||||||
|
|
||||||
public OnSolid(BlockState clusterBlock,
|
public OnSolid(BlockState clusterBlock,
|
||||||
BlockState tipBlock,
|
Optional<BlockState> tipBlock,
|
||||||
BlockState bottomBlock,
|
Optional<BlockState> bottomBlock,
|
||||||
Optional<BlockState> baseState,
|
Optional<BlockState> baseState,
|
||||||
float baseReplaceChance,
|
float baseReplaceChance,
|
||||||
float chanceOfDirectionalSpread,
|
float chanceOfDirectionalSpread,
|
||||||
|
|
|
@ -16,10 +16,15 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
public class IsEmptyAboveSampledFilter extends PlacementFilter {
|
public class IsEmptyAboveSampledFilter extends PlacementFilter {
|
||||||
private static final IsEmptyAboveSampledFilter DEFAULT = new IsEmptyAboveSampledFilter(4, 2);
|
private static final IsEmptyAboveSampledFilter DEFAULT = new IsEmptyAboveSampledFilter(4, 2);
|
||||||
private static final IsEmptyAboveSampledFilter DEFAULT1 = new IsEmptyAboveSampledFilter(1, 1);
|
private static final IsEmptyAboveSampledFilter DEFAULT1 = new IsEmptyAboveSampledFilter(1, 1);
|
||||||
|
private static final IsEmptyAboveSampledFilter DEFAULT2 = new IsEmptyAboveSampledFilter(1, 2);
|
||||||
|
|
||||||
|
private static final IsEmptyAboveSampledFilter BELOW_DEFAULT = new IsEmptyAboveSampledFilter(-4, -2);
|
||||||
|
private static final IsEmptyAboveSampledFilter BELOW_DEFAULT1 = new IsEmptyAboveSampledFilter(-1, -1);
|
||||||
|
private static final IsEmptyAboveSampledFilter BELOW_DEFAULT2 = new IsEmptyAboveSampledFilter(-1, -2);
|
||||||
public static final Codec<IsEmptyAboveSampledFilter> CODEC = RecordCodecBuilder.create((instance) -> instance
|
public static final Codec<IsEmptyAboveSampledFilter> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
.group(
|
.group(
|
||||||
Codec.intRange(1, 32).fieldOf("d1").orElse(2).forGetter((p) -> p.distance1),
|
Codec.intRange(-32, 32).fieldOf("d1").orElse(4).forGetter((p) -> p.distance1),
|
||||||
Codec.intRange(1, 32).fieldOf("d2").orElse(4).forGetter((p) -> p.distance1)
|
Codec.intRange(-32, 32).fieldOf("d2").orElse(2).forGetter((p) -> p.distance1)
|
||||||
)
|
)
|
||||||
.apply(instance, IsEmptyAboveSampledFilter::new));
|
.apply(instance, IsEmptyAboveSampledFilter::new));
|
||||||
|
|
||||||
|
@ -27,10 +32,26 @@ public class IsEmptyAboveSampledFilter extends PlacementFilter {
|
||||||
return DEFAULT;
|
return DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyAbove2() {
|
||||||
|
return DEFAULT2;
|
||||||
|
}
|
||||||
|
|
||||||
public static PlacementFilter emptyAbove() {
|
public static PlacementFilter emptyAbove() {
|
||||||
return DEFAULT1;
|
return DEFAULT1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyBelow4() {
|
||||||
|
return BELOW_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyBelow2() {
|
||||||
|
return BELOW_DEFAULT2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyBelow() {
|
||||||
|
return BELOW_DEFAULT1;
|
||||||
|
}
|
||||||
|
|
||||||
public IsEmptyAboveSampledFilter(int d1, int d2) {
|
public IsEmptyAboveSampledFilter(int d1, int d2) {
|
||||||
this.distance1 = d1;
|
this.distance1 = d1;
|
||||||
this.distance2 = d2;
|
this.distance2 = d2;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue