--- a/net/minecraft/entity/player/PlayerEntity.java
+++ b/net/minecraft/entity/player/PlayerEntity.java
@@ -110,6 +110,7 @@
 import net.minecraftforge.api.distmarker.OnlyIn;
 
 public abstract class PlayerEntity extends LivingEntity {
+   public static final String PERSISTED_NBT_TAG = "PlayerPersisted";
    public static final EntitySize field_213835_bs = EntitySize.func_220314_b(0.6F, 1.8F);
    private static final Map<Pose, EntitySize> field_213836_b = ImmutableMap.<Pose, EntitySize>builder().put(Pose.STANDING, field_213835_bs).put(Pose.SLEEPING, field_213377_as).put(Pose.FALL_FLYING, EntitySize.func_220314_b(0.6F, 0.6F)).put(Pose.SWIMMING, EntitySize.func_220314_b(0.6F, 0.6F)).put(Pose.SPIN_ATTACK, EntitySize.func_220314_b(0.6F, 0.6F)).put(Pose.CROUCHING, EntitySize.func_220314_b(0.6F, 1.5F)).put(Pose.DYING, EntitySize.func_220311_c(0.2F, 0.2F)).build();
    private static final DataParameter<Float> field_184829_a = EntityDataManager.func_187226_a(PlayerEntity.class, DataSerializers.field_187193_c);
@@ -150,6 +151,9 @@
    private final CooldownTracker field_184832_bU = this.func_184815_l();
    @Nullable
    public FishingBobberEntity field_71104_cf;
+   private final java.util.Collection<IFormattableTextComponent> prefixes = new java.util.LinkedList<>();
+   private final java.util.Collection<IFormattableTextComponent> suffixes = new java.util.LinkedList<>();
+   @Nullable private Pose forcedPose;
 
    public PlayerEntity(World p_i241920_1_, BlockPos p_i241920_2_, float p_i241920_3_, GameProfile p_i241920_4_) {
       super(EntityType.field_200729_aH, p_i241920_1_);
@@ -175,7 +179,7 @@
    }
 
    public static AttributeModifierMap.MutableAttribute func_234570_el_() {
-      return LivingEntity.func_233639_cI_().func_233815_a_(Attributes.field_233823_f_, 1.0D).func_233815_a_(Attributes.field_233821_d_, (double)0.1F).func_233814_a_(Attributes.field_233825_h_).func_233814_a_(Attributes.field_233828_k_);
+      return LivingEntity.func_233639_cI_().func_233815_a_(Attributes.field_233823_f_, 1.0D).func_233815_a_(Attributes.field_233821_d_, (double)0.1F).func_233814_a_(Attributes.field_233825_h_).func_233814_a_(Attributes.field_233828_k_).func_233814_a_(net.minecraftforge.common.ForgeMod.REACH_DISTANCE.get());
    }
 
    protected void func_70088_a() {
@@ -189,6 +193,7 @@
    }
 
    public void func_70071_h_() {
+      net.minecraftforge.fml.hooks.BasicEventHooks.onPlayerPreTick(this);
       this.field_70145_X = this.func_175149_v();
       if (this.func_175149_v()) {
          this.field_70122_E = false;
@@ -204,7 +209,7 @@
             this.field_71076_b = 100;
          }
 
-         if (!this.field_70170_p.field_72995_K && this.field_70170_p.func_72935_r()) {
+         if (!this.field_70170_p.field_72995_K && !net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, func_213374_dv())) {
             this.func_225652_a_(false, true);
          }
       } else if (this.field_71076_b > 0) {
@@ -258,6 +263,7 @@
       this.func_203041_m();
       this.field_184832_bU.func_185144_a();
       this.func_213832_dB();
+      net.minecraftforge.fml.hooks.BasicEventHooks.onPlayerPostTick(this);
    }
 
    public boolean func_226563_dT_() {
@@ -333,6 +339,10 @@
    }
 
    protected void func_213832_dB() {
+      if(forcedPose != null) {
+         this.func_213301_b(forcedPose);
+         return;
+      }
       if (this.func_213298_c(Pose.SWIMMING)) {
          Pose pose;
          if (this.func_184613_cA()) {
@@ -550,6 +560,7 @@
    }
 
    public void func_70645_a(DamageSource p_70645_1_) {
+      if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this,  p_70645_1_)) return;
       super.func_70645_a(p_70645_1_);
       this.func_226264_Z_();
       if (!this.func_175149_v()) {
@@ -603,12 +614,14 @@
    }
 
    public boolean func_225609_n_(boolean p_225609_1_) {
-      return this.func_146097_a(this.field_71071_by.func_70298_a(this.field_71071_by.field_70461_c, p_225609_1_ && !this.field_71071_by.func_70448_g().func_190926_b() ? this.field_71071_by.func_70448_g().func_190916_E() : 1), false, true) != null;
+      ItemStack stack = field_71071_by.func_70448_g();
+      if (stack.func_190926_b() || !stack.onDroppedByPlayer(this)) return false;
+      return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, this.field_71071_by.func_70298_a(this.field_71071_by.field_70461_c, p_225609_1_ && !this.field_71071_by.func_70448_g().func_190926_b() ? this.field_71071_by.func_70448_g().func_190916_E() : 1), true) != null;
    }
 
    @Nullable
    public ItemEntity func_71019_a(ItemStack p_71019_1_, boolean p_71019_2_) {
-      return this.func_146097_a(p_71019_1_, false, p_71019_2_);
+      return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, p_71019_1_, false);
    }
 
    @Nullable
@@ -646,7 +659,12 @@
       }
    }
 
+   @Deprecated //Use location sensitive version below
    public float func_184813_a(BlockState p_184813_1_) {
+      return getDigSpeed(p_184813_1_, null);
+   }
+
+   public float getDigSpeed(BlockState p_184813_1_, @Nullable BlockPos pos) {
       float f = this.field_71071_by.func_184438_a(p_184813_1_);
       if (f > 1.0F) {
          int i = EnchantmentHelper.func_185293_e(this);
@@ -688,11 +706,12 @@
          f /= 5.0F;
       }
 
+      f = net.minecraftforge.event.ForgeEventFactory.getBreakSpeed(this, p_184813_1_, f, pos);
       return f;
    }
 
    public boolean func_234569_d_(BlockState p_234569_1_) {
-      return !p_234569_1_.func_235783_q_() || this.field_71071_by.func_70448_g().func_150998_b(p_234569_1_);
+      return net.minecraftforge.event.ForgeEventFactory.doPlayerHarvestCheck(this, p_234569_1_, !p_234569_1_.func_235783_q_() || this.field_71071_by.func_70448_g().func_150998_b(p_234569_1_));
    }
 
    public void func_70037_a(CompoundNBT p_70037_1_) {
@@ -767,6 +786,7 @@
    }
 
    public boolean func_70097_a(DamageSource p_70097_1_, float p_70097_2_) {
+      if (!net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, p_70097_1_, p_70097_2_)) return false;
       if (this.func_180431_b(p_70097_1_)) {
          return false;
       } else if (this.field_71075_bZ.field_75102_a && !p_70097_1_.func_76357_e()) {
@@ -798,7 +818,7 @@
 
    protected void func_190629_c(LivingEntity p_190629_1_) {
       super.func_190629_c(p_190629_1_);
-      if (p_190629_1_.func_184614_ca().func_77973_b() instanceof AxeItem) {
+      if (p_190629_1_.func_184614_ca().canDisableShield(this.field_184627_bm, this, p_190629_1_)) {
          this.func_190777_m(true);
       }
 
@@ -819,7 +839,7 @@
    }
 
    protected void func_184590_k(float p_184590_1_) {
-      if (this.field_184627_bm.func_77973_b() == Items.field_185159_cQ) {
+      if (this.field_184627_bm.isShield(this)) {
          if (!this.field_70170_p.field_72995_K) {
             this.func_71029_a(Stats.field_75929_E.func_199076_b(this.field_184627_bm.func_77973_b()));
          }
@@ -829,6 +849,7 @@
             Hand hand = this.func_184600_cs();
             this.field_184627_bm.func_222118_a(i, this, (p_213833_1_) -> {
                p_213833_1_.func_213334_d(hand);
+               net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, this.field_184627_bm, hand);
             });
             if (this.field_184627_bm.func_190926_b()) {
                if (hand == Hand.MAIN_HAND) {
@@ -847,10 +868,13 @@
 
    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);
          this.func_110149_m(this.func_110139_bj() - (p_70665_2_ - f2));
+         f2 = net.minecraftforge.common.ForgeHooks.onLivingDamage(this, p_70665_1_, f2);
          float f = p_70665_2_ - f2;
          if (f > 0.0F && f < 3.4028235E37F) {
             this.func_195067_a(Stats.field_212738_J, Math.round(f * 10.0F));
@@ -909,6 +933,8 @@
 
          return ActionResultType.PASS;
       } else {
+         ActionResultType cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntity(this, p_190775_1_, p_190775_2_);
+         if (cancelResult != null) return cancelResult;
          ItemStack itemstack = this.func_184586_b(p_190775_2_);
          ItemStack itemstack1 = itemstack.func_77946_l();
          ActionResultType actionresulttype = p_190775_1_.func_184230_a(this, p_190775_2_);
@@ -917,6 +943,9 @@
                itemstack.func_190920_e(itemstack1.func_190916_E());
             }
 
+            if (!this.field_71075_bZ.field_75098_d && itemstack.func_190926_b()) {
+               net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, p_190775_2_);
+            }
             return actionresulttype;
          } else {
             if (!itemstack.func_190926_b() && p_190775_1_ instanceof LivingEntity) {
@@ -927,6 +956,7 @@
                ActionResultType actionresulttype1 = itemstack.func_111282_a_(this, (LivingEntity)p_190775_1_, p_190775_2_);
                if (actionresulttype1.func_226246_a_()) {
                   if (itemstack.func_190926_b() && !this.field_71075_bZ.field_75098_d) {
+                     net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, p_190775_2_);
                      this.func_184611_a(p_190775_2_, ItemStack.field_190927_a);
                   }
 
@@ -1011,6 +1041,7 @@
    }
 
    public void func_71059_n(Entity p_71059_1_) {
+      if (!net.minecraftforge.common.ForgeHooks.onPlayerAttackTarget(this, p_71059_1_)) return;
       if (p_71059_1_.func_70075_an()) {
          if (!p_71059_1_.func_85031_j(this)) {
             float f = (float)this.func_233637_b_(Attributes.field_233823_f_);
@@ -1038,8 +1069,10 @@
 
                boolean flag2 = flag && this.field_70143_R > 0.0F && !this.field_70122_E && !this.func_70617_f_() && !this.func_70090_H() && !this.func_70644_a(Effects.field_76440_q) && !this.func_184218_aH() && p_71059_1_ instanceof LivingEntity;
                flag2 = flag2 && !this.func_70051_ag();
+               net.minecraftforge.event.entity.player.CriticalHitEvent hitResult = net.minecraftforge.common.ForgeHooks.getCriticalHit(this, p_71059_1_, flag2, flag2 ? 1.5F : 1.0F);
+               flag2 = hitResult != null;
                if (flag2) {
-                  f *= 1.5F;
+                  f *= hitResult.getDamageModifier();
                }
 
                f = f + f1;
@@ -1127,8 +1160,10 @@
                   }
 
                   if (!this.field_70170_p.field_72995_K && !itemstack1.func_190926_b() && entity instanceof LivingEntity) {
+                     ItemStack copy = itemstack1.func_77946_l();
                      itemstack1.func_77961_a((LivingEntity)entity, this);
                      if (itemstack1.func_190926_b()) {
+                        net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, copy, Hand.MAIN_HAND);
                         this.func_184611_a(Hand.MAIN_HAND, ItemStack.field_190927_a);
                      }
                   }
@@ -1170,7 +1205,7 @@
       }
 
       if (this.field_70146_Z.nextFloat() < f) {
-         this.func_184811_cZ().func_185145_a(Items.field_185159_cQ, 100);
+         this.func_184811_cZ().func_185145_a(this.func_184607_cu().func_77973_b(), 100);
          this.func_184602_cy();
          this.field_70170_p.func_72960_a(this, (byte)30);
       }
@@ -1196,8 +1231,9 @@
    public void func_71004_bE() {
    }
 
-   public void func_70106_y() {
-      super.func_70106_y();
+   @Override
+   public void remove(boolean keepData) {
+      super.remove(keepData);
       this.field_71069_bz.func_75134_a(this);
       if (this.field_71070_bA != null) {
          this.field_71070_bA.func_75134_a(this);
@@ -1220,6 +1256,7 @@
    }
 
    public void func_225652_a_(boolean p_225652_1_, boolean p_225652_2_) {
+      net.minecraftforge.event.ForgeEventFactory.onPlayerWakeup(this, p_225652_1_, p_225652_2_);
       super.func_213366_dy();
       if (this.field_70170_p instanceof ServerWorld && p_225652_2_) {
          ((ServerWorld)this.field_70170_p).func_72854_c();
@@ -1242,8 +1279,8 @@
          }
 
          return optional;
-      } else if (block instanceof BedBlock && BedBlock.func_235330_a_(p_242374_0_)) {
-         return BedBlock.func_242652_a(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_);
+      } else if (blockstate.isBed(p_242374_0_, p_242374_1_, null) && BedBlock.func_235330_a_(p_242374_0_)) {
+         return blockstate.getBedSpawnPosition(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_, null);
       } else if (!p_242374_3_) {
          return Optional.empty();
       } else {
@@ -1425,6 +1462,7 @@
 
    public boolean func_225503_b_(float p_225503_1_, float p_225503_2_) {
       if (this.field_71075_bZ.field_75101_c) {
+         net.minecraftforge.event.ForgeEventFactory.onPlayerFall(this, p_225503_1_, p_225503_2_);
          return false;
       } else {
          if (p_225503_1_ >= 2.0F) {
@@ -1438,7 +1476,7 @@
    public boolean func_226566_ei_() {
       if (!this.field_70122_E && !this.func_184613_cA() && !this.func_70090_H() && !this.func_70644_a(Effects.field_188424_y)) {
          ItemStack itemstack = this.func_184582_a(EquipmentSlotType.CHEST);
-         if (itemstack.func_77973_b() == Items.field_185160_cR && ElytraItem.func_185069_d(itemstack)) {
+         if (itemstack.canElytraFly(this)) {
             this.func_226567_ej_();
             return true;
          }
@@ -1479,6 +1517,10 @@
    }
 
    public void func_195068_e(int p_195068_1_) {
+      net.minecraftforge.event.entity.player.PlayerXpEvent.XpChange event = new net.minecraftforge.event.entity.player.PlayerXpEvent.XpChange(this, p_195068_1_);
+      if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return;
+      p_195068_1_ = event.getAmount();
+
       this.func_85039_t(p_195068_1_);
       this.field_71106_cc += (float)p_195068_1_ / (float)this.func_71050_bK();
       this.field_71067_cb = MathHelper.func_76125_a(this.field_71067_cb + p_195068_1_, 0, Integer.MAX_VALUE);
@@ -1507,7 +1549,7 @@
    }
 
    public void func_192024_a(ItemStack p_192024_1_, int p_192024_2_) {
-      this.field_71068_ca -= p_192024_2_;
+      func_82242_a(-p_192024_2_);
       if (this.field_71068_ca < 0) {
          this.field_71068_ca = 0;
          this.field_71106_cc = 0.0F;
@@ -1518,6 +1560,10 @@
    }
 
    public void func_82242_a(int p_82242_1_) {
+      net.minecraftforge.event.entity.player.PlayerXpEvent.LevelChange event = new net.minecraftforge.event.entity.player.PlayerXpEvent.LevelChange(this, p_82242_1_);
+      if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return;
+      p_82242_1_ = event.getLevels();
+
       this.field_71068_ca += p_82242_1_;
       if (this.field_71068_ca < 0) {
          this.field_71068_ca = 0;
@@ -1708,7 +1754,11 @@
    }
 
    public ITextComponent func_145748_c_() {
-      IFormattableTextComponent iformattabletextcomponent = ScorePlayerTeam.func_237500_a_(this.func_96124_cp(), this.func_200200_C_());
+      if (this.displayname == null) this.displayname = net.minecraftforge.event.ForgeEventFactory.getPlayerDisplayName(this, this.func_200200_C_());
+      IFormattableTextComponent iformattabletextcomponent = new StringTextComponent("");
+      iformattabletextcomponent = prefixes.stream().reduce(iformattabletextcomponent, IFormattableTextComponent::func_230529_a_);
+      iformattabletextcomponent = iformattabletextcomponent.func_230529_a_(ScorePlayerTeam.func_237500_a_(this.func_96124_cp(), this.displayname));
+      iformattabletextcomponent = suffixes.stream().reduce(iformattabletextcomponent, IFormattableTextComponent::func_230529_a_);
       return this.func_208016_c(iformattabletextcomponent);
    }
 
@@ -1987,4 +2037,62 @@
          return this.field_221260_g;
       }
    }
+
+   // =========== FORGE START ==============//
+   public Collection<IFormattableTextComponent> getPrefixes() {
+       return this.prefixes;
+   }
+
+   public Collection<IFormattableTextComponent> getSuffixes() {
+       return this.suffixes;
+   }
+
+   private ITextComponent displayname = null;
+   /**
+    * Force the displayed name to refresh, by firing {@link net.minecraftforge.event.entity.player.PlayerEvent.NameFormat}, using the real player name as event parameter.
+    */
+   public void refreshDisplayName() {
+      this.displayname = net.minecraftforge.event.ForgeEventFactory.getPlayerDisplayName(this, this.func_200200_C_());
+   }
+
+   private final net.minecraftforge.common.util.LazyOptional<net.minecraftforge.items.IItemHandler>
+         playerMainHandler = net.minecraftforge.common.util.LazyOptional.of(
+               () -> new net.minecraftforge.items.wrapper.PlayerMainInvWrapper(field_71071_by));
+
+   private final net.minecraftforge.common.util.LazyOptional<net.minecraftforge.items.IItemHandler>
+         playerEquipmentHandler = net.minecraftforge.common.util.LazyOptional.of(
+               () -> new net.minecraftforge.items.wrapper.CombinedInvWrapper(
+                     new net.minecraftforge.items.wrapper.PlayerArmorInvWrapper(field_71071_by),
+                     new net.minecraftforge.items.wrapper.PlayerOffhandInvWrapper(field_71071_by)));
+
+   private final net.minecraftforge.common.util.LazyOptional<net.minecraftforge.items.IItemHandler>
+         playerJoinedHandler = net.minecraftforge.common.util.LazyOptional.of(
+               () -> new net.minecraftforge.items.wrapper.PlayerInvWrapper(field_71071_by));
+
+   @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 playerJoinedHandler.cast();
+         else if (facing.func_176740_k().func_200128_b()) return playerMainHandler.cast();
+         else if (facing.func_176740_k().func_176722_c()) return playerEquipmentHandler.cast();
+      }
+      return super.getCapability(capability, facing);
+   }
+
+   /**
+    * Force a pose for the player. If set, the vanilla pose determination and clearance check is skipped. Make sure the pose is clear yourself (e.g. in PlayerTick).
+    * This has to be set just once, do not set it every tick.
+    * Make sure to clear (null) the pose if not required anymore and only use if necessary.
+    */
+   public void setForcedPose(@Nullable Pose pose) {
+      this.forcedPose = pose;
+   }
+
+   /**
+    * @return The forced pose if set, null otherwise
+    */
+   @Nullable
+   public Pose getForcedPose() {
+      return this.forcedPose;
+   }
 }
