--- a/net/minecraft/world/level/block/TurtleEggBlock.java
+++ b/net/minecraft/world/level/block/TurtleEggBlock.java
@@ -74,11 +_,24 @@
             && level instanceof ServerLevel serverLevel
             && this.canDestroyEgg(serverLevel, entity)
             && level.random.nextInt(chance) == 0) {
+            // CraftBukkit start - Step on eggs
+            org.bukkit.event.Cancellable cancellable;
+            if (entity instanceof Player) {
+                cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null);
+            } else {
+                cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos));
+                level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable);
+            }
+
+            if (cancellable.isCancelled()) {
+                return;
+            }
+            // CraftBukkit end
             this.decreaseEggs(serverLevel, pos, state);
         }
     }
 
-    private void decreaseEggs(Level level, BlockPos pos, BlockState state) {
+    public void decreaseEggs(Level level, BlockPos pos, BlockState state) {
         level.playSound(null, pos, SoundEvents.TURTLE_EGG_BREAK, SoundSource.BLOCKS, 0.7F, 0.9F + level.random.nextFloat() * 0.2F);
         int eggsValue = state.getValue(EGGS);
         if (eggsValue <= 1) {
@@ -95,10 +_,20 @@
         if (this.shouldUpdateHatchLevel(level) && onSand(level, pos)) {
             int hatchValue = state.getValue(HATCH);
             if (hatchValue < 2) {
+                // CraftBukkit start - Call BlockGrowEvent
+                if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(TurtleEggBlock.HATCH, hatchValue + 1), 2)) {
+                    return;
+                }
+                // CraftBukkit end
                 level.playSound(null, pos, SoundEvents.TURTLE_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
-                level.setBlock(pos, state.setValue(HATCH, Integer.valueOf(hatchValue + 1)), 2);
+                // level.setBlock(pos, state.setValue(HATCH, Integer.valueOf(hatchValue + 1)), 2); // CraftBukkit - handled above
                 level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state));
             } else {
+                // CraftBukkit start - Call BlockFadeEvent
+                if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.AIR.defaultBlockState()).isCancelled()) {
+                    return;
+                }
+                // CraftBukkit end
                 level.playSound(null, pos, SoundEvents.TURTLE_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
                 level.removeBlock(pos, false);
                 level.gameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Context.of(state));
@@ -110,7 +_,7 @@
                         turtle.setAge(-24000);
                         turtle.setHomePos(pos);
                         turtle.moveTo(pos.getX() + 0.3 + i * 0.2, pos.getY(), pos.getZ() + 0.3, 0.0F, 0.0F);
-                        level.addFreshEntity(turtle);
+                        level.addFreshEntity(turtle, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // CraftBukkit
                     }
                 }
             }
@@ -138,8 +_,8 @@
     }
 
     @Override
-    public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) {
-        super.playerDestroy(level, player, pos, state, te, stack);
+    public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion
+        super.playerDestroy(level, player, pos, state, te, stack, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion
         this.decreaseEggs(level, pos, state);
     }
 
