@Override
  public IMessage onMessage(PacketKurosawaAttack message, MessageContext ctx) {
    EntityPlayer player = ctx.getServerHandler().playerEntity;
    Kurosawa item = (Kurosawa) player.getHeldItem().getItem();

    if (!item.getCooldown()) {
      World world = player.worldObj;
      EntityLivingBase target = (EntityLivingBase) world.getEntityByID(message.targetID);
      Vec3 targetPos = target.getPositionVector();
      Vec3 attackerPos = player.getPositionVector();

      Vec3 distance = targetPos.subtractReverse(attackerPos).normalize();
      distance = new Vec3(distance.xCoord * 3, distance.yCoord * 3, distance.zCoord * 3);

      player.setPositionAndRotation(
          target.posX - distance.xCoord,
          target.posY - distance.yCoord,
          target.posZ - distance.zCoord,
          player.rotationYaw + 180,
          player.rotationPitch);
      player.setRotationYawHead(player.rotationYawHead + 180);
      player.cameraPitch += 180;
      player.setPositionAndUpdate(
          target.posX - distance.xCoord,
          target.posY - distance.yCoord,
          target.posZ - distance.zCoord);
      target.attackEntityFrom(DamageSource.causePlayerDamage(player), 44);
      item.setCooldown();
    }
    return null;
  }
  public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
    DimensionalLinkEntry[] entries = readEntries(itemStack);
    if (player.isSneaking()) {
      if (!world.isRemote) {
        int dimID = world.provider.dimensionId;
        DimensionalLinkEntry alreadyHasForThisWorld = null;
        for (DimensionalLinkEntry entry : entries)
          if (entry.dimID == dimID) alreadyHasForThisWorld = entry;
        if (alreadyHasForThisWorld != null) removeEntry(itemStack, alreadyHasForThisWorld.dimID);
        addEntry(
            itemStack,
            new DimensionalLinkEntry(
                dimID,
                (int) Math.floor(player.posX),
                (int) Math.floor(player.posY),
                (int) Math.floor(player.posZ)));

        player.addChatMessage(EnumChatFormatting.DARK_GREEN + "Warp point for this world set.");
      }
    } else {
      int dimID = world.provider.dimensionId;
      DimensionalLinkEntry link = null;
      for (DimensionalLinkEntry entry : entries) if (entry.dimID == dimID) link = entry;
      if (link != null) {
        double targetX = link.x + 0.5D;
        double targetY = link.y + 1.0D;
        double targetZ = link.z + 0.5D;
        EAVector3 targetVec = new EAVector3(targetX, targetY, targetZ);
        EAVector3 playerVec = EAVector3.fromEntityCenter(player);
        double distance = targetVec.subtract(playerVec).mag();
        int rfToConsume = (int) (distance * 2500.0D);
        if ((getEnergyStored(itemStack) >= rfToConsume)
            || ((player.capabilities.isCreativeMode) && (ensureCooldown(itemStack)))) {
          for (int i = 0; i < 128; i++) {
            world.spawnParticle(
                "portal",
                targetX,
                targetY,
                targetZ,
                world.rand.nextGaussian(),
                0.0D,
                world.rand.nextGaussian());
          }

          if (!world.isRemote) {
            if (!player.capabilities.isCreativeMode) extractEnergy(itemStack, rfToConsume, false);
            player.setPositionAndUpdate(targetX, targetY, targetZ);
            player.addChatMessage(EnumChatFormatting.DARK_GREEN + "Teleported.");
          }
        } else {
          player.addChatMessage(EnumChatFormatting.DARK_RED + "Not enough energy.");
        }
      } else {
        player.addChatMessage(
            EnumChatFormatting.DARK_RED + "Warp point is not set for this world.");
      }
    }

    return itemStack;
  }
 @Override
 public boolean onSkillTrigger(EntityPlayer player) {
   if (!canPlayerUseSkill(player)) return false;
   if (!player.worldObj.isRemote) {
     if (!player.worldObj.provider.canRespawnHere()) player.travelToDimension(0);
     BlockPos pos = player.worldObj.getSpawnPoint();
     while (!player.worldObj.isAirBlock(pos)) pos = pos.up(); // So you don't spawn in the floor.
     player.setPositionAndUpdate(pos.getX() + 0.5F, pos.getY() + 0.1F, pos.getZ() + 0.5F);
   }
   player.inventory.consumeInventoryItem(GenericSkills.heritageAmulet);
   player.worldObj.playSoundAtEntity(player, "mob.ghast.fireball", 1.0F, 1.0F);
   return true;
 }
  @Override
  public void trigger(World world, int x, int y, int z, EntityPlayer player) {
    int xChange = ((world.rand.nextInt(50) + 20) + x) - 35;
    int zChange = ((world.rand.nextInt(50) + 20) + z) - 35;

    int yChange = -1;

    for (int yy = 0; yy <= world.getActualHeight(); yy++) {
      if (world.getBlock(xChange, yy, zChange).isAir(world, xChange, yy, zChange)
          && world.getBlock(xChange, yy + 1, zChange).isAir(world, xChange, yy + 1, zChange)) {
        yChange = yy;
        break;
      }
    }
    if (yChange == -1) return;

    player.setPositionAndUpdate(xChange, yChange, zChange);
  }
 public boolean onBlockActivated(
     World par1World,
     int par2,
     int par3,
     int par4,
     EntityPlayer par5EntityPlayer,
     int par6,
     float par7,
     float par8,
     float par9) {
   ExtendedPlayer.get(par5EntityPlayer).addAXp(1);
   ExtendedPlayer props = ExtendedPlayer.get(par5EntityPlayer);
   if (par1World.isRemote) {
     par5EntityPlayer.addChatMessage(
         "Your current agility xp is " + String.valueOf(props.getAgilityxp()));
   }
   par5EntityPlayer.setPositionAndUpdate(par2, par3 - 20, par4);
   return true;
 }
  @SubscribeEvent
  public void entityHurt(LivingHurtEvent event) {
    if (event.entityLiving instanceof EntityPlayer
        && event.source == DamageSource.outOfWorld
        && ((EntityPlayer) event.entityLiving).posY < 0
        && isServer()) {
      EntityPlayer player = (EntityPlayer) event.entityLiving;
      if (!DiscoveryManager.itemUnlocked(QADiscoveries.Item.VACUUM.get().getKey(), player)
          && DiscoveryManager.areParentsUnlocked(
              QADiscoveries.Item.VACUUM.get().getKey(), player)) {
        String translate = "qa.aboutToVoid";
        player.addChatComponentMessage(
            new ChatComponentText(
                LocalizationUtils.translateLocalWithColours(translate, translate)));
        ChunkCoordinates spawn = player.getBedLocation(player.worldObj.provider.dimensionId);

        ChunkCoordinates portalEntrance =
            MinecraftServer.getServer()
                .worldServerForDimension(player.dimension)
                .getEntrancePortalLocation();
        if (portalEntrance != null && spawn == null) {
          spawn = portalEntrance;
        }

        if (spawn == null) {
          spawn = player.worldObj.getSpawnPoint();
        }

        int y = spawn.posY;

        while (!player.worldObj.isAirBlock(spawn.posX, y, spawn.posZ)) // Get top block
        y++;

        player.setPositionAndUpdate(spawn.posX, y, spawn.posZ);
        player.fallDistance = 0F;

        DiscoveryManager.unlockItem(QADiscoveries.Item.VACUUM.get().getKey(), player, false);
      }
    }
  }
  public ItemStack onItemRightClick(
      ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {
    if (!par2World.isRemote) {
      if (par1ItemStack.getTagCompound() == null)
        par1ItemStack.setTagCompound(new NBTTagCompound());

      dimensionIn = par2World.provider.dimensionId;
      NBTTagCompound tag = par1ItemStack.getTagCompound();
      this.currentCharge = tag.getInteger("CurrentCharge");
      state = tag.getBoolean("state");
      isSet = tag.getBoolean("isSet");
      x = tag.getInteger("posX");
      y = tag.getInteger("posY");
      z = tag.getInteger("posZ");

      if (par3EntityPlayer.isSneaking() && !par2World.isRemote) {
        if (state == false) {

          par3EntityPlayer.addChatMessage("Recall Mode Activated");
          state = true;
          tag.setBoolean("state", state);
          return par1ItemStack;
        }
        if (state == true) {
          par3EntityPlayer.addChatMessage("Mark Mode Activated");
          state = false;
          tag.setBoolean("state", state);
          return par1ItemStack;
        }
      }
      if (!par3EntityPlayer.isSneaking()) {
        if (this.currentCharge < 100) {
          par3EntityPlayer.addChatMessage("Not enough charge.");

          return par1ItemStack;
        }
        if (this.currentCharge >= 100) {

          if (state == false) {

            if (isSet == true) {
              World otherWorld =
                  MinecraftServer.getServer().worldServerForDimension(tag.getInteger("Dimension"));
              otherWorld.setBlock(
                  tag.getInteger("posX"), tag.getInteger("posY"), tag.getInteger("posZ"), 0);
              this.x = (int) par3EntityPlayer.posX;
              this.y = (int) par3EntityPlayer.posY;
              this.z = (int) par3EntityPlayer.posZ;
              par2World.setBlock(x, y, z, MysticAdditions.markblockid);
              this.currentCharge -= 100;

              tag.setInteger("CurrentCharge", this.currentCharge);
            }
            if (isSet == false) {

              this.x = (int) par3EntityPlayer.posX;
              this.y = (int) par3EntityPlayer.posY;
              this.z = (int) par3EntityPlayer.posZ;
              par2World.setBlock(x, y, z, MysticAdditions.markblockid);
              this.currentCharge -= 100;

              tag.setInteger("CurrentCharge", this.currentCharge);

              isSet = true;
              tag.setBoolean("isSet", isSet);
            }

            tag.setInteger("posX", x);
            tag.setInteger("posY", y);
            tag.setInteger("posZ", z);
            tag.setInteger("Dimension", par2World.provider.dimensionId);
            this.setItemDamageByCharge(par1ItemStack);
            return par1ItemStack;
          }
          if (state == true) {
            if (x == 0 && y == 0 && z == 0) {
              return par1ItemStack;
            }
            par3EntityPlayer.travelToDimension(tag.getInteger("Dimension"));
            par3EntityPlayer.setPositionAndUpdate(x, y, z);
            par3EntityPlayer.fallDistance = 0;
            this.currentCharge -= 100;

            tag.setInteger("CurrentCharge", this.currentCharge);
            this.setItemDamageByCharge(par1ItemStack);
            return par1ItemStack;
          }
        }
      }
    }
    return par1ItemStack;
  }
  @Override
  public ItemStack onItemRightClick(
      ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {
    PropertyDoom doom = PropertyDoom.get(par3EntityPlayer);

    if (!par3EntityPlayer.isSneaking()
        || !TragicWeapon.canUseAbility(doom, TragicConfig.doomAbilityCost[5])) {
      ArrowNockEvent event = new ArrowNockEvent(par3EntityPlayer, par1ItemStack);
      MinecraftForge.EVENT_BUS.post(event);
      if (event.isCanceled()) return event.result;

      if (par3EntityPlayer.capabilities.isCreativeMode
          || par3EntityPlayer.inventory.hasItem(Items.arrow)) {
        par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack));
      }
    } else {
      if (TragicWeapon.getStackCooldown(par1ItemStack) == 0 && TragicConfig.doomAbility[8]) {
        float f = 1.0F;
        float f1 =
            par3EntityPlayer.prevRotationPitch
                + (par3EntityPlayer.rotationPitch - par3EntityPlayer.prevRotationPitch) * f;
        float f2 =
            par3EntityPlayer.prevRotationYaw
                + (par3EntityPlayer.rotationYaw - par3EntityPlayer.prevRotationYaw) * f;
        double d0 =
            par3EntityPlayer.prevPosX + (par3EntityPlayer.posX - par3EntityPlayer.prevPosX) * f;
        double d1 =
            par3EntityPlayer.prevPosY
                + (par3EntityPlayer.posY - par3EntityPlayer.prevPosY) * f
                + (par3EntityPlayer.worldObj.isRemote
                    ? par3EntityPlayer.getEyeHeight() - par3EntityPlayer.getDefaultEyeHeight()
                    : par3EntityPlayer
                        .getEyeHeight()); // isRemote check to revert changes to ray trace position
        // due to adding the eye height clientside and player
        // yOffset differences
        double d2 =
            par3EntityPlayer.prevPosZ + (par3EntityPlayer.posZ - par3EntityPlayer.prevPosZ) * f;
        Vec3 vec3 = Vec3.createVectorHelper(d0, d1, d2);
        float f3 = MathHelper.cos(-f2 * 0.017453292F - (float) Math.PI);
        float f4 = MathHelper.sin(-f2 * 0.017453292F - (float) Math.PI);
        float f5 = -MathHelper.cos(-f1 * 0.017453292F);
        float f6 = MathHelper.sin(-f1 * 0.017453292F);
        float f7 = f4 * f5;
        float f8 = f3 * f5;
        double d3 = 50.0D;

        if (par3EntityPlayer instanceof EntityPlayerMP) {
          d3 =
              ((EntityPlayerMP) par3EntityPlayer).theItemInWorldManager.getBlockReachDistance()
                  + 46.0;
        }

        Vec3 vec31 = vec3.addVector(f7 * d3, f6 * d3, f8 * d3);
        MovingObjectPosition mop =
            par3EntityPlayer.worldObj.func_147447_a(vec3, vec31, true, false, true);

        if (mop == null) {
          if (!par2World.isRemote)
            par3EntityPlayer.addChatMessage(new ChatComponentText("Out of range to teleport to!"));
          return par1ItemStack;
        }

        if (mop.typeOfHit == MovingObjectType.BLOCK
            && par3EntityPlayer instanceof EntityPlayerMP
            && ((EntityPlayerMP) par3EntityPlayer)
                .playerNetServerHandler
                .func_147362_b()
                .isChannelOpen()) {
          if (par3EntityPlayer.isRiding()) par3EntityPlayer.mountEntity((Entity) null);

          double d4 = WorldHelper.getXPositionFromSide(mop.sideHit, mop.hitVec.xCoord);
          double d5 = WorldHelper.getYPositionFromSide(mop.sideHit, mop.hitVec.yCoord);
          double d6 = WorldHelper.getZPositionFromSide(mop.sideHit, mop.hitVec.zCoord);

          par3EntityPlayer.setPositionAndUpdate(d4, d5, d6);
          par3EntityPlayer.fallDistance = 0.0F;
          if (!par3EntityPlayer.capabilities.isCreativeMode)
            doom.increaseDoom(-TragicConfig.doomAbilityCost[8]);
          TragicWeapon.setStackCooldown(par1ItemStack, 5);
        }
      }
    }
    return par1ItemStack;
  }