/**
   * @author blood - May 12th, 2016
   * @reason SpongeForge requires an overwrite so we do it here instead. This handles player death
   *     events.
   */
  @Overwrite
  public void onDeath(DamageSource cause) {
    if (SpongeCommonEventFactory.callDestructEntityEventDeath(
            (EntityLivingBase) (Object) this, cause)
        == null) {
      return;
    }

    super.onDeath(cause);
    this.setSize(0.2F, 0.2F);
    this.setPosition(this.posX, this.posY, this.posZ);
    this.motionY = 0.10000000149011612D;

    this.captureItemDrops = true;
    this.capturedItemDrops.clear();

    if (this.getName().equals("Notch")) {
      this.dropItem(new ItemStack(Items.apple, 1), true, false);
    }

    if (!this.worldObj.getGameRules().getBoolean("keepInventory")) {
      this.inventory.dropAllItems();
    }

    this.captureItemDrops = false;
    if (this.capturedItemDrops.size() > 0) {
      IMixinWorld spongeWorld = (IMixinWorld) this.worldObj;
      final CauseTracker causeTracker = spongeWorld.getCauseTracker();
      causeTracker.setIgnoreSpawnEvents(true);
      DropItemEvent.Destruct event =
          SpongeCommonEventFactory.callDropItemEventDestruct(
              (EntityPlayerMP) (Object) this, cause, this.capturedItemDrops);
      if (!event.isCancelled()) {
        for (net.minecraft.entity.item.EntityItem item : this.capturedItemDrops) {
          this.worldObj.spawnEntityInWorld(item);
        }
        this.inventory.clear();
      }
      causeTracker.setIgnoreSpawnEvents(false);
    }

    if (cause != null) {
      this.motionX =
          (double)
              (-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float) Math.PI / 180.0F)
                  * 0.1F);
      this.motionZ =
          (double)
              (-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float) Math.PI / 180.0F)
                  * 0.1F);
    } else {
      this.motionX = this.motionZ = 0.0D;
    }

    this.triggerAchievement(StatList.deathsStat);
  }
  /**
   * @author blood - May 21st, 2016
   * @reason - adjusted to support {@link DisplaceEntityEvent.Teleport.Portal}
   * @param playerIn The player teleporting to another dimension
   * @param targetDimensionId The id of target dimension.
   * @param teleporter The teleporter used to transport and create the portal
   */
  public void transferPlayerToDimension(
      EntityPlayerMP playerIn, int targetDimensionId, net.minecraft.world.Teleporter teleporter) {
    DisplaceEntityEvent.Teleport.Portal event =
        SpongeCommonEventFactory.handleDisplaceEntityPortalEvent(
            playerIn, targetDimensionId, teleporter);
    if (event == null || event.isCancelled()) {
      return;
    }

    WorldServer fromWorld = (WorldServer) event.getFromTransform().getExtent();
    WorldServer toWorld = (WorldServer) event.getToTransform().getExtent();
    playerIn.dimension = toWorld.provider.getDimensionId();
    // Support vanilla clients teleporting to custom dimensions
    int dimension =
        DimensionManager.getClientDimensionToSend(
            toWorld.provider.getDimensionId(), toWorld, playerIn);
    if (((IMixinEntityPlayerMP) playerIn).usesCustomClient()) {
      DimensionManager.sendDimensionRegistration(toWorld, playerIn, dimension);
    }
    playerIn.playerNetServerHandler.sendPacket(
        new S07PacketRespawn(
            playerIn.dimension,
            fromWorld.getDifficulty(),
            fromWorld.getWorldInfo().getTerrainType(),
            playerIn.theItemInWorldManager.getGameType()));
    fromWorld.removePlayerEntityDangerously(playerIn);
    playerIn.isDead = false;
    // we do not need to call transferEntityToWorld as we already have the correct transform and
    // created the portal in handleDisplaceEntityPortalEvent
    ((IMixinEntity) playerIn).setLocationAndAngles(event.getToTransform());
    toWorld.spawnEntityInWorld(playerIn);
    toWorld.updateEntityWithOptionalForce(playerIn, false);
    playerIn.setWorld(toWorld);
    this.preparePlayer(playerIn, fromWorld);
    playerIn.playerNetServerHandler.setPlayerLocation(
        playerIn.posX, playerIn.posY, playerIn.posZ, playerIn.rotationYaw, playerIn.rotationPitch);
    playerIn.theItemInWorldManager.setWorld(toWorld);
    this.updateTimeAndWeatherForPlayer(playerIn, toWorld);
    this.syncPlayerInventory(playerIn);

    for (PotionEffect potioneffect : playerIn.getActivePotionEffects()) {
      playerIn.playerNetServerHandler.sendPacket(
          new S1DPacketEntityEffect(playerIn.getEntityId(), potioneffect));
    }
    ((IMixinEntityPlayerMP) playerIn).refreshXpHealthAndFood();
    // Forge needs to know when a player changes to new a dimension
    // This cannot be mapped to DisplaceEntityEvent.Teleport as this event must be called AFTER
    // transfer.
    net.minecraftforge.fml.common.FMLCommonHandler.instance()
        .firePlayerChangedDimensionEvent(
            playerIn, fromWorld.provider.getDimensionId(), toWorld.provider.getDimensionId());
  }
 @Inject(
     method = "onCollideWithPlayer",
     at =
         @At(
             value = "INVOKE",
             target =
                 "Lnet/minecraft/entity/item/EntityItem;getEntityItem()Lnet/minecraft/item/ItemStack;"),
     cancellable = true)
 public void onPlayerItemPickup(EntityPlayer entityIn, CallbackInfo ci) {
   if (!SpongeCommonEventFactory.callPlayerChangeInventoryPickupEvent(
       entityIn, this.getEntityItem(), this.delayBeforeCanPickup)) {
     ci.cancel();
   }
 }