--- a/net/minecraft/world/entity/animal/MushroomCow.java
+++ b/net/minecraft/world/entity/animal/MushroomCow.java
@@ -47,7 +_,7 @@
     private static final int MUTATE_CHANCE = 1024;
     private static final String TAG_STEW_EFFECTS = "stew_effects";
     @Nullable
-    private SuspiciousStewEffects stewEffects;
+    public SuspiciousStewEffects stewEffects;
     @Nullable
     private UUID lastLightningBoltUUID;
 
@@ -110,7 +_,17 @@
             return InteractionResult.SUCCESS;
         } else if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) {
             if (this.level() instanceof ServerLevel serverLevel) {
-                this.shear(serverLevel, SoundSource.PLAYERS, itemInHand);
+                // CraftBukkit start
+                // Paper start - custom shear drops
+                java.util.List<ItemStack> drops = this.generateDefaultDrops(serverLevel, itemInHand);
+                org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemInHand, hand, drops);
+                if (event != null) {
+                    if (event.isCancelled()) return InteractionResult.PASS;
+                    drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
+                    // Paper end - custom shear drops
+                }
+                // CraftBukkit end
+                this.shear(serverLevel, SoundSource.PLAYERS, itemInHand, drops); // Paper - custom shear drops
                 this.gameEvent(GameEvent.SHEAR, player);
                 itemInHand.hurtAndBreak(1, player, getSlotForHand(hand));
             }
@@ -163,15 +_,31 @@
 
     @Override
     public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) {
+        // Paper start - custom shear drops
+        this.shear(level, soundSource, shears, this.generateDefaultDrops(level, shears));
+    }
+
+    @Override
+    public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
+        final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+        this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (ignored, stack) -> {
+            for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1));
+        });
+        return drops;
+    }
+
+    @Override
+    public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears, java.util.List<ItemStack> drops) {
+        // Paper end
         level.playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, soundSource, 1.0F, 1.0F);
         this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), mob -> {
             level.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0);
-            this.dropFromShearingLootTable(level, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (serverLevel, itemStack) -> {
-                for (int i = 0; i < itemStack.getCount(); i++) {
-                    serverLevel.addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), itemStack.copyWithCount(1)));
-                }
+            // Paper start - custom shear drops; moved drop generation to separate method
+            drops.forEach(drop -> {
+                this.spawnAtLocation(level, new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), drop));
             });
-        });
+            // Paper end - custom shear drops
+        }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.SHEARED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); // CraftBukkit
     }
 
     @Override
