Exemplo n.º 1
0
        /// <summary>
        ///     Gets the spell damage.
        /// </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>System.Double.</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);
            }

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

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

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

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

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

            var alreadyAdd1 = false;

            var targetHero   = target as Obj_AI_Hero;
            var targetMinion = target as Obj_AI_Minion;

            var dmgBase    = 0d;
            var dmgBonus   = 0d;
            var dmgPassive = 0d;
            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 scalingTarget = spellData.ScalingBuffTarget == DamageScalingTarget.Source ? source : target;
                    var buffCount     = scalingTarget.GetRealBuffCount(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)
                {
                    alreadyAdd1 = true;
                }

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

            if (spellData.BonusDamages?.Count > 0)
            {
                foreach (var bonusDmg in spellData.BonusDamages)
                {
                    var dmg = source.GetBonusSpellDamage(target, bonusDmg, spellLevel - 1);
                    if (dmg <= 0)
                    {
                        continue;
                    }

                    if (!alreadyAdd1 &&
                        (spellData.IsModifiedDamage || spellData.SpellEffectType == SpellEffectType.Single))
                    {
                        alreadyAdd1 = true;
                    }

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

            var totalDamage = dmgBase + dmgBonus;

            if (totalDamage > 0)
            {
                if (spellData.ScalePerCritPercent > 0)
                {
                    totalDamage *= source.Crit * 100 * spellData.ScalePerCritPercent;
                }

                if (spellData.ScalePerTargetMissHealth > 0)
                {
                    totalDamage *= (target.MaxHealth - target.Health) / target.MaxHealth * spellData.ScalePerTargetMissHealth + 1;
                }

                if (target is Obj_AI_Minion)
                {
                    if (spellData.MaxDamageOnMinion?.Count > 0)
                    {
                        totalDamage = Math.Min(
                            totalDamage,
                            spellData.MaxDamageOnMinion[Math.Min(spellLevel - 1, spellData.MaxDamageOnMinion.Count - 1)]);
                    }

                    if (target.Team == GameObjectTeam.Neutral &&
                        spellData.MaxDamageOnMonster?.Count > 0)
                    {
                        totalDamage = Math.Min(
                            totalDamage,
                            spellData.MaxDamageOnMonster[Math.Min(spellLevel - 1, spellData.MaxDamageOnMonster.Count - 1)]);
                    }
                }

                if (spellData.IsModifiedDamage)
                {
                    if (targetHero != null &&
                        targetHero.HasItem(ItemId.NinjaTabi))
                    {
                        dmgReduce *= 0.9;
                    }
                }
            }

            if (spellData.IsApplyOnHit ||
                spellData.IsModifiedDamage)
            {
                var itemDamage = DamageItems.ComputeItemDamages(source, target);
                totalDamage += source.CalculateDamage(target, DamageType.Physical, itemDamage.PhysicalDamage);
                totalDamage += source.CalculateDamage(target, DamageType.Magical, itemDamage.MagicalDamage);
            }

            if (source.ChampionName == "Sejuani" &&
                target.HasBuff("sejuanistun"))
            {
                switch (target.Type)
                {
                case GameObjectType.obj_AI_Hero:
                    if (source.Level < 7)
                    {
                        dmgPassive += 0.1 * target.MaxHealth;
                    }
                    else if (source.Level < 14)
                    {
                        dmgPassive += 0.15 * target.MaxHealth;
                    }
                    else
                    {
                        dmgPassive += 0.2 * target.MaxHealth;
                    }
                    break;

                case GameObjectType.obj_AI_Minion:
                    dmgPassive += 400;
                    break;
                }

                dmgPassive = source.CalculateDamage(target, DamageType.Magical, dmgPassive);
            }

            return(Math.Max(Math.Floor(totalDamage * dmgReduce + dmgPassive), 0));
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Gets the spell damage.
        /// </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>System.Double.</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);
            }

            if (!DamageLibrary.Damages.TryGetValue(source.ChampionName, out ChampionDamage 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 alreadyAdd1 = false;
            var alreadyAdd2 = false;

            var targetHero   = target as Obj_AI_Hero;
            var targetMinion = target as Obj_AI_Minion;

            var dmgBase    = 0d;
            var dmgBonus   = 0d;
            var dmgPassive = 0d;
            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)
                {
                    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.GetBonusSpellDamage(target, bonusDmg, spellLevel - 1);

                    if (dmg <= 0)
                    {
                        continue;
                    }

                    if (!alreadyAdd1 && (spellData.IsModifiedDamage ||
                                         spellData.SpellEffectType == SpellEffectType.Single))
                    {
                        alreadyAdd1 = true;
                    }

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

                    if (alreadyAdd2 || !spellData.IsModifiedDamage || bonusDmg.DamageType != DamageType.Physical ||
                        targetHero == null || targetHero.ChampionName != "Fizz")
                    {
                        continue;
                    }

                    dmgBonus   -= 4 + (2 * Math.Floor((targetHero.Level - 1) / 3d));
                    alreadyAdd2 = true;
                }
            }

            var totalDamage = dmgBase + dmgBonus;

            if (totalDamage > 0)
            {
                if (spellData.ScalePerCritPercent > 0)
                {
                    totalDamage *= source.Crit * 100 * spellData.ScalePerCritPercent;
                }

                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 += 0; // todo get passive shit

                    if (targetHero != null)
                    {
                        if (spellData.IsModifiedDamage && targetHero.HasItem(3047))
                        {
                            dmgReduce *= 0.9;
                        }
                    }
                }
            }

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