minecraft-src/net/minecraft/world/level/levelgen/structure/structures/MineshaftStructure.java
2025-07-04 03:45:38 +03:00

120 lines
4.8 KiB
Java

package net.minecraft.world.level.levelgen.structure.structures;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.Optional;
import java.util.function.IntFunction;
import net.minecraft.core.BlockPos;
import net.minecraft.util.ByIdMap;
import net.minecraft.util.Mth;
import net.minecraft.util.StringRepresentable;
import net.minecraft.util.ByIdMap.OutOfBoundsStrategy;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.StructureType;
import net.minecraft.world.level.levelgen.structure.Structure.GenerationContext;
import net.minecraft.world.level.levelgen.structure.Structure.GenerationStub;
import net.minecraft.world.level.levelgen.structure.Structure.StructureSettings;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
public class MineshaftStructure extends Structure {
public static final MapCodec<MineshaftStructure> CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(
settingsCodec(instance), MineshaftStructure.Type.CODEC.fieldOf("mineshaft_type").forGetter(mineshaftStructure -> mineshaftStructure.type)
)
.apply(instance, MineshaftStructure::new)
);
private final MineshaftStructure.Type type;
public MineshaftStructure(StructureSettings settings, MineshaftStructure.Type type) {
super(settings);
this.type = type;
}
@Override
public Optional<GenerationStub> findGenerationPoint(GenerationContext context) {
context.random().nextDouble();
ChunkPos chunkPos = context.chunkPos();
BlockPos blockPos = new BlockPos(chunkPos.getMiddleBlockX(), 50, chunkPos.getMinBlockZ());
StructurePiecesBuilder structurePiecesBuilder = new StructurePiecesBuilder();
int i = this.generatePiecesAndAdjust(structurePiecesBuilder, context);
return Optional.of(new GenerationStub(blockPos.offset(0, i, 0), Either.right(structurePiecesBuilder)));
}
private int generatePiecesAndAdjust(StructurePiecesBuilder builder, GenerationContext context) {
ChunkPos chunkPos = context.chunkPos();
WorldgenRandom worldgenRandom = context.random();
ChunkGenerator chunkGenerator = context.chunkGenerator();
MineshaftPieces.MineShaftRoom mineShaftRoom = new MineshaftPieces.MineShaftRoom(0, worldgenRandom, chunkPos.getBlockX(2), chunkPos.getBlockZ(2), this.type);
builder.addPiece(mineShaftRoom);
mineShaftRoom.addChildren(mineShaftRoom, builder, worldgenRandom);
int i = chunkGenerator.getSeaLevel();
if (this.type == MineshaftStructure.Type.MESA) {
BlockPos blockPos = builder.getBoundingBox().getCenter();
int j = chunkGenerator.getBaseHeight(blockPos.getX(), blockPos.getZ(), Heightmap.Types.WORLD_SURFACE_WG, context.heightAccessor(), context.randomState());
int k = j <= i ? i : Mth.randomBetweenInclusive(worldgenRandom, i, j);
int l = k - blockPos.getY();
builder.offsetPiecesVertically(l);
return l;
} else {
return builder.moveBelowSeaLevel(i, chunkGenerator.getMinY(), worldgenRandom, 10);
}
}
@Override
public StructureType<?> type() {
return StructureType.MINESHAFT;
}
public static enum Type implements StringRepresentable {
NORMAL("normal", Blocks.OAK_LOG, Blocks.OAK_PLANKS, Blocks.OAK_FENCE),
MESA("mesa", Blocks.DARK_OAK_LOG, Blocks.DARK_OAK_PLANKS, Blocks.DARK_OAK_FENCE);
public static final Codec<MineshaftStructure.Type> CODEC = StringRepresentable.fromEnum(MineshaftStructure.Type::values);
private static final IntFunction<MineshaftStructure.Type> BY_ID = ByIdMap.continuous(Enum::ordinal, values(), OutOfBoundsStrategy.ZERO);
private final String name;
private final BlockState woodState;
private final BlockState planksState;
private final BlockState fenceState;
private Type(final String name, final Block woodBlock, final Block planksBlock, final Block fenceBlock) {
this.name = name;
this.woodState = woodBlock.defaultBlockState();
this.planksState = planksBlock.defaultBlockState();
this.fenceState = fenceBlock.defaultBlockState();
}
public String getName() {
return this.name;
}
public static MineshaftStructure.Type byId(int id) {
return (MineshaftStructure.Type)BY_ID.apply(id);
}
public BlockState getWoodState() {
return this.woodState;
}
public BlockState getPlanksState() {
return this.planksState;
}
public BlockState getFenceState() {
return this.fenceState;
}
@Override
public String getSerializedName() {
return this.name;
}
}
}