diff --git a/build.gradle.kts b/build.gradle.kts index 3453bf98f2..f57497cb0b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -141,6 +141,7 @@ tasks.register("showWork") { } tasks.register("checkWork") { + notCompatibleWithConfigurationCache("This task is interactive") fun expandUserHome(path: String): Path { return Path.of(path.replaceFirst("^~".toRegex(), System.getProperty("user.home"))) } diff --git a/paper-server/patches/unapplied/net/minecraft/network/syncher/SynchedEntityData.java.patch b/paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch similarity index 56% rename from paper-server/patches/unapplied/net/minecraft/network/syncher/SynchedEntityData.java.patch rename to paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch index d2519790c5..ac8c137be4 100644 --- a/paper-server/patches/unapplied/net/minecraft/network/syncher/SynchedEntityData.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch @@ -1,23 +1,21 @@ --- a/net/minecraft/network/syncher/SynchedEntityData.java +++ b/net/minecraft/network/syncher/SynchedEntityData.java -@@ -50,8 +50,8 @@ +@@ -45,7 +_,7 @@ } } - private SynchedEntityData.DataItem getItem(EntityDataAccessor key) { -- return this.itemsById[key.id()]; + public SynchedEntityData.DataItem getItem(EntityDataAccessor key) { // Paper - public -+ return (SynchedEntityData.DataItem) this.itemsById[key.id()]; // CraftBukkit - decompile error + return (SynchedEntityData.DataItem)this.itemsById[key.id()]; } - public T get(EntityDataAccessor data) { -@@ -74,6 +74,13 @@ - +@@ -67,6 +_,13 @@ + } } + // CraftBukkit start - add method from above -+ public void markDirty(EntityDataAccessor datawatcherobject) { -+ this.getItem(datawatcherobject).setDirty(true); ++ public void markDirty(final EntityDataAccessor entityDataAccessor) { ++ this.getItem(entityDataAccessor).setDirty(true); + this.isDirty = true; + } + // CraftBukkit end @@ -25,15 +23,11 @@ public boolean isDirty() { return this.isDirty; } -@@ -140,10 +147,24 @@ - if (!Objects.equals(from.serializer(), to.accessor.serializer())) { - throw new IllegalStateException(String.format(Locale.ROOT, "Invalid entity data item type for field %d on entity %s: old=%s(%s), new=%s(%s)", to.accessor.id(), this.entity, to.value, to.value.getClass(), from.value, from.value.getClass())); - } else { -- to.setValue(from.value); -+ to.setValue((T) from.value); // CraftBukkit - decompile error +@@ -169,6 +_,20 @@ + return new SynchedEntityData(this.entity, this.itemsById); } } - ++ + // Paper start + // We need to pack all as we cannot rely on "non default values" or "dirty" ones. + // Because these values can possibly be desynced on the client. @@ -47,7 +41,6 @@ + return list; + } + // Paper end -+ - public static class DataItem { + public static class DataItem { final EntityDataAccessor accessor; diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/frog/Frog.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch similarity index 59% rename from paper-server/patches/unapplied/net/minecraft/world/entity/animal/frog/Frog.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch index f849bb1ffc..f46b1c8ba3 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/animal/frog/Frog.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/animal/frog/Frog.java +++ b/net/minecraft/world/entity/animal/frog/Frog.java -@@ -270,7 +270,12 @@ +@@ -270,7 +_,12 @@ @Override - public void spawnChildFromBreeding(ServerLevel world, Animal other) { -- this.finalizeSpawnChildFromBreeding(world, other, null); + public void spawnChildFromBreeding(ServerLevel level, Animal mate) { +- this.finalizeSpawnChildFromBreeding(level, mate, null); + // Paper start - Add EntityFertilizeEggEvent event -+ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other); ++ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, mate); + if (result.isCancelled()) return; + -+ this.finalizeSpawnChildFromBreeding(world, other, null, result.getExperience()); // Paper - use craftbukkit call that takes experience amount ++ this.finalizeSpawnChildFromBreeding(level, mate, null, result.getExperience()); // Paper - use craftbukkit call that takes experience amount + // Paper end - Add EntityFertilizeEggEvent event this.getBrain().setMemory(MemoryModuleType.IS_PREGNANT, Unit.INSTANCE); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/ShootTongue.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/ShootTongue.java.patch new file mode 100644 index 0000000000..f503b6b310 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/ShootTongue.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/animal/frog/ShootTongue.java ++++ b/net/minecraft/world/entity/animal/frog/ShootTongue.java +@@ -96,7 +_,7 @@ + if (entity.isAlive()) { + frog.doHurtTarget(level, entity); + if (!entity.isAlive()) { +- entity.remove(Entity.RemovalReason.KILLED); ++ entity.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Tadpole.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Tadpole.java.patch new file mode 100644 index 0000000000..86db73a415 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Tadpole.java.patch @@ -0,0 +1,84 @@ +--- a/net/minecraft/world/entity/animal/frog/Tadpole.java ++++ b/net/minecraft/world/entity/animal/frog/Tadpole.java +@@ -62,6 +_,7 @@ + MemoryModuleType.BREED_TARGET, + MemoryModuleType.IS_PANICKING + ); ++ public boolean ageLocked; // Paper + + public Tadpole(EntityType entityType, Level level) { + super(entityType, level); +@@ -113,7 +_,7 @@ + @Override + public void aiStep() { + super.aiStep(); +- if (!this.level().isClientSide) { ++ if (!this.level().isClientSide && !this.ageLocked) { // Paper + this.setAge(this.age + 1); + } + } +@@ -122,12 +_,14 @@ + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.putInt("Age", this.age); ++ tag.putBoolean("AgeLocked", this.ageLocked); // Paper + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + this.setAge(tag.getInt("Age")); ++ this.ageLocked = tag.getBoolean("AgeLocked"); // Paper + } + + @Nullable +@@ -177,7 +_,12 @@ + @Override + public void saveToBucketTag(ItemStack stack) { + Bucketable.saveDefaultDataToBucketTag(this, stack); +- CustomData.update(DataComponents.BUCKET_ENTITY_DATA, stack, compoundTag -> compoundTag.putInt("Age", this.getAge())); ++ // Paper start - Save tadpole age ++ CustomData.update(DataComponents.BUCKET_ENTITY_DATA, stack, compoundTag -> { ++ compoundTag.putInt("Age", this.getAge()); ++ compoundTag.putBoolean("AgeLocked", this.ageLocked); ++ }); ++ // Paper end - Save tadpole age + } + + @Override +@@ -186,6 +_,7 @@ + if (tag.contains("Age")) { + this.setAge(tag.getInt("Age")); + } ++ this.ageLocked = tag.getBoolean("AgeLocked"); // Paper + } + + @Override +@@ -217,6 +_,7 @@ + } + + private void ageUp(int offset) { ++ if (this.ageLocked) return; // Paper + this.setAge(this.age + offset * 20); + } + +@@ -229,12 +_,17 @@ + + private void ageUp() { + if (this.level() instanceof ServerLevel serverLevel) { +- this.convertTo(EntityType.FROG, ConversionParams.single(this, false, false), mob -> { ++ Frog converted = this.convertTo(EntityType.FROG, ConversionParams.single(this, false, false), mob -> { // CraftBukkit + mob.finalizeSpawn(serverLevel, this.level().getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.CONVERSION, null); + mob.setPersistenceRequired(); + mob.fudgePositionAfterSizeChange(this.getDimensions(this.getPose())); + this.playSound(SoundEvents.TADPOLE_GROW_UP, 0.15F, 1.0F); +- }); ++ // CraftBukkit start ++ }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.METAMORPHOSIS, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.METAMORPHOSIS); ++ if (converted == null) { ++ this.setAge(0); // Sets the age to 0 for avoid a loop if the event is canceled ++ } ++ // CraftBukkit end + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch b/paper-server/patches/sources/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch new file mode 100644 index 0000000000..36b61e1dd6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java ++++ b/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java +@@ -214,7 +_,14 @@ + return false; + } else { + Vec3 vec3 = position.get(); +- if (!vibrationUser.canReceiveVibration(level, BlockPos.containing(pos), gameEvent, context)) { ++ // CraftBukkit start ++ boolean defaultCancel = !vibrationUser.canReceiveVibration(level, BlockPos.containing(pos), gameEvent, context); ++ Entity entity = context.sourceEntity(); ++ org.bukkit.event.block.BlockReceiveGameEvent event1 = new org.bukkit.event.block.BlockReceiveGameEvent(org.bukkit.craftbukkit.CraftGameEvent.minecraftToBukkit(gameEvent.value()), org.bukkit.craftbukkit.block.CraftBlock.at(level, BlockPos.containing(vec3)), (entity == null) ? null : entity.getBukkitEntity()); ++ event1.setCancelled(defaultCancel); ++ level.getCraftServer().getPluginManager().callEvent(event1); ++ if (event1.isCancelled()) { ++ // CraftBukkit end + return false; + } else if (isOccluded(level, pos, vec3)) { + return false; diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java.patch new file mode 100644 index 0000000000..d79551ea59 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java.patch @@ -0,0 +1,93 @@ +--- a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java ++++ b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java +@@ -79,14 +_,30 @@ + return this.exclusionZone; + } + ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add missing structure set seed configs + public boolean isStructureChunk(ChunkGeneratorStructureState structureState, int x, int z) { ++ // Paper start - Add missing structure set seed configs ++ return this.isStructureChunk(structureState, x, z, null); ++ } ++ public boolean isStructureChunk(ChunkGeneratorStructureState structureState, int x, int z, @org.jetbrains.annotations.Nullable net.minecraft.resources.ResourceKey structureSetKey) { ++ Integer saltOverride = null; ++ if (structureSetKey != null) { ++ if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.MINESHAFTS) { ++ saltOverride = structureState.conf.mineshaftSeed; ++ } else if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.BURIED_TREASURES) { ++ saltOverride = structureState.conf.buriedTreasureSeed; ++ } ++ } ++ // Paper end - Add missing structure set seed configs + return this.isPlacementChunk(structureState, x, z) +- && this.applyAdditionalChunkRestrictions(x, z, structureState.getLevelSeed()) ++ && this.applyAdditionalChunkRestrictions(x, z, structureState.getLevelSeed(), saltOverride) // Paper - Add missing structure set seed configs + && this.applyInteractionsWithOtherStructures(structureState, x, z); + } + +- public boolean applyAdditionalChunkRestrictions(int regionX, int regionZ, long levelSeed) { +- return !(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(levelSeed, this.salt, regionX, regionZ, this.frequency); ++ // Paper start - Add missing structure set seed configs ++ public boolean applyAdditionalChunkRestrictions(int regionX, int regionZ, long levelSeed, @org.jetbrains.annotations.Nullable Integer saltOverride) { ++ return !(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(levelSeed, this.salt, regionX, regionZ, this.frequency, saltOverride); ++ // Paper end - Add missing structure set seed configs + } + + public boolean applyInteractionsWithOtherStructures(ChunkGeneratorStructureState structureState, int x, int z) { +@@ -101,25 +_,31 @@ + + public abstract StructurePlacementType type(); + +- private static boolean probabilityReducer(long levelSeed, int regionX, int regionZ, int salt, float probability) { ++ private static boolean probabilityReducer(long levelSeed, int regionX, int regionZ, int salt, float probability, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here + WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); + worldgenRandom.setLargeFeatureWithSalt(levelSeed, regionX, regionZ, salt); + return worldgenRandom.nextFloat() < probability; + } + +- private static boolean legacyProbabilityReducerWithDouble(long baseSeed, int salt, int chunkX, int chunkZ, float probability) { ++ private static boolean legacyProbabilityReducerWithDouble(long baseSeed, int salt, int chunkX, int chunkZ, float probability, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs + WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); ++ if (saltOverride == null) { // Paper - Add missing structure set seed configs + worldgenRandom.setLargeFeatureSeed(baseSeed, chunkX, chunkZ); ++ // Paper start - Add missing structure set seed configs ++ } else { ++ worldgenRandom.setLargeFeatureWithSalt(baseSeed, chunkX, chunkZ, saltOverride); ++ } ++ // Paper end - Add missing structure set seed configs + return worldgenRandom.nextDouble() < probability; + } + +- private static boolean legacyArbitrarySaltProbabilityReducer(long levelSeed, int salt, int regionX, int regionZ, float probability) { ++ private static boolean legacyArbitrarySaltProbabilityReducer(long levelSeed, int salt, int regionX, int regionZ, float probability, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs + WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureWithSalt(levelSeed, regionX, regionZ, 10387320); ++ worldgenRandom.setLargeFeatureWithSalt(levelSeed, regionX, regionZ, saltOverride != null ? saltOverride : HIGHLY_ARBITRARY_RANDOM_SALT); // Paper - Add missing structure set seed configs + return worldgenRandom.nextFloat() < probability; + } + +- private static boolean legacyPillagerOutpostReducer(long levelSeed, int salt, int regionX, int regionZ, float probability) { ++ private static boolean legacyPillagerOutpostReducer(long levelSeed, int salt, int regionX, int regionZ, float probability, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here + int i = regionX >> 4; + int i1 = regionZ >> 4; + WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +@@ -147,7 +_,7 @@ + + @FunctionalInterface + public interface FrequencyReducer { +- boolean shouldGenerate(long levelSeed, int i, int salt, int regionX, float regionZ); ++ boolean shouldGenerate(long levelSeed, int i, int salt, int regionX, float regionZ, @org.jetbrains.annotations.Nullable Integer saltOverride); // Paper - Add missing structure set seed configs + } + + public static enum FrequencyReductionMethod implements StringRepresentable { +@@ -167,8 +_,8 @@ + this.reducer = reducer; + } + +- public boolean shouldGenerate(long levelSeed, int salt, int regionX, int regionZ, float probability) { +- return this.reducer.shouldGenerate(levelSeed, salt, regionX, regionZ, probability); ++ public boolean shouldGenerate(long levelSeed, int salt, int regionX, int regionZ, float probability, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs ++ return this.reducer.shouldGenerate(levelSeed, salt, regionX, regionZ, probability, saltOverride); // Paper - Add missing structure set seed configs + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java.patch deleted file mode 100644 index 8abda3baff..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java.patch +++ /dev/null @@ -1,93 +0,0 @@ ---- a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java -+++ b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java -@@ -79,14 +79,30 @@ - return this.exclusionZone; - } - -+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add missing structure set seed configs - public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ) { -+ // Paper start - Add missing structure set seed configs -+ return this.isStructureChunk(calculator, chunkX, chunkZ, null); -+ } -+ public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ, @org.jetbrains.annotations.Nullable net.minecraft.resources.ResourceKey structureSetKey) { -+ Integer saltOverride = null; -+ if (structureSetKey != null) { -+ if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.MINESHAFTS) { -+ saltOverride = calculator.conf.mineshaftSeed; -+ } else if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.BURIED_TREASURES) { -+ saltOverride = calculator.conf.buriedTreasureSeed; -+ } -+ } -+ // Paper end - Add missing structure set seed configs - return this.isPlacementChunk(calculator, chunkX, chunkZ) -- && this.applyAdditionalChunkRestrictions(chunkX, chunkZ, calculator.getLevelSeed()) -+ && this.applyAdditionalChunkRestrictions(chunkX, chunkZ, calculator.getLevelSeed(), saltOverride) // Paper - Add missing structure set seed configs - && this.applyInteractionsWithOtherStructures(calculator, chunkX, chunkZ); - } - -- public boolean applyAdditionalChunkRestrictions(int chunkX, int chunkZ, long seed) { -- return !(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(seed, this.salt, chunkX, chunkZ, this.frequency); -+ // Paper start - Add missing structure set seed configs -+ public boolean applyAdditionalChunkRestrictions(int chunkX, int chunkZ, long seed, @org.jetbrains.annotations.Nullable Integer saltOverride) { -+ return !(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(seed, this.salt, chunkX, chunkZ, this.frequency, saltOverride); -+ // Paper end - Add missing structure set seed configs - } - - public boolean applyInteractionsWithOtherStructures(ChunkGeneratorStructureState calculator, int centerChunkX, int centerChunkZ) { -@@ -101,25 +117,31 @@ - - public abstract StructurePlacementType type(); - -- private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) { -+ private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here - WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); - worldgenRandom.setLargeFeatureWithSalt(seed, salt, chunkX, chunkZ); - return worldgenRandom.nextFloat() < frequency; - } - -- private static boolean legacyProbabilityReducerWithDouble(long seed, int salt, int chunkX, int chunkZ, float frequency) { -+ private static boolean legacyProbabilityReducerWithDouble(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs - WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); -+ if (saltOverride == null) { // Paper - Add missing structure set seed configs - worldgenRandom.setLargeFeatureSeed(seed, chunkX, chunkZ); -+ // Paper start - Add missing structure set seed configs -+ } else { -+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride); -+ } -+ // Paper end - Add missing structure set seed configs - return worldgenRandom.nextDouble() < (double)frequency; - } - -- private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) { -+ private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs - WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); -- worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, 10387320); -+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride != null ? saltOverride : HIGHLY_ARBITRARY_RANDOM_SALT); // Paper - Add missing structure set seed configs - return worldgenRandom.nextFloat() < frequency; - } - -- private static boolean legacyPillagerOutpostReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) { -+ private static boolean legacyPillagerOutpostReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here - int i = chunkX >> 4; - int j = chunkZ >> 4; - WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); -@@ -147,7 +169,7 @@ - - @FunctionalInterface - public interface FrequencyReducer { -- boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance); -+ boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride); // Paper - Add missing structure set seed configs - } - - public static enum FrequencyReductionMethod implements StringRepresentable { -@@ -167,8 +189,8 @@ - this.reducer = generationPredicate; - } - -- public boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance) { -- return this.reducer.shouldGenerate(seed, salt, chunkX, chunkZ, chance); -+ public boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs -+ return this.reducer.shouldGenerate(seed, salt, chunkX, chunkZ, chance, saltOverride); // Paper - Add missing structure set seed configs - } - - @Override