--- 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 } default void readLeashData(NBTTagCompound nbttagcompound) { @@ -64,7 +69,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); @@ -79,6 +84,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; @@ -121,7 +131,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); } } @@ -130,11 +142,11 @@ } default void dropLeash() { - dropLeash((Entity) this, true, true); + dropLeash((Entity & Leashable) this, true, true); // CraftBukkit - decompile error } default void removeLeash() { - dropLeash((Entity) this, true, false); + dropLeash((Entity & Leashable) this, true, false); // CraftBukkit - decompile error } default void onLeashRemoved() {} @@ -151,7 +163,9 @@ WorldServer worldserver = (WorldServer) world; if (flag1) { + e0.forceDrops = true; // CraftBukkit e0.spawnAtLocation(worldserver, (IMaterial) Items.LEAD); + e0.forceDrops = false; // CraftBukkit } if (flag) { @@ -171,7 +185,8 @@ if (leashable_a != null && leashable_a.leashHolder != null) { if (!e0.isAlive() || !leashable_a.leashHolder.isAlive()) { - if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { + worldserver.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(e0.getBukkitEntity(), (!e0.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit + if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !e0.pluginRemoved) { // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin ((Leashable) e0).dropLeash(); } else { ((Leashable) e0).removeLeash(); @@ -205,13 +220,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(); } 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) { @@ -223,7 +243,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) { @@ -254,7 +274,7 @@ @Nullable default Entity getLeashHolder() { - return getLeashHolder((Entity) this); + return getLeashHolder((Entity & Leashable) this); // CraftBukkit - decompile error } @Nullable