From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Thu, 6 Jan 2022 15:59:06 -0800 Subject: [PATCH] Expose vanilla BiomeProvider from WorldInfo diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index edd2e83df282b0e24d4c7e3a34776a5b039c2c6b..c133a646baf88e0489d358e302d67f21f76b47c3 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -625,7 +625,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver)); LevelStem worlddimension = (LevelStem) dimensions.getValue(dimensionKey); - org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value()); + org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value(), worlddimension.generator(), this.registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo if (biomeProvider == null && gen != null) { biomeProvider = gen.getDefaultBiomeProvider(worldInfo); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 3205ef2b0027a2fa7f9ba5ed3437f71f1c6e02b5..fda4b5f2b848b432138207eff9a77fed6aaf3805 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -363,7 +363,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.serverLevelData.setWorld(this); if (biomeProvider != null) { - BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().lookupOrThrow(Registries.BIOME)); + BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().lookupOrThrow(Registries.BIOME), chunkgenerator.getBiomeSource()); // Paper - add vanillaBiomeProvider if (chunkgenerator instanceof NoiseBasedChunkGenerator cga) { chunkgenerator = new NoiseBasedChunkGenerator(worldChunkManager, cga.settings); } else if (chunkgenerator instanceof FlatLevelSource cpf) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 33d9f3778996eedc83064332a2fbbdc7c6a8ba90..62ab88e022230d25ffb359981ce7da4e64a9be5a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1310,7 +1310,7 @@ public final class CraftServer implements Server { List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata)); LevelStem worlddimension = iregistry.getValue(actualDimension); - WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value()); + WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value(), worlddimension.generator(), this.getHandle().getServer().registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 744e3631cd2d5c157c9b6023ca813e57c6f860d6..66778ebd82563823f692c7151f40a373e8d7427a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -209,6 +209,39 @@ public class CraftWorld extends CraftRegionAccessor implements World { public int getPlayerCount() { return world.players().size(); } + + @Override + public BiomeProvider vanillaBiomeProvider() { + net.minecraft.server.level.ServerChunkCache serverCache = this.getHandle().chunkSource; + + final net.minecraft.world.level.chunk.ChunkGenerator gen = serverCache.getGenerator(); + net.minecraft.world.level.biome.BiomeSource biomeSource; + if (gen instanceof org.bukkit.craftbukkit.generator.CustomChunkGenerator custom) { + biomeSource = custom.getDelegate().getBiomeSource(); + } else { + biomeSource = gen.getBiomeSource(); + } + if (biomeSource instanceof org.bukkit.craftbukkit.generator.CustomWorldChunkManager customBiomeSource) { + biomeSource = customBiomeSource.vanillaBiomeSource; + } + final net.minecraft.world.level.biome.BiomeSource finalBiomeSource = biomeSource; + final net.minecraft.world.level.biome.Climate.Sampler sampler = serverCache.randomState().sampler(); + + final List<Biome> possibleBiomes = finalBiomeSource.possibleBiomes().stream() + .map(CraftBiome::minecraftHolderToBukkit) + .toList(); + return new BiomeProvider() { + @Override + public Biome getBiome(final org.bukkit.generator.WorldInfo worldInfo, final int x, final int y, final int z) { + return CraftBiome.minecraftHolderToBukkit(finalBiomeSource.getNoiseBiome(x >> 2, y >> 2, z >> 2, sampler)); + } + + @Override + public List<Biome> getBiomes(final org.bukkit.generator.WorldInfo worldInfo) { + return possibleBiomes; + } + }; + } // Paper end private static final Random rand = new Random(); diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java index 5d655d6cd3e23e0287069f8bdf77601487e862fd..c81455a4ee9a3185f125ebf8cec325f4ed2e501d 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java @@ -17,8 +17,14 @@ public class CraftWorldInfo implements WorldInfo { private final long seed; private final int minHeight; private final int maxHeight; + // Paper start + private final net.minecraft.world.level.chunk.ChunkGenerator vanillaChunkGenerator; + private final net.minecraft.core.RegistryAccess.Frozen registryAccess; - public CraftWorldInfo(ServerLevelData worldDataServer, LevelStorageSource.LevelStorageAccess session, World.Environment environment, DimensionType dimensionManager) { + public CraftWorldInfo(PrimaryLevelData worldDataServer, LevelStorageSource.LevelStorageAccess session, World.Environment environment, DimensionType dimensionManager, net.minecraft.world.level.chunk.ChunkGenerator chunkGenerator, net.minecraft.core.RegistryAccess.Frozen registryAccess) { + this.registryAccess = registryAccess; + this.vanillaChunkGenerator = chunkGenerator; + // Paper end this.name = worldDataServer.getLevelName(); this.uuid = WorldUUID.getUUID(session.levelDirectory.path().toFile()); this.environment = environment; @@ -27,15 +33,6 @@ public class CraftWorldInfo implements WorldInfo { this.maxHeight = dimensionManager.minY() + dimensionManager.height(); } - public CraftWorldInfo(String name, UUID uuid, World.Environment environment, long seed, int minHeight, int maxHeight) { - this.name = name; - this.uuid = uuid; - this.environment = environment; - this.seed = seed; - this.minHeight = minHeight; - this.maxHeight = maxHeight; - } - @Override public String getName() { return this.name; @@ -65,4 +62,34 @@ public class CraftWorldInfo implements WorldInfo { public int getMaxHeight() { return this.maxHeight; } + + // Paper start + @Override + public org.bukkit.generator.BiomeProvider vanillaBiomeProvider() { + final net.minecraft.world.level.levelgen.RandomState randomState; + if (vanillaChunkGenerator instanceof net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator noiseBasedChunkGenerator) { + randomState = net.minecraft.world.level.levelgen.RandomState.create(noiseBasedChunkGenerator.generatorSettings().value(), + registryAccess.lookupOrThrow(net.minecraft.core.registries.Registries.NOISE), getSeed()); + } else { + randomState = net.minecraft.world.level.levelgen.RandomState.create(net.minecraft.world.level.levelgen.NoiseGeneratorSettings.dummy(), + registryAccess.lookupOrThrow(net.minecraft.core.registries.Registries.NOISE), getSeed()); + } + + final java.util.List<org.bukkit.block.Biome> possibleBiomes = CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().possibleBiomes().stream() + .map(biome -> org.bukkit.craftbukkit.block.CraftBiome.minecraftHolderToBukkit(biome)) + .toList(); + return new org.bukkit.generator.BiomeProvider() { + @Override + public org.bukkit.block.Biome getBiome(final WorldInfo worldInfo, final int x, final int y, final int z) { + return org.bukkit.craftbukkit.block.CraftBiome.minecraftHolderToBukkit( + CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().getNoiseBiome(x >> 2, y >> 2, z >> 2, randomState.sampler())); + } + + @Override + public java.util.List<org.bukkit.block.Biome> getBiomes(final org.bukkit.generator.WorldInfo worldInfo) { + return possibleBiomes; + } + }; + } + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java index 0063c4c17d05a77adf81164fb9307a29860cbe12..0bac128d6faff0063b03f595b82deea78d1ae161 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java @@ -31,7 +31,11 @@ public class CustomWorldChunkManager extends BiomeSource { return biomeBases; } - public CustomWorldChunkManager(WorldInfo worldInfo, BiomeProvider biomeProvider, Registry<net.minecraft.world.level.biome.Biome> registry) { + // Paper start - add vanillaBiomeProvider + public final BiomeSource vanillaBiomeSource; + public CustomWorldChunkManager(WorldInfo worldInfo, BiomeProvider biomeProvider, Registry<net.minecraft.world.level.biome.Biome> registry, BiomeSource vanillaBiomeSource) { + this.vanillaBiomeSource = vanillaBiomeSource; + // Paper end - add vanillaBiomeProvider this.worldInfo = worldInfo; this.biomeProvider = biomeProvider; this.registry = registry;