/// <summary> /// Calculates the damage. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <param name="damageType">Type of the damage.</param> /// <param name="amount">The amount.</param> /// <returns>System.Double.</returns> /// <exception cref="ArgumentOutOfRangeException">damageType - null</exception> public static double CalculateDamage( this Obj_AI_Base source, Obj_AI_Base target, DamageType damageType, double amount) { var damage = 0d; switch (damageType) { case DamageType.Magical: damage = source.CalculateMagicDamage(target, amount); break; case DamageType.Physical: damage = source.CalculatePhysicalDamage(target, amount); break; case DamageType.Mixed: damage = source.CalculateMixedDamage(target, damage / 2d, damage / 2d); break; case DamageType.True: damage = Math.Max(Math.Floor(amount), 0); break; default: throw new ArgumentOutOfRangeException(nameof(damageType), damageType, null); } return(damage); }
/// <summary> /// Gets the calculated damage based on the given damage type onto the target from source. /// </summary> /// <param name="source"> /// The source /// </param> /// <param name="target"> /// The target /// </param> /// <param name="damageType"> /// The damage type /// </param> /// <param name="amount"> /// The amount /// </param> /// <returns> /// The estimated damage from calculations. /// </returns> public static double CalculateDamage( this Obj_AI_Base source, Obj_AI_Base target, DamageType damageType, double amount) { var damage = 0d; switch (damageType) { case DamageType.Magical: damage = source.CalculateMagicDamage(target, amount); break; case DamageType.Physical: damage = source.CalculatePhysicalDamage(target, amount); break; case DamageType.Mixed: damage = source.CalculateMixedDamage(target, damage / 2, damage / 2); break; case DamageType.True: damage = Math.Max(Math.Floor(amount), 0); break; } return(damage); }
/// <summary> /// Gets the calculated damage based on the given damage type onto the target from source. /// </summary> /// <param name="source"> /// The source /// </param> /// <param name="target"> /// The target /// </param> /// <param name="damageType"> /// The damage type /// </param> /// <param name="amount"> /// The amount /// </param> /// <returns> /// The estimated damage from calculations. /// </returns> public static double CalculateDamage( this Obj_AI_Base source, Obj_AI_Base target, DamageType damageType, double amount) { var damage = 0d; switch (damageType) { case DamageType.Magical: damage = source.CalculateMagicDamage(target, amount); break; case DamageType.Physical: damage = source.CalculatePhysicalDamage(target, amount); break; case DamageType.True: damage = amount; break; } return(Math.Max(damage, 0)); }
/// <summary> /// Gets the calculated mixed damage onto the target from source. /// </summary> /// <param name="source"> /// The source /// </param> /// <param name="target"> /// The target /// </param> /// <param name="physicalAmount"> /// The physical amount /// </param> /// <param name="magicalAmount"> /// The magical amount /// </param> /// <returns> /// The estimated damage from calculations. /// </returns> public static double CalculateMixedDamage( this Obj_AI_Base source, Obj_AI_Base target, double physicalAmount, double magicalAmount) { return(source.CalculatePhysicalDamage(target, physicalAmount) + source.CalculateMagicDamage(target, magicalAmount)); }
/// <summary> /// Gets the source auto attack damage on the target. /// </summary> /// <param name="source"> /// The source /// </param> /// <param name="target"> /// The target /// </param> /// <returns> /// The estimated auto attack damage. /// </returns> public static double GetAutoAttackDamage(this Obj_AI_Base source, Obj_AI_Base target) { double dmgPhysical = source.TotalAttackDamage, dmgMagical = 0, dmgPassive = 0; var dmgReduce = 1d; var hero = source as Obj_AI_Hero; var targetHero = target as Obj_AI_Hero; var isMixDmg = false; if (hero != null) { // Spoils Of War if (hero.IsMelee() && target is Obj_AI_Minion && target.Team != GameObjectTeam.Neutral && hero.GetBuffCount("TalentReaper") > 0) { var eyeEquinox = Items.HasItem(2303, hero); if ( GameObjects.Heroes.Any( h => h.Team == hero.Team && !h.Compare(hero) && h.Distance(hero) < (eyeEquinox ? 850 : 1050))) { var spoilwarDmg = 200; if (Items.HasItem((int)ItemId.Targons_Brace, hero)) { spoilwarDmg = 240; } else if (Items.HasItem((int)ItemId.Face_of_the_Mountain, hero) || eyeEquinox) { spoilwarDmg = 400; } if (target.Health < spoilwarDmg) { return(float.MaxValue); } } } // Bonus Damage (Passive) var passiveInfo = hero.GetPassiveDamageInfo(target); dmgPassive += passiveInfo.Value; if (passiveInfo.Override) { return(dmgPassive); } switch (hero.ChampionName) { case "Kalista": dmgPhysical *= 0.9; break; case "Jhin": dmgPhysical += Math.Round( (new[] { 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40 }[ hero.Level - 1] +(Math.Round((hero.Crit * 100 / 10) * 4)) + (Math.Round(((hero.AttackSpeedMod - 1) * 100 / 10) * 2.5))) / 100 * dmgPhysical); break; case "Corki": dmgPhysical /= 2; dmgMagical = dmgPhysical; isMixDmg = true; break; case "Quinn": if (target.HasBuff("quinnw")) { dmgPhysical += 10 + (5 * hero.Level) + (0.14 + (0.02 * hero.Level)) * hero.TotalAttackDamage; } break; } // Serrated Dirk if (hero.HasBuff("Serrated")) { if (!isMixDmg) { dmgPhysical += 15; } else { dmgPhysical += 7.5; dmgMagical += 7.5; } } if (targetHero != null) { // Dorans Shield if (Items.HasItem((int)ItemId.Dorans_Shield, targetHero)) { var subDmg = (dmgPhysical + dmgMagical) - 8; dmgPhysical = !isMixDmg ? subDmg : (dmgMagical = subDmg / 2); } // Fervor Of Battle if (hero.GetFerocity(Ferocity.FervorofBattle).IsValid()) { var fervorBuffCount = hero.GetBuffCount("MasteryOnHitDamageStacker"); if (fervorBuffCount > 0) { dmgPassive += hero.CalculatePhysicalDamage( target, (0.13 + (0.77 * hero.Level)) * fervorBuffCount); } } } else if (target is Obj_AI_Minion) { // Savagery var savagery = hero.GetCunning(Cunning.Savagery); if (savagery.IsValid()) { dmgPhysical += savagery.Points; } // RiftHerald P if (!hero.IsMelee() && target.Team == GameObjectTeam.Neutral && target.Name == "SRU_RiftHerald") { dmgReduce *= 0.65; } } } // Ninja Tabi if (targetHero != null && !(source is Obj_AI_Turret) && new[] { 3047, 1316, 1318, 1315, 1317 }.Any(i => Items.HasItem(i, targetHero))) { dmgReduce *= 0.9; } dmgPhysical = source.CalculatePhysicalDamage(target, dmgPhysical); dmgMagical = source.CalculateMagicDamage(target, dmgMagical); // Fizz P if (targetHero != null && targetHero.ChampionName == "Fizz") { dmgPhysical -= 4 + (2 * Math.Floor((targetHero.Level - 1) / 3d)); } // This formula is right, work out the math yourself if you don't believe me return (Math.Max( Math.Floor((dmgPhysical + dmgMagical) * dmgReduce + source.PassiveFlatMod(target) + dmgPassive), 0)); }
/// <summary> /// Gets the automatic attack damage. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <returns>System.Double.</returns> public static double GetAutoAttackDamage(this Obj_AI_Base source, Obj_AI_Base target) { var dmgPhysical = (double)source.TotalAttackDamage; var dmgMagical = 0d; var dmgTrue = 0d; var dmgReduce = 1d; var hero = source as Obj_AI_Hero; var targetHero = target as Obj_AI_Hero; if (hero != null) { var passiveDamage = DamagePassives.ComputePassiveDamages(hero, target); dmgPhysical += passiveDamage.PhysicalDamage; dmgMagical += passiveDamage.MagicalDamage; dmgTrue += passiveDamage.TrueDamage; dmgPhysical *= passiveDamage.PhysicalDamagePercent; dmgMagical *= passiveDamage.MagicalDamagePercent; dmgTrue *= passiveDamage.TrueDamagePercent; if (target is Obj_AI_Minion) { if (hero.HasItem(ItemId.DoransShield)) { dmgPhysical += 5; } if (!hero.IsMelee && target.Team == GameObjectTeam.Neutral && Regex.IsMatch(target.Name, "SRU_RiftHerald")) { dmgReduce *= 0.65; } } } if (targetHero != null) { if (!(source is Obj_AI_Turret) && targetHero.HasItem(ItemId.NinjaTabi)) { dmgReduce *= 0.9; } switch (targetHero.ChampionName) { case "Fizz": dmgPhysical -= 4 + 2 * Math.Floor((targetHero.Level - 1) / 3d); break; } } var itemDamage = DamageItems.ComputeItemDamages(source, target); dmgPhysical += itemDamage.PhysicalDamage; dmgMagical += itemDamage.MagicalDamage; dmgPhysical = source.CalculatePhysicalDamage(target, dmgPhysical); dmgMagical = source.CalculateMagicDamage(target, dmgMagical); switch (targetHero?.ChampionName) { case "Amumu": if (targetHero.HasBuff("Tantrum")) { dmgPhysical -= new[] { 2, 4, 6, 8, 10 }[targetHero.SpellBook.GetSpell(SpellSlot.E).Level - 1]; } break; } return(Math.Max(Math.Floor(dmgPhysical + dmgMagical) * dmgReduce + dmgTrue, 0)); }
/// <summary> /// Gets the automatic attack damage. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <returns>System.Double.</returns> public static double GetAutoAttackDamage(this Obj_AI_Base source, Obj_AI_Base target) { var dmgPhysical = (double)source.TotalAttackDamage; var dmgMagical = 0d; //var dmgPassive = 0d; var dmgReduce = 1d; var hero = source as Obj_AI_Hero; var targetHero = target as Obj_AI_Hero; if (hero != null) { // todo passives switch (hero.ChampionName) { case "Kalista": dmgPhysical *= 0.9; break; case "Jhin": dmgPhysical += Math.Round( (new[] { 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40 }[hero.Level - 1] +Math.Round(hero.Crit * 100 / 10 * 4) + Math.Round((hero.AttackSpeedMod - 1) * 100 / 10 * 2.5)) / 100 * dmgPhysical); break; case "Corki": dmgPhysical /= 2; dmgMagical = dmgPhysical; break; case "Quinn": if (target.HasBuff("quinnw")) { dmgPhysical += 10 + 5 * hero.Level + (0.14 + 0.02 * hero.Level) * hero.TotalAttackDamage; } break; case "Galio": if (hero.HasBuff("galiopassivebuff")) { dmgMagical += 8 + 4 * hero.Level + hero.TotalAttackDamage + 0.6 * hero.TotalAbilityDamage + 0.6 * hero.BonusSpellBlock; } break; // TODO getting the actual buffname case "Sejuani": if (target.HasBuff("sejuanistun") && targetHero != null) { switch (target.Type) { case GameObjectType.AIHeroClient: if (hero.Level < 7) { dmgMagical += 0.1 * targetHero.MaxHealth; } else if (hero.Level < 14) { dmgMagical += 0.15 * targetHero.MaxHealth; } else { dmgMagical += 0.2 * targetHero.MaxHealth; } break; case GameObjectType.obj_AI_Minion: dmgMagical += 400; break; } } break; } if (target is Obj_AI_Minion) { // RiftHerald P if (!hero.IsMelee && target.Team == GameObjectTeam.Neutral && Regex.IsMatch(target.Name, "SRU_RiftHerald")) { dmgReduce *= 0.65; } // Dorans Shield if (hero.HasItem(ItemId.DoransShield)) { dmgPhysical += 5; } } } // Ninja Tabi if (targetHero != null && !(source is Obj_AI_Turret) && targetHero.HasItem(3047)) { dmgReduce *= 0.9; } dmgPhysical = source.CalculatePhysicalDamage(target, dmgPhysical); dmgMagical = source.CalculateMagicDamage(target, dmgMagical); // Fizz P if (targetHero != null && targetHero.ChampionName == "Fizz") { dmgPhysical -= 4 + 2 * Math.Floor((targetHero.Level - 1) / 3d); } return(Math.Max(Math.Floor((dmgPhysical + dmgMagical) * dmgReduce + source.GetPassiveFlatMod(target)), 0)); }