package net.minecraft.world.level.levelgen.structure.structures; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Optional; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.levelgen.Heightmap.Types; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.StructureType; import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; import net.minecraft.world.level.levelgen.structure.structures.ShipwreckPieces.ShipwreckPiece; public class ShipwreckStructure extends Structure { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( instance -> instance.group(settingsCodec(instance), Codec.BOOL.fieldOf("is_beached").forGetter(shipwreckStructure -> shipwreckStructure.isBeached)) .apply(instance, ShipwreckStructure::new) ); public final boolean isBeached; public ShipwreckStructure(Structure.StructureSettings settings, boolean isBeached) { super(settings); this.isBeached = isBeached; } @Override public Optional findGenerationPoint(Structure.GenerationContext context) { Types types = this.isBeached ? Types.WORLD_SURFACE_WG : Types.OCEAN_FLOOR_WG; return onTopOfChunkCenter(context, types, structurePiecesBuilder -> this.generatePieces(structurePiecesBuilder, context)); } private void generatePieces(StructurePiecesBuilder builder, Structure.GenerationContext context) { Rotation rotation = Rotation.getRandom(context.random()); BlockPos blockPos = new BlockPos(context.chunkPos().getMinBlockX(), 90, context.chunkPos().getMinBlockZ()); ShipwreckPiece shipwreckPiece = ShipwreckPieces.addRandomPiece( context.structureTemplateManager(), blockPos, rotation, builder, context.random(), this.isBeached ); if (shipwreckPiece.isTooBigToFitInWorldGenRegion()) { BoundingBox boundingBox = shipwreckPiece.getBoundingBox(); int j; if (this.isBeached) { int i = Structure.getLowestY(context, boundingBox.minX(), boundingBox.getXSpan(), boundingBox.minZ(), boundingBox.getZSpan()); j = shipwreckPiece.calculateBeachedPosition(i, context.random()); } else { j = Structure.getMeanFirstOccupiedHeight(context, boundingBox.minX(), boundingBox.getXSpan(), boundingBox.minZ(), boundingBox.getZSpan()); } shipwreckPiece.adjustPositionHeight(j); } } @Override public StructureType type() { return StructureType.SHIPWRECK; } }