--- a/net/minecraft/world/entity/animal/Bucketable.java +++ b/net/minecraft/world/entity/animal/Bucketable.java @@ -18,6 +18,14 @@ import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.World; +// CraftBukkit start +import net.minecraft.network.protocol.game.PacketPlayOutSpawnEntity; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerBucketEntityEvent; +// CraftBukkit end + public interface Bucketable { boolean fromBucket(); @@ -64,7 +72,7 @@ /** @deprecated */ @Deprecated static void loadDefaultDataFromBucketTag(EntityInsentient entityinsentient, NBTTagCompound nbttagcompound) { - Optional optional = nbttagcompound.getBoolean("NoAI"); + Optional optional = nbttagcompound.getBoolean("NoAI"); // CraftBukkit - decompile error Objects.requireNonNull(entityinsentient); optional.ifPresent(entityinsentient::setNoAi); @@ -80,19 +88,31 @@ optional = nbttagcompound.getBoolean("Invulnerable"); Objects.requireNonNull(entityinsentient); optional.ifPresent(entityinsentient::setInvulnerable); - optional = nbttagcompound.getFloat("Health"); + Optional optional2 = nbttagcompound.getFloat("Health"); // CraftBukkit - decompile error Objects.requireNonNull(entityinsentient); - optional.ifPresent(entityinsentient::setHealth); + optional2.ifPresent(entityinsentient::setHealth); // CraftBukkit - decompile error } static Optional bucketMobPickup(EntityHuman entityhuman, EnumHand enumhand, T t0) { ItemStack itemstack = entityhuman.getItemInHand(enumhand); if (itemstack.getItem() == Items.WATER_BUCKET && t0.isAlive()) { - t0.playSound(((Bucketable) t0).getPickupSound(), 1.0F, 1.0F); + // CraftBukkit start + // t0.playSound(((Bucketable) t0).getPickupSound(), 1.0F, 1.0F); // CraftBukkit - moved down ItemStack itemstack1 = ((Bucketable) t0).getBucketItemStack(); ((Bucketable) t0).saveToBucketTag(itemstack1); + + PlayerBucketEntityEvent playerBucketFishEvent = CraftEventFactory.callPlayerFishBucketEvent(t0, entityhuman, itemstack, itemstack1, enumhand); + itemstack1 = CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket()); + if (playerBucketFishEvent.isCancelled()) { + ((EntityPlayer) entityhuman).containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket + t0.getBukkitEntity().update((EntityPlayer) entityhuman); // We need to play out these packets as the client assumes the fish is gone + t0.refreshEntityData((EntityPlayer) entityhuman); // Need to send data such as the display name to client + return Optional.of(EnumInteractionResult.FAIL); + } + t0.playSound(((Bucketable) t0).getPickupSound(), 1.0F, 1.0F); + // CraftBukkit end ItemStack itemstack2 = ItemLiquidUtil.createFilledResult(itemstack, entityhuman, itemstack1, false); entityhuman.setItemInHand(enumhand, itemstack2); @@ -102,7 +122,7 @@ CriterionTriggers.FILLED_BUCKET.trigger((EntityPlayer) entityhuman, itemstack1); } - t0.discard(); + t0.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause return Optional.of(EnumInteractionResult.SUCCESS); } else { return Optional.empty();