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 public net.minecraft.world.level.levelgen.SurfaceSystem getOrCreateRandomFactory(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/world/level/levelgen/PositionalRandomFactory; 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..02d98ec591b676acf64460d14d608860d32a362a --- /dev/null +++ b/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java @@ -0,0 +1,76 @@ +package io.papermc.paper.world.worldgen; + +import com.mojang.serialization.Codec; +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, new ResourceLocation(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 c887d34171f89c731d76c4ca92c70be2b1edc1e6..5816998cde8504d58732e63eb2179a5d828f35bb 100644 --- a/src/main/java/net/minecraft/server/Bootstrap.java +++ b/src/main/java/net/minecraft/server/Bootstrap.java @@ -78,6 +78,7 @@ public class Bootstrap { CauldronInteraction.bootStrap(); // Paper start BuiltInRegistries.bootStrap(() -> { + io.papermc.paper.world.worldgen.OptionallyFlatBedrockConditionSource.bootstrap(); // Paper - optional flat bedrock io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler.enterBootstrappers(); // Paper - Entrypoint for bootstrapping }); // Paper end 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 902156477bdfc9917105f1229f760c26e5af302a..58609a0911c4e32b6f80f050cd3d23f70ad75b1b 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java @@ -207,7 +207,7 @@ 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 this.buildSurface(chunk, worldgenerationcontext, noiseConfig, structures, region.getBiomeManager(), region.registryAccess().registryOrThrow(Registries.BIOME), Blender.of(region)); } @@ -235,7 +235,7 @@ 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 CarvingMask carvingmask = ((ProtoChunk) chunk).getOrCreateCarvingMask(carverStep); 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 b99283c31193e2110f6e3f39c23dbfc2442bab2b..1c9d9ecdafb2bd04348045ba0404da052dcd6437 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java +++ b/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java @@ -6,10 +6,13 @@ 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 - public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world) { + public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world) { this(generator, world, null); } // Paper + public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world, @org.jetbrains.annotations.Nullable net.minecraft.world.level.Level level) { // Paper this.minY = Math.max(world.getMinBuildHeight(), generator.getMinY()); this.height = Math.min(world.getHeight(), generator.getGenDepth()); + this.level = level; // Paper } public int getMinGenY() { @@ -19,4 +22,13 @@ public class WorldGenerationContext { public int getGenDepth() { return this.height; } + + // Paper start + 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 } 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 a745458ea3581ea91a68c863e3fd0a0292d73a61..f84ee8afe95f912a972e37fbae7a06ecdd3aba06 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 @@ -21,8 +21,8 @@ public class CarvingContext extends WorldGenerationContext { private final RandomState randomState; private final SurfaceRules.RuleSource surfaceRule; - public CarvingContext(NoiseBasedChunkGenerator noiseChunkGenerator, RegistryAccess registryManager, LevelHeightAccessor heightLimitView, NoiseChunk chunkNoiseSampler, RandomState noiseConfig, SurfaceRules.RuleSource materialRule) { - super(noiseChunkGenerator, heightLimitView); + public CarvingContext(NoiseBasedChunkGenerator noiseChunkGenerator, RegistryAccess registryManager, LevelHeightAccessor heightLimitView, NoiseChunk chunkNoiseSampler, RandomState noiseConfig, SurfaceRules.RuleSource materialRule, @javax.annotation.Nullable net.minecraft.world.level.Level level) { // Paper + super(noiseChunkGenerator, heightLimitView, level); // Paper 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 640c2683c842655bbaee8f293f1c2613ef44844e..53d818b0cc602f827d0b907e293515f6810c6792 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 @@ -18,7 +18,7 @@ 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 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 3f61ea695aa6a91a0cacf1fa8dc0a9bdc6fa36e6..02d32bbdbc795db271205bef95e6987ac34b0136 100644 --- a/src/main/resources/data/minecraft/worldgen/noise_settings/amplified.json +++ b/src/main/resources/data/minecraft/worldgen/noise_settings/amplified.json @@ -389,7 +389,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/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json b/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json index 1fe9ce904cba21ff4e6efb948a0bc274a22bcb0b..2e8c1aad10a2b0adbdee4180cfc1902984b6565b 100644 --- a/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json +++ b/src/main/resources/data/minecraft/worldgen/noise_settings/caves.json @@ -110,7 +110,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 +131,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/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json b/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json index f4c34de998d78a80bc026d8e0d423c9bed9bbf8a..fd5bd5474b8f931f2e04706997e71cd5145a5a82 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 @@ -389,7 +389,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/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json b/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json index 6219d25fcdbc761debc1d1e357757d1b977dc0b0..1657179b8c3f7e549e3b8774ecb75f292ae79c38 100644 --- a/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json +++ b/src/main/resources/data/minecraft/worldgen/noise_settings/nether.json @@ -108,7 +108,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 +130,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/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json b/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json index da3bda6167859f4ddf7d76ec2053f40b2139c13e..70beb7665a43a06b4afcb3c77aa77f923cb444cb 100644 --- a/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json +++ b/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json @@ -389,7 +389,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 },