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

137 lines
6.7 KiB
Java

package net.minecraft.world.level.levelgen.structure.structures;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.ServerLevelAccessor;
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.Mirror;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
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.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.StructurePieceAccessor;
import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor;
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
public class IglooPieces {
public static final int GENERATION_HEIGHT = 90;
static final ResourceLocation STRUCTURE_LOCATION_IGLOO = ResourceLocation.withDefaultNamespace("igloo/top");
private static final ResourceLocation STRUCTURE_LOCATION_LADDER = ResourceLocation.withDefaultNamespace("igloo/middle");
private static final ResourceLocation STRUCTURE_LOCATION_LABORATORY = ResourceLocation.withDefaultNamespace("igloo/bottom");
static final Map<ResourceLocation, BlockPos> PIVOTS = ImmutableMap.of(
STRUCTURE_LOCATION_IGLOO, new BlockPos(3, 5, 5), STRUCTURE_LOCATION_LADDER, new BlockPos(1, 3, 1), STRUCTURE_LOCATION_LABORATORY, new BlockPos(3, 6, 7)
);
static final Map<ResourceLocation, BlockPos> OFFSETS = ImmutableMap.of(
STRUCTURE_LOCATION_IGLOO, BlockPos.ZERO, STRUCTURE_LOCATION_LADDER, new BlockPos(2, -3, 4), STRUCTURE_LOCATION_LABORATORY, new BlockPos(0, -3, -2)
);
public static void addPieces(
StructureTemplateManager structureTemplateManager, BlockPos startPos, Rotation rotation, StructurePieceAccessor pieces, RandomSource random
) {
if (random.nextDouble() < 0.5) {
int i = random.nextInt(8) + 4;
pieces.addPiece(new IglooPieces.IglooPiece(structureTemplateManager, STRUCTURE_LOCATION_LABORATORY, startPos, rotation, i * 3));
for (int j = 0; j < i - 1; j++) {
pieces.addPiece(new IglooPieces.IglooPiece(structureTemplateManager, STRUCTURE_LOCATION_LADDER, startPos, rotation, j * 3));
}
}
pieces.addPiece(new IglooPieces.IglooPiece(structureTemplateManager, STRUCTURE_LOCATION_IGLOO, startPos, rotation, 0));
}
public static class IglooPiece extends TemplateStructurePiece {
public IglooPiece(StructureTemplateManager structureTemplateManager, ResourceLocation location, BlockPos startPos, Rotation rotation, int down) {
super(
StructurePieceType.IGLOO,
0,
structureTemplateManager,
location,
location.toString(),
makeSettings(rotation, location),
makePosition(location, startPos, down)
);
}
public IglooPiece(StructureTemplateManager structureTemplateManager, CompoundTag tag) {
super(
StructurePieceType.IGLOO,
tag,
structureTemplateManager,
resourceLocation -> makeSettings((Rotation)tag.read("Rot", Rotation.LEGACY_CODEC).orElseThrow(), resourceLocation)
);
}
private static StructurePlaceSettings makeSettings(Rotation rotation, ResourceLocation location) {
return new StructurePlaceSettings()
.setRotation(rotation)
.setMirror(Mirror.NONE)
.setRotationPivot((BlockPos)IglooPieces.PIVOTS.get(location))
.addProcessor(BlockIgnoreProcessor.STRUCTURE_BLOCK)
.setLiquidSettings(LiquidSettings.IGNORE_WATERLOGGING);
}
private static BlockPos makePosition(ResourceLocation location, BlockPos pos, int down) {
return pos.offset((Vec3i)IglooPieces.OFFSETS.get(location)).below(down);
}
@Override
protected void addAdditionalSaveData(StructurePieceSerializationContext context, CompoundTag tag) {
super.addAdditionalSaveData(context, tag);
tag.store("Rot", Rotation.LEGACY_CODEC, this.placeSettings.getRotation());
}
@Override
protected void handleDataMarker(String name, BlockPos pos, ServerLevelAccessor level, RandomSource random, BoundingBox box) {
if ("chest".equals(name)) {
level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
BlockEntity blockEntity = level.getBlockEntity(pos.below());
if (blockEntity instanceof ChestBlockEntity) {
((ChestBlockEntity)blockEntity).setLootTable(BuiltInLootTables.IGLOO_CHEST, random.nextLong());
}
}
}
@Override
public void postProcess(
WorldGenLevel level, StructureManager structureManager, ChunkGenerator generator, RandomSource random, BoundingBox box, ChunkPos chunkPos, BlockPos pos
) {
ResourceLocation resourceLocation = ResourceLocation.parse(this.templateName);
StructurePlaceSettings structurePlaceSettings = makeSettings(this.placeSettings.getRotation(), resourceLocation);
BlockPos blockPos = (BlockPos)IglooPieces.OFFSETS.get(resourceLocation);
BlockPos blockPos2 = this.templatePosition
.offset(StructureTemplate.calculateRelativePosition(structurePlaceSettings, new BlockPos(3 - blockPos.getX(), 0, -blockPos.getZ())));
int i = level.getHeight(Heightmap.Types.WORLD_SURFACE_WG, blockPos2.getX(), blockPos2.getZ());
BlockPos blockPos3 = this.templatePosition;
this.templatePosition = this.templatePosition.offset(0, i - 90 - 1, 0);
super.postProcess(level, structureManager, generator, random, box, chunkPos, pos);
if (resourceLocation.equals(IglooPieces.STRUCTURE_LOCATION_IGLOO)) {
BlockPos blockPos4 = this.templatePosition.offset(StructureTemplate.calculateRelativePosition(structurePlaceSettings, new BlockPos(3, 0, 5)));
BlockState blockState = level.getBlockState(blockPos4.below());
if (!blockState.isAir() && !blockState.is(Blocks.LADDER)) {
level.setBlock(blockPos4, Blocks.SNOW_BLOCK.defaultBlockState(), 3);
}
}
this.templatePosition = blockPos3;
}
}
}