Added Warp Cap Feature

This commit is contained in:
Frank 2022-06-03 11:31:56 +02:00
parent 3a61c4cb86
commit f82d8b6178
4 changed files with 82 additions and 42 deletions

View file

@ -275,6 +275,10 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
return modifier(new FindSolidInDirection(dir, distance));
}
public BCLFeatureBuilder findSolidSurface(List<Direction> dir, int distance) {
return modifier(new FindSolidInDirection(dir, distance));
}
public BCLFeatureBuilder heightmap() {
return modifier(PlacementUtils.HEIGHTMAP);
}

View file

@ -87,7 +87,8 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
if (direction.isEmpty()) {
return false;
}
BlockPos basePos = origin.relative(direction.get().getOpposite());
BlockPos basePos = origin.relative(direction.get(), -1);
int i = (int) (random.nextFloat() * (1 + config.maxHeight - config.minHeight) + config.minHeight);
growCenterPillar(level, origin, basePos, direction.get(), i, config, random);
@ -105,10 +106,8 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
if (config.isValidBase(level.getBlockState(basePos))) {
final Direction surfaceDirection = direction.getOpposite();
BlockPos.MutableBlockPos POS = new BlockPos.MutableBlockPos();
basePos = basePos.relative(direction, 1);
buildPillarWithBase(level, origin, basePos, direction, centerHeight, config, random);
final double distNormalizer = (config.maxSpread * Math.sqrt(2));
final int tryCount = config.spreadCount.sample(random);
for (int i = 0; i < tryCount; i++) {

View file

@ -2,6 +2,7 @@ package org.betterx.bclib.api.features.placement;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.placement.PlacementContext;
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
@ -12,20 +13,30 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.util.BlocksHelper;
import java.util.List;
import java.util.stream.Stream;
public class FindSolidInDirection extends PlacementModifier {
public static final Codec<FindSolidInDirection> CODEC = RecordCodecBuilder
.create((instance) -> instance.group(
ExtraCodecs.nonEmptyList(Direction.CODEC.listOf())
.fieldOf("dir")
.orElse(List.of(Direction.DOWN))
.forGetter(a -> a.direction),
Codec.intRange(1, 32).fieldOf("dist").orElse(12).forGetter((p) -> p.maxSearchDistance))
.apply(instance,
FindSolidInDirection::new));
protected static final FindSolidInDirection DOWN = new FindSolidInDirection(Direction.DOWN, 6);
protected static final FindSolidInDirection UP = new FindSolidInDirection(Direction.UP, 6);
public static final Codec<FindSolidInDirection> CODEC = RecordCodecBuilder.create((instance) -> instance
.group(
Direction.CODEC.fieldOf("dir").orElse(Direction.DOWN).forGetter((p) -> p.direction),
Codec.intRange(1, 32).fieldOf("dist").orElse(12).forGetter((p) -> p.maxSearchDistance)
)
.apply(instance, FindSolidInDirection::new));
private final List<Direction> direction;
private final int maxSearchDistance;
public FindSolidInDirection(Direction direction, int maxSearchDistance) {
this(List.of(direction), maxSearchDistance);
}
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance) {
this.direction = direction;
this.maxSearchDistance = maxSearchDistance;
}
@ -48,25 +59,26 @@ public class FindSolidInDirection extends PlacementModifier {
return new FindSolidInDirection(Direction.UP, dist);
}
public Direction randomDirection(RandomSource random) {
return direction.get(Math.max(0, Math.min(direction.size(), random.nextInt(direction.size()))));
}
@Override
public Stream<BlockPos> getPositions(PlacementContext placementContext,
RandomSource randomSource,
BlockPos blockPos) {
BlockPos.MutableBlockPos POS = blockPos.mutable();
if (BlocksHelper.findSurroundingSurface(placementContext.getLevel(),
Direction d = randomDirection(randomSource);
if (BlocksHelper.findOnSurroundingSurface(placementContext.getLevel(),
POS,
direction,
d,
maxSearchDistance,
state -> state.is(CommonBlockTags.TERRAIN))
) return Stream.of(POS);
state -> state.is(CommonBlockTags.TERRAIN)))
return Stream.of(POS);
return Stream.of();
}
private final Direction direction;
private final int maxSearchDistance;
@Override
public PlacementModifierType<?> type() {
return PlacementModifiers.SOLID_IN_DIR;

View file

@ -229,6 +229,31 @@ public class BlocksHelper {
return false;
}
public static boolean findOnSurroundingSurface(LevelAccessor level,
MutableBlockPos startPos,
Direction dir,
int length,
Predicate<BlockState> surface) {
for (int len = 0; len < length; len++) {
if (surface.test(level.getBlockState(startPos))) {
if (len == 0) { //we started inside of the surface
for (int lenUp = 0; lenUp < length; lenUp++) {
startPos.move(dir, -1);
if (!surface.test(level.getBlockState(startPos))) {
return true;
}
}
return false;
}
startPos.move(dir, -1);
return true;
}
startPos.move(dir, 1);
}
return false;
}
public static boolean findSurroundingSurface(LevelAccessor level,
MutableBlockPos startPos,
Direction dir,