--- a/net/minecraft/entity/LivingEntity.java
+++ b/net/minecraft/entity/LivingEntity.java
@@ -116,7 +116,9 @@
 public abstract class LivingEntity extends Entity {
    private static final UUID field_110156_b = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D");
    private static final UUID field_233625_c_ = UUID.fromString("87f46a96-686f-4796-b035-22e16ee9e038");
+   private static final UUID SLOW_FALLING_ID = UUID.fromString("A5B6CF2A-2F7C-31EF-9022-7C3E7D5E6ABA");
    private static final AttributeModifier field_110157_c = new AttributeModifier(field_110156_b, "Sprinting speed boost", (double)0.3F, AttributeModifier.Operation.MULTIPLY_TOTAL);
+   private static final AttributeModifier SLOW_FALLING = new AttributeModifier(SLOW_FALLING_ID, "Slow falling acceleration reduction", -0.07, AttributeModifier.Operation.ADDITION); // Add -0.07 to 0.08 so we get the vanilla default of 0.01
    protected static final DataParameter<Byte> field_184621_as = EntityDataManager.func_187226_a(LivingEntity.class, DataSerializers.field_187191_a);
    private static final DataParameter<Float> field_184632_c = EntityDataManager.func_187226_a(LivingEntity.class, DataSerializers.field_187193_c);
    private static final DataParameter<Integer> field_184633_f = EntityDataManager.func_187226_a(LivingEntity.class, DataSerializers.field_187192_b);
@@ -244,7 +246,7 @@
    }
 
    public static AttributeModifierMap.MutableAttribute func_233639_cI_() {
-      return AttributeModifierMap.func_233803_a_().func_233814_a_(Attributes.field_233818_a_).func_233814_a_(Attributes.field_233820_c_).func_233814_a_(Attributes.field_233821_d_).func_233814_a_(Attributes.field_233826_i_).func_233814_a_(Attributes.field_233827_j_);
+      return AttributeModifierMap.func_233803_a_().func_233814_a_(Attributes.field_233818_a_).func_233814_a_(Attributes.field_233820_c_).func_233814_a_(Attributes.field_233821_d_).func_233814_a_(Attributes.field_233826_i_).func_233814_a_(Attributes.field_233827_j_).func_233814_a_(net.minecraftforge.common.ForgeMod.SWIM_SPEED.get()).func_233814_a_(net.minecraftforge.common.ForgeMod.NAMETAG_DISTANCE.get()).func_233814_a_(net.minecraftforge.common.ForgeMod.ENTITY_GRAVITY.get());
    }
 
    protected void func_184231_a(double p_184231_1_, boolean p_184231_3_, BlockState p_184231_4_, BlockPos p_184231_5_) {
@@ -259,9 +261,10 @@
 
       if (!this.field_70170_p.field_72995_K && this.field_70143_R > 3.0F && p_184231_3_) {
          float f = (float)MathHelper.func_76123_f(this.field_70143_R - 3.0F);
-         if (!p_184231_4_.func_196958_f()) {
+         if (!p_184231_4_.isAir(field_70170_p, p_184231_5_)) {
             double d0 = Math.min((double)(0.2F + f / 15.0F), 2.5D);
             int i = (int)(150.0D * d0);
+            if (!p_184231_4_.addLandingEffects((ServerWorld)this.field_70170_p, p_184231_5_, p_184231_4_, this, i))
             ((ServerWorld)this.field_70170_p).func_195598_a(new BlockParticleData(ParticleTypes.field_197611_d, p_184231_4_), this.func_226277_ct_(), this.func_226278_cu_(), this.func_226281_cx_(), i, 0.0D, 0.0D, 0.0D, (double)0.15F);
          }
       }
@@ -329,7 +332,7 @@
                }
             }
 
-            if (!this.field_70170_p.field_72995_K && this.func_184218_aH() && this.func_184187_bx() != null && !this.func_184187_bx().func_205710_ba()) {
+            if (!this.field_70170_p.field_72995_K && this.func_184218_aH() && this.func_184187_bx() != null && !this.func_184187_bx().canBeRiddenInWater(this)) {
                this.func_184210_p();
             }
          } else if (this.func_70086_ai() < this.func_205010_bg()) {
@@ -474,7 +477,7 @@
    protected void func_70609_aI() {
       ++this.field_70725_aQ;
       if (this.field_70725_aQ == 20) {
-         this.func_70106_y();
+         this.remove(this instanceof net.minecraft.entity.player.ServerPlayerEntity); //Forge keep data until we revive player
 
          for(int i = 0; i < 20; ++i) {
             double d0 = this.field_70146_Z.nextGaussian() * 0.02D;
@@ -667,7 +670,7 @@
             if (!effectinstance.func_76455_a(this, () -> {
                this.func_70695_b(effectinstance, true);
             })) {
-               if (!this.field_70170_p.field_72995_K) {
+               if (!this.field_70170_p.field_72995_K && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionExpiryEvent(this, effectinstance))) {
                   iterator.remove();
                   this.func_70688_c(effectinstance);
                }
@@ -716,8 +719,10 @@
          this.func_82142_c(false);
       } else {
          Collection<EffectInstance> collection = this.field_70713_bf.values();
-         this.field_70180_af.func_187227_b(field_184634_g, func_184593_a(collection));
-         this.field_70180_af.func_187227_b(field_184633_f, PotionUtils.func_185181_a(collection));
+         net.minecraftforge.event.entity.living.PotionColorCalculationEvent event = new net.minecraftforge.event.entity.living.PotionColorCalculationEvent(this, PotionUtils.func_185181_a(collection), func_184593_a(collection), collection);
+         net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
+         this.field_70180_af.func_187227_b(field_184634_g, event.areParticlesHidden());
+         this.field_70180_af.func_187227_b(field_184633_f, event.getColor());
          this.func_82142_c(this.func_70644_a(Effects.field_76441_p));
       }
 
@@ -781,7 +786,9 @@
 
          boolean flag;
          for(flag = false; iterator.hasNext(); flag = true) {
-            this.func_70688_c(iterator.next());
+            EffectInstance effect = iterator.next();
+            if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect))) continue;
+            this.func_70688_c(effect);
             iterator.remove();
          }
 
@@ -811,6 +818,7 @@
          return false;
       } else {
          EffectInstance effectinstance = this.field_70713_bf.get(p_195064_1_.func_188419_a());
+         net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionAddedEvent(this, effectinstance, p_195064_1_));
          if (effectinstance == null) {
             this.field_70713_bf.put(p_195064_1_.func_188419_a(), p_195064_1_);
             this.func_70670_a(p_195064_1_);
@@ -825,6 +833,9 @@
    }
 
    public boolean func_70687_e(EffectInstance p_70687_1_) {
+      net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent event = new net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent(this, p_70687_1_);
+      net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
+      if (event.getResult() != net.minecraftforge.eventbus.api.Event.Result.DEFAULT) return event.getResult() == net.minecraftforge.eventbus.api.Event.Result.ALLOW;
       if (this.func_70668_bt() == CreatureAttribute.field_223223_b_) {
          Effect effect = p_70687_1_.func_188419_a();
          if (effect == Effects.field_76428_l || effect == Effects.field_76436_u) {
@@ -858,6 +869,7 @@
    }
 
    public boolean func_195063_d(Effect p_195063_1_) {
+      if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, p_195063_1_))) return false;
       EffectInstance effectinstance = this.func_184596_c(p_195063_1_);
       if (effectinstance != null) {
          this.func_70688_c(effectinstance);
@@ -894,6 +906,8 @@
    }
 
    public void func_70691_i(float p_70691_1_) {
+      p_70691_1_ = net.minecraftforge.event.ForgeEventFactory.onLivingHeal(this, p_70691_1_);
+      if (p_70691_1_ <= 0) return;
       float f = this.func_110143_aJ();
       if (f > 0.0F) {
          this.func_70606_j(f + p_70691_1_);
@@ -914,6 +928,7 @@
    }
 
    public boolean func_70097_a(DamageSource p_70097_1_, float p_70097_2_) {
+      if (!net.minecraftforge.common.ForgeHooks.onLivingAttack(this, p_70097_1_, p_70097_2_)) return false;
       if (this.func_180431_b(p_70097_1_)) {
          return false;
       } else if (this.field_70170_p.field_72995_K) {
@@ -980,8 +995,8 @@
             if (entity1 instanceof PlayerEntity) {
                this.field_70718_bc = 100;
                this.field_70717_bb = (PlayerEntity)entity1;
-            } else if (entity1 instanceof WolfEntity) {
-               WolfEntity wolfentity = (WolfEntity)entity1;
+            } else if (entity1 instanceof net.minecraft.entity.passive.TameableEntity) {
+               net.minecraft.entity.passive.TameableEntity wolfentity = (net.minecraft.entity.passive.TameableEntity)entity1;
                if (wolfentity.func_70909_n()) {
                   this.field_70718_bc = 100;
                   LivingEntity livingentity = wolfentity.func_70902_q();
@@ -1163,6 +1178,7 @@
    }
 
    public void func_70645_a(DamageSource p_70645_1_) {
+      if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, p_70645_1_)) return;
       if (!this.field_70128_L && !this.field_70729_aU) {
          Entity entity = p_70645_1_.func_76346_g();
          LivingEntity livingentity = this.func_94060_bK();
@@ -1194,10 +1210,10 @@
       if (!this.field_70170_p.field_72995_K) {
          boolean flag = false;
          if (p_226298_1_ instanceof WitherEntity) {
-            if (this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223599_b)) {
+            if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.field_70170_p, this)) {
                BlockPos blockpos = this.func_233580_cy_();
                BlockState blockstate = Blocks.field_222388_bz.func_176223_P();
-               if (this.field_70170_p.func_180495_p(blockpos).func_196958_f() && blockstate.func_196955_c(this.field_70170_p, blockpos)) {
+               if (this.field_70170_p.func_175623_d(blockpos) && blockstate.func_196955_c(this.field_70170_p, blockpos)) {
                   this.field_70170_p.func_180501_a(blockpos, blockstate, 3);
                   flag = true;
                }
@@ -1214,13 +1230,10 @@
 
    protected void func_213345_d(DamageSource p_213345_1_) {
       Entity entity = p_213345_1_.func_76346_g();
-      int i;
-      if (entity instanceof PlayerEntity) {
-         i = EnchantmentHelper.func_185283_h((LivingEntity)entity);
-      } else {
-         i = 0;
-      }
 
+      int i = net.minecraftforge.common.ForgeHooks.getLootingLevel(this, entity, p_213345_1_);
+      this.captureDrops(new java.util.ArrayList<>());
+
       boolean flag = this.field_70718_bc > 0;
       if (this.func_230282_cS_() && this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223602_e)) {
          this.func_213354_a(p_213345_1_, flag);
@@ -1229,6 +1242,10 @@
 
       this.func_213337_cE();
       this.func_226294_cV_();
+
+      Collection<ItemEntity> drops = captureDrops(null);
+      if (!net.minecraftforge.common.ForgeHooks.onLivingDrops(this, p_213345_1_, drops, i, field_70718_bc > 0))
+         drops.forEach(e -> field_70170_p.func_217376_c(e));
    }
 
    protected void func_213337_cE() {
@@ -1238,6 +1255,7 @@
       if (!this.field_70170_p.field_72995_K && (this.func_70684_aJ() || this.field_70718_bc > 0 && this.func_146066_aG() && this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223602_e))) {
          int i = this.func_70693_a(this.field_70717_bb);
 
+         i = net.minecraftforge.event.ForgeEventFactory.getExperienceDrop(this, this.field_70717_bb, i);
          while(i > 0) {
             int j = ExperienceOrbEntity.func_70527_a(i);
             i -= j;
@@ -1258,7 +1276,8 @@
       ResourceLocation resourcelocation = this.func_213346_cF();
       LootTable loottable = this.field_70170_p.func_73046_m().func_200249_aQ().func_186521_a(resourcelocation);
       LootContext.Builder lootcontext$builder = this.func_213363_a(p_213354_2_, p_213354_1_);
-      loottable.func_216120_b(lootcontext$builder.func_216022_a(LootParameterSets.field_216263_d), this::func_199701_a_);
+      LootContext ctx = lootcontext$builder.func_216022_a(LootParameterSets.field_216263_d);
+      loottable.func_216113_a(ctx).forEach(this::func_199701_a_);
    }
 
    protected LootContext.Builder func_213363_a(boolean p_213363_1_, DamageSource p_213363_2_) {
@@ -1271,6 +1290,12 @@
    }
 
    public void func_233627_a_(float p_233627_1_, double p_233627_2_, double p_233627_4_) {
+       //TODO, Vanilla removed the attacker entity from this method, 1.15-mcp: knockBack
+      net.minecraftforge.event.entity.living.LivingKnockBackEvent event = net.minecraftforge.common.ForgeHooks.onLivingKnockBack(this, null, p_233627_1_, p_233627_2_, p_233627_4_);
+      if(event.isCanceled()) return;
+      p_233627_1_ = event.getStrength();
+      p_233627_2_ = event.getRatioX();
+      p_233627_4_ = event.getRatioZ();
       p_233627_1_ = (float)((double)p_233627_1_ * (1.0D - this.func_233637_b_(Attributes.field_233820_c_)));
       if (!(p_233627_1_ <= 0.0F)) {
          this.field_70160_al = true;
@@ -1320,16 +1345,7 @@
       } else {
          BlockPos blockpos = this.func_233580_cy_();
          BlockState blockstate = this.func_213339_cH();
-         Block block = blockstate.func_177230_c();
-         if (block.func_203417_a(BlockTags.field_232878_as_)) {
-            this.field_233624_bE_ = Optional.of(blockpos);
-            return true;
-         } else if (block instanceof TrapDoorBlock && this.func_184604_a(blockpos, blockstate)) {
-            this.field_233624_bE_ = Optional.of(blockpos);
-            return true;
-         } else {
-            return false;
-         }
+         return net.minecraftforge.common.ForgeHooks.isLivingOnLadder(blockstate, field_70170_p, blockpos, this);
       }
    }
 
@@ -1353,6 +1369,11 @@
    }
 
    public boolean func_225503_b_(float p_225503_1_, float p_225503_2_) {
+      float[] ret = net.minecraftforge.common.ForgeHooks.onLivingFall(this, p_225503_1_, p_225503_2_);
+      if (ret == null) return false;
+      p_225503_1_ = ret[0];
+      p_225503_2_ = ret[1];
+
       boolean flag = super.func_225503_b_(p_225503_1_, p_225503_2_);
       int i = this.func_225508_e_(p_225503_1_, p_225503_2_);
       if (i > 0) {
@@ -1376,9 +1397,10 @@
          int i = MathHelper.func_76128_c(this.func_226277_ct_());
          int j = MathHelper.func_76128_c(this.func_226278_cu_() - (double)0.2F);
          int k = MathHelper.func_76128_c(this.func_226281_cx_());
-         BlockState blockstate = this.field_70170_p.func_180495_p(new BlockPos(i, j, k));
-         if (!blockstate.func_196958_f()) {
-            SoundType soundtype = blockstate.func_215695_r();
+         BlockPos pos = new BlockPos(i, j, k);
+         BlockState blockstate = this.field_70170_p.func_180495_p(pos);
+         if (!blockstate.isAir(this.field_70170_p, pos)) {
+            SoundType soundtype = blockstate.getSoundType(field_70170_p, pos, this);
             this.func_184185_a(soundtype.func_185842_g(), soundtype.func_185843_a() * 0.5F, soundtype.func_185847_b() * 0.75F);
          }
 
@@ -1446,6 +1468,8 @@
 
    protected void func_70665_d(DamageSource p_70665_1_, float p_70665_2_) {
       if (!this.func_180431_b(p_70665_1_)) {
+         p_70665_2_ = net.minecraftforge.common.ForgeHooks.onLivingHurt(this, p_70665_1_, p_70665_2_);
+         if (p_70665_2_ <= 0) return;
          p_70665_2_ = this.func_70655_b(p_70665_1_, p_70665_2_);
          p_70665_2_ = this.func_70672_c(p_70665_1_, p_70665_2_);
          float f2 = Math.max(p_70665_2_ - this.func_110139_bj(), 0.0F);
@@ -1455,10 +1479,11 @@
             ((ServerPlayerEntity)p_70665_1_.func_76346_g()).func_195067_a(Stats.field_212735_F, Math.round(f * 10.0F));
          }
 
+         f2 = net.minecraftforge.common.ForgeHooks.onLivingDamage(this, p_70665_1_, f2);
          if (f2 != 0.0F) {
             float f1 = this.func_110143_aJ();
-            this.func_70606_j(f1 - f2);
             this.func_110142_aN().func_94547_a(p_70665_1_, f1, f2);
+            this.func_70606_j(f1 - f2); // Forge: moved to fix MC-121048
             this.func_110149_m(this.func_110139_bj() - f2);
          }
       }
@@ -1512,6 +1537,8 @@
    }
 
    public void func_226292_a_(Hand p_226292_1_, boolean p_226292_2_) {
+      ItemStack stack = this.func_184586_b(p_226292_1_);
+      if (!stack.func_190926_b() && stack.onEntitySwing(this)) return;
       if (!this.field_82175_bq || this.field_110158_av >= this.func_82166_i() / 2 || this.field_110158_av < 0) {
          this.field_110158_av = -1;
          this.field_82175_bq = true;
@@ -1846,15 +1873,16 @@
       }
 
       this.field_70160_al = true;
+      net.minecraftforge.common.ForgeHooks.onLivingJump(this);
    }
 
    @OnlyIn(Dist.CLIENT)
    protected void func_203010_cG() {
-      this.func_213317_d(this.func_213322_ci().func_72441_c(0.0D, (double)-0.04F, 0.0D));
+      this.func_213317_d(this.func_213322_ci().func_72441_c(0.0D, (double)-0.04F * this.func_110148_a(net.minecraftforge.common.ForgeMod.SWIM_SPEED.get()).func_111126_e(), 0.0D));
    }
 
    protected void func_180466_bG(ITag<Fluid> p_180466_1_) {
-      this.func_213317_d(this.func_213322_ci().func_72441_c(0.0D, (double)0.04F, 0.0D));
+      this.func_213317_d(this.func_213322_ci().func_72441_c(0.0D, (double)0.04F * this.func_110148_a(net.minecraftforge.common.ForgeMod.SWIM_SPEED.get()).func_111126_e(), 0.0D));
    }
 
    protected float func_189749_co() {
@@ -1868,11 +1896,15 @@
    public void func_213352_e(Vector3d p_213352_1_) {
       if (this.func_70613_aW() || this.func_184186_bw()) {
          double d0 = 0.08D;
+          ModifiableAttributeInstance gravity = this.func_110148_a(net.minecraftforge.common.ForgeMod.ENTITY_GRAVITY.get());
          boolean flag = this.func_213322_ci().field_72448_b <= 0.0D;
          if (flag && this.func_70644_a(Effects.field_204839_B)) {
-            d0 = 0.01D;
+            if (!gravity.func_180374_a(SLOW_FALLING)) gravity.func_233767_b_(SLOW_FALLING);
             this.field_70143_R = 0.0F;
+         } else if (gravity.func_180374_a(SLOW_FALLING)) {
+            gravity.func_111124_b(SLOW_FALLING);
          }
+         d0 = gravity.func_111126_e();
 
          FluidState fluidstate = this.field_70170_p.func_204610_c(this.func_233580_cy_());
          if (this.func_70090_H() && this.func_241208_cS_() && !this.func_230285_a_(fluidstate.func_206886_c())) {
@@ -1897,6 +1929,7 @@
                f5 = 0.96F;
             }
 
+            f6 *= (float)this.func_110148_a(net.minecraftforge.common.ForgeMod.SWIM_SPEED.get()).func_111126_e();
             this.func_213309_a(f6, p_213352_1_);
             this.func_213315_a(MoverType.SELF, this.func_213322_ci());
             Vector3d vector3d6 = this.func_213322_ci();
@@ -1975,7 +2008,7 @@
             }
          } else {
             BlockPos blockpos = this.func_226270_aj_();
-            float f3 = this.field_70170_p.func_180495_p(blockpos).func_177230_c().func_208618_m();
+            float f3 = this.field_70170_p.func_180495_p(this.func_226270_aj_()).getSlipperiness(field_70170_p, this.func_226270_aj_(), this);
             float f4 = this.field_70122_E ? f3 * 0.91F : 0.91F;
             Vector3d vector3d5 = this.func_233633_a_(p_213352_1_, f3);
             double d2 = vector3d5.field_72448_b;
@@ -2075,6 +2108,7 @@
    }
 
    public void func_70071_h_() {
+      if (net.minecraftforge.common.ForgeHooks.onLivingUpdate(this)) return;
       super.func_70071_h_();
       this.func_184608_ct();
       this.func_205014_p();
@@ -2230,6 +2264,8 @@
 
          ItemStack itemstack1 = this.func_184582_a(equipmentslottype);
          if (!ItemStack.func_77989_b(itemstack1, itemstack)) {
+            if (!itemstack1.equals(itemstack1, true))
+               net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent(this, equipmentslottype, itemstack, itemstack1));
             if (map == null) {
                map = Maps.newEnumMap(EquipmentSlotType.class);
             }
@@ -2658,8 +2694,16 @@
 
    private void func_184608_ct() {
       if (this.func_184587_cr()) {
-         if (ItemStack.func_185132_d(this.func_184586_b(this.func_184600_cs()), this.field_184627_bm)) {
-            this.field_184627_bm = this.func_184586_b(this.func_184600_cs());
+         ItemStack itemStack = this.func_184586_b(this.func_184600_cs());
+         if (net.minecraftforge.common.ForgeHooks.canContinueUsing(this.field_184627_bm, itemStack)) this.field_184627_bm = itemStack;
+         if (itemStack == this.field_184627_bm) {
+
+            if (!this.field_184627_bm.func_190926_b()) {
+              field_184628_bn = net.minecraftforge.event.ForgeEventFactory.onItemUseTick(this, field_184627_bm, field_184628_bn);
+              if (field_184628_bn > 0)
+                 field_184627_bm.onUsingTick(this, field_184628_bn);
+            }
+
             this.field_184627_bm.func_222121_b(this.field_70170_p, this, this.func_184605_cv());
             if (this.func_226299_p_()) {
                this.func_226293_b_(this.field_184627_bm, 5);
@@ -2707,8 +2751,10 @@
    public void func_184598_c(Hand p_184598_1_) {
       ItemStack itemstack = this.func_184586_b(p_184598_1_);
       if (!itemstack.func_190926_b() && !this.func_184587_cr()) {
+         int duration = net.minecraftforge.event.ForgeEventFactory.onItemUseStart(this, itemstack, itemstack.func_77988_m());
+         if (duration <= 0) return;
          this.field_184627_bm = itemstack;
-         this.field_184628_bn = itemstack.func_77988_m();
+         this.field_184628_bn = duration;
          if (!this.field_70170_p.field_72995_K) {
             this.func_204802_c(1, true);
             this.func_204802_c(2, p_184598_1_ == Hand.OFF_HAND);
@@ -2768,6 +2814,9 @@
          vector3d1 = vector3d1.func_178789_a(-this.field_70125_A * ((float)Math.PI / 180F));
          vector3d1 = vector3d1.func_178785_b(-this.field_70177_z * ((float)Math.PI / 180F));
          vector3d1 = vector3d1.func_72441_c(this.func_226277_ct_(), this.func_226280_cw_(), this.func_226281_cx_());
+         if (this.field_70170_p instanceof ServerWorld) //Forge: Fix MC-2518 spawnParticle is nooped on server, need to use server specific variant
+             ((ServerWorld)this.field_70170_p).func_195598_a(new ItemParticleData(ParticleTypes.field_197591_B, p_195062_1_), vector3d1.field_72450_a, vector3d1.field_72448_b, vector3d1.field_72449_c, 1, vector3d.field_72450_a, vector3d.field_72448_b + 0.05D, vector3d.field_72449_c, 0.0D);
+         else
          this.field_70170_p.func_195594_a(new ItemParticleData(ParticleTypes.field_197591_B, p_195062_1_), vector3d1.field_72450_a, vector3d1.field_72448_b, vector3d1.field_72449_c, vector3d.field_72450_a, vector3d.field_72448_b + 0.05D, vector3d.field_72449_c);
       }
 
@@ -2779,7 +2828,9 @@
       } else {
          if (!this.field_184627_bm.func_190926_b() && this.func_184587_cr()) {
             this.func_226293_b_(this.field_184627_bm, 16);
-            this.func_184611_a(this.func_184600_cs(), this.field_184627_bm.func_77950_b(this.field_70170_p, this));
+            ItemStack copy = this.field_184627_bm.func_77946_l();
+            ItemStack stack = net.minecraftforge.event.ForgeEventFactory.onItemUseFinish(this, copy, func_184605_cv(), this.field_184627_bm.func_77950_b(this.field_70170_p, this));
+            this.func_184611_a(this.func_184600_cs(), stack);
             this.func_184602_cy();
          }
 
@@ -2800,7 +2851,11 @@
 
    public void func_184597_cx() {
       if (!this.field_184627_bm.func_190926_b()) {
+         if (!net.minecraftforge.event.ForgeEventFactory.onUseItemStop(this, field_184627_bm, this.func_184605_cv())) {
+            ItemStack copy = this instanceof PlayerEntity ? field_184627_bm.func_77946_l() : null;
          this.field_184627_bm.func_77974_b(this.field_70170_p, this, this.func_184605_cv());
+           if (copy != null && field_184627_bm.func_190926_b()) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem((PlayerEntity)this, copy, func_184600_cs());
+         }
          if (this.field_184627_bm.func_222122_m()) {
             this.func_184608_ct();
          }
@@ -2949,8 +3004,8 @@
       }
 
       BlockState blockstate = this.field_70170_p.func_180495_p(p_213342_1_);
-      if (blockstate.func_177230_c() instanceof BedBlock) {
-         this.field_70170_p.func_180501_a(p_213342_1_, blockstate.func_206870_a(BedBlock.field_176471_b, Boolean.valueOf(true)), 3);
+      if (blockstate.isBed(field_70170_p, p_213342_1_, this)) {
+         blockstate.setBedOccupied(field_70170_p, p_213342_1_, this, true);
       }
 
       this.func_213301_b(Pose.SLEEPING);
@@ -2966,15 +3021,15 @@
 
    private boolean func_213359_p() {
       return this.func_213374_dv().map((p_241350_1_) -> {
-         return this.field_70170_p.func_180495_p(p_241350_1_).func_177230_c() instanceof BedBlock;
+         return net.minecraftforge.event.ForgeEventFactory.fireSleepingLocationCheck(this, p_241350_1_);
       }).orElse(false);
    }
 
    public void func_213366_dy() {
       this.func_213374_dv().filter(this.field_70170_p::func_175667_e).ifPresent((p_241348_1_) -> {
          BlockState blockstate = this.field_70170_p.func_180495_p(p_241348_1_);
-         if (blockstate.func_177230_c() instanceof BedBlock) {
-            this.field_70170_p.func_180501_a(p_241348_1_, blockstate.func_206870_a(BedBlock.field_176471_b, Boolean.valueOf(false)), 3);
+         if (blockstate.isBed(field_70170_p, p_241348_1_, this)) {
+            blockstate.setBedOccupied(field_70170_p, p_241348_1_, this, false);
             Vector3d vector3d1 = BedBlock.func_220172_a(this.func_200600_R(), this.field_70170_p, p_241348_1_, 0).orElseGet(() -> {
                BlockPos blockpos = p_241348_1_.func_177984_a();
                return new Vector3d((double)blockpos.func_177958_n() + 0.5D, (double)blockpos.func_177956_o() + 0.1D, (double)blockpos.func_177952_p() + 0.5D);
@@ -2993,7 +3048,9 @@
    @OnlyIn(Dist.CLIENT)
    public Direction func_213376_dz() {
       BlockPos blockpos = this.func_213374_dv().orElse((BlockPos)null);
-      return blockpos != null ? BedBlock.func_220174_a(this.field_70170_p, blockpos) : null;
+      if (blockpos == null) return Direction.UP;
+      BlockState state = this.field_70170_p.func_180495_p(blockpos);
+      return !state.isBed(field_70170_p, blockpos, this) ? Direction.UP : state.getBedDirection(field_70170_p, blockpos);
    }
 
    public boolean func_70094_T() {
@@ -3062,4 +3119,58 @@
    public void func_213334_d(Hand p_213334_1_) {
       this.func_213361_c(p_213334_1_ == Hand.MAIN_HAND ? EquipmentSlotType.MAINHAND : EquipmentSlotType.OFFHAND);
    }
+
+   /* ==== FORGE START ==== */
+   /***
+    * Removes all potion effects that have curativeItem as a curative item for its effect
+    * @param curativeItem The itemstack we are using to cure potion effects
+    */
+   public boolean curePotionEffects(ItemStack curativeItem) {
+      if (this.field_70170_p.field_72995_K)
+         return false;
+      boolean ret = false;
+      Iterator<EffectInstance> itr = this.field_70713_bf.values().iterator();
+      while (itr.hasNext()) {
+         EffectInstance effect = itr.next();
+         if (effect.isCurativeItem(curativeItem) && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect))) {
+            this.func_70688_c(effect);
+            itr.remove();
+            ret = true;
+            this.field_70752_e = true;
+         }
+      }
+      return ret;
+   }
+
+   /**
+    * Returns true if the entity's rider (EntityPlayer) should face forward when mounted.
+    * currently only used in vanilla code by pigs.
+    *
+    * @param player The player who is riding the entity.
+    * @return If the player should orient the same direction as this entity.
+    */
+   public boolean shouldRiderFaceForward(PlayerEntity player) {
+      return this instanceof net.minecraft.entity.passive.PigEntity;
+   }
+
+   private final net.minecraftforge.common.util.LazyOptional<?>[] handlers = net.minecraftforge.items.wrapper.EntityEquipmentInvWrapper.create(this);
+
+   @Override
+   public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
+      if (this.func_70089_S() && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
+         if (facing == null) return handlers[2].cast();
+         else if (facing.func_176740_k().func_200128_b()) return handlers[0].cast();
+         else if (facing.func_176740_k().func_176722_c()) return handlers[1].cast();
+      }
+      return super.getCapability(capability, facing);
+   }
+
+   @Override
+   public void remove(boolean keepData) {
+      super.remove(keepData);
+      if (!keepData) {
+         for (int x = 0; x < handlers.length; x++)
+            handlers[x].invalidate();
+      }
+   }
 }
