Ejemplo n.º 1
0
        private float TotalDmg(AIBaseClient enemy, bool useQ, bool useE, bool useR, bool qRange)
        {
            var  qaaDmg   = new Double[] { 20, 40, 60, 80, 100 };
            var  damage   = 0d;
            var  rTicks   = sliderLinks["rTicks"].GetValue <MenuSlider>().Value;
            bool inQRange = ((qRange && enemy.InAutoAttackRange()) || qRange == false);

            //Base Q damage
            if (useQ && Q.IsReady() && inQRange)
            {
                damage += player.GetSpellDamage(enemy, SpellSlot.Q);
                damage += player.CalculateDamage(enemy, DamageType.Magical, qaaDmg[Q.Level - 1] + 0.5 * player.TotalMagicalDamage + player.TotalAttackDamage);
            }

            // Q damage on AA
            if (useQ && !Q.IsReady() && player.HasBuff("viktorpowertransferreturn") && inQRange)
            {
                damage += player.CalculateDamage(enemy, DamageType.Magical, qaaDmg[Q.Level - 1] + 0.5 * player.TotalMagicalDamage + player.TotalAttackDamage);
            }

            //E damage
            if (useE && E.IsReady())
            {
                if (player.HasBuff("viktoreaug") || player.HasBuff("viktorqeaug") || player.HasBuff("viktorqweaug"))
                {
                    damage += player.GetSpellDamage(enemy, SpellSlot.E);
                }
                else
                {
                    damage += player.GetSpellDamage(enemy, SpellSlot.E);
                }
            }

            //R damage + 2 ticks
            if (useR && R.Level > 0 && R.IsReady() && R.Instance.Name == "ViktorChaosStorm")
            {
                damage += player.GetSpellDamage(enemy, SpellSlot.R) * rTicks;
                damage += player.GetSpellDamage(enemy, SpellSlot.R);
            }

            // Ludens Echo damage
            if (Items.HasItem(player, 3285))
            {
                damage += player.CalculateDamage(enemy, DamageType.Magical, 100 + player.FlatMagicDamageMod * 0.1);
            }

            //sheen damage
            if (Items.HasItem(player, 3057))
            {
                damage += player.CalculateDamage(enemy, DamageType.Physical, 0.5 * player.BaseAttackDamage);
            }

            //lich bane dmg
            if (Items.HasItem(player, 3100))
            {
                damage += player.CalculateDamage(enemy, DamageType.Magical, 0.5 * player.FlatMagicDamageMod + 0.75 * player.BaseAttackDamage);
            }

            return((float)damage);
        }
Ejemplo n.º 2
0
 internal static float QDmg(AIBaseClient unit)
 {
     return
         ((float)
          Player.CalculateDamage(unit, DamageType.Physical,
                                 new[] { 50, 50, 80, 110, 140, 170 }[Spellbook["Q"].Level] +
                                 (new[] { 1.0, 1.0, 1.1, 1.2, 1.3, 1.4 }[Spellbook["Q"].Level] *Player.FlatPhysicalDamageMod)));
 }
Ejemplo n.º 3
0
 private static float getJayceEQDmg(AIBaseClient target)
 {
     return
         ((float)
          Player.CalculateDamage(target, DamageType.Physical,
                                 (7 + (ObjectManager.Player.Spellbook.GetSpell(SpellSlot.Q).Level * 77)) +
                                 (1.68 * ObjectManager.Player.FlatPhysicalDamageMod)));
 }
Ejemplo n.º 4
0
        private static double QDamage(AIBaseClient target)
        {
            var qLevel      = _q.Level;
            var qPercentage = new[] { 0, 20, 22.5f, 25, 27.5f, 30 }[qLevel] / 100 + 1;
            var minQDamage  = new[] { 0, 80, 130, 180, 230, 280 }[qLevel];

            return(qPercentage * target.Health < minQDamage
                ? Player.CalculateDamage(target, DamageType.Magical,
                                         qPercentage *target.Health)
                : Player.CalculateDamage(target, DamageType.Magical, minQDamage));
        }
Ejemplo n.º 5
0
        public static float RDamage(AIBaseClient target)
        {
            var rLevel = R.Level;

            var rBaseDamage = RBaseDamage[rLevel] +
                              Player.TotalAttackDamage +
                              0.9f * Player.TotalMagicalDamage;

            return((float)Player.CalculateDamage(target, DamageType.Magical, rBaseDamage));
        }
Ejemplo n.º 6
0
        public static int GetCustomDamage(this AIHeroClient source, string auraname, AIHeroClient target)
        {
            if (auraname == "sheen")
            {
                return
                    ((int)
                     source.CalculateDamage(target, DamageType.Physical,
                                            1.0 * source.FlatPhysicalDamageMod + source.BaseAttackDamage));
            }

            if (auraname == "lichbane")
            {
                return
                    ((int)
                     source.CalculateDamage(target, DamageType.Magical,
                                            (0.75 * source.FlatPhysicalDamageMod + source.BaseAttackDamage) +
                                            (0.50 * source.FlatMagicDamageMod)));
            }

            return(0);
        }
Ejemplo n.º 7
0
        private static double GetQDmg(AIBaseClient target)
        {
            double dmgQ       = Q.GetDamage(target);
            double dmgSheen   = 0;
            double dmgMinions = 55;

            if (objPlayer.HasBuff("Sheen") || (objPlayer.HasItem((int)ItemId.Sheen) && objPlayer.CanUseItem((int)ItemId.Sheen)))
            {
                dmgSheen = objPlayer.GetAutoAttackDamage(target);
            }
            if (Q.Level == 1)
            {
                dmgQ       = 5f + objPlayer.TotalAttackDamage;
                dmgMinions = 55;
            }
            if (Q.Level == 2)
            {
                dmgQ       = 25f + objPlayer.TotalAttackDamage;
                dmgMinions = 75;
            }
            if (Q.Level == 3)
            {
                dmgQ       = 45f + objPlayer.TotalAttackDamage;
                dmgMinions = 95;
            }
            if (Q.Level == 4)
            {
                dmgQ       = 65f + objPlayer.TotalAttackDamage;
                dmgMinions = 115;
            }
            if (Q.Level == 5)
            {
                dmgQ       = 85f + objPlayer.TotalAttackDamage;
                dmgMinions = 135;
            }
            double Alldmg = dmgQ + dmgSheen;

            if (target.IsMinion)
            {
                Alldmg = dmgQ + dmgSheen + dmgMinions + objPlayer.GetAutoAttackDamage(target) * 25 / 100;
            }
            return(objPlayer.CalculateDamage(target, DamageType.Physical, Alldmg));
        }
Ejemplo n.º 8
0
        /// <summary>
        ///     Get the spell damage value.
        /// </summary>
        /// <param name="source">
        ///     The source
        /// </param>
        /// <param name="target">
        ///     The target
        /// </param>
        /// <param name="spellSlot">
        ///     The spell slot
        /// </param>
        /// <param name="stage">
        ///     The stage
        /// </param>
        /// <returns>
        ///     The <see cref="double" /> value of damage.
        /// </returns>
        public static double LSGetSpellDamage(
            this AIHeroClient source,
            Obj_AI_Base target,
            SpellSlot spellSlot,
            DamageStage stage = DamageStage.Default)
        {
            if (source == null || !source.IsValid || target == null || !target.IsValid)
            {
                return(0);
            }

            ChampionDamage value;

            if (!DamageCollection.TryGetValue(source.ChampionName, out value))
            {
                return(0);
            }

            var spellData = value.GetSlot(spellSlot)?.FirstOrDefault(e => e.Stage == stage)?.SpellData;

            if (spellData == null)
            {
                return(0);
            }

            var spellLevel =
                source.Spellbook.GetSpell(spellData.ScaleSlot != SpellSlot.Unknown ? spellData.ScaleSlot : spellSlot)
                .Level;

            if (spellLevel == 0)
            {
                return(0);
            }

            bool alreadyAdd1 = false, alreadyAdd2 = false;
            var  targetHero   = target as AIHeroClient;
            var  targetMinion = target as Obj_AI_Minion;

            double dmgBase = 0, dmgBonus = 0, dmgPassive = 0;
            var    dmgReduce = 1d;

            if (spellData.DamagesPerLvl?.Count > 0)
            {
                dmgBase = spellData.DamagesPerLvl[Math.Min(source.Level - 1, spellData.DamagesPerLvl.Count - 1)];
            }
            else if (spellData.Damages?.Count > 0)
            {
                dmgBase = spellData.Damages[Math.Min(spellLevel - 1, spellData.Damages.Count - 1)];
                if (!string.IsNullOrEmpty(spellData.ScalingBuff))
                {
                    var buffCount =
                        (spellData.ScalingBuffTarget == DamageScalingTarget.Source ? source : target).GetBuffCount(
                            spellData.ScalingBuff);
                    dmgBase = buffCount > 0 ? dmgBase * (buffCount + spellData.ScalingBuffOffset) : 0;
                }
            }
            if (dmgBase > 0)
            {
                if (targetMinion != null && spellData.BonusDamageOnMinion?.Count > 0)
                {
                    dmgBase +=
                        spellData.BonusDamageOnMinion[Math.Min(spellLevel - 1, spellData.BonusDamageOnMinion.Count - 1)];
                }
                if (spellData.IsApplyOnHit || spellData.IsModifiedDamage ||
                    spellData.SpellEffectType == SpellEffectType.Single)
                {
                    if (source.HasBuff("Serrated"))
                    {
                        dmgBase += 15;
                    }
                    if (targetHero != null)
                    {
                        if (!spellData.IsApplyOnHit && Items.HasItem((int)ItemId.Dorans_Shield, targetHero))
                        {
                            dmgBase -= 8;
                        }
                    }
                    else if (targetMinion != null)
                    {
                        var savagery = source.GetCunning(Cunning.Savagery);
                        if (savagery.IsValid())
                        {
                            dmgBase += savagery.Points;
                        }
                    }
                    alreadyAdd1 = true;
                }
                dmgBase = source.CalculateDamage(target, spellData.DamageType, dmgBase);
                if (spellData.IsModifiedDamage && spellData.DamageType == DamageType.Physical && targetHero != null &&
                    targetHero.ChampionName == "Fizz")
                {
                    dmgBase    -= 4 + (2 * Math.Floor((targetHero.Level - 1) / 3d));
                    alreadyAdd2 = true;
                }
            }
            if (spellData.BonusDamages?.Count > 0)
            {
                foreach (var bonusDmg in spellData.BonusDamages)
                {
                    var dmg = source.ResolveBonusSpellDamage(target, bonusDmg, spellLevel - 1);
                    if (dmg <= 0)
                    {
                        continue;
                    }
                    if (!alreadyAdd1 &&
                        (spellData.IsModifiedDamage || spellData.SpellEffectType == SpellEffectType.Single))
                    {
                        if (source.HasBuff("Serrated"))
                        {
                            dmg += 15;
                        }
                        if (targetHero != null)
                        {
                            if (Items.HasItem((int)ItemId.Dorans_Shield, targetHero))
                            {
                                dmg -= 8;
                            }
                        }
                        else if (targetMinion == null)
                        {
                            var savagery = source.GetCunning(Cunning.Savagery);
                            if (savagery.IsValid())
                            {
                                dmg += savagery.Points;
                            }
                        }
                        alreadyAdd1 = true;
                    }
                    dmgBonus += source.CalculateDamage(target, bonusDmg.DamageType, dmg);
                    if (!alreadyAdd2 && spellData.IsModifiedDamage && bonusDmg.DamageType == DamageType.Physical &&
                        targetHero != null && targetHero.ChampionName == "Fizz")
                    {
                        dmgBonus   -= 4 + (2 * Math.Floor((targetHero.Level - 1) / 3d));
                        alreadyAdd2 = true;
                    }
                }
            }

            var totalDamage = dmgBase + dmgBonus;

            if (totalDamage > 0)
            {
                if (spellData.ScalePerTargetMissHealth > 0)
                {
                    totalDamage *= (target.MaxHealth - target.Health) / target.MaxHealth
                                   * spellData.ScalePerTargetMissHealth + 1;
                }
                if (target is Obj_AI_Minion && spellData.MaxDamageOnMinion?.Count > 0)
                {
                    totalDamage = Math.Min(
                        totalDamage,
                        spellData.MaxDamageOnMinion[Math.Min(spellLevel - 1, spellData.MaxDamageOnMinion.Count - 1)]);
                }
                if (spellData.IsApplyOnHit || spellData.IsModifiedDamage)
                {
                    dmgPassive += source.GetPassiveDamageInfo(target, false).Value;
                    if (targetHero != null)
                    {
                        if (spellData.IsModifiedDamage && Items.HasItem(3047, targetHero))
                        {
                            dmgReduce *= 0.88;
                        }
                        if (source.GetFerocity(Ferocity.FervorofBattle).IsValid())
                        {
                            var fervorBuffCount = source.GetBuffCount("MasteryOnHitDamageStacker");
                            if (fervorBuffCount > 0)
                            {
                                dmgPassive += source.CalculateDamage(
                                    target,
                                    DamageType.Physical,
                                    (0.13 + (0.77 * source.Level)) * fervorBuffCount);
                            }
                        }
                    }
                }
            }

            return
                (Math.Max(
                     Math.Floor(
                         totalDamage * dmgReduce
                         + (spellData.IsApplyOnHit || spellData.IsModifiedDamage ? source.PassiveFlatMod(target) : 0)
                         + dmgPassive),
                     0));
        }
Ejemplo n.º 9
0
        private void LogicW()
        {
            var t = TargetSelector.GetTarget(W.Range);

            if (t.IsValidTarget())
            {
                var wDmg = GetWdmg(t);
                if (wDmg > t.Health - Player.CalculateDamage(t, DamageType.Physical, 1))
                {
                    CastSpell(W, t);
                }

                if (Config["WConfig"].GetValue <MenuBool>("autoWcombo") && !Combo)
                {
                    return;
                }

                if (Player.CountEnemyHeroesInRange(400) > 1 || Player.CountEnemyHeroesInRange(250) > 0)
                {
                    return;
                }

                if (t.HasBuff("jhinespotteddebuff") || !Config["WConfig"].GetValue <MenuBool>("Wmark"))
                {
                    if (Player.Distance(t) < Config["WConfig"].GetValue <MenuSlider>("MaxRangeW").Value)
                    {
                        if (Combo && Player.Mana > RMANA + WMANA)
                        {
                            CastSpell(W, t);
                        }
                        else if (Farm && Config["WConfig"].GetValue <MenuBool>("harrasW") &&
                                 Player.Mana > RMANA + WMANA + QMANA + WMANA)
                        {
                            CastSpell(W, t);
                        }
                    }
                }

                if (!None && Player.Mana > RMANA + WMANA)
                {
                    if (Config["WConfig"].GetValue <MenuBool>("Waoe"))
                    {
                        W.CastIfWillHit(t, 2);
                    }

                    if (Config["WConfig"].GetValue <MenuBool>("autoWcc"))
                    {
                        foreach (var enemy in GameObjects.EnemyHeroes.Where(enemy => enemy.IsValidTarget(W.Range) && !Orbwalker.CanMove()))
                        {
                            CastSpell(W, enemy);
                        }
                    }
                    if (Config["WConfig"].GetValue <MenuBool>("Wmarkall"))
                    {
                        foreach (var enemy in GameObjects.EnemyHeroes.Where(enemy => enemy.IsValidTarget(W.Range) && enemy.HasBuff("jhinespotteddebuff")))
                        {
                            CastSpell(W, enemy);
                        }
                    }
                }
            }
            if (LaneClear && Player.ManaPercent > Config["Farm"].GetValue <MenuSlider>("Mana").Value&& Config["Farm"].GetValue <MenuBool>("farmW") && Player.Mana > RMANA + WMANA)
            {
                var minionList   = MinionManager.GetMinions(Player.Position, W.Range);
                var farmPosition = W.GetLineFarmLocation(minionList, W.Width);

                if (farmPosition.MinionsHit >= Config["Farm"].GetValue <MenuSlider>("LCminions").Value)
                {
                    W.Cast(farmPosition.Position);
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        ///     Get the spell damage value.
        /// </summary>
        /// <param name="source">
        ///     The source
        /// </param>
        /// <param name="target">
        ///     The target
        /// </param>
        /// <param name="spellSlot">
        ///     The spell slot
        /// </param>
        /// <param name="stage">
        ///     The stage
        /// </param>
        /// <returns>
        ///     The <see cref="double" /> value of damage.
        /// </returns>
        public static double GetSpellDamage(
            this AIHeroClient source,
            AIBaseClient target,
            SpellSlot spellSlot,
            DamageStage stage = DamageStage.Default)
        {
            if (source == null || !source.IsValid || target == null || !target.IsValid)
            {
                return(0);
            }

            ChampionDamage value;

            if (!DamageCollection.TryGetValue(source.CharacterName, out value))
            {
                return(0);
            }

            var spellData = value.GetSlot(spellSlot)?.FirstOrDefault(e => e.Stage == stage)?.SpellData;

            if (spellData == null)
            {
                return(0);
            }

            var spellLevel =
                source.Spellbook.GetSpell(spellData.ScaleSlot != SpellSlot.Unknown ? spellData.ScaleSlot : spellSlot)
                .Level;

            if (spellLevel == 0)
            {
                return(0);
            }

            bool alreadyAdd1 = false, alreadyAdd2 = false, alreadyAdd3 = false, isBuff = false;
            var  targetHero   = target as AIHeroClient;
            var  targetMinion = target as AIMinionClient;

            double dmgBase = 0, dmgBonus = 0, dmgPassive = 0, dmgExtra = 0;
            var    dmgReduce = 1d;

            if (spellData.DamagesPerLvl?.Count > 0)
            {
                dmgBase += spellData.DamagesPerLvl[Math.Min(source.Level - 1, spellData.DamagesPerLvl.Count - 1)];
            }
            if (spellData.Damages?.Count > 0)
            {
                dmgBase += spellData.Damages[Math.Min(spellLevel - 1, spellData.Damages.Count - 1)];
                if (!string.IsNullOrEmpty(spellData.ScalingBuff))
                {
                    var buffCount =
                        (spellData.ScalingBuffTarget == DamageScalingTarget.Source ? source : target).GetBuffCount(
                            spellData.ScalingBuff);
                    dmgBase = buffCount > 0 ? dmgBase * (buffCount + spellData.ScalingBuffOffset) : 0;
                    isBuff  = buffCount <= 0;
                }
            }

            if (dmgBase > 0 || !isBuff)
            {
                if (targetMinion != null && spellData.BonusDamageOnMinion?.Count > 0)
                {
                    dmgBase +=
                        spellData.BonusDamageOnMinion[Math.Min(spellLevel - 1, spellData.BonusDamageOnMinion.Count - 1)];
                }
                if (targetMinion != null && target.Team == GameObjectTeam.Neutral && spellData.BonusDamageOnMonster?.Count > 0)
                {
                    dmgBase +=
                        spellData.BonusDamageOnMonster[Math.Min(spellLevel - 1, spellData.BonusDamageOnMonster.Count - 1)];
                }
                if (targetMinion != null && target.Team != GameObjectTeam.Neutral && target.Team != source.Team && spellData.BonusDamageOnSoldier?.Count > 0)
                {
                    dmgBase +=
                        spellData.BonusDamageOnSoldier[Math.Min(spellLevel - 1, spellData.BonusDamageOnSoldier.Count - 1)];
                }
            }

            if (dmgBase > 0)
            {
                if (spellData.IsApplyOnHit || spellData.IsModifiedDamage ||
                    (spellData.SpellEffectType == SpellEffectType.Single || spellData.SpellEffectType == SpellEffectType.AoE || spellData.SpellEffectType == SpellEffectType.Attack))
                {
                    // Spoils Of War
                    if (spellData.IsApplyOnHit || spellData.IsModifiedDamage)
                    {
                        if (source.IsMelee() && target is AIMinionClient && target.Team != GameObjectTeam.Neutral &&
                            source.GetBuffCount("talentreaperdisplay") > 0)
                        {
                            if (GameObjects.Heroes.Any(
                                    h => h.Team == source.Team && !h.Compare(source) && h.Distance(source) < 1000 && h.Distance(target) < 1000))
                            {
                                var spoilwarDmg = 0;
                                if (Items.HasItem((int)ItemId.Relic_Shield, source))
                                {
                                    spoilwarDmg = 195 + 5 * source.Level;
                                }
                                else if (Items.HasItem((int)ItemId.Targons_Brace, source))
                                {
                                    spoilwarDmg = 200 + 15 * source.Level;
                                }
                                else if (Items.HasItem((int)ItemId.Remnant_of_the_Aspect, source))
                                {
                                    spoilwarDmg = 320 + 30 * source.Level;
                                }
                                if (target.Health < spoilwarDmg)
                                {
                                    return(float.MaxValue);
                                }
                            }
                        }
                    }

                    // Serrated Dirk
                    if (!spellData.IsModifiedDamage && source.HasBuff("itemserrateddirkprocbuff"))
                    {
                        dmgExtra += source.CalculateDamage(target, DamageType.Physical, 40);
                    }

                    alreadyAdd1 = true;
                }

                dmgBase  = source.CalculateDamage(target, spellData.DamageType, dmgBase);
                dmgBase += dmgExtra;

                if (spellData.IsModifiedDamage && spellData.DamageType == DamageType.Physical &&
                    targetHero != null && targetHero.CharacterName == "Fizz")
                {
                    dmgBase    -= 4 + (2 * Math.Floor((targetHero.Level - 1) / 3d));
                    alreadyAdd2 = true;
                }

                if (targetHero != null && Items.HasItem((int)ItemId.Guardians_Horn, targetHero))
                {
                    dmgBase    -= spellData.SpellEffectType == SpellEffectType.OverTime ? 3 : 12;
                    alreadyAdd3 = true;
                }
            }
            if (spellData.BonusDamages?.Count > 0)
            {
                foreach (var bonusDmg in spellData.BonusDamages)
                {
                    dmgExtra = 0;
                    var dmg = source.ResolveBonusSpellDamage(target, bonusDmg, spellLevel - 1);
                    if (dmg <= 0)
                    {
                        continue;
                    }

                    if (!alreadyAdd1 &&
                        (spellData.IsApplyOnHit || spellData.IsModifiedDamage || (spellData.SpellEffectType == SpellEffectType.Single || spellData.SpellEffectType == SpellEffectType.AoE || spellData.SpellEffectType == SpellEffectType.Attack)))
                    {
                        // Spoils Of War
                        if (spellData.IsApplyOnHit || spellData.IsModifiedDamage)
                        {
                            if (source.IsMelee() && target is AIMinionClient && target.Team != GameObjectTeam.Neutral &&
                                source.GetBuffCount("talentreaperdisplay") > 0)
                            {
                                if (GameObjects.Heroes.Any(
                                        h => h.Team == source.Team && !h.Compare(source) && h.Distance(source) < 1000 && h.Distance(target) < 1000))
                                {
                                    var spoilwarDmg = 0;
                                    if (Items.HasItem((int)ItemId.Relic_Shield, source))
                                    {
                                        spoilwarDmg = 195 + 5 * source.Level;
                                    }
                                    else if (Items.HasItem((int)ItemId.Targons_Brace, source))
                                    {
                                        spoilwarDmg = 200 + 15 * source.Level;
                                    }
                                    else if (Items.HasItem((int)ItemId.Remnant_of_the_Aspect, source))
                                    {
                                        spoilwarDmg = 320 + 30 * source.Level;
                                    }
                                    if (target.Health < spoilwarDmg)
                                    {
                                        return(float.MaxValue);
                                    }
                                }
                            }
                        }

                        // Serrated Dirk
                        if (!spellData.IsModifiedDamage && source.HasBuff("itemserrateddirkprocbuff"))
                        {
                            dmgExtra += source.CalculateDamage(target, DamageType.Physical, 40);
                        }

                        alreadyAdd1 = true;
                    }

                    dmgBonus += source.CalculateDamage(target, bonusDmg.DamageType, dmg);
                    dmgBonus += dmgExtra;

                    if (!alreadyAdd2 && spellData.IsModifiedDamage && bonusDmg.DamageType == DamageType.Physical &&
                        targetHero != null && targetHero.CharacterName == "Fizz")
                    {
                        dmgBonus   -= 4 + (2 * Math.Floor((targetHero.Level - 1) / 3d));
                        alreadyAdd2 = true;
                    }

                    if (!alreadyAdd3 && targetHero != null && Items.HasItem((int)ItemId.Guardians_Horn, targetHero))
                    {
                        dmgBonus   -= spellData.SpellEffectType == SpellEffectType.OverTime ? 3 : 12;
                        alreadyAdd3 = true;
                    }
                }
            }

            var totalDamage = dmgBase + dmgBonus;

            if (spellData.DamagesOnMonster?.Count > 0 && targetMinion != null && targetMinion.Team == GameObjectTeam.Neutral)
            {
                foreach (var dmgOnMonster in spellData.DamagesOnMonster)
                {
                    totalDamage += source.CalculateDamage(
                        target,
                        dmgOnMonster.DamageType,
                        source.ResolveMonsterDamage(target,
                                                    dmgOnMonster,
                                                    spellLevel - 1));
                }
            }

            if (totalDamage > 0)
            {
                if (spellData.ScalingValueOnSoldier > 0 && targetMinion != null && target.Team != GameObjectTeam.Neutral && target.Team != source.Team)
                {
                    totalDamage *= spellData.ScalingValueOnSoldier;
                }
                if (spellData.MaxLevelScalingValueOnMinion > 0 && spellLevel == 5 && targetMinion != null)
                {
                    totalDamage *= spellData.MaxLevelScalingValueOnMinion;
                }
                if (spellData.ScalePerCritChance > 0)
                {
                    totalDamage *= source.Crit * spellData.ScalePerCritChance + 1;
                }
                if (spellData.ScalePerTargetMissHealth?.Count > 0)
                {
                    totalDamage *= Math.Min((target.MaxHealth - target.Health) / target.MaxHealth, spellData.MaxScaleTargetMissHealth)
                                   * spellData.ScalePerTargetMissHealth[Math.Min(spellLevel - 1, spellData.ScalePerTargetMissHealth.Count - 1)] + 1;
                }
                if (spellData.DamagesReductionOnSoldier?.Count > 0 && targetMinion != null && target.Team != GameObjectTeam.Neutral && target.Team != source.Team)
                {
                    totalDamage *= 1 - spellData.DamagesReductionOnSoldier[Math.Min(spellLevel - 1, spellData.DamagesReductionOnSoldier.Count - 1)];
                }
                if (spellData.DamagesReductionPerLvlOnSoldier?.Count > 0 && targetMinion != null && target.Team != GameObjectTeam.Neutral && target.Team != source.Team)
                {
                    totalDamage *= 1 - spellData.DamagesReductionPerLvlOnSoldier[Math.Min(source.Level - 1, spellData.DamagesReductionPerLvlOnSoldier.Count - 1)];
                }
                // Jax E
                if (spellData.SpellEffectType == SpellEffectType.AoE && target.HasBuff("JaxCounterStrike"))
                {
                    totalDamage *= 0.75;
                }
                // Hand of Baron
                if (target.HasBuff("exaltedwithbaronnashorminion"))
                {
                    var minion = target as AIMinionClient;
                    if (minion != null && minion.GetMinionType() == MinionTypes.Super &&
                        (spellData.SpellEffectType == SpellEffectType.AoE || spellData.SpellEffectType == SpellEffectType.OverTime))
                    {
                        totalDamage *= 0.25;
                    }
                }
                if (targetMinion != null && spellData.MaxDamageOnMinion?.Count > 0)
                {
                    totalDamage = Math.Min(
                        totalDamage,
                        spellData.MaxDamageOnMinion[Math.Min(spellLevel - 1, spellData.MaxDamageOnMinion.Count - 1)]);
                }
                if (targetMinion != null && target.Team == GameObjectTeam.Neutral && spellData.MaxDamageOnMonster?.Count > 0)
                {
                    totalDamage = Math.Min(
                        totalDamage,
                        spellData.MaxDamageOnMonster[Math.Min(spellLevel - 1, spellData.MaxDamageOnMonster.Count - 1)]);
                }
                if (targetMinion != null && target.Team != GameObjectTeam.Neutral && target.Team != source.Team && spellData.MinDamageOnSoldier?.Count > 0)
                {
                    totalDamage = Math.Max(
                        totalDamage,
                        spellData.MinDamageOnSoldier[Math.Min(spellLevel - 1, spellData.MinDamageOnSoldier.Count - 1)]);
                }
                if (spellData.IsApplyOnHit || spellData.IsModifiedDamage)
                {
                    dmgPassive += source.GetPassiveDamageInfo(target, false).Value;

                    // Ninja Tabi
                    if (targetHero != null && spellData.IsModifiedDamage &&
                        new[] { ItemId.Ninja_Tabi }.Any(i => Items.HasItem((int)i, targetHero)))
                    {
                        dmgReduce *= 0.88;
                    }
                }
            }

            return
                (Math.Max(
                     Math.Floor(
                         totalDamage * dmgReduce
                         + (spellData.IsApplyOnHit || spellData.IsModifiedDamage ? source.PassiveFlatMod(target) : 0)
                         + dmgPassive),
                     0));
        }