@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
  public void onPlayerSprint(PlayerToggleSprintEvent event) {
    Player player = event.getPlayer();
    if (!player.isSprinting()) {
      BendingPlayer bender = BendingPlayer.getBendingPlayer(player);
      if (bender.isBender(BendingElement.AIR)
          && EntityTools.canBendPassive(player, BendingElement.AIR)) {
        AirSpeed ab =
            new AirSpeed(AbilityManager.getManager().getRegisteredAbility(AirSpeed.NAME), player);
        if (ab.canBeInitialized()) {
          ab.start();
          if (ab.getState() != BendingAbilityState.START
              && ab.getState() != BendingAbilityState.ENDED) {
            AbilityManager.getManager().addInstance(ab);
            return;
          }
        }
      }

      if (bender.isBender(BendingElement.MASTER)
          && EntityTools.canBendPassive(player, BendingElement.MASTER)) {
        Speed ab = new Speed(AbilityManager.getManager().getRegisteredAbility(Speed.NAME), player);
        if (ab.canBeInitialized()) {
          ab.start();
          if (ab.getState() != BendingAbilityState.START
              && ab.getState() != BendingAbilityState.ENDED) {
            AbilityManager.getManager().addInstance(ab);
            return;
          }
        }
      }
    }
  }
  @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
  public void onPlayerChat(AsyncPlayerChatEvent event) {
    if (!(Settings.CHAT_ENABLED)) {
      return;
    }
    if (!(Settings.CHAT_COMPATIBILITY)) {

      Player player = event.getPlayer();
      ChatColor color = ChatColor.WHITE;

      if (Settings.CHAT_COLORED) {
        if (player.hasPermission("bending.admin.avatarstate")) {
          color = PluginTools.getColor(Settings.getColor(BendingElement.ENERGY));
        } else {
          BendingPlayer bender = BendingPlayer.getBendingPlayer(player);
          List<BendingElement> els = bender.getBendingTypes();
          if ((els != null) && els.isEmpty()) {
            color = PluginTools.getColor(Settings.getColor(els.get(0)));
          }
        }
      }
      String format = Settings.CHAT_FORMAT;
      format = format.replace("<message>", "%2$s");
      format = format.replace("<name>", color + player.getDisplayName() + ChatColor.RESET);
      event.setFormat(format);
    }
  }
  @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
  public void onPlayerLogin(PlayerLoginEvent event) {
    Player player = event.getPlayer();

    Bending.getInstance().getBendingDatabase().lease(player.getUniqueId());

    BendingPlayer bender = BendingPlayer.getBendingPlayer(player);

    if (!(Settings.CHAT_COMPATIBILITY) && (Settings.CHAT_ENABLED)) {
      player.setDisplayName(player.getName());
    }

    if ((Settings.CHAT_COMPATIBILITY) && (Settings.CHAT_ENABLED)) {
      ChatColor color = ChatColor.WHITE;
      if (Settings.CHAT_COLORED) {
        if (player.hasPermission("bending.avatar")) {
          color = PluginTools.getColor(Settings.getColor(BendingElement.ENERGY));
        } else {
          List<BendingElement> els = bender.getBendingTypes();
          if ((els != null) && !els.isEmpty()) {
            color = PluginTools.getColor(Settings.getColor(els.get(0)));
          }
        }
      }
      player.setDisplayName("<" + color + player.getName() + ChatColor.WHITE + ">");
    }
  }
 @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
 public void onPlayerScoreboard(PlayerJoinEvent event) {
   if (Settings.USE_SCOREBOARD) {
     BendingPlayer bender = BendingPlayer.getBendingPlayer(event.getPlayer());
     if (bender != null) {
       bender.loadScoreboard();
     }
   }
 }
  public Ripple(Player player, BendingAbility ability, Location origin, Vector direction) {
    this.player = player;
    this.ability = ability;
    if (origin == null) return;
    this.direction = direction.clone().normalize();
    this.origin = origin.clone();
    this.location = origin.clone();

    initializeLocations();
    maxstep = locations.size();

    bender = BendingPlayer.getBendingPlayer(player);
  }
  @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
  public void onPlayerQuit(PlayerQuitEvent event) {
    if (EarthArmor.hasEarthArmor(event.getPlayer())) {
      event.getPlayer().removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE);
    }
    if (Suffocate.isTargeted(event.getPlayer())) {
      Suffocate.getSuffocateByTarget(event.getPlayer()).remove();
    }
    // Unregister scoreboard
    BendingPlayer bender = BendingPlayer.getBendingPlayer(event.getPlayer());
    if (bender != null) {
      bender.unloadScoreboard();
    }

    Bending.getInstance().getBendingDatabase().release(event.getPlayer().getUniqueId());
  }
  @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
  public void onBendingDamage(BendingDamageEvent event) {
    if (event.getEntity() instanceof Player) {
      Player player = (Player) event.getEntity();
      BendingPlayer bender = BendingPlayer.getBendingPlayer(player);
      if (bender == null) {
        return;
      }

      if (bender.hasPath(BendingPath.TOUGH)) {
        event.setDamage(event.getDamage() * 0.9);
      }
      if (bender.hasAffinity(BendingAffinity.SWORD) && player.isBlocking()) {
        event.setDamage(event.getDamage() * 0.60);
      }
    }
  }
  @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
  public void onPlayerDamage(EntityDamageEvent event) {
    if (event.getEntity() instanceof Player) {
      Player player = (Player) event.getEntity();
      BendingPlayer bender = BendingPlayer.getBendingPlayer(player);
      String ability = bender.getAbility();

      if (event.getCause() == DamageCause.FALL) {
        BendingPassiveAbility ab = null;
        if (bender != null && bender.isBender(BendingElement.EARTH)) {
          ab =
              new EarthPassive(
                  AbilityManager.getManager().getRegisteredAbility(EarthPassive.NAME), player);
          if (ab.start()) {
            AbilityManager.getManager().addInstance(ab);
            player.setFallDistance(0);
            event.setDamage(0);
            event.setCancelled(true);
            return;
          }

          if (MetalWire.hasNoFallDamage(player)) {
            player.setFallDistance(0);
            event.setDamage(0);
            event.setCancelled(true);
            return;
          }
        }

        if (bender != null
            && bender.isBender(BendingElement.AIR)
            && EntityTools.canBendPassive(player, BendingElement.AIR)) {
          if (AirBurst.NAME.equals(ability)) {
            BendingActiveAbility burst =
                AbilityManager.getManager().buildAbility(AirBurst.NAME, player);
            if (burst.canBeInitialized()) {
              burst.fall();
              if (burst.getState() != BendingAbilityState.START
                  && burst.getState() != BendingAbilityState.ENDED) {
                AbilityManager.getManager().addInstance(burst);
              }
            }
          }
          player.setFallDistance(0);
          event.setDamage(0);
          event.setCancelled(true);
          return;
        }

        if (!event.isCancelled() && EntityTools.isBender(player, BendingElement.WATER)) {
          ab =
              new WaterPassive(
                  AbilityManager.getManager().getRegisteredAbility(WaterPassive.NAME), player);
          AbilityManager.getManager().addInstance(ab);
          if (ab.start()) {
            player.setFallDistance(0);
            event.setDamage(0);
            event.setCancelled(true);
            return;
          }
        }

        if (!event.isCancelled()
            && bender.isBender(BendingElement.MASTER)
            && EntityTools.canBendPassive(player, BendingElement.MASTER)) {
          event.setDamage((int) (event.getDamage() * (Settings.MASTER_FALL_REDUCTION / 100.)));
          if (event.getEntity().getFallDistance() < 10) {
            event.setCancelled(true);
            return;
          }
        }

        if (!event.isCancelled() && EntityTools.isFallImmune(player)) {
          event.setCancelled(true);
          return;
        }
      }

      if (EntityTools.canBendPassive(player, BendingElement.FIRE)
          && EntityTools.isBender(player, BendingElement.FIRE)
          && ((event.getCause() == DamageCause.FIRE)
              || (event.getCause() == DamageCause.FIRE_TICK))) {
        event.setCancelled(!Enflamed.canBurn(player));
      }

      if (EntityTools.isBender(player, BendingElement.EARTH)
          && ((event.getCause() == DamageCause.SUFFOCATION)
              && TempBlock.isTempBlock(player.getEyeLocation().getBlock()))) {
        event.setDamage(0);
        event.setCancelled(true);
      }

      if (bender != null) {
        Map<Object, BendingAbility> instances =
            AbilityManager.getManager().getInstances(AvatarShield.NAME);
        if (instances.containsKey(player)) {
          AvatarShield ab = (AvatarShield) instances.get(player);
          if (ab.hit()) {
            event.setCancelled(true);
          }
        }
      }
    }
  }
  @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
  public void onPlayerSneak(PlayerToggleSneakEvent event) {
    Player player = event.getPlayer();
    if (player == null) {
      Bending.getInstance().getLogger().warning("Null player in PlayerSneak");
      return;
    }
    BendingPlayer bender = BendingPlayer.getBendingPlayer(player);
    if (Bloodbending.isBloodbended(player) || Concussion.getTarget(player) != null) {
      event.setCancelled(true);
      return;
    }

    String ability = EntityTools.getBendingAbility(player);
    RegisteredAbility register = AbilityManager.getManager().getRegisteredAbility(ability);
    if (!player.isSneaking()
        && ((ability == null) || (register == null) || !register.isShift())
        && (player.getGameMode() == GameMode.SURVIVAL
            || player.getGameMode() == GameMode.ADVENTURE
            || !player.isFlying())) {
      if (bender.isBender(BendingElement.WATER)
          && EntityTools.canBendPassive(player, BendingElement.WATER)
          && !WaterSpout.isBending(player)) {
        FastSwimming ab =
            new FastSwimming(
                AbilityManager.getManager().getRegisteredAbility(FastSwimming.NAME), player);
        if (ab.canBeInitialized()) {
          ab.start();
          if (ab.getState() != BendingAbilityState.START
              && ab.getState() != BendingAbilityState.ENDED) {
            AbilityManager.getManager().addInstance(ab);
            return;
          }
        }
      }
    }

    if (EntityTools.canBend(player, register) && !player.isSneaking()) {
      Map<Object, BendingAbility> abilities = AbilityManager.getManager().getInstances(ability);
      boolean shouldCreateNew = true;
      for (BendingAbility a : abilities.values()) {
        if (a.getPlayer().equals(player) && !((BendingActiveAbility) a).sneak()) {
          shouldCreateNew = false;
        }
      }
      if (shouldCreateNew) {
        BendingActiveAbility ab = AbilityManager.getManager().buildAbility(ability, player);
        if (ab == null) {
          Bending.getInstance()
              .getLogger()
              .log(
                  Level.SEVERE,
                  "Ability "
                      + ability
                      + " failed to construct with buildAbility for player "
                      + player.getName());
          return;
        }
        if (ab.canBeInitialized()) {
          ab.sneak();
          if (ab.getState() != BendingAbilityState.START
              && ab.getState() != BendingAbilityState.ENDED) {
            AbilityManager.getManager().addInstance(ab);
          }
        }
      }
    }
  }