1046 lines
39 KiB
Java
1046 lines
39 KiB
Java
package net.minecraft.world.level.levelgen.structure.structures;
|
|
|
|
import com.google.common.collect.Lists;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.resources.ResourceKey;
|
|
import net.minecraft.tags.BiomeTags;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.entity.EntitySpawnReason;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.vehicle.MinecartChest;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import net.minecraft.world.level.ChunkPos;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.level.LevelReader;
|
|
import net.minecraft.world.level.StructureManager;
|
|
import net.minecraft.world.level.WorldGenLevel;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.Blocks;
|
|
import net.minecraft.world.level.block.FallingBlock;
|
|
import net.minecraft.world.level.block.FenceBlock;
|
|
import net.minecraft.world.level.block.RailBlock;
|
|
import net.minecraft.world.level.block.WallTorchBlock;
|
|
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.block.state.properties.RailShape;
|
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
|
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
|
import net.minecraft.world.level.levelgen.structure.StructurePieceAccessor;
|
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
|
|
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
|
|
import net.minecraft.world.level.storage.loot.LootTable;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public class MineshaftPieces {
|
|
private static final int DEFAULT_SHAFT_WIDTH = 3;
|
|
private static final int DEFAULT_SHAFT_HEIGHT = 3;
|
|
private static final int DEFAULT_SHAFT_LENGTH = 5;
|
|
private static final int MAX_PILLAR_HEIGHT = 20;
|
|
private static final int MAX_CHAIN_HEIGHT = 50;
|
|
private static final int MAX_DEPTH = 8;
|
|
public static final int MAGIC_START_Y = 50;
|
|
|
|
private static MineshaftPieces.MineShaftPiece createRandomShaftPiece(
|
|
StructurePieceAccessor pieces, RandomSource random, int x, int y, int z, @Nullable Direction orientation, int genDepth, MineshaftStructure.Type type
|
|
) {
|
|
int i = random.nextInt(100);
|
|
if (i >= 80) {
|
|
BoundingBox boundingBox = MineshaftPieces.MineShaftCrossing.findCrossing(pieces, random, x, y, z, orientation);
|
|
if (boundingBox != null) {
|
|
return new MineshaftPieces.MineShaftCrossing(genDepth, boundingBox, orientation, type);
|
|
}
|
|
} else if (i >= 70) {
|
|
BoundingBox boundingBox = MineshaftPieces.MineShaftStairs.findStairs(pieces, random, x, y, z, orientation);
|
|
if (boundingBox != null) {
|
|
return new MineshaftPieces.MineShaftStairs(genDepth, boundingBox, orientation, type);
|
|
}
|
|
} else {
|
|
BoundingBox boundingBox = MineshaftPieces.MineShaftCorridor.findCorridorSize(pieces, random, x, y, z, orientation);
|
|
if (boundingBox != null) {
|
|
return new MineshaftPieces.MineShaftCorridor(genDepth, random, boundingBox, orientation, type);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
static MineshaftPieces.MineShaftPiece generateAndAddPiece(
|
|
StructurePiece piece, StructurePieceAccessor pieces, RandomSource random, int x, int y, int z, Direction direction, int genDepth
|
|
) {
|
|
if (genDepth > 8) {
|
|
return null;
|
|
} else if (Math.abs(x - piece.getBoundingBox().minX()) <= 80 && Math.abs(z - piece.getBoundingBox().minZ()) <= 80) {
|
|
MineshaftStructure.Type type = ((MineshaftPieces.MineShaftPiece)piece).type;
|
|
MineshaftPieces.MineShaftPiece mineShaftPiece = createRandomShaftPiece(pieces, random, x, y, z, direction, genDepth + 1, type);
|
|
if (mineShaftPiece != null) {
|
|
pieces.addPiece(mineShaftPiece);
|
|
mineShaftPiece.addChildren(piece, pieces, random);
|
|
}
|
|
|
|
return mineShaftPiece;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static class MineShaftCorridor extends MineshaftPieces.MineShaftPiece {
|
|
private final boolean hasRails;
|
|
private final boolean spiderCorridor;
|
|
private boolean hasPlacedSpider;
|
|
private final int numSections;
|
|
|
|
public MineShaftCorridor(CompoundTag tag) {
|
|
super(StructurePieceType.MINE_SHAFT_CORRIDOR, tag);
|
|
this.hasRails = tag.getBooleanOr("hr", false);
|
|
this.spiderCorridor = tag.getBooleanOr("sc", false);
|
|
this.hasPlacedSpider = tag.getBooleanOr("hps", false);
|
|
this.numSections = tag.getIntOr("Num", 0);
|
|
}
|
|
|
|
@Override
|
|
protected void addAdditionalSaveData(StructurePieceSerializationContext context, CompoundTag tag) {
|
|
super.addAdditionalSaveData(context, tag);
|
|
tag.putBoolean("hr", this.hasRails);
|
|
tag.putBoolean("sc", this.spiderCorridor);
|
|
tag.putBoolean("hps", this.hasPlacedSpider);
|
|
tag.putInt("Num", this.numSections);
|
|
}
|
|
|
|
public MineShaftCorridor(int genDepth, RandomSource random, BoundingBox boundingBox, Direction orientation, MineshaftStructure.Type type) {
|
|
super(StructurePieceType.MINE_SHAFT_CORRIDOR, genDepth, type, boundingBox);
|
|
this.setOrientation(orientation);
|
|
this.hasRails = random.nextInt(3) == 0;
|
|
this.spiderCorridor = !this.hasRails && random.nextInt(23) == 0;
|
|
if (this.getOrientation().getAxis() == Direction.Axis.Z) {
|
|
this.numSections = boundingBox.getZSpan() / 5;
|
|
} else {
|
|
this.numSections = boundingBox.getXSpan() / 5;
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
public static BoundingBox findCorridorSize(StructurePieceAccessor pieces, RandomSource random, int x, int y, int z, Direction direction) {
|
|
for (int i = random.nextInt(3) + 2; i > 0; i--) {
|
|
int j = i * 5;
|
|
|
|
BoundingBox boundingBox = switch (direction) {
|
|
default -> new BoundingBox(0, 0, -(j - 1), 2, 2, 0);
|
|
case SOUTH -> new BoundingBox(0, 0, 0, 2, 2, j - 1);
|
|
case WEST -> new BoundingBox(-(j - 1), 0, 0, 0, 2, 2);
|
|
case EAST -> new BoundingBox(0, 0, 0, j - 1, 2, 2);
|
|
};
|
|
boundingBox.move(x, y, z);
|
|
if (pieces.findCollisionPiece(boundingBox) == null) {
|
|
return boundingBox;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void addChildren(StructurePiece piece, StructurePieceAccessor pieces, RandomSource random) {
|
|
int i = this.getGenDepth();
|
|
int j = random.nextInt(4);
|
|
Direction direction = this.getOrientation();
|
|
if (direction != null) {
|
|
switch (direction) {
|
|
case NORTH:
|
|
default:
|
|
if (j <= 1) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX(), this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.minZ() - 1, direction, i
|
|
);
|
|
} else if (j == 2) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.minZ(), Direction.WEST, i
|
|
);
|
|
} else {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.minZ(), Direction.EAST, i
|
|
);
|
|
}
|
|
break;
|
|
case SOUTH:
|
|
if (j <= 1) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX(), this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.maxZ() + 1, direction, i
|
|
);
|
|
} else if (j == 2) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.maxZ() - 3, Direction.WEST, i
|
|
);
|
|
} else {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.maxZ() - 3, Direction.EAST, i
|
|
);
|
|
}
|
|
break;
|
|
case WEST:
|
|
if (j <= 1) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.minZ(), direction, i
|
|
);
|
|
} else if (j == 2) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX(), this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
} else {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX(), this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
}
|
|
break;
|
|
case EAST:
|
|
if (j <= 1) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.minZ(), direction, i
|
|
);
|
|
} else if (j == 2) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() - 3, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
} else {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() - 3, this.boundingBox.minY() - 1 + random.nextInt(3), this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (i < 8) {
|
|
if (direction != Direction.NORTH && direction != Direction.SOUTH) {
|
|
for (int k = this.boundingBox.minX() + 3; k + 3 <= this.boundingBox.maxX(); k += 5) {
|
|
int l = random.nextInt(5);
|
|
if (l == 0) {
|
|
MineshaftPieces.generateAndAddPiece(piece, pieces, random, k, this.boundingBox.minY(), this.boundingBox.minZ() - 1, Direction.NORTH, i + 1);
|
|
} else if (l == 1) {
|
|
MineshaftPieces.generateAndAddPiece(piece, pieces, random, k, this.boundingBox.minY(), this.boundingBox.maxZ() + 1, Direction.SOUTH, i + 1);
|
|
}
|
|
}
|
|
} else {
|
|
for (int kx = this.boundingBox.minZ() + 3; kx + 3 <= this.boundingBox.maxZ(); kx += 5) {
|
|
int l = random.nextInt(5);
|
|
if (l == 0) {
|
|
MineshaftPieces.generateAndAddPiece(piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY(), kx, Direction.WEST, i + 1);
|
|
} else if (l == 1) {
|
|
MineshaftPieces.generateAndAddPiece(piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY(), kx, Direction.EAST, i + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected boolean createChest(WorldGenLevel level, BoundingBox box, RandomSource random, int x, int y, int z, ResourceKey<LootTable> lootTable) {
|
|
BlockPos blockPos = this.getWorldPos(x, y, z);
|
|
if (box.isInside(blockPos) && level.getBlockState(blockPos).isAir() && !level.getBlockState(blockPos.below()).isAir()) {
|
|
BlockState blockState = Blocks.RAIL.defaultBlockState().setValue(RailBlock.SHAPE, random.nextBoolean() ? RailShape.NORTH_SOUTH : RailShape.EAST_WEST);
|
|
this.placeBlock(level, blockState, x, y, z, box);
|
|
MinecartChest minecartChest = EntityType.CHEST_MINECART.create(level.getLevel(), EntitySpawnReason.CHUNK_GENERATION);
|
|
if (minecartChest != null) {
|
|
minecartChest.setInitialPos(blockPos.getX() + 0.5, blockPos.getY() + 0.5, blockPos.getZ() + 0.5);
|
|
minecartChest.setLootTable(lootTable, random.nextLong());
|
|
level.addFreshEntity(minecartChest);
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void postProcess(
|
|
WorldGenLevel level, StructureManager structureManager, ChunkGenerator generator, RandomSource random, BoundingBox box, ChunkPos chunkPos, BlockPos pos
|
|
) {
|
|
if (!this.isInInvalidLocation(level, box)) {
|
|
int i = 0;
|
|
int j = 2;
|
|
int k = 0;
|
|
int l = 2;
|
|
int m = this.numSections * 5 - 1;
|
|
BlockState blockState = this.type.getPlanksState();
|
|
this.generateBox(level, box, 0, 0, 0, 2, 1, m, CAVE_AIR, CAVE_AIR, false);
|
|
this.generateMaybeBox(level, box, random, 0.8F, 0, 2, 0, 2, 2, m, CAVE_AIR, CAVE_AIR, false, false);
|
|
if (this.spiderCorridor) {
|
|
this.generateMaybeBox(level, box, random, 0.6F, 0, 0, 0, 2, 1, m, Blocks.COBWEB.defaultBlockState(), CAVE_AIR, false, true);
|
|
}
|
|
|
|
for (int n = 0; n < this.numSections; n++) {
|
|
int o = 2 + n * 5;
|
|
this.placeSupport(level, box, 0, 0, o, 2, 2, random);
|
|
this.maybePlaceCobWeb(level, box, random, 0.1F, 0, 2, o - 1);
|
|
this.maybePlaceCobWeb(level, box, random, 0.1F, 2, 2, o - 1);
|
|
this.maybePlaceCobWeb(level, box, random, 0.1F, 0, 2, o + 1);
|
|
this.maybePlaceCobWeb(level, box, random, 0.1F, 2, 2, o + 1);
|
|
this.maybePlaceCobWeb(level, box, random, 0.05F, 0, 2, o - 2);
|
|
this.maybePlaceCobWeb(level, box, random, 0.05F, 2, 2, o - 2);
|
|
this.maybePlaceCobWeb(level, box, random, 0.05F, 0, 2, o + 2);
|
|
this.maybePlaceCobWeb(level, box, random, 0.05F, 2, 2, o + 2);
|
|
if (random.nextInt(100) == 0) {
|
|
this.createChest(level, box, random, 2, 0, o - 1, BuiltInLootTables.ABANDONED_MINESHAFT);
|
|
}
|
|
|
|
if (random.nextInt(100) == 0) {
|
|
this.createChest(level, box, random, 0, 0, o + 1, BuiltInLootTables.ABANDONED_MINESHAFT);
|
|
}
|
|
|
|
if (this.spiderCorridor && !this.hasPlacedSpider) {
|
|
int p = 1;
|
|
int q = o - 1 + random.nextInt(3);
|
|
BlockPos blockPos = this.getWorldPos(1, 0, q);
|
|
if (box.isInside(blockPos) && this.isInterior(level, 1, 0, q, box)) {
|
|
this.hasPlacedSpider = true;
|
|
level.setBlock(blockPos, Blocks.SPAWNER.defaultBlockState(), 2);
|
|
if (level.getBlockEntity(blockPos) instanceof SpawnerBlockEntity spawnerBlockEntity) {
|
|
spawnerBlockEntity.setEntityId(EntityType.CAVE_SPIDER, random);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int n = 0; n <= 2; n++) {
|
|
for (int ox = 0; ox <= m; ox++) {
|
|
this.setPlanksBlock(level, box, blockState, n, -1, ox);
|
|
}
|
|
}
|
|
|
|
int n = 2;
|
|
this.placeDoubleLowerOrUpperSupport(level, box, 0, -1, 2);
|
|
if (this.numSections > 1) {
|
|
int ox = m - 2;
|
|
this.placeDoubleLowerOrUpperSupport(level, box, 0, -1, ox);
|
|
}
|
|
|
|
if (this.hasRails) {
|
|
BlockState blockState2 = Blocks.RAIL.defaultBlockState().setValue(RailBlock.SHAPE, RailShape.NORTH_SOUTH);
|
|
|
|
for (int p = 0; p <= m; p++) {
|
|
BlockState blockState3 = this.getBlock(level, 1, -1, p, box);
|
|
if (!blockState3.isAir() && blockState3.isSolidRender()) {
|
|
float f = this.isInterior(level, 1, 0, p, box) ? 0.7F : 0.9F;
|
|
this.maybeGenerateBlock(level, box, random, f, 1, 0, p, blockState2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void placeDoubleLowerOrUpperSupport(WorldGenLevel level, BoundingBox box, int x, int y, int z) {
|
|
BlockState blockState = this.type.getWoodState();
|
|
BlockState blockState2 = this.type.getPlanksState();
|
|
if (this.getBlock(level, x, y, z, box).is(blockState2.getBlock())) {
|
|
this.fillPillarDownOrChainUp(level, blockState, x, y, z, box);
|
|
}
|
|
|
|
if (this.getBlock(level, x + 2, y, z, box).is(blockState2.getBlock())) {
|
|
this.fillPillarDownOrChainUp(level, blockState, x + 2, y, z, box);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void fillColumnDown(WorldGenLevel level, BlockState state, int x, int y, int z, BoundingBox box) {
|
|
BlockPos.MutableBlockPos mutableBlockPos = this.getWorldPos(x, y, z);
|
|
if (box.isInside(mutableBlockPos)) {
|
|
int i = mutableBlockPos.getY();
|
|
|
|
while (this.isReplaceableByStructures(level.getBlockState(mutableBlockPos)) && mutableBlockPos.getY() > level.getMinY() + 1) {
|
|
mutableBlockPos.move(Direction.DOWN);
|
|
}
|
|
|
|
if (this.canPlaceColumnOnTopOf(level, mutableBlockPos, level.getBlockState(mutableBlockPos))) {
|
|
while (mutableBlockPos.getY() < i) {
|
|
mutableBlockPos.move(Direction.UP);
|
|
level.setBlock(mutableBlockPos, state, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void fillPillarDownOrChainUp(WorldGenLevel level, BlockState state, int x, int y, int z, BoundingBox box) {
|
|
BlockPos.MutableBlockPos mutableBlockPos = this.getWorldPos(x, y, z);
|
|
if (box.isInside(mutableBlockPos)) {
|
|
int i = mutableBlockPos.getY();
|
|
int j = 1;
|
|
boolean bl = true;
|
|
|
|
for (boolean bl2 = true; bl || bl2; j++) {
|
|
if (bl) {
|
|
mutableBlockPos.setY(i - j);
|
|
BlockState blockState = level.getBlockState(mutableBlockPos);
|
|
boolean bl3 = this.isReplaceableByStructures(blockState) && !blockState.is(Blocks.LAVA);
|
|
if (!bl3 && this.canPlaceColumnOnTopOf(level, mutableBlockPos, blockState)) {
|
|
fillColumnBetween(level, state, mutableBlockPos, i - j + 1, i);
|
|
return;
|
|
}
|
|
|
|
bl = j <= 20 && bl3 && mutableBlockPos.getY() > level.getMinY() + 1;
|
|
}
|
|
|
|
if (bl2) {
|
|
mutableBlockPos.setY(i + j);
|
|
BlockState blockState = level.getBlockState(mutableBlockPos);
|
|
boolean bl3 = this.isReplaceableByStructures(blockState);
|
|
if (!bl3 && this.canHangChainBelow(level, mutableBlockPos, blockState)) {
|
|
level.setBlock(mutableBlockPos.setY(i + 1), this.type.getFenceState(), 2);
|
|
fillColumnBetween(level, Blocks.CHAIN.defaultBlockState(), mutableBlockPos, i + 2, i + j);
|
|
return;
|
|
}
|
|
|
|
bl2 = j <= 50 && bl3 && mutableBlockPos.getY() < level.getMaxY();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void fillColumnBetween(WorldGenLevel level, BlockState state, BlockPos.MutableBlockPos pos, int minY, int maxY) {
|
|
for (int i = minY; i < maxY; i++) {
|
|
level.setBlock(pos.setY(i), state, 2);
|
|
}
|
|
}
|
|
|
|
private boolean canPlaceColumnOnTopOf(LevelReader level, BlockPos pos, BlockState state) {
|
|
return state.isFaceSturdy(level, pos, Direction.UP);
|
|
}
|
|
|
|
private boolean canHangChainBelow(LevelReader level, BlockPos pos, BlockState state) {
|
|
return Block.canSupportCenter(level, pos, Direction.DOWN) && !(state.getBlock() instanceof FallingBlock);
|
|
}
|
|
|
|
private void placeSupport(WorldGenLevel level, BoundingBox box, int minX, int minY, int z, int maxY, int maxX, RandomSource random) {
|
|
if (this.isSupportingBox(level, box, minX, maxX, maxY, z)) {
|
|
BlockState blockState = this.type.getPlanksState();
|
|
BlockState blockState2 = this.type.getFenceState();
|
|
this.generateBox(level, box, minX, minY, z, minX, maxY - 1, z, blockState2.setValue(FenceBlock.WEST, true), CAVE_AIR, false);
|
|
this.generateBox(level, box, maxX, minY, z, maxX, maxY - 1, z, blockState2.setValue(FenceBlock.EAST, true), CAVE_AIR, false);
|
|
if (random.nextInt(4) == 0) {
|
|
this.generateBox(level, box, minX, maxY, z, minX, maxY, z, blockState, CAVE_AIR, false);
|
|
this.generateBox(level, box, maxX, maxY, z, maxX, maxY, z, blockState, CAVE_AIR, false);
|
|
} else {
|
|
this.generateBox(level, box, minX, maxY, z, maxX, maxY, z, blockState, CAVE_AIR, false);
|
|
this.maybeGenerateBlock(
|
|
level, box, random, 0.05F, minX + 1, maxY, z - 1, Blocks.WALL_TORCH.defaultBlockState().setValue(WallTorchBlock.FACING, Direction.SOUTH)
|
|
);
|
|
this.maybeGenerateBlock(
|
|
level, box, random, 0.05F, minX + 1, maxY, z + 1, Blocks.WALL_TORCH.defaultBlockState().setValue(WallTorchBlock.FACING, Direction.NORTH)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void maybePlaceCobWeb(WorldGenLevel level, BoundingBox box, RandomSource random, float chance, int x, int y, int z) {
|
|
if (this.isInterior(level, x, y, z, box) && random.nextFloat() < chance && this.hasSturdyNeighbours(level, box, x, y, z, 2)) {
|
|
this.placeBlock(level, Blocks.COBWEB.defaultBlockState(), x, y, z, box);
|
|
}
|
|
}
|
|
|
|
private boolean hasSturdyNeighbours(WorldGenLevel level, BoundingBox box, int x, int y, int z, int required) {
|
|
BlockPos.MutableBlockPos mutableBlockPos = this.getWorldPos(x, y, z);
|
|
int i = 0;
|
|
|
|
for (Direction direction : Direction.values()) {
|
|
mutableBlockPos.move(direction);
|
|
if (box.isInside(mutableBlockPos) && level.getBlockState(mutableBlockPos).isFaceSturdy(level, mutableBlockPos, direction.getOpposite())) {
|
|
if (++i >= required) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
mutableBlockPos.move(direction.getOpposite());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static class MineShaftCrossing extends MineshaftPieces.MineShaftPiece {
|
|
private final Direction direction;
|
|
private final boolean isTwoFloored;
|
|
|
|
public MineShaftCrossing(CompoundTag tag) {
|
|
super(StructurePieceType.MINE_SHAFT_CROSSING, tag);
|
|
this.isTwoFloored = tag.getBooleanOr("tf", false);
|
|
this.direction = (Direction)tag.read("D", Direction.LEGACY_ID_CODEC_2D).orElse(Direction.SOUTH);
|
|
}
|
|
|
|
@Override
|
|
protected void addAdditionalSaveData(StructurePieceSerializationContext context, CompoundTag tag) {
|
|
super.addAdditionalSaveData(context, tag);
|
|
tag.putBoolean("tf", this.isTwoFloored);
|
|
tag.store("D", Direction.LEGACY_ID_CODEC_2D, this.direction);
|
|
}
|
|
|
|
public MineShaftCrossing(int genDepth, BoundingBox boundingBox, @Nullable Direction direction, MineshaftStructure.Type type) {
|
|
super(StructurePieceType.MINE_SHAFT_CROSSING, genDepth, type, boundingBox);
|
|
this.direction = direction;
|
|
this.isTwoFloored = boundingBox.getYSpan() > 3;
|
|
}
|
|
|
|
@Nullable
|
|
public static BoundingBox findCrossing(StructurePieceAccessor pieces, RandomSource random, int x, int y, int z, Direction direction) {
|
|
int i;
|
|
if (random.nextInt(4) == 0) {
|
|
i = 6;
|
|
} else {
|
|
i = 2;
|
|
}
|
|
BoundingBox boundingBox = switch (direction) {
|
|
default -> new BoundingBox(-1, 0, -4, 3, i, 0);
|
|
case SOUTH -> new BoundingBox(-1, 0, 0, 3, i, 4);
|
|
case WEST -> new BoundingBox(-4, 0, -1, 0, i, 3);
|
|
case EAST -> new BoundingBox(0, 0, -1, 4, i, 3);
|
|
};
|
|
boundingBox.move(x, y, z);
|
|
return pieces.findCollisionPiece(boundingBox) != null ? null : boundingBox;
|
|
}
|
|
|
|
@Override
|
|
public void addChildren(StructurePiece piece, StructurePieceAccessor pieces, RandomSource random) {
|
|
int i = this.getGenDepth();
|
|
switch (this.direction) {
|
|
case NORTH:
|
|
default:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, Direction.WEST, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, Direction.EAST, i
|
|
);
|
|
break;
|
|
case SOUTH:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, Direction.WEST, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, Direction.EAST, i
|
|
);
|
|
break;
|
|
case WEST:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, Direction.WEST, i
|
|
);
|
|
break;
|
|
case EAST:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, Direction.EAST, i
|
|
);
|
|
}
|
|
|
|
if (this.isTwoFloored) {
|
|
if (random.nextBoolean()) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY() + 3 + 1, this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
}
|
|
|
|
if (random.nextBoolean()) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY() + 3 + 1, this.boundingBox.minZ() + 1, Direction.WEST, i
|
|
);
|
|
}
|
|
|
|
if (random.nextBoolean()) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() + 3 + 1, this.boundingBox.minZ() + 1, Direction.EAST, i
|
|
);
|
|
}
|
|
|
|
if (random.nextBoolean()) {
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + 1, this.boundingBox.minY() + 3 + 1, this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void postProcess(
|
|
WorldGenLevel level, StructureManager structureManager, ChunkGenerator generator, RandomSource random, BoundingBox box, ChunkPos chunkPos, BlockPos pos
|
|
) {
|
|
if (!this.isInInvalidLocation(level, box)) {
|
|
BlockState blockState = this.type.getPlanksState();
|
|
if (this.isTwoFloored) {
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX() + 1,
|
|
this.boundingBox.minY(),
|
|
this.boundingBox.minZ(),
|
|
this.boundingBox.maxX() - 1,
|
|
this.boundingBox.minY() + 3 - 1,
|
|
this.boundingBox.maxZ(),
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX(),
|
|
this.boundingBox.minY(),
|
|
this.boundingBox.minZ() + 1,
|
|
this.boundingBox.maxX(),
|
|
this.boundingBox.minY() + 3 - 1,
|
|
this.boundingBox.maxZ() - 1,
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX() + 1,
|
|
this.boundingBox.maxY() - 2,
|
|
this.boundingBox.minZ(),
|
|
this.boundingBox.maxX() - 1,
|
|
this.boundingBox.maxY(),
|
|
this.boundingBox.maxZ(),
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX(),
|
|
this.boundingBox.maxY() - 2,
|
|
this.boundingBox.minZ() + 1,
|
|
this.boundingBox.maxX(),
|
|
this.boundingBox.maxY(),
|
|
this.boundingBox.maxZ() - 1,
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX() + 1,
|
|
this.boundingBox.minY() + 3,
|
|
this.boundingBox.minZ() + 1,
|
|
this.boundingBox.maxX() - 1,
|
|
this.boundingBox.minY() + 3,
|
|
this.boundingBox.maxZ() - 1,
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
} else {
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX() + 1,
|
|
this.boundingBox.minY(),
|
|
this.boundingBox.minZ(),
|
|
this.boundingBox.maxX() - 1,
|
|
this.boundingBox.maxY(),
|
|
this.boundingBox.maxZ(),
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX(),
|
|
this.boundingBox.minY(),
|
|
this.boundingBox.minZ() + 1,
|
|
this.boundingBox.maxX(),
|
|
this.boundingBox.maxY(),
|
|
this.boundingBox.maxZ() - 1,
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
}
|
|
|
|
this.placeSupportPillar(level, box, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, this.boundingBox.maxY());
|
|
this.placeSupportPillar(level, box, this.boundingBox.minX() + 1, this.boundingBox.minY(), this.boundingBox.maxZ() - 1, this.boundingBox.maxY());
|
|
this.placeSupportPillar(level, box, this.boundingBox.maxX() - 1, this.boundingBox.minY(), this.boundingBox.minZ() + 1, this.boundingBox.maxY());
|
|
this.placeSupportPillar(level, box, this.boundingBox.maxX() - 1, this.boundingBox.minY(), this.boundingBox.maxZ() - 1, this.boundingBox.maxY());
|
|
int i = this.boundingBox.minY() - 1;
|
|
|
|
for (int j = this.boundingBox.minX(); j <= this.boundingBox.maxX(); j++) {
|
|
for (int k = this.boundingBox.minZ(); k <= this.boundingBox.maxZ(); k++) {
|
|
this.setPlanksBlock(level, box, blockState, j, i, k);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void placeSupportPillar(WorldGenLevel level, BoundingBox box, int x, int y, int z, int maxY) {
|
|
if (!this.getBlock(level, x, maxY + 1, z, box).isAir()) {
|
|
this.generateBox(level, box, x, y, z, x, maxY, z, this.type.getPlanksState(), CAVE_AIR, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract static class MineShaftPiece extends StructurePiece {
|
|
protected MineshaftStructure.Type type;
|
|
|
|
public MineShaftPiece(StructurePieceType structurePieceType, int genDepth, MineshaftStructure.Type type, BoundingBox boundingBox) {
|
|
super(structurePieceType, genDepth, boundingBox);
|
|
this.type = type;
|
|
}
|
|
|
|
public MineShaftPiece(StructurePieceType structurePieceType, CompoundTag compoundTag) {
|
|
super(structurePieceType, compoundTag);
|
|
this.type = MineshaftStructure.Type.byId(compoundTag.getIntOr("MST", 0));
|
|
}
|
|
|
|
@Override
|
|
protected boolean canBeReplaced(LevelReader level, int x, int y, int z, BoundingBox box) {
|
|
BlockState blockState = this.getBlock(level, x, y, z, box);
|
|
return !blockState.is(this.type.getPlanksState().getBlock())
|
|
&& !blockState.is(this.type.getWoodState().getBlock())
|
|
&& !blockState.is(this.type.getFenceState().getBlock())
|
|
&& !blockState.is(Blocks.CHAIN);
|
|
}
|
|
|
|
@Override
|
|
protected void addAdditionalSaveData(StructurePieceSerializationContext context, CompoundTag tag) {
|
|
tag.putInt("MST", this.type.ordinal());
|
|
}
|
|
|
|
protected boolean isSupportingBox(BlockGetter level, BoundingBox box, int xStart, int xEnd, int y, int z) {
|
|
for (int i = xStart; i <= xEnd; i++) {
|
|
if (this.getBlock(level, i, y + 1, z, box).isAir()) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
protected boolean isInInvalidLocation(LevelAccessor level, BoundingBox boundingBox) {
|
|
int i = Math.max(this.boundingBox.minX() - 1, boundingBox.minX());
|
|
int j = Math.max(this.boundingBox.minY() - 1, boundingBox.minY());
|
|
int k = Math.max(this.boundingBox.minZ() - 1, boundingBox.minZ());
|
|
int l = Math.min(this.boundingBox.maxX() + 1, boundingBox.maxX());
|
|
int m = Math.min(this.boundingBox.maxY() + 1, boundingBox.maxY());
|
|
int n = Math.min(this.boundingBox.maxZ() + 1, boundingBox.maxZ());
|
|
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos((i + l) / 2, (j + m) / 2, (k + n) / 2);
|
|
if (level.getBiome(mutableBlockPos).is(BiomeTags.MINESHAFT_BLOCKING)) {
|
|
return true;
|
|
} else {
|
|
for (int o = i; o <= l; o++) {
|
|
for (int p = k; p <= n; p++) {
|
|
if (level.getBlockState(mutableBlockPos.set(o, j, p)).liquid()) {
|
|
return true;
|
|
}
|
|
|
|
if (level.getBlockState(mutableBlockPos.set(o, m, p)).liquid()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int o = i; o <= l; o++) {
|
|
for (int p = j; p <= m; p++) {
|
|
if (level.getBlockState(mutableBlockPos.set(o, p, k)).liquid()) {
|
|
return true;
|
|
}
|
|
|
|
if (level.getBlockState(mutableBlockPos.set(o, p, n)).liquid()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int o = k; o <= n; o++) {
|
|
for (int p = j; p <= m; p++) {
|
|
if (level.getBlockState(mutableBlockPos.set(i, p, o)).liquid()) {
|
|
return true;
|
|
}
|
|
|
|
if (level.getBlockState(mutableBlockPos.set(l, p, o)).liquid()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
protected void setPlanksBlock(WorldGenLevel level, BoundingBox box, BlockState plankState, int x, int y, int z) {
|
|
if (this.isInterior(level, x, y, z, box)) {
|
|
BlockPos blockPos = this.getWorldPos(x, y, z);
|
|
BlockState blockState = level.getBlockState(blockPos);
|
|
if (!blockState.isFaceSturdy(level, blockPos, Direction.UP)) {
|
|
level.setBlock(blockPos, plankState, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class MineShaftRoom extends MineshaftPieces.MineShaftPiece {
|
|
private final List<BoundingBox> childEntranceBoxes = Lists.<BoundingBox>newLinkedList();
|
|
|
|
public MineShaftRoom(int genDepth, RandomSource random, int x, int z, MineshaftStructure.Type type) {
|
|
super(
|
|
StructurePieceType.MINE_SHAFT_ROOM, genDepth, type, new BoundingBox(x, 50, z, x + 7 + random.nextInt(6), 54 + random.nextInt(6), z + 7 + random.nextInt(6))
|
|
);
|
|
this.type = type;
|
|
}
|
|
|
|
public MineShaftRoom(CompoundTag tag) {
|
|
super(StructurePieceType.MINE_SHAFT_ROOM, tag);
|
|
this.childEntranceBoxes.addAll((Collection)tag.read("Entrances", BoundingBox.CODEC.listOf()).orElse(List.of()));
|
|
}
|
|
|
|
@Override
|
|
public void addChildren(StructurePiece piece, StructurePieceAccessor pieces, RandomSource random) {
|
|
int i = this.getGenDepth();
|
|
int j = this.boundingBox.getYSpan() - 3 - 1;
|
|
if (j <= 0) {
|
|
j = 1;
|
|
}
|
|
|
|
int k = 0;
|
|
|
|
while (k < this.boundingBox.getXSpan()) {
|
|
k += random.nextInt(this.boundingBox.getXSpan());
|
|
if (k + 3 > this.boundingBox.getXSpan()) {
|
|
break;
|
|
}
|
|
|
|
MineshaftPieces.MineShaftPiece mineShaftPiece = MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + k, this.boundingBox.minY() + random.nextInt(j) + 1, this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
if (mineShaftPiece != null) {
|
|
BoundingBox boundingBox = mineShaftPiece.getBoundingBox();
|
|
this.childEntranceBoxes
|
|
.add(
|
|
new BoundingBox(boundingBox.minX(), boundingBox.minY(), this.boundingBox.minZ(), boundingBox.maxX(), boundingBox.maxY(), this.boundingBox.minZ() + 1)
|
|
);
|
|
}
|
|
|
|
k += 4;
|
|
}
|
|
|
|
k = 0;
|
|
|
|
while (k < this.boundingBox.getXSpan()) {
|
|
k += random.nextInt(this.boundingBox.getXSpan());
|
|
if (k + 3 > this.boundingBox.getXSpan()) {
|
|
break;
|
|
}
|
|
|
|
MineshaftPieces.MineShaftPiece mineShaftPiece = MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() + k, this.boundingBox.minY() + random.nextInt(j) + 1, this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
if (mineShaftPiece != null) {
|
|
BoundingBox boundingBox = mineShaftPiece.getBoundingBox();
|
|
this.childEntranceBoxes
|
|
.add(
|
|
new BoundingBox(boundingBox.minX(), boundingBox.minY(), this.boundingBox.maxZ() - 1, boundingBox.maxX(), boundingBox.maxY(), this.boundingBox.maxZ())
|
|
);
|
|
}
|
|
|
|
k += 4;
|
|
}
|
|
|
|
k = 0;
|
|
|
|
while (k < this.boundingBox.getZSpan()) {
|
|
k += random.nextInt(this.boundingBox.getZSpan());
|
|
if (k + 3 > this.boundingBox.getZSpan()) {
|
|
break;
|
|
}
|
|
|
|
MineshaftPieces.MineShaftPiece mineShaftPiece = MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY() + random.nextInt(j) + 1, this.boundingBox.minZ() + k, Direction.WEST, i
|
|
);
|
|
if (mineShaftPiece != null) {
|
|
BoundingBox boundingBox = mineShaftPiece.getBoundingBox();
|
|
this.childEntranceBoxes
|
|
.add(
|
|
new BoundingBox(this.boundingBox.minX(), boundingBox.minY(), boundingBox.minZ(), this.boundingBox.minX() + 1, boundingBox.maxY(), boundingBox.maxZ())
|
|
);
|
|
}
|
|
|
|
k += 4;
|
|
}
|
|
|
|
k = 0;
|
|
|
|
while (k < this.boundingBox.getZSpan()) {
|
|
k += random.nextInt(this.boundingBox.getZSpan());
|
|
if (k + 3 > this.boundingBox.getZSpan()) {
|
|
break;
|
|
}
|
|
|
|
StructurePiece structurePiece = MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() + random.nextInt(j) + 1, this.boundingBox.minZ() + k, Direction.EAST, i
|
|
);
|
|
if (structurePiece != null) {
|
|
BoundingBox boundingBox = structurePiece.getBoundingBox();
|
|
this.childEntranceBoxes
|
|
.add(
|
|
new BoundingBox(this.boundingBox.maxX() - 1, boundingBox.minY(), boundingBox.minZ(), this.boundingBox.maxX(), boundingBox.maxY(), boundingBox.maxZ())
|
|
);
|
|
}
|
|
|
|
k += 4;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void postProcess(
|
|
WorldGenLevel level, StructureManager structureManager, ChunkGenerator generator, RandomSource random, BoundingBox box, ChunkPos chunkPos, BlockPos pos
|
|
) {
|
|
if (!this.isInInvalidLocation(level, box)) {
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX(),
|
|
this.boundingBox.minY() + 1,
|
|
this.boundingBox.minZ(),
|
|
this.boundingBox.maxX(),
|
|
Math.min(this.boundingBox.minY() + 3, this.boundingBox.maxY()),
|
|
this.boundingBox.maxZ(),
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
|
|
for (BoundingBox boundingBox : this.childEntranceBoxes) {
|
|
this.generateBox(
|
|
level,
|
|
box,
|
|
boundingBox.minX(),
|
|
boundingBox.maxY() - 2,
|
|
boundingBox.minZ(),
|
|
boundingBox.maxX(),
|
|
boundingBox.maxY(),
|
|
boundingBox.maxZ(),
|
|
CAVE_AIR,
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
}
|
|
|
|
this.generateUpperHalfSphere(
|
|
level,
|
|
box,
|
|
this.boundingBox.minX(),
|
|
this.boundingBox.minY() + 4,
|
|
this.boundingBox.minZ(),
|
|
this.boundingBox.maxX(),
|
|
this.boundingBox.maxY(),
|
|
this.boundingBox.maxZ(),
|
|
CAVE_AIR,
|
|
false
|
|
);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void move(int x, int y, int z) {
|
|
super.move(x, y, z);
|
|
|
|
for (BoundingBox boundingBox : this.childEntranceBoxes) {
|
|
boundingBox.move(x, y, z);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void addAdditionalSaveData(StructurePieceSerializationContext context, CompoundTag tag) {
|
|
super.addAdditionalSaveData(context, tag);
|
|
tag.store("Entrances", BoundingBox.CODEC.listOf(), this.childEntranceBoxes);
|
|
}
|
|
}
|
|
|
|
public static class MineShaftStairs extends MineshaftPieces.MineShaftPiece {
|
|
public MineShaftStairs(int genDepth, BoundingBox boundingBox, Direction orientation, MineshaftStructure.Type type) {
|
|
super(StructurePieceType.MINE_SHAFT_STAIRS, genDepth, type, boundingBox);
|
|
this.setOrientation(orientation);
|
|
}
|
|
|
|
public MineShaftStairs(CompoundTag tag) {
|
|
super(StructurePieceType.MINE_SHAFT_STAIRS, tag);
|
|
}
|
|
|
|
@Nullable
|
|
public static BoundingBox findStairs(StructurePieceAccessor pieces, RandomSource random, int x, int y, int z, Direction direction) {
|
|
BoundingBox boundingBox = switch (direction) {
|
|
default -> new BoundingBox(0, -5, -8, 2, 2, 0);
|
|
case SOUTH -> new BoundingBox(0, -5, 0, 2, 2, 8);
|
|
case WEST -> new BoundingBox(-8, -5, 0, 0, 2, 2);
|
|
case EAST -> new BoundingBox(0, -5, 0, 8, 2, 2);
|
|
};
|
|
boundingBox.move(x, y, z);
|
|
return pieces.findCollisionPiece(boundingBox) != null ? null : boundingBox;
|
|
}
|
|
|
|
@Override
|
|
public void addChildren(StructurePiece piece, StructurePieceAccessor pieces, RandomSource random) {
|
|
int i = this.getGenDepth();
|
|
Direction direction = this.getOrientation();
|
|
if (direction != null) {
|
|
switch (direction) {
|
|
case NORTH:
|
|
default:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX(), this.boundingBox.minY(), this.boundingBox.minZ() - 1, Direction.NORTH, i
|
|
);
|
|
break;
|
|
case SOUTH:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX(), this.boundingBox.minY(), this.boundingBox.maxZ() + 1, Direction.SOUTH, i
|
|
);
|
|
break;
|
|
case WEST:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.minX() - 1, this.boundingBox.minY(), this.boundingBox.minZ(), Direction.WEST, i
|
|
);
|
|
break;
|
|
case EAST:
|
|
MineshaftPieces.generateAndAddPiece(
|
|
piece, pieces, random, this.boundingBox.maxX() + 1, this.boundingBox.minY(), this.boundingBox.minZ(), Direction.EAST, i
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void postProcess(
|
|
WorldGenLevel level, StructureManager structureManager, ChunkGenerator generator, RandomSource random, BoundingBox box, ChunkPos chunkPos, BlockPos pos
|
|
) {
|
|
if (!this.isInInvalidLocation(level, box)) {
|
|
this.generateBox(level, box, 0, 5, 0, 2, 7, 1, CAVE_AIR, CAVE_AIR, false);
|
|
this.generateBox(level, box, 0, 0, 7, 2, 2, 8, CAVE_AIR, CAVE_AIR, false);
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
this.generateBox(level, box, 0, 5 - i - (i < 4 ? 1 : 0), 2 + i, 2, 7 - i, 2 + i, CAVE_AIR, CAVE_AIR, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|