Example #1
0
 public AttackerCriticalStatus checkAttackerCriticalStatus(AttackStatus status, boolean isSkill) {
   if (attackCalcObservers.size() > 0) {
     for (AttackCalcObserver observer : attackCalcObservers) {
       AttackerCriticalStatus acStatus = observer.checkAttackerCriticalStatus(status, isSkill);
       if (acStatus.isResult()) {
         return acStatus;
       }
     }
   }
   return new AttackerCriticalStatus(false);
 }
  /**
   * Calculates CRITICAL chance
   * http://www.wolframalpha.com/input/?i=quadratic+fit+%7B%7B300%2C+30.97%7D%2C+%7B320%2C+31.68%7D%2C+%7B340%2C+33.30%7D%2C+%7B360%2C+36.09%7D%2C+%7B380%2C+37.81%7D%2C+%7B400%2C+40.72%7D%2C+%7B420%2C+42.12%7D%2C+%7B440%2C+44.03%7D%2C+%7B480%2C+44.66%7D%2C+%7B500%2C+45.96%7D%2C%7B604%2C+51.84%7D%2C+%7B649%2C+52.69%7D%7D
   * http://www.aionsource.com/topic/40542-character-stats-xp-dp-origin-gerbatorteam-july-2009/
   * http://www.wolframalpha.com/input/?i=-0.000126341+x%5E2%2B0.184411+x-13.7738
   * https://docs.google.com/spreadsheet/ccc?key=0AqxBGNJV9RrzdGNjbEhQNHN3S3M5bUVfUVQxRkVIT3c&hl=en_US#gid=0
   *
   * @param attacker
   * @return double
   */
  public static boolean calculatePhysicalCriticalRate(
      Creature attacker, Creature attacked, boolean isMainHand, int criticalProb, boolean isSkill) {
    if (attacker instanceof Servant || attacker instanceof Homing) {
      return false;
    }
    int critical;
    if (attacker instanceof Player && !isMainHand) {
      critical = ((PlayerGameStats) attacker.getGameStats()).getOffHandPCritical().getCurrent();
    } else {
      critical = attacker.getGameStats().getMainHandPCritical().getCurrent();
    }

    // check one time boost skill critical
    AttackerCriticalStatus acStatus =
        attacker.getObserveController().checkAttackerCriticalStatus(AttackStatus.CRITICAL, isSkill);
    if (acStatus.isResult()) {
      if (acStatus.isPercent()) {
        critical *= (1 + acStatus.getValue() / 100);
      } else {
        return Rnd.nextInt(1000) < acStatus.getValue();
      }
    }

    critical =
        attacked.getGameStats().getPositiveReverseStat(StatEnum.PHYSICAL_CRITICAL_RESIST, critical)
            - attacker.getGameStats().getStat(StatEnum.PVP_HIT_ACCURACY, 0).getCurrent();

    // add critical Prob
    critical *= (float) criticalProb / 100f;

    double criticalRate;

    if (critical <= 440) {
      criticalRate = critical * 0.1f;
    } else if (critical <= 600) {
      criticalRate = (440 * 0.1f) + ((critical - 440) * 0.05f);
    } else {
      criticalRate = (440 * 0.1f) + (160 * 0.05f) + ((critical - 600) * 0.02f);
    }

    return Rnd.nextInt(100) < criticalRate;
  }