--- a/net/minecraft/world/entity/Leashable.java +++ b/net/minecraft/world/entity/Leashable.java @@ -16,6 +16,11 @@ import net.minecraft.world.level.IMaterial; import net.minecraft.world.level.World; +// CraftBukkit start +import org.bukkit.event.entity.EntityUnleashEvent; +import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason; +// CraftBukkit end + public interface Leashable { String LEASH_TAG = "leash"; @@ -45,7 +50,7 @@ default void setDelayedLeashHolderId(int i) { this.setLeashData(new Leashable.a(i)); - dropLeash((Entity) this, false, false); + dropLeash((Entity & Leashable) this, false, false); // CraftBukkit - decompile error } @Nullable @@ -54,7 +59,7 @@ return new Leashable.a(Either.left(nbttagcompound.getCompound("leash").getUUID("UUID"))); } else { if (nbttagcompound.contains("leash", 11)) { - Either either = (Either) GameProfileSerializer.readBlockPos(nbttagcompound, "leash").map(Either::right).orElse((Object) null); + Either either = (Either) GameProfileSerializer.readBlockPos(nbttagcompound, "leash").map(Either::right).orElse(null); // CraftBukkit - decompile error if (either != null) { return new Leashable.a(either); @@ -69,6 +74,11 @@ if (leashable_a != null) { Either either = leashable_a.delayedLeashInfo; Entity entity = leashable_a.leashHolder; + // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin + if (entity != null && entity.pluginRemoved) { + return; + } + // CraftBukkit end if (entity instanceof EntityLeash) { EntityLeash entityleash = (EntityLeash) entity; @@ -111,7 +121,9 @@ } if (e0.tickCount > 100) { + e0.forceDrops = true; // CraftBukkit e0.spawnAtLocation(worldserver, (IMaterial) Items.LEAD); + e0.forceDrops = false; // CraftBukkit ((Leashable) e0).setLeashData((Leashable.a) null); } } @@ -120,7 +132,7 @@ } default void dropLeash(boolean flag, boolean flag1) { - dropLeash((Entity) this, flag, flag1); + dropLeash((Entity & Leashable) this, flag, flag1); // CraftBukkit - decompile error } private static void dropLeash(E e0, boolean flag, boolean flag1) { @@ -134,7 +146,9 @@ WorldServer worldserver = (WorldServer) world; if (flag1) { + e0.forceDrops = true; // CraftBukkit e0.spawnAtLocation(worldserver, (IMaterial) Items.LEAD); + e0.forceDrops = false; // CraftBukkit } if (flag) { @@ -154,7 +168,8 @@ if (leashable_a != null && leashable_a.leashHolder != null) { if (!e0.isAlive() || !leashable_a.leashHolder.isAlive()) { - dropLeash(e0, true, worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)); + worldserver.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(e0.getBukkitEntity(), (!e0.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit + dropLeash(e0, true, worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !e0.pluginRemoved); // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin } Entity entity = ((Leashable) e0).getLeashHolder(); @@ -184,13 +199,18 @@ } default void leashTooFarBehaviour() { + // CraftBukkit start + if (this instanceof Entity entity) { + entity.level().getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(entity.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); + } + // CraftBukkit end this.dropLeash(true, true); } default void closeRangeLeashBehaviour(Entity entity) {} default void elasticRangeLeashBehaviour(Entity entity, float f) { - legacyElasticRangeLeashBehaviour((Entity) this, entity, f); + legacyElasticRangeLeashBehaviour((Entity & Leashable) this, entity, f); // CraftBukkit - decompile error } private static void legacyElasticRangeLeashBehaviour(E e0, Entity entity, float f) { @@ -202,7 +222,7 @@ } default void setLeashedTo(Entity entity, boolean flag) { - setLeashedTo((Entity) this, entity, flag); + setLeashedTo((Entity & Leashable) this, entity, flag); // CraftBukkit - decompile error } private static void setLeashedTo(E e0, Entity entity, boolean flag) { @@ -233,7 +253,7 @@ @Nullable default Entity getLeashHolder() { - return getLeashHolder((Entity) this); + return getLeashHolder((Entity & Leashable) this); // CraftBukkit - decompile error } @Nullable