116 lines
6.9 KiB
Diff
116 lines
6.9 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Phoenix616 <mail@moep.tv>
|
|
Date: Mon, 13 Jan 2020 15:40:32 +0100
|
|
Subject: [PATCH] Seed based feature search
|
|
|
|
This tries to work around the issue where the server will load
|
|
surrounding chunks up to a radius of 100 chunks in order to search for
|
|
features e.g. when running the /locate command or for treasure maps
|
|
(issue #2312).
|
|
This is done by backporting Mojang's change in 1.17 which makes it so
|
|
that the biome (generated by the seed) is checked first if the feature
|
|
can be generated before actually to load the chunk.
|
|
|
|
Additionally to that the center location of the target chunk is simply
|
|
returned if the chunk is not loaded to avoid the sync chunk load.
|
|
As this can lead to less precise locations a toggle is provided to
|
|
enable the sync loading of the target chunk again.
|
|
|
|
The main downside of this is that it breaks once the seed or generator
|
|
changes but this should usually not happen. A config option to disable
|
|
this completely is added though in case that should ever be necessary.
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 424754a0183b071d20c86f0420cec784a8992e2b..97870622e41cca36d9c7493bfad796f35f3831f4 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -337,6 +337,14 @@ public class PaperWorldConfig {
|
|
}
|
|
}
|
|
|
|
+ public boolean seedBasedFeatureSearch = true;
|
|
+ public boolean seedBasedFeatureSearchLoadsChunks = false;
|
|
+ private void seedBasedFeatureSearch() {
|
|
+ seedBasedFeatureSearch = getBoolean("seed-based-feature-search", seedBasedFeatureSearch);
|
|
+ seedBasedFeatureSearchLoadsChunks = getBoolean("seed-based-feature-search-loads-chunks", seedBasedFeatureSearchLoadsChunks);
|
|
+ log("Feature search is based on seed: " + seedBasedFeatureSearch + ", loads chunks:" + seedBasedFeatureSearchLoadsChunks);
|
|
+ }
|
|
+
|
|
public int maxCollisionsPerEntity;
|
|
private void maxEntityCollision() {
|
|
maxCollisionsPerEntity = getInt( "max-entity-collisions", this.spigotConfig.getInt("max-entity-collisions", 8) );
|
|
diff --git a/src/main/java/net/minecraft/world/level/ChunkPos.java b/src/main/java/net/minecraft/world/level/ChunkPos.java
|
|
index 4a5f318adf5bc2ca1c3fab5d173a99cddd77ab85..f61a3eda40328922b95f166be4dc604500e000be 100644
|
|
--- a/src/main/java/net/minecraft/world/level/ChunkPos.java
|
|
+++ b/src/main/java/net/minecraft/world/level/ChunkPos.java
|
|
@@ -68,10 +68,12 @@ public class ChunkPos {
|
|
}
|
|
}
|
|
|
|
+ public int getBlockX() { return getMinBlockX(); } // Paper - OBFHELPER
|
|
public int getMinBlockX() {
|
|
return this.x << 4;
|
|
}
|
|
|
|
+ public int getBlockZ() { return getMinBlockZ(); } // Paper - OBFHELPER
|
|
public int getMinBlockZ() {
|
|
return this.z << 4;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index 2ad8a4558aa812885adebee8c05dab45f2bf5f90..066d5f7ee93351bff67c0d39ee9d940ac51515d8 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -1511,8 +1511,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
return this.profiler;
|
|
}
|
|
|
|
- @Override
|
|
- public BiomeManager getBiomeManager() {
|
|
+ public BiomeManager getBiomeManager() { return getBiomeManager(); } // Paper - OBFHELPER
|
|
+ @Override public BiomeManager getBiomeManager() {
|
|
return this.biomeManager;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
|
|
index d22ac114440d807a6cf5f286961bc63935fa7823..3a1909c0b198d89539f4351d70a39d16cfd84987 100644
|
|
--- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
|
|
+++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
|
|
@@ -23,6 +23,7 @@ public class BiomeManager {
|
|
return new BiomeManager(source, this.biomeZoomSeed, this.zoomer);
|
|
}
|
|
|
|
+ public Biome getBiome(BlockPos blockposition) { return getBiome(blockposition); } // Paper - OBFHELPER
|
|
public Biome getBiome(BlockPos pos) {
|
|
return this.zoomer.getBiome(this.biomeZoomSeed, pos.getX(), pos.getY(), pos.getZ(), this.noiseBiomeSource);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
|
|
index 0624b8270bc28c83c5479cd51fa4633ed5c36f44..6b24590a1ac460a7fd4bbc2c70d4a4981378e79c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
|
|
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
|
|
@@ -176,7 +176,24 @@ public abstract class StructureFeature<C extends FeatureConfiguration> {
|
|
int j2 = i1 + k * l1;
|
|
ChunkPos chunkcoordintpair = this.getPotentialFeatureChunk(config, worldSeed, seededrandom, i2, j2);
|
|
if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper
|
|
- ChunkAccess ichunkaccess = world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS);
|
|
+ // Paper start - seed based feature search
|
|
+ ChunkAccess ichunkaccess = null;
|
|
+ if (structureAccessor.getWorld().paperConfig.seedBasedFeatureSearch) {
|
|
+ Biome biomeBase = structureAccessor.getWorld().getBiomeManager().getBiome(new BlockPos(chunkcoordintpair.getBlockX() + 9, 0, chunkcoordintpair.getBlockZ() + 9));
|
|
+ if (!biomeBase.getGenerationSettings().isValidStart(this)) {
|
|
+ continue;
|
|
+ }
|
|
+ if (!structureAccessor.getWorld().paperConfig.seedBasedFeatureSearchLoadsChunks) {
|
|
+ ichunkaccess = structureAccessor.getWorld().getChunkIfLoaded(chunkcoordintpair.x, chunkcoordintpair.z);
|
|
+ if (ichunkaccess == null) {
|
|
+ return chunkcoordintpair.asPosition().add(8, searchStartPos.getY(), 8);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (ichunkaccess == null) {
|
|
+ ichunkaccess = world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS);
|
|
+ }
|
|
+ // Paper end
|
|
StructureStart<?> structurestart = structureAccessor.getStartForFeature(SectionPos.of(ichunkaccess.getPos(), 0), this, ichunkaccess);
|
|
|
|
if (structurestart != null && structurestart.e()) {
|