package net.minecraft.world.level.levelgen.structure.structures; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.level.ChunkPos; 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.FenceBlock; import net.minecraft.world.level.block.StairBlock; import net.minecraft.world.level.block.entity.SpawnerBlockEntity; import net.minecraft.world.level.block.state.BlockState; 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.material.Fluids; import net.minecraft.world.level.storage.loot.BuiltInLootTables; import org.jspecify.annotations.Nullable; public class NetherFortressPieces { private static final int MAX_DEPTH = 30; private static final int LOWEST_Y_POSITION = 10; public static final int MAGIC_START_Y = 64; private static final NetherFortressPieces.PieceWeight[] BRIDGE_PIECE_WEIGHTS = new NetherFortressPieces.PieceWeight[]{ new NetherFortressPieces.PieceWeight(NetherFortressPieces.BridgeStraight.class, 30, 0, true), new NetherFortressPieces.PieceWeight(NetherFortressPieces.BridgeCrossing.class, 10, 4), new NetherFortressPieces.PieceWeight(NetherFortressPieces.RoomCrossing.class, 10, 4), new NetherFortressPieces.PieceWeight(NetherFortressPieces.StairsRoom.class, 10, 3), new NetherFortressPieces.PieceWeight(NetherFortressPieces.MonsterThrone.class, 5, 2), new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleEntrance.class, 5, 1) }; private static final NetherFortressPieces.PieceWeight[] CASTLE_PIECE_WEIGHTS = new NetherFortressPieces.PieceWeight[]{ new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleSmallCorridorPiece.class, 25, 0, true), new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleSmallCorridorCrossingPiece.class, 15, 5), new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleSmallCorridorRightTurnPiece.class, 5, 10), new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleSmallCorridorLeftTurnPiece.class, 5, 10), new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleCorridorStairsPiece.class, 10, 3, true), new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleCorridorTBalconyPiece.class, 7, 2), new NetherFortressPieces.PieceWeight(NetherFortressPieces.CastleStalkRoom.class, 5, 2) }; @Nullable private static NetherFortressPieces.NetherBridgePiece findAndCreateBridgePieceFactory( final NetherFortressPieces.PieceWeight piece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int depth ) { Class pieceClass = piece.pieceClass; NetherFortressPieces.NetherBridgePiece structurePiece = null; if (pieceClass == NetherFortressPieces.BridgeStraight.class) { structurePiece = NetherFortressPieces.BridgeStraight.createPiece(structurePieceAccessor, random, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.BridgeCrossing.class) { structurePiece = NetherFortressPieces.BridgeCrossing.createPiece(structurePieceAccessor, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.RoomCrossing.class) { structurePiece = NetherFortressPieces.RoomCrossing.createPiece(structurePieceAccessor, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.StairsRoom.class) { structurePiece = NetherFortressPieces.StairsRoom.createPiece(structurePieceAccessor, footX, footY, footZ, depth, direction); } else if (pieceClass == NetherFortressPieces.MonsterThrone.class) { structurePiece = NetherFortressPieces.MonsterThrone.createPiece(structurePieceAccessor, footX, footY, footZ, depth, direction); } else if (pieceClass == NetherFortressPieces.CastleEntrance.class) { structurePiece = NetherFortressPieces.CastleEntrance.createPiece(structurePieceAccessor, random, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.CastleSmallCorridorPiece.class) { structurePiece = NetherFortressPieces.CastleSmallCorridorPiece.createPiece(structurePieceAccessor, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.CastleSmallCorridorRightTurnPiece.class) { structurePiece = NetherFortressPieces.CastleSmallCorridorRightTurnPiece.createPiece(structurePieceAccessor, random, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.CastleSmallCorridorLeftTurnPiece.class) { structurePiece = NetherFortressPieces.CastleSmallCorridorLeftTurnPiece.createPiece(structurePieceAccessor, random, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.CastleCorridorStairsPiece.class) { structurePiece = NetherFortressPieces.CastleCorridorStairsPiece.createPiece(structurePieceAccessor, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.CastleCorridorTBalconyPiece.class) { structurePiece = NetherFortressPieces.CastleCorridorTBalconyPiece.createPiece(structurePieceAccessor, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.CastleSmallCorridorCrossingPiece.class) { structurePiece = NetherFortressPieces.CastleSmallCorridorCrossingPiece.createPiece(structurePieceAccessor, footX, footY, footZ, direction, depth); } else if (pieceClass == NetherFortressPieces.CastleStalkRoom.class) { structurePiece = NetherFortressPieces.CastleStalkRoom.createPiece(structurePieceAccessor, footX, footY, footZ, direction, depth); } return structurePiece; } public static class BridgeCrossing extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 19; private static final int HEIGHT = 10; private static final int DEPTH = 19; public BridgeCrossing(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_BRIDGE_CROSSING, genDepth, boundingBox); this.setOrientation(direction); } protected BridgeCrossing(final int west, final int north, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_BRIDGE_CROSSING, 0, StructurePiece.makeBoundingBox(west, 64, north, direction, 19, 10, 19)); this.setOrientation(direction); } protected BridgeCrossing(final StructurePieceType type, final CompoundTag tag) { super(type, tag); } public BridgeCrossing(final CompoundTag tag) { this(StructurePieceType.NETHER_FORTRESS_BRIDGE_CROSSING, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 8, 3, false); this.generateChildLeft((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 3, 8, false); this.generateChildRight((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 3, 8, false); } @Nullable public static NetherFortressPieces.BridgeCrossing createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -8, -3, 0, 19, 10, 19, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.BridgeCrossing(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 7, 3, 0, 11, 4, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 3, 7, 18, 4, 11, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 5, 0, 10, 7, 18, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 8, 18, 7, 10, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 7, 5, 0, 7, 5, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 7, 5, 11, 7, 5, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 11, 5, 0, 11, 5, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 11, 5, 11, 11, 5, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 7, 7, 5, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 11, 5, 7, 18, 5, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 11, 7, 5, 11, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 11, 5, 11, 18, 5, 11, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 7, 2, 0, 11, 2, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 7, 2, 13, 11, 2, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 7, 0, 0, 11, 1, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 7, 0, 15, 11, 1, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 7; x <= 11; x++) { for (int z = 0; z <= 2; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, 18 - z, chunkBB); } } this.generateBox(level, chunkBB, 0, 2, 7, 5, 2, 11, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 13, 2, 7, 18, 2, 11, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 0, 7, 3, 1, 11, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 15, 0, 7, 18, 1, 11, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 0; x <= 2; x++) { for (int z = 7; z <= 11; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), 18 - x, -1, z, chunkBB); } } } } public static class BridgeEndFiller extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 5; private static final int HEIGHT = 10; private static final int DEPTH = 8; private final int selfSeed; public BridgeEndFiller(final int genDepth, final RandomSource random, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_BRIDGE_END_FILLER, genDepth, boundingBox); this.setOrientation(direction); this.selfSeed = random.nextInt(); } public BridgeEndFiller(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_BRIDGE_END_FILLER, tag); this.selfSeed = tag.getIntOr("Seed", 0); } @Nullable public static NetherFortressPieces.BridgeEndFiller createPiece( final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -1, -3, 0, 5, 10, 8, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.BridgeEndFiller(genDepth, random, box, direction) : null; } @Override protected void addAdditionalSaveData(final StructurePieceSerializationContext context, final CompoundTag tag) { super.addAdditionalSaveData(context, tag); tag.putInt("Seed", this.selfSeed); } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { RandomSource selfRandom = RandomSource.createThreadLocalInstance(this.selfSeed); for (int x = 0; x <= 4; x++) { for (int y = 3; y <= 4; y++) { int z = selfRandom.nextInt(8); this.generateBox(level, chunkBB, x, y, 0, x, y, z, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); } } int z = selfRandom.nextInt(8); this.generateBox(level, chunkBB, 0, 5, 0, 0, 5, z, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); z = selfRandom.nextInt(8); this.generateBox(level, chunkBB, 4, 5, 0, 4, 5, z, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 0; x <= 4; x++) { int zx = selfRandom.nextInt(5); this.generateBox(level, chunkBB, x, 2, 0, x, 2, zx, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); } for (int x = 0; x <= 4; x++) { for (int y = 0; y <= 1; y++) { int zx = selfRandom.nextInt(3); this.generateBox(level, chunkBB, x, y, 0, x, y, zx, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); } } } } public static class BridgeStraight extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 5; private static final int HEIGHT = 10; private static final int DEPTH = 19; public BridgeStraight(final int genDepth, final RandomSource random, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_BRIDGE_STRAIGHT, genDepth, boundingBox); this.setOrientation(direction); } public BridgeStraight(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_BRIDGE_STRAIGHT, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 1, 3, false); } @Nullable public static NetherFortressPieces.BridgeStraight createPiece( final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -1, -3, 0, 5, 10, 19, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.BridgeStraight(genDepth, random, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 3, 0, 4, 4, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 5, 0, 3, 7, 18, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 0, 0, 5, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 5, 0, 4, 5, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 4, 2, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 13, 4, 2, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 0, 0, 4, 1, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 0, 15, 4, 1, 18, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 2; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, 18 - z, chunkBB); } } BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); BlockState nseFence = nsFence.setValue(FenceBlock.EAST, true); BlockState nswFence = nsFence.setValue(FenceBlock.WEST, true); this.generateBox(level, chunkBB, 0, 1, 1, 0, 4, 1, nseFence, nseFence, false); this.generateBox(level, chunkBB, 0, 3, 4, 0, 4, 4, nseFence, nseFence, false); this.generateBox(level, chunkBB, 0, 3, 14, 0, 4, 14, nseFence, nseFence, false); this.generateBox(level, chunkBB, 0, 1, 17, 0, 4, 17, nseFence, nseFence, false); this.generateBox(level, chunkBB, 4, 1, 1, 4, 4, 1, nswFence, nswFence, false); this.generateBox(level, chunkBB, 4, 3, 4, 4, 4, 4, nswFence, nswFence, false); this.generateBox(level, chunkBB, 4, 3, 14, 4, 4, 14, nswFence, nswFence, false); this.generateBox(level, chunkBB, 4, 1, 17, 4, 4, 17, nswFence, nswFence, false); } } public static class CastleCorridorStairsPiece extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 5; private static final int HEIGHT = 14; private static final int DEPTH = 10; public CastleCorridorStairsPiece(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_CORRIDOR_STAIRS, genDepth, boundingBox); this.setOrientation(direction); } public CastleCorridorStairsPiece(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_CORRIDOR_STAIRS, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 1, 0, true); } @Nullable public static NetherFortressPieces.CastleCorridorStairsPiece createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -1, -7, 0, 5, 14, 10, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleCorridorStairsPiece(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { BlockState stairs = Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.FACING, Direction.SOUTH); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); for (int step = 0; step <= 9; step++) { int floor = Math.max(1, 7 - step); int roof = Math.min(Math.max(floor + 5, 14 - step), 13); int z = step; this.generateBox(level, chunkBB, 0, 0, step, 4, floor, step, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, floor + 1, step, 3, roof - 1, step, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); if (step <= 6) { this.placeBlock(level, stairs, 1, floor + 1, step, chunkBB); this.placeBlock(level, stairs, 2, floor + 1, step, chunkBB); this.placeBlock(level, stairs, 3, floor + 1, step, chunkBB); } this.generateBox(level, chunkBB, 0, roof, step, 4, roof, step, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox( level, chunkBB, 0, floor + 1, step, 0, roof - 1, step, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false ); this.generateBox( level, chunkBB, 4, floor + 1, step, 4, roof - 1, step, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false ); if ((step & 1) == 0) { this.generateBox(level, chunkBB, 0, floor + 2, step, 0, floor + 3, step, nsFence, nsFence, false); this.generateBox(level, chunkBB, 4, floor + 2, step, 4, floor + 3, step, nsFence, nsFence, false); } for (int x = 0; x <= 4; x++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class CastleCorridorTBalconyPiece extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 9; private static final int HEIGHT = 7; private static final int DEPTH = 9; public CastleCorridorTBalconyPiece(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_CORRIDOR_T_BALCONY, genDepth, boundingBox); this.setOrientation(direction); } public CastleCorridorTBalconyPiece(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_CORRIDOR_T_BALCONY, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { int zOff = 1; Direction orientation = this.getOrientation(); if (orientation == Direction.WEST || orientation == Direction.NORTH) { zOff = 5; } this.generateChildLeft((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, zOff, random.nextInt(8) > 0); this.generateChildRight((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, zOff, random.nextInt(8) > 0); } @Nullable public static NetherFortressPieces.CastleCorridorTBalconyPiece createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -3, 0, 0, 9, 7, 9, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleCorridorTBalconyPiece(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); this.generateBox(level, chunkBB, 0, 0, 0, 8, 1, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 8, 5, 8, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 6, 0, 8, 6, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 2, 5, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 2, 0, 8, 5, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 3, 0, 1, 4, 0, weFence, weFence, false); this.generateBox(level, chunkBB, 7, 3, 0, 7, 4, 0, weFence, weFence, false); this.generateBox(level, chunkBB, 0, 2, 4, 8, 2, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 1, 4, 2, 2, 4, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 1, 4, 7, 2, 4, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 3, 8, 7, 3, 8, weFence, weFence, false); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.EAST, true).setValue(FenceBlock.SOUTH, true), 0, 3, 8, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.SOUTH, true), 8, 3, 8, chunkBB); this.generateBox(level, chunkBB, 0, 3, 6, 0, 3, 7, nsFence, nsFence, false); this.generateBox(level, chunkBB, 8, 3, 6, 8, 3, 7, nsFence, nsFence, false); this.generateBox(level, chunkBB, 0, 3, 4, 0, 5, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 3, 4, 8, 5, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 3, 5, 2, 5, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 3, 5, 7, 5, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 4, 5, 1, 5, 5, weFence, weFence, false); this.generateBox(level, chunkBB, 7, 4, 5, 7, 5, 5, weFence, weFence, false); for (int z = 0; z <= 5; z++) { for (int x = 0; x <= 8; x++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class CastleEntrance extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 13; private static final int HEIGHT = 14; private static final int DEPTH = 13; public CastleEntrance(final int genDepth, final RandomSource random, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_ENTRANCE, genDepth, boundingBox); this.setOrientation(direction); } public CastleEntrance(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_ENTRANCE, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 5, 3, true); } @Nullable public static NetherFortressPieces.CastleEntrance createPiece( final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -5, -3, 0, 13, 14, 13, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleEntrance(genDepth, random, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 3, 0, 12, 4, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 0, 12, 13, 12, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 0, 1, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 11, 5, 0, 12, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 11, 4, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 5, 11, 10, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 9, 11, 7, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 0, 4, 12, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 5, 0, 10, 12, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 9, 0, 7, 12, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 11, 2, 10, 12, 10, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 8, 0, 7, 8, 0, Blocks.NETHER_BRICK_FENCE.defaultBlockState(), Blocks.NETHER_BRICK_FENCE.defaultBlockState(), false); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); for (int i = 1; i <= 11; i += 2) { this.generateBox(level, chunkBB, i, 10, 0, i, 11, 0, weFence, weFence, false); this.generateBox(level, chunkBB, i, 10, 12, i, 11, 12, weFence, weFence, false); this.generateBox(level, chunkBB, 0, 10, i, 0, 11, i, nsFence, nsFence, false); this.generateBox(level, chunkBB, 12, 10, i, 12, 11, i, nsFence, nsFence, false); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), i, 13, 0, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), i, 13, 12, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), 0, 13, i, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), 12, 13, i, chunkBB); if (i != 11) { this.placeBlock(level, weFence, i + 1, 13, 0, chunkBB); this.placeBlock(level, weFence, i + 1, 13, 12, chunkBB); this.placeBlock(level, nsFence, 0, 13, i + 1, chunkBB); this.placeBlock(level, nsFence, 12, 13, i + 1, chunkBB); } } this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.EAST, true), 0, 13, 0, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.SOUTH, true).setValue(FenceBlock.EAST, true), 0, 13, 12, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.SOUTH, true).setValue(FenceBlock.WEST, true), 12, 13, 12, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.WEST, true), 12, 13, 0, chunkBB); for (int z = 3; z <= 9; z += 2) { this.generateBox(level, chunkBB, 1, 7, z, 1, 8, z, nsFence.setValue(FenceBlock.WEST, true), nsFence.setValue(FenceBlock.WEST, true), false); this.generateBox(level, chunkBB, 11, 7, z, 11, 8, z, nsFence.setValue(FenceBlock.EAST, true), nsFence.setValue(FenceBlock.EAST, true), false); } this.generateBox(level, chunkBB, 4, 2, 0, 8, 2, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 4, 12, 2, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 0, 0, 8, 1, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 0, 9, 8, 1, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 0, 4, 3, 1, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 9, 0, 4, 12, 1, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 4; x <= 8; x++) { for (int z = 0; z <= 2; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, 12 - z, chunkBB); } } for (int x = 0; x <= 2; x++) { for (int z = 4; z <= 8; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), 12 - x, -1, z, chunkBB); } } this.generateBox(level, chunkBB, 5, 5, 5, 7, 5, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 1, 6, 6, 4, 6, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), 6, 0, 6, chunkBB); this.placeBlock(level, Blocks.LAVA.defaultBlockState(), 6, 5, 6, chunkBB); BlockPos pos = this.getWorldPos(6, 5, 6); if (chunkBB.isInside(pos)) { level.scheduleTick(pos, Fluids.LAVA, 0); } } } public static class CastleSmallCorridorCrossingPiece extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 5; private static final int HEIGHT = 7; private static final int DEPTH = 5; public CastleSmallCorridorCrossingPiece(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR_CROSSING, genDepth, boundingBox); this.setOrientation(direction); } public CastleSmallCorridorCrossingPiece(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR_CROSSING, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 1, 0, true); this.generateChildLeft((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, 1, true); this.generateChildRight((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, 1, true); } @Nullable public static NetherFortressPieces.CastleSmallCorridorCrossingPiece createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -1, 0, 0, 5, 7, 5, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleSmallCorridorCrossingPiece(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 0, 5, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 2, 0, 4, 5, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 4, 0, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 2, 4, 4, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class CastleSmallCorridorLeftTurnPiece extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 5; private static final int HEIGHT = 7; private static final int DEPTH = 5; private boolean isNeedingChest; public CastleSmallCorridorLeftTurnPiece(final int genDepth, final RandomSource random, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR_LEFT_TURN, genDepth, boundingBox); this.setOrientation(direction); this.isNeedingChest = random.nextInt(3) == 0; } public CastleSmallCorridorLeftTurnPiece(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR_LEFT_TURN, tag); this.isNeedingChest = tag.getBooleanOr("Chest", false); } @Override protected void addAdditionalSaveData(final StructurePieceSerializationContext context, final CompoundTag tag) { super.addAdditionalSaveData(context, tag); tag.putBoolean("Chest", this.isNeedingChest); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildLeft((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, 1, true); } @Nullable public static NetherFortressPieces.CastleSmallCorridorLeftTurnPiece createPiece( final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -1, 0, 0, 5, 7, 5, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleSmallCorridorLeftTurnPiece(genDepth, random, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); this.generateBox(level, chunkBB, 4, 2, 0, 4, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 3, 1, 4, 4, 1, nsFence, nsFence, false); this.generateBox(level, chunkBB, 4, 3, 3, 4, 4, 3, nsFence, nsFence, false); this.generateBox(level, chunkBB, 0, 2, 0, 0, 5, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 4, 3, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 3, 4, 1, 4, 4, weFence, weFence, false); this.generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, weFence, weFence, false); if (this.isNeedingChest && chunkBB.isInside(this.getWorldPos(3, 2, 3))) { this.isNeedingChest = false; this.createChest(level, chunkBB, random, 3, 2, 3, BuiltInLootTables.NETHER_BRIDGE); } this.generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class CastleSmallCorridorPiece extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 5; private static final int HEIGHT = 7; private static final int DEPTH = 5; public CastleSmallCorridorPiece(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR, genDepth, boundingBox); this.setOrientation(direction); } public CastleSmallCorridorPiece(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 1, 0, true); } @Nullable public static NetherFortressPieces.CastleSmallCorridorPiece createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -1, 0, 0, 5, 7, 5, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleSmallCorridorPiece(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); this.generateBox(level, chunkBB, 0, 2, 0, 0, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 2, 0, 4, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 3, 1, 0, 4, 1, nsFence, nsFence, false); this.generateBox(level, chunkBB, 0, 3, 3, 0, 4, 3, nsFence, nsFence, false); this.generateBox(level, chunkBB, 4, 3, 1, 4, 4, 1, nsFence, nsFence, false); this.generateBox(level, chunkBB, 4, 3, 3, 4, 4, 3, nsFence, nsFence, false); this.generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class CastleSmallCorridorRightTurnPiece extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 5; private static final int HEIGHT = 7; private static final int DEPTH = 5; private boolean isNeedingChest; public CastleSmallCorridorRightTurnPiece(final int genDepth, final RandomSource random, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR_RIGHT_TURN, genDepth, boundingBox); this.setOrientation(direction); this.isNeedingChest = random.nextInt(3) == 0; } public CastleSmallCorridorRightTurnPiece(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_SMALL_CORRIDOR_RIGHT_TURN, tag); this.isNeedingChest = tag.getBooleanOr("Chest", false); } @Override protected void addAdditionalSaveData(final StructurePieceSerializationContext context, final CompoundTag tag) { super.addAdditionalSaveData(context, tag); tag.putBoolean("Chest", this.isNeedingChest); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildRight((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, 1, true); } @Nullable public static NetherFortressPieces.CastleSmallCorridorRightTurnPiece createPiece( final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -1, 0, 0, 5, 7, 5, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleSmallCorridorRightTurnPiece(genDepth, random, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); this.generateBox(level, chunkBB, 0, 2, 0, 0, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 3, 1, 0, 4, 1, nsFence, nsFence, false); this.generateBox(level, chunkBB, 0, 3, 3, 0, 4, 3, nsFence, nsFence, false); this.generateBox(level, chunkBB, 4, 2, 0, 4, 5, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 2, 4, 4, 5, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 3, 4, 1, 4, 4, weFence, weFence, false); this.generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, weFence, weFence, false); if (this.isNeedingChest && chunkBB.isInside(this.getWorldPos(1, 2, 3))) { this.isNeedingChest = false; this.createChest(level, chunkBB, random, 1, 2, 3, BuiltInLootTables.NETHER_BRIDGE); } this.generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class CastleStalkRoom extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 13; private static final int HEIGHT = 14; private static final int DEPTH = 13; public CastleStalkRoom(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_STALK_ROOM, genDepth, boundingBox); this.setOrientation(direction); } public CastleStalkRoom(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_CASTLE_STALK_ROOM, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 5, 3, true); this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 5, 11, true); } @Nullable public static NetherFortressPieces.CastleStalkRoom createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -5, -3, 0, 13, 14, 13, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.CastleStalkRoom(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 3, 0, 12, 4, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 0, 12, 13, 12, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 0, 1, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 11, 5, 0, 12, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 11, 4, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 5, 11, 10, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 9, 11, 7, 12, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 0, 4, 12, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 5, 0, 10, 12, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 9, 0, 7, 12, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 11, 2, 10, 12, 10, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); BlockState nswFence = nsFence.setValue(FenceBlock.WEST, true); BlockState nseFence = nsFence.setValue(FenceBlock.EAST, true); for (int i = 1; i <= 11; i += 2) { this.generateBox(level, chunkBB, i, 10, 0, i, 11, 0, weFence, weFence, false); this.generateBox(level, chunkBB, i, 10, 12, i, 11, 12, weFence, weFence, false); this.generateBox(level, chunkBB, 0, 10, i, 0, 11, i, nsFence, nsFence, false); this.generateBox(level, chunkBB, 12, 10, i, 12, 11, i, nsFence, nsFence, false); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), i, 13, 0, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), i, 13, 12, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), 0, 13, i, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), 12, 13, i, chunkBB); if (i != 11) { this.placeBlock(level, weFence, i + 1, 13, 0, chunkBB); this.placeBlock(level, weFence, i + 1, 13, 12, chunkBB); this.placeBlock(level, nsFence, 0, 13, i + 1, chunkBB); this.placeBlock(level, nsFence, 12, 13, i + 1, chunkBB); } } this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.EAST, true), 0, 13, 0, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.SOUTH, true).setValue(FenceBlock.EAST, true), 0, 13, 12, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.SOUTH, true).setValue(FenceBlock.WEST, true), 12, 13, 12, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.WEST, true), 12, 13, 0, chunkBB); for (int z = 3; z <= 9; z += 2) { this.generateBox(level, chunkBB, 1, 7, z, 1, 8, z, nswFence, nswFence, false); this.generateBox(level, chunkBB, 11, 7, z, 11, 8, z, nseFence, nseFence, false); } BlockState stairs = Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.FACING, Direction.NORTH); for (int ix = 0; ix <= 6; ix++) { int z = ix + 4; for (int x = 5; x <= 7; x++) { this.placeBlock(level, stairs, x, 5 + ix, z, chunkBB); } if (z >= 5 && z <= 8) { this.generateBox(level, chunkBB, 5, 5, z, 7, ix + 4, z, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); } else if (z >= 9 && z <= 10) { this.generateBox(level, chunkBB, 5, 8, z, 7, ix + 4, z, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); } if (ix >= 1) { this.generateBox(level, chunkBB, 5, 6 + ix, z, 7, 9 + ix, z, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); } } for (int x = 5; x <= 7; x++) { this.placeBlock(level, stairs, x, 12, 11, chunkBB); } this.generateBox(level, chunkBB, 5, 6, 7, 5, 7, 7, nseFence, nseFence, false); this.generateBox(level, chunkBB, 7, 6, 7, 7, 7, 7, nswFence, nswFence, false); this.generateBox(level, chunkBB, 5, 13, 12, 7, 13, 12, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 2, 3, 5, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 9, 3, 5, 10, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 4, 2, 5, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 9, 5, 2, 10, 5, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 9, 5, 9, 10, 5, 10, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 10, 5, 4, 10, 5, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); BlockState eastStairs = stairs.setValue(StairBlock.FACING, Direction.EAST); BlockState westStairs = stairs.setValue(StairBlock.FACING, Direction.WEST); this.placeBlock(level, westStairs, 4, 5, 2, chunkBB); this.placeBlock(level, westStairs, 4, 5, 3, chunkBB); this.placeBlock(level, westStairs, 4, 5, 9, chunkBB); this.placeBlock(level, westStairs, 4, 5, 10, chunkBB); this.placeBlock(level, eastStairs, 8, 5, 2, chunkBB); this.placeBlock(level, eastStairs, 8, 5, 3, chunkBB); this.placeBlock(level, eastStairs, 8, 5, 9, chunkBB); this.placeBlock(level, eastStairs, 8, 5, 10, chunkBB); this.generateBox(level, chunkBB, 3, 4, 4, 4, 4, 8, Blocks.SOUL_SAND.defaultBlockState(), Blocks.SOUL_SAND.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 4, 4, 9, 4, 8, Blocks.SOUL_SAND.defaultBlockState(), Blocks.SOUL_SAND.defaultBlockState(), false); this.generateBox(level, chunkBB, 3, 5, 4, 4, 5, 8, Blocks.NETHER_WART.defaultBlockState(), Blocks.NETHER_WART.defaultBlockState(), false); this.generateBox(level, chunkBB, 8, 5, 4, 9, 5, 8, Blocks.NETHER_WART.defaultBlockState(), Blocks.NETHER_WART.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 2, 0, 8, 2, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 4, 12, 2, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 0, 0, 8, 1, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 4, 0, 9, 8, 1, 12, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 0, 4, 3, 1, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 9, 0, 4, 12, 1, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); for (int x = 4; x <= 8; x++) { for (int z = 0; z <= 2; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, 12 - z, chunkBB); } } for (int x = 0; x <= 2; x++) { for (int z = 4; z <= 8; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), 12 - x, -1, z, chunkBB); } } } } public static class MonsterThrone extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 7; private static final int HEIGHT = 8; private static final int DEPTH = 9; private boolean hasPlacedSpawner; public MonsterThrone(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_MONSTER_THRONE, genDepth, boundingBox); this.setOrientation(direction); } public MonsterThrone(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_MONSTER_THRONE, tag); this.hasPlacedSpawner = tag.getBooleanOr("Mob", false); } @Override protected void addAdditionalSaveData(final StructurePieceSerializationContext context, final CompoundTag tag) { super.addAdditionalSaveData(context, tag); tag.putBoolean("Mob", this.hasPlacedSpawner); } @Nullable public static NetherFortressPieces.MonsterThrone createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final int genDepth, final Direction direction ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -2, 0, 0, 7, 8, 9, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.MonsterThrone(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 2, 0, 6, 7, 7, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 0, 0, 5, 1, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 2, 1, 5, 2, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 3, 2, 5, 3, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 4, 3, 5, 4, 7, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 2, 0, 1, 4, 2, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 2, 0, 5, 4, 2, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 5, 2, 1, 5, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 5, 2, 5, 5, 3, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 3, 0, 5, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 5, 3, 6, 5, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 5, 8, 5, 5, 8, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true), 1, 6, 3, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.EAST, true), 5, 6, 3, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.EAST, true).setValue(FenceBlock.NORTH, true), 0, 6, 3, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.NORTH, true), 6, 6, 3, chunkBB); this.generateBox(level, chunkBB, 0, 6, 4, 0, 6, 7, nsFence, nsFence, false); this.generateBox(level, chunkBB, 6, 6, 4, 6, 6, 7, nsFence, nsFence, false); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.EAST, true).setValue(FenceBlock.SOUTH, true), 0, 6, 8, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.SOUTH, true), 6, 6, 8, chunkBB); this.generateBox(level, chunkBB, 1, 6, 8, 5, 6, 8, weFence, weFence, false); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.EAST, true), 1, 7, 8, chunkBB); this.generateBox(level, chunkBB, 2, 7, 8, 4, 7, 8, weFence, weFence, false); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true), 5, 7, 8, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.EAST, true), 2, 8, 8, chunkBB); this.placeBlock(level, weFence, 3, 8, 8, chunkBB); this.placeBlock(level, Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true), 4, 8, 8, chunkBB); if (!this.hasPlacedSpawner) { BlockPos pos = this.getWorldPos(3, 5, 5); if (chunkBB.isInside(pos)) { this.hasPlacedSpawner = true; level.setBlock(pos, Blocks.SPAWNER.defaultBlockState(), 2); if (level.getBlockEntity(pos) instanceof SpawnerBlockEntity spawner) { spawner.setEntityId(EntityTypes.BLAZE, random); } } } for (int x = 0; x <= 6; x++) { for (int z = 0; z <= 6; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } private abstract static class NetherBridgePiece extends StructurePiece { protected NetherBridgePiece(final StructurePieceType type, final int genDepth, final BoundingBox boundingBox) { super(type, genDepth, boundingBox); } public NetherBridgePiece(final StructurePieceType type, final CompoundTag tag) { super(type, tag); } @Override protected void addAdditionalSaveData(final StructurePieceSerializationContext context, final CompoundTag tag) { } private int updatePieceWeight(final List currentPieces) { boolean hasAnyPieces = false; int totalWeight = 0; for (NetherFortressPieces.PieceWeight piece : currentPieces) { if (piece.maxPlaceCount > 0 && piece.placeCount < piece.maxPlaceCount) { hasAnyPieces = true; } totalWeight += piece.weight; } return hasAnyPieces ? totalWeight : -1; } @Nullable private NetherFortressPieces.NetherBridgePiece generatePiece( final NetherFortressPieces.StartPiece startPiece, final List currentPieces, final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int depth ) { int totalWeight = this.updatePieceWeight(currentPieces); boolean doStuff = totalWeight > 0 && depth <= 30; int numAttempts = 0; while (numAttempts < 5 && doStuff) { numAttempts++; int weightSelection = random.nextInt(totalWeight); for (NetherFortressPieces.PieceWeight piece : currentPieces) { weightSelection -= piece.weight; if (weightSelection < 0) { if (!piece.doPlace(depth) || piece == startPiece.previousPiece && !piece.allowInRow) { break; } NetherFortressPieces.NetherBridgePiece structurePiece = NetherFortressPieces.findAndCreateBridgePieceFactory( piece, structurePieceAccessor, random, footX, footY, footZ, direction, depth ); if (structurePiece != null) { piece.placeCount++; startPiece.previousPiece = piece; if (!piece.isValid()) { currentPieces.remove(piece); } return structurePiece; } } } } return NetherFortressPieces.BridgeEndFiller.createPiece(structurePieceAccessor, random, footX, footY, footZ, direction, depth); } @Nullable private StructurePiece generateAndAddPiece( final NetherFortressPieces.StartPiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int footX, final int footY, final int footZ, final Direction direction, final int depth, final boolean isCastle ) { if (Math.abs(footX - startPiece.getBoundingBox().minX()) <= 112 && Math.abs(footZ - startPiece.getBoundingBox().minZ()) <= 112) { List availablePieces = startPiece.availableBridgePieces; if (isCastle) { availablePieces = startPiece.availableCastlePieces; } StructurePiece newPiece = this.generatePiece(startPiece, availablePieces, structurePieceAccessor, random, footX, footY, footZ, direction, depth + 1); if (newPiece != null) { structurePieceAccessor.addPiece(newPiece); startPiece.pendingChildren.add(newPiece); } return newPiece; } else { return NetherFortressPieces.BridgeEndFiller.createPiece(structurePieceAccessor, random, footX, footY, footZ, direction, depth); } } @Nullable protected StructurePiece generateChildForward( final NetherFortressPieces.StartPiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int xOff, final int yOff, final boolean isCastle ) { Direction orientation = this.getOrientation(); if (orientation != null) { switch (orientation) { case NORTH: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() + xOff, this.boundingBox.minY() + yOff, this.boundingBox.minZ() - 1, orientation, this.getGenDepth(), isCastle ); case SOUTH: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() + xOff, this.boundingBox.minY() + yOff, this.boundingBox.maxZ() + 1, orientation, this.getGenDepth(), isCastle ); case WEST: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() - 1, this.boundingBox.minY() + yOff, this.boundingBox.minZ() + xOff, orientation, this.getGenDepth(), isCastle ); case EAST: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() + yOff, this.boundingBox.minZ() + xOff, orientation, this.getGenDepth(), isCastle ); } } return null; } @Nullable protected StructurePiece generateChildLeft( final NetherFortressPieces.StartPiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int yOff, final int zOff, final boolean isCastle ) { Direction orientation = this.getOrientation(); if (orientation != null) { switch (orientation) { case NORTH: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() - 1, this.boundingBox.minY() + yOff, this.boundingBox.minZ() + zOff, Direction.WEST, this.getGenDepth(), isCastle ); case SOUTH: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() - 1, this.boundingBox.minY() + yOff, this.boundingBox.minZ() + zOff, Direction.WEST, this.getGenDepth(), isCastle ); case WEST: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() + zOff, this.boundingBox.minY() + yOff, this.boundingBox.minZ() - 1, Direction.NORTH, this.getGenDepth(), isCastle ); case EAST: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() + zOff, this.boundingBox.minY() + yOff, this.boundingBox.minZ() - 1, Direction.NORTH, this.getGenDepth(), isCastle ); } } return null; } @Nullable protected StructurePiece generateChildRight( final NetherFortressPieces.StartPiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random, final int yOff, final int zOff, final boolean isCastle ) { Direction orientation = this.getOrientation(); if (orientation != null) { switch (orientation) { case NORTH: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() + yOff, this.boundingBox.minZ() + zOff, Direction.EAST, this.getGenDepth(), isCastle ); case SOUTH: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.maxX() + 1, this.boundingBox.minY() + yOff, this.boundingBox.minZ() + zOff, Direction.EAST, this.getGenDepth(), isCastle ); case WEST: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() + zOff, this.boundingBox.minY() + yOff, this.boundingBox.maxZ() + 1, Direction.SOUTH, this.getGenDepth(), isCastle ); case EAST: return this.generateAndAddPiece( startPiece, structurePieceAccessor, random, this.boundingBox.minX() + zOff, this.boundingBox.minY() + yOff, this.boundingBox.maxZ() + 1, Direction.SOUTH, this.getGenDepth(), isCastle ); } } return null; } protected static boolean isOkBox(final BoundingBox box) { return box.minY() > 10; } } private static class PieceWeight { public final Class pieceClass; public final int weight; public int placeCount; public final int maxPlaceCount; public final boolean allowInRow; public PieceWeight( final Class pieceClass, final int weight, final int maxPlaceCount, final boolean allowInRow ) { this.pieceClass = pieceClass; this.weight = weight; this.maxPlaceCount = maxPlaceCount; this.allowInRow = allowInRow; } public PieceWeight(final Class pieceClass, final int weight, final int maxPlaceCount) { this(pieceClass, weight, maxPlaceCount, false); } public boolean doPlace(final int depth) { return this.maxPlaceCount == 0 || this.placeCount < this.maxPlaceCount; } public boolean isValid() { return this.maxPlaceCount == 0 || this.placeCount < this.maxPlaceCount; } } public static class RoomCrossing extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 7; private static final int HEIGHT = 9; private static final int DEPTH = 7; public RoomCrossing(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_ROOM_CROSSING, genDepth, boundingBox); this.setOrientation(direction); } public RoomCrossing(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_ROOM_CROSSING, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildForward((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 2, 0, false); this.generateChildLeft((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, 2, false); this.generateChildRight((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 0, 2, false); } @Nullable public static NetherFortressPieces.RoomCrossing createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final Direction direction, final int genDepth ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -2, 0, 0, 7, 9, 7, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.RoomCrossing(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 0, 0, 6, 1, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 6, 7, 6, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 1, 6, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 6, 1, 6, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 2, 0, 6, 6, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 2, 6, 6, 6, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 0, 6, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 5, 0, 6, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 2, 0, 6, 6, 1, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 2, 5, 6, 6, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); this.generateBox(level, chunkBB, 2, 6, 0, 4, 6, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 0, 4, 5, 0, weFence, weFence, false); this.generateBox(level, chunkBB, 2, 6, 6, 4, 6, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 6, 4, 5, 6, weFence, weFence, false); this.generateBox(level, chunkBB, 0, 6, 2, 0, 6, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 5, 2, 0, 5, 4, nsFence, nsFence, false); this.generateBox(level, chunkBB, 6, 6, 2, 6, 6, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 5, 2, 6, 5, 4, nsFence, nsFence, false); for (int x = 0; x <= 6; x++) { for (int z = 0; z <= 6; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class StairsRoom extends NetherFortressPieces.NetherBridgePiece { private static final int WIDTH = 7; private static final int HEIGHT = 11; private static final int DEPTH = 7; public StairsRoom(final int genDepth, final BoundingBox boundingBox, final Direction direction) { super(StructurePieceType.NETHER_FORTRESS_STAIRS_ROOM, genDepth, boundingBox); this.setOrientation(direction); } public StairsRoom(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_STAIRS_ROOM, tag); } @Override public void addChildren(final StructurePiece startPiece, final StructurePieceAccessor structurePieceAccessor, final RandomSource random) { this.generateChildRight((NetherFortressPieces.StartPiece)startPiece, structurePieceAccessor, random, 6, 2, false); } @Nullable public static NetherFortressPieces.StairsRoom createPiece( final StructurePieceAccessor structurePieceAccessor, final int footX, final int footY, final int footZ, final int genDepth, final Direction direction ) { BoundingBox box = BoundingBox.orientBox(footX, footY, footZ, -2, 0, 0, 7, 11, 7, direction); return isOkBox(box) && structurePieceAccessor.findCollisionPiece(box) == null ? new NetherFortressPieces.StairsRoom(genDepth, box, direction) : null; } @Override public void postProcess( final WorldGenLevel level, final StructureManager structureManager, final ChunkGenerator generator, final RandomSource random, final BoundingBox chunkBB, final ChunkPos chunkPos, final BlockPos referencePos ) { this.generateBox(level, chunkBB, 0, 0, 0, 6, 1, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 6, 10, 6, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 0, 1, 8, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 5, 2, 0, 6, 8, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 0, 2, 1, 0, 8, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 2, 1, 6, 8, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 2, 6, 5, 8, 6, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); BlockState weFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.WEST, true).setValue(FenceBlock.EAST, true); BlockState nsFence = Blocks.NETHER_BRICK_FENCE.defaultBlockState().setValue(FenceBlock.NORTH, true).setValue(FenceBlock.SOUTH, true); this.generateBox(level, chunkBB, 0, 3, 2, 0, 5, 4, nsFence, nsFence, false); this.generateBox(level, chunkBB, 6, 3, 2, 6, 5, 2, nsFence, nsFence, false); this.generateBox(level, chunkBB, 6, 3, 4, 6, 5, 4, nsFence, nsFence, false); this.placeBlock(level, Blocks.NETHER_BRICKS.defaultBlockState(), 5, 2, 5, chunkBB); this.generateBox(level, chunkBB, 4, 2, 5, 4, 3, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 3, 2, 5, 3, 4, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 2, 5, 2, 5, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 2, 5, 1, 6, 5, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 1, 7, 1, 5, 7, 4, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 6, 8, 2, 6, 8, 4, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 6, 0, 4, 8, 0, Blocks.NETHER_BRICKS.defaultBlockState(), Blocks.NETHER_BRICKS.defaultBlockState(), false); this.generateBox(level, chunkBB, 2, 5, 0, 4, 5, 0, weFence, weFence, false); for (int x = 0; x <= 6; x++) { for (int z = 0; z <= 6; z++) { this.fillColumnDown(level, Blocks.NETHER_BRICKS.defaultBlockState(), x, -1, z, chunkBB); } } } } public static class StartPiece extends NetherFortressPieces.BridgeCrossing { @Nullable private NetherFortressPieces.PieceWeight previousPiece; private final List availableBridgePieces = new ArrayList(); private final List availableCastlePieces = new ArrayList(); public final List pendingChildren = Lists.newArrayList(); public StartPiece(final RandomSource random, final int west, final int north) { super(west, north, getRandomHorizontalDirection(random)); for (NetherFortressPieces.PieceWeight piece : NetherFortressPieces.BRIDGE_PIECE_WEIGHTS) { piece.placeCount = 0; this.availableBridgePieces.add(piece); } for (NetherFortressPieces.PieceWeight piece : NetherFortressPieces.CASTLE_PIECE_WEIGHTS) { piece.placeCount = 0; this.availableCastlePieces.add(piece); } } public StartPiece(final CompoundTag tag) { super(StructurePieceType.NETHER_FORTRESS_START, tag); } } }