@ArenaEventHandler(suppressCastWarnings = true, priority = EventPriority.LOW)
  public void onEntityDamageEvent(EntityDamageEvent event) {
    if (!(event.getEntity() instanceof Player)) return;
    final TransitionOptions to = transitionOptions.getOptions(match.getMatchState());
    if (to == null) return;
    final PVPState pvp = to.getPVP();
    if (pvp == null) return;
    final ArenaPlayer target = BattleArena.toArenaPlayer((Player) event.getEntity());
    if (pvp == PVPState.INVINCIBLE) {
      /// all damage is cancelled
      target.setFireTicks(0);
      handler.setDamage(event, 0);
      event.setCancelled(true);
      return;
    }
    if (!(event instanceof EntityDamageByEntityEvent)) {
      return;
    }

    final Entity damagerEntity = ((EntityDamageByEntityEvent) event).getDamager();
    ArenaPlayer damager;
    switch (pvp) {
      case ON:
        ArenaTeam targetTeam = match.getTeam(target);
        if (targetTeam == null
            || !targetTeam.hasAliveMember(target)) // / We dont care about dead players
        return;
        damager = DmgDeathUtil.getPlayerCause(damagerEntity);
        if (damager == null) { // / damage from some source, its not pvp though. so we dont care
          return;
        }
        ArenaTeam t = match.getTeam(damager);
        if (t != null && t.hasMember(target)) { // / attacker is on the same team
          event.setCancelled(true);
        } else { /// different teams... lets make sure they can actually hit
          event.setCancelled(false);
        }
        break;
      case OFF:
        damager = DmgDeathUtil.getPlayerCause(damagerEntity);
        if (damager != null) { // / damage done from a player
          handler.setDamage(event, 0);
          event.setCancelled(true);
        }
        break;
      default:
        break;
    }
  }
 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 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);
  }