--- a/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/net/minecraft/world/entity/animal/SnowGolem.java
@@ -91,7 +_,7 @@
         super.aiStep();
         if (this.level() instanceof ServerLevel serverLevel) {
             if (this.level().getBiome(this.blockPosition()).is(BiomeTags.SNOW_GOLEM_MELTS)) {
-                this.hurtServer(serverLevel, this.damageSources().onFire(), 1.0F);
+                this.hurtServer(serverLevel, this.damageSources().onFire().knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.MELTING), 1.0F); // CraftBukkit
             }
 
             if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
@@ -106,7 +_,7 @@
                 int floor2 = Mth.floor(this.getZ() + (i / 2 % 2 * 2 - 1) * 0.25F);
                 BlockPos blockPos = new BlockPos(floor, floor1, floor2);
                 if (this.level().getBlockState(blockPos).isAir() && blockState.canSurvive(this.level(), blockPos)) {
-                    this.level().setBlockAndUpdate(blockPos, blockState);
+                    if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this.level(), blockPos, blockState, 3, this)) continue; // CraftBukkit
                     this.level().gameEvent(GameEvent.BLOCK_PLACE, blockPos, GameEvent.Context.of(this, blockState));
                 }
             }
@@ -134,7 +_,19 @@
         ItemStack itemInHand = player.getItemInHand(hand);
         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));
             }
@@ -147,11 +_,29 @@
 
     @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_SNOW_GOLEM, shears, (ignored, stack) -> {
+            drops.add(stack);
+        });
+        return drops;
+    }
+
+    @Override
+    public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears, java.util.List<ItemStack> drops) {
+        // Paper end - custom shear drops
         level.playSound(null, this, SoundEvents.SNOW_GOLEM_SHEAR, soundSource, 1.0F, 1.0F);
         this.setPumpkin(false);
-        this.dropFromShearingLootTable(
-            level, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (serverLevel, itemStack) -> this.spawnAtLocation(serverLevel, itemStack, this.getEyeHeight())
-        );
+        drops.forEach(itemStack -> { // Paper - custom shear drops
+            this.forceDrops = true; // CraftBukkit
+            this.spawnAtLocation(level, itemStack, this.getEyeHeight());
+            this.forceDrops = false; // CraftBukkit
+        });
     }
 
     @Override
@@ -174,19 +_,19 @@
 
     @Nullable
     @Override
-    protected SoundEvent getAmbientSound() {
+    public SoundEvent getAmbientSound() {
         return SoundEvents.SNOW_GOLEM_AMBIENT;
     }
 
     @Nullable
     @Override
-    protected SoundEvent getHurtSound(DamageSource damageSource) {
+    public SoundEvent getHurtSound(DamageSource damageSource) {
         return SoundEvents.SNOW_GOLEM_HURT;
     }
 
     @Nullable
     @Override
-    protected SoundEvent getDeathSound() {
+    public SoundEvent getDeathSound() {
         return SoundEvents.SNOW_GOLEM_DEATH;
     }
 
