예제 #1
0
 public float GetDamage(AIBaseClient target, DamageStage stage = DamageStage.Default)
 {
     if (this.GetCustomDamages != null && this.GetCustomDamageType == stage)
     {
         return((float)this.GetCustomDamages(target));
     }
     return((float)ObjectManager.Player.GetSpellDamage(target, this.Slot, stage));
 }
예제 #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 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);
            }

            bool alreadyAdd1 = false, alreadyAdd2 = false;
            var  targetHero   = target as Obj_AI_Hero;
            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 &&
                            new[] { 3047, 1316, 1318, 1315, 1317 }.Any(i => Items.HasItem(i, targetHero)))
                        {
                            dmgReduce *= 0.9;
                        }
                        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));
        }
예제 #3
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;
        }
 /// <summary>
 ///     Returns the damage a spell will deal to target.
 /// </summary>
 /// <param name="target">
 ///     The <see cref="Obj_AI_Hero" /> target.
 /// </param>
 /// <param name="stage">
 ///     The <see cref="DamageStage" /> of the spell.
 /// </param>
 /// <returns>
 ///     The damage value to target unit.
 /// </returns>
 public float GetDamage(Obj_AI_Base target, DamageStage stage = DamageStage.Default)
 {
     return((float)GameObjects.Player.GetSpellDamage(target, this.Slot, stage));
 }
 /// <summary>
 ///     Returns if a spell can kill a target.
 /// </summary>
 /// <param name="unit">The Target</param>
 /// <param name="stage">
 ///     The <see cref="DamageStage" /> of the spell.
 /// </param>
 /// <returns>Can spell kill target</returns>
 public bool CanKill(Obj_AI_Base unit, DamageStage stage = DamageStage.Default)
 {
     return(unit.IsValidTarget() && this.GetDamage(unit, stage) > unit.Health);
 }
예제 #6
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);
        }
예제 #7
0
    // Update is called once per frame
    void Update()
    {
        if (inMag != 0)
        {
            canFire = true;
        }
        else if (inMag == 0)
        {
            canFire = false;
        }

        if (Input.GetButtonDown("Reload") && inMag != magSize)
        {
            Invoke("Reload", reloadDelay);
        }

        if (isAuto == true && canFire == true)
        {
            if (Input.GetButton("Fire1") || Input.GetAxisRaw("Fire1") > 0)
            {
                if (Time.time > nextFire)
                {
                    nextFire = Time.time + fireRate;
                    StartCoroutine(ShotEffect());

                    Vector3    rayOrigin = playerCamera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0));
                    RaycastHit hit;
                    laserLine.SetPosition(0, gunBarrel.position);

                    if (Physics.Raycast(rayOrigin, playerCamera.transform.forward, out hit, range))
                    {
                        laserLine.SetPosition(1, hit.point);
                        DamageStage health = hit.collider.GetComponent <DamageStage>();
                        if (health != null)
                        {
                            health.Damage(gunDamage);
                        }
                        if (hit.rigidbody != null)
                        {
                            hit.rigidbody.AddForce(-hit.normal * hitForce);
                        }
                    }
                    else
                    {
                        laserLine.SetPosition(1, rayOrigin + (playerCamera.transform.forward * range));
                    }
                }
            }
        }
        else if (isAuto == false && canFire == true)
        {
            if (Input.GetButtonDown("Fire1") || Input.GetAxisRaw("Fire1") > 0)
            {
                canFire = false;
                StartCoroutine(ShotEffect());

                Vector3    rayOrigin = playerCamera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0));
                RaycastHit hit;
                laserLine.SetPosition(0, gunBarrel.position);

                if (Physics.Raycast(rayOrigin, playerCamera.transform.forward, out hit, range))
                {
                    laserLine.SetPosition(1, hit.point);
                    DamageStage health = hit.collider.GetComponent <DamageStage>();
                    if (health != null)
                    {
                        health.Damage(gunDamage);
                    }
                    if (hit.rigidbody != null)
                    {
                        hit.rigidbody.AddForce(-hit.normal * hitForce);
                    }
                }
                else
                {
                    laserLine.SetPosition(1, rayOrigin + (playerCamera.transform.forward * range));
                }
            }
            if (canFire == false && inMag != 0)
            {
                if (Input.GetButtonUp("Fire1") || Input.GetAxisRaw("Fire1") == 0)
                {
                    canFire = true;
                }
            }
        }
    }
예제 #8
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));
        }
예제 #9
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);
        }
예제 #10
0
 /// <summary>
 ///     Returns the damage a spell will deal to target.
 /// </summary>
 /// <param name="target">
 ///     The <see cref="AIHeroClient" /> target.
 /// </param>
 /// <param name="stage">
 ///     The <see cref="Damage.DamageStage" /> of the spell.
 /// </param>
 /// <returns>
 ///     The damage value to target unit.
 /// </returns>
 public float GetDamage(Obj_AI_Base target, DamageStage stage = DamageStage.Default)
 {
     return (float)GameObjects.Player.LSGetSpellDamage(target, this.Slot, stage);
 }
예제 #11
0
 /// <summary>
 ///     Returns if a spell can kill a target.
 /// </summary>
 /// <param name="unit">The Target</param>
 /// <param name="stage">
 ///     The <see cref="Damage.DamageStage" /> of the spell.
 /// </param>
 /// <returns>Can spell kill target</returns>
 public bool CanKill(Obj_AI_Base unit, DamageStage stage = DamageStage.Default)
 {
     return unit.IsValidTarget() && this.GetDamage(unit, stage) > unit.Health;
 }
예제 #12
0
파일: Damage.cs 프로젝트: PynMax/Aimtec.SDK
        /// <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));
        }
예제 #13
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);
        }
예제 #14
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));
        }
예제 #15
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;
        }
예제 #16
0
 public bool CanKill(AIBaseClient unit, SpellSlot slot, DamageStage stage = DamageStage.Default)
 {
     return(unit.IsValidTarget() && GetDamage(unit, stage) > unit.Health);
 }