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)); }
/// <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)); }
/// <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); }
/// <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); }
// 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; } } } }
/// <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)); }
/// <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="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); }
/// <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; }
/// <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)); }
/// <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); }
/// <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)); }
/// <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; }
public bool CanKill(AIBaseClient unit, SpellSlot slot, DamageStage stage = DamageStage.Default) { return(unit.IsValidTarget() && GetDamage(unit, stage) > unit.Health); }