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 24c88555ea85dd2a0656e1f67a4828a5137157b8..cbbb0ff40488c430d15c2ed054d1b2880c9e92b7 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -564,7 +564,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver)); LevelStem worlddimension = (LevelStem) dimensions.get(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 if (biomeProvider == null && gen != null) { biomeProvider = gen.getDefaultBiomeProvider(worldInfo); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 9f172ccae28779ae28eeeceb4305298b9ceed44a..8be3aeab748b57a73522f6124f8e3aacf1f2ee0e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1217,7 +1217,7 @@ public final class CraftServer implements Server { List list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata)); LevelStem worlddimension = iregistry.get(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 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 dc9e6042e6c8deb997f609e10455f7947faa479e..5f9696a4a2490baf7667fa15a8b01a5f845e5f23 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -200,6 +200,30 @@ 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.biome.BiomeSource biomeSource = serverCache.getGenerator().getBiomeSource(); + final net.minecraft.world.level.biome.Climate.Sampler sampler = serverCache.randomState().sampler(); + final net.minecraft.core.Registry biomeRegistry = this.getHandle().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME); + + final List possibleBiomes = biomeSource.possibleBiomes().stream() + .map(biome -> CraftBlock.biomeBaseToBiome(biomeRegistry, biome)) + .toList(); + return new BiomeProvider() { + @Override + public Biome getBiome(final org.bukkit.generator.WorldInfo worldInfo, final int x, final int y, final int z) { + return CraftBlock.biomeBaseToBiome(biomeRegistry, biomeSource.getNoiseBiome(x >> 2, y >> 2, z >> 2, sampler)); + } + + @Override + public List 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..5dbd1a6d314ebbb072cb61360ca5c1043f47a38d 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(ServerLevelData 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,35 @@ 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 net.minecraft.core.Registry biomeRegistry = CraftWorldInfo.this.registryAccess.registryOrThrow(net.minecraft.core.registries.Registries.BIOME); + final java.util.List possibleBiomes = CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().possibleBiomes().stream() + .map(biome -> org.bukkit.craftbukkit.block.CraftBlock.biomeBaseToBiome(biomeRegistry, 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.CraftBlock.biomeBaseToBiome(biomeRegistry, + CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().getNoiseBiome(x >> 2, y >> 2, z >> 2, randomState.sampler())); + } + + @Override + public java.util.List getBiomes(final org.bukkit.generator.WorldInfo worldInfo) { + return possibleBiomes; + } + }; + } + // Paper end }