--- a/net/minecraft/client/multiplayer/PlayerController.java
+++ b/net/minecraft/client/multiplayer/PlayerController.java
@@ -94,6 +94,7 @@
    }
 
    public boolean func_187103_a(BlockPos p_187103_1_) {
+      if (field_78776_a.field_71439_g.func_184614_ca().onBlockStartBreak(p_187103_1_, field_78776_a.field_71439_g)) return false;
       if (this.field_78776_a.field_71439_g.func_223729_a(this.field_78776_a.field_71441_e, p_187103_1_, this.field_78779_k)) {
          return false;
       } else {
@@ -105,12 +106,11 @@
             Block block = blockstate.func_177230_c();
             if ((block instanceof CommandBlockBlock || block instanceof StructureBlock || block instanceof JigsawBlock) && !this.field_78776_a.field_71439_g.func_195070_dx()) {
                return false;
-            } else if (blockstate.func_196958_f()) {
+            } else if (blockstate.isAir(world, p_187103_1_)) {
                return false;
             } else {
-               block.func_176208_a(world, p_187103_1_, blockstate, this.field_78776_a.field_71439_g);
                FluidState fluidstate = world.func_204610_c(p_187103_1_);
-               boolean flag = world.func_180501_a(p_187103_1_, fluidstate.func_206883_i(), 11);
+               boolean flag = blockstate.removedByPlayer(world, p_187103_1_, field_78776_a.field_71439_g, false, fluidstate);
                if (flag) {
                   block.func_176206_d(world, p_187103_1_, blockstate);
                }
@@ -131,21 +131,25 @@
             BlockState blockstate = this.field_78776_a.field_71441_e.func_180495_p(p_180511_1_);
             this.field_78776_a.func_193032_ao().func_193294_a(this.field_78776_a.field_71441_e, p_180511_1_, blockstate, 1.0F);
             this.func_225324_a(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, p_180511_1_, p_180511_2_);
+            if (!net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.field_78776_a.field_71439_g, p_180511_1_, p_180511_2_).isCanceled())
             this.func_187103_a(p_180511_1_);
             this.field_78781_i = 5;
          } else if (!this.field_78778_j || !this.func_178893_a(p_180511_1_)) {
             if (this.field_78778_j) {
                this.func_225324_a(CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, this.field_178895_c, p_180511_2_);
             }
+            net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock event = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.field_78776_a.field_71439_g, p_180511_1_, p_180511_2_);
 
             BlockState blockstate1 = this.field_78776_a.field_71441_e.func_180495_p(p_180511_1_);
             this.field_78776_a.func_193032_ao().func_193294_a(this.field_78776_a.field_71441_e, p_180511_1_, blockstate1, 0.0F);
             this.func_225324_a(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, p_180511_1_, p_180511_2_);
-            boolean flag = !blockstate1.func_196958_f();
+            boolean flag = !blockstate1.isAir(this.field_78776_a.field_71441_e, p_180511_1_);
             if (flag && this.field_78770_f == 0.0F) {
+               if (event.getUseBlock() != net.minecraftforge.eventbus.api.Event.Result.DENY)
                blockstate1.func_196942_a(this.field_78776_a.field_71441_e, p_180511_1_, this.field_78776_a.field_71439_g);
             }
 
+            if (event.getUseItem() == net.minecraftforge.eventbus.api.Event.Result.DENY) return true;
             if (flag && blockstate1.func_185903_a(this.field_78776_a.field_71439_g, this.field_78776_a.field_71439_g.field_70170_p, p_180511_1_) >= 1.0F) {
                this.func_187103_a(p_180511_1_);
             } else {
@@ -185,22 +189,24 @@
          BlockState blockstate1 = this.field_78776_a.field_71441_e.func_180495_p(p_180512_1_);
          this.field_78776_a.func_193032_ao().func_193294_a(this.field_78776_a.field_71441_e, p_180512_1_, blockstate1, 1.0F);
          this.func_225324_a(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, p_180512_1_, p_180512_2_);
+         if (!net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.field_78776_a.field_71439_g, p_180512_1_, p_180512_2_).isCanceled())
          this.func_187103_a(p_180512_1_);
          return true;
       } else if (this.func_178893_a(p_180512_1_)) {
          BlockState blockstate = this.field_78776_a.field_71441_e.func_180495_p(p_180512_1_);
-         if (blockstate.func_196958_f()) {
+         if (blockstate.isAir(this.field_78776_a.field_71441_e, p_180512_1_)) {
             this.field_78778_j = false;
             return false;
          } else {
             this.field_78770_f += blockstate.func_185903_a(this.field_78776_a.field_71439_g, this.field_78776_a.field_71439_g.field_70170_p, p_180512_1_);
             if (this.field_78780_h % 4.0F == 0.0F) {
-               SoundType soundtype = blockstate.func_215695_r();
+               SoundType soundtype = blockstate.getSoundType(this.field_78776_a.field_71441_e, p_180512_1_, this.field_78776_a.field_71439_g);
                this.field_78776_a.func_147118_V().func_147682_a(new SimpleSound(soundtype.func_185846_f(), SoundCategory.BLOCKS, (soundtype.func_185843_a() + 1.0F) / 8.0F, soundtype.func_185847_b() * 0.5F, p_180512_1_));
             }
 
             ++this.field_78780_h;
             this.field_78776_a.func_193032_ao().func_193294_a(this.field_78776_a.field_71441_e, p_180512_1_, blockstate, MathHelper.func_76131_a(this.field_78770_f, 0.0F, 1.0F));
+            if (net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.field_78776_a.field_71439_g, p_180512_1_, p_180512_2_).getUseItem() == net.minecraftforge.eventbus.api.Event.Result.DENY) return true;
             if (this.field_78770_f >= 1.0F) {
                this.field_78778_j = false;
                this.func_225324_a(CPlayerDiggingPacket.Action.STOP_DESTROY_BLOCK, p_180512_1_, p_180512_2_);
@@ -219,7 +225,8 @@
    }
 
    public float func_78757_d() {
-      return this.field_78779_k.func_77145_d() ? 5.0F : 4.5F;
+      float attrib = (float)field_78776_a.field_71439_g.func_110148_a(net.minecraftforge.common.ForgeMod.REACH_DISTANCE.get()).func_111126_e();
+      return this.field_78779_k.func_77145_d() ? attrib : attrib - 0.5F;
    }
 
    public void func_78765_e() {
@@ -236,7 +243,7 @@
       ItemStack itemstack = this.field_78776_a.field_71439_g.func_184614_ca();
       boolean flag = this.field_85183_f.func_190926_b() && itemstack.func_190926_b();
       if (!this.field_85183_f.func_190926_b() && !itemstack.func_190926_b()) {
-         flag = itemstack.func_77973_b() == this.field_85183_f.func_77973_b() && ItemStack.func_77970_a(itemstack, this.field_85183_f) && (itemstack.func_77984_f() || itemstack.func_77952_i() == this.field_85183_f.func_77952_i());
+         flag = !this.field_85183_f.shouldCauseBlockBreakReset(itemstack);
       }
 
       return p_178893_1_.equals(this.field_178895_c) && flag;
@@ -258,13 +265,27 @@
          return ActionResultType.FAIL;
       } else {
          ItemStack itemstack = p_217292_1_.func_184586_b(p_217292_3_);
+         net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock event = net.minecraftforge.common.ForgeHooks
+                 .onRightClickBlock(p_217292_1_, p_217292_3_, blockpos, p_217292_4_.func_216354_b());
+         if (event.isCanceled()) {
+            this.field_78774_b.func_147297_a(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
+            return event.getCancellationResult();
+         }
          if (this.field_78779_k == GameType.SPECTATOR) {
             this.field_78774_b.func_147297_a(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
             return ActionResultType.SUCCESS;
          } else {
-            boolean flag = !p_217292_1_.func_184614_ca().func_190926_b() || !p_217292_1_.func_184592_cb().func_190926_b();
+            ItemUseContext itemusecontext = new ItemUseContext(p_217292_1_, p_217292_3_, p_217292_4_);
+            if (event.getUseItem() != net.minecraftforge.eventbus.api.Event.Result.DENY) {
+               ActionResultType result = itemstack.onItemUseFirst(itemusecontext);
+               if (result != ActionResultType.PASS) {
+                  this.field_78774_b.func_147297_a(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
+                  return result;
+               }
+            }
+            boolean flag = !p_217292_1_.func_184614_ca().doesSneakBypassUse(p_217292_2_,blockpos,p_217292_1_) || !p_217292_1_.func_184592_cb().doesSneakBypassUse(p_217292_2_,blockpos,p_217292_1_);
             boolean flag1 = p_217292_1_.func_226563_dT_() && flag;
-            if (!flag1) {
+            if (event.getUseBlock() != net.minecraftforge.eventbus.api.Event.Result.DENY && !flag1) {
                ActionResultType actionresulttype = p_217292_2_.func_180495_p(blockpos).func_227031_a_(p_217292_2_, p_217292_1_, p_217292_3_, p_217292_4_);
                if (actionresulttype.func_226246_a_()) {
                   this.field_78774_b.func_147297_a(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
@@ -273,8 +294,8 @@
             }
 
             this.field_78774_b.func_147297_a(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
+            if (event.getUseItem() == net.minecraftforge.eventbus.api.Event.Result.DENY) return ActionResultType.PASS;
             if (!itemstack.func_190926_b() && !p_217292_1_.func_184811_cZ().func_185141_a(itemstack.func_77973_b())) {
-               ItemUseContext itemusecontext = new ItemUseContext(p_217292_1_, p_217292_3_, p_217292_4_);
                ActionResultType actionresulttype1;
                if (this.field_78779_k.func_77145_d()) {
                   int i = itemstack.func_190916_E();
@@ -302,11 +323,14 @@
          if (p_187101_1_.func_184811_cZ().func_185141_a(itemstack.func_77973_b())) {
             return ActionResultType.PASS;
          } else {
+            ActionResultType cancelResult = net.minecraftforge.common.ForgeHooks.onItemRightClick(p_187101_1_, p_187101_3_);
+            if (cancelResult != null) return cancelResult;
             int i = itemstack.func_190916_E();
             ActionResult<ItemStack> actionresult = itemstack.func_77957_a(p_187101_2_, p_187101_1_, p_187101_3_);
             ItemStack itemstack1 = actionresult.func_188398_b();
             if (itemstack1 != itemstack) {
                p_187101_1_.func_184611_a(p_187101_3_, itemstack1);
+               if (itemstack1.func_190926_b()) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(p_187101_1_, itemstack, p_187101_3_);
             }
 
             return actionresult.func_188397_a();
@@ -335,6 +359,9 @@
    public ActionResultType func_187097_a(PlayerEntity p_187097_1_, Entity p_187097_2_, Hand p_187097_3_) {
       this.func_78750_j();
       this.field_78774_b.func_147297_a(new CUseEntityPacket(p_187097_2_, p_187097_3_, p_187097_1_.func_225608_bj_()));
+      if (this.field_78779_k == GameType.SPECTATOR) return ActionResultType.PASS; // don't fire for spectators to match non-specific EntityInteract
+      ActionResultType cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntity(p_187097_1_, p_187097_2_, p_187097_3_);
+      if(cancelResult != null) return cancelResult;
       return this.field_78779_k == GameType.SPECTATOR ? ActionResultType.PASS : p_187097_1_.func_190775_a(p_187097_2_, p_187097_3_);
    }
 
@@ -342,6 +369,9 @@
       this.func_78750_j();
       Vector3d vector3d = p_187102_3_.func_216347_e().func_178786_a(p_187102_2_.func_226277_ct_(), p_187102_2_.func_226278_cu_(), p_187102_2_.func_226281_cx_());
       this.field_78774_b.func_147297_a(new CUseEntityPacket(p_187102_2_, p_187102_4_, vector3d, p_187102_1_.func_225608_bj_()));
+      if (this.field_78779_k == GameType.SPECTATOR) return ActionResultType.PASS; // don't fire for spectators to match non-specific EntityInteract
+      ActionResultType cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntityAt(p_187102_1_, p_187102_2_, p_187102_3_, p_187102_4_);
+      if(cancelResult != null) return cancelResult;
       return this.field_78779_k == GameType.SPECTATOR ? ActionResultType.PASS : p_187102_2_.func_184199_a(p_187102_1_, vector3d, p_187102_4_);
    }
 
