@Override
  public String getDescription(Hero hero) {
    int level = hero.getSkillLevel(this);
    double chance =
        (SkillConfigManager.getUseSetting(hero, this, Setting.CHANCE.node(), 0.2, false)
                + (SkillConfigManager.getUseSetting(
                        hero, this, Setting.CHANCE_LEVEL.node(), 0.2, false)
                    * level))
            * 100;
    chance = chance > 0 ? chance : 0;
    double duration =
        (SkillConfigManager.getUseSetting(hero, this, Setting.DURATION.node(), 2000, false)
                + (level
                    * SkillConfigManager.getUseSetting(hero, this, "duration-increase", 0, false)))
            / 1000;
    duration = duration > 0 ? duration : 0;
    String description = getDescription().replace("$1", chance + "").replace("$2", duration + "");

    // COOLDOWN
    int cooldown =
        (SkillConfigManager.getUseSetting(hero, this, Setting.COOLDOWN.node(), 0, false)
                - SkillConfigManager.getUseSetting(
                        hero, this, Setting.COOLDOWN_REDUCE.node(), 0, false)
                    * hero.getSkillLevel(this))
            / 1000;
    if (cooldown > 0) {
      description += " CD:" + cooldown + "s";
    }
    return description;
  }
 @Override
 public ConfigurationSection getDefaultConfig() {
   ConfigurationSection node = super.getDefaultConfig();
   node.set(Setting.CHANCE.node(), 0.2);
   node.set(Setting.CHANCE_LEVEL.node(), 0.0);
   node.set(Setting.COOLDOWN.node(), 500);
   node.set(Setting.DURATION.node(), 2000);
   node.set("duration-increase", 0);
   node.set("exp-per-stun", 0);
   return node;
 }
  @Override
  public String getDescription(Hero hero) {
    int chance2x =
        (int)
            (SkillConfigManager.getUseSetting(hero, this, "chance-2x", 0.2, false) * 100
                + SkillConfigManager.getUseSetting(
                        hero, this, "added-chance-2x-per-level", 0.0, false)
                    * hero.getSkillLevel(this));
    int chance3x =
        (int)
            (SkillConfigManager.getUseSetting(hero, this, "chance-3x", 0.1, false) * 100
                + SkillConfigManager.getUseSetting(
                        hero, this, "added-chance-3x-per-level", 0.0, false)
                    * hero.getSkillLevel(this));
    String description =
        getDescription()
            .replace("$1", (100 - (chance2x + chance3x)) + "")
            .replace("$2", chance2x + "")
            .replace("$3", chance3x + "");

    // COOLDOWN
    int cooldown =
        (SkillConfigManager.getUseSetting(hero, this, Setting.COOLDOWN.node(), 0, false)
                - SkillConfigManager.getUseSetting(
                        hero, this, Setting.COOLDOWN_REDUCE.node(), 0, false)
                    * hero.getSkillLevel(this))
            / 1000;
    if (cooldown > 0) {
      description += " CD:" + cooldown + "s";
    }

    // MANA
    int mana =
        SkillConfigManager.getUseSetting(hero, this, Setting.MANA.node(), 10, false)
            - (SkillConfigManager.getUseSetting(hero, this, Setting.MANA_REDUCE.node(), 0, false)
                * hero.getSkillLevel(this));
    if (mana > 0) {
      description += " M:" + mana;
    }

    // HEALTH_COST
    int healthCost =
        SkillConfigManager.getUseSetting(hero, this, Setting.HEALTH_COST, 0, false)
            - (SkillConfigManager.getUseSetting(hero, this, Setting.HEALTH_COST_REDUCE, mana, true)
                * hero.getSkillLevel(this));
    if (healthCost > 0) {
      description += " HP:" + healthCost;
    }

    // STAMINA
    int staminaCost =
        SkillConfigManager.getUseSetting(hero, this, Setting.STAMINA.node(), 0, false)
            - (SkillConfigManager.getUseSetting(hero, this, Setting.STAMINA_REDUCE.node(), 0, false)
                * hero.getSkillLevel(this));
    if (staminaCost > 0) {
      description += " FP:" + staminaCost;
    }

    // DELAY
    int delay = SkillConfigManager.getUseSetting(hero, this, Setting.DELAY.node(), 0, false) / 1000;
    if (delay > 0) {
      description += " W:" + delay + "s";
    }

    // EXP
    int exp = SkillConfigManager.getUseSetting(hero, this, Setting.EXP.node(), 0, false);
    if (exp > 0) {
      description += " XP:" + exp;
    }
    return description;
  }
  @Override
  public String getDescription(Hero hero) {
    int bDmg = SkillConfigManager.getUseSetting(hero, this, "BaseTickDamage", 0, false);
    float bMulti = SkillConfigManager.getUseSetting(hero, this, "LevelMultiplier", 0, false);
    long duration = SkillConfigManager.getUseSetting(hero, this, Setting.DURATION, 12000, false);
    int damage = (int) (bMulti <= 0L ? bDmg : bDmg + bMulti * hero.getLevel());
    String newDmg = damage > 0 ? "Deals " + damage + " over " + duration / 1000D + " seconds" : "";

    String base =
        String.format("Encapsulate your target in ice for %s seconds. ", duration / 1000D);

    StringBuilder description = new StringBuilder(base + newDmg);

    // Additional descriptive-ness of skill settings
    int initCD = SkillConfigManager.getUseSetting(hero, this, Setting.COOLDOWN.node(), 0, false);
    int redCD =
        SkillConfigManager.getUseSetting(hero, this, Setting.COOLDOWN_REDUCE.node(), 0, false)
            * hero.getSkillLevel(this);
    int CD = (initCD - redCD) / 1000;
    if (CD > 0) {
      description.append(" CD:" + CD + "s");
    }

    int initM = SkillConfigManager.getUseSetting(hero, this, Setting.MANA.node(), 0, false);
    int redM =
        SkillConfigManager.getUseSetting(hero, this, Setting.MANA_REDUCE.node(), 0, false)
            * hero.getSkillLevel(this);
    int manaUse = initM - redM;
    if (manaUse > 0) {
      description.append(" M:" + manaUse);
    }

    int initHP = SkillConfigManager.getUseSetting(hero, this, Setting.HEALTH_COST, 0, false);
    int redHP =
        SkillConfigManager.getUseSetting(hero, this, Setting.HEALTH_COST_REDUCE, 0, true)
            * hero.getSkillLevel(this);
    int HPCost = initHP - redHP;
    if (HPCost > 0) {
      description.append(" HP:" + HPCost);
    }

    int initF = SkillConfigManager.getUseSetting(hero, this, Setting.STAMINA.node(), 0, false);
    int redF =
        SkillConfigManager.getUseSetting(hero, this, Setting.STAMINA_REDUCE.node(), 0, false)
            * hero.getSkillLevel(this);
    int foodCost = initF - redF;
    if (foodCost > 0) {
      description.append(" FP:" + foodCost);
    }

    int delay = SkillConfigManager.getUseSetting(hero, this, Setting.DELAY.node(), 0, false) / 1000;
    if (delay > 0) {
      description.append(" W:" + delay);
    }

    int exp = SkillConfigManager.getUseSetting(hero, this, Setting.EXP.node(), 0, false);
    if (exp > 0) {
      description.append(" XP:" + exp);
    }

    return description.toString();
  }
    @EventHandler()
    public void onEntityDamage(EntityDamageEvent event) {
      if (event.isCancelled()
          || event.getDamage() == 0
          || event.getCause() != DamageCause.ENTITY_ATTACK
          || !(event.getEntity() instanceof Player)
          || !(event instanceof EntityDamageByEntityEvent)) {
        return;
      }
      EntityDamageByEntityEvent edby = (EntityDamageByEntityEvent) event;
      Player tPlayer = (Player) event.getEntity();
      if (edby.getDamager() instanceof Player) {
        Player player = (Player) edby.getDamager();
        Hero hero = plugin.getCharacterManager().getHero(player);

        if (hero.hasEffect("Basher")) {
          if (hero.getCooldown("Basher") == null
              || hero.getCooldown("Basher") <= System.currentTimeMillis()) {
            double chance =
                (double)
                        SkillConfigManager.getUseSetting(
                            hero, skill, Setting.CHANCE.node(), 0.2, false)
                    + (hero.getSkillLevel(skill)
                        * SkillConfigManager.getUseSetting(
                            hero, skill, Setting.CHANCE_LEVEL.node(), 0.0, false));
            chance = chance > 0 ? chance : 0;
            long cooldown =
                (long)
                    (SkillConfigManager.getUseSetting(
                            hero, skill, Setting.COOLDOWN.node(), 0, false)
                        - SkillConfigManager.getUseSetting(
                                hero, skill, Setting.COOLDOWN_REDUCE.node(), 0, false)
                            * hero.getSkillLevel(skill));
            cooldown = cooldown > 0 ? cooldown : 0;
            hero.setCooldown("Basher", cooldown + System.currentTimeMillis());
            if (Math.random() <= chance) {
              long duration =
                  (long)
                      (SkillConfigManager.getUseSetting(
                              hero, skill, Setting.DURATION.node(), 2000, false)
                          + (hero.getSkillLevel(skill)
                              * SkillConfigManager.getUseSetting(
                                  hero, skill, "duration-increase", 0, false)));
              duration = duration > 0 ? duration : 0;
              plugin
                  .getCharacterManager()
                  .getHero(tPlayer)
                  .addEffect(new StunEffect(basher, duration));
              double exp = SkillConfigManager.getUseSetting(hero, skill, "exp-per-stun", 0, false);
              if (exp > 0) {
                if (hero.hasParty()) {
                  hero.getParty().gainExp(exp, ExperienceType.SKILL, player.getLocation());
                } else {
                  hero.gainExp(exp, ExperienceType.SKILL);
                }
              }
              return;
            }
          }
        }
      } else if (edby.getDamager() instanceof Projectile) {
        if (((Projectile) edby.getDamager()).getShooter() instanceof Player) {
          Player player = (Player) ((Projectile) edby.getDamager()).getShooter();
          Hero hero = plugin.getCharacterManager().getHero(player);

          if (hero.hasEffect("Basher")) {
            if (hero.getCooldown("Basher") == null
                || hero.getCooldown("Basher") <= System.currentTimeMillis()) {
              double chance =
                  (double)
                          SkillConfigManager.getUseSetting(
                              hero, skill, Setting.CHANCE.node(), 0.2, false)
                      + (hero.getSkillLevel(skill)
                          * SkillConfigManager.getUseSetting(
                              hero, skill, Setting.CHANCE_LEVEL.node(), 0.0, false));
              chance = chance > 0 ? chance : 0;
              long cooldown =
                  (long)
                      (SkillConfigManager.getUseSetting(
                              hero, skill, Setting.COOLDOWN.node(), 0, false)
                          - SkillConfigManager.getUseSetting(
                                  hero, skill, Setting.COOLDOWN_REDUCE.node(), 0, false)
                              * hero.getSkillLevel(skill));
              cooldown = cooldown > 0 ? cooldown : 0;
              hero.setCooldown("Basher", cooldown + System.currentTimeMillis());
              if (Math.random() <= chance) {
                long duration =
                    (long)
                        (SkillConfigManager.getUseSetting(
                                hero, skill, Setting.DURATION.node(), 2000, false)
                            + (hero.getSkillLevel(skill)
                                * SkillConfigManager.getUseSetting(
                                    hero, skill, "duration-increase", 0, false)));
                duration = duration > 0 ? duration : 0;
                plugin
                    .getCharacterManager()
                    .getHero(tPlayer)
                    .addEffect(new StunEffect(basher, duration));
                double exp =
                    SkillConfigManager.getUseSetting(hero, skill, "exp-per-stun", 0, false);
                if (exp > 0) {
                  if (hero.hasParty()) {
                    hero.getParty().gainExp(exp, ExperienceType.SKILL, player.getLocation());
                  } else {
                    hero.gainExp(exp, ExperienceType.SKILL);
                  }
                }
                return;
              }
            }
          }
        }
      }
    }