--- ../work/decompile-8eb82bde//net/minecraft/server/EntityHanging.java 2014-11-28 17:43:43.097707435 +0000 +++ src/main/java/net/minecraft/server/EntityHanging.java 2014-11-28 17:38:18.000000000 +0000 @@ -4,6 +4,13 @@ import java.util.List; import org.apache.commons.lang3.Validate; +// CraftBukkit start +import org.bukkit.entity.Hanging; +import org.bukkit.entity.Painting; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.painting.PaintingBreakEvent; +// CraftBukkit end + public abstract class EntityHanging extends Entity { private int c; @@ -77,6 +84,33 @@ if (this.c++ == 100 && !this.world.isStatic) { this.c = 0; if (!this.dead && !this.survives()) { + // CraftBukkit start - fire break events + Material material = this.world.getType(new BlockPosition(this)).getBlock().getMaterial(); + HangingBreakEvent.RemoveCause cause; + + if (!material.equals(Material.AIR)) { + // TODO: This feels insufficient to catch 100% of suffocation cases + cause = HangingBreakEvent.RemoveCause.OBSTRUCTION; + } else { + cause = HangingBreakEvent.RemoveCause.PHYSICS; + } + + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), cause); + this.world.getServer().getPluginManager().callEvent(event); + + PaintingBreakEvent paintingEvent = null; + if (this instanceof EntityPainting) { + // Fire old painting event until it can be removed + paintingEvent = new PaintingBreakEvent((Painting) this.getBukkitEntity(), PaintingBreakEvent.RemoveCause.valueOf(cause.name())); + paintingEvent.setCancelled(event.isCancelled()); + this.world.getServer().getPluginManager().callEvent(paintingEvent); + } + + if (dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { + return; + } + // CraftBukkit end + this.die(); this.b((Entity) null); } @@ -138,6 +172,32 @@ return false; } else { if (!this.dead && !this.world.isStatic) { + // CraftBukkit start - fire break events + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.DEFAULT); + PaintingBreakEvent paintingEvent = null; + if (damagesource.getEntity() != null) { + event = new org.bukkit.event.hanging.HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity()); + + if (this instanceof EntityPainting) { + // Fire old painting event until it can be removed + paintingEvent = new org.bukkit.event.painting.PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity()); + } + } else if (damagesource.isExplosion()) { + event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.EXPLOSION); + } + + this.world.getServer().getPluginManager().callEvent(event); + + if (paintingEvent != null) { + paintingEvent.setCancelled(event.isCancelled()); + this.world.getServer().getPluginManager().callEvent(paintingEvent); + } + + if (this.dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { + return true; + } + // CraftBukkit end + this.die(); this.ac(); this.b(damagesource.getEntity()); @@ -149,6 +209,18 @@ public void move(double d0, double d1, double d2) { if (!this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { + if (this.dead) return; // CraftBukkit + + // CraftBukkit start - fire break events + // TODO - Does this need its own cause? Seems to only be triggered by pistons + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.PHYSICS); + this.world.getServer().getPluginManager().callEvent(event); + + if (this.dead || event.isCancelled()) { + return; + } + // CraftBukkit end + this.die(); this.b((Entity) null); } @@ -156,7 +228,7 @@ } public void g(double d0, double d1, double d2) { - if (!this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { + if (false && !this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed this.die(); this.b((Entity) null); }