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; }