@Override
 public void setTargetedLocation(@Nullable Vector3d vec) {
   this.targetedLocation = vec != null ? vec : VecHelper.toVector3d(this.worldObj.getSpawnPoint());
   if (!((Object) this instanceof EntityPlayerMP)) {
     this.worldObj.setSpawnPoint(VecHelper.toBlockPos(this.targetedLocation));
   }
 }
  public static BlockEvent.NeighborNotifyEvent createBlockNeighborNotifyEvent(Event event) {
    if (!(event instanceof NotifyNeighborBlockEvent)) {
      throw new IllegalArgumentException(
          "Event " + event.getClass() + " is not a valid NotifyNeighborBlockEvent.");
    }

    NotifyNeighborBlockEvent spongeEvent = (NotifyNeighborBlockEvent) event;
    Optional<BlockSnapshot> blockSnapshot = spongeEvent.getCause().first(BlockSnapshot.class);
    if (!blockSnapshot.isPresent() || !blockSnapshot.get().getLocation().isPresent()) {
      return null;
    }

    EnumSet<EnumFacing> facings = EnumSet.noneOf(EnumFacing.class);
    for (Map.Entry<Direction, BlockState> mapEntry : spongeEvent.getNeighbors().entrySet()) {
      facings.add(DirectionFacingProvider.getInstance().get(mapEntry.getKey()).get());
    }

    IBlockState state = (IBlockState) blockSnapshot.get().getState();
    BlockPos pos = VecHelper.toBlockPos(blockSnapshot.get().getLocation().get());
    net.minecraft.world.World world =
        (net.minecraft.world.World) blockSnapshot.get().getLocation().get().getExtent();

    final NeighborNotifyEvent forgeEvent = new NeighborNotifyEvent(world, pos, state, facings);
    return forgeEvent;
  }
 public static Cause generateCauseFor(DamageSource damageSource) {
   if (damageSource instanceof EntityDamageSourceIndirect) {
     net.minecraft.entity.Entity source = damageSource.getEntity();
     Optional<User> owner =
         ((IMixinEntity) source).getTrackedPlayer(NbtDataUtil.SPONGE_ENTITY_CREATOR);
     if (owner.isPresent()) {
       return Cause.of(
           NamedCause.of(DamageEntityEvent.SOURCE, damageSource),
           NamedCause.of(DamageEntityEvent.CREATOR, owner.get()));
     } else {
       return Cause.of(NamedCause.of(DamageEntityEvent.SOURCE, damageSource));
     }
   } else if (damageSource instanceof EntityDamageSource) {
     net.minecraft.entity.Entity source = damageSource.getEntity();
     Optional<User> owner =
         ((IMixinEntity) source).getTrackedPlayer(NbtDataUtil.SPONGE_ENTITY_CREATOR);
     Optional<User> notifier =
         ((IMixinEntity) source).getTrackedPlayer(NbtDataUtil.SPONGE_ENTITY_NOTIFIER);
     List<Object> causeObjects = new ArrayList<>();
     causeObjects.add(NamedCause.of(DamageEntityEvent.SOURCE, damageSource));
     if (notifier.isPresent()) {
       causeObjects.add(NamedCause.of(DamageEntityEvent.NOTIFIER, notifier.get()));
     }
     if (owner.isPresent()) {
       causeObjects.add(NamedCause.of(DamageEntityEvent.CREATOR, owner.get()));
     }
     return Cause.of(causeObjects.toArray());
   } else if (damageSource instanceof BlockDamageSource) {
     List<Object> causeObjects = new ArrayList<>();
     Location<org.spongepowered.api.world.World> location =
         ((BlockDamageSource) damageSource).getLocation();
     BlockPos blockPos = VecHelper.toBlockPos(location);
     Optional<User> owner =
         ((IMixinChunk)
                 ((net.minecraft.world.World) location.getExtent())
                     .getChunkFromBlockCoords(blockPos))
             .getBlockOwner(blockPos);
     Optional<User> notifier =
         ((IMixinChunk)
                 ((net.minecraft.world.World) location.getExtent())
                     .getChunkFromBlockCoords(blockPos))
             .getBlockNotifier(blockPos);
     causeObjects.add(NamedCause.of(DamageEntityEvent.SOURCE, damageSource));
     if (notifier.isPresent()) {
       causeObjects.add(NamedCause.of(DamageEntityEvent.NOTIFIER, notifier.get()));
     }
     if (owner.isPresent()) {
       causeObjects.add(NamedCause.of(DamageEntityEvent.CREATOR, owner.get()));
     }
     return Cause.of(causeObjects.toArray());
   } else {
     return Cause.of(NamedCause.of(DamageEntityEvent.SOURCE, damageSource));
   }
 }
 public SpongeProxyBlockAccess(
     IBlockAccess original, List<Transaction<BlockSnapshot>> snapshotTransaction) {
   this.original = original;
   this.transactions = snapshotTransaction;
   this.poses =
       this.transactions
           .stream()
           .map(transaction -> VecHelper.toBlockPos(transaction.getOriginal().getPosition()))
           .collect(GuavaCollectors.toImmutableList());
   this.index = 0;
 }
    @SuppressWarnings({"unchecked"})
    @Override
    public void syncDataToForge(org.spongepowered.api.event.Event spongeEvent) {
      super.syncDataToForge(spongeEvent);

      ExplosionEvent.Detonate event = (ExplosionEvent.Detonate) spongeEvent;
      List<BlockPos> affectedBlocks = this.explosion.func_180343_e();
      affectedBlocks.clear();

      for (BlockTransaction blockTransaction : event.getTransactions()) {
        if (blockTransaction.isValid()) {
          affectedBlocks.add(
              VecHelper.toBlockPos(blockTransaction.getFinalReplacement().getPosition()));
        }
      }
    }
  private static PlayerInteractEvent createPlayerInteractEvent(Event event) {
    if (!(event instanceof InteractBlockEvent)) {
      throw new IllegalArgumentException("Event " + event + " is not a valid InteractBlockEvent.");
    }

    InteractBlockEvent spongeEvent = (InteractBlockEvent) event;
    Optional<Player> player = spongeEvent.getCause().first(Player.class);
    if (!player.isPresent()) {
      return null;
    }

    BlockPos pos =
        VecHelper.toBlockPos(spongeEvent.getTargetBlock().getLocation().get().getPosition());
    Optional<EnumFacing> face =
        DirectionFacingProvider.getInstance().get(spongeEvent.getTargetSide());
    Action action = null;
    if (spongeEvent instanceof InteractBlockEvent.Primary) {
      action = Action.LEFT_CLICK_BLOCK;
    } else if (spongeEvent instanceof InteractBlockEvent.Secondary) {
      if (spongeEvent.getTargetBlock().getState().getType() == BlockTypes.AIR) {
        action = Action.RIGHT_CLICK_AIR;
      } else {
        action = Action.RIGHT_CLICK_BLOCK;
      }
    } else { // attempt to determine action
      EntityPlayer entityplayer = (EntityPlayer) player.get();
      action = Action.RIGHT_CLICK_BLOCK;
      if (entityplayer.isUsingItem()) {
        action = Action.LEFT_CLICK_BLOCK;
      } else if (entityplayer.worldObj.isAirBlock(pos)) {
        action = Action.RIGHT_CLICK_AIR;
      }
    }

    PlayerInteractEvent forgeEvent =
        new PlayerInteractEvent(
            (EntityPlayer) player.get(),
            action,
            pos,
            face.isPresent() ? face.get() : null,
            (net.minecraft.world.World) player.get().getWorld());
    return forgeEvent;
  }
    @SuppressWarnings("unchecked")
    @Override
    public void syncDataToSponge(net.minecraftforge.fml.common.eventhandler.Event forgeEvent) {
      super.syncDataToSponge(forgeEvent);

      net.minecraftforge.event.world.ExplosionEvent event =
          (net.minecraftforge.event.world.ExplosionEvent) forgeEvent;
      // TODO - handle this better
      List<BlockPos> affectedBlocks = event.explosion.func_180343_e();
      for (BlockTransaction transaction : this.blockTransactions) {
        BlockPos pos = VecHelper.toBlockPos(transaction.getFinalReplacement().getPosition());
        boolean match = false;
        for (BlockPos forgePos : affectedBlocks) {
          if (forgePos.getX() == pos.getX()
              && forgePos.getY() == pos.getY()
              && forgePos.getZ() == pos.getZ()) {
            match = true;
          }
        }
        if (!match) {
          transaction.setIsValid(false);
        }
      }
    }
  public static ChangeBlockEvent.Place callBlockPlaceEvent(Event event) {
    if (!(event instanceof ChangeBlockEvent.Place)) {
      throw new IllegalArgumentException("Event is not a valid ChangeBlockEventPlace");
    }

    ChangeBlockEvent.Place spongeEvent = (ChangeBlockEvent.Place) event;

    if (spongeEvent.getCause().first(Player.class).isPresent()) {
      EntityPlayer player = (EntityPlayer) spongeEvent.getCause().first(Player.class).get();
      net.minecraft.world.World world = (net.minecraft.world.World) spongeEvent.getTargetWorld();

      if (spongeEvent.getTransactions().size() == 1) {
        BlockPos pos =
            VecHelper.toBlockPos(spongeEvent.getTransactions().get(0).getOriginal().getPosition());
        IBlockState state =
            (IBlockState) spongeEvent.getTransactions().get(0).getOriginal().getState();
        net.minecraftforge.common.util.BlockSnapshot blockSnapshot =
            new net.minecraftforge.common.util.BlockSnapshot(world, pos, state);
        IBlockState placedAgainst = Blocks.air.getDefaultState();
        if (StaticMixinHelper.packetPlayer != null
            && StaticMixinHelper.processingPacket instanceof C08PacketPlayerBlockPlacement) {
          C08PacketPlayerBlockPlacement packet =
              (C08PacketPlayerBlockPlacement) StaticMixinHelper.processingPacket;
          EnumFacing facing = EnumFacing.getFront(packet.getPlacedBlockDirection());
          placedAgainst =
              blockSnapshot.world.getBlockState(blockSnapshot.pos.offset(facing.getOpposite()));
        }

        BlockEvent.PlaceEvent forgeEvent =
            new BlockEvent.PlaceEvent(blockSnapshot, placedAgainst, player);
        ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
        if (forgeEvent.isCanceled()) {
          spongeEvent.getTransactions().get(0).setValid(false);
        }
      } else { // multi
        Iterator<Transaction<BlockSnapshot>> iterator = spongeEvent.getTransactions().iterator();
        List<net.minecraftforge.common.util.BlockSnapshot> blockSnapshots = new ArrayList<>();

        while (iterator.hasNext()) {
          Transaction<BlockSnapshot> transaction = iterator.next();
          Location<World> location = transaction.getOriginal().getLocation().get();
          IBlockState state = (IBlockState) transaction.getOriginal().getState();
          BlockPos pos =
              new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
          net.minecraftforge.common.util.BlockSnapshot blockSnapshot =
              new net.minecraftforge.common.util.BlockSnapshot(world, pos, state);
          blockSnapshots.add(blockSnapshot);
        }

        IBlockState placedAgainst = Blocks.air.getDefaultState();
        if (StaticMixinHelper.packetPlayer != null
            && StaticMixinHelper.processingPacket instanceof C08PacketPlayerBlockPlacement) {
          C08PacketPlayerBlockPlacement packet =
              (C08PacketPlayerBlockPlacement) StaticMixinHelper.processingPacket;
          EnumFacing facing = EnumFacing.getFront(packet.getPlacedBlockDirection());
          placedAgainst =
              blockSnapshots
                  .get(0)
                  .world
                  .getBlockState(blockSnapshots.get(0).pos.offset(facing.getOpposite()));
        }

        BlockEvent.MultiPlaceEvent forgeEvent =
            new BlockEvent.MultiPlaceEvent(blockSnapshots, placedAgainst, player);
        ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
        if (forgeEvent.isCanceled()) {
          while (iterator.hasNext()) {
            iterator.next().setValid(false);
          }
        }
      }
    }
    return spongeEvent;
  }