Example #1
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 Obj_AI_Hero 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;
            }

            var baseDamage = 0d;
            var bonusDamage = 0d;

            if (spellData.Damages?.Count > 0)
            {
                if (spellData.DamageType == DamageType.Mixed)
                {
                    var oriDamage = spellData.Damages[Math.Min(spellLevel - 1, spellData.Damages.Count - 1)];
                    baseDamage = source.CalculateMixedDamage(target, oriDamage / 2, oriDamage / 2);
                    if (!string.IsNullOrEmpty(spellData.ScalingBuff))
                    {
                        var buffCount =
                            (spellData.ScalingBuffTarget == DamageScalingTarget.Source ? source : target).GetBuffCount(
                                spellData.ScalingBuff);
                        baseDamage = buffCount != 0 ? baseDamage * (buffCount + spellData.ScalingBuffOffset) : 0;
                    }
                }
                else
                {
                    baseDamage = source.CalculateDamage(
                        target,
                        spellData.DamageType,
                        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);
                        baseDamage = buffCount != 0 ? baseDamage * (buffCount + spellData.ScalingBuffOffset) : 0;
                    }
                }
            }
            if (spellData.DamagesPerLvl?.Count > 0)
            {
                baseDamage = source.CalculateDamage(
                    target,
                    spellData.DamageType,
                    spellData.Damages[Math.Min(source.Level - 1, spellData.DamagesPerLvl.Count - 1)]);
            }
            if (spellData.BonusDamages?.Count > 0)
            {
                foreach (var bonusDmg in
                    spellData.BonusDamages.Where(i => source.ResolveBonusSpellDamage(target, i, spellLevel - 1) > 0))
                {
                    if (bonusDmg.DamageType == DamageType.Mixed)
                    {
                        var oriDamage = source.ResolveBonusSpellDamage(target, bonusDmg, spellLevel - 1);
                        bonusDamage += source.CalculateMixedDamage(target, oriDamage / 2, oriDamage / 2);
                    }
                    else
                    {
                        bonusDamage += source.CalculateDamage(
                            target,
                            bonusDmg.DamageType,
                            source.ResolveBonusSpellDamage(target, bonusDmg, spellLevel - 1));
                    }
                }
            }

            var totalDamage = baseDamage + bonusDamage;
            var passiveDamage = 0d;

            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.SpellEffectType == SpellEffectType.Single && target is Obj_AI_Minion)
                {
                    var savagery = source.GetCunning(DamageMastery.Cunning.Savagery);
                    if (savagery.IsValid())
                    {
                        passiveDamage += savagery.Points;
                    }
                }
            }

            return totalDamage + passiveDamage;
        }
Example #2
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);
        }
Example #3
0
        public static int GetCustomDamage(this Obj_AI_Hero source, string auraname, Obj_AI_Hero 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;
        }
        /// <summary>
        ///     Gets the passive raw damage summary.
        /// </summary>
        /// <param name="source">
        ///     The source
        /// </param>
        /// <param name="target">
        ///     The target.
        /// </param>
        /// <returns>
        ///     The <see cref="double" />.
        /// </returns>
        private static PassiveDamageInfo GetPassiveDamageInfo(this Obj_AI_Hero source, Obj_AI_Base target)
        {
            var @double = 0d;
            var @override = false;
            List<PassiveDamage> value;

            // If you don't understand the code below, you should be flipping burgers instead.
            if (PassiveDamages.TryGetValue(string.Empty, out value))
            {
                // This should fix something that should never happen.
                value =
                    value.Where(i => (i.Condition?.Invoke(source, target)).GetValueOrDefault() && i.Func != null)
                        .ToList();
                @double +=
                    value.Sum(
                        item =>
                        item.IgnoreCalculation
                            ? item.Func(source, target)
                            : source.CalculateDamage(target, item.DamageType, item.Func(source, target)));

                @override = value.Any(i => i.Override);
            }

            if (PassiveDamages.TryGetValue(source.ChampionName, out value))
            {
                value =
                    value.Where(i => (i.Condition?.Invoke(source, target)).GetValueOrDefault() && i.Func != null)
                        .ToList();
                @double +=
                    value.Sum(
                        item =>
                        item.IgnoreCalculation
                            ? item.Func(source, target)
                            : source.CalculateDamage(target, item.DamageType, item.Func(source, target)));

                if (!@override)
                {
                    @override = value.Any(i => i.Override);
                }
            }

            return new PassiveDamageInfo { Value = @double, Override = @override };
        }
Example #5
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 Obj_AI_Hero source,
            Obj_AI_Base target,
            SpellSlot spellSlot,
            DamageStage stage = DamageStage.Default)
        {
            if (source == null || !source.IsValid || target == null || !target.IsValid)
            {
                return 0d;
            }

            var spellLevel = source.Spellbook.GetSpell(spellSlot).Level;
            if (spellLevel == 0)
            {
                return 0d;
            }

            ChampionDamage value;
            if (DamageCollection.TryGetValue(source.ChampionName, out value))
            {
                var baseDamage = 0d;
                var bonusDamage = 0d;

                var spellData = value.GetSlot(spellSlot)?.FirstOrDefault(e => e.Stage == stage)?.SpellData;
                if (spellData?.Damages?.Count > 0)
                {
                    baseDamage = source.CalculateDamage(
                        target,
                        spellData.DamageType,
                        spellData.Damages[Math.Min(spellLevel - 1, spellData.Damages.Count)]);

                    if (!string.IsNullOrEmpty(spellData.ScalingBuff))
                    {
                        var buffCount =
                            (spellData.ScalingBuffTarget == DamageScalingTarget.Source ? source : target).GetBuffCount(
                                spellData.ScalingBuff);

                        if (buffCount != 0)
                        {
                            baseDamage *= buffCount + spellData.ScalingBuffOffset;
                        }
                    }
                }

                if (spellData?.BonusDamages?.Count > 0)
                {
                    bonusDamage =
                        spellData.BonusDamages.Sum(
                            instance =>
                            source.CalculateDamage(
                                target,
                                instance.DamageType,
                                source.ResolveBonusSpellDamage(target, instance, spellLevel - 1)));
                }

                return baseDamage + bonusDamage;
            }

            return 0d;
        }