From 83c3aa188bbde405f584f7b66e4fe5cab90aff35 Mon Sep 17 00:00:00 2001
From: Wesley Wolfe <weswolf@aol.com>
Date: Wed, 24 Apr 2013 03:03:38 -0500
Subject: [PATCH] Rework EntityExplodeEvent. Fixes BUKKIT-4140. Adds
 BUKKIT-4141

---
 .../minecraft/server/EntityEnderDragon.java   | 23 ++++++++++++++++++-
 .../java/net/minecraft/server/Explosion.java  |  6 ++---
 .../org/bukkit/craftbukkit/CraftWorld.java    | 17 --------------
 3 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java
index decb9057fc..e020e7f5fa 100644
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -34,6 +34,7 @@ public class EntityEnderDragon extends EntityLiving implements IComplex {
     private Entity bT;
     public int bR = 0;
     public EntityEnderCrystal bS = null;
+    private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN); // CraftBukkit - reusable source for CraftTNTPrimed.getSource()
 
     public EntityEnderDragon(World world) {
         super(world);
@@ -439,9 +440,29 @@ public class EntityEnderDragon extends EntityLiving implements IComplex {
                 // This flag literally means 'Dragon hit something hard' (Obsidian, White Stone or Bedrock) and will cause the dragon to slow down.
                 // We should consider adding an event extension for it, or perhaps returning true if the event is cancelled.
                 return flag;
+            } else if (event.getYield() == 0F) {
+                // Yield zero ==> no drops
+                for (org.bukkit.block.Block block : event.blockList()) {
+                    this.world.setAir(block.getX(), block.getY(), block.getZ());
+                }
             } else {
                 for (org.bukkit.block.Block block : event.blockList()) {
-                    craftWorld.explodeBlock(block, event.getYield());
+                    int blockId = block.getTypeId();
+
+                    if (blockId == 0) {
+                        continue;
+                    }
+
+                    int blockX = block.getX();
+                    int blockY = block.getY();
+                    int blockZ = block.getZ();
+
+                    if (Block.byId[blockId].a(explosionSource)) {
+                        Block.byId[blockId].dropNaturally(this.world, blockX, blockY, blockZ, block.getData(), event.getYield(), 0);
+                    }
+                    Block.byId[blockId].wasExploded(world, blockX, blockY, blockZ, explosionSource);
+
+                    this.world.setAir(blockX, blockY, blockZ);
                 }
             }
             // CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
index b43953a018..ef220c1fe5 100644
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
@@ -262,13 +262,11 @@ public class Explosion {
                     this.world.addParticle("smoke", d0, d1, d2, d3, d4, d5);
                 }
 
-
-                // CraftBukkit - stop explosions from putting out fire
-                if (l > 0 && l != Block.FIRE.id) {
+                if (l > 0) {
                     Block block = Block.byId[l];
 
                     if (block.a(this)) {
-                        // CraftBukkit
+                        // CraftBukkit - add yield
                         block.dropNaturally(this.world, i, j, k, this.world.getData(i, j, k), event.getYield(), 0);
                     }
 
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index b5a68af15e..6c7f5709df 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1097,23 +1097,6 @@ public class CraftWorld implements World {
         return ((WorldNBTStorage) world.getDataManager()).getDirectory();
     }
 
-    public void explodeBlock(Block block, float yield) {
-        // First of all, don't explode fire
-        if (block.getType().equals(org.bukkit.Material.AIR) || block.getType().equals(org.bukkit.Material.FIRE)) {
-            return;
-        }
-        int blockId = block.getTypeId();
-        int blockX = block.getX();
-        int blockY = block.getY();
-        int blockZ = block.getZ();
-        // following code is lifted from Explosion.a(boolean), and modified
-        net.minecraft.server.Block.byId[blockId].dropNaturally(this.world, blockX, blockY, blockZ, block.getData(), yield, 0);
-        block.setType(org.bukkit.Material.AIR);
-        // not sure what this does, seems to have something to do with the 'base' material of a block.
-        // For example, WOODEN_STAIRS does something with WOOD in this method
-        net.minecraft.server.Block.byId[blockId].wasExploded(this.world, blockX, blockY, blockZ, null);
-    }
-
     public void sendPluginMessage(Plugin source, String channel, byte[] message) {
         StandardMessenger.validatePluginMessage(server.getMessenger(), source, channel, message);