From 88a3a87015f84bcc46ce8b558e9f3b2823eb9107 Mon Sep 17 00:00:00 2001 From: Mart Date: Sat, 3 May 2025 18:51:19 +0000 Subject: [PATCH] Configurable xp orb merge group count (#12503) --- .../world/entity/ExperienceOrb.java.patch | 14 +++++++++++--- .../paper/configuration/Configurations.java | 3 ++- .../configuration/GlobalConfiguration.java | 3 +++ .../configuration/constraint/Constraints.java | 18 ++++++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch index 5640424cdf..295adfef55 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch @@ -97,7 +97,7 @@ Vec3 vec3 = new Vec3( this.followingPlayer.getX() - this.getX(), this.followingPlayer.getY() + this.followingPlayer.getEyeHeight() / 2.0 - this.getY(), -@@ -161,16 +_,27 @@ +@@ -161,18 +_,29 @@ } public static void award(ServerLevel level, Vec3 pos, int amount) { @@ -124,9 +124,17 @@ private static boolean tryMergeToExisting(ServerLevel level, Vec3 pos, int amount) { + // Paper - TODO some other event for this kind of merge AABB aabb = AABB.ofSize(pos, 1.0, 1.0, 1.0); - int randomInt = level.getRandom().nextInt(40); +- int randomInt = level.getRandom().nextInt(40); ++ int randomInt = level.getRandom().nextInt(io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA)); // Paper - Configure how many orb groups per area List entities = level.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), aabb, orb -> canMerge(orb, randomInt, amount)); -@@ -193,9 +_,14 @@ + if (!entities.isEmpty()) { + ExperienceOrb experienceOrb = entities.get(0); +@@ -189,13 +_,18 @@ + } + + private static boolean canMerge(ExperienceOrb orb, int amount, int other) { +- return !orb.isRemoved() && (orb.getId() - amount) % 40 == 0 && orb.getValue() == other; ++ return !orb.isRemoved() && (orb.getId() - amount) % io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA) == 0 && orb.getValue() == other; // Paper - Configure how many orbs will merge together } private void merge(ExperienceOrb orb) { diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java b/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java index 4a9258b62d..d0c4037c3c 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java @@ -62,7 +62,8 @@ public abstract class Configurations { protected ObjectMapper.Factory.Builder createObjectMapper() { return ObjectMapper.factoryBuilder() .addConstraint(Constraint.class, new Constraint.Factory()) - .addConstraint(Constraints.Min.class, Number.class, new Constraints.Min.Factory()); + .addConstraint(Constraints.Min.class, Number.class, new Constraints.Min.Factory()) + .addConstraint(Constraints.Max.class, Number.class, new Constraints.Max.Factory()); } protected YamlConfigurationLoader.Builder createLoaderBuilder() { diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java index 6e9bfd9866..27940b8603 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -356,6 +356,9 @@ public class GlobalConfiguration extends ConfigurationPart { public IntOr.Default compressionLevel = IntOr.Default.USE_DEFAULT; @Comment("Defines the leniency distance added on the server to the interaction range of a player when validating interact packets.") public DoubleOr.Default clientInteractionLeniencyDistance = DoubleOr.Default.USE_DEFAULT; + @Comment("Defines how many orbs groups can exist in an area.") + @Constraints.Min(1) + public IntOr.Default xpOrbGroupsPerArea = IntOr.Default.USE_DEFAULT; } public BlockUpdates blockUpdates; diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java b/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java index 9cab83a5b4..0353ed62e4 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java @@ -40,4 +40,22 @@ public final class Constraints { } } } + + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface Max { + int value(); + + final class Factory implements Constraint.Factory { + @Override + public Constraint make(Max data, Type type) { + return value -> { + if (value != null && value.intValue() > data.value()) { + throw new SerializationException(value + " is greater than the max " + data.value()); + } + }; + } + } + } }