@Inject(
     method = "dropItem",
     at =
         @At(
             value = "FIELD",
             opcode = Opcodes.GETFIELD,
             target = "Lnet/minecraft/entity/player/EntityPlayer;posY:D"),
     cancellable = true)
 private void onDropTop(
     ItemStack itemStack,
     boolean a,
     boolean b,
     CallbackInfoReturnable<EntityItem> callbackInfoReturnable) {
   final double height = this.posY - 0.3D + (double) this.getEyeHeight();
   Transform<org.spongepowered.api.world.World> transform =
       new Transform<>(this.getWorld(), new Vector3d(this.posX, height, this.posZ));
   SpawnCause cause =
       EntitySpawnCause.builder().entity(this).type(SpawnTypes.DROPPED_ITEM).build();
   ConstructEntityEvent.Pre event =
       SpongeEventFactory.createConstructEntityEventPre(
           Cause.of(NamedCause.source(cause)), EntityTypes.ITEM, transform);
   SpongeImpl.postEvent(event);
   if (event.isCancelled()) {
     callbackInfoReturnable.setReturnValue(null);
   }
 }
  /**
   * @author gabizou - January 30th, 2016
   * @author blood - May 12th, 2016
   * @reason If capturing is enabled, captures the item and avoids spawn. If capturing is not
   *     enabled, redirects the dropped item spawning to use our world spawning since we know the
   *     cause.
   */
  @Overwrite
  public void joinEntityItemWithWorld(EntityItem itemIn) {
    if (this.worldObj.isRemote) {
      this.worldObj.spawnEntityInWorld(itemIn);
      return;
    }

    if (this.captureItemDrops) {
      this.capturedItemDrops.add(itemIn);
      return;
    }

    SpawnCause spawnCause =
        EntitySpawnCause.builder().entity(this).type(SpawnTypes.DROPPED_ITEM).build();
    ((org.spongepowered.api.world.World) this.worldObj)
        .spawnEntity((Entity) itemIn, Cause.of(NamedCause.source(spawnCause)));
  }