diff --git a/patches/server/Add-missing-structure-set-seed-configs.patch b/patches/server/Add-missing-structure-set-seed-configs.patch index 6f7c80ead0..1b1e334cee 100644 --- a/patches/server/Add-missing-structure-set-seed-configs.patch +++ b/patches/server/Add-missing-structure-set-seed-configs.patch @@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z)) { -+ if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z, holder::is)) { // Paper - add missing structure set configs ++ if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z, structureplacement instanceof net.minecraft.world.level.chunk.ChunkGeneratorStructureState.KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - add missing structure set configs if (list.size() == 1) { this.tryGenerateStructure((StructureSet.StructureSelectionEntry) list.get(0), structureAccessor, registryManager, randomstate, structureTemplateManager, placementCalculator.getLevelSeed(), chunk, chunkcoordintpair, sectionposition); } else { @@ -59,12 +59,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, i, ChunkGeneratorStructureState.injectSpigot(list, conf)); // Spigot + return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, i, ChunkGeneratorStructureState.injectSpigot(list, conf), conf); // Spigot } ++ // Paper start - horrible hack because spigot creates a ton of direct Holders which lose track of the identifying key ++ public static final class KeyedRandomSpreadStructurePlacement extends RandomSpreadStructurePlacement { ++ public final net.minecraft.resources.ResourceKey key; ++ public KeyedRandomSpreadStructurePlacement(net.minecraft.resources.ResourceKey key, net.minecraft.core.Vec3i locateOffset, FrequencyReductionMethod frequencyReductionMethod, float frequency, int salt, java.util.Optional exclusionZone, int spacing, int separation, net.minecraft.world.level.levelgen.structure.placement.RandomSpreadType spreadType) { ++ super(locateOffset, frequencyReductionMethod, frequency, salt, exclusionZone, spacing, separation, spreadType); ++ this.key = key; ++ } ++ } ++ // Paper end // Spigot start private static List> injectSpigot(List> list, SpigotWorldConfig conf) { return list.stream().map((holder) -> { StructureSet structureset = holder.value(); - if (structureset.placement() instanceof RandomSpreadStructurePlacement randomConfig) { ++ final Holder newHolder; // Paper + if (structureset.placement() instanceof RandomSpreadStructurePlacement randomConfig && holder.unwrapKey().orElseThrow().location().getNamespace().equals(net.minecraft.resources.ResourceLocation.DEFAULT_NAMESPACE)) { // Paper - check namespace cause datapacks could add structure sets with the same path String name = holder.unwrapKey().orElseThrow().location().getPath(); int seed = randomConfig.salt; @@ -80,7 +90,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - structureset = new StructureSet(structureset.structures(), new RandomSpreadStructurePlacement(randomConfig.locateOffset, randomConfig.frequencyReductionMethod, randomConfig.frequency, seed, randomConfig.exclusionZone, randomConfig.spacing(), randomConfig.separation(), randomConfig.spreadType())); +- structureset = new StructureSet(structureset.structures(), new RandomSpreadStructurePlacement(randomConfig.locateOffset, randomConfig.frequencyReductionMethod, randomConfig.frequency, seed, randomConfig.exclusionZone, randomConfig.spacing(), randomConfig.separation(), randomConfig.spreadType())); ++ // Paper start ++ structureset = new StructureSet(structureset.structures(), new KeyedRandomSpreadStructurePlacement(holder.unwrapKey().orElseThrow(), randomConfig.locateOffset, randomConfig.frequencyReductionMethod, randomConfig.frequency, seed, randomConfig.exclusionZone, randomConfig.spacing(), randomConfig.separation(), randomConfig.spreadType())); ++ newHolder = Holder.direct(structureset); // I really wish we didn't have to do this here ++ } else { ++ newHolder = holder; + } +- return Holder.direct(structureset); ++ return newHolder; ++ // Paper end + }).collect(Collectors.toUnmodifiableList()); + } + // Spigot end @@ -0,0 +0,0 @@ public class ChunkGeneratorStructureState { return stream.anyMatch(set::contains); } @@ -115,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 for (int l = centerChunkX - chunkCount; l <= centerChunkX + chunkCount; ++l) { for (int i1 = centerChunkZ - chunkCount; i1 <= centerChunkZ + chunkCount; ++i1) { - if (structureplacement.isStructureChunk(this, l, i1)) { -+ if (structureplacement.isStructureChunk(this, l, i1, structureSetEntry::is)) { // Paper - add missing structure set configs ++ if (structureplacement.isStructureChunk(this, l, i1, structureplacement instanceof KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - add missing structure set configs return true; } } @@ -132,12 +154,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - add missing structure set configs + return this.isStructureChunk(calculator, chunkX, chunkZ, null); + } -+ public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ, @org.jetbrains.annotations.Nullable java.util.function.Predicate> structureSetPredicate) { ++ public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ, @org.jetbrains.annotations.Nullable net.minecraft.resources.ResourceKey structureSetKey) { + Integer saltOverride = null; -+ if (structureSetPredicate != null) { -+ if (structureSetPredicate.test(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.MINESHAFTS)) { ++ if (structureSetKey != null) { ++ if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.MINESHAFTS) { + saltOverride = calculator.conf.mineshaftSeed; -+ } else if (structureSetPredicate.test(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.BURIED_TREASURES)) { ++ } else if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.BURIED_TREASURES) { + saltOverride = calculator.conf.buriedTreasureSeed; + } + } @@ -177,7 +199,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); - worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, 10387320); -+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride != null ? saltOverride : 10387320); // Paper ++ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride != null ? saltOverride : HIGHLY_ARBITRARY_RANDOM_SALT); // Paper return worldgenRandom.nextFloat() < frequency; }