--- a/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
@@ -231,13 +_,22 @@
     public InteractionResult mobInteract(Player player, InteractionHand hand) {
         ItemStack itemInHand = player.getItemInHand(hand);
         if (itemInHand.is(Items.BUCKET) && !this.isBaby()) {
+            // CraftBukkit start - Got milk?
+            org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemInHand, Items.MILK_BUCKET, hand);
+
+            if (event.isCancelled()) {
+                player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
+                return InteractionResult.PASS;
+            }
+            // CraftBukkit end
             player.playSound(this.getMilkingSound(), 1.0F, 1.0F);
-            ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, Items.MILK_BUCKET.getDefaultInstance());
+            ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit
             player.setItemInHand(hand, itemStack);
             return InteractionResult.SUCCESS;
         } else {
+            boolean isFood = this.isFood(itemInHand); // Paper - track before stack is possibly decreased to 0 (Fixes MC-244739)
             InteractionResult interactionResult = super.mobInteract(player, hand);
-            if (interactionResult.consumesAction() && this.isFood(itemInHand)) {
+            if (interactionResult.consumesAction() && isFood) { // Paper
                 this.playEatingSound();
             }
 
@@ -349,8 +_,7 @@
             double d1 = Mth.randomBetween(this.random, 0.3F, 0.7F);
             double d2 = Mth.randomBetween(this.random, -0.2F, 0.2F);
             ItemEntity itemEntity = new ItemEntity(this.level(), vec3.x(), vec3.y(), vec3.z(), itemStack, d, d1, d2);
-            this.level().addFreshEntity(itemEntity);
-            return true;
+            return this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), itemEntity) != null; // Paper - Call EntityDropItemEvent
         }
     }
 
@@ -381,4 +_,15 @@
     ) {
         return level.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(level, pos);
     }
+
+    // Paper start - Goat ram API
+    public void ram(net.minecraft.world.entity.LivingEntity entity) {
+        Brain<Goat> brain = this.getBrain();
+        brain.setMemory(MemoryModuleType.RAM_TARGET, entity.position());
+        brain.eraseMemory(MemoryModuleType.RAM_COOLDOWN_TICKS);
+        brain.eraseMemory(MemoryModuleType.BREED_TARGET);
+        brain.eraseMemory(MemoryModuleType.TEMPTING_PLAYER);
+        brain.setActiveActivityIfPossible(net.minecraft.world.entity.schedule.Activity.RAM);
+    }
+    // Paper end - Goat ram API
 }
