diff --git a/feature-patches/1042-Flat-bedrock-generator-settings.patch b/feature-patches/1042-Flat-bedrock-generator-settings.patch deleted file mode 100644 index 4d8c54d243..0000000000 --- a/feature-patches/1042-Flat-bedrock-generator-settings.patch +++ /dev/null @@ -1,292 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Byteflux -Date: Wed, 2 Mar 2016 02:17:54 -0600 -Subject: [PATCH] Flat bedrock generator settings - -== AT == -public net.minecraft.world.level.levelgen.SurfaceRules$Condition -public net.minecraft.world.level.levelgen.SurfaceRules$Context -public net.minecraft.world.level.levelgen.SurfaceRules$Context blockX -public net.minecraft.world.level.levelgen.SurfaceRules$Context blockY -public net.minecraft.world.level.levelgen.SurfaceRules$Context blockZ -public net.minecraft.world.level.levelgen.SurfaceRules$Context context -public net.minecraft.world.level.levelgen.SurfaceRules$Context randomState -public net.minecraft.world.level.levelgen.SurfaceRules$LazyYCondition -public net.minecraft.world.level.levelgen.SurfaceRules$LazyCondition -public net.minecraft.world.level.levelgen.SurfaceRules$VerticalGradientConditionSource -public net.minecraft.world.level.levelgen.SurfaceRules$SurfaceRule - -Co-authored-by: Noah van der Aa - -diff --git a/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java b/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java -@@ -0,0 +0,0 @@ -+package io.papermc.paper.world.worldgen; -+ -+import com.mojang.serialization.Codec; -+import com.mojang.serialization.MapCodec; -+import com.mojang.serialization.codecs.RecordCodecBuilder; -+import net.minecraft.core.Registry; -+import net.minecraft.core.registries.BuiltInRegistries; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.resources.ResourceKey; -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.util.KeyDispatchDataCodec; -+import net.minecraft.util.Mth; -+import net.minecraft.util.RandomSource; -+import net.minecraft.world.level.levelgen.PositionalRandomFactory; -+import net.minecraft.world.level.levelgen.SurfaceRules; -+import net.minecraft.world.level.levelgen.VerticalAnchor; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+// Modelled off of SurfaceRules$VerticalGradientConditionSource -+@DefaultQualifier(NonNull.class) -+public record OptionallyFlatBedrockConditionSource(ResourceLocation randomName, VerticalAnchor trueAtAndBelow, VerticalAnchor falseAtAndAbove, boolean isRoof) implements SurfaceRules.ConditionSource { -+ -+ private static final ResourceKey> CODEC_RESOURCE_KEY = ResourceKey.create( -+ Registries.MATERIAL_CONDITION, -+ ResourceLocation.fromNamespaceAndPath(ResourceLocation.PAPER_NAMESPACE, "optionally_flat_bedrock_condition_source") -+ ); -+ private static final KeyDispatchDataCodec CODEC = KeyDispatchDataCodec.of(RecordCodecBuilder.mapCodec((instance) -> { -+ return instance.group( -+ ResourceLocation.CODEC.fieldOf("random_name").forGetter(OptionallyFlatBedrockConditionSource::randomName), -+ VerticalAnchor.CODEC.fieldOf("true_at_and_below").forGetter(OptionallyFlatBedrockConditionSource::trueAtAndBelow), -+ VerticalAnchor.CODEC.fieldOf("false_at_and_above").forGetter(OptionallyFlatBedrockConditionSource::falseAtAndAbove), -+ Codec.BOOL.fieldOf("is_roof").forGetter(OptionallyFlatBedrockConditionSource::isRoof) -+ ).apply(instance, OptionallyFlatBedrockConditionSource::new); -+ })); -+ -+ public static void bootstrap() { -+ Registry.register(BuiltInRegistries.MATERIAL_CONDITION, CODEC_RESOURCE_KEY, CODEC.codec()); -+ } -+ -+ @Override -+ public KeyDispatchDataCodec codec() { -+ return CODEC; -+ } -+ -+ @Override -+ public SurfaceRules.Condition apply(final SurfaceRules.Context context) { -+ boolean hasFlatBedrock = context.context.getWorld().paperConfig().environment.generateFlatBedrock; -+ int tempTrueAtAndBelowY = this.trueAtAndBelow().resolveY(context.context); -+ int tempFalseAtAndAboveY = this.falseAtAndAbove().resolveY(context.context); -+ -+ int flatYLevel = this.isRoof ? Math.max(tempFalseAtAndAboveY, tempTrueAtAndBelowY) - 1 : Math.min(tempFalseAtAndAboveY, tempTrueAtAndBelowY); -+ final int trueAtAndBelowY = hasFlatBedrock ? flatYLevel : tempTrueAtAndBelowY; -+ final int falseAtAndAboveY = hasFlatBedrock ? flatYLevel : tempFalseAtAndAboveY; -+ -+ final PositionalRandomFactory positionalRandomFactory = context.randomState.getOrCreateRandomFactory(this.randomName()); -+ -+ class VerticalGradientCondition extends SurfaceRules.LazyYCondition { -+ VerticalGradientCondition(SurfaceRules.Context context) { -+ super(context); -+ } -+ -+ @Override -+ protected boolean compute() { -+ int blockY = this.context.blockY; -+ if (blockY <= trueAtAndBelowY) { -+ return true; -+ } else if (blockY >= falseAtAndAboveY) { -+ return false; -+ } else { -+ double d = Mth.map(blockY, trueAtAndBelowY, falseAtAndAboveY, 1.0D, 0.0D); -+ RandomSource randomSource = positionalRandomFactory.at(this.context.blockX, blockY, this.context.blockZ); -+ return (double)randomSource.nextFloat() < d; -+ } -+ } -+ } -+ -+ return new VerticalGradientCondition(context); -+ } -+} -diff --git a/src/main/java/net/minecraft/server/Bootstrap.java b/src/main/java/net/minecraft/server/Bootstrap.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/Bootstrap.java -+++ b/src/main/java/net/minecraft/server/Bootstrap.java -@@ -0,0 +0,0 @@ public class Bootstrap { - CauldronInteraction.bootStrap(); - // Paper start - BuiltInRegistries.bootStrap(() -> { -+ io.papermc.paper.world.worldgen.OptionallyFlatBedrockConditionSource.bootstrap(); // Paper - Flat bedrock generator settings - }); - // Paper end - CreativeModeTabs.validate(); -diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - @Override - public void buildSurface(WorldGenRegion region, StructureManager structures, RandomState noiseConfig, ChunkAccess chunk) { - if (!SharedConstants.debugVoidTerrain(chunk.getPos())) { -- WorldGenerationContext worldgenerationcontext = new WorldGenerationContext(this, region); -+ WorldGenerationContext worldgenerationcontext = new WorldGenerationContext(this, region, region.getMinecraftWorld()); // Paper - Flat bedrock generator settings - - this.buildSurface(chunk, worldgenerationcontext, noiseConfig, structures, region.getBiomeManager(), region.registryAccess().lookupOrThrow(Registries.BIOME), Blender.of(region)); - } -@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - return this.createNoiseChunk(ichunkaccess1, structureAccessor, Blender.of(chunkRegion), noiseConfig); - }); - Aquifer aquifer = noisechunk.aquifer(); -- CarvingContext carvingcontext = new CarvingContext(this, chunkRegion.registryAccess(), chunk.getHeightAccessorForGeneration(), noisechunk, noiseConfig, ((NoiseGeneratorSettings) this.settings.value()).surfaceRule()); -+ CarvingContext carvingcontext = new CarvingContext(this, chunkRegion.registryAccess(), chunk.getHeightAccessorForGeneration(), noisechunk, noiseConfig, ((NoiseGeneratorSettings) this.settings.value()).surfaceRule(), chunkRegion.getMinecraftWorld()); // Paper - Flat bedrock generator settings - CarvingMask carvingmask = ((ProtoChunk) chunk).getOrCreateCarvingMask(); - - for (int j = -8; j <= 8; ++j) { -diff --git a/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java b/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java -@@ -0,0 +0,0 @@ import net.minecraft.world.level.chunk.ChunkGenerator; - public class WorldGenerationContext { - private final int minY; - private final int height; -+ private final @javax.annotation.Nullable net.minecraft.world.level.Level level; // Paper - Flat bedrock generator settings - -- public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world) { -+ public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world) { this(generator, world, null); } // Paper - Flat bedrock generator settings -+ public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world, @org.jetbrains.annotations.Nullable net.minecraft.world.level.Level level) { // Paper - Flat bedrock generator settings - this.minY = Math.max(world.getMinY(), generator.getMinY()); - this.height = Math.min(world.getHeight(), generator.getGenDepth()); -+ this.level = level; // Paper - Flat bedrock generator settings - } - - public int getMinGenY() { -@@ -0,0 +0,0 @@ public class WorldGenerationContext { - public int getGenDepth() { - return this.height; - } -+ -+ // Paper start - Flat bedrock generator settings -+ public net.minecraft.world.level.Level getWorld() { -+ if (this.level == null) { -+ throw new NullPointerException("WorldGenerationContext was initialized without a Level, but WorldGenerationContext#getWorld was called"); -+ } -+ return this.level; -+ } -+ // Paper end - Flat bedrock generator settings - } -diff --git a/src/main/java/net/minecraft/world/level/levelgen/carver/CarvingContext.java b/src/main/java/net/minecraft/world/level/levelgen/carver/CarvingContext.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/carver/CarvingContext.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/carver/CarvingContext.java -@@ -0,0 +0,0 @@ public class CarvingContext extends WorldGenerationContext { - LevelHeightAccessor heightLimitView, - NoiseChunk chunkNoiseSampler, - RandomState noiseConfig, -- SurfaceRules.RuleSource materialRule -+ SurfaceRules.RuleSource materialRule, @javax.annotation.Nullable net.minecraft.world.level.Level level // Paper - Flat bedrock generator settings - ) { -- super(noiseChunkGenerator, heightLimitView); -+ super(noiseChunkGenerator, heightLimitView, level); // Paper - Flat bedrock generator settings - this.registryAccess = registryManager; - this.noiseChunk = chunkNoiseSampler; - this.randomState = noiseConfig; -diff --git a/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java b/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java -@@ -0,0 +0,0 @@ public class PlacementContext extends WorldGenerationContext { - private final Optional topFeature; - - public PlacementContext(WorldGenLevel world, ChunkGenerator generator, Optional placedFeature) { -- super(generator, world); -+ super(generator, world, world.getLevel()); // Paper - Flat bedrock generator settings - this.level = world; - this.generator = generator; - this.topFeature = placedFeature; -diff --git a/src/main/resources/data/minecraft/worldgen/noise_settings/amplified.json b/src/main/resources/data/minecraft/worldgen/noise_settings/amplified.json -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/resources/data/minecraft/worldgen/noise_settings/amplified.json -+++ b/src/main/resources/data/minecraft/worldgen/noise_settings/amplified.json -@@ -0,0 +0,0 @@ - { - "type": "minecraft:condition", - "if_true": { -- "type": "minecraft:vertical_gradient", -+ "type": "paper:optionally_flat_bedrock_condition_source", -+ "is_roof": false, - "false_at_and_above": { - "above_bottom": 5 - }, -diff --git a/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json b/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json -+++ b/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json -@@ -0,0 +0,0 @@ - "if_true": { - "type": "minecraft:not", - "invert": { -- "type": "minecraft:vertical_gradient", -+ "type": "paper:optionally_flat_bedrock_condition_source", -+ "is_roof": true, - "false_at_and_above": { - "below_top": 0 - }, -@@ -0,0 +0,0 @@ - { - "type": "minecraft:condition", - "if_true": { -- "type": "minecraft:vertical_gradient", -+ "type": "paper:optionally_flat_bedrock_condition_source", -+ "is_roof": false, - "false_at_and_above": { - "above_bottom": 5 - }, -diff --git a/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json b/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json -+++ b/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json -@@ -0,0 +0,0 @@ - { - "type": "minecraft:condition", - "if_true": { -- "type": "minecraft:vertical_gradient", -+ "type": "paper:optionally_flat_bedrock_condition_source", -+ "is_roof": false, - "false_at_and_above": { - "above_bottom": 5 - }, -diff --git a/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json b/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json -+++ b/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json -@@ -0,0 +0,0 @@ - { - "type": "minecraft:condition", - "if_true": { -- "type": "minecraft:vertical_gradient", -+ "type": "paper:optionally_flat_bedrock_condition_source", -+ "is_roof": false, - "false_at_and_above": { - "above_bottom": 5 - }, -@@ -0,0 +0,0 @@ - "if_true": { - "type": "minecraft:not", - "invert": { -- "type": "minecraft:vertical_gradient", -+ "type": "paper:optionally_flat_bedrock_condition_source", -+ "is_roof": true, - "false_at_and_above": { - "below_top": 0 - }, -diff --git a/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json b/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json -+++ b/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json -@@ -0,0 +0,0 @@ - { - "type": "minecraft:condition", - "if_true": { -- "type": "minecraft:vertical_gradient", -+ "type": "paper:optionally_flat_bedrock_condition_source", -+ "is_roof": false, - "false_at_and_above": { - "above_bottom": 5 - }, diff --git a/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/amplified.json.patch b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/amplified.json.patch new file mode 100644 index 0000000000..356d44998f --- /dev/null +++ b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/amplified.json.patch @@ -0,0 +1,12 @@ +--- a/data/minecraft/worldgen/noise_settings/amplified.json ++++ b/data/minecraft/worldgen/noise_settings/amplified.json +@@ -389,7 +_,8 @@ + { + "type": "minecraft:condition", + "if_true": { +- "type": "minecraft:vertical_gradient", ++ "type": "paper:optionally_flat_bedrock_condition_source", ++ "is_roof": false, + "false_at_and_above": { + "above_bottom": 5 + }, diff --git a/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/caves.json.patch b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/caves.json.patch new file mode 100644 index 0000000000..64ecd45575 --- /dev/null +++ b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/caves.json.patch @@ -0,0 +1,22 @@ +--- a/data/minecraft/worldgen/noise_settings/caves.json ++++ b/data/minecraft/worldgen/noise_settings/caves.json +@@ -110,7 +_,8 @@ + "if_true": { + "type": "minecraft:not", + "invert": { +- "type": "minecraft:vertical_gradient", ++ "type": "paper:optionally_flat_bedrock_condition_source", ++ "is_roof": true, + "false_at_and_above": { + "below_top": 0 + }, +@@ -130,7 +_,8 @@ + { + "type": "minecraft:condition", + "if_true": { +- "type": "minecraft:vertical_gradient", ++ "type": "paper:optionally_flat_bedrock_condition_source", ++ "is_roof": false, + "false_at_and_above": { + "above_bottom": 5 + }, diff --git a/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/large_biomes.json.patch b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/large_biomes.json.patch new file mode 100644 index 0000000000..e82d43382c --- /dev/null +++ b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/large_biomes.json.patch @@ -0,0 +1,12 @@ +--- a/data/minecraft/worldgen/noise_settings/large_biomes.json ++++ b/data/minecraft/worldgen/noise_settings/large_biomes.json +@@ -389,7 +_,8 @@ + { + "type": "minecraft:condition", + "if_true": { +- "type": "minecraft:vertical_gradient", ++ "type": "paper:optionally_flat_bedrock_condition_source", ++ "is_roof": false, + "false_at_and_above": { + "above_bottom": 5 + }, diff --git a/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/nether.json.patch b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/nether.json.patch new file mode 100644 index 0000000000..ad053aec9a --- /dev/null +++ b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/nether.json.patch @@ -0,0 +1,22 @@ +--- a/data/minecraft/worldgen/noise_settings/nether.json ++++ b/data/minecraft/worldgen/noise_settings/nether.json +@@ -108,7 +_,8 @@ + { + "type": "minecraft:condition", + "if_true": { +- "type": "minecraft:vertical_gradient", ++ "type": "paper:optionally_flat_bedrock_condition_source", ++ "is_roof": false, + "false_at_and_above": { + "above_bottom": 5 + }, +@@ -129,7 +_,8 @@ + "if_true": { + "type": "minecraft:not", + "invert": { +- "type": "minecraft:vertical_gradient", ++ "type": "paper:optionally_flat_bedrock_condition_source", ++ "is_roof": true, + "false_at_and_above": { + "below_top": 0 + }, diff --git a/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/overworld.json.patch b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/overworld.json.patch new file mode 100644 index 0000000000..868ffa6476 --- /dev/null +++ b/paper-server/patches/resources/data/minecraft/worldgen/noise_settings/overworld.json.patch @@ -0,0 +1,12 @@ +--- a/data/minecraft/worldgen/noise_settings/overworld.json ++++ b/data/minecraft/worldgen/noise_settings/overworld.json +@@ -389,7 +_,8 @@ + { + "type": "minecraft:condition", + "if_true": { +- "type": "minecraft:vertical_gradient", ++ "type": "paper:optionally_flat_bedrock_condition_source", ++ "is_roof": false, + "false_at_and_above": { + "above_bottom": 5 + }, diff --git a/paper-server/patches/sources/net/minecraft/server/Bootstrap.java.patch b/paper-server/patches/sources/net/minecraft/server/Bootstrap.java.patch index 701d502fec..20a795954e 100644 --- a/paper-server/patches/sources/net/minecraft/server/Bootstrap.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/Bootstrap.java.patch @@ -8,13 +8,14 @@ if (BuiltInRegistries.REGISTRY.keySet().isEmpty()) { throw new IllegalStateException("Unable to load registries"); } else { -@@ -54,11 +_,77 @@ +@@ -54,11 +_,78 @@ EntitySelectorOptions.bootStrap(); DispenseItemBehavior.bootStrap(); CauldronInteraction.bootStrap(); - BuiltInRegistries.bootStrap(); + // Paper start + BuiltInRegistries.bootStrap(() -> { ++ io.papermc.paper.world.worldgen.OptionallyFlatBedrockConditionSource.bootstrap(); // Paper - Flat bedrock generator settings + }); + // Paper end CreativeModeTabs.validate(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch index 18943c3caa..c986ea09a9 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java.patch @@ -5,3 +5,21 @@ package net.minecraft.world.level.levelgen; import com.google.common.annotations.VisibleForTesting; +@@ -218,7 +_,7 @@ + @Override + public void buildSurface(WorldGenRegion level, StructureManager structureManager, RandomState random, ChunkAccess chunk) { + if (!SharedConstants.debugVoidTerrain(chunk.getPos())) { +- WorldGenerationContext worldGenerationContext = new WorldGenerationContext(this, level); ++ WorldGenerationContext worldGenerationContext = new WorldGenerationContext(this, level, level.getMinecraftWorld()); // Paper - Flat bedrock generator settings + this.buildSurface( + chunk, + worldGenerationContext, +@@ -260,7 +_,7 @@ + NoiseChunk noiseChunk = chunk.getOrCreateNoiseChunk(chunkAccess -> this.createNoiseChunk(chunkAccess, structureManager, Blender.of(level), random)); + Aquifer aquifer = noiseChunk.aquifer(); + CarvingContext carvingContext = new CarvingContext( +- this, level.registryAccess(), chunk.getHeightAccessorForGeneration(), noiseChunk, random, this.settings.value().surfaceRule() ++ this, level.registryAccess(), chunk.getHeightAccessorForGeneration(), noiseChunk, random, this.settings.value().surfaceRule(), level.getMinecraftWorld() // Paper - Flat bedrock generator settings + ); + CarvingMask carvingMask = ((ProtoChunk)chunk).getOrCreateCarvingMask(); + diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/WorldGenerationContext.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/WorldGenerationContext.java.patch new file mode 100644 index 0000000000..a0993bf36a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/WorldGenerationContext.java.patch @@ -0,0 +1,32 @@ +--- a/net/minecraft/world/level/levelgen/WorldGenerationContext.java ++++ b/net/minecraft/world/level/levelgen/WorldGenerationContext.java +@@ -6,8 +_,15 @@ + public class WorldGenerationContext { + private final int minY; + private final int height; ++ // Paper start - Flat bedrock generator settings ++ private final @javax.annotation.Nullable net.minecraft.world.level.Level serverLevel; + + public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor level) { ++ this(generator, level, null); ++ } ++ public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor level, net.minecraft.world.level.Level serverLevel) { ++ this.serverLevel = serverLevel; ++ // Paper end - Flat bedrock generator settings + this.minY = Math.max(level.getMinY(), generator.getMinY()); + this.height = Math.min(level.getHeight(), generator.getGenDepth()); + } +@@ -19,4 +_,13 @@ + public int getGenDepth() { + return this.height; + } ++ ++ // Paper start - Flat bedrock generator settings ++ public net.minecraft.world.level.Level level() { ++ if (this.serverLevel == null) { ++ throw new NullPointerException("WorldGenerationContext was initialized without a Level, but WorldGenerationContext#level was called"); ++ } ++ return this.serverLevel; ++ } ++ // Paper end - Flat bedrock generator settings + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/carver/CarvingContext.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/carver/CarvingContext.java.patch new file mode 100644 index 0000000000..63d7237796 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/carver/CarvingContext.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/level/levelgen/carver/CarvingContext.java ++++ b/net/minecraft/world/level/levelgen/carver/CarvingContext.java +@@ -27,9 +_,9 @@ + LevelHeightAccessor level, + NoiseChunk noiseChunk, + RandomState randomState, +- SurfaceRules.RuleSource surfaceRule ++ SurfaceRules.RuleSource surfaceRule, @javax.annotation.Nullable net.minecraft.world.level.Level serverLevel // Paper - Flat bedrock generator settings + ) { +- super(generator, level); ++ super(generator, level, serverLevel); // Paper - Flat bedrock generator settings + this.registryAccess = registryAccess; + this.noiseChunk = noiseChunk; + this.randomState = randomState; diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/placement/PlacementContext.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/placement/PlacementContext.java.patch new file mode 100644 index 0000000000..1d38b1ee7c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/placement/PlacementContext.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/levelgen/placement/PlacementContext.java ++++ b/net/minecraft/world/level/levelgen/placement/PlacementContext.java +@@ -17,7 +_,7 @@ + private final Optional topFeature; + + public PlacementContext(WorldGenLevel level, ChunkGenerator generator, Optional topFeature) { +- super(generator, level); ++ super(generator, level, level.getLevel()); // Paper - Flat bedrock generator settings + this.level = level; + this.generator = generator; + this.topFeature = topFeature; diff --git a/paper-server/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java b/paper-server/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java new file mode 100644 index 0000000000..60b6e040df --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java @@ -0,0 +1,81 @@ +package io.papermc.paper.world.worldgen; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.levelgen.PositionalRandomFactory; +import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.VerticalAnchor; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + +// Modelled off of SurfaceRules$VerticalGradientConditionSource +// Flat bedrock generator settings +@DefaultQualifier(NonNull.class) +public record OptionallyFlatBedrockConditionSource(ResourceLocation randomName, VerticalAnchor trueAtAndBelow, VerticalAnchor falseAtAndAbove, boolean isRoof) implements SurfaceRules.ConditionSource { + + private static final ResourceKey> CODEC_RESOURCE_KEY = ResourceKey.create( + Registries.MATERIAL_CONDITION, + ResourceLocation.fromNamespaceAndPath(ResourceLocation.PAPER_NAMESPACE, "optionally_flat_bedrock_condition_source") + ); + private static final KeyDispatchDataCodec CODEC = KeyDispatchDataCodec.of(RecordCodecBuilder.mapCodec((instance) -> { + return instance.group( + ResourceLocation.CODEC.fieldOf("random_name").forGetter(OptionallyFlatBedrockConditionSource::randomName), + VerticalAnchor.CODEC.fieldOf("true_at_and_below").forGetter(OptionallyFlatBedrockConditionSource::trueAtAndBelow), + VerticalAnchor.CODEC.fieldOf("false_at_and_above").forGetter(OptionallyFlatBedrockConditionSource::falseAtAndAbove), + Codec.BOOL.fieldOf("is_roof").forGetter(OptionallyFlatBedrockConditionSource::isRoof) + ).apply(instance, OptionallyFlatBedrockConditionSource::new); + })); + + public static void bootstrap() { + Registry.register(BuiltInRegistries.MATERIAL_CONDITION, CODEC_RESOURCE_KEY, CODEC.codec()); + } + + @Override + public KeyDispatchDataCodec codec() { + return CODEC; + } + + @Override + public SurfaceRules.Condition apply(final SurfaceRules.Context context) { + boolean hasFlatBedrock = context.context.level().paperConfig().environment.generateFlatBedrock; + int tempTrueAtAndBelowY = this.trueAtAndBelow().resolveY(context.context); + int tempFalseAtAndAboveY = this.falseAtAndAbove().resolveY(context.context); + + int flatYLevel = this.isRoof ? Math.max(tempFalseAtAndAboveY, tempTrueAtAndBelowY) - 1 : Math.min(tempFalseAtAndAboveY, tempTrueAtAndBelowY); + final int trueAtAndBelowY = hasFlatBedrock ? flatYLevel : tempTrueAtAndBelowY; + final int falseAtAndAboveY = hasFlatBedrock ? flatYLevel : tempFalseAtAndAboveY; + + final PositionalRandomFactory positionalRandomFactory = context.randomState.getOrCreateRandomFactory(this.randomName()); + + class VerticalGradientCondition extends SurfaceRules.LazyYCondition { + VerticalGradientCondition(SurfaceRules.Context context) { + super(context); + } + + @Override + protected boolean compute() { + int blockY = this.context.blockY; + if (blockY <= trueAtAndBelowY) { + return true; + } else if (blockY >= falseAtAndAboveY) { + return false; + } else { + double d = Mth.map(blockY, trueAtAndBelowY, falseAtAndAboveY, 1.0D, 0.0D); + RandomSource randomSource = positionalRandomFactory.at(this.context.blockX, blockY, this.context.blockZ); + return (double)randomSource.nextFloat() < d; + } + } + } + + return new VerticalGradientCondition(context); + } +}