63 lines
2.1 KiB
Java
63 lines
2.1 KiB
Java
package net.minecraft.server.level;
|
|
|
|
import net.minecraft.SharedConstants;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.SectionPos;
|
|
import net.minecraft.world.level.ChunkPos;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.chunk.LevelChunk;
|
|
import net.minecraft.world.level.levelgen.Heightmap;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public class PlayerRespawnLogic {
|
|
@Nullable
|
|
protected static BlockPos getOverworldRespawnPos(ServerLevel level, int x, int z) {
|
|
boolean bl = level.dimensionType().hasCeiling();
|
|
LevelChunk levelChunk = level.getChunk(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(z));
|
|
int i = bl ? level.getChunkSource().getGenerator().getSpawnHeight(level) : levelChunk.getHeight(Heightmap.Types.MOTION_BLOCKING, x & 15, z & 15);
|
|
if (i < level.getMinY()) {
|
|
return null;
|
|
} else {
|
|
int j = levelChunk.getHeight(Heightmap.Types.WORLD_SURFACE, x & 15, z & 15);
|
|
if (j <= i && j > levelChunk.getHeight(Heightmap.Types.OCEAN_FLOOR, x & 15, z & 15)) {
|
|
return null;
|
|
} else {
|
|
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
|
|
|
for (int k = i + 1; k >= level.getMinY(); k--) {
|
|
mutableBlockPos.set(x, k, z);
|
|
BlockState blockState = level.getBlockState(mutableBlockPos);
|
|
if (!blockState.getFluidState().isEmpty()) {
|
|
break;
|
|
}
|
|
|
|
if (Block.isFaceFull(blockState.getCollisionShape(level, mutableBlockPos), Direction.UP)) {
|
|
return mutableBlockPos.above().immutable();
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
public static BlockPos getSpawnPosInChunk(ServerLevel level, ChunkPos chunkPos) {
|
|
if (SharedConstants.debugVoidTerrain(chunkPos)) {
|
|
return null;
|
|
} else {
|
|
for (int i = chunkPos.getMinBlockX(); i <= chunkPos.getMaxBlockX(); i++) {
|
|
for (int j = chunkPos.getMinBlockZ(); j <= chunkPos.getMaxBlockZ(); j++) {
|
|
BlockPos blockPos = getOverworldRespawnPos(level, i, j);
|
|
if (blockPos != null) {
|
|
return blockPos;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|