aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0641-Expose-vanilla-BiomeProvider-from-WorldInfo.patch
blob: b09fd4e69919bdc2ce1d9f8a0ed2e24a41669be1 (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 7ab9a9c04f94a68dccb5ec9bfc8171bfc02927a2..8cbc8eeaa8719f8bb136543e80ec85248c90e154 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -626,7 +626,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 3b3024fcf39266cc6ae61fb77dbffb391dc96c92..2d77e9526917a83987ae0486a669538d5417b781 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -357,7 +357,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 1c72862b3167acc05f06b44cd9a0929ad8d2b9c8..6d32505266fef119289bcf6761c1948368238eb9 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 5050c9a9d5369a829f5b47a56b7621de05c9a6de..0ff12d4e74c14b2b0ecf06d720c5e06edb35fcdb 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -216,6 +216,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;