From 35cbcde2f909a1ca8b610c52e4ed9944e140fc2d Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 2 Nov 2020 16:15:33 +0300 Subject: [PATCH] Improved erosion --- .../ru/betterend/util/StructureHelper.java | 130 ++++++++++++++++++ .../features/StructureEternalPortal.java | 2 +- .../world/structures/piece/NBTPiece.java | 21 ++- 3 files changed, 150 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/betterend/util/StructureHelper.java b/src/main/java/ru/betterend/util/StructureHelper.java index 9d22cbe9..ce5134bf 100644 --- a/src/main/java/ru/betterend/util/StructureHelper.java +++ b/src/main/java/ru/betterend/util/StructureHelper.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.Random; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtIo; import net.minecraft.server.MinecraftServer; @@ -14,9 +16,15 @@ import net.minecraft.util.BlockRotation; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockBox; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.util.math.Direction; import net.minecraft.world.StructureWorldAccess; +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndTags; public class StructureHelper { + private static final Direction[] DIR = BlocksHelper.makeHorizontal(); + public static Structure readStructure(Identifier resource) { String ns = resource.getNamespace(); String nm = resource.getPath(); @@ -70,4 +78,126 @@ public class StructureHelper { max = max.subtract(min); return new BlockBox(min.add(pos), max.add(pos)); } + + public static void erode(StructureWorldAccess world, BlockBox bounds, int iterations, Random random) { + Mutable mut = new Mutable(); + 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); + if (state.isOf(EndBlocks.FLAVOLITE_RUNED_ETERNAL) && random.nextInt(8) == 0 && world.isAir(mut.down(2))) { + int r = MHelper.randRange(1, 3, random); + int cx = mut.getX(); + int cy = mut.getY(); + int cz = mut.getZ(); + int x1 = mut.getX() - r; + int y1 = mut.getY() - r; + int z1 = mut.getZ() - r; + int x2 = mut.getX() - r; + int y2 = mut.getY() - r; + int z2 = mut.getZ() - 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 && world.getBlockState(mut).isOf(EndBlocks.FLAVOLITE_RUNED_ETERNAL)) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + } + } + } + } + mut.setX(cx); + mut.setY(cy); + mut.setZ(cz); + continue; + } + else if (state.isIn(EndTags.END_GROUND) || state.isOf(EndBlocks.ETERNAL_PEDESTAL) || state.isOf(EndBlocks.FLAVOLITE_RUNED_ETERNAL)) { + continue; + } + if (!state.isAir() && random.nextBoolean()) { + shuffle(random); + for (Direction dir: DIR) { + if (world.isAir(mut.offset(dir)) && world.isAir(mut.down().offset(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.isAir(mut)) { + mut.setY(py); + BlocksHelper.setWithoutUpdate(world, mut, state); + break; + } + } + } + } + break; + } + else if (random.nextInt(8) == 0 && !world.getBlockState(mut.up()).isOf(EndBlocks.ETERNAL_PEDESTAL)) { + 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 (!state.isIn(EndTags.END_GROUND) && !state.isOf(EndBlocks.FLAVOLITE_RUNED_ETERNAL) && !state.isAir() && world.isAir(mut.down())) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + for (int py = mut.getY(); y >= bounds.minY - 10; y--) { + mut.setY(py - 1); + if (!world.isAir(mut)) { + mut.setY(py); + BlocksHelper.setWithoutUpdate(world, mut, state); + break; + } + } + } + } + } + } + } + + private static void shuffle(Random random) { + for (int i = 0; i < 4; i++) { + int j = random.nextInt(4); + Direction d = DIR[i]; + DIR[i] = DIR[j]; + DIR[j] = d; + } + } + + public static void cover(StructureWorldAccess world, BlockBox bounds, Random random) { + Mutable mut = new Mutable(); + 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 = world.getBiome(mut).getGenerationSettings().getSurfaceConfig().getTopMaterial(); + for (int y = bounds.maxY; y >= bounds.minY; y--) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + if (state.isIn(EndTags.END_GROUND) && !world.getBlockState(mut.up()).getMaterial().blocksLight()) { + BlocksHelper.setWithoutUpdate(world, mut, top); + } + } + } + } + } } diff --git a/src/main/java/ru/betterend/world/structures/features/StructureEternalPortal.java b/src/main/java/ru/betterend/world/structures/features/StructureEternalPortal.java index e41202f5..872329a0 100644 --- a/src/main/java/ru/betterend/world/structures/features/StructureEternalPortal.java +++ b/src/main/java/ru/betterend/world/structures/features/StructureEternalPortal.java @@ -37,7 +37,7 @@ public class StructureEternalPortal extends StructureFeatureBase { int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); int y = chunkGenerator.getHeight(x, z, Type.WORLD_SURFACE_WG); if (y > 50) { - this.children.add(new NBTPiece(STRUCTURE_ID, STRUCTURE, new BlockPos(x, y - 3, z), random)); + this.children.add(new NBTPiece(STRUCTURE_ID, STRUCTURE, new BlockPos(x, y - 3, z), 3, true, random)); } this.setBoundingBoxFromChildren(); } diff --git a/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java b/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java index be03d741..71982028 100644 --- a/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java +++ b/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java @@ -25,14 +25,18 @@ public class NBTPiece extends BasePiece { private BlockMirror mirror; private Structure structure; private BlockPos pos; + private int erosion; + private boolean cover; - public NBTPiece(Identifier structureID, Structure structure, BlockPos pos, Random random) { + public NBTPiece(Identifier structureID, Structure structure, BlockPos pos, int erosion, boolean cover, Random random) { super(EndStructures.NBT_PIECE, random.nextInt()); this.structureID = structureID; this.structure = structure; this.rotation = BlockRotation.random(random); this.mirror = BlockMirror.values()[random.nextInt(3)]; this.pos = StructureHelper.offsetPos(pos, structure, rotation, mirror); + this.erosion = erosion; + this.cover = cover; makeBoundingBox(); } @@ -46,7 +50,9 @@ public class NBTPiece extends BasePiece { tag.putString("id", structureID.toString()); tag.putInt("rotation", rotation.ordinal()); tag.putInt("mirror", mirror.ordinal()); + tag.putInt("erosion", erosion); tag.put("pos", NbtHelper.fromBlockPos(pos)); + tag.putBoolean("cover", cover); } @Override @@ -54,14 +60,25 @@ public class NBTPiece extends BasePiece { structureID = new Identifier(tag.getString("id")); rotation = BlockRotation.values()[tag.getInt("rotation")]; mirror = BlockMirror.values()[tag.getInt("mirror")]; + erosion = tag.getInt("erosion"); pos = NbtHelper.toBlockPos(tag.getCompound("pos")); + cover = tag.getBoolean("cover"); structure = StructureHelper.readStructure(structureID); } @Override public boolean generate(StructureWorldAccess world, StructureAccessor arg, ChunkGenerator chunkGenerator, Random random, BlockBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { - StructurePlacementData placementData = new StructurePlacementData().setRotation(rotation).setMirror(mirror).setBoundingBox(blockBox); + BlockBox bounds = new BlockBox(blockBox); + bounds.maxY = this.boundingBox.maxY; + bounds.minY = this.boundingBox.minY; + StructurePlacementData placementData = new StructurePlacementData().setRotation(rotation).setMirror(mirror).setBoundingBox(bounds); structure.place(world, pos, placementData, random); + if (erosion > 0) { + StructureHelper.erode(world, bounds, erosion, random); + } + if (cover) { + StructureHelper.cover(world, bounds, random); + } return true; }