From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 22 Oct 2021 16:25:07 -0700
Subject: [PATCH] Add exploded block state to BlockExplodeEvent and
 EntityDamageByBlockEvent


diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
index 1a0f86b5a632469942e33c237c247d2d1dee4a3d..25a5a3b949a0eb632611355e74ccd4865be108ca 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
@@ -52,6 +52,7 @@ public class DamageSource {
         return this;
     }
     // CraftBukkit end
+    public @Nullable org.bukkit.block.BlockState explodedBlockState; // Paper - add exploded state
 
     public String toString() {
         return "DamageSource (" + this.type().msgId() + ")";
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
index 8bde8c581796ed11809b80b9a30a33df86116745..4604f8b38460e9113e966889a679d4547f24aff6 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
@@ -247,8 +247,17 @@ public class DamageSources {
         return this.source(DamageTypes.SONIC_BOOM, attacker);
     }
 
+    @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper
     public DamageSource badRespawnPointExplosion(Vec3 position) {
-        return new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position);
+        // Paper start
+        return this.badRespawnPointExplosion(position, null);
+    }
+
+    public DamageSource badRespawnPointExplosion(Vec3 position, @Nullable org.bukkit.block.BlockState explodedBlockState) {
+        DamageSource source = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position);
+        source.explodedBlockState = explodedBlockState;
+        return source;
+        // Paper end
     }
 
     public DamageSource outOfBorder() {
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index 316df76570a7a6843b5a8ed2c44467a0cdf2a6cd..8f97c9df726ac20cfce7bdddd5dd4f8c5aa76c35 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -343,7 +343,7 @@ public class Explosion {
                 bukkitBlocks = event.blockList();
                 yield = event.getYield();
             } else {
-                BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F);
+                BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F, this.damageSource.explodedBlockState); // Paper - exploded block state
                 this.level.getCraftServer().getPluginManager().callEvent(event);
                 cancelled = event.isCancelled();
                 bukkitBlocks = event.blockList();
diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java
index a605c9739ebc8e60bd668ff67c760cca9bd210dc..69839965926c511b6396a0041b6e7295ebf5209b 100644
--- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
@@ -86,6 +86,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
 
             // CraftBukkit - moved world and biome check into EntityHuman
             if (false && !BedBlock.canSetSpawn(world)) {
+                final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getUnplacedBlockState(world, pos, state); // Paper - exploded block state (this won't be called due to the false, but it's good for reference)
                 world.removeBlock(pos, false);
                 BlockPos blockposition1 = pos.relative(((Direction) state.getValue(BedBlock.FACING)).getOpposite());
 
@@ -95,7 +96,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
 
                 Vec3 vec3d = pos.getCenter();
 
-                world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
+                world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
                 return InteractionResult.SUCCESS;
             } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) {
                 if (!this.kickVillagerOutOfBed(world, pos)) {
@@ -137,6 +138,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
     private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) {
         {
             {
+                final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getUnplacedBlockState(world, blockposition, iblockdata); // Paper - exploded block state
                 world.removeBlock(blockposition, false);
                 BlockPos blockposition1 = blockposition.relative(((Direction) iblockdata.getValue(BedBlock.FACING)).getOpposite());
 
@@ -146,7 +148,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
 
                 Vec3 vec3d = blockposition.getCenter();
 
-                world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
+                world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
                 return InteractionResult.SUCCESS;
             }
         }
diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
index b9903c29bdea8d1e3b6fce0e97be6bd9493cfdf4..2ed78cf83c0ae66a6ddba1ff307da89a24b0d0a8 100644
--- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
@@ -124,6 +124,7 @@ public class RespawnAnchorBlock extends Block {
     }
 
     private void explode(BlockState state, Level world, final BlockPos explodedPos) {
+        final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(explodedPos, state, null); // Paper - exploded block state
         world.removeBlock(explodedPos, false);
         Stream<Direction> stream = Direction.Plane.HORIZONTAL.stream(); // CraftBukkit - decompile error
 
@@ -140,7 +141,7 @@ public class RespawnAnchorBlock extends Block {
         };
         Vec3 vec3d = explodedPos.getCenter();
 
-        world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
+        world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper
     }
 
     public static boolean canSetSpawn(Level world) {
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index da4609caecc8183d02c301c7cedbca52ed39323f..716021520c228b5bbced525b751f5d4126d882eb 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -273,6 +273,12 @@ public final class CraftBlockStates {
         BlockEntity tileEntity = (blockEntityTag == null) ? null : BlockEntity.loadStatic(blockPosition, blockData, blockEntityTag);
         return CraftBlockStates.getBlockState(null, blockPosition, blockData, tileEntity);
     }
+    // Paper start
+    public static BlockState getUnplacedBlockState(net.minecraft.world.level.BlockGetter levelAccessor, BlockPos blockPos, net.minecraft.world.level.block.state.BlockState blockData) {
+        BlockEntity tileEntity = levelAccessor.getBlockEntity(blockPos);
+        return CraftBlockStates.getBlockState(null, blockPos, blockData, tileEntity);
+    }
+    // Paper end
 
     // See BlockStateFactory#createBlockState(World, BlockPosition, IBlockData, TileEntity)
     private static CraftBlockState getBlockState(World world, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) {
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index e2a346d2cd813dd64ab61403e531f9ebf221d4b4..ee382cae3feca1de40d95faf6af023c8a7df05b9 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1018,7 +1018,7 @@ public class CraftEventFactory {
             CraftEventFactory.entityDamage = null;
             EntityDamageEvent event;
             if (damager == null) {
-                event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions);
+                event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions, source.explodedBlockState); // Paper - handle block state in damage
             } else if (entity instanceof EnderDragon && /*PAIL FIXME ((EntityEnderDragon) entity).target == damager*/ false) {
                 event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions);
             } else {