diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java index 2897ab4f8a..a653756274 100644 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -1,12 +1,18 @@ package net.minecraft.server; -import org.bukkit.Bukkit; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; - import java.util.Iterator; import java.util.List; +// CraftBukkit start +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityExplodeEvent; + +import java.util.ArrayList; +// CraftBukkit end + public class EntityEnderDragon extends EntityComplex { public double a; @@ -455,6 +461,10 @@ public class EntityEnderDragon extends EntityComplex { boolean flag = false; boolean flag1 = false; + // CraftBukkit start - create a list to hold all the destroyed blocks + List destroyedBlocks = new ArrayList(); + CraftWorld craftWorld = this.world.getWorld(); + // CraftBukkit end for (int k1 = i; k1 <= l; ++k1) { for (int l1 = j; l1 <= i1; ++l1) { for (int i2 = k; i2 <= j1; ++i2) { @@ -463,7 +473,10 @@ public class EntityEnderDragon extends EntityComplex { if (j2 != 0) { if (j2 != Block.OBSIDIAN.id && j2 != Block.WHITESTONE.id && j2 != Block.BEDROCK.id) { flag1 = true; - this.world.setTypeId(k1, l1, i2, 0); + // CraftBukkit start - add blocks to list rather than destroying them + //this.world.setTypeId(k1, l1, i2, 0); + destroyedBlocks.add(craftWorld.getBlockAt(k1, l1, i2)); + // CraftBukkit end } else { flag = true; } @@ -473,6 +486,19 @@ public class EntityEnderDragon extends EntityComplex { } if (flag1) { + // CraftBukkit start - set off an EntityExplodeEvent for the dragon exploding all these blocks + org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity(); + EntityExplodeEvent event = new EntityExplodeEvent(bukkitEntity, bukkitEntity.getLocation(), destroyedBlocks, 0F); + if (event.isCancelled()) { + // 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 { + for (org.bukkit.block.Block block : event.blockList()) { + craftWorld.explodeBlock(block, event.getYield()); + } + } + // CraftBukkit end double d0 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) this.random.nextFloat(); double d1 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) this.random.nextFloat(); double d2 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) this.random.nextFloat(); diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java index 739f1f4951..7ceb116f5c 100644 --- a/src/main/java/net/minecraft/server/Explosion.java +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -185,7 +185,7 @@ public class Explosion { } } - EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList); + EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, 0.3F); this.world.getServer().getPluginManager().callEvent(event); arraylist.clear(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 0740b3022f..334930f62e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -895,4 +895,21 @@ public class CraftWorld implements World { public File getWorldFolder() { return ((WorldNBTStorage)world.getDataManager()).getDirectory(); } + + public void explodeBlock(Block block, float yield) { + // First of all, don't explode fire + if (block.getType().equals(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].a_(this.world, blockX, blockY, blockZ); + } }