Allow BlockStateProviders in ScatterFeature

This commit is contained in:
Frank 2022-06-06 03:35:07 +02:00
parent c9daf3c5d3
commit 0bcfa65f0c
2 changed files with 48 additions and 37 deletions

View file

@ -28,7 +28,6 @@ import org.betterx.bclib.util.BlocksHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer;
public class ScatterFeature<FC extends ScatterFeatureConfig> public class ScatterFeature<FC extends ScatterFeatureConfig>
extends Feature<FC> { extends Feature<FC> {
@ -161,7 +160,8 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
RandomSource random) { RandomSource random) {
if (BlocksHelper.isFreeSpace(level, origin, direction, height, BlocksHelper::isFree)) { if (BlocksHelper.isFreeSpace(level, origin, direction, height, BlocksHelper::isFree)) {
createPatchOfBaseBlocks(level, random, basePos, config); createPatchOfBaseBlocks(level, random, basePos, config);
if (config.bottomBlock.canSurvive(level, origin)) { BlockState bottom = config.bottomBlock.getState(random, origin);
if (bottom.canSurvive(level, origin)) {
buildPillar(level, origin, direction, height, config, random); buildPillar(level, origin, direction, height, config, random);
} }
} }
@ -175,22 +175,14 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
RandomSource random) { RandomSource random) {
final BlockPos.MutableBlockPos POS = origin.mutable(); final BlockPos.MutableBlockPos POS = origin.mutable();
buildBaseToTipColumn(height, (blockState) -> { for (int size = 0; size < height; size++) {
BlockState previous = level.getBlockState(POS); BlockState previous = level.getBlockState(POS);
BlockState state = config.createBlock(size, height - 1, random, POS);
if (!BlocksHelper.isFree(previous)) { if (!BlocksHelper.isFree(previous)) {
System.out.println("Replaced " + previous + " with " + blockState + " at " + POS); System.out.println("Replaced " + previous + " with " + state + " at " + POS);
} }
BlocksHelper.setWithoutUpdate(level, POS, blockState); BlocksHelper.setWithoutUpdate(level, POS, state);
POS.move(direction); POS.move(direction);
}, config, random);
}
protected void buildBaseToTipColumn(int totalHeight,
Consumer<BlockState> consumer,
ScatterFeatureConfig config,
RandomSource random) {
for (int size = 0; size < totalHeight; size++) {
consumer.accept(config.createBlock(size, totalHeight - 1, random));
} }
} }

View file

@ -1,5 +1,6 @@
package org.betterx.bclib.api.features.config; package org.betterx.bclib.api.features.config;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource; import net.minecraft.util.RandomSource;
import net.minecraft.util.valueproviders.ConstantInt; import net.minecraft.util.valueproviders.ConstantInt;
import net.minecraft.util.valueproviders.IntProvider; import net.minecraft.util.valueproviders.IntProvider;
@ -7,6 +8,7 @@ import net.minecraft.util.valueproviders.UniformInt;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
import com.mojang.datafixers.util.Function15; import com.mojang.datafixers.util.Function15;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
@ -17,12 +19,12 @@ import org.betterx.bclib.util.BlocksHelper;
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, Optional<BlockState>, Optional<BlockState>, Optional<BlockState>, Float, Float, Float, Float, Integer, Integer, Float, Float, Float, Boolean, IntProvider, T> { public interface Instancer<T extends ScatterFeatureConfig> extends Function15<BlockStateProvider, Optional<BlockStateProvider>, Optional<BlockStateProvider>, Optional<BlockState>, Float, Float, Float, Float, Integer, Integer, Float, Float, Float, Boolean, IntProvider, T> {
} }
public final BlockState clusterBlock; public final BlockStateProvider clusterBlock;
public final BlockState tipBlock; public final BlockStateProvider tipBlock;
public final BlockState bottomBlock; public final BlockStateProvider bottomBlock;
public final Optional<BlockState> baseState; public final Optional<BlockState> baseState;
public final float baseReplaceChance; public final float baseReplaceChance;
public final float chanceOfDirectionalSpread; public final float chanceOfDirectionalSpread;
@ -38,9 +40,9 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
public final boolean growWhileFree; public final boolean growWhileFree;
public ScatterFeatureConfig(BlockState clusterBlock, public ScatterFeatureConfig(BlockStateProvider clusterBlock,
Optional<BlockState> tipBlock, Optional<BlockStateProvider> tipBlock,
Optional<BlockState> bottomBlock, Optional<BlockStateProvider> bottomBlock,
Optional<BlockState> baseState, Optional<BlockState> baseState,
float baseReplaceChance, float baseReplaceChance,
float chanceOfDirectionalSpread, float chanceOfDirectionalSpread,
@ -77,20 +79,20 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
public abstract boolean isValidBase(BlockState state); public abstract boolean isValidBase(BlockState state);
public abstract BlockState createBlock(int height, int maxHeight, RandomSource random); public abstract BlockState createBlock(int height, int maxHeight, RandomSource random, BlockPos pos);
public static <T extends ScatterFeatureConfig> Codec<T> buildCodec(Instancer<T> instancer) { public static <T extends ScatterFeatureConfig> Codec<T> buildCodec(Instancer<T> instancer) {
return RecordCodecBuilder.create((instance) -> instance return RecordCodecBuilder.create((instance) -> instance
.group(BlockState.CODEC .group(BlockStateProvider.CODEC
.fieldOf("cluster_block") .fieldOf("cluster_block")
.forGetter((T cfg) -> cfg.clusterBlock), .forGetter((T cfg) -> cfg.clusterBlock),
BlockState.CODEC BlockStateProvider.CODEC
.optionalFieldOf("tip_block") .optionalFieldOf("tip_block")
.orElse(Optional.empty()) .orElse(Optional.empty())
.forGetter((T cfg) -> cfg.tipBlock == cfg.clusterBlock .forGetter((T cfg) -> cfg.tipBlock == cfg.clusterBlock
? Optional.empty() ? Optional.empty()
: Optional.of(cfg.tipBlock)), : Optional.of(cfg.tipBlock)),
BlockState.CODEC BlockStateProvider.CODEC
.optionalFieldOf("bottom_block") .optionalFieldOf("bottom_block")
.orElse(Optional.empty()) .orElse(Optional.empty())
.forGetter((T cfg) -> cfg.bottomBlock == cfg.clusterBlock .forGetter((T cfg) -> cfg.bottomBlock == cfg.clusterBlock
@ -159,9 +161,9 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
} }
public static class Builder<T extends ScatterFeatureConfig> { public static class Builder<T extends ScatterFeatureConfig> {
private BlockState clusterBlock; private BlockStateProvider clusterBlock;
private BlockState tipBlock; private BlockStateProvider tipBlock;
private BlockState bottomBlock; private BlockStateProvider bottomBlock;
private Optional<BlockState> baseState = Optional.empty(); private Optional<BlockState> baseState = Optional.empty();
private float baseReplaceChance = 0; private float baseReplaceChance = 0;
private float chanceOfDirectionalSpread = 0; private float chanceOfDirectionalSpread = 0;
@ -193,18 +195,35 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
} }
public Builder<T> block(BlockState s) { public Builder<T> block(BlockState s) {
this.clusterBlock = BlockStateProvider.simple(s);
if (tipBlock == null) tipBlock = BlockStateProvider.simple(s);
if (bottomBlock == null) bottomBlock = BlockStateProvider.simple(s);
return this;
}
public Builder<T> tipBlock(BlockState s) {
tipBlock = BlockStateProvider.simple(s);
return this;
}
public Builder<T> bottomBlock(BlockState s) {
bottomBlock = BlockStateProvider.simple(s);
return this;
}
public Builder<T> block(BlockStateProvider s) {
this.clusterBlock = s; this.clusterBlock = s;
if (tipBlock == null) tipBlock = s; if (tipBlock == null) tipBlock = s;
if (bottomBlock == null) bottomBlock = s; if (bottomBlock == null) bottomBlock = s;
return this; return this;
} }
public Builder<T> tipBlock(BlockState s) { public Builder<T> tipBlock(BlockStateProvider s) {
tipBlock = s; tipBlock = s;
return this; return this;
} }
public Builder<T> bottomBlock(BlockState s) { public Builder<T> bottomBlock(BlockStateProvider s) {
bottomBlock = s; bottomBlock = s;
return this; return this;
} }
@ -316,9 +335,9 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
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(BlockState clusterBlock, public OnSolid(BlockStateProvider clusterBlock,
Optional<BlockState> tipBlock, Optional<BlockStateProvider> tipBlock,
Optional<BlockState> bottomBlock, Optional<BlockStateProvider> bottomBlock,
Optional<BlockState> baseState, Optional<BlockState> baseState,
float baseReplaceChance, float baseReplaceChance,
float chanceOfDirectionalSpread, float chanceOfDirectionalSpread,
@ -361,11 +380,11 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
} }
@Override @Override
public BlockState createBlock(int height, int maxHeight, RandomSource random) { public BlockState createBlock(int height, int maxHeight, RandomSource random, BlockPos pos) {
if (height == 0) return this.bottomBlock; if (height == 0) return this.bottomBlock.getState(random, pos);
return height == maxHeight return height == maxHeight
? this.tipBlock ? this.tipBlock.getState(random, pos)
: this.clusterBlock; : this.clusterBlock.getState(random, pos);
} }
} }