package net.minecraft.world.level.biome; import com.mojang.datafixers.util.Pair; import java.util.List; import java.util.function.Consumer; import net.minecraft.SharedConstants; import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup.Provider; import net.minecraft.core.registries.Registries; import net.minecraft.data.registries.VanillaRegistries; import net.minecraft.data.worldgen.TerrainProvider; import net.minecraft.resources.ResourceKey; import net.minecraft.util.ToFloatFunction; import net.minecraft.util.VisibleForDebug; import net.minecraft.util.CubicSpline.Multipoint; import net.minecraft.world.level.biome.Climate.Parameter; import net.minecraft.world.level.biome.Climate.ParameterPoint; import net.minecraft.world.level.levelgen.DensityFunction; import net.minecraft.world.level.levelgen.NoiseRouterData; import net.minecraft.world.level.levelgen.DensityFunction.FunctionContext; import net.minecraft.world.level.levelgen.DensityFunctions.Spline.Coordinate; public final class OverworldBiomeBuilder { private static final float VALLEY_SIZE = 0.05F; private static final float LOW_START = 0.26666668F; public static final float HIGH_START = 0.4F; private static final float HIGH_END = 0.93333334F; private static final float PEAK_SIZE = 0.1F; public static final float PEAK_START = 0.56666666F; private static final float PEAK_END = 0.7666667F; public static final float NEAR_INLAND_START = -0.11F; public static final float MID_INLAND_START = 0.03F; public static final float FAR_INLAND_START = 0.3F; public static final float EROSION_INDEX_1_START = -0.78F; public static final float EROSION_INDEX_2_START = -0.375F; private static final float EROSION_DEEP_DARK_DRYNESS_THRESHOLD = -0.225F; private static final float DEPTH_DEEP_DARK_DRYNESS_THRESHOLD = 0.9F; private final Parameter FULL_RANGE = Parameter.span(-1.0F, 1.0F); private final Parameter[] temperatures = new Parameter[]{ Parameter.span(-1.0F, -0.45F), Parameter.span(-0.45F, -0.15F), Parameter.span(-0.15F, 0.2F), Parameter.span(0.2F, 0.55F), Parameter.span(0.55F, 1.0F) }; private final Parameter[] humidities = new Parameter[]{ Parameter.span(-1.0F, -0.35F), Parameter.span(-0.35F, -0.1F), Parameter.span(-0.1F, 0.1F), Parameter.span(0.1F, 0.3F), Parameter.span(0.3F, 1.0F) }; private final Parameter[] erosions = new Parameter[]{ Parameter.span(-1.0F, -0.78F), Parameter.span(-0.78F, -0.375F), Parameter.span(-0.375F, -0.2225F), Parameter.span(-0.2225F, 0.05F), Parameter.span(0.05F, 0.45F), Parameter.span(0.45F, 0.55F), Parameter.span(0.55F, 1.0F) }; private final Parameter FROZEN_RANGE = this.temperatures[0]; private final Parameter UNFROZEN_RANGE = Parameter.span(this.temperatures[1], this.temperatures[4]); private final Parameter mushroomFieldsContinentalness = Parameter.span(-1.2F, -1.05F); private final Parameter deepOceanContinentalness = Parameter.span(-1.05F, -0.455F); private final Parameter oceanContinentalness = Parameter.span(-0.455F, -0.19F); private final Parameter coastContinentalness = Parameter.span(-0.19F, -0.11F); private final Parameter inlandContinentalness = Parameter.span(-0.11F, 0.55F); private final Parameter nearInlandContinentalness = Parameter.span(-0.11F, 0.03F); private final Parameter midInlandContinentalness = Parameter.span(0.03F, 0.3F); private final Parameter farInlandContinentalness = Parameter.span(0.3F, 1.0F); private final ResourceKey[][] OCEANS = new ResourceKey[][]{ {Biomes.DEEP_FROZEN_OCEAN, Biomes.DEEP_COLD_OCEAN, Biomes.DEEP_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN, Biomes.WARM_OCEAN}, {Biomes.FROZEN_OCEAN, Biomes.COLD_OCEAN, Biomes.OCEAN, Biomes.LUKEWARM_OCEAN, Biomes.WARM_OCEAN} }; private final ResourceKey[][] MIDDLE_BIOMES = new ResourceKey[][]{ {Biomes.SNOWY_PLAINS, Biomes.SNOWY_PLAINS, Biomes.SNOWY_PLAINS, Biomes.SNOWY_TAIGA, Biomes.TAIGA}, {Biomes.PLAINS, Biomes.PLAINS, Biomes.FOREST, Biomes.TAIGA, Biomes.OLD_GROWTH_SPRUCE_TAIGA}, {Biomes.FLOWER_FOREST, Biomes.PLAINS, Biomes.FOREST, Biomes.BIRCH_FOREST, Biomes.DARK_FOREST}, {Biomes.SAVANNA, Biomes.SAVANNA, Biomes.FOREST, Biomes.JUNGLE, Biomes.JUNGLE}, {Biomes.DESERT, Biomes.DESERT, Biomes.DESERT, Biomes.DESERT, Biomes.DESERT} }; private final ResourceKey[][] MIDDLE_BIOMES_VARIANT = new ResourceKey[][]{ {Biomes.ICE_SPIKES, null, Biomes.SNOWY_TAIGA, null, null}, {null, null, null, null, Biomes.OLD_GROWTH_PINE_TAIGA}, {Biomes.SUNFLOWER_PLAINS, null, null, Biomes.OLD_GROWTH_BIRCH_FOREST, null}, {null, null, Biomes.PLAINS, Biomes.SPARSE_JUNGLE, Biomes.BAMBOO_JUNGLE}, {null, null, null, null, null} }; private final ResourceKey[][] PLATEAU_BIOMES = new ResourceKey[][]{ {Biomes.SNOWY_PLAINS, Biomes.SNOWY_PLAINS, Biomes.SNOWY_PLAINS, Biomes.SNOWY_TAIGA, Biomes.SNOWY_TAIGA}, {Biomes.MEADOW, Biomes.MEADOW, Biomes.FOREST, Biomes.TAIGA, Biomes.OLD_GROWTH_SPRUCE_TAIGA}, {Biomes.MEADOW, Biomes.MEADOW, Biomes.MEADOW, Biomes.MEADOW, Biomes.DARK_FOREST}, {Biomes.SAVANNA_PLATEAU, Biomes.SAVANNA_PLATEAU, Biomes.FOREST, Biomes.FOREST, Biomes.JUNGLE}, {Biomes.BADLANDS, Biomes.BADLANDS, Biomes.BADLANDS, Biomes.WOODED_BADLANDS, Biomes.WOODED_BADLANDS} }; private final ResourceKey[][] PLATEAU_BIOMES_VARIANT = new ResourceKey[][]{ {Biomes.ICE_SPIKES, null, null, null, null}, {Biomes.CHERRY_GROVE, null, Biomes.MEADOW, Biomes.MEADOW, Biomes.OLD_GROWTH_PINE_TAIGA}, {Biomes.CHERRY_GROVE, Biomes.CHERRY_GROVE, Biomes.FOREST, Biomes.BIRCH_FOREST, Biomes.PALE_GARDEN}, {null, null, null, null, null}, {Biomes.ERODED_BADLANDS, Biomes.ERODED_BADLANDS, null, null, null} }; private final ResourceKey[][] SHATTERED_BIOMES = new ResourceKey[][]{ {Biomes.WINDSWEPT_GRAVELLY_HILLS, Biomes.WINDSWEPT_GRAVELLY_HILLS, Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_FOREST, Biomes.WINDSWEPT_FOREST}, {Biomes.WINDSWEPT_GRAVELLY_HILLS, Biomes.WINDSWEPT_GRAVELLY_HILLS, Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_FOREST, Biomes.WINDSWEPT_FOREST}, {Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_FOREST, Biomes.WINDSWEPT_FOREST}, {null, null, null, null, null}, {null, null, null, null, null} }; public List spawnTarget() { Parameter parameter = Parameter.point(0.0F); float f = 0.16F; return List.of( new ParameterPoint( this.FULL_RANGE, this.FULL_RANGE, Parameter.span(this.inlandContinentalness, this.FULL_RANGE), this.FULL_RANGE, parameter, Parameter.span(-1.0F, -0.16F), 0L ), new ParameterPoint( this.FULL_RANGE, this.FULL_RANGE, Parameter.span(this.inlandContinentalness, this.FULL_RANGE), this.FULL_RANGE, parameter, Parameter.span(0.16F, 1.0F), 0L ) ); } protected void addBiomes(Consumer>> key) { if (SharedConstants.debugGenerateSquareTerrainWithoutNoise) { this.addDebugBiomes(key); } else { this.addOffCoastBiomes(key); this.addInlandBiomes(key); this.addUndergroundBiomes(key); } } private void addDebugBiomes(Consumer>> key) { Provider provider = VanillaRegistries.createLookup(); HolderGetter holderGetter = provider.lookupOrThrow(Registries.DENSITY_FUNCTION); Coordinate coordinate = new Coordinate(holderGetter.getOrThrow(NoiseRouterData.CONTINENTS)); Coordinate coordinate2 = new Coordinate(holderGetter.getOrThrow(NoiseRouterData.EROSION)); Coordinate coordinate3 = new Coordinate(holderGetter.getOrThrow(NoiseRouterData.RIDGES_FOLDED)); key.accept( Pair.of(Climate.parameters(this.FULL_RANGE, this.FULL_RANGE, this.FULL_RANGE, this.FULL_RANGE, Parameter.point(0.0F), this.FULL_RANGE, 0.01F), Biomes.PLAINS) ); if (TerrainProvider.buildErosionOffsetSpline(coordinate2, coordinate3, -0.15F, 0.0F, 0.0F, 0.1F, 0.0F, -0.03F, false, false, ToFloatFunction.IDENTITY) instanceof Multipoint multipoint ) { ResourceKey resourceKey = Biomes.DESERT; for (float f : multipoint.locations()) { key.accept( Pair.of( Climate.parameters(this.FULL_RANGE, this.FULL_RANGE, this.FULL_RANGE, Parameter.point(f), Parameter.point(0.0F), this.FULL_RANGE, 0.0F), resourceKey ) ); resourceKey = resourceKey == Biomes.DESERT ? Biomes.BADLANDS : Biomes.DESERT; } } if (TerrainProvider.overworldOffset(coordinate, coordinate2, coordinate3, false) instanceof Multipoint multipoint2) { for (float f : multipoint2.locations()) { key.accept( Pair.of( Climate.parameters(this.FULL_RANGE, this.FULL_RANGE, Parameter.point(f), this.FULL_RANGE, Parameter.point(0.0F), this.FULL_RANGE, 0.0F), Biomes.SNOWY_TAIGA ) ); } } } private void addOffCoastBiomes(Consumer>> consumer) { this.addSurfaceBiome( consumer, this.FULL_RANGE, this.FULL_RANGE, this.mushroomFieldsContinentalness, this.FULL_RANGE, this.FULL_RANGE, 0.0F, Biomes.MUSHROOM_FIELDS ); for (int i = 0; i < this.temperatures.length; i++) { Parameter parameter = this.temperatures[i]; this.addSurfaceBiome(consumer, parameter, this.FULL_RANGE, this.deepOceanContinentalness, this.FULL_RANGE, this.FULL_RANGE, 0.0F, this.OCEANS[0][i]); this.addSurfaceBiome(consumer, parameter, this.FULL_RANGE, this.oceanContinentalness, this.FULL_RANGE, this.FULL_RANGE, 0.0F, this.OCEANS[1][i]); } } private void addInlandBiomes(Consumer>> consumer) { this.addMidSlice(consumer, Parameter.span(-1.0F, -0.93333334F)); this.addHighSlice(consumer, Parameter.span(-0.93333334F, -0.7666667F)); this.addPeaks(consumer, Parameter.span(-0.7666667F, -0.56666666F)); this.addHighSlice(consumer, Parameter.span(-0.56666666F, -0.4F)); this.addMidSlice(consumer, Parameter.span(-0.4F, -0.26666668F)); this.addLowSlice(consumer, Parameter.span(-0.26666668F, -0.05F)); this.addValleys(consumer, Parameter.span(-0.05F, 0.05F)); this.addLowSlice(consumer, Parameter.span(0.05F, 0.26666668F)); this.addMidSlice(consumer, Parameter.span(0.26666668F, 0.4F)); this.addHighSlice(consumer, Parameter.span(0.4F, 0.56666666F)); this.addPeaks(consumer, Parameter.span(0.56666666F, 0.7666667F)); this.addHighSlice(consumer, Parameter.span(0.7666667F, 0.93333334F)); this.addMidSlice(consumer, Parameter.span(0.93333334F, 1.0F)); } private void addPeaks(Consumer>> consumer, Parameter param) { for (int i = 0; i < this.temperatures.length; i++) { Parameter parameter = this.temperatures[i]; for (int j = 0; j < this.humidities.length; j++) { Parameter parameter2 = this.humidities[j]; ResourceKey resourceKey = this.pickMiddleBiome(i, j, param); ResourceKey resourceKey2 = this.pickMiddleBiomeOrBadlandsIfHot(i, j, param); ResourceKey resourceKey3 = this.pickMiddleBiomeOrBadlandsIfHotOrSlopeIfCold(i, j, param); ResourceKey resourceKey4 = this.pickPlateauBiome(i, j, param); ResourceKey resourceKey5 = this.pickShatteredBiome(i, j, param); ResourceKey resourceKey6 = this.maybePickWindsweptSavannaBiome(i, j, param, resourceKey5); ResourceKey resourceKey7 = this.pickPeakBiome(i, j, param); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), this.erosions[0], param, 0.0F, resourceKey7 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.nearInlandContinentalness), this.erosions[1], param, 0.0F, resourceKey3 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[1], param, 0.0F, resourceKey7 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.nearInlandContinentalness), Parameter.span(this.erosions[2], this.erosions[3]), param, 0.0F, resourceKey ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[2], param, 0.0F, resourceKey4 ); this.addSurfaceBiome(consumer, parameter, parameter2, this.midInlandContinentalness, this.erosions[3], param, 0.0F, resourceKey2); this.addSurfaceBiome(consumer, parameter, parameter2, this.farInlandContinentalness, this.erosions[3], param, 0.0F, resourceKey4); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), this.erosions[4], param, 0.0F, resourceKey ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.nearInlandContinentalness), this.erosions[5], param, 0.0F, resourceKey6 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[5], param, 0.0F, resourceKey5 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, resourceKey ); } } } private void addHighSlice(Consumer>> consumer, Parameter param) { for (int i = 0; i < this.temperatures.length; i++) { Parameter parameter = this.temperatures[i]; for (int j = 0; j < this.humidities.length; j++) { Parameter parameter2 = this.humidities[j]; ResourceKey resourceKey = this.pickMiddleBiome(i, j, param); ResourceKey resourceKey2 = this.pickMiddleBiomeOrBadlandsIfHot(i, j, param); ResourceKey resourceKey3 = this.pickMiddleBiomeOrBadlandsIfHotOrSlopeIfCold(i, j, param); ResourceKey resourceKey4 = this.pickPlateauBiome(i, j, param); ResourceKey resourceKey5 = this.pickShatteredBiome(i, j, param); ResourceKey resourceKey6 = this.maybePickWindsweptSavannaBiome(i, j, param, resourceKey); ResourceKey resourceKey7 = this.pickSlopeBiome(i, j, param); ResourceKey resourceKey8 = this.pickPeakBiome(i, j, param); this.addSurfaceBiome( consumer, parameter, parameter2, this.coastContinentalness, Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, resourceKey ); this.addSurfaceBiome(consumer, parameter, parameter2, this.nearInlandContinentalness, this.erosions[0], param, 0.0F, resourceKey7); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[0], param, 0.0F, resourceKey8 ); this.addSurfaceBiome(consumer, parameter, parameter2, this.nearInlandContinentalness, this.erosions[1], param, 0.0F, resourceKey3); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[1], param, 0.0F, resourceKey7 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.nearInlandContinentalness), Parameter.span(this.erosions[2], this.erosions[3]), param, 0.0F, resourceKey ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[2], param, 0.0F, resourceKey4 ); this.addSurfaceBiome(consumer, parameter, parameter2, this.midInlandContinentalness, this.erosions[3], param, 0.0F, resourceKey2); this.addSurfaceBiome(consumer, parameter, parameter2, this.farInlandContinentalness, this.erosions[3], param, 0.0F, resourceKey4); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), this.erosions[4], param, 0.0F, resourceKey ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.nearInlandContinentalness), this.erosions[5], param, 0.0F, resourceKey6 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[5], param, 0.0F, resourceKey5 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, resourceKey ); } } } private void addMidSlice(Consumer>> consumer, Parameter param) { this.addSurfaceBiome( consumer, this.FULL_RANGE, this.FULL_RANGE, this.coastContinentalness, Parameter.span(this.erosions[0], this.erosions[2]), param, 0.0F, Biomes.STONY_SHORE ); this.addSurfaceBiome( consumer, Parameter.span(this.temperatures[1], this.temperatures[2]), this.FULL_RANGE, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, Biomes.SWAMP ); this.addSurfaceBiome( consumer, Parameter.span(this.temperatures[3], this.temperatures[4]), this.FULL_RANGE, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, Biomes.MANGROVE_SWAMP ); for (int i = 0; i < this.temperatures.length; i++) { Parameter parameter = this.temperatures[i]; for (int j = 0; j < this.humidities.length; j++) { Parameter parameter2 = this.humidities[j]; ResourceKey resourceKey = this.pickMiddleBiome(i, j, param); ResourceKey resourceKey2 = this.pickMiddleBiomeOrBadlandsIfHot(i, j, param); ResourceKey resourceKey3 = this.pickMiddleBiomeOrBadlandsIfHotOrSlopeIfCold(i, j, param); ResourceKey resourceKey4 = this.pickShatteredBiome(i, j, param); ResourceKey resourceKey5 = this.pickPlateauBiome(i, j, param); ResourceKey resourceKey6 = this.pickBeachBiome(i, j); ResourceKey resourceKey7 = this.maybePickWindsweptSavannaBiome(i, j, param, resourceKey); ResourceKey resourceKey8 = this.pickShatteredCoastBiome(i, j, param); ResourceKey resourceKey9 = this.pickSlopeBiome(i, j, param); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[0], param, 0.0F, resourceKey9 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.nearInlandContinentalness, this.midInlandContinentalness), this.erosions[1], param, 0.0F, resourceKey3 ); this.addSurfaceBiome(consumer, parameter, parameter2, this.farInlandContinentalness, this.erosions[1], param, 0.0F, i == 0 ? resourceKey9 : resourceKey5); this.addSurfaceBiome(consumer, parameter, parameter2, this.nearInlandContinentalness, this.erosions[2], param, 0.0F, resourceKey); this.addSurfaceBiome(consumer, parameter, parameter2, this.midInlandContinentalness, this.erosions[2], param, 0.0F, resourceKey2); this.addSurfaceBiome(consumer, parameter, parameter2, this.farInlandContinentalness, this.erosions[2], param, 0.0F, resourceKey5); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.nearInlandContinentalness), this.erosions[3], param, 0.0F, resourceKey ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[3], param, 0.0F, resourceKey2 ); if (param.max() < 0L) { this.addSurfaceBiome(consumer, parameter, parameter2, this.coastContinentalness, this.erosions[4], param, 0.0F, resourceKey6); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[4], param, 0.0F, resourceKey ); } else { this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), this.erosions[4], param, 0.0F, resourceKey ); } this.addSurfaceBiome(consumer, parameter, parameter2, this.coastContinentalness, this.erosions[5], param, 0.0F, resourceKey8); this.addSurfaceBiome(consumer, parameter, parameter2, this.nearInlandContinentalness, this.erosions[5], param, 0.0F, resourceKey7); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[5], param, 0.0F, resourceKey4 ); if (param.max() < 0L) { this.addSurfaceBiome(consumer, parameter, parameter2, this.coastContinentalness, this.erosions[6], param, 0.0F, resourceKey6); } else { this.addSurfaceBiome(consumer, parameter, parameter2, this.coastContinentalness, this.erosions[6], param, 0.0F, resourceKey); } if (i == 0) { this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, resourceKey ); } } } } private void addLowSlice(Consumer>> consumer, Parameter param) { this.addSurfaceBiome( consumer, this.FULL_RANGE, this.FULL_RANGE, this.coastContinentalness, Parameter.span(this.erosions[0], this.erosions[2]), param, 0.0F, Biomes.STONY_SHORE ); this.addSurfaceBiome( consumer, Parameter.span(this.temperatures[1], this.temperatures[2]), this.FULL_RANGE, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, Biomes.SWAMP ); this.addSurfaceBiome( consumer, Parameter.span(this.temperatures[3], this.temperatures[4]), this.FULL_RANGE, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, Biomes.MANGROVE_SWAMP ); for (int i = 0; i < this.temperatures.length; i++) { Parameter parameter = this.temperatures[i]; for (int j = 0; j < this.humidities.length; j++) { Parameter parameter2 = this.humidities[j]; ResourceKey resourceKey = this.pickMiddleBiome(i, j, param); ResourceKey resourceKey2 = this.pickMiddleBiomeOrBadlandsIfHot(i, j, param); ResourceKey resourceKey3 = this.pickMiddleBiomeOrBadlandsIfHotOrSlopeIfCold(i, j, param); ResourceKey resourceKey4 = this.pickBeachBiome(i, j); ResourceKey resourceKey5 = this.maybePickWindsweptSavannaBiome(i, j, param, resourceKey); ResourceKey resourceKey6 = this.pickShatteredCoastBiome(i, j, param); this.addSurfaceBiome( consumer, parameter, parameter2, this.nearInlandContinentalness, Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, resourceKey2 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, resourceKey3 ); this.addSurfaceBiome( consumer, parameter, parameter2, this.nearInlandContinentalness, Parameter.span(this.erosions[2], this.erosions[3]), param, 0.0F, resourceKey ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), Parameter.span(this.erosions[2], this.erosions[3]), param, 0.0F, resourceKey2 ); this.addSurfaceBiome( consumer, parameter, parameter2, this.coastContinentalness, Parameter.span(this.erosions[3], this.erosions[4]), param, 0.0F, resourceKey4 ); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[4], param, 0.0F, resourceKey ); this.addSurfaceBiome(consumer, parameter, parameter2, this.coastContinentalness, this.erosions[5], param, 0.0F, resourceKey6); this.addSurfaceBiome(consumer, parameter, parameter2, this.nearInlandContinentalness, this.erosions[5], param, 0.0F, resourceKey5); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), this.erosions[5], param, 0.0F, resourceKey ); this.addSurfaceBiome(consumer, parameter, parameter2, this.coastContinentalness, this.erosions[6], param, 0.0F, resourceKey4); if (i == 0) { this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.nearInlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, resourceKey ); } } } } private void addValleys(Consumer>> consumer, Parameter param) { this.addSurfaceBiome( consumer, this.FROZEN_RANGE, this.FULL_RANGE, this.coastContinentalness, Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, param.max() < 0L ? Biomes.STONY_SHORE : Biomes.FROZEN_RIVER ); this.addSurfaceBiome( consumer, this.UNFROZEN_RANGE, this.FULL_RANGE, this.coastContinentalness, Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, param.max() < 0L ? Biomes.STONY_SHORE : Biomes.RIVER ); this.addSurfaceBiome( consumer, this.FROZEN_RANGE, this.FULL_RANGE, this.nearInlandContinentalness, Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, Biomes.FROZEN_RIVER ); this.addSurfaceBiome( consumer, this.UNFROZEN_RANGE, this.FULL_RANGE, this.nearInlandContinentalness, Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, Biomes.RIVER ); this.addSurfaceBiome( consumer, this.FROZEN_RANGE, this.FULL_RANGE, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), Parameter.span(this.erosions[2], this.erosions[5]), param, 0.0F, Biomes.FROZEN_RIVER ); this.addSurfaceBiome( consumer, this.UNFROZEN_RANGE, this.FULL_RANGE, Parameter.span(this.coastContinentalness, this.farInlandContinentalness), Parameter.span(this.erosions[2], this.erosions[5]), param, 0.0F, Biomes.RIVER ); this.addSurfaceBiome(consumer, this.FROZEN_RANGE, this.FULL_RANGE, this.coastContinentalness, this.erosions[6], param, 0.0F, Biomes.FROZEN_RIVER); this.addSurfaceBiome(consumer, this.UNFROZEN_RANGE, this.FULL_RANGE, this.coastContinentalness, this.erosions[6], param, 0.0F, Biomes.RIVER); this.addSurfaceBiome( consumer, Parameter.span(this.temperatures[1], this.temperatures[2]), this.FULL_RANGE, Parameter.span(this.inlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, Biomes.SWAMP ); this.addSurfaceBiome( consumer, Parameter.span(this.temperatures[3], this.temperatures[4]), this.FULL_RANGE, Parameter.span(this.inlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, Biomes.MANGROVE_SWAMP ); this.addSurfaceBiome( consumer, this.FROZEN_RANGE, this.FULL_RANGE, Parameter.span(this.inlandContinentalness, this.farInlandContinentalness), this.erosions[6], param, 0.0F, Biomes.FROZEN_RIVER ); for (int i = 0; i < this.temperatures.length; i++) { Parameter parameter = this.temperatures[i]; for (int j = 0; j < this.humidities.length; j++) { Parameter parameter2 = this.humidities[j]; ResourceKey resourceKey = this.pickMiddleBiomeOrBadlandsIfHot(i, j, param); this.addSurfaceBiome( consumer, parameter, parameter2, Parameter.span(this.midInlandContinentalness, this.farInlandContinentalness), Parameter.span(this.erosions[0], this.erosions[1]), param, 0.0F, resourceKey ); } } } private void addUndergroundBiomes(Consumer>> consume) { this.addUndergroundBiome( consume, this.FULL_RANGE, this.FULL_RANGE, Parameter.span(0.8F, 1.0F), this.FULL_RANGE, this.FULL_RANGE, 0.0F, Biomes.DRIPSTONE_CAVES ); this.addUndergroundBiome(consume, this.FULL_RANGE, Parameter.span(0.7F, 1.0F), this.FULL_RANGE, this.FULL_RANGE, this.FULL_RANGE, 0.0F, Biomes.LUSH_CAVES); this.addBottomBiome( consume, this.FULL_RANGE, this.FULL_RANGE, this.FULL_RANGE, Parameter.span(this.erosions[0], this.erosions[1]), this.FULL_RANGE, 0.0F, Biomes.DEEP_DARK ); } private ResourceKey pickMiddleBiome(int temperature, int humidity, Parameter param) { if (param.max() < 0L) { return this.MIDDLE_BIOMES[temperature][humidity]; } else { ResourceKey resourceKey = this.MIDDLE_BIOMES_VARIANT[temperature][humidity]; return resourceKey == null ? this.MIDDLE_BIOMES[temperature][humidity] : resourceKey; } } private ResourceKey pickMiddleBiomeOrBadlandsIfHot(int temperature, int humidity, Parameter param) { return temperature == 4 ? this.pickBadlandsBiome(humidity, param) : this.pickMiddleBiome(temperature, humidity, param); } private ResourceKey pickMiddleBiomeOrBadlandsIfHotOrSlopeIfCold(int temperature, int humidity, Parameter param) { return temperature == 0 ? this.pickSlopeBiome(temperature, humidity, param) : this.pickMiddleBiomeOrBadlandsIfHot(temperature, humidity, param); } private ResourceKey maybePickWindsweptSavannaBiome(int temperature, int humidity, Parameter param, ResourceKey key) { return temperature > 1 && humidity < 4 && param.max() >= 0L ? Biomes.WINDSWEPT_SAVANNA : key; } private ResourceKey pickShatteredCoastBiome(int temperature, int humidity, Parameter param) { ResourceKey resourceKey = param.max() >= 0L ? this.pickMiddleBiome(temperature, humidity, param) : this.pickBeachBiome(temperature, humidity); return this.maybePickWindsweptSavannaBiome(temperature, humidity, param, resourceKey); } private ResourceKey pickBeachBiome(int temperature, int humidity) { if (temperature == 0) { return Biomes.SNOWY_BEACH; } else { return temperature == 4 ? Biomes.DESERT : Biomes.BEACH; } } private ResourceKey pickBadlandsBiome(int humidity, Parameter param) { if (humidity < 2) { return param.max() < 0L ? Biomes.BADLANDS : Biomes.ERODED_BADLANDS; } else { return humidity < 3 ? Biomes.BADLANDS : Biomes.WOODED_BADLANDS; } } private ResourceKey pickPlateauBiome(int temperature, int humidity, Parameter param) { if (param.max() >= 0L) { ResourceKey resourceKey = this.PLATEAU_BIOMES_VARIANT[temperature][humidity]; if (resourceKey != null) { return resourceKey; } } return this.PLATEAU_BIOMES[temperature][humidity]; } private ResourceKey pickPeakBiome(int temperature, int humidity, Parameter param) { if (temperature <= 2) { return param.max() < 0L ? Biomes.JAGGED_PEAKS : Biomes.FROZEN_PEAKS; } else { return temperature == 3 ? Biomes.STONY_PEAKS : this.pickBadlandsBiome(humidity, param); } } private ResourceKey pickSlopeBiome(int temperature, int humidity, Parameter param) { if (temperature >= 3) { return this.pickPlateauBiome(temperature, humidity, param); } else { return humidity <= 1 ? Biomes.SNOWY_SLOPES : Biomes.GROVE; } } private ResourceKey pickShatteredBiome(int temperature, int humidity, Parameter param) { ResourceKey resourceKey = this.SHATTERED_BIOMES[temperature][humidity]; return resourceKey == null ? this.pickMiddleBiome(temperature, humidity, param) : resourceKey; } private void addSurfaceBiome( Consumer>> consumer, Parameter temperature, Parameter humidity, Parameter continentalness, Parameter erosion, Parameter depth, float weirdness, ResourceKey key ) { consumer.accept(Pair.of(Climate.parameters(temperature, humidity, continentalness, erosion, Parameter.point(0.0F), depth, weirdness), key)); consumer.accept(Pair.of(Climate.parameters(temperature, humidity, continentalness, erosion, Parameter.point(1.0F), depth, weirdness), key)); } private void addUndergroundBiome( Consumer>> consumer, Parameter temperature, Parameter humidity, Parameter continentalness, Parameter erosion, Parameter depth, float weirdness, ResourceKey key ) { consumer.accept(Pair.of(Climate.parameters(temperature, humidity, continentalness, erosion, Parameter.span(0.2F, 0.9F), depth, weirdness), key)); } private void addBottomBiome( Consumer>> consumer, Parameter temerature, Parameter humidity, Parameter continentalness, Parameter erosion, Parameter depth, float weirdness, ResourceKey key ) { consumer.accept(Pair.of(Climate.parameters(temerature, humidity, continentalness, erosion, Parameter.point(1.1F), depth, weirdness), key)); } public static boolean isDeepDarkRegion(DensityFunction erosionFunction, DensityFunction depthFunction, FunctionContext functionContext) { return erosionFunction.compute(functionContext) < -0.225F && depthFunction.compute(functionContext) > 0.9F; } public static String getDebugStringForPeaksAndValleys(double peaksAndValleysData) { if (peaksAndValleysData < NoiseRouterData.peaksAndValleys(0.05F)) { return "Valley"; } else if (peaksAndValleysData < NoiseRouterData.peaksAndValleys(0.26666668F)) { return "Low"; } else if (peaksAndValleysData < NoiseRouterData.peaksAndValleys(0.4F)) { return "Mid"; } else { return peaksAndValleysData < NoiseRouterData.peaksAndValleys(0.56666666F) ? "High" : "Peak"; } } public String getDebugStringForContinentalness(double continentalness) { double d = Climate.quantizeCoord((float)continentalness); if (d < this.mushroomFieldsContinentalness.max()) { return "Mushroom fields"; } else if (d < this.deepOceanContinentalness.max()) { return "Deep ocean"; } else if (d < this.oceanContinentalness.max()) { return "Ocean"; } else if (d < this.coastContinentalness.max()) { return "Coast"; } else if (d < this.nearInlandContinentalness.max()) { return "Near inland"; } else { return d < this.midInlandContinentalness.max() ? "Mid inland" : "Far inland"; } } public String getDebugStringForErosion(double erosion) { return getDebugStringForNoiseValue(erosion, this.erosions); } public String getDebugStringForTemperature(double temperature) { return getDebugStringForNoiseValue(temperature, this.temperatures); } public String getDebugStringForHumidity(double humidity) { return getDebugStringForNoiseValue(humidity, this.humidities); } private static String getDebugStringForNoiseValue(double depth, Parameter[] values) { double d = Climate.quantizeCoord((float)depth); for (int i = 0; i < values.length; i++) { if (d < values[i].max()) { return i + ""; } } return "?"; } @VisibleForDebug public Parameter[] getTemperatureThresholds() { return this.temperatures; } @VisibleForDebug public Parameter[] getHumidityThresholds() { return this.humidities; } @VisibleForDebug public Parameter[] getErosionThresholds() { return this.erosions; } @VisibleForDebug public Parameter[] getContinentalnessThresholds() { return new Parameter[]{ this.mushroomFieldsContinentalness, this.deepOceanContinentalness, this.oceanContinentalness, this.coastContinentalness, this.nearInlandContinentalness, this.midInlandContinentalness, this.farInlandContinentalness }; } @VisibleForDebug public Parameter[] getPeaksAndValleysThresholds() { return new Parameter[]{ Parameter.span(-2.0F, NoiseRouterData.peaksAndValleys(0.05F)), Parameter.span(NoiseRouterData.peaksAndValleys(0.05F), NoiseRouterData.peaksAndValleys(0.26666668F)), Parameter.span(NoiseRouterData.peaksAndValleys(0.26666668F), NoiseRouterData.peaksAndValleys(0.4F)), Parameter.span(NoiseRouterData.peaksAndValleys(0.4F), NoiseRouterData.peaksAndValleys(0.56666666F)), Parameter.span(NoiseRouterData.peaksAndValleys(0.56666666F), 2.0F) }; } @VisibleForDebug public Parameter[] getWeirdnessThresholds() { return new Parameter[]{Parameter.span(-2.0F, 0.0F), Parameter.span(0.0F, 2.0F)}; } }