Paper/patches/server/0799-Configurable-feature-seeds.patch
Noah van der Aa 2e99e5e677
Updated Upstream (Bukkit/CraftBukkit) (#7411)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
af88996a SPIGOT-6890: Add repair cost amount in AnvilInventory
bc7bd363 PR-716: Fix scheduler javadocs (previously, the <b> tag broke the rendering)
6db1ab70 Improve item cooldown JavaDocs

CraftBukkit Changes:
13670b44 SPIGOT-6890: Add repair cost amount in AnvilInventory
0d109e86 PR-999: Prevent non-item cooldowns
2022-01-27 15:35:36 +01:00

111 lines
6.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <jahnke.nassim@gmail.com>
Date: Tue, 31 Aug 2021 17:05:27 +0200
Subject: [PATCH] Configurable feature seeds
Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com>
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
index ee53453440177537fc653ea156785d7591498614..5e3b7fb2e0b7608610555cd23e7ad25a05883181 100644
--- a/src/main/java/co/aikar/timings/TimingsExport.java
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -273,7 +273,7 @@ public class TimingsExport extends Thread {
JSONObject object = new JSONObject();
for (String key : config.getKeys(false)) {
String fullKey = (parentKey != null ? parentKey + "." + key : key);
- if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey) || key.startsWith("seed-") || key.equals("worldeditregentempworld")) {
+ if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey) || key.startsWith("seed-") || key.equals("worldeditregentempworld") || key.equals("feature-seeds")) {
continue;
}
final Object val = config.get(key);
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index e5eeab49d167a9a151301ca910e1421550e14245..0a70dfd7880f5fcf1292dd2fdae2964bc2f51d61 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -946,6 +946,55 @@ public class PaperWorldConfig {
return table;
}
+ public it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<net.minecraft.resources.ResourceLocation> featureSeeds = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
+ private void featureSeeds() {
+ featureSeeds.defaultReturnValue(-1);
+ final boolean randomise = getBoolean("feature-seeds.generate-random-seeds-for-all", false);
+ final ConfigurationSection defaultSection = config.getConfigurationSection("world-settings.default.feature-seeds");
+ final ConfigurationSection section = config.getConfigurationSection("world-settings." + worldName + ".feature-seeds");
+ final net.minecraft.core.Registry<net.minecraft.world.level.levelgen.feature.ConfiguredFeature<?, ?>> registry
+ = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(net.minecraft.core.Registry.CONFIGURED_FEATURE_REGISTRY);
+ if (section != null) {
+ loadFeatureSeeds(section, registry);
+ }
+
+ // Also use default set seeds if not already set per world
+ loadFeatureSeeds(defaultSection, registry);
+
+ if (randomise) {
+ final Map<String, Object> randomisedSeeds = new HashMap<>();
+ final java.util.Random random = new java.security.SecureRandom();
+ for (final net.minecraft.resources.ResourceLocation resourceLocation : registry.keySet()) {
+ if (featureSeeds.containsKey(resourceLocation)) {
+ continue;
+ }
+
+ final long seed = random.nextLong();
+ randomisedSeeds.put("world-settings." + worldName + ".feature-seeds." + resourceLocation.getPath(), seed);
+ featureSeeds.put(resourceLocation, seed);
+ }
+ if (!randomisedSeeds.isEmpty()) {
+ config.addDefaults(randomisedSeeds);
+ }
+ }
+ }
+
+ private void loadFeatureSeeds(final ConfigurationSection section, final net.minecraft.core.Registry<net.minecraft.world.level.levelgen.feature.ConfiguredFeature<?, ?>> registry) {
+ for (final String key : section.getKeys(false)) {
+ if (!(section.get(key) instanceof Number)) {
+ continue;
+ }
+
+ final net.minecraft.resources.ResourceLocation location = new net.minecraft.resources.ResourceLocation(key);
+ if (!registry.containsKey(location)) {
+ logError("Invalid feature resource location: " + location);
+ continue;
+ }
+
+ featureSeeds.putIfAbsent(location, section.getLong(key));
+ }
+ }
+
public int getBehaviorTickRate(String typeName, String entityType, int def) {
return getIntOrDefault(behaviorTickRates, typeName, entityType, def);
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
index 3461e62af6de8e4c5c72ff27937948d314bebf6a..3f0d83a90e1319baa0622b708b3ba940d3cee64a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -277,7 +277,7 @@ public abstract class ChunkGenerator implements BiomeManager.NoiseBiomeSource {
int j = list.size();
try {
- Registry<PlacedFeature> iregistry = generatoraccessseed.registryAccess().registryOrThrow(Registry.PLACED_FEATURE_REGISTRY);
+ Registry<PlacedFeature> iregistry = generatoraccessseed.registryAccess().registryOrThrow(Registry.PLACED_FEATURE_REGISTRY); // Paper - diff on change
Registry<StructureFeature<?>> iregistry1 = generatoraccessseed.registryAccess().registryOrThrow(Registry.STRUCTURE_FEATURE_REGISTRY);
int k = Math.max(GenerationStep.Decoration.values().length, j);
@@ -351,7 +351,15 @@ public abstract class ChunkGenerator implements BiomeManager.NoiseBiomeSource {
return (String) optional.orElseGet(placedfeature::toString);
};
- seededrandom.setFeatureSeed(i, l1, l);
+ // Paper start - change populationSeed used in random
+ long featurePopulationSeed = i;
+ final net.minecraft.resources.ResourceLocation location = iregistry.getKey(placedfeature);
+ final long configFeatureSeed = generatoraccessseed.getMinecraftWorld().paperConfig.featureSeeds.getLong(location);
+ if (configFeatureSeed != -1) {
+ featurePopulationSeed = seededrandom.setDecorationSeed(configFeatureSeed, blockposition.getX(), blockposition.getZ()); // See seededrandom.setDecorationSeed from above
+ }
+ seededrandom.setFeatureSeed(featurePopulationSeed, l1, l);
+ // Paper end
try {
generatoraccessseed.setCurrentlyGenerating(supplier1);