private void spawnClone() { Npc KutolClone = getPosition().getWorldMapInstance().getNpc(282302); int random = Rnd.get(1, 3); if (KutolClone == null) { switch (random) { case 1: spawn(282302, getOwner().getX(), getOwner().getY(), getOwner().getZ() + 2, (byte) 3); break; case 2: spawn(282302, getOwner().getX(), getOwner().getY(), getOwner().getZ() + 2, (byte) 3); spawn( 282302, getOwner().getX() - 5, getOwner().getY() - 3, getOwner().getZ() + 2, (byte) 3); break; default: spawn(282302, getOwner().getX(), getOwner().getY(), getOwner().getZ() + 2, (byte) 3); spawn( 282302, getOwner().getX() - 5, getOwner().getY() - 3, getOwner().getZ() + 2, (byte) 3); spawn( 282302, getOwner().getX() + 5, getOwner().getY() - 3, getOwner().getZ() + 2, (byte) 3); break; } } }
/** * Calculates BLOCK chance * * @param attacker * @param attacked * @return int */ public static boolean calculatePhysicalBlockRate(Creature attacker, Creature attacked) { // check always block if (attacked.getObserveController().checkAttackStatus(AttackStatus.BLOCK)) { return true; } float accuracy = attacker.getGameStats().getMainHandPAccuracy().getCurrent(); float block = 0; if (attacked instanceof Player) { block = attacked.getGameStats().getBlock().getBonus() + getMovementModifier( attacked, StatEnum.BLOCK, attacked.getGameStats().getBlock().getBase()) + attacked.getGameStats().getStat(StatEnum.PVP_BLOCK, 0).getCurrent(); } else { block = attacked.getGameStats().getBlock().getBonus() + getMovementModifier( attacked, StatEnum.BLOCK, attacked.getGameStats().getBlock().getBase()); } float blockRate = block - accuracy; // blockRate = blockRate*0.6f+50; if (blockRate > 500) { blockRate = 500; } return Rnd.nextInt(1000) < blockRate; }
/** * Calculates MAGICAL CRITICAL chance * * @param attacker * @param attacke * @return boolean */ public static boolean calculateMagicalCriticalRate( Creature attacker, Creature attacked, int criticalProb) { if (attacker instanceof Servant || attacker instanceof Homing) { return false; } int critical = attacker.getGameStats().getMCritical().getCurrent(); if (attacked instanceof Player) { critical = attacked.getGameStats().getPositiveReverseStat(StatEnum.MAGICAL_CRITICAL_RESIST, critical) + attacked .getGameStats() .getPositiveReverseStat(StatEnum.PVP_MAGICAL_RESIST, critical); } else { critical = attacked .getGameStats() .getPositiveReverseStat(StatEnum.MAGICAL_CRITICAL_RESIST, critical); } // 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; }
@Override protected void handleAttack(Creature creature) { super.handleAttack(creature); if (Rnd.get(1, 100) < 3) { spawnServant(); } }
/** * Accuracy (includes evasion/parry/block formulas): Accuracy formula is based on opponents * evasion/parry/block vs your own Accuracy. If your Accuracy is 300 or more above opponents * evasion/parry/block then you can not be evaded, parried or blocked. <br> * https://docs.google.com/spreadsheet/ccc?key=0AqxBGNJV9RrzdF9tOWpwUlVLOXE5bVRWeHQtbGQxaUE&hl=en_US#gid=2 */ public static boolean calculatePhysicalEvasion(float diff, int upperCap) { diff = diff * 0.6f + 50; if (diff > upperCap) { diff = upperCap; } return Rnd.nextInt(1000) < diff; }
private void spawnServant() { Npc healServant = getPosition().getWorldMapInstance().getNpc(282988); if (healServant == null) { rndSpawn(282988, Rnd.get(1, 3)); NpcShoutsService.getInstance().sendMsg(getOwner(), 341784, getObjectId(), 0, 0); } }
@Override public void onDie(Npc npc) { switch (npc.getNpcId()) { case 233719: // bosses spawnChests(npc); break; case 235537: int ap = 0; switch (Rnd.get(1, 3)) { case 1: ap = 3000; break; case 2: ap = 6000; break; case 3: ap = 15000; break; } final int apReward = ap / instance.getPlayersInside().size(); instance.doOnAllPlayers( new Visitor<Player>() { @Override public void visit(Player player) { AbyssPointsService.addAGp(player, apReward, 0); PacketSendUtility.sendPacket(player, new SM_ABYSS_RANK(player.getAbyssRank())); } }); despawnNpc(npc); break; } }
@Override public void onDropRegistered(Npc npc) { Set<DropItem> dropItems = DropRegistrationService.getInstance().geCurrentDropMap().get(npc.getObjectId()); int npcId = npc.getNpcId(); int itemId = 0; Integer object = instance.getSoloPlayerObj(); switch (npcId) { case 832865: dropItems.clear(); switch (Rnd.get(1, 3)) { case 1: itemId = 188052742; break; case 2: itemId = 188052485; break; case 3: itemId = 188053450; break; } dropItems.add( DropRegistrationService.getInstance().regDropItem(1, object, npcId, itemId, 1)); break; } }
@Override protected void handleAttack(Creature creature) { super.handleAttack(creature); if (Rnd.get(1, 100) < 1) { spawnClone(); } }
/** * 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; }
private SpawnTemplate rndSpawnInRange(int npcId) { float direction = Rnd.get(0, 199) / 100f; float x1 = (float) (Math.cos(Math.PI * direction) * 5); float y1 = (float) (Math.sin(Math.PI * direction) * 5); return SpawnEngine.addNewSingleTimeSpawn( getPosition().getMapId(), npcId, getPosition().getX() + x1, getPosition().getY() + y1, getPosition().getZ(), getPosition().getHeading()); }
@Override public void onEnterInstance(Player player) { if (isInstanceStarted.compareAndSet(false, true)) { sp(730311, 554.83081f, 173.87158f, 432.52448f, (byte) 0, 9, 720000); sp(730312, 397.11661f, 184.29782f, 432.80328f, (byte) 0, 42, 720000); if (Rnd.get(1, 100) < 21) { sp(216889, 484.1199f, 314.08817f, 403.7213f, (byte) 5, 720000); } if (Rnd.get(1, 100) < 21) { sp(216890, 499.52f, 598.67f, 390.49f, (byte) 59, 720000); } if (Rnd.get(1, 100) < 21) { spawn(216887, 486.26382f, 909.48175f, 405.24463f, (byte) 90); } if (Rnd.get(1, 100) < 51) { switch (Rnd.get(2)) { case 0: spawn(216888, 416.3429f, 282.32785f, 409.7311f, (byte) 80); break; default: spawn(216888, 552.07446f, 289.058f, 409.7311f, (byte) 80); break; } } int spawnTime = Rnd.get(10, 15) * 60 * 1000 + 120000; sendMsgByRace(1400633, Race.PC_ALL, spawnTime); sp(216941, 485.99f, 299.23f, 402.57f, (byte) 30, spawnTime); startInstanceTask(); } super.onEnterInstance(player); }
@Override public void onDropRegistered(Npc npc) { Set<DropItem> dropItems = DropRegistrationService.getInstance().geCurrentDropMap().get(npc.getObjectId()); int npcId = npc.getNpcId(); int itemId = 0; Integer object = instance.getSoloPlayerObj(); switch (npcId) { case 702700: dropItems.add( DropRegistrationService.getInstance().regDropItem(1, object, npcId, 185000224, 1)); if (Rnd.get(1, 100) < 70) { dropItems.add( DropRegistrationService.getInstance().regDropItem(1, object, npcId, 186000066, 1)); } break; case 219963: case 219964: case 219965: case 219966: case 219967: case 219968: dropItems.clear(); switch (Rnd.get(1, 3)) { case 1: itemId = 188052548; break; case 2: itemId = 188053620; break; case 3: itemId = 188053400; break; } dropItems.add( DropRegistrationService.getInstance().regDropItem(1, object, npcId, itemId, 3)); break; } }
private void spawn(Player player) { int mobToSpawn = mobs.get(Rnd.get(0, 3)); float x = 0; float y = 0; final float z = 124.942f; switch (mobToSpawn) { case 218760: { x = 250.081f; y = 268.308f; break; } case 218762: { x = 273.354f; y = 244.489f; break; } case 218761: { x = 272.994f; y = 244.674f; break; } case 218763: { x = 250.800f; y = 222.782f; break; } } Npc spawn = (Npc) QuestService.spawnQuestNpc( 300330000, player.getInstanceId(), mobToSpawn, x, y, z, (byte) 0); Collection<Npc> allNpcs = World.getInstance().getNpcs(); Npc target = null; for (Npc npc : allNpcs) { if (npc.getNpcId() == 730493) { target = npc; } } if (target != null) { spawn.getAggroList().addHate(target, 1); } }
private static void initPig() { float[] coords = floatArray.get(Rnd.get(floatArray.size())); SpawnTemplate spawn = SpawnEngine.addNewSingleTimeSpawn( WORLD_ID, NPC_ID, coords[0], coords[1], coords[2], (byte) coords[3]); VisibleObject mainObject = SpawnEngine.spawnObject(spawn, 1); if (mainObject instanceof Npc) { mainN = (Npc) mainObject; } ActionObserver observer = new ActionObserver(ObserverType.ATTACKED) { @Override public void attacked(Creature creature) { if (creature instanceof Player) { final Player player = (Player) creature; final int id = rewards[Rnd.get(rewards.length)]; ItemService.addItem(player, id, 1); World.getInstance() .doOnAllPlayers( new Visitor<Player>() { @Override public void visit(Player object) { PacketSendUtility.sendYellowMessageOnCenter( object, player.getName() + MuiService.getInstance().getMessage("PIG_EVENT_REWARD", id)); } }); } mainN.getObserveController().removeObserver(this); // mainN.setSpawn(null); mainN.getController().onDelete(); initPig(); } }; if (mainN != null) { mainN.getObserveController().attach(observer); } }
@Override public void onInstanceCreate(WorldMapInstance instance) { super.onInstanceCreate(instance); int spawn_point = Rnd.get(1, 2); spawn(spawn_point == 1 ? 235537 : 832865, 649.1376f, 278.06427f, 191.72736f, (byte) 90); int spawn_point2 = Rnd.get(1, 2); spawn(spawn_point2 == 1 ? 235537 : 832865, 424.37238f, 278.05197f, 191.72f, (byte) 90); int spawn_point3 = Rnd.get(1, 2); spawn(spawn_point3 == 1 ? 235537 : 832865, 387.86472f, 431.94095f, 197.20628f, (byte) 0); int spawn_point4 = Rnd.get(1, 2); spawn(spawn_point4 == 1 ? 235537 : 832865, 661.91473f, 431.9554f, 197.20628f, (byte) 60); int spawn_point5 = Rnd.get(1, 2); spawn(spawn_point5 == 1 ? 235537 : 832865, 500.65875f, 338.41437f, 180.32727f, (byte) 0); int spawn_point6 = Rnd.get(1, 2); spawn(spawn_point6 == 1 ? 235537 : 832865, 555.80597f, 575.031f, 176.89429f, (byte) 60); int spawn_point7 = Rnd.get(1, 2); spawn(spawn_point7 == 1 ? 235537 : 832865, 393.83f, 591.704f, 191.18f, (byte) 90); int spawn_point8 = Rnd.get(1, 2); spawn(spawn_point8 == 1 ? 235537 : 832865, 659.3397f, 571.47174f, 191.20131f, (byte) 60); int spawn_point9 = Rnd.get(1, 2); spawn(spawn_point9 == 1 ? 235537 : 832865, 540.199f, 448.91748f, 180.8847f, (byte) 90); // legion int spawn_legion_point = Rnd.get(1, 2); spawn(spawn_legion_point == 1 ? 235537 : 832865, 434.95197f, 591.77057f, 191.18217f, (byte) 90); int spawn_legion_point2 = Rnd.get(1, 2); spawn( spawn_legion_point2 == 1 ? 235537 : 832865, 437.78436f, 432.13367f, 197.20628f, (byte) 60); int spawn_legion_point3 = Rnd.get(1, 2); spawn(spawn_legion_point3 == 1 ? 235537 : 832865, 390.86206f, 270.09f, 191.78427f, (byte) 90); int spawn_legion_point4 = Rnd.get(1, 2); spawn(spawn_legion_point4 == 1 ? 235537 : 832865, 552.3796f, 338.2951f, 180.32727f, (byte) 60); int spawn_legion_point5 = Rnd.get(1, 2); spawn( spawn_legion_point5 == 1 ? 235537 : 832865, 506.79877f, 441.54056f, 180.94101f, (byte) 90); int spawn_legion_point6 = Rnd.get(1, 2); spawn(spawn_legion_point6 == 1 ? 235537 : 832865, 496.29544f, 575.58014f, 176.89429f, (byte) 0); int spawn_legion_point7 = Rnd.get(1, 2); spawn(spawn_legion_point7 == 1 ? 235537 : 832865, 615.22076f, 586.3513f, 191.21751f, (byte) 0); int spawn_legion_point8 = Rnd.get(1, 2); spawn(spawn_legion_point8 == 1 ? 235537 : 832865, 611.54803f, 431.9057f, 197.20628f, (byte) 0); int spawn_legion_point9 = Rnd.get(1, 2); spawn( spawn_legion_point9 == 1 ? 235537 : 832865, 615.80884f, 270.33264f, 191.78235f, (byte) 90); }
/** Apply effects and perform actions specified in skill template */ protected void endCast() { if (!effector.isCasting() || isCancelled) return; // if target out of range if (skillTemplate == null) return; // Check if target is out of skill range Properties properties = skillTemplate.getProperties(); if (properties != null && !properties.endCastValidate(this)) { effector.getController().cancelCurrentSkill(); return; } if (!validateEffectedList()) { effector.getController().cancelCurrentSkill(); return; } if (!preUsageCheck()) { return; } effector.setCasting(null); if (this.getSkillTemplate().isDeityAvatar() && effector instanceof Player) { AbyssService.rankerSkillAnnounce((Player) effector, this.getSkillTemplate().getNameId()); } /** try removing item, if its not possible return to prevent exploits */ if (effector instanceof Player && skillMethod == SkillMethod.ITEM) { Item item = ((Player) effector).getInventory().getItemByObjId(this.itemObjectId); if (item == null) return; if (item.getActivationCount() > 1) { item.setActivationCount(item.getActivationCount() - 1); } else { if (!((Player) effector) .getInventory() .decreaseByObjectId(item.getObjectId(), 1, ItemUpdateType.DEC_USE)) return; } } /** Create effects and precalculate result */ int spellStatus = 0; int dashStatus = 0; int resistCount = 0; boolean blockedChain = false; boolean blockedStance = false; final List<Effect> effects = new ArrayList<Effect>(); if (skillTemplate.getEffects() != null) { boolean blockAOESpread = false; for (Creature effected : effectedList) { Effect effect = new Effect(this, effected, 0, itemTemplate); if (effected instanceof Player) { if (effect.getEffectResult() == EffectResult.CONFLICT) blockedStance = true; } // Force RESIST status if AOE spell spread must be blocked if (blockAOESpread) effect.setAttackStatus(AttackStatus.RESIST); effect.initialize(); final int worldId = effector.getWorldId(); final int instanceId = effector.getInstanceId(); effect.setWorldPosition(worldId, instanceId, x, y, z); effects.add(effect); spellStatus = effect.getSpellStatus().getId(); dashStatus = effect.getDashStatus().getId(); // Block AOE propagation if firstTarget resists the spell if ((!blockAOESpread) && (effect.getAttackStatus() == AttackStatus.RESIST) && (isTargetAOE())) blockAOESpread = true; if (effect.getAttackStatus() == AttackStatus.RESIST || effect.getAttackStatus() == AttackStatus.DODGE) { resistCount++; } } if (resistCount == effectedList.size()) { blockedChain = true; blockedPenaltySkill = true; } // exception for point point skills(example Ice Sheet) if (effectedList.isEmpty() && this.isPointPointSkill()) { Effect effect = new Effect(this, null, 0, itemTemplate); effect.initialize(); final int worldId = effector.getWorldId(); final int instanceId = effector.getInstanceId(); effect.setWorldPosition(worldId, instanceId, x, y, z); effects.add(effect); spellStatus = effect.getSpellStatus().getId(); } } if (effector instanceof Player && skillMethod == SkillMethod.CAST) { Player playerEffector = (Player) effector; if (playerEffector.getController().isUnderStance()) { playerEffector.getController().stopStance(); } if (skillTemplate.isStance() && !blockedStance) { playerEffector.getController().startStance(skillTemplate.getSkillId()); } } boolean setCooldowns = true; if (effector instanceof Player) { if (this.isMulticast() && ((Player) effector) .getChainSkills() .getChainCount((Player) effector, this.getSkillTemplate(), this.chainCategory) != 0) { setCooldowns = false; } } // Check Chain Skill Trigger Rate if (CustomConfig.SKILL_CHAIN_TRIGGERRATE) { int chainProb = skillTemplate.getChainSkillProb(); if (this.chainCategory != null && !blockedChain) { this.chainSuccess = Rnd.get(90) < chainProb; } } else { this.chainSuccess = true; } /** set variables for chaincondition check */ if (effector instanceof Player && this.chainSuccess && this.chainCategory != null) { ((Player) effector).getChainSkills().addChainSkill(this.chainCategory, this.isMulticast()); } /** Perform necessary actions (use mp,dp items etc) */ Actions skillActions = skillTemplate.getActions(); if (skillActions != null) { for (Action action : skillActions.getActions()) { if (!action.act(this)) return; } } if (effector instanceof Player) { QuestEnv env = new QuestEnv(effector.getTarget(), (Player) effector, 0, 0); QuestEngine.getInstance().onUseSkill(env, skillTemplate.getSkillId()); } if (setCooldowns) this.setCooldowns(); if (hitTime == 0) applyEffect(effects); else { ThreadPoolManager.getInstance() .schedule( new Runnable() { @Override public void run() { applyEffect(effects); } }, hitTime); } if (skillMethod == SkillMethod.CAST || skillMethod == SkillMethod.ITEM || skillMethod == SkillMethod.CHARGE) sendCastspellEnd(spellStatus, dashStatus, effects); endCondCheck(); if (effector instanceof Npc) SkillAttackManager.afterUseSkill((NpcAI2) ((Npc) effector).getAi2()); }
/** * Start gathering process * * @param player */ public void onStartUse(final Player player) { // basic actions, need to improve here final GatherableTemplate template = this.getObjectTemplate(); if (!checkPlayerSkill(player, template)) return; List<Material> materials = template.getMaterials().getMaterial(); int index = 0; Material material = materials.get(index); // default is 0 int count = materials.size(); if (count < 1) { // error - theoretically if XML data is correct, this should never happen. return; } else if (count == 1) { // default is 0 } else { if (player.getInventory().isFull()) { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.EXTRACT_GATHER_INVENTORY_IS_FULL()); return; } int gatherRate = 1; // 1x rates (probably make config later, if fixed to non-linear statistic probability) float maxrate = 0; int rate = 0; int i = 0; // index counter // sort materials to ascending order SortedMap<Integer, Integer> hasMat = new TreeMap<Integer, Integer>(); for (Material mat : materials) { maxrate += mat.getRate(); // get maxrate hasMat.put( mat.getRate(), i); // sort and save index of materials (key is rate and rate is unique on each // gatherId) i++; } Iterator<Integer> it = hasMat.keySet().iterator(); while (it.hasNext()) { rate = it.next(); float percent = Rnd.get() * 100f; float chance = ((rate / maxrate) * 100f * gatherRate); // default index is to 0, look to up little bit on 'material' if (percent < chance) { index = hasMat.get(rate); // return index material = materials.get(index); break; } } } final Material finalMaterial = material; if (state != GatherState.GATHERING) { state = GatherState.GATHERING; currentGatherer = player.getObjectId(); player .getObserveController() .attach( new StartMovingListener() { @Override public void moved() { finishGathering(player); } }); int skillLvlDiff = player.getSkillList().getSkillLevel(template.getHarvestSkill()) - template.getSkillLevel(); task = new GatheringTask(player, this, finalMaterial, skillLvlDiff); task.start(); } }
/** @param worldMapInstance */ private static void startInstanceChecker(WorldMapInstance worldMapInstance) { int delay = 60000 + Rnd.get(-10, 10); worldMapInstance.setEmptyInstanceTask( ThreadPoolManager.getInstance() .scheduleAtFixedRate(new EmptyInstanceCheckerTask(worldMapInstance), delay, delay)); }
public static int calculateMagicalAttackDamage( Creature attacker, Creature target, SkillElement element, boolean isMainHand) { Preconditions.checkNotNull(element, "Skill element should be NONE instead of null"); Stat2 mAttack; if (isMainHand) { mAttack = attacker.getGameStats().getMainHandMAttack(); } else { mAttack = attacker.getGameStats().getOffHandMAttack(); } float resultDamage = mAttack.getCurrent(); if (attacker instanceof Player) { Equipment equipment = ((Player) attacker).getEquipment(); Item weapon = equipment.getMainHandWeapon(); if (weapon != null) { WeaponStats weaponStat = weapon.getItemTemplate().getWeaponStats(); if (weaponStat == null) { return 0; } int totalMin = weaponStat.getMinDamage(); int totalMax = weaponStat.getMaxDamage(); if (totalMax - totalMin < 1) { log.warn("Weapon stat MIN_MAX_DAMAGE resulted average zero in main-hand calculation"); log.warn( "Weapon ID: " + String.valueOf( equipment.getMainHandWeapon().getItemTemplate().getTemplateId())); log.warn("MIN_DAMAGE = " + String.valueOf(totalMin)); log.warn("MAX_DAMAGE = " + String.valueOf(totalMax)); } float knowledge = attacker.getGameStats().getKnowledge().getCurrent() * 0.01f; int diff = Math.round((totalMax - totalMin) * knowledge / 2); resultDamage = mAttack.getBonus() + getMovementModifier(attacker, StatEnum.MAGICAL_ATTACK, mAttack.getBase()); resultDamage += Rnd.get(-diff, diff); if (attacker.isInState(CreatureState.POWERSHARD)) { Item firstShard = equipment.getMainHandPowerShard(); Item secondShard = equipment.getOffHandPowerShard(); if (firstShard != null) { equipment.usePowerShard(firstShard, 1); resultDamage += firstShard.getItemTemplate().getWeaponBoost(); } if (secondShard != null) { equipment.usePowerShard(secondShard, 1); resultDamage += secondShard.getItemTemplate().getWeaponBoost(); } } } } if (element != SkillElement.NONE) { float elementalDef = getMovementModifier( target, SkillElement.getResistanceForElement(element), target.getGameStats().getMagicalDefenseFor(element)); resultDamage = Math.round(resultDamage * (1 - elementalDef / 1300f)); } if (resultDamage <= 0) { resultDamage = 1; } return Math.round(resultDamage); }
/** * @param player * @param target * @param effectTemplate * @param skillDamages * @return Damage made to target (-hp value) */ public static int calculatePhysicalAttackDamage( Creature attacker, Creature target, boolean isMainHand) { Stat2 pAttack; if (isMainHand) { pAttack = attacker.getGameStats().getMainHandPAttack(); } else { pAttack = ((Player) attacker).getGameStats().getOffHandPAttack(); } float resultDamage = pAttack.getCurrent(); float baseDamage = pAttack.getBase(); if (attacker instanceof Player) { Equipment equipment = ((Player) attacker).getEquipment(); Item weapon; if (isMainHand) { weapon = equipment.getMainHandWeapon(); } else { weapon = equipment.getOffHandWeapon(); } if (weapon != null) { WeaponStats weaponStat = weapon.getItemTemplate().getWeaponStats(); if (weaponStat == null) { return 0; } int totalMin = weaponStat.getMinDamage(); int totalMax = weaponStat.getMaxDamage(); if (totalMax - totalMin < 1) { log.warn("Weapon stat MIN_MAX_DAMAGE resulted average zero in main-hand calculation"); log.warn( "Weapon ID: " + String.valueOf( equipment.getMainHandWeapon().getItemTemplate().getTemplateId())); log.warn("MIN_DAMAGE = " + String.valueOf(totalMin)); log.warn("MAX_DAMAGE = " + String.valueOf(totalMax)); } float power = attacker.getGameStats().getPower().getCurrent() * 0.01f; int diff = Math.round((totalMax - totalMin) * power / 2); resultDamage = pAttack.getBonus() + baseDamage; // adjust with value from WeaponDualEffect // it makes lower cap of damage lower, so damage is more random on offhand int negativeDiff = diff; if (!isMainHand) { negativeDiff = (int) Math.round((200 - ((Player) attacker).getDualEffectValue()) * 0.01 * diff); } resultDamage += Rnd.get(-negativeDiff, diff); // add powerShard damage if (attacker.isInState(CreatureState.POWERSHARD)) { Item firstShard; Item secondShard = null; if (isMainHand) { firstShard = equipment.getMainHandPowerShard(); if (weapon.getItemTemplate().isTwoHandWeapon()) { secondShard = equipment.getOffHandPowerShard(); } } else { firstShard = equipment.getOffHandPowerShard(); } if (firstShard != null) { equipment.usePowerShard(firstShard, 1); resultDamage += firstShard.getItemTemplate().getWeaponBoost(); } if (secondShard != null) { equipment.usePowerShard(secondShard, 1); resultDamage += secondShard.getItemTemplate().getWeaponBoost(); } } } else { // if hand attack int totalMin = 16; int totalMax = 20; float power = attacker.getGameStats().getPower().getCurrent() * 0.01f; int diff = Math.round((totalMax - totalMin) * power / 2); resultDamage = pAttack.getBonus() + baseDamage; resultDamage += Rnd.get(-diff, diff); } } else { int rnd = (int) (resultDamage * 0.25); resultDamage += Rnd.get(-rnd, rnd); } // subtract defense float pDef = target.getGameStats().getPDef().getBonus() + getMovementModifier( target, StatEnum.PHYSICAL_DEFENSE, target.getGameStats().getPDef().getBase()); resultDamage -= (pDef * 0.10f); if (resultDamage <= 0) { resultDamage = 1; } return Math.round(resultDamage); }