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

146 lines
5 KiB
Java

package net.minecraft.world.level.levelgen.structure;
import com.mojang.logging.LogUtils;
import java.util.List;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.PiecesContainer;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
import net.minecraft.world.level.levelgen.structure.structures.OceanMonumentStructure;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
public final class StructureStart {
public static final String INVALID_START_ID = "INVALID";
public static final StructureStart INVALID_START = new StructureStart(null, new ChunkPos(0, 0), 0, new PiecesContainer(List.of()));
private static final Logger LOGGER = LogUtils.getLogger();
private final Structure structure;
private final PiecesContainer pieceContainer;
private final ChunkPos chunkPos;
private int references;
@Nullable
private volatile BoundingBox cachedBoundingBox;
public StructureStart(Structure structure, ChunkPos chunkPos, int references, PiecesContainer pieceContainer) {
this.structure = structure;
this.chunkPos = chunkPos;
this.references = references;
this.pieceContainer = pieceContainer;
}
@Nullable
public static StructureStart loadStaticStart(StructurePieceSerializationContext context, CompoundTag tag, long seed) {
String string = tag.getStringOr("id", "");
if ("INVALID".equals(string)) {
return INVALID_START;
} else {
Registry<Structure> registry = context.registryAccess().lookupOrThrow(Registries.STRUCTURE);
Structure structure = registry.getValue(ResourceLocation.parse(string));
if (structure == null) {
LOGGER.error("Unknown stucture id: {}", string);
return null;
} else {
ChunkPos chunkPos = new ChunkPos(tag.getIntOr("ChunkX", 0), tag.getIntOr("ChunkZ", 0));
int i = tag.getIntOr("references", 0);
ListTag listTag = tag.getListOrEmpty("Children");
try {
PiecesContainer piecesContainer = PiecesContainer.load(listTag, context);
if (structure instanceof OceanMonumentStructure) {
piecesContainer = OceanMonumentStructure.regeneratePiecesAfterLoad(chunkPos, seed, piecesContainer);
}
return new StructureStart(structure, chunkPos, i, piecesContainer);
} catch (Exception var11) {
LOGGER.error("Failed Start with id {}", string, var11);
return null;
}
}
}
}
public BoundingBox getBoundingBox() {
BoundingBox boundingBox = this.cachedBoundingBox;
if (boundingBox == null) {
boundingBox = this.structure.adjustBoundingBox(this.pieceContainer.calculateBoundingBox());
this.cachedBoundingBox = boundingBox;
}
return boundingBox;
}
public void placeInChunk(
WorldGenLevel level, StructureManager structureManager, ChunkGenerator generator, RandomSource random, BoundingBox box, ChunkPos chunkPos
) {
List<StructurePiece> list = this.pieceContainer.pieces();
if (!list.isEmpty()) {
BoundingBox boundingBox = ((StructurePiece)list.get(0)).boundingBox;
BlockPos blockPos = boundingBox.getCenter();
BlockPos blockPos2 = new BlockPos(blockPos.getX(), boundingBox.minY(), blockPos.getZ());
for (StructurePiece structurePiece : list) {
if (structurePiece.getBoundingBox().intersects(box)) {
structurePiece.postProcess(level, structureManager, generator, random, box, chunkPos, blockPos2);
}
}
this.structure.afterPlace(level, structureManager, generator, random, box, chunkPos, this.pieceContainer);
}
}
public CompoundTag createTag(StructurePieceSerializationContext context, ChunkPos chunkPos) {
CompoundTag compoundTag = new CompoundTag();
if (this.isValid()) {
compoundTag.putString("id", context.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.structure).toString());
compoundTag.putInt("ChunkX", chunkPos.x);
compoundTag.putInt("ChunkZ", chunkPos.z);
compoundTag.putInt("references", this.references);
compoundTag.put("Children", this.pieceContainer.save(context));
return compoundTag;
} else {
compoundTag.putString("id", "INVALID");
return compoundTag;
}
}
public boolean isValid() {
return !this.pieceContainer.isEmpty();
}
public ChunkPos getChunkPos() {
return this.chunkPos;
}
public boolean canBeReferenced() {
return this.references < this.getMaxReferences();
}
public void addReference() {
this.references++;
}
public int getReferences() {
return this.references;
}
protected int getMaxReferences() {
return 1;
}
public Structure getStructure() {
return this.structure;
}
public List<StructurePiece> getPieces() {
return this.pieceContainer.pieces();
}
}