Expose vanilla BiomeProvider from WorldInfo

This commit is contained in:
Jason Penilla 2022-01-06 15:59:06 -08:00
parent a6dd9f7a68
commit 25af4f1bec
6 changed files with 78 additions and 14 deletions

View File

@ -483,7 +483,7 @@
+ List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver)); + List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver));
+ LevelStem worlddimension = (LevelStem) dimensions.getValue(dimensionKey); + 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) { + if (biomeProvider == null && gen != null) {
+ biomeProvider = gen.getDefaultBiomeProvider(worldInfo); + biomeProvider = gen.getDefaultBiomeProvider(worldInfo);
+ } + }

View File

@ -212,7 +212,7 @@
+ this.serverLevelData.setWorld(this); + this.serverLevelData.setWorld(this);
+ +
+ if (biomeProvider != null) { + 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) { + if (chunkgenerator instanceof NoiseBasedChunkGenerator cga) {
+ chunkgenerator = new NoiseBasedChunkGenerator(worldChunkManager, cga.settings); + chunkgenerator = new NoiseBasedChunkGenerator(worldChunkManager, cga.settings);
+ } else if (chunkgenerator instanceof FlatLevelSource cpf) { + } else if (chunkgenerator instanceof FlatLevelSource cpf) {

View File

@ -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)); List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata));
LevelStem worlddimension = iregistry.getValue(actualDimension); 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) { if (biomeProvider == null && generator != null) {
biomeProvider = generator.getDefaultBiomeProvider(worldInfo); biomeProvider = generator.getDefaultBiomeProvider(worldInfo);
} }

View File

@ -209,6 +209,39 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public int getPlayerCount() { public int getPlayerCount() {
return world.players().size(); 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 // Paper end
private static final Random rand = new Random(); private static final Random rand = new Random();

View File

@ -17,8 +17,14 @@ public class CraftWorldInfo implements WorldInfo {
private final long seed; private final long seed;
private final int minHeight; private final int minHeight;
private final int maxHeight; 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.name = worldDataServer.getLevelName();
this.uuid = WorldUUID.getUUID(session.levelDirectory.path().toFile()); this.uuid = WorldUUID.getUUID(session.levelDirectory.path().toFile());
this.environment = environment; this.environment = environment;
@ -27,15 +33,6 @@ public class CraftWorldInfo implements WorldInfo {
this.maxHeight = dimensionManager.minY() + dimensionManager.height(); 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 @Override
public String getName() { public String getName() {
return this.name; return this.name;
@ -65,4 +62,34 @@ public class CraftWorldInfo implements WorldInfo {
public int getMaxHeight() { public int getMaxHeight() {
return this.maxHeight; 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
} }

View File

@ -31,7 +31,11 @@ public class CustomWorldChunkManager extends BiomeSource {
return biomeBases; 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.worldInfo = worldInfo;
this.biomeProvider = biomeProvider; this.biomeProvider = biomeProvider;
this.registry = registry; this.registry = registry;