/// <summary> /// Checks if given ability can be used /// </summary> /// <param name="ability"></param> /// <param name="target"></param> /// <returns>returns true in case ability can be used</returns> public static bool CanBeCasted(this Ability ability, Unit target) { if (!target.IsValidTarget()) { return false; } var canBeCasted = ability.CanBeCasted(); if (!target.IsMagicImmune()) { return canBeCasted; } var data = AbilityDatabase.Find(ability.Name); return data == null ? canBeCasted : data.MagicImmunityPierce; }
/// <summary> /// Uses given ability in case enemy is not disabled or would be chain stunned. /// </summary> /// <param name="ability"> /// The ability. /// </param> /// <param name="target"> /// The target. /// </param> /// <param name="sourcePosition"> /// The source Position. /// </param> /// <param name="straightTimeforSkillShot"> /// The straight Time for Skill Shot. /// </param> /// <param name="chainStun"> /// The chain Stun. /// </param> /// <param name="useSleep"> /// The use Sleep. /// </param> /// <param name="abilityName"> /// The ability Name. /// </param> /// <param name="soulRing"> /// The soul Ring. /// </param> /// <param name="otherTargets"> /// The other Targets. /// </param> /// <returns> /// returns true in case of successful cast /// </returns> public static bool CastStun( this Ability ability, Unit target, Vector3 sourcePosition, float straightTimeforSkillShot = 0, bool chainStun = true, bool useSleep = true, string abilityName = null, Ability soulRing = null, List<Unit> otherTargets = null) { if (!ability.CanBeCasted()) { return false; } if (target == null || !target.IsValid) { return false; } var name = abilityName ?? ability.StoredName(); var delay = ability.GetHitDelay(target, name) + 0.1f; var canUse = Utils.ChainStun(target, delay, null, false, name); if (!canUse && chainStun && (!target.HasModifier("modifier_pudge_meat_hook") || (ability.StoredName() != "pudge_dismember" && ability.StoredName() != "pudge_rot"))) { return false; } if (ability.IsAbilityBehavior(AbilityBehavior.UnitTarget, name) && name != "lion_impale" && !target.IsInvul()) { if (!ability.CanHit(target, sourcePosition)) { return false; } if (ability.ManaCost > 0 && soulRing.CanBeCasted()) { soulRing.UseAbility(); } ability.UseAbility(target); } else if (ability.IsAbilityBehavior(AbilityBehavior.AreaOfEffect, name) || ability.IsAbilityBehavior(AbilityBehavior.Point, name) || name == "lion_impale" || (name == "earthshaker_enchant_totem" && (ability.Owner as Hero).AghanimState()) || ability.IsSkillShot()) { var stunned = target.IsStunned() || target.IsInvul() || target.IsRooted() || target.IsHexed(); if ((!(Prediction.StraightTime(target) > straightTimeforSkillShot * 1000) && !stunned) || !ability.CastSkillShot(target, name, soulRing, otherTargets)) { return false; } if (useSleep) { Utils.Sleep(Math.Max(delay, 0.2) * 1000 + 250, "CHAINSTUN_SLEEP"); } return true; } else if (ability.IsAbilityBehavior(AbilityBehavior.NoTarget, name)) { if (name == "invoker_ice_wall") { ability.CastSkillShot(target, name); } else { if (ability.ManaCost > 0 && soulRing.CanBeCasted()) { soulRing.UseAbility(); } ability.UseAbility(); } } if (useSleep) { Utils.Sleep(Math.Max(delay, 0.2) * 1000 + 250, "CHAINSTUN_SLEEP"); } return true; }
/// <summary> /// Checks if given ability can be used /// </summary> /// <param name="ability"> /// The ability. /// </param> /// <param name="target"> /// The target. /// </param> /// <returns> /// returns true in case ability can be used /// </returns> public static bool CanBeCasted(this Ability ability, Unit target) { if (ability == null || !ability.IsValid) { return false; } if (target == null || !target.IsValid) { return false; } if (!target.IsValidTarget()) { return false; } var canBeCasted = ability.CanBeCasted(); if (!target.IsMagicImmune()) { return canBeCasted; } var data = ability.CommonProperties(); return data == null ? canBeCasted : data.MagicImmunityPierce; }
/// <summary> /// Checks if given ability can be used /// </summary> /// <param name="ability"></param> /// <param name="target"></param> /// <returns>returns true in case ability can be used</returns> public static bool CanBeCasted(this Ability ability, Unit target) { if (!target.IsValidTarget()) { return false; } var canBeCasted = ability.CanBeCasted(); if (!target.IsMagicImmune()) { return canBeCasted; } AbilityInfo data; if (!AbilityDamage.DataDictionary.TryGetValue(ability, out data)) { data = AbilityDatabase.Find(ability.Name); AbilityDamage.DataDictionary.Add(ability, data); } return data == null ? canBeCasted : data.MagicImmunityPierce; }
/// <summary> /// Uses given ability in case enemy is not disabled or would be chain stunned. /// </summary> /// <param name="ability"></param> /// <param name="target"></param> /// <param name="sourcePosition"></param> /// <param name="straightTimeforSkillShot"></param> /// <param name="chainStun"></param> /// <param name="useSleep"></param> /// <returns>returns true in case of successfull cast</returns> public static bool CastStun( this Ability ability, Unit target, Vector3 sourcePosition, float straightTimeforSkillShot = 0, bool chainStun = true, bool useSleep = true) { var owner = ability.Owner as Unit; var position = owner.Position; if (sourcePosition != Vector3.Zero) { position = sourcePosition; } if (!ability.CanBeCasted()) { return false; } var delay = ability.GetHitDelay(target); var radius = ability.GetRadius(); var canUse = Utils.ChainStun(target, delay, null, false, ability.Name); if (!canUse && chainStun) { return false; } if (ability.AbilityBehavior.HasFlag(AbilityBehavior.UnitTarget) && ability.Name != "lion_impale") { ability.UseAbility(target); } else if ((ability.AbilityBehavior.HasFlag(AbilityBehavior.AreaOfEffect) || ability.AbilityBehavior.HasFlag(AbilityBehavior.Point))) { if (Prediction.StraightTime(target) > straightTimeforSkillShot * 1000 && ability.CastSkillShot(target)) { if (useSleep) { Utils.Sleep(Math.Max(delay, 0.2) * 1000 + 250, "CHAINSTUN_SLEEP"); } return true; } return false; } else if (ability.AbilityBehavior.HasFlag(AbilityBehavior.NoTarget)) { if (target.Distance2D(position) > radius) { return false; } ability.UseAbility(); } if (useSleep) { Utils.Sleep(Math.Max(delay, 0.2) * 1000 + 250, "CHAINSTUN_SLEEP"); } return true; }
/// <summary> /// Uses given ability in case enemy is not disabled or would be chain stunned. /// </summary> /// <param name="ability"></param> /// <param name="target"></param> /// <returns>returns true in case of successfull cast</returns> public static bool CastStun(this Ability ability, Unit target) { if (!ability.CanBeCasted()) { return false; } var data = AbilityDatabase.Find(ability.Name); var owner = ability.Owner; var delay = Game.Ping / 1000 + ability.GetCastPoint(); var radius = 0f; if (!ability.AbilityBehavior.HasFlag(AbilityBehavior.NoTarget)) { delay += (float)owner.GetTurnTime(target); } if (data != null) { if (data.AdditionalDelay > 0) { delay += (float)data.AdditionalDelay; } if (data.Speed != null) { var speed = ability.AbilityData.FirstOrDefault(x => x.Name == data.Speed) .GetValue(ability.Level - 1); delay += owner.Distance2D(target) / speed; } if (data.Radius != 0) { radius = data.Radius; } else if (data.StringRadius != null) { radius = ability.AbilityData.FirstOrDefault(x => x.Name == data.StringRadius).GetValue(ability.Level - 1); } else if (data.Width != null) { radius = ability.AbilityData.FirstOrDefault(x => x.Name == data.Width).GetValue(ability.Level - 1); } } var canUse = Utils.ChainStun(target, delay, null, false); if (!canUse) { return false; } if (ability.AbilityBehavior.HasFlag(AbilityBehavior.UnitTarget)) { ability.UseAbility(target); } else if (ability.AbilityBehavior.HasFlag(AbilityBehavior.AreaOfEffect)) { ability.CastSkillShot(target); } else if (ability.AbilityBehavior.HasFlag(AbilityBehavior.NoTarget)) { if (target.Distance2D(owner) > radius) { return false; } ability.UseAbility(); } Utils.Sleep(delay * 1000, "CHAINSTUN_SLEEP"); return true; }
/// <summary> /// Uses given ability in case enemy is not disabled or would be chain stunned. /// </summary> /// <param name="ability"></param> /// <param name="target"></param> /// <param name="sourcePosition"></param> /// <param name="straightTimeforSkillShot"></param> /// <param name="chainStun"></param> /// <param name="useSleep"></param> /// <param name="abilityName"></param> /// <param name="soulRing"></param> /// <param name="otherTargets"></param> /// <returns>returns true in case of successfull cast</returns> public static bool CastStun( this Ability ability, Unit target, Vector3 sourcePosition, float straightTimeforSkillShot = 0, bool chainStun = true, bool useSleep = true, string abilityName = null, Ability soulRing = null, List<Unit> otherTargets = null) { if (!ability.CanBeCasted()) { return false; } var name = abilityName ?? ability.StoredName(); var delay = ability.GetHitDelay(target, name); var canUse = Utils.ChainStun(target, delay, null, false, name); if (!canUse && chainStun) { return false; } if (ability.IsAbilityBehavior(AbilityBehavior.UnitTarget, name) && name != "lion_impale" && !target.IsInvul()) { if (ability.ManaCost > 0 && soulRing.CanBeCasted()) { soulRing.UseAbility(); } ability.UseAbility(target); } else if (ability.IsAbilityBehavior(AbilityBehavior.AreaOfEffect, name) || ability.IsAbilityBehavior(AbilityBehavior.Point, name) || name == "lion_impale") { if (Prediction.StraightTime(target) > straightTimeforSkillShot * 1000 && ability.CastSkillShot(target, name, soulRing, otherTargets)) { if (useSleep) { Utils.Sleep(Math.Max(delay, 0.2) * 1000 + 250, "CHAINSTUN_SLEEP"); } return true; } return false; } else if (ability.IsAbilityBehavior(AbilityBehavior.NoTarget, name)) { if (name == "invoker_ice_wall") { ability.CastSkillShot(target, name); } else { if (ability.ManaCost > 0 && soulRing.CanBeCasted()) { soulRing.UseAbility(); } ability.UseAbility(); } } if (useSleep) { Utils.Sleep(Math.Max(delay, 0.2) * 1000 + 250, "CHAINSTUN_SLEEP"); } return true; }