Fixed ScatterFeature
This commit is contained in:
parent
51bd560fa0
commit
0149b17a1a
6 changed files with 170 additions and 146 deletions
|
@ -260,6 +260,10 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
||||||
return modifier(new IsBasin(BlockPredicate.anyOf(predicates)));
|
return modifier(new IsBasin(BlockPredicate.anyOf(predicates)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder inOpenBasinOf(BlockPredicate... predicates) {
|
||||||
|
return modifier(IsBasin.openTop(BlockPredicate.anyOf(predicates)));
|
||||||
|
}
|
||||||
|
|
||||||
public BCLFeatureBuilder is(BlockPredicate... predicates) {
|
public BCLFeatureBuilder is(BlockPredicate... predicates) {
|
||||||
return modifier(new Is(BlockPredicate.anyOf(predicates)));
|
return modifier(new Is(BlockPredicate.anyOf(predicates)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import net.minecraft.util.valueproviders.ConstantInt;
|
||||||
import net.minecraft.util.valueproviders.UniformInt;
|
import net.minecraft.util.valueproviders.UniformInt;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
|
@ -23,6 +22,7 @@ import net.minecraft.world.level.levelgen.placement.*;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.tag.CommonBlockTags;
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -40,21 +40,21 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
Feature<T> inlineFeature) {
|
Feature<T> inlineFeature) {
|
||||||
List<Holder<PlacedFeature>> set = new ArrayList<>(2);
|
List<Holder<PlacedFeature>> set = new ArrayList<>(2);
|
||||||
if (cfg.floorChance > 0) set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
if (cfg.floorChance > 0) set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
||||||
cfg,
|
cfg,
|
||||||
EnvironmentScanPlacement.scanningFor(Direction.DOWN,
|
EnvironmentScanPlacement.scanningFor(Direction.DOWN,
|
||||||
BlockPredicate.solid(),
|
BlockPredicate.matchesTag(CommonBlockTags.TERRAIN),
|
||||||
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
||||||
12),
|
12),
|
||||||
RandomOffsetPlacement.vertical(ConstantInt.of(1))));
|
RandomOffsetPlacement.vertical(ConstantInt.of(1))));
|
||||||
|
|
||||||
if (cfg.floorChance < 1) {
|
if (cfg.floorChance < 1) {
|
||||||
set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
||||||
cfg,
|
cfg,
|
||||||
EnvironmentScanPlacement.scanningFor(Direction.UP,
|
EnvironmentScanPlacement.scanningFor(Direction.UP,
|
||||||
BlockPredicate.solid(),
|
BlockPredicate.matchesTag(CommonBlockTags.TERRAIN),
|
||||||
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
||||||
12),
|
12),
|
||||||
RandomOffsetPlacement.vertical(ConstantInt.of(-1))));
|
RandomOffsetPlacement.vertical(ConstantInt.of(-1))));
|
||||||
}
|
}
|
||||||
SimpleRandomFeatureConfiguration configuration = new SimpleRandomFeatureConfiguration(HolderSet.direct(set));
|
SimpleRandomFeatureConfiguration configuration = new SimpleRandomFeatureConfiguration(HolderSet.direct(set));
|
||||||
|
|
||||||
|
@ -112,21 +112,21 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
for (int i = 0; i < tryCount; i++) {
|
for (int i = 0; i < tryCount; i++) {
|
||||||
int x = origin.getX() + (int) (random.nextGaussian() * config.maxSpread);
|
int x = origin.getX() + (int) (random.nextGaussian() * config.maxSpread);
|
||||||
int z = origin.getZ() + (int) (random.nextGaussian() * config.maxSpread);
|
int z = origin.getZ() + (int) (random.nextGaussian() * config.maxSpread);
|
||||||
POS.set(x, origin.getY(), z);
|
POS.set(x, basePos.getY(), z);
|
||||||
|
|
||||||
if (BlocksHelper.findSurroundingSurface(level, POS, surfaceDirection, 4, config::isValidBase)) {
|
if (BlocksHelper.findSurroundingSurface(level, POS, surfaceDirection, 4, config::isValidBase)) {
|
||||||
int myHeight;
|
int myHeight;
|
||||||
if (config.growWhileFree) {
|
if (config.growWhileFree) {
|
||||||
myHeight = BlocksHelper.blockCount(level,
|
myHeight = BlocksHelper.blockCount(level,
|
||||||
POS,
|
POS,
|
||||||
direction,
|
direction,
|
||||||
config.maxHeight,
|
config.maxHeight,
|
||||||
state -> state.getMaterial().isReplaceable());
|
BlocksHelper::isFree
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
myHeight = centerHeight;
|
myHeight = centerHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
POS.move(direction, 1);
|
|
||||||
int dx = x - POS.getX();
|
int dx = x - POS.getX();
|
||||||
int dz = z - POS.getZ();
|
int dz = z - POS.getZ();
|
||||||
float sizeFactor = (1 - (float) (Math.sqrt(dx * dx + dz * dz) / distNormalizer));
|
float sizeFactor = (1 - (float) (Math.sqrt(dx * dx + dz * dz) / distNormalizer));
|
||||||
|
@ -134,15 +134,19 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
myHeight = (int) Math.min(Math.max(
|
myHeight = (int) Math.min(Math.max(
|
||||||
config.minHeight,
|
config.minHeight,
|
||||||
config.minHeight + sizeFactor * (myHeight - config.minHeight)
|
config.minHeight + sizeFactor * (myHeight - config.minHeight)
|
||||||
), config.maxHeight);
|
), config.maxHeight);
|
||||||
|
|
||||||
|
BlockState baseState = level.getBlockState(POS.relative(direction.getOpposite()));
|
||||||
|
if (!config.isValidBase(baseState)) {
|
||||||
|
System.out.println("Starting from " + baseState + " at " + POS.relative(direction.getOpposite()));
|
||||||
|
}
|
||||||
buildPillarWithBase(level,
|
buildPillarWithBase(level,
|
||||||
POS,
|
POS,
|
||||||
POS.relative(direction.getOpposite()),
|
POS.relative(direction.getOpposite()),
|
||||||
direction,
|
direction,
|
||||||
myHeight,
|
myHeight,
|
||||||
config,
|
config,
|
||||||
random);
|
random);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +159,7 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
int height,
|
int height,
|
||||||
ScatterFeatureConfig config,
|
ScatterFeatureConfig config,
|
||||||
RandomSource random) {
|
RandomSource random) {
|
||||||
if (BlocksHelper.isFreeSpace(level, origin, direction, height, (state) -> state.is(Blocks.AIR))) {
|
if (BlocksHelper.isFreeSpace(level, origin, direction, height, BlocksHelper::isFree)) {
|
||||||
createPatchOfBaseBlocks(level, random, basePos, config);
|
createPatchOfBaseBlocks(level, random, basePos, config);
|
||||||
buildPillar(level, origin, direction, height, config, random);
|
buildPillar(level, origin, direction, height, config, random);
|
||||||
}
|
}
|
||||||
|
@ -170,6 +174,10 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
|
|
||||||
final BlockPos.MutableBlockPos POS = origin.mutable();
|
final BlockPos.MutableBlockPos POS = origin.mutable();
|
||||||
buildBaseToTipColumn(height, (blockState) -> {
|
buildBaseToTipColumn(height, (blockState) -> {
|
||||||
|
BlockState previous = level.getBlockState(POS);
|
||||||
|
if (!BlocksHelper.isFree(previous)) {
|
||||||
|
System.out.println("Replaced " + previous + " with " + blockState + " at " + POS);
|
||||||
|
}
|
||||||
BlocksHelper.setWithoutUpdate(level, POS, blockState);
|
BlocksHelper.setWithoutUpdate(level, POS, blockState);
|
||||||
POS.move(direction);
|
POS.move(direction);
|
||||||
}, config, random);
|
}, config, random);
|
||||||
|
@ -181,16 +189,6 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
RandomSource random) {
|
RandomSource random) {
|
||||||
for (int size = 0; size < totalHeight; size++) {
|
for (int size = 0; size < totalHeight; size++) {
|
||||||
consumer.accept(config.createBlock(size, totalHeight - 1, random));
|
consumer.accept(config.createBlock(size, totalHeight - 1, random));
|
||||||
// Block s = config.createBlock(size, totalHeight - 1, random).getBlock();
|
|
||||||
// if (size == 0) s = Blocks.YELLOW_CONCRETE;
|
|
||||||
// else if (size == 1) s = Blocks.LIME_CONCRETE;
|
|
||||||
// else if (size == 2) s = Blocks.CYAN_CONCRETE;
|
|
||||||
// else if (size == 3) s = Blocks.LIGHT_BLUE_CONCRETE;
|
|
||||||
// else if (size == 4) s = Blocks.BLUE_CONCRETE;
|
|
||||||
// else if (size == 5) s = Blocks.PURPLE_CONCRETE;
|
|
||||||
// else if (size == 6) s = Blocks.MAGENTA_CONCRETE;
|
|
||||||
// else s = Blocks.GRAY_CONCRETE;
|
|
||||||
// consumer.accept(s.defaultBlockState());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,81 +81,81 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
|
|
||||||
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(BlockState.CODEC
|
||||||
.fieldOf("cluster_block")
|
.fieldOf("cluster_block")
|
||||||
.forGetter((T cfg) -> cfg.clusterBlock),
|
.forGetter((T cfg) -> cfg.clusterBlock),
|
||||||
BlockState.CODEC
|
BlockState.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
|
BlockState.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
|
||||||
? Optional.empty()
|
? Optional.empty()
|
||||||
: Optional.of(cfg.bottomBlock)),
|
: Optional.of(cfg.bottomBlock)),
|
||||||
BlockState.CODEC
|
BlockState.CODEC
|
||||||
.optionalFieldOf("base_state")
|
.optionalFieldOf("base_state")
|
||||||
.forGetter((T cfg) -> cfg.baseState),
|
.forGetter((T cfg) -> cfg.baseState),
|
||||||
Codec
|
Codec
|
||||||
.floatRange(0.0F, 1.0F)
|
.floatRange(0.0F, 1.0F)
|
||||||
.fieldOf("baseReplaceChance")
|
.fieldOf("baseReplaceChance")
|
||||||
.orElse(1.0F)
|
.orElse(1.0F)
|
||||||
.forGetter((T cfg) -> cfg.baseReplaceChance),
|
.forGetter((T cfg) -> cfg.baseReplaceChance),
|
||||||
Codec
|
Codec
|
||||||
.floatRange(0.0F, 1.0F)
|
.floatRange(0.0F, 1.0F)
|
||||||
.fieldOf("chance_of_directional_spread")
|
.fieldOf("chance_of_directional_spread")
|
||||||
.orElse(0.7F)
|
.orElse(0.7F)
|
||||||
.forGetter((T cfg) -> cfg.chanceOfDirectionalSpread),
|
.forGetter((T cfg) -> cfg.chanceOfDirectionalSpread),
|
||||||
Codec
|
Codec
|
||||||
.floatRange(0.0F, 1.0F)
|
.floatRange(0.0F, 1.0F)
|
||||||
.fieldOf("chance_of_spread_radius2")
|
.fieldOf("chance_of_spread_radius2")
|
||||||
.orElse(0.5F)
|
.orElse(0.5F)
|
||||||
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius2),
|
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius2),
|
||||||
Codec
|
Codec
|
||||||
.floatRange(0.0F, 1.0F)
|
.floatRange(0.0F, 1.0F)
|
||||||
.fieldOf("chance_of_spread_radius3")
|
.fieldOf("chance_of_spread_radius3")
|
||||||
.orElse(0.5F)
|
.orElse(0.5F)
|
||||||
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius3),
|
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius3),
|
||||||
Codec
|
Codec
|
||||||
.intRange(1, 20)
|
.intRange(1, 20)
|
||||||
.fieldOf("min_height")
|
.fieldOf("min_height")
|
||||||
.orElse(2)
|
.orElse(2)
|
||||||
.forGetter((T cfg) -> cfg.minHeight),
|
.forGetter((T cfg) -> cfg.minHeight),
|
||||||
Codec
|
Codec
|
||||||
.intRange(1, 20)
|
.intRange(1, 20)
|
||||||
.fieldOf("max_height")
|
.fieldOf("max_height")
|
||||||
.orElse(7)
|
.orElse(7)
|
||||||
.forGetter((T cfg) -> cfg.maxHeight),
|
.forGetter((T cfg) -> cfg.maxHeight),
|
||||||
Codec
|
Codec
|
||||||
.floatRange(0, 10)
|
.floatRange(0, 10)
|
||||||
.fieldOf("max_spread")
|
.fieldOf("max_spread")
|
||||||
.orElse(2f)
|
.orElse(2f)
|
||||||
.forGetter((T cfg) -> cfg.maxSpread),
|
.forGetter((T cfg) -> cfg.maxSpread),
|
||||||
Codec
|
Codec
|
||||||
.floatRange(0, 1)
|
.floatRange(0, 1)
|
||||||
.fieldOf("size_variation")
|
.fieldOf("size_variation")
|
||||||
.orElse(0.7f)
|
.orElse(0.7f)
|
||||||
.forGetter((T cfg) -> cfg.sizeVariation),
|
.forGetter((T cfg) -> cfg.sizeVariation),
|
||||||
Codec
|
Codec
|
||||||
.floatRange(0, 1)
|
.floatRange(0, 1)
|
||||||
.fieldOf("floor_chance")
|
.fieldOf("floor_chance")
|
||||||
.orElse(0.5f)
|
.orElse(0.5f)
|
||||||
.forGetter((T cfg) -> cfg.floorChance),
|
.forGetter((T cfg) -> cfg.floorChance),
|
||||||
Codec
|
Codec
|
||||||
.BOOL
|
.BOOL
|
||||||
.fieldOf("grow_while_empty")
|
.fieldOf("grow_while_empty")
|
||||||
.orElse(false)
|
.orElse(false)
|
||||||
.forGetter((T cfg) -> cfg.growWhileFree),
|
.forGetter((T cfg) -> cfg.growWhileFree),
|
||||||
IntProvider.codec(0, 64)
|
IntProvider.codec(0, 64)
|
||||||
.fieldOf("length")
|
.fieldOf("length")
|
||||||
.orElse(UniformInt.of(0, 3))
|
.orElse(UniformInt.of(0, 3))
|
||||||
.forGetter(cfg -> cfg.spreadCount)
|
.forGetter(cfg -> cfg.spreadCount)
|
||||||
)
|
)
|
||||||
.apply(instance, instancer)
|
.apply(instance, instancer)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder<T extends ScatterFeatureConfig> {
|
public static class Builder<T extends ScatterFeatureConfig> {
|
||||||
|
@ -244,10 +244,10 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
float chanceOfSpreadRadius2,
|
float chanceOfSpreadRadius2,
|
||||||
float chanceOfSpreadRadius3) {
|
float chanceOfSpreadRadius3) {
|
||||||
return generateBaseBlock(baseState,
|
return generateBaseBlock(baseState,
|
||||||
1,
|
1,
|
||||||
chanceOfDirectionalSpread,
|
chanceOfDirectionalSpread,
|
||||||
chanceOfSpreadRadius2,
|
chanceOfSpreadRadius2,
|
||||||
chanceOfSpreadRadius3);
|
chanceOfSpreadRadius3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder<T> generateBaseBlock(BlockState baseState,
|
public Builder<T> generateBaseBlock(BlockState baseState,
|
||||||
|
@ -309,7 +309,7 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
this.floorChance,
|
this.floorChance,
|
||||||
this.growWhileFree,
|
this.growWhileFree,
|
||||||
this.spreadCount
|
this.spreadCount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,20 +332,20 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
boolean growWhileFree,
|
boolean growWhileFree,
|
||||||
IntProvider spreadCount) {
|
IntProvider spreadCount) {
|
||||||
super(clusterBlock,
|
super(clusterBlock,
|
||||||
tipBlock,
|
tipBlock,
|
||||||
bottomBlock,
|
bottomBlock,
|
||||||
baseState,
|
baseState,
|
||||||
baseReplaceChance,
|
baseReplaceChance,
|
||||||
chanceOfDirectionalSpread,
|
chanceOfDirectionalSpread,
|
||||||
chanceOfSpreadRadius2,
|
chanceOfSpreadRadius2,
|
||||||
chanceOfSpreadRadius3,
|
chanceOfSpreadRadius3,
|
||||||
minHeight,
|
minHeight,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
maxSpread,
|
maxSpread,
|
||||||
sizeVariation,
|
sizeVariation,
|
||||||
floorChance,
|
floorChance,
|
||||||
growWhileFree,
|
growWhileFree,
|
||||||
spreadCount);
|
spreadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,29 +11,46 @@ import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class IsBasin extends PlacementFilter {
|
public class IsBasin extends PlacementFilter {
|
||||||
public static final Codec<IsBasin> CODEC = RecordCodecBuilder.create((instance) -> instance
|
public static final Codec<IsBasin> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
.group(
|
.group(
|
||||||
BlockPredicate.CODEC
|
BlockPredicate.CODEC
|
||||||
.fieldOf("predicate")
|
.fieldOf("predicate")
|
||||||
.forGetter(cfg -> cfg.predicate)
|
.forGetter(cfg -> cfg.predicate),
|
||||||
|
BlockPredicate.CODEC
|
||||||
|
.optionalFieldOf("top_predicate")
|
||||||
|
.orElse(Optional.empty())
|
||||||
|
.forGetter(cfg -> cfg.topPredicate)
|
||||||
)
|
)
|
||||||
.apply(instance, IsBasin::new));
|
.apply(instance, IsBasin::new));
|
||||||
|
|
||||||
private final BlockPredicate predicate;
|
private final BlockPredicate predicate;
|
||||||
|
private final Optional<BlockPredicate> topPredicate;
|
||||||
|
|
||||||
public IsBasin(BlockPredicate predicate) {
|
public IsBasin(BlockPredicate predicate) {
|
||||||
|
this(predicate, Optional.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IsBasin(BlockPredicate predicate, Optional<BlockPredicate> topPredicate) {
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
|
this.topPredicate = topPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IsBasin simple(BlockPredicate predicate) {
|
public static IsBasin simple(BlockPredicate predicate) {
|
||||||
|
|
||||||
return new IsBasin(predicate);
|
return new IsBasin(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IsBasin openTop(BlockPredicate predicate) {
|
||||||
|
return new IsBasin(predicate, Optional.of(BlockPredicate.ONLY_IN_AIR_PREDICATE));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
||||||
WorldGenLevel level = ctx.getLevel();
|
WorldGenLevel level = ctx.getLevel();
|
||||||
|
if (topPredicate.isPresent() && !topPredicate.get().test(level, pos.above())) return false;
|
||||||
|
|
||||||
return predicate.test(level, pos.below())
|
return predicate.test(level, pos.below())
|
||||||
&& predicate.test(level, pos.west())
|
&& predicate.test(level, pos.west())
|
||||||
&& predicate.test(level, pos.east())
|
&& predicate.test(level, pos.east())
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class MinEmptyFilter extends PlacementFilter {
|
||||||
pos.relative(direction),
|
pos.relative(direction),
|
||||||
direction,
|
direction,
|
||||||
distance - 1,
|
distance - 1,
|
||||||
state -> state.getMaterial().isReplaceable()
|
BlocksHelper::isFree
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,21 +251,28 @@ public class BlocksHelper {
|
||||||
Direction dir,
|
Direction dir,
|
||||||
int length,
|
int length,
|
||||||
Predicate<BlockState> surface) {
|
Predicate<BlockState> surface) {
|
||||||
|
BlockState beforeState = null;
|
||||||
|
BlockState nowState;
|
||||||
for (int len = 0; len < length; len++) {
|
for (int len = 0; len < length; len++) {
|
||||||
if (surface.test(level.getBlockState(startPos))) {
|
nowState = level.getBlockState(startPos);
|
||||||
|
if (surface.test(nowState)) {
|
||||||
if (len == 0) { //we started inside of the surface
|
if (len == 0) { //we started inside of the surface
|
||||||
|
beforeState = nowState;
|
||||||
for (int lenUp = 0; lenUp < length; lenUp++) {
|
for (int lenUp = 0; lenUp < length; lenUp++) {
|
||||||
startPos.move(dir, -1);
|
startPos.move(dir, -1);
|
||||||
if (BlocksHelper.isFree(level.getBlockState(startPos))) {
|
nowState = level.getBlockState(startPos);
|
||||||
startPos.move(dir, 1);
|
if (BlocksHelper.isFree(nowState)) {
|
||||||
return true;
|
return surface.test(beforeState);
|
||||||
}
|
}
|
||||||
|
beforeState = nowState;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
startPos.move(dir, -1);
|
||||||
|
return BlocksHelper.isFree(beforeState);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
beforeState = nowState;
|
||||||
startPos.move(dir, 1);
|
startPos.move(dir, 1);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -279,11 +286,10 @@ public class BlocksHelper {
|
||||||
Predicate<BlockState> freeSurface) {
|
Predicate<BlockState> freeSurface) {
|
||||||
MutableBlockPos POS = startPos.mutable();
|
MutableBlockPos POS = startPos.mutable();
|
||||||
for (int len = 0; len < length; len++) {
|
for (int len = 0; len < length; len++) {
|
||||||
POS.move(dir, 1);
|
|
||||||
if (!freeSurface.test(level.getBlockState(POS))) {
|
if (!freeSurface.test(level.getBlockState(POS))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
POS.move(dir, 1);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -294,12 +300,11 @@ public class BlocksHelper {
|
||||||
int length,
|
int length,
|
||||||
Predicate<BlockState> freeSurface) {
|
Predicate<BlockState> freeSurface) {
|
||||||
MutableBlockPos POS = startPos.mutable();
|
MutableBlockPos POS = startPos.mutable();
|
||||||
for (int len = 1; len < length; len++) {
|
for (int len = 0; len < length; len++) {
|
||||||
POS.move(dir, 1);
|
|
||||||
if (!freeSurface.test(level.getBlockState(POS))) {
|
if (!freeSurface.test(level.getBlockState(POS))) {
|
||||||
return len - 1;
|
return len;
|
||||||
}
|
}
|
||||||
|
POS.move(dir, 1);
|
||||||
}
|
}
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue