--- a/net/minecraft/world/level/block/BlockBed.java
+++ b/net/minecraft/world/level/block/BlockBed.java
@@ -95,7 +95,8 @@
                 }
             }
 
-            if (!canSetSpawn(world)) {
+            // CraftBukkit - moved world and biome check into EntityHuman
+            if (false && !canSetSpawn(world)) {
                 world.removeBlock(blockposition, false);
                 BlockPosition blockposition1 = blockposition.relative(((EnumDirection) iblockdata.getValue(BlockBed.FACING)).getOpposite());
 
@@ -114,7 +115,16 @@
 
                 return EnumInteractionResult.SUCCESS_SERVER;
             } else {
+                // CraftBukkit start
+                IBlockData finaliblockdata = iblockdata;
+                BlockPosition finalblockposition = blockposition;
+                // CraftBukkit end
                 entityhuman.startSleepInBed(blockposition).ifLeft((entityhuman_enumbedresult) -> {
+                    // CraftBukkit start - handling bed explosion from below here
+                    if (!world.dimensionType().bedWorks()) {
+                        this.explodeBed(finaliblockdata, world, finalblockposition);
+                    } else
+                    // CraftBukkit end
                     if (entityhuman_enumbedresult.getMessage() != null) {
                         entityhuman.displayClientMessage(entityhuman_enumbedresult.getMessage(), true);
                     }
@@ -125,8 +135,30 @@
         }
     }
 
+    // CraftBukkit start
+    private EnumInteractionResult explodeBed(IBlockData iblockdata, World world, BlockPosition blockposition) {
+        {
+            {
+                org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition).getState(); // CraftBukkit - capture BlockState before remove block
+                world.removeBlock(blockposition, false);
+                BlockPosition blockposition1 = blockposition.relative(((EnumDirection) iblockdata.getValue(BlockBed.FACING)).getOpposite());
+
+                if (world.getBlockState(blockposition1).getBlock() == this) {
+                    world.removeBlock(blockposition1, false);
+                }
+
+                Vec3D vec3d = blockposition.getCenter();
+
+                world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, World.a.BLOCK); // CraftBukkit - add state
+                return EnumInteractionResult.SUCCESS;
+            }
+        }
+    }
+    // CraftBukkit end
+
     public static boolean canSetSpawn(World world) {
-        return world.dimensionType().bedWorks();
+        // CraftBukkit - moved world and biome check into EntityHuman
+        return true || world.dimensionType().bedWorks();
     }
 
     private boolean kickVillagerOutOfBed(World world, BlockPosition blockposition) {
@@ -320,6 +352,11 @@
             BlockPosition blockposition1 = blockposition.relative((EnumDirection) iblockdata.getValue(BlockBed.FACING));
 
             world.setBlock(blockposition1, (IBlockData) iblockdata.setValue(BlockBed.PART, BlockPropertyBedPart.HEAD), 3);
+            // CraftBukkit start - SPIGOT-7315: Don't updated if we capture block states
+            if (world.captureBlockStates) {
+                return;
+            }
+            // CraftBukkit end
             world.blockUpdated(blockposition, Blocks.AIR);
             iblockdata.updateNeighbourShapes(world, blockposition, 3);
         }
