package net.minecraft.world.level.biome; import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.Lifecycle; import com.mojang.serialization.MapCodec; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.QuartPos; import net.minecraft.resources.ResourceKey; import net.minecraft.util.VisibleForDebug; import net.minecraft.world.level.biome.Climate.ParameterList; import net.minecraft.world.level.biome.Climate.Sampler; import net.minecraft.world.level.biome.Climate.TargetPoint; import net.minecraft.world.level.levelgen.NoiseRouterData; public class MultiNoiseBiomeSource extends BiomeSource { private static final MapCodec> ENTRY_CODEC = Biome.CODEC.fieldOf("biome"); public static final MapCodec>> DIRECT_CODEC = ParameterList.codec(ENTRY_CODEC).fieldOf("biomes"); private static final MapCodec> PRESET_CODEC = MultiNoiseBiomeSourceParameterList.CODEC .fieldOf("preset") .withLifecycle(Lifecycle.stable()); public static final MapCodec CODEC = Codec.mapEither(DIRECT_CODEC, PRESET_CODEC) .xmap(MultiNoiseBiomeSource::new, multiNoiseBiomeSource -> multiNoiseBiomeSource.parameters); private final Either>, Holder> parameters; private MultiNoiseBiomeSource(Either>, Holder> parameters) { this.parameters = parameters; } public static MultiNoiseBiomeSource createFromList(ParameterList> parameters) { return new MultiNoiseBiomeSource(Either.left(parameters)); } public static MultiNoiseBiomeSource createFromPreset(Holder parameters) { return new MultiNoiseBiomeSource(Either.right(parameters)); } private ParameterList> parameters() { return this.parameters.map(parameterList -> parameterList, holder -> ((MultiNoiseBiomeSourceParameterList)holder.value()).parameters()); } @Override protected Stream> collectPossibleBiomes() { return this.parameters().values().stream().map(Pair::getSecond); } @Override protected MapCodec codec() { return CODEC; } public boolean stable(ResourceKey resourceKey) { Optional> optional = this.parameters.right(); return optional.isPresent() && ((Holder)optional.get()).is(resourceKey); } @Override public Holder getNoiseBiome(int i, int j, int k, Sampler sampler) { return this.getNoiseBiome(sampler.sample(i, j, k)); } @VisibleForDebug public Holder getNoiseBiome(TargetPoint targetPoint) { return this.parameters().findValue(targetPoint); } @Override public void addDebugInfo(List info, BlockPos pos, Sampler sampler) { int i = QuartPos.fromBlock(pos.getX()); int j = QuartPos.fromBlock(pos.getY()); int k = QuartPos.fromBlock(pos.getZ()); TargetPoint targetPoint = sampler.sample(i, j, k); float f = Climate.unquantizeCoord(targetPoint.continentalness()); float g = Climate.unquantizeCoord(targetPoint.erosion()); float h = Climate.unquantizeCoord(targetPoint.temperature()); float l = Climate.unquantizeCoord(targetPoint.humidity()); float m = Climate.unquantizeCoord(targetPoint.weirdness()); double d = NoiseRouterData.peaksAndValleys(m); OverworldBiomeBuilder overworldBiomeBuilder = new OverworldBiomeBuilder(); info.add( "Biome builder PV: " + OverworldBiomeBuilder.getDebugStringForPeaksAndValleys(d) + " C: " + overworldBiomeBuilder.getDebugStringForContinentalness(f) + " E: " + overworldBiomeBuilder.getDebugStringForErosion(g) + " T: " + overworldBiomeBuilder.getDebugStringForTemperature(h) + " H: " + overworldBiomeBuilder.getDebugStringForHumidity(l) ); } }