public static void respawnClick(
     PlayerInteractEvent event, PlayerHolder am, Map<String, Integer> respawnTimer) {
   ArenaPlayer ap = BattleArena.toArenaPlayer(event.getPlayer());
   Integer id = respawnTimer.remove(ap.getName());
   Bukkit.getScheduler().cancelTask(id);
   Location loc =
       am.getSpawn(
           am.getTeam(ap).getIndex(),
           am.getParams().hasOptionAt(MatchState.ONSPAWN, TransitionOption.RANDOMRESPAWN));
   TeleportController.teleport(ap.getPlayer(), loc);
 }
  public static void teleportOut(
      PlayerHolder am,
      ArenaTeam team,
      ArenaPlayer player,
      TransitionOptions mo,
      int teamIndex,
      boolean insideArena,
      boolean onlyInMatch,
      boolean wipeInventory) {
    MatchParams mp = am.getParams();
    Location loc = null;
    ArenaLocation src = player.getCurLocation();
    final LocationType type;
    if (mo.hasOption(TransitionOption.TELEPORTTO)) {
      loc = mo.getTeleportToLoc();
      type = LocationType.CUSTOM;
    } else {
      type = LocationType.HOME;
      loc = player.getOldLocation();
      /// TODO
      /// This is a bit of a kludge, sometimes we are "teleporting them out"
      /// when they are already out... so need to rethink how this can happen and should it
      if (loc == null && src.getType() == LocationType.HOME) {
        loc = src.getLocation();
      }
    }
    player.clearOldLocation();
    if (loc == null) {
      Log.err(
          BattleArena.getNameAndVersion()
              + " Teleporting to a null location!  teleportTo="
              + mo.hasOption(TransitionOption.TELEPORTTO));
    }

    ArenaLocation dest = new ArenaLocation(AbstractAreaContainer.HOMECONTAINER, loc, type);
    ArenaPlayerTeleportEvent apte =
        new ArenaPlayerTeleportEvent(
            am.getParams().getType(), player, team, src, dest, TeleportDirection.OUT);
    movePlayer(player, apte, mp);
  }
  private static ArenaLocation getArenaLocation(
      PlayerHolder am, ArenaTeam team, ArenaPlayer player, TransitionOptions mo, int teamIndex) {
    final MatchParams mp = am.getParams();
    final boolean randomRespawn = mo.hasOption(TransitionOption.RANDOMRESPAWN);
    Location l;
    final boolean teleportWaitRoom = mo.shouldTeleportWaitRoom();
    final boolean teleportLobby = mo.shouldTeleportLobby();
    final boolean teleportSpectate = mo.shouldTeleportSpectate();
    final LocationType type;
    final PlayerHolder ph;
    if (Defaults.DEBUG_TRACE)
      Log.info(" teamindex = " + teamIndex + "   " + am.getClass().getSimpleName() + "  " + am);

    if (teleportWaitRoom) {
      if (mo.hasOption(TransitionOption.TELEPORTMAINWAITROOM)) {
        teamIndex = Defaults.MAIN_SPAWN;
      }
      ph = (am instanceof Match) ? ((Match) am).getArena().getWaitroom() : am;
      type = LocationType.WAITROOM;
      l = jitter(ph.getSpawn(teamIndex, randomRespawn), teamIndex);
    } else if (teleportLobby) {
      if (mo.hasOption(TransitionOption.TELEPORTMAINLOBBY)) {
        teamIndex = Defaults.MAIN_SPAWN;
      }
      ph = RoomController.getLobby(mp.getType());
      type = LocationType.LOBBY;
      l = jitter(RoomController.getLobbySpawn(teamIndex, mp.getType(), randomRespawn), 0);
    } else if (teleportSpectate) {
      ph = (am instanceof Match) ? ((Match) am).getArena().getSpectatorRoom() : am;
      type = LocationType.SPECTATE;
      l = jitter(ph.getSpawn(teamIndex, randomRespawn), teamIndex);
    } else { // They should teleportIn, aka to the Arena
      final Arena arena;
      if (am instanceof Arena) {
        arena = (Arena) am;
      } else if (am instanceof Match) {
        Match m = (Match) am;
        arena = m.getArena();
      } else {
        throw new IllegalStateException("[BA Error] Instance is " + am.getClass().getSimpleName());
      }
      ph = am;
      type = LocationType.ARENA;
      l = arena.getSpawn(teamIndex, false);
    }
    return new ArenaLocation(ph, l, type);
  }
  public static void teleport(
      PlayerHolder am, ArenaTeam team, ArenaPlayer player, TransitionOptions mo, int teamIndex) {
    player.markOldLocation();
    MatchParams mp = am.getParams();

    /// EnterWaitRoom is supposed to happen before the teleport in event, but it depends on the
    // result of a teleport
    /// Since we cant really tell the eventual result.. do our best guess
    ArenaLocation dest = getArenaLocation(am, team, player, mo, teamIndex);
    ArenaLocation src = player.getCurLocation();
    src.setLocation(player.getLocation());
    if (Defaults.DEBUG_TRACE)
      Log.info(" ########### @@ " + player.getCurLocation() + "  -->  " + am.getTeam(player));

    TeleportDirection td = calcTeleportDirection(player, src, dest);
    ArenaPlayerTeleportEvent apte =
        new ArenaPlayerTeleportEvent(mp.getType(), player, team, src, dest, td);

    movePlayer(player, apte, mp);
  }
 public DamageListener(PlayerHolder match) {
   this.transitionOptions = match.getParams().getTransitionOptions();
   this.match = match;
 }