--- ../src-base/minecraft/net/minecraft/server/management/ItemInWorldManager.java
+++ ../src-work/minecraft/net/minecraft/server/management/ItemInWorldManager.java
@@ -22,6 +22,8 @@
 
 public class ItemInWorldManager
 {
+    /** Forge reach distance */
+    private double blockReachDistance = 5.0d;
     public World field_73092_a;
     public EntityPlayerMP field_73090_b;
     private WorldSettings.GameType field_73091_c;
@@ -137,6 +139,14 @@
 
     public void func_180784_a(BlockPos p_180784_1_, EnumFacing p_180784_2_)
     {
+        net.minecraftforge.event.entity.player.PlayerInteractEvent event = net.minecraftforge.event.ForgeEventFactory.onPlayerInteract(field_73090_b,
+                net.minecraftforge.event.entity.player.PlayerInteractEvent.Action.LEFT_CLICK_BLOCK, field_73092_a, p_180784_1_, p_180784_2_);
+        if (event.isCanceled())
+        {
+            field_73090_b.field_71135_a.func_147359_a(new S23PacketBlockChange(field_73092_a, p_180784_1_));
+            return;
+        }
+
         if (this.func_73083_d())
         {
             if (!this.field_73092_a.func_175719_a((EntityPlayer)null, p_180784_1_, p_180784_2_))
@@ -171,18 +181,35 @@
                 }
             }
 
-            this.field_73092_a.func_175719_a((EntityPlayer)null, p_180784_1_, p_180784_2_);
+            //
             this.field_73089_e = this.field_73100_i;
             float f = 1.0F;
 
-            if (block.func_149688_o() != Material.field_151579_a)
+            if (!block.isAir(field_73092_a, p_180784_1_))
             {
-                block.func_180649_a(this.field_73092_a, p_180784_1_, this.field_73090_b);
+                if (event.useBlock != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY)
+                {
+                    block.func_180649_a(this.field_73092_a, p_180784_1_, this.field_73090_b);
+                    this.field_73092_a.func_175719_a((EntityPlayer)null, p_180784_1_, p_180784_2_);
+                }
+                else
+                {
+                    field_73090_b.field_71135_a.func_147359_a(new S23PacketBlockChange(field_73092_a, p_180784_1_));
+                }
                 f = block.func_180647_a(this.field_73090_b, this.field_73090_b.field_70170_p, p_180784_1_);
             }
 
-            if (block.func_149688_o() != Material.field_151579_a && f >= 1.0F)
+            if (event.useItem == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY)
             {
+                if (f >= 1.0F)
+                {
+                    field_73090_b.field_71135_a.func_147359_a(new S23PacketBlockChange(field_73092_a, p_180784_1_));
+                }
+                return;
+            }
+
+            if (block.isAir(field_73092_a, p_180784_1_) && f >= 1.0F)
+            {
                 this.func_180237_b(p_180784_1_);
             }
             else
@@ -203,7 +230,7 @@
             int i = this.field_73100_i - this.field_73089_e;
             Block block = this.field_73092_a.func_180495_p(p_180785_1_).func_177230_c();
 
-            if (block.func_149688_o() != Material.field_151579_a)
+            if (block.isAir(field_73092_a, p_180785_1_))
             {
                 float f = block.func_180647_a(this.field_73090_b, this.field_73090_b.field_70170_p, p_180785_1_) * (float)(i + 1);
 
@@ -232,9 +259,13 @@
 
     private boolean func_180235_c(BlockPos p_180235_1_)
     {
+        return removeBlock(p_180235_1_, false);
+    }
+    private boolean removeBlock(BlockPos p_180235_1_, boolean canHarvest)
+    {
         IBlockState iblockstate = this.field_73092_a.func_180495_p(p_180235_1_);
         iblockstate.func_177230_c().func_176208_a(this.field_73092_a, p_180235_1_, iblockstate, this.field_73090_b);
-        boolean flag = this.field_73092_a.func_175698_g(p_180235_1_);
+        boolean flag = iblockstate.func_177230_c().removedByPlayer(field_73092_a, p_180235_1_, field_73090_b, canHarvest);
 
         if (flag)
         {
@@ -246,7 +277,8 @@
 
     public boolean func_180237_b(BlockPos p_180237_1_)
     {
-        if (this.field_73091_c.func_77145_d() && this.field_73090_b.func_70694_bm() != null && this.field_73090_b.func_70694_bm().func_77973_b() instanceof ItemSword)
+        int exp = net.minecraftforge.common.ForgeHooks.onBlockBreakEvent(field_73092_a, field_73091_c, field_73090_b, p_180237_1_);
+        if (exp == -1)
         {
             return false;
         }
@@ -255,40 +287,21 @@
             IBlockState iblockstate = this.field_73092_a.func_180495_p(p_180237_1_);
             TileEntity tileentity = this.field_73092_a.func_175625_s(p_180237_1_);
 
-            if (this.field_73091_c.func_82752_c())
-            {
-                if (this.field_73091_c == WorldSettings.GameType.SPECTATOR)
-                {
-                    return false;
-                }
+            ItemStack stack = field_73090_b.func_71045_bC();
+            if (stack != null && stack.func_77973_b().onBlockStartBreak(stack, p_180237_1_, field_73090_b)) return false;
 
-                if (!this.field_73090_b.func_175142_cm())
-                {
-                    ItemStack itemstack = this.field_73090_b.func_71045_bC();
-
-                    if (itemstack == null)
-                    {
-                        return false;
-                    }
-
-                    if (!itemstack.func_179544_c(iblockstate.func_177230_c()))
-                    {
-                        return false;
-                    }
-                }
-            }
-
             this.field_73092_a.func_180498_a(this.field_73090_b, 2001, p_180237_1_, Block.func_176210_f(iblockstate));
-            boolean flag1 = this.func_180235_c(p_180237_1_);
+            boolean flag1 = false;
 
             if (this.func_73083_d())
             {
+                flag1 = this.func_180235_c(p_180237_1_);
                 this.field_73090_b.field_71135_a.func_147359_a(new S23PacketBlockChange(this.field_73092_a, p_180237_1_));
             }
             else
             {
                 ItemStack itemstack1 = this.field_73090_b.func_71045_bC();
-                boolean flag = this.field_73090_b.func_146099_a(iblockstate.func_177230_c());
+                boolean flag = iblockstate.func_177230_c().canHarvestBlock(field_73092_a, p_180237_1_, field_73090_b);
 
                 if (itemstack1 != null)
                 {
@@ -300,12 +313,18 @@
                     }
                 }
 
+                flag1 = this.removeBlock(p_180237_1_, flag);
                 if (flag1 && flag)
                 {
                     iblockstate.func_177230_c().func_180657_a(this.field_73092_a, this.field_73090_b, p_180237_1_, iblockstate, tileentity);
                 }
             }
 
+            // Drop experiance
+            if (!this.func_73083_d() && flag1 && exp > 0)
+            {
+                iblockstate.func_177230_c().func_180637_b(field_73092_a, p_180237_1_, exp);
+            }
             return flag1;
         }
     }
@@ -343,6 +362,7 @@
                 if (itemstack1.field_77994_a == 0)
                 {
                     p_73085_1_.field_71071_by.field_70462_a[p_73085_1_.field_71071_by.field_70461_c] = null;
+                    net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(p_73085_1_, itemstack1);
                 }
 
                 if (!p_73085_1_.func_71039_bw())
@@ -387,33 +407,51 @@
         }
         else
         {
-            if (!p_180236_1_.func_70093_af() || p_180236_1_.func_70694_bm() == null)
+            net.minecraftforge.event.entity.player.PlayerInteractEvent event = net.minecraftforge.event.ForgeEventFactory.onPlayerInteract(p_180236_1_,
+                    net.minecraftforge.event.entity.player.PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, p_180236_2_, p_180236_4_, p_180236_5_);
+            if (event.isCanceled())
             {
-                IBlockState iblockstate = p_180236_2_.func_180495_p(p_180236_4_);
-
-                if (iblockstate.func_177230_c().func_180639_a(p_180236_2_, p_180236_4_, iblockstate, p_180236_1_, p_180236_5_, p_180236_6_, p_180236_7_, p_180236_8_))
-                {
-                    return true;
-                }
+                field_73090_b.field_71135_a.func_147359_a(new S23PacketBlockChange(field_73092_a, p_180236_4_));
+                return false;
             }
 
-            if (p_180236_3_ == null)
+            if (p_180236_3_ != null && p_180236_3_.func_77973_b().onItemUseFirst(p_180236_3_, p_180236_1_, p_180236_2_, p_180236_4_, p_180236_5_, p_180236_6_, p_180236_7_, p_180236_8_))
             {
-                return false;
+                if (p_180236_3_.field_77994_a <= 0) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(field_73090_b, p_180236_3_);
+                return true;
             }
-            else if (this.func_73083_d())
+
+            IBlockState iblockstate = p_180236_2_.func_180495_p(p_180236_4_);
+            boolean isAir = p_180236_2_.func_175623_d(p_180236_4_);
+            boolean useBlock = !p_180236_1_.func_70093_af() || p_180236_1_.func_70694_bm() == null;
+            if (!useBlock) useBlock = p_180236_1_.func_70694_bm().func_77973_b().doesSneakBypassUse(p_180236_2_, p_180236_4_, p_180236_1_);
+            boolean result = false;
+
+            if (useBlock)
             {
-                int j = p_180236_3_.func_77960_j();
-                int i = p_180236_3_.field_77994_a;
-                boolean flag = p_180236_3_.func_179546_a(p_180236_1_, p_180236_2_, p_180236_4_, p_180236_5_, p_180236_6_, p_180236_7_, p_180236_8_);
-                p_180236_3_.func_77964_b(j);
-                p_180236_3_.field_77994_a = i;
-                return flag;
+                if (event.useBlock != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY)
+                {
+                    result = iblockstate.func_177230_c().func_180639_a(p_180236_2_, p_180236_4_, iblockstate, p_180236_1_, p_180236_5_, p_180236_6_, p_180236_7_, p_180236_8_);
+                }
+                else
+                {
+                    field_73090_b.field_71135_a.func_147359_a(new S23PacketBlockChange(field_73092_a, p_180236_4_));
+                    result = event.useItem != net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW;
+                }
             }
-            else
+            if (p_180236_3_ != null && !result && event.useItem != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY)
             {
-                return p_180236_3_.func_179546_a(p_180236_1_, p_180236_2_, p_180236_4_, p_180236_5_, p_180236_6_, p_180236_7_, p_180236_8_);
+                int meta = p_180236_3_.func_77960_j();
+                int size = p_180236_3_.field_77994_a;
+                result = p_180236_3_.func_179546_a(p_180236_1_, p_180236_2_, p_180236_4_, p_180236_5_, p_180236_6_, p_180236_7_, p_180236_8_);
+                if (func_73083_d())
+                {
+                    p_180236_3_.func_77964_b(meta);
+                    p_180236_3_.field_77994_a = size;
+                }
+                if (p_180236_3_.field_77994_a <= 0) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(field_73090_b, p_180236_3_);
             }
+            return result;
         }
     }
 
@@ -421,4 +459,13 @@
     {
         this.field_73092_a = p_73080_1_;
     }
+
+    public double getBlockReachDistance()
+    {
+        return blockReachDistance;
+    }
+    public void setBlockReachDistance(double distance)
+    {
+        blockReachDistance = distance;
+    }
 }
