public boolean calcSkillSuccess(L2Character player, L2Character target, L2Skill skill) { if(Config.ALT_GAME_SKILL_FORMULAS.equalsIgnoreCase("alt") || Config.ALT_GAME_SKILL_FORMULAS.equalsIgnoreCase("true")) return calcAltSkillSuccess(player, target, skill); SkillType type = skill.getSkillType(); boolean success = false; int rate = 1; int check = _rnd.nextInt(100); double modifier = 1; int value = 1; int maxLevel = SkillTable.getInstance().getMaxLevel(skill.getId(),skill.getLevel()); double pAtk, pDef, mAtk, mDef; switch(type) { case STUN: // For normal Stun Attack, with skillType = STUN pAtk = player.getPAtk(target); pDef = target.getPDef(player); pDef = target.calcStat(Stats.STUN_RES,pDef,target,null); value = 30 * 100 + (int)(70 * 100 * ((float)skill.getLevel()/maxLevel)); if (pDef > 0 && pAtk > 0) value *= 0.6 * pAtk/pDef; modifier = 100 * target.getCON()/30; break; case CONFUSION: case MUTE: case PARALYZE: mAtk = player.getMAtk(target, skill); mDef = target.getMDef(player, skill); value = 30 * 100 + (int)(70 * 100 * ((float)skill.getLevel()/maxLevel)); if (mDef > 0 && mAtk > 0) value *= 0.6 * mAtk/mDef; modifier = 100 * target.getMEN()/15; //_log.fine(player.getName()+" matk:"+mAtk+",mdef="+mDef+",value="+value+",modifier="+modifier+",maxlevel="+maxLevel+",level="+skill.getLevel()); break; case SLEEP: mAtk = player.getMAtk(target, skill); mDef = target.getMDef(player, skill); value = 30 * 100 + (int)(70 * 100 * ((float)skill.getLevel()/maxLevel)); mDef = target.calcStat(Stats.SLEEP_RES,mDef,target,null); if (mDef > 0 && mAtk > 0) value *= 0.6 * mAtk/mDef; modifier = 100 * target.getWIT()/15; //_log.fine(player.getName()+" matk:"+mAtk+",mdef="+mDef+",value="+value+",modifier="+modifier+",maxlevel="+maxLevel+",level="+skill.getLevel()); break; case ROOT: mAtk = player.getMAtk(target, skill); mDef = target.getMDef(player, skill); value = 30 * 100 + (int)(70 * 100 * ((float)skill.getLevel()/maxLevel)); mDef = target.calcStat(Stats.ROOT_RES,mDef,target,null); if (mDef > 0 && mAtk > 0) value *= 0.6 * mAtk/mDef; modifier = 100 * target.getDEX()/30; break; default: // For normal Stun attack with skillType = PDAM pAtk = (int)skill.getPower(); pDef = target.getPDef(player); pDef = target.calcStat(Stats.STUN_RES,pDef,target,null); // value = 30 * 100 + (int)(70 * 100 * ((float)skill.getLevel()/maxLevel)); value = 100 * 100; if (pDef > 0 && pAtk > 0) value *= 0.6 * pAtk/pDef; modifier = 100 * target.getCON()/30; break; } if (modifier == 0) { _log.warning("Name: "+target.getName()+" has bad base stat value. Fix datapack or notify dp ppl"); modifier = 1; } rate = ((player.getLevel() - target.getLevel()) + (int)(value / modifier)); //_log.fine(player.getName()+" rate:"+rate); if (rate > 100) rate = 100; else if (rate < 0) rate = 0; if (check > rate) success = false; else success = true; return success; } public boolean calcAltSkillSuccess(L2Character player, L2Character target, L2Skill skill) { SkillType type = skill.getSkillType(); boolean success = false; double rate = 0; int check = _rnd.nextInt(100); int skillLevelMod = skill.getLevel() / 10; int levelrange = ((player.getLevel() - target.getLevel()) + 4) * 2; switch(type) { case STUN: // For normal Stun Attack, with skillType = STUN rate = levelrange + skillLevelMod + (((player.getPAtk(target)*2) / target.getPDef(player)) * (( player.getCON() * 2.5) / target.getCON()) * 5.2); break; case SLEEP: rate = levelrange + skillLevelMod + (((player.getMAtk(target, skill)*2) / target.getMDef(player, skill)) * ((player.getWIT() * 2.5) / target.getWIT())*5); break; case ROOT: rate = levelrange + skillLevelMod + (((player.getMAtk(target, skill)*2) / target.getMDef(player, skill)) * ((player.getDEX() * 2.5) / target.getDEX())*5); break; case PARALYZE: rate = levelrange + skillLevelMod + (((player.getMAtk(target, skill)*2) / target.getMDef(player, skill)) * ((player.getWIT() * 2.5) / target.getWIT())*5); break; default: // For normal Stun attack with skillType = PDAM rate = levelrange + skillLevelMod + (((player.getPAtk(target)*2) / target.getPDef(player)) * ((player.getCON() * 2.5) / target.getCON())*5.2); break; } if (rate > 100) rate = 100; else if (rate < 0) rate = 1; if (check > rate) success = false; else success = true; return success; }