@EventHandler(priority = EventPriority.HIGHEST)
  public void onPlayerTeleport(PlayerTeleportEvent event) {
    final Player player = event.getPlayer();
    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
    // Check absolute value to account for negatives
    if (Math.abs(event.getTo().getX()) >= MAX_XY_COORD
        || Math.abs(event.getTo().getZ()) >= MAX_XY_COORD) {
      event.setCancelled(true); // illegal position, cancel it
    }

    if (!TFM_AdminList.isSuperAdmin(player) && playerdata.isFrozen()) {
      TFM_Util.setFlying(player, true);
      event.setTo(playerdata.getFreezeLocation());
      return; // Don't process adminworld validation
    }

    TFM_AdminWorld.getInstance().validateMovement(event);
  }
  @EventHandler(priority = EventPriority.HIGH)
  public void onPlayerInteract(PlayerInteractEvent event) {
    final Player player = event.getPlayer();
    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);

    switch (event.getAction()) {
      case RIGHT_CLICK_AIR:
      case RIGHT_CLICK_BLOCK:
        {
          switch (event.getMaterial()) {
            case WATER_BUCKET:
              {
                if (TFM_AdminList.isSuperAdmin(player)
                    || TFM_ConfigEntry.ALLOW_WATER_PLACE.getBoolean()) {
                  break;
                }

                player
                    .getInventory()
                    .setItem(
                        player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
                player.sendMessage(ChatColor.GRAY + "Water buckets are currently disabled.");
                event.setCancelled(true);
                break;
              }

            case LAVA_BUCKET:
              {
                if (TFM_AdminList.isSuperAdmin(player)
                    || TFM_ConfigEntry.ALLOW_LAVA_PLACE.getBoolean()) {
                  break;
                }

                player
                    .getInventory()
                    .setItem(
                        player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
                player.sendMessage(ChatColor.GRAY + "Lava buckets are currently disabled.");
                event.setCancelled(true);
                break;
              }

            case EXPLOSIVE_MINECART:
              {
                if (TFM_ConfigEntry.ALLOW_TNT_MINECARTS.getBoolean()) {
                  break;
                }

                player.getInventory().clear(player.getInventory().getHeldItemSlot());
                player.sendMessage(ChatColor.GRAY + "TNT minecarts are currently disabled.");
                event.setCancelled(true);
                break;
              }
          }
          break;
        }

      case LEFT_CLICK_AIR:
      case LEFT_CLICK_BLOCK:
        {
          switch (event.getMaterial()) {
            case STICK:
              {
                if (!TFM_AdminList.isSuperAdmin(player)) {
                  break;
                }

                event.setCancelled(true);

                final Location location =
                    TFM_DepreciationAggregator.getTargetBlock(player, null, 5).getLocation();
                final List<RollbackEntry> entries =
                    TFM_RollbackManager.getEntriesAtLocation(location);

                if (entries.isEmpty()) {
                  TFM_Util.playerMsg(player, "No block edits at that location.");
                  break;
                }

                TFM_Util.playerMsg(
                    player,
                    "Block edits at ("
                        + ChatColor.WHITE
                        + "x"
                        + location.getBlockX()
                        + ", y"
                        + location.getBlockY()
                        + ", z"
                        + location.getBlockZ()
                        + ChatColor.BLUE
                        + ")"
                        + ChatColor.WHITE
                        + ":",
                    ChatColor.BLUE);
                for (RollbackEntry entry : entries) {
                  TFM_Util.playerMsg(
                      player,
                      " - "
                          + ChatColor.BLUE
                          + entry.author
                          + " "
                          + entry.getType()
                          + " "
                          + StringUtils.capitalize(entry.getMaterial().toString().toLowerCase())
                          + (entry.data == 0 ? "" : ":" + entry.data));
                }

                break;
              }

            case BONE:
              {
                if (!playerdata.mobThrowerEnabled()) {
                  break;
                }

                Location player_pos = player.getLocation();
                Vector direction = player_pos.getDirection().normalize();

                LivingEntity rezzed_mob =
                    (LivingEntity)
                        player
                            .getWorld()
                            .spawnEntity(
                                player_pos.add(direction.multiply(2.0)),
                                playerdata.mobThrowerCreature());
                rezzed_mob.setVelocity(direction.multiply(playerdata.mobThrowerSpeed()));
                playerdata.enqueueMob(rezzed_mob);

                event.setCancelled(true);
                break;
              }

            case SULPHUR:
              {
                if (!playerdata.isMP44Armed()) {
                  break;
                }

                event.setCancelled(true);

                if (playerdata.toggleMP44Firing()) {
                  playerdata.startArrowShooter(TotalFreedomMod.plugin);
                } else {
                  playerdata.stopArrowShooter();
                }
                break;
              }

            case BLAZE_ROD:
              {
                if (!TFM_ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) {
                  break;
                }

                if (!TFM_AdminList.isSeniorAdmin(player, true)) {
                  break;
                }

                event.setCancelled(true);
                Block targetBlock;

                if (event.getAction().equals(Action.LEFT_CLICK_AIR)) {
                  targetBlock = TFM_DepreciationAggregator.getTargetBlock(player, null, 120);
                } else {
                  targetBlock = event.getClickedBlock();
                }

                if (targetBlock == null) {
                  player.sendMessage("Can't resolve target block.");
                  break;
                }

                player.getWorld().createExplosion(targetBlock.getLocation(), 4F, true);
                player.getWorld().strikeLightning(targetBlock.getLocation());

                break;
              }

            case CARROT:
              {
                if (!TFM_ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) {
                  break;
                }

                if (!TFM_AdminList.isSeniorAdmin(player, true)) {
                  break;
                }

                Location location = player.getLocation().clone();

                Vector playerPostion = location.toVector().add(new Vector(0.0, 1.65, 0.0));
                Vector playerDirection = location.getDirection().normalize();

                double distance = 150.0;
                Block targetBlock =
                    TFM_DepreciationAggregator.getTargetBlock(
                        player, null, Math.round((float) distance));
                if (targetBlock != null) {
                  distance = location.distance(targetBlock.getLocation());
                }

                final List<Block> affected = new ArrayList<Block>();

                Block lastBlock = null;
                for (double offset = 0.0; offset <= distance; offset += (distance / 25.0)) {
                  Block block =
                      playerPostion
                          .clone()
                          .add(playerDirection.clone().multiply(offset))
                          .toLocation(player.getWorld())
                          .getBlock();

                  if (!block.equals(lastBlock)) {
                    if (block.isEmpty()) {
                      affected.add(block);
                      block.setType(Material.TNT);
                    } else {
                      break;
                    }
                  }

                  lastBlock = block;
                }

                new BukkitRunnable() {
                  @Override
                  public void run() {
                    for (Block tntBlock : affected) {
                      TNTPrimed tnt =
                          tntBlock.getWorld().spawn(tntBlock.getLocation(), TNTPrimed.class);
                      tnt.setFuseTicks(5);
                      tntBlock.setType(Material.AIR);
                    }
                  }
                }.runTaskLater(TotalFreedomMod.plugin, 30L);

                event.setCancelled(true);
                break;
              }

            case RAW_FISH:
              {
                final int RADIUS_HIT = 5;
                final int STRENGTH = 4;

                // Clownfish
                if (TFM_DepreciationAggregator.getData_MaterialData(event.getItem().getData())
                    == 2) {
                  if (TFM_AdminList.isSeniorAdmin(player, true)
                      || TFM_AdminList.isTelnetAdmin(player, true)) {
                    boolean didHit = false;

                    final Location playerLoc = player.getLocation();
                    final Vector playerLocVec = playerLoc.toVector();

                    final List<Player> players = player.getWorld().getPlayers();
                    for (final Player target : players) {
                      if (target == player) {
                        continue;
                      }

                      final Location targetPos = target.getLocation();
                      final Vector targetPosVec = targetPos.toVector();

                      try {
                        if (targetPosVec.distanceSquared(playerLocVec)
                            < (RADIUS_HIT * RADIUS_HIT)) {
                          TFM_Util.setFlying(player, false);
                          target.setVelocity(
                              targetPosVec.subtract(playerLocVec).normalize().multiply(STRENGTH));
                          didHit = true;
                        }
                      } catch (IllegalArgumentException ex) {
                      }
                    }

                    if (didHit) {
                      final Sound[] sounds = Sound.values();
                      for (Sound sound : sounds) {
                        if (sound.toString().contains("HIT")) {
                          playerLoc
                              .getWorld()
                              .playSound(
                                  randomOffset(playerLoc, 5.0),
                                  sound,
                                  100.0f,
                                  randomDoubleRange(0.5, 2.0).floatValue());
                        }
                      }
                    }
                  } else {
                    final StringBuilder msg = new StringBuilder();
                    final char[] chars = (player.getName() + " is a clown.").toCharArray();
                    for (char c : chars) {
                      msg.append(TFM_Util.randomChatColor()).append(c);
                    }
                    TFM_Util.bcastMsg(msg.toString());

                    player.getInventory().getItemInHand().setType(Material.POTATO_ITEM);
                  }

                  event.setCancelled(true);
                  break;
                }
              }
          }
          break;
        }
    }
  }
  @EventHandler(priority = EventPriority.NORMAL)
  public void onPlayerMove(PlayerMoveEvent event) {
    final Location from = event.getFrom();
    final Location to = event.getTo();
    try {
      if (from.getWorld() == to.getWorld() && from.distanceSquared(to) < (0.0001 * 0.0001)) {
        // If player just rotated, but didn't move, don't process this event.
        return;
      }
    } catch (IllegalArgumentException ex) {
    }

    if (!TFM_AdminWorld.getInstance().validateMovement(event)) {
      return;
    }

    final Player player = event.getPlayer();
    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);

    for (Entry<Player, Double> fuckoff : TotalFreedomMod.fuckoffEnabledFor.entrySet()) {
      Player fuckoffPlayer = fuckoff.getKey();

      if (fuckoffPlayer.equals(player) || !fuckoffPlayer.isOnline()) {
        continue;
      }

      double fuckoffRange = fuckoff.getValue();

      Location playerLocation = player.getLocation();
      Location fuckoffLocation = fuckoffPlayer.getLocation();

      double distanceSquared;
      try {
        distanceSquared = playerLocation.distanceSquared(fuckoffLocation);
      } catch (IllegalArgumentException ex) {
        continue;
      }

      if (distanceSquared < (fuckoffRange * fuckoffRange)) {
        event.setTo(
            fuckoffLocation
                .clone()
                .add(
                    playerLocation
                        .subtract(fuckoffLocation)
                        .toVector()
                        .normalize()
                        .multiply(fuckoffRange * 1.1)));
        break;
      }
    }

    // Freeze
    if (!TFM_AdminList.isSuperAdmin(player) && playerdata.isFrozen()) {
      TFM_Util.setFlying(player, true);
      event.setTo(playerdata.getFreezeLocation());
    }

    if (playerdata.isCaged()) {
      Location targetPos = player.getLocation().add(0, 1, 0);

      boolean outOfCage;
      if (!targetPos.getWorld().equals(playerdata.getCagePos().getWorld())) {
        outOfCage = true;
      } else {
        outOfCage = targetPos.distanceSquared(playerdata.getCagePos()) > (2.5 * 2.5);
      }

      if (outOfCage) {
        playerdata.setCaged(
            true,
            targetPos,
            playerdata.getCageMaterial(TFM_PlayerData.CageLayer.OUTER),
            playerdata.getCageMaterial(TFM_PlayerData.CageLayer.INNER));
        playerdata.regenerateHistory();
        playerdata.clearHistory();
        TFM_Util.buildHistory(targetPos, 2, playerdata);
        TFM_Util.generateHollowCube(
            targetPos, 2, playerdata.getCageMaterial(TFM_PlayerData.CageLayer.OUTER));
        TFM_Util.generateCube(
            targetPos, 1, playerdata.getCageMaterial(TFM_PlayerData.CageLayer.INNER));
      }
    }

    if (playerdata.isOrbiting()) {
      if (player.getVelocity().length() < playerdata.orbitStrength() * (2.0 / 3.0)) {
        player.setVelocity(new Vector(0, playerdata.orbitStrength(), 0));
      }
    }

    if (TFM_Jumppads.getMode().isOn()) {
      TFM_Jumppads.PlayerMoveEvent(event);
    }

    if (!(TFM_ConfigEntry.LANDMINES_ENABLED.getBoolean()
        && TFM_ConfigEntry.ALLOW_EXPLOSIONS.getBoolean())) {
      return;
    }

    final Iterator<Command_landmine.TFM_LandmineData> landmines =
        Command_landmine.TFM_LandmineData.landmines.iterator();
    while (landmines.hasNext()) {
      final Command_landmine.TFM_LandmineData landmine = landmines.next();

      final Location location = landmine.location;
      if (location.getBlock().getType() != Material.TNT) {
        landmines.remove();
        continue;
      }

      if (landmine.player.equals(player)) {
        break;
      }

      if (!player.getWorld().equals(location.getWorld())) {
        continue;
      }

      if (!(player.getLocation().distanceSquared(location)
          <= (landmine.radius * landmine.radius))) {
        break;
      }

      landmine.location.getBlock().setType(Material.AIR);

      final TNTPrimed tnt1 = location.getWorld().spawn(location, TNTPrimed.class);
      tnt1.setFuseTicks(40);
      tnt1.setPassenger(player);
      tnt1.setVelocity(new Vector(0.0, 2.0, 0.0));

      final TNTPrimed tnt2 = location.getWorld().spawn(player.getLocation(), TNTPrimed.class);
      tnt2.setFuseTicks(1);

      player.setGameMode(GameMode.SURVIVAL);
      landmines.remove();
    }
  }