From 5af1e7ca1fa1515c120e791eb41fc441cbc52021 Mon Sep 17 00:00:00 2001 From: Doc Date: Sat, 2 May 2026 10:55:46 -0400 Subject: [PATCH 1/2] Add Allies and additional rule API --- .../main/java/org/bukkit/entity/Entity.java | 28 +++++++++++++++++++ .../0001-Moonrise-optimisation-patches.patch | 20 ++++++------- .../0005-Entity-Activation-Range-2.0.patch | 12 ++++---- ...025-Optimise-EntityScheduler-ticking.patch | 6 ++-- .../minecraft/world/entity/Entity.java.patch | 12 +++++++- .../craftbukkit/entity/CraftEntity.java | 17 +++++++++++ 6 files changed, 75 insertions(+), 20 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/entity/Entity.java b/paper-api/src/main/java/org/bukkit/entity/Entity.java index 2c68aae864a7..438cb55583b8 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Entity.java +++ b/paper-api/src/main/java/org/bukkit/entity/Entity.java @@ -5,6 +5,7 @@ import java.util.UUID; import io.papermc.paper.datacomponent.DataComponentView; import io.papermc.paper.entity.LookAnchor; +import java.util.function.Predicate; import net.kyori.adventure.util.TriState; import org.bukkit.Chunk; // Paper import org.bukkit.EntityEffect; @@ -1322,4 +1323,31 @@ default boolean spawnAt(@NotNull Location location) { */ void broadcastHurtAnimation(@NotNull java.util.Collection players); // Paper end - broadcast hurt animation + + /** + * Gets if the entity is allied to the given entity. + * + * @param other the other entity + * @return true if the entity is allied to the given entity + */ + boolean isAlliedTo(@NotNull Entity other); + + /** + * Gets the current additional rule of alliance with any entity. + *
+ * This is an additional rule from the vanilla behaviour for any entity, like share a team. + *
+ * This rule is not (currently) persistent. + * + * @return additional rule of alliance + * @see #setAdditionalAlliedRule(Predicate) + */ + @Nullable Predicate getAdditionalAlliedRule(); + + /** + * Sets the current additional rule of alliance with any entity. + * + * @param predicate the additional rule of alliance with any entity + */ + void setAdditionalAlliedRule(@Nullable Predicate predicate); } diff --git a/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch index 2f5fc143544b..5fe05961fc94 100644 --- a/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch @@ -28453,7 +28453,7 @@ index c974b6cafb1f6aa2a57cfdc8a39c887f02f42b1d..ec40f02032f965f548b0c0a29aa9d9bb // Paper start - PlayerChunkLoadEvent if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { diff --git a/net/minecraft/server/network/config/PrepareSpawnTask.java b/net/minecraft/server/network/config/PrepareSpawnTask.java -index 83af9ee3ba150da85b9b694cd76a5fabb5b2d8ef..1fb40837bd02672850ec9adc2797190df22b33fc 100644 +index b5d993095aa77bb132c513f73dbf6d2afb2e3943..8b318dd8aa918284c5fa89e990b13bec425102cb 100644 --- a/net/minecraft/server/network/config/PrepareSpawnTask.java +++ b/net/minecraft/server/network/config/PrepareSpawnTask.java @@ -171,7 +171,7 @@ public class PrepareSpawnTask implements ConfigurationTask { @@ -28885,7 +28885,7 @@ index 1ceb7e4a3abd4d9de5133d182d3267d2164918f6..eb2fa32cff6824c14f865c8731df7d08 + // Paper end - block counting } diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4e81a3d3a 100644 +index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f7fa7f8cb 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -167,7 +167,7 @@ public abstract class Entity @@ -28979,7 +28979,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 } // Paper end - Share random for entities to make them more random public org.bukkit.event.entity.CreatureSpawnEvent.@Nullable SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason -@@ -433,6 +389,156 @@ public abstract class Entity +@@ -434,6 +390,156 @@ public abstract class Entity return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -29136,7 +29136,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 public Entity(final EntityType type, final Level level) { this.type = type; -@@ -1421,34 +1527,76 @@ public abstract class Entity +@@ -1422,34 +1528,76 @@ public abstract class Entity } private Vec3 collide(final Vec3 movement) { @@ -29236,7 +29236,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 } private static float[] collectCandidateStepUpHeights( -@@ -2738,21 +2886,110 @@ public abstract class Entity +@@ -2739,21 +2887,110 @@ public abstract class Entity } public boolean isInWall() { @@ -29358,7 +29358,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 } public InteractionResult interact(final Player player, final InteractionHand hand, final Vec3 location) { -@@ -4363,15 +4600,17 @@ public abstract class Entity +@@ -4364,15 +4601,17 @@ public abstract class Entity } public Iterable getIndirectPassengers() { @@ -29384,7 +29384,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 } public int countPlayerPassengers() { -@@ -4682,6 +4921,15 @@ public abstract class Entity +@@ -4683,6 +4922,15 @@ public abstract class Entity } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29400,7 +29400,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 if (!checkPosition(this, x, y, z)) { return; } -@@ -4831,6 +5079,12 @@ public abstract class Entity +@@ -4832,6 +5080,12 @@ public abstract class Entity @Override public final void setRemoved(final Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.@Nullable Cause cause) { // CraftBukkit - add Bukkit remove cause @@ -29413,7 +29413,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers if (this.removalReason == null) { -@@ -4841,7 +5095,7 @@ public abstract class Entity +@@ -4842,7 +5096,7 @@ public abstract class Entity this.stopRiding(); } @@ -29422,7 +29422,7 @@ index 29896cb17fcf8ab967a937e9b0e102a8354b6889..e087d5596979044fe7fbcf7f2cccdae4 this.levelCallback.onRemove(reason); this.onRemoval(reason); // Paper start - Folia schedulers -@@ -4875,7 +5129,7 @@ public abstract class Entity +@@ -4876,7 +5130,7 @@ public abstract class Entity public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() diff --git a/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch index bf988f7f15f9..854a5d1c51e8 100644 --- a/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch @@ -462,10 +462,10 @@ index 0df8332933203a904bd9ef9efb3c9bce21e65441..1a502cbd8acea9420fa6dd8d716018b5 public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index e087d5596979044fe7fbcf7f2cccdae4e81a3d3a..fea6c3b48c4eb162fbdc099fa775bc3161a4dd4e 100644 +index bf65239ad8954dfd6dc4fafe4753908f7fa7f8cb..837e117181d9378bf1fdd67212b24436eca36a6c 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -382,6 +382,15 @@ public abstract class Entity +@@ -383,6 +383,15 @@ public abstract class Entity private final int despawnTime; // Paper - entity despawn time limit public int totalEntityAge; // Paper - age-like counter for all entities public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges @@ -481,7 +481,7 @@ index e087d5596979044fe7fbcf7f2cccdae4e81a3d3a..fea6c3b48c4eb162fbdc099fa775bc31 // CraftBukkit end // Paper start -@@ -547,6 +556,13 @@ public abstract class Entity +@@ -548,6 +557,13 @@ public abstract class Entity this.position = Vec3.ZERO; this.blockPosition = BlockPos.ZERO; this.chunkPosition = ChunkPos.ZERO; @@ -495,7 +495,7 @@ index e087d5596979044fe7fbcf7f2cccdae4e81a3d3a..fea6c3b48c4eb162fbdc099fa775bc31 SynchedEntityData.Builder entityDataBuilder = new SynchedEntityData.Builder(this); entityDataBuilder.define(DATA_SHARED_FLAGS_ID, (byte)0); entityDataBuilder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply()); -@@ -1135,6 +1151,10 @@ public abstract class Entity +@@ -1136,6 +1152,10 @@ public abstract class Entity } else { if (moverType == MoverType.PISTON) { delta = this.limitPistonMovement(delta); @@ -506,7 +506,7 @@ index e087d5596979044fe7fbcf7f2cccdae4e81a3d3a..fea6c3b48c4eb162fbdc099fa775bc31 if (delta.equals(Vec3.ZERO)) { return; } -@@ -1150,6 +1170,13 @@ public abstract class Entity +@@ -1151,6 +1171,13 @@ public abstract class Entity this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } @@ -817,7 +817,7 @@ index 3a590d4dc980a2912e9cc043d8c8db4cf9d60803..06ab7c48b18c03af494ab10fc2b584ce + } diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index b8d56c7a14521cb77ba2cf619be826fb06be81da..2b3ec0a012918815ed0eda8b40647c2274a5b418 100644 +index c0f901c4ac61a0aa2b480f102feb3669b111f4c0..07c301ba02c7f2c032a29a0ae3bdf95fc522c03b 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -155,6 +155,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl diff --git a/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch b/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch index c929667c8ef8..1314d28136a1 100644 --- a/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch +++ b/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch @@ -20,7 +20,7 @@ index 2bc436cdf5180a7943c45fabb9fbbedae6f7db56..f312a7f5b1b2a777ab36b94ce7cbf387 @Override diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 8c4b40362f77cdea6e57315a6639006ac7ab27c7..a5217deb236ee922d020a7a6a03141a5f67acd77 100644 +index 72bc7f6efc8f23d6ff31d2dabb13490655c58074..9a438cbdb05c7a8c33804c3b66ff42f357a96bc3 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -1794,32 +1794,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop movementThisTick = new ArrayDeque<>(100); -@@ -299,6 +_,40 @@ +@@ -299,6 +_,41 @@ private final LongSet visitedBlocks = new LongOpenHashSet(); private final InsideBlockEffectApplier.StepBasedCollector insideEffectCollector = new InsideBlockEffectApplier.StepBasedCollector(); private CustomData customData = CustomData.EMPTY; @@ -148,6 +148,7 @@ + public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled + public boolean persistentInvisibility = false; + public @Nullable BlockPos lastLavaContact; ++ public @Nullable Predicate alliesPredicate; // Paper - Allies API + // Marks an entity, that it was removed by a plugin via Entity#remove + // Main use case currently is for SPIGOT-7487, preventing dropping of leash when leash is removed + public boolean pluginRemoved = false; @@ -1307,6 +1308,15 @@ return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); } +@@ -2699,7 +_,7 @@ + } + + protected boolean considersEntityAsAlly(final Entity other) { +- return this.isAlliedTo(other.getTeam()); ++ return this.isAlliedTo(other.getTeam()) || (this.alliesPredicate != null && this.alliesPredicate.test(other.getBukkitEntity())); // Paper - Allies API + } + + public boolean isAlliedTo(final @Nullable Team other) { @@ -2707,7 +_,11 @@ } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 2f40476da09c..3e2990889676 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -14,6 +14,7 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.function.Predicate; import net.kyori.adventure.pointer.PointersSupplier; import net.kyori.adventure.util.TriState; import net.md_5.bungee.api.chat.BaseComponent; @@ -1331,4 +1332,20 @@ public boolean hasData(final @NotNull DataComponentType type) { return this.entity.get(io.papermc.paper.datacomponent.PaperDataComponentType.bukkitToMinecraft(type)) != null; } + @Override + public boolean isAlliedTo(@NotNull org.bukkit.entity.Entity other) { + Preconditions.checkArgument(other != null, "other cannot be null"); + return this.getHandle().isAlliedTo(((CraftEntity)other).getHandle()); + } + + @Override + public Predicate getAdditionalAlliedRule() { + return this.getHandle().alliesPredicate; + } + + @Override + public void setAdditionalAlliedRule(Predicate predicate) { + this.getHandle().alliesPredicate = predicate; + } + } From 38bb33775d37bf481364ac772611718ae811c849 Mon Sep 17 00:00:00 2001 From: Doc Date: Sun, 3 May 2026 10:25:48 -0400 Subject: [PATCH 2/2] Allow allied rules by key --- .../main/java/org/bukkit/entity/Entity.java | 15 ++++++++++--- .../0001-Moonrise-optimisation-patches.patch | 18 ++++++++-------- .../0005-Entity-Activation-Range-2.0.patch | 10 ++++----- ...025-Optimise-EntityScheduler-ticking.patch | 4 ++-- .../minecraft/world/entity/Entity.java.patch | 5 ++--- .../craftbukkit/entity/CraftEntity.java | 21 +++++++++++++++---- 6 files changed, 47 insertions(+), 26 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/entity/Entity.java b/paper-api/src/main/java/org/bukkit/entity/Entity.java index 438cb55583b8..66d8d1349c6a 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Entity.java +++ b/paper-api/src/main/java/org/bukkit/entity/Entity.java @@ -6,6 +6,7 @@ import io.papermc.paper.datacomponent.DataComponentView; import io.papermc.paper.entity.LookAnchor; import java.util.function.Predicate; +import net.kyori.adventure.key.Key; import net.kyori.adventure.util.TriState; import org.bukkit.Chunk; // Paper import org.bukkit.EntityEffect; @@ -1340,14 +1341,22 @@ default boolean spawnAt(@NotNull Location location) { * This rule is not (currently) persistent. * * @return additional rule of alliance - * @see #setAdditionalAlliedRule(Predicate) + * @see #addAdditionalAlliedRule(Key, Predicate) */ - @Nullable Predicate getAdditionalAlliedRule(); + @Nullable Predicate getAdditionalAlliedRule(@NotNull Key key); /** * Sets the current additional rule of alliance with any entity. * + * @param key the key of the additional rule * @param predicate the additional rule of alliance with any entity */ - void setAdditionalAlliedRule(@Nullable Predicate predicate); + void addAdditionalAlliedRule(@NotNull Key key, @NotNull Predicate predicate); + + /** + * Remove the additional rule of alliance with any entity. + * + * @param key the key of the additional rule + */ + void removeAdditionalAlliedRule(@NotNull Key key); } diff --git a/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch index 5fe05961fc94..3da8abd7020d 100644 --- a/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0001-Moonrise-optimisation-patches.patch @@ -28885,7 +28885,7 @@ index 1ceb7e4a3abd4d9de5133d182d3267d2164918f6..eb2fa32cff6824c14f865c8731df7d08 + // Paper end - block counting } diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f7fa7f8cb 100644 +index 67a0481c2dbfe1c6692a0ced2179d272100b1979..2d7616e6d5a425677c1057b3e16325150cc87ae6 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -167,7 +167,7 @@ public abstract class Entity @@ -28979,7 +28979,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f } // Paper end - Share random for entities to make them more random public org.bukkit.event.entity.CreatureSpawnEvent.@Nullable SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason -@@ -434,6 +390,156 @@ public abstract class Entity +@@ -433,6 +389,156 @@ public abstract class Entity return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -29136,7 +29136,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f public Entity(final EntityType type, final Level level) { this.type = type; -@@ -1422,34 +1528,76 @@ public abstract class Entity +@@ -1421,34 +1527,76 @@ public abstract class Entity } private Vec3 collide(final Vec3 movement) { @@ -29236,7 +29236,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f } private static float[] collectCandidateStepUpHeights( -@@ -2739,21 +2887,110 @@ public abstract class Entity +@@ -2738,21 +2886,110 @@ public abstract class Entity } public boolean isInWall() { @@ -29358,7 +29358,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f } public InteractionResult interact(final Player player, final InteractionHand hand, final Vec3 location) { -@@ -4364,15 +4601,17 @@ public abstract class Entity +@@ -4363,15 +4600,17 @@ public abstract class Entity } public Iterable getIndirectPassengers() { @@ -29384,7 +29384,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f } public int countPlayerPassengers() { -@@ -4683,6 +4922,15 @@ public abstract class Entity +@@ -4682,6 +4921,15 @@ public abstract class Entity } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29400,7 +29400,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f if (!checkPosition(this, x, y, z)) { return; } -@@ -4832,6 +5080,12 @@ public abstract class Entity +@@ -4831,6 +5079,12 @@ public abstract class Entity @Override public final void setRemoved(final Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.@Nullable Cause cause) { // CraftBukkit - add Bukkit remove cause @@ -29413,7 +29413,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers if (this.removalReason == null) { -@@ -4842,7 +5096,7 @@ public abstract class Entity +@@ -4841,7 +5095,7 @@ public abstract class Entity this.stopRiding(); } @@ -29422,7 +29422,7 @@ index 85231da452ce7c115e832b5344194f6db1d52d40..bf65239ad8954dfd6dc4fafe4753908f this.levelCallback.onRemove(reason); this.onRemoval(reason); // Paper start - Folia schedulers -@@ -4876,7 +5130,7 @@ public abstract class Entity +@@ -4875,7 +5129,7 @@ public abstract class Entity public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() diff --git a/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch index 854a5d1c51e8..270fba53b128 100644 --- a/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch @@ -462,10 +462,10 @@ index 0df8332933203a904bd9ef9efb3c9bce21e65441..1a502cbd8acea9420fa6dd8d716018b5 public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index bf65239ad8954dfd6dc4fafe4753908f7fa7f8cb..837e117181d9378bf1fdd67212b24436eca36a6c 100644 +index 2d7616e6d5a425677c1057b3e16325150cc87ae6..7ab3cf2fb50804c314df576743d19b0aba1ee8bb 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -383,6 +383,15 @@ public abstract class Entity +@@ -382,6 +382,15 @@ public abstract class Entity private final int despawnTime; // Paper - entity despawn time limit public int totalEntityAge; // Paper - age-like counter for all entities public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges @@ -481,7 +481,7 @@ index bf65239ad8954dfd6dc4fafe4753908f7fa7f8cb..837e117181d9378bf1fdd67212b24436 // CraftBukkit end // Paper start -@@ -548,6 +557,13 @@ public abstract class Entity +@@ -547,6 +556,13 @@ public abstract class Entity this.position = Vec3.ZERO; this.blockPosition = BlockPos.ZERO; this.chunkPosition = ChunkPos.ZERO; @@ -495,7 +495,7 @@ index bf65239ad8954dfd6dc4fafe4753908f7fa7f8cb..837e117181d9378bf1fdd67212b24436 SynchedEntityData.Builder entityDataBuilder = new SynchedEntityData.Builder(this); entityDataBuilder.define(DATA_SHARED_FLAGS_ID, (byte)0); entityDataBuilder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply()); -@@ -1136,6 +1152,10 @@ public abstract class Entity +@@ -1135,6 +1151,10 @@ public abstract class Entity } else { if (moverType == MoverType.PISTON) { delta = this.limitPistonMovement(delta); @@ -506,7 +506,7 @@ index bf65239ad8954dfd6dc4fafe4753908f7fa7f8cb..837e117181d9378bf1fdd67212b24436 if (delta.equals(Vec3.ZERO)) { return; } -@@ -1151,6 +1171,13 @@ public abstract class Entity +@@ -1150,6 +1170,13 @@ public abstract class Entity this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } diff --git a/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch b/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch index 1314d28136a1..b78ca6ef9f6c 100644 --- a/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch +++ b/paper-server/patches/features/0025-Optimise-EntityScheduler-ticking.patch @@ -66,10 +66,10 @@ index 72bc7f6efc8f23d6ff31d2dabb13490655c58074..9a438cbdb05c7a8c33804c3b66ff42f3 io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.ADVENTURE_CLICK_MANAGER.handleQueue(this.tickCount); // Paper io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue(this.tickCount); // Paper diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 837e117181d9378bf1fdd67212b24436eca36a6c..8888df296b14a3b5de6268e5996de3c2758e1ad3 100644 +index 7ab3cf2fb50804c314df576743d19b0aba1ee8bb..960ab20654b054e1518c48be3434465a1ca28803 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -5147,6 +5147,11 @@ public abstract class Entity +@@ -5146,6 +5146,11 @@ public abstract class Entity this.getBukkitEntity().taskScheduler.retire(); } // Paper end - Folia schedulers diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index 748cd0dbbfed..b11fb78ca248 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -132,7 +132,7 @@ private @Nullable BlockState inBlockState = null; public static final int MAX_MOVEMENTS_HANDELED_PER_TICK = 100; private final ArrayDeque movementThisTick = new ArrayDeque<>(100); -@@ -299,6 +_,41 @@ +@@ -299,6 +_,40 @@ private final LongSet visitedBlocks = new LongOpenHashSet(); private final InsideBlockEffectApplier.StepBasedCollector insideEffectCollector = new InsideBlockEffectApplier.StepBasedCollector(); private CustomData customData = CustomData.EMPTY; @@ -148,7 +148,6 @@ + public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled + public boolean persistentInvisibility = false; + public @Nullable BlockPos lastLavaContact; -+ public @Nullable Predicate alliesPredicate; // Paper - Allies API + // Marks an entity, that it was removed by a plugin via Entity#remove + // Main use case currently is for SPIGOT-7487, preventing dropping of leash when leash is removed + public boolean pluginRemoved = false; @@ -1313,7 +1312,7 @@ protected boolean considersEntityAsAlly(final Entity other) { - return this.isAlliedTo(other.getTeam()); -+ return this.isAlliedTo(other.getTeam()) || (this.alliesPredicate != null && this.alliesPredicate.test(other.getBukkitEntity())); // Paper - Allies API ++ return this.isAlliedTo(other.getTeam()) || this.getBukkitEntity().considersEntityAsAlly0(other.getBukkitEntity()); // Paper - Allies API } public boolean isAlliedTo(final @Nullable Team other) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 3e2990889676..77c4106c1ed5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -10,11 +10,14 @@ import io.papermc.paper.entity.LookAnchor; import io.papermc.paper.entity.TeleportFlag; import java.util.EnumSet; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import net.kyori.adventure.key.Key; import net.kyori.adventure.pointer.PointersSupplier; import net.kyori.adventure.util.TriState; import net.md_5.bungee.api.chat.BaseComponent; @@ -98,6 +101,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { protected Entity entity; private final EntityType entityType; private EntityDamageEvent lastDamageEvent; + private final Map> additionalAlliedRules = new HashMap<>(); private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftEntity.DATA_TYPE_REGISTRY); // Paper start - Folia shedulers public final io.papermc.paper.threadedregions.EntityScheduler taskScheduler = new io.papermc.paper.threadedregions.EntityScheduler(this); @@ -1332,6 +1336,10 @@ public boolean hasData(final @NotNull DataComponentType type) { return this.entity.get(io.papermc.paper.datacomponent.PaperDataComponentType.bukkitToMinecraft(type)) != null; } + public boolean considersEntityAsAlly0(org.bukkit.entity.Entity entity) { + return this.additionalAlliedRules.values().stream().anyMatch(entityPredicate -> entityPredicate.test(entity)); + } + @Override public boolean isAlliedTo(@NotNull org.bukkit.entity.Entity other) { Preconditions.checkArgument(other != null, "other cannot be null"); @@ -1339,13 +1347,18 @@ public boolean isAlliedTo(@NotNull org.bukkit.entity.Entity other) { } @Override - public Predicate getAdditionalAlliedRule() { - return this.getHandle().alliesPredicate; + public Predicate getAdditionalAlliedRule(@NotNull Key key) { + return this.additionalAlliedRules.get(key); + } + + @Override + public void addAdditionalAlliedRule(@NotNull Key key, @NotNull Predicate predicate) { + this.additionalAlliedRules.put(key, predicate); } @Override - public void setAdditionalAlliedRule(Predicate predicate) { - this.getHandle().alliesPredicate = predicate; + public void removeAdditionalAlliedRule(@NotNull Key key) { + this.additionalAlliedRules.remove(key); } }