summaryrefslogtreecommitdiffhomepage
path: root/patches/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch
blob: 4fa91f877c8e57921df50b7a093c593679537d8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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 56589fee8dd09783e01f2ae290ffacb5dff3f05f..718b653a118a1c64d07efab93192f10dfcbf414e 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -611,7 +611,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.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 - 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 3c947dc0aea06d66a00aeca51355ea41e8d98f88..60a77bd04489ee592ec61d3d739cb3062c1eefbb 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -369,7 +369,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
         this.serverLevelData.setWorld(this);
 
         if (biomeProvider != null) {
-            BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().registryOrThrow(Registries.BIOME));
+            BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().registryOrThrow(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 b8117fac959a894c9821c82f624bc463174d3568..8364316aac2c13c99244912122c333feeeb5dd06 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1306,7 +1306,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.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 - 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 0c2734c1d06b6c5dff383f9c6139c0389f220a76..110a5d92d6154bc39c1916006a5cb74798092445 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -212,6 +212,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;