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


diff --git a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
index 641c71ab66bd2499b35cf3c1d533fd105d096e10..7dcbb75170296c1dd1d784a032bf369602328b29 100644
--- a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
+++ b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
@@ -10,18 +10,31 @@ import org.jetbrains.annotations.NotNull;
  * Called when a block explodes interacting with blocks. The
  * event isn't called if the {@link org.bukkit.GameRule#MOB_GRIEFING}
  * is disabled as no block interaction will occur.
+ * <p>
+ * The {@link Block} returned by this event is not necessarily
+ * the block that caused the explosion, just the block at the location where
+ * the explosion originated. See {@link #getExplodedBlockState()}
  */
 public class BlockExplodeEvent extends BlockEvent implements Cancellable {
     private static final HandlerList handlers = new HandlerList();
     private boolean cancel;
     private final List<Block> blocks;
     private float yield;
+    private final org.bukkit.block.BlockState explodedBlockState; // Paper
 
+    @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper
     public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield) {
+        // Paper start
+        this(what, blocks, yield, null);
+    }
+    @org.jetbrains.annotations.ApiStatus.Internal
+    public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield, @org.jetbrains.annotations.Nullable org.bukkit.block.BlockState explodedBlockState) {
+        // Paper end
         super(what);
         this.blocks = blocks;
         this.yield = yield;
         this.cancel = false;
+        this.explodedBlockState = explodedBlockState; // Paper
     }
 
     @Override
@@ -34,6 +47,22 @@ public class BlockExplodeEvent extends BlockEvent implements Cancellable {
         this.cancel = cancel;
     }
 
+    // Paper start
+    /**
+     * Get a capture of the block that directly caused
+     * the explosion, like a bed or respawn anchor. This
+     * block state is not placed so {@link org.bukkit.block.BlockState#isPlaced}
+     * will be false.
+     * <p>
+     * Can be null if no block directly caused the explosion.
+     *
+     * @return the exploded block state or null if not applicable
+     */
+    public @org.jetbrains.annotations.Nullable org.bukkit.block.BlockState getExplodedBlockState() {
+        return this.explodedBlockState;
+    }
+    // Paper end
+
     /**
      * Returns the list of blocks that would have been removed or were removed
      * from the explosion event.
diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
index 467a0d6cabc5e860628be3b1e62de773efde5d2e..1fb15e2ade8ff3c4d662eca87b078b4577f786e1 100644
--- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
+++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
@@ -11,28 +11,35 @@ import org.jetbrains.annotations.Nullable;
 
 /**
  * Called when an entity is damaged by a block
+ * <p>
+ * For explosions, the Block returned by {@link #getDamager()} has
+ * already been cleared. See {@link #getDamagerBlockState()} for a snapshot
+ * of the block if it has already been changed.
  */
 public class EntityDamageByBlockEvent extends EntityDamageEvent {
     private final Block damager;
+    private final org.bukkit.block.BlockState damagerBlockState; // Paper
 
     @Deprecated(forRemoval = true)
     public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage) {
-        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), damage);
+        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), damage, null); // Paper
     }
 
-    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, final double damage) {
+    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, final double damage, final @Nullable org.bukkit.block.BlockState damagerBlockState) { // Paper
         super(damagee, cause, damageSource, damage);
         this.damager = damager;
+        this.damagerBlockState = damagerBlockState; // Paper
     }
 
     @Deprecated(forRemoval = true)
     public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
-        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions);
+        this(damager, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions, null); // Paper
     }
 
-    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
+    public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions, final @Nullable org.bukkit.block.BlockState damagerBlockState) { // Paper
         super(damagee, cause, damageSource, modifiers, modifierFunctions);
         this.damager = damager;
+        this.damagerBlockState = damagerBlockState; // Paper
     }
 
     /**
@@ -44,4 +51,20 @@ public class EntityDamageByBlockEvent extends EntityDamageEvent {
     public Block getDamager() {
         return damager;
     }
+
+    // Paper start
+    /**
+    * Get a capture of the block that directly caused
+    * the damage, like a bed or respawn anchor. This
+    * block state is not placed so {@link org.bukkit.block.BlockState#isPlaced}
+    * will be false.
+    * <p>
+    * Can be null if the block wasn't changed before the event
+    *
+    * @return the damager block state or null if not applicable
+    */
+    public @Nullable org.bukkit.block.BlockState getDamagerBlockState() {
+        return this.damagerBlockState;
+    }
+    // Paper end
 }