public float GetResistanceMod(DamageType damageType, WorldObject damageSource, float weaponResistanceMod) { var ignoreMagicResist = damageSource != null ? damageSource.IgnoreMagicResist : false; var resistanceType = Creature.GetResistanceType(damageType); if (ignoreMagicResist) { return((float)Creature.GetNaturalResistance(resistanceType)); } else { return((float)Creature.GetResistanceMod(resistanceType, weaponResistanceMod)); } }
/// <summary> /// Calculates the damage for a spell projectile /// Used by war magic, void magic, and life magic projectiles /// </summary> public double?CalculateDamage(WorldObject _source, Creature target, ref bool criticalHit) { var source = _source as Creature; var sourcePlayer = source as Player; var targetPlayer = target as Player; if (source == null || targetPlayer != null && targetPlayer.Invincible == true) { return(null); } // target already dead? if (target.Health.Current <= 0) { return(-1); } // check lifestone protection if (targetPlayer != null && targetPlayer.UnderLifestoneProtection) { targetPlayer.HandleLifestoneProtection(); return(null); } double damageBonus = 0.0f, warSkillBonus = 0.0f, finalDamage = 0.0f; var resistanceType = GetResistanceType(Spell.DamageType); var resisted = source.ResistSpell(target, Spell); if (resisted != null && resisted == true) { return(null); } CreatureSkill attackSkill = null; var sourceCreature = source as Creature; if (sourceCreature != null) { attackSkill = sourceCreature.GetCreatureSkill(Spell.School); } // critical hit var critical = GetWeaponMagicCritFrequencyModifier(source, attackSkill); if (ThreadSafeRandom.Next(0.0f, 1.0f) < critical) { criticalHit = true; } bool isPVP = sourcePlayer != null && targetPlayer != null; var elementalDmgBonus = GetCasterElementalDamageModifier(source, target, Spell.DamageType); // Possible 2x + damage bonus for the slayer property var slayerBonus = GetWeaponCreatureSlayerModifier(source, target); // life magic projectiles: ie., martyr's hecatomb if (Spell.School == MagicSchool.LifeMagic) { var lifeMagicDamage = LifeProjectileDamage * Spell.DamageRatio; // could life magic projectiles crit? // if so, did they use the same 1.5x formula as war magic, instead of 2.0x? if (criticalHit) { damageBonus = lifeMagicDamage * 0.5f * GetWeaponCritMultiplierModifier(source, attackSkill); } finalDamage = (lifeMagicDamage + damageBonus) * elementalDmgBonus * slayerBonus; return(finalDamage); } // war magic projectiles (and void currently) else { if (criticalHit) { if (isPVP) // PvP: 50% of the MIN damage added to normal damage roll { damageBonus = Spell.MinDamage * 0.5f; } else // PvE: 50% of the MAX damage added to normal damage roll { damageBonus = Spell.MaxDamage * 0.5f; } var critDamageMod = GetWeaponCritMultiplierModifier(source, attackSkill); damageBonus *= critDamageMod; } /* War Magic skill-based damage bonus * http://acpedia.org/wiki/Announcements_-_2002/08_-_Atonement#Letter_to_the_Players */ if (sourcePlayer != null && Spell.School == MagicSchool.WarMagic) { var warSkill = source.GetCreatureSkill(Spell.School).Current; if (warSkill > Spell.Power) { // Bonus clamped to a maximum of 50% var percentageBonus = Math.Clamp((warSkill - Spell.Power) / 100.0f, 0.0f, 0.5f); warSkillBonus = Spell.MinDamage * percentageBonus; } } var baseDamage = ThreadSafeRandom.Next(Spell.MinDamage, Spell.MaxDamage); finalDamage = baseDamage + damageBonus + warSkillBonus; finalDamage *= target.GetNaturalResistance(resistanceType, GetWeaponResistanceModifier(source, attackSkill, Spell.DamageType)) * elementalDmgBonus * slayerBonus; return(finalDamage); } }