[Feature] Ability to erode Template Structures
This commit is contained in:
parent
65e9140812
commit
0e0b7a5f51
3 changed files with 355 additions and 5 deletions
|
@ -1,15 +1,23 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.structures;
|
package org.betterx.bclib.api.v2.levelgen.structures;
|
||||||
|
|
||||||
import org.betterx.bclib.BCLib;
|
import org.betterx.bclib.BCLib;
|
||||||
|
import org.betterx.bclib.util.MHelper;
|
||||||
|
import org.betterx.bclib.util.StructureErode;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.ServerLevelAccessor;
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
|
import net.minecraft.world.level.StructureManager;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.Mirror;
|
import net.minecraft.world.level.block.Mirror;
|
||||||
import net.minecraft.world.level.block.Rotation;
|
import net.minecraft.world.level.block.Rotation;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||||
import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece;
|
import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece;
|
||||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
||||||
|
@ -20,6 +28,8 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
|
|
||||||
public class TemplatePiece extends TemplateStructurePiece {
|
public class TemplatePiece extends TemplateStructurePiece {
|
||||||
|
private final int erosion;
|
||||||
|
private final boolean cover;
|
||||||
public static final StructurePieceType INSTANCE = setTemplatePieceId(
|
public static final StructurePieceType INSTANCE = setTemplatePieceId(
|
||||||
TemplatePiece::new,
|
TemplatePiece::new,
|
||||||
"template_piece"
|
"template_piece"
|
||||||
|
@ -41,7 +51,6 @@ public class TemplatePiece extends TemplateStructurePiece {
|
||||||
public static void ensureStaticInitialization() {
|
public static void ensureStaticInitialization() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public TemplatePiece(
|
public TemplatePiece(
|
||||||
StructureTemplateManager structureTemplateManager,
|
StructureTemplateManager structureTemplateManager,
|
||||||
ResourceLocation resourceLocation,
|
ResourceLocation resourceLocation,
|
||||||
|
@ -49,6 +58,19 @@ public class TemplatePiece extends TemplateStructurePiece {
|
||||||
Rotation rotation,
|
Rotation rotation,
|
||||||
Mirror mirror,
|
Mirror mirror,
|
||||||
BlockPos halfSize
|
BlockPos halfSize
|
||||||
|
) {
|
||||||
|
this(structureTemplateManager, resourceLocation, centerPos, rotation, mirror, halfSize, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemplatePiece(
|
||||||
|
StructureTemplateManager structureTemplateManager,
|
||||||
|
ResourceLocation resourceLocation,
|
||||||
|
BlockPos centerPos,
|
||||||
|
Rotation rotation,
|
||||||
|
Mirror mirror,
|
||||||
|
BlockPos halfSize,
|
||||||
|
int erosion,
|
||||||
|
boolean cover
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
INSTANCE,
|
INSTANCE,
|
||||||
|
@ -59,6 +81,8 @@ public class TemplatePiece extends TemplateStructurePiece {
|
||||||
makeSettings(rotation, mirror, halfSize),
|
makeSettings(rotation, mirror, halfSize),
|
||||||
shiftPos(rotation, mirror, halfSize, centerPos)
|
shiftPos(rotation, mirror, halfSize, centerPos)
|
||||||
);
|
);
|
||||||
|
this.erosion = erosion;
|
||||||
|
this.cover = cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemplatePiece(StructureTemplateManager structureTemplateManager, CompoundTag compoundTag) {
|
public TemplatePiece(StructureTemplateManager structureTemplateManager, CompoundTag compoundTag) {
|
||||||
|
@ -68,6 +92,15 @@ public class TemplatePiece extends TemplateStructurePiece {
|
||||||
structureTemplateManager,
|
structureTemplateManager,
|
||||||
(ResourceLocation resourceLocation) -> makeSettings(compoundTag)
|
(ResourceLocation resourceLocation) -> makeSettings(compoundTag)
|
||||||
);
|
);
|
||||||
|
if (compoundTag.contains("E"))
|
||||||
|
this.erosion = compoundTag.getInt("E");
|
||||||
|
else
|
||||||
|
this.erosion = 0;
|
||||||
|
|
||||||
|
if (compoundTag.contains("C"))
|
||||||
|
this.cover = compoundTag.getBoolean("C");
|
||||||
|
else
|
||||||
|
this.cover = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockPos shiftPos(
|
private static BlockPos shiftPos(
|
||||||
|
@ -107,6 +140,8 @@ public class TemplatePiece extends TemplateStructurePiece {
|
||||||
tag.putInt("RX", this.placeSettings.getRotationPivot().getX());
|
tag.putInt("RX", this.placeSettings.getRotationPivot().getX());
|
||||||
tag.putInt("RY", this.placeSettings.getRotationPivot().getY());
|
tag.putInt("RY", this.placeSettings.getRotationPivot().getY());
|
||||||
tag.putInt("RZ", this.placeSettings.getRotationPivot().getZ());
|
tag.putInt("RZ", this.placeSettings.getRotationPivot().getZ());
|
||||||
|
tag.putInt("E", this.erosion);
|
||||||
|
tag.putBoolean("C", this.cover);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,4 +154,35 @@ public class TemplatePiece extends TemplateStructurePiece {
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcess(
|
||||||
|
WorldGenLevel world,
|
||||||
|
StructureManager structureManager,
|
||||||
|
ChunkGenerator chunkGenerator,
|
||||||
|
RandomSource random,
|
||||||
|
BoundingBox boundingBox,
|
||||||
|
ChunkPos chunkPos,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
super.postProcess(world, structureManager, chunkGenerator, random, boundingBox, chunkPos, blockPos);
|
||||||
|
BoundingBox bounds = BoundingBox.fromCorners(new Vec3i(
|
||||||
|
this.boundingBox.minX(),
|
||||||
|
this.boundingBox.minY(),
|
||||||
|
this.boundingBox.minZ()
|
||||||
|
), new Vec3i(this.boundingBox.maxX(), this.boundingBox.maxX(), this.boundingBox.maxZ()));
|
||||||
|
|
||||||
|
if (erosion > 0) {
|
||||||
|
int x1 = MHelper.min(bounds.maxX(), this.boundingBox.maxX());
|
||||||
|
int x0 = MHelper.max(bounds.minX(), this.boundingBox.minX());
|
||||||
|
int z1 = MHelper.min(bounds.maxZ(), this.boundingBox.maxZ());
|
||||||
|
int z0 = MHelper.max(bounds.minZ(), this.boundingBox.minZ());
|
||||||
|
bounds = BoundingBox.fromCorners(new Vec3i(x0, bounds.minY(), z0), new Vec3i(x1, bounds.maxY(), z1));
|
||||||
|
StructureErode.erode(world, bounds, erosion, random);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cover) {
|
||||||
|
StructureErode.cover(world, bounds, random, Blocks.END_STONE.defaultBlockState());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public abstract class TemplateStructure extends Structure {
|
public abstract class TemplateStructure extends Structure {
|
||||||
protected final List<Config> configs;
|
protected final List<Config> configs;
|
||||||
|
@ -83,6 +82,14 @@ public abstract class TemplateStructure extends Structure {
|
||||||
return (state == null || state.is(Blocks.AIR)) && before.getMaterial().isSolid();
|
return (state == null || state.is(Blocks.AIR)) && before.getMaterial().isSolid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int erosion(RandomSource rnd) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean cover(RandomSource rnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<GenerationStub> findGenerationPoint(GenerationContext ctx) {
|
public Optional<GenerationStub> findGenerationPoint(GenerationContext ctx) {
|
||||||
WorldGenerationContext worldGenerationContext = new WorldGenerationContext(
|
WorldGenerationContext worldGenerationContext = new WorldGenerationContext(
|
||||||
|
@ -152,8 +159,7 @@ public abstract class TemplateStructure extends Structure {
|
||||||
blockPos.getZ(),
|
blockPos.getZ(),
|
||||||
ctx.heightAccessor(),
|
ctx.heightAccessor(),
|
||||||
ctx.randomState()
|
ctx.randomState()
|
||||||
))
|
)).toList();
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
int y = noiseColumns
|
int y = noiseColumns
|
||||||
.stream()
|
.stream()
|
||||||
|
@ -199,7 +205,9 @@ public abstract class TemplateStructure extends Structure {
|
||||||
),
|
),
|
||||||
rotation,
|
rotation,
|
||||||
mirror,
|
mirror,
|
||||||
halfSize
|
halfSize,
|
||||||
|
erosion(ctx.random()),
|
||||||
|
cover(ctx.random())
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
276
src/main/java/org/betterx/bclib/util/StructureErode.java
Normal file
276
src/main/java/org/betterx/bclib/util/StructureErode.java
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
package org.betterx.bclib.util;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||||
|
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
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.levelgen.structure.BoundingBox;
|
||||||
|
import net.minecraft.world.level.material.Material;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class StructureErode {
|
||||||
|
private static final Direction[] DIR = BlocksHelper.makeHorizontal();
|
||||||
|
|
||||||
|
public static void erode(WorldGenLevel world, BoundingBox bounds, int iterations, RandomSource random) {
|
||||||
|
MutableBlockPos mut = new MutableBlockPos();
|
||||||
|
boolean canDestruct = true;
|
||||||
|
for (int i = 0; i < iterations; i++) {
|
||||||
|
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||||
|
mut.setX(x);
|
||||||
|
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||||
|
mut.setZ(z);
|
||||||
|
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||||
|
mut.setY(y);
|
||||||
|
BlockState state = world.getBlockState(mut);
|
||||||
|
boolean ignore = ignore(state, world, mut);
|
||||||
|
if (canDestruct && BlocksHelper.isInvulnerable(
|
||||||
|
state,
|
||||||
|
world,
|
||||||
|
mut
|
||||||
|
) && random.nextInt(8) == 0 && world.isEmptyBlock(
|
||||||
|
mut.below(2))) {
|
||||||
|
int r = MHelper.randRange(1, 4, random);
|
||||||
|
int cx = mut.getX();
|
||||||
|
int cy = mut.getY();
|
||||||
|
int cz = mut.getZ();
|
||||||
|
int x1 = cx - r;
|
||||||
|
int y1 = cy - r;
|
||||||
|
int z1 = cz - r;
|
||||||
|
int x2 = cx + r;
|
||||||
|
int y2 = cy + r;
|
||||||
|
int z2 = cz + r;
|
||||||
|
for (int px = x1; px <= x2; px++) {
|
||||||
|
int dx = px - cx;
|
||||||
|
dx *= dx;
|
||||||
|
mut.setX(px);
|
||||||
|
for (int py = y1; py <= y2; py++) {
|
||||||
|
int dy = py - cy;
|
||||||
|
dy *= dy;
|
||||||
|
mut.setY(py);
|
||||||
|
for (int pz = z1; pz <= z2; pz++) {
|
||||||
|
int dz = pz - cz;
|
||||||
|
dz *= dz;
|
||||||
|
mut.setZ(pz);
|
||||||
|
if (dx + dy + dz <= r && BlocksHelper.isInvulnerable(
|
||||||
|
world.getBlockState(mut),
|
||||||
|
world,
|
||||||
|
mut
|
||||||
|
)) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mut.setX(cx);
|
||||||
|
mut.setY(cy);
|
||||||
|
mut.setZ(cz);
|
||||||
|
canDestruct = false;
|
||||||
|
continue;
|
||||||
|
} else if (ignore) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!state.isAir() && random.nextBoolean()) {
|
||||||
|
MHelper.shuffle(DIR, random);
|
||||||
|
for (Direction dir : DIR) {
|
||||||
|
if (world.isEmptyBlock(mut.relative(dir)) && world.isEmptyBlock(mut.below()
|
||||||
|
.relative(dir))) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||||
|
mut.move(dir).move(Direction.DOWN);
|
||||||
|
for (int py = mut.getY(); y >= bounds.minY() - 10; y--) {
|
||||||
|
mut.setY(py - 1);
|
||||||
|
if (!world.isEmptyBlock(mut)) {
|
||||||
|
mut.setY(py);
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (random.nextInt(8) == 0 && !BlocksHelper.isInvulnerable(
|
||||||
|
world.getBlockState(mut.above()),
|
||||||
|
world,
|
||||||
|
mut
|
||||||
|
)) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||||
|
mut.setX(x);
|
||||||
|
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||||
|
mut.setZ(z);
|
||||||
|
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||||
|
mut.setY(y);
|
||||||
|
BlockState state = world.getBlockState(mut);
|
||||||
|
if (!ignore(state, world, mut) && world.isEmptyBlock(mut.below())) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||||
|
for (int py = mut.getY(); py >= bounds.minY() - 10; py--) {
|
||||||
|
mut.setY(py - 1);
|
||||||
|
if (!world.isEmptyBlock(mut)) {
|
||||||
|
mut.setY(py);
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void erodeIntense(WorldGenLevel world, BoundingBox bounds, RandomSource random) {
|
||||||
|
MutableBlockPos mut = new MutableBlockPos();
|
||||||
|
MutableBlockPos mut2 = new MutableBlockPos();
|
||||||
|
int minY = bounds.minY() - 10;
|
||||||
|
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||||
|
mut.setX(x);
|
||||||
|
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||||
|
mut.setZ(z);
|
||||||
|
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||||
|
mut.setY(y);
|
||||||
|
BlockState state = world.getBlockState(mut);
|
||||||
|
if (!ignore(state, world, mut)) {
|
||||||
|
if (random.nextInt(6) == 0) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||||
|
if (random.nextBoolean()) {
|
||||||
|
int px = MHelper.floor(random.nextGaussian() * 2 + x + 0.5);
|
||||||
|
int pz = MHelper.floor(random.nextGaussian() * 2 + z + 0.5);
|
||||||
|
mut2.set(px, y, pz);
|
||||||
|
while (world.getBlockState(mut2).getMaterial().isReplaceable() && mut2.getY() > minY) {
|
||||||
|
mut2.setY(mut2.getY() - 1);
|
||||||
|
}
|
||||||
|
if (!world.getBlockState(mut2).isAir() && state.canSurvive(world, mut2)) {
|
||||||
|
mut2.setY(mut2.getY() + 1);
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut2, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (random.nextInt(8) == 0) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(world, bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void drop(WorldGenLevel world, BoundingBox bounds) {
|
||||||
|
MutableBlockPos mut = new MutableBlockPos();
|
||||||
|
|
||||||
|
Set<BlockPos> blocks = Sets.newHashSet();
|
||||||
|
Set<BlockPos> edge = Sets.newHashSet();
|
||||||
|
Set<BlockPos> add = Sets.newHashSet();
|
||||||
|
|
||||||
|
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||||
|
mut.setX(x);
|
||||||
|
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||||
|
mut.setZ(z);
|
||||||
|
for (int y = bounds.minY(); y <= bounds.maxY(); y++) {
|
||||||
|
mut.setY(y);
|
||||||
|
BlockState state = world.getBlockState(mut);
|
||||||
|
if (!ignore(state, world, mut) && isTerrainNear(world, mut)) {
|
||||||
|
edge.add(mut.immutable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!edge.isEmpty()) {
|
||||||
|
for (BlockPos center : edge) {
|
||||||
|
for (Direction dir : BlocksHelper.DIRECTIONS) {
|
||||||
|
BlockState state = world.getBlockState(center);
|
||||||
|
if (state.isCollisionShapeFullBlock(world, center)) {
|
||||||
|
mut.set(center).move(dir);
|
||||||
|
if (bounds.isInside(mut)) {
|
||||||
|
state = world.getBlockState(mut);
|
||||||
|
if (!ignore(state, world, mut) && !blocks.contains(mut)) {
|
||||||
|
add.add(mut.immutable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks.addAll(edge);
|
||||||
|
edge.clear();
|
||||||
|
edge.addAll(add);
|
||||||
|
add.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int minY = bounds.minY() - 10;
|
||||||
|
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||||
|
mut.setX(x);
|
||||||
|
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||||
|
mut.setZ(z);
|
||||||
|
for (int y = bounds.minY(); y <= bounds.maxY(); y++) {
|
||||||
|
mut.setY(y);
|
||||||
|
BlockState state = world.getBlockState(mut);
|
||||||
|
if (!ignore(state, world, mut) && !blocks.contains(mut)) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||||
|
while (world.getBlockState(mut).getMaterial().isReplaceable() && mut.getY() > minY) {
|
||||||
|
mut.setY(mut.getY() - 1);
|
||||||
|
}
|
||||||
|
if (mut.getY() > minY) {
|
||||||
|
mut.setY(mut.getY() + 1);
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean ignore(BlockState state, WorldGenLevel world, BlockPos pos) {
|
||||||
|
if (state.is(CommonBlockTags.GEN_END_STONES) || state.is(BlockTags.NYLIUM)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !state.getMaterial().equals(Material.STONE) || BlocksHelper.isInvulnerable(state, world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isTerrainNear(WorldGenLevel world, BlockPos pos) {
|
||||||
|
for (Direction dir : BlocksHelper.DIRECTIONS) {
|
||||||
|
if (world.getBlockState(pos.relative(dir)).is(CommonBlockTags.GEN_END_STONES)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cover(WorldGenLevel world, BoundingBox bounds, RandomSource random, BlockState defaultBlock) {
|
||||||
|
MutableBlockPos mut = new MutableBlockPos();
|
||||||
|
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||||
|
mut.setX(x);
|
||||||
|
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||||
|
mut.setZ(z);
|
||||||
|
BlockState top = BiomeAPI.findTopMaterial(world.getBiome(mut)).orElse(defaultBlock);
|
||||||
|
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||||
|
mut.setY(y);
|
||||||
|
BlockState state = world.getBlockState(mut);
|
||||||
|
if (state.is(CommonBlockTags.TERRAIN) && !world.getBlockState(mut.above())
|
||||||
|
.getMaterial()
|
||||||
|
.isSolidBlocking()) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, mut, top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue