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

145 lines
4.9 KiB
Java

package net.minecraft.world.level.levelgen;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.HolderSet;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.NoiseColumn;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.biome.FixedBiomeSource;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
import net.minecraft.world.level.levelgen.blending.Blender;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraft.world.level.levelgen.structure.StructureSet;
public class FlatLevelSource extends ChunkGenerator {
public static final MapCodec<FlatLevelSource> CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(FlatLevelGeneratorSettings.CODEC.fieldOf("settings").forGetter(FlatLevelSource::settings))
.apply(instance, instance.stable(FlatLevelSource::new))
);
private final FlatLevelGeneratorSettings settings;
public FlatLevelSource(FlatLevelGeneratorSettings settings) {
super(new FixedBiomeSource(settings.getBiome()), Util.memoize(settings::adjustGenerationSettings));
this.settings = settings;
}
@Override
public ChunkGeneratorStructureState createState(HolderLookup<StructureSet> structureSetLookup, RandomState randomState, long seed) {
Stream<Holder<StructureSet>> stream = (Stream<Holder<StructureSet>>)this.settings
.structureOverrides()
.map(HolderSet::stream)
.orElseGet(() -> structureSetLookup.listElements().map(reference -> reference));
return ChunkGeneratorStructureState.createForFlat(randomState, seed, this.biomeSource, stream);
}
@Override
protected MapCodec<? extends ChunkGenerator> codec() {
return CODEC;
}
public FlatLevelGeneratorSettings settings() {
return this.settings;
}
@Override
public void buildSurface(WorldGenRegion level, StructureManager structureManager, RandomState random, ChunkAccess chunk) {
}
@Override
public int getSpawnHeight(LevelHeightAccessor level) {
return level.getMinY() + Math.min(level.getHeight(), this.settings.getLayers().size());
}
@Override
public CompletableFuture<ChunkAccess> fillFromNoise(Blender blender, RandomState randomState, StructureManager structureManager, ChunkAccess chunk) {
List<BlockState> list = this.settings.getLayers();
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
Heightmap heightmap = chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.OCEAN_FLOOR_WG);
Heightmap heightmap2 = chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE_WG);
for (int i = 0; i < Math.min(chunk.getHeight(), list.size()); i++) {
BlockState blockState = (BlockState)list.get(i);
if (blockState != null) {
int j = chunk.getMinY() + i;
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
chunk.setBlockState(mutableBlockPos.set(k, j, l), blockState);
heightmap.update(k, j, l, blockState);
heightmap2.update(k, j, l, blockState);
}
}
}
}
return CompletableFuture.completedFuture(chunk);
}
@Override
public int getBaseHeight(int x, int z, Heightmap.Types type, LevelHeightAccessor level, RandomState random) {
List<BlockState> list = this.settings.getLayers();
for (int i = Math.min(list.size() - 1, level.getMaxY()); i >= 0; i--) {
BlockState blockState = (BlockState)list.get(i);
if (blockState != null && type.isOpaque().test(blockState)) {
return level.getMinY() + i + 1;
}
}
return level.getMinY();
}
@Override
public NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor height, RandomState random) {
return new NoiseColumn(
height.getMinY(),
(BlockState[])this.settings
.getLayers()
.stream()
.limit(height.getHeight())
.map(blockState -> blockState == null ? Blocks.AIR.defaultBlockState() : blockState)
.toArray(BlockState[]::new)
);
}
@Override
public void addDebugScreenInfo(List<String> info, RandomState random, BlockPos pos) {
}
@Override
public void applyCarvers(WorldGenRegion level, long seed, RandomState random, BiomeManager biomeManager, StructureManager structureManager, ChunkAccess chunk) {
}
@Override
public void spawnOriginalMobs(WorldGenRegion level) {
}
@Override
public int getMinY() {
return 0;
}
@Override
public int getGenDepth() {
return 384;
}
@Override
public int getSeaLevel() {
return -63;
}
}