--- a/net/minecraft/world/entity/Leashable.java +++ b/net/minecraft/world/entity/Leashable.java @@ -56,6 +_,11 @@ } default void writeLeashData(CompoundTag tag, @Nullable Leashable.LeashData leashData) { + // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin + if (leashData != null && leashData.leashHolder != null && leashData.leashHolder.pluginRemoved) { + return; + } + // CraftBukkit end tag.storeNullable("leash", Leashable.LeashData.CODEC, leashData); } @@ -75,7 +_,9 @@ } if (entity.tickCount > 100) { + entity.forceDrops = true; // CraftBukkit entity.spawnAtLocation(serverLevel, Items.LEAD); + entity.forceDrops = false; // CraftBukkit entity.setLeashData(null); } } @@ -99,7 +_,9 @@ entity.onLeashRemoved(); if (entity.level() instanceof ServerLevel serverLevel) { if (dropItem) { + entity.forceDrops = true; // CraftBukkit entity.spawnAtLocation(serverLevel, Items.LEAD); + entity.forceDrops = false; // CraftBukkit } if (broadcastPacket) { @@ -117,7 +_,15 @@ if (leashData != null && leashData.leashHolder != null) { if (!entity.isAlive() || !leashData.leashHolder.isAlive()) { - if (level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { + // Paper start - Expand EntityUnleashEvent + final org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent( + entity.getBukkitEntity(), + !entity.isAlive() ? org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.PLAYER_UNLEASH : org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.HOLDER_GONE, + level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved + ); + event.callEvent(); + if (event.isDropLeash()) { // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin + // Paper end - Expand EntityUnleashEvent entity.dropLeash(); } else { entity.removeLeash(); @@ -131,7 +_,7 @@ return; } - if (f > 10.0) { + if (f > entity.level().paperConfig().misc.maxLeashDistance.or(LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance entity.leashTooFarBehaviour(); } else if (f > 6.0) { entity.elasticRangeLeashBehaviour(leashHolder, f); @@ -148,7 +_,21 @@ } default void leashTooFarBehaviour() { - this.dropLeash(); + // CraftBukkit start + boolean dropLeash = true; // Paper + if (this instanceof Entity entity) { + // Paper start - Expand EntityUnleashEvent + final org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent(entity.getBukkitEntity(), org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.DISTANCE, true); + if (!event.callEvent()) return; + dropLeash = event.isDropLeash(); + } + // CraftBukkit end + if (dropLeash) { + this.dropLeash(); + } else { + this.removeLeash(); + } + // Paper end - Expand EntityUnleashEvent } default void closeRangeLeashBehaviour(Entity entity) {