/**
   * @param npcAI
   * @return
   */
  public static NpcSkillEntry chooseNextSkill(NpcAI2 npcAI) {
    if (npcAI.isInSubState(AISubState.CAST)) {
      return null;
    }

    Npc owner = npcAI.getOwner();
    NpcSkillList skillList = owner.getSkillList();
    if (skillList == null || skillList.size() == 0) {
      return null;
    }

    if (owner.getGameStats().canUseNextSkill()) {
      NpcSkillEntry npcSkill = skillList.getRandomSkill();
      if (npcSkill != null) {
        int currentHpPercent = owner.getLifeStats().getHpPercentage();

        if (npcSkill.isReady(
            currentHpPercent,
            System.currentTimeMillis() - owner.getGameStats().getFightStartingTime())) {
          // Check for Bind/Silence/Fear debuffs on npc
          SkillTemplate template = npcSkill.getSkillTemplate();
          if ((template.getType() == SkillType.MAGICAL
                  && owner.getEffectController().isAbnormalSet(AbnormalState.SILENCE))
              || (template.getType() == SkillType.PHYSICAL
                  && owner.getEffectController().isAbnormalSet(AbnormalState.BIND))
              || (owner.getEffectController().isUnderFear())) return null;

          npcSkill.setLastTimeUsed();

          return npcSkill;
        }
      }
    }
    return null;
  }
 @Override
 protected void handleDespawned() {
   WorldMapInstance instance = getPosition().getWorldMapInstance();
   deleteMobs(instance.getNpcs(251588));
   deleteMobs(instance.getNpcs(279954));
   deleteMobs(instance.getNpcs(279955));
   super.handleDespawned();
 }
 /**
  * @param npcAI
  * @param delay
  */
 public static void performAttack(NpcAI2 npcAI, int delay) {
   if (npcAI.getOwner().getObjectTemplate().getAttackRange() == 0) {
     if (npcAI.getOwner().getTarget() != null
         && !MathUtil.isInRange(
             npcAI.getOwner(), npcAI.getOwner().getTarget(), npcAI.getOwner().getAggroRange())) {
       npcAI.onGeneralEvent(AIEventType.TARGET_TOOFAR);
       npcAI.getOwner().getController().abortCast();
       return;
     }
   }
   if (npcAI.setSubStateIfNot(AISubState.CAST)) {
     if (delay > 0) {
       ThreadPoolManager.getInstance()
           .schedule(
               new SkillAction(npcAI),
               delay + DataManager.SKILL_DATA.getSkillTemplate(npcAI.getSkillId()).getDuration());
     } else {
       skillAction(npcAI);
     }
   }
 }
  /** @param npcAI */
  protected static void skillAction(NpcAI2 npcAI) {
    Creature target = (Creature) npcAI.getOwner().getTarget();
    if (npcAI.getOwner().getObjectTemplate().getAttackRange() == 0) {
      if (npcAI.getOwner().getTarget() != null
          && !MathUtil.isInRange(
              npcAI.getOwner(), npcAI.getOwner().getTarget(), npcAI.getOwner().getAggroRange())) {
        npcAI.onGeneralEvent(AIEventType.TARGET_TOOFAR);
        npcAI.getOwner().getController().abortCast();
        return;
      }
    }
    if (target != null && !target.getLifeStats().isAlreadyDead()) {
      final int skillId = npcAI.getSkillId();
      final int skillLevel = npcAI.getSkillLevel();

      SkillTemplate template = DataManager.SKILL_DATA.getSkillTemplate(skillId);
      int duration = template.getDuration();
      if (npcAI.isLogging()) {
        AI2Logger.info(
            npcAI, "Using skill " + skillId + " level: " + skillLevel + " duration: " + duration);
      }
      switch (template.getSubType()) {
        case BUFF:
          switch (template.getProperties().getFirstTarget()) {
            case ME:
              if (npcAI.getOwner().getEffectController().isAbnormalPresentBySkillId(skillId)) {
                afterUseSkill(npcAI);
                return;
              }
              break;
            default:
              if (target.getEffectController().isAbnormalPresentBySkillId(skillId)) {
                afterUseSkill(npcAI);
                return;
              }
          }
          break;
      }
      boolean success = npcAI.getOwner().getController().useSkill(skillId, skillLevel);
      if (!success) {
        afterUseSkill(npcAI);
      }
    } else {
      npcAI.setSubStateIfNot(AISubState.NONE);
      npcAI.onGeneralEvent(AIEventType.TARGET_GIVEUP);
    }
  }
 /** @param npcAI */
 public static void afterUseSkill(NpcAI2 npcAI) {
   npcAI.setSubStateIfNot(AISubState.NONE);
   npcAI.onGeneralEvent(AIEventType.ATTACK_COMPLETE);
 }