public override async Task ExecuteComboAsync(Unit target, CancellationToken tk = new CancellationToken()) { // check if we are near the enemy var myHeroNetworkPosition = this.MyHero.NetworkPosition; if (!await this.MoveOrBlinkToEnemy(target, tk, 200, 475)) { if (!this.MyHero.IsSilenced() && this.MyHero.Distance2D(target) >= 700) { var pos = (target.NetworkPosition - myHeroNetworkPosition).Normalized(); pos *= 475; pos = target.NetworkPosition - pos; if (this._wAbility.IsAbilityEnabled()) { if (target.IsMoving) { Log.Debug($"Jumping the gun"); var moves = Prediction.InFront(target, 700); this._wAbility.UseAbility(moves); await Await.Delay((int)(this.MyHero.GetTurnTime(moves) * 1000) + ItemDelay, tk); } else { Log.Debug($"Jumping close but far"); this._wAbility.UseAbility(pos); await Await.Delay((int)(this.MyHero.GetTurnTime(pos) * 1000) + ItemDelay, tk); } } } return; } await this.HasNoLinkens(target, tk); await this.UseItems(target, tk); await this.DisableEnemy(target, tk); if (!this.MyHero.IsSilenced()) { if (this._eAbility.IsAbilityEnabled() && this._eAbility.CanBeCasted(target) && this._eAbility.CanHit(target)) { Log.Debug($"use e"); this._eAbility.UseAbility(); await Await.Delay(this.GetAbilityDelay(this._eAbility), tk); } if (this._qAbility.IsAbilityEnabled() && this._qAbility.CanBeCasted(target) && this._qAbility.CanHit(target) && !target.HasModifier("modifier_queenofpain_shadow_strike")) { Log.Debug($"use q"); this._qAbility.UseAbility(target); await Await.Delay(this.GetAbilityDelay(target, this._qAbility), tk); } if (this._ultAbility.IsAbilityEnabled() && this._ultAbility.CanBeCasted(target) && this._ultAbility.CanHit(target)) { var enemyClose = ObjectManager.GetEntitiesParallel <Hero>() .Any( x => x.IsAlive && x != target && x.Team != this.MyHero.Team && !x.IsIllusion && this._ultAbility.CanBeCasted(x) && this._ultAbility.CanHit(x) && x.Distance2D(this.MyHero) <= 1500); List <Hero> enemies = null; if (enemyClose) { var startWidth = this._ultAbility.GetAbilityData("starting_aoe"); var endWidth = this._ultAbility.GetAbilityData("final_aoe"); var distance = this._ultAbility.GetAbilityData("distance"); var endPos = myHeroNetworkPosition + (target.NetworkPosition - myHeroNetworkPosition).Normalized() * distance; var polygon = new Geometry.Polygon.Trapezoid( myHeroNetworkPosition, endPos, startWidth, endWidth); enemies = ObjectManager.GetEntitiesParallel <Hero>() .Where( x => x.IsAlive && x != target && x.Team != this.MyHero.Team && !x.IsIllusion && this._ultAbility.CanBeCasted(x) && this._ultAbility.CanHit(x) && polygon.IsInside(x.NetworkPosition) && !x.CantBeKilled()) .ToList(); } if (!enemyClose || enemies.Count() >= this.EnemyCountForUlt) { Log.Debug( $"use ult since no enemy {!enemyClose} or {enemies?.Count()} >= {this.EnemyCountForUlt}"); this._ultAbility.UseAbility(target.NetworkPosition); await Await.Delay(this.GetAbilityDelay(target.NetworkPosition, this._ultAbility), tk); } } } if (ZaioMenu.ShouldUseOrbwalker) { this.Orbwalk(); } }
public override async Task ExecuteAsync(CancellationToken token) { this.KillStealHandler.RunAsync(); var target = this.TargetSelector.Value.Active.GetTargets().FirstOrDefault(x => !x.IsInvulnerable() && !UnitExtensions.IsMagicImmune(x) && x.IsAlive); var silenced = UnitExtensions.IsSilenced(this.Owner); var sliderValue = this.Config.UseBlinkPrediction.Item.GetValue <Slider>().Value; if (this.SolarCrest != null && this.SolarCrest.IsValid && target != null && this.SolarCrest.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_solar_crest")) { Log.Debug("Using Solar Crest"); this.SolarCrest.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } //Are we in an ult phase? var inUltimate = UnitExtensions.HasModifier(Owner, "modifier_storm_spirit_ball_lightning") || Lightning.IsInAbilityPhase; //Check if we're silenced, our target is alive, and we have a target. var UltDistance = Config.DistanceForUlt.Item.GetValue <Slider>().Value; //Check for distance to target and push against slider value if (target != null && target.IsAlive && Owner.Distance2D(target) >= 600 && Owner.Distance2D(target) <= UltDistance && //era 400----------------------------- Config.AbilityToggler.Value.IsEnabled(Lightning.Name) && !silenced) { //Based on whether they are moving or not, predict where they will be. if (target.IsMoving) { var PredictedPosition = EnsagePredict.InFront(target, 300); //Check the mana consumed from our prediction. double TempManaConsumed = (Lightning.GetAbilityData("ball_lightning_initial_mana_base") + ((Lightning.GetAbilityData("ball_lightning_initial_mana_percentage") / 100) * Owner.MaximumMana)) + ((Ensage.SDK.Extensions.EntityExtensions.Distance2D(Owner, PredictedPosition) / 100) * (((Lightning.GetAbilityData("ball_lightning_travel_cost_percent") / 100) * Owner.MaximumMana))); if (TempManaConsumed <= Owner.Mana && !inUltimate) { Lightning.UseAbility(PredictedPosition); // await Await.Delay((int)(Lightning.FindCastPoint() + Owner.GetTurnTime(PredictedPosition) * 2250 + Game.Ping), token); } } else { var PredictedPosition = target.NetworkPosition; double TempManaConsumed = (Lightning.GetAbilityData("ball_lightning_initial_mana_base") + ((Lightning.GetAbilityData("ball_lightning_initial_mana_percentage") / 100) * Owner.MaximumMana)) + ((Ensage.SDK.Extensions.EntityExtensions.Distance2D(Owner, PredictedPosition) / 100) * (((Lightning.GetAbilityData("ball_lightning_travel_cost_percent") / 100) * Owner.MaximumMana))); if (TempManaConsumed <= Owner.Mana && !inUltimate) { Lightning.UseAbility(PredictedPosition); await Await.Delay((int)(Lightning.FindCastPoint() + Owner.GetTurnTime(PredictedPosition) * 2250 + Game.Ping), token); } } } //Vars we need before combo. bool HasAghanims = Owner.HasItem(ClassId.CDOTA_Item_UltimateScepter); float VortexCost = Vortex.GetManaCost(Vortex.Level - 1); float RemnantCost = Remnant.GetManaCost(Remnant.Level - 1); float CurrentMana = Owner.Mana; float TotalMana = Owner.MaximumMana; //This is here to stop us from ulting after our target dies. float RemnantAutoDamage = this.Remnant.GetAbilityData("static_remnant_damage") + this.Overload.GetDamage(Overload.Level - 1); RemnantAutoDamage += (Owner.MinimumDamage + Owner.BonusDamage); RemnantAutoDamage *= GetSpellAmp(); var RemnantAutokillableTar = ObjectManager.GetEntitiesParallel <Hero>() .FirstOrDefault( x => x.IsAlive && x.Team != this.Owner.Team && !x.IsIllusion && this.Remnant.CanBeCasted() && this.Remnant.CanHit(x) && x.Health < (RemnantAutoDamage * (1 - x.MagicDamageResist)) && !UnitExtensions.IsMagicImmune(x) && x.Distance2D(this.Owner) <= 235); var ActiveRemnant = Remnants.Any(unit => unit.Distance2D(RemnantAutokillableTar) < 240); if (!silenced && target != null) { //there is a reason behind this; the default delay on storm ult is larger than a minimum distance travelled. var TargetPosition = target.NetworkPosition; /* TargetPosition *= 100; * TargetPosition = target.NetworkPosition + TargetPosition;*/ double ManaConsumed = (Lightning.GetAbilityData("ball_lightning_initial_mana_base") + ((Lightning.GetAbilityData("ball_lightning_initial_mana_percentage") / 100) * CurrentMana)) + ((Ensage.SDK.Extensions.EntityExtensions.Distance2D(Owner, TargetPosition) / 100) * (((Lightning.GetAbilityData("ball_lightning_travel_cost_percent") / 100) * CurrentMana))); //Always auto attack if we have an overload charge. if (UnitExtensions.HasModifier(Owner, "modifier_storm_spirit_overload") && target != null) { Owner.Attack(target); await Await.Delay(250); //tava 500------------------------------------------------------ } //Vortex prioritization logic [do we have q/w enabled, do we have the mana to cast both, do they have lotus, do we have an overload modifier] if (!UnitExtensions.HasModifier(Owner, "modifier_storm_spirit_overload") && Config.AbilityToggler.Value.IsEnabled(Vortex.Name) && Vortex.CanBeCasted() && Config.AbilityToggler.Value.IsEnabled(Remnant.Name) && Remnant.CanBeCasted() && (VortexCost + RemnantCost) <= CurrentMana) { //Use Vortex if (!HasAghanims) { Vortex.UseAbility(target); await Await.Delay(GetAbilityDelay(Owner, Vortex), token); } //Use Vortex differently for aghanims. else { Vortex.UseAbility(); await Await.Delay(GetAbilityDelay(Owner, Vortex), token); } } //Remnant logic [w is not available, cant ult, close enough for the detonation] if (!UnitExtensions.HasModifier(Owner, "modifier_storm_spirit_overload") && target.IsAlive && Config.AbilityToggler.Value.IsEnabled(Remnant.Name) && Remnant.CanBeCasted() && !Vortex.CanBeCasted() && (CurrentMana <= RemnantCost + ManaConsumed || Owner.Distance2D(target) <= Remnant.GetAbilityData("static_remnant_radius"))) { Remnant.UseAbility(); await Await.Delay(GetAbilityDelay(Owner, Remnant), token); } //Ult logic [nothing else is available or we are not in range for a q] if (!UnitExtensions.HasModifier(Owner, "modifier_storm_spirit_overload") && target.IsAlive && Config.AbilityToggler.Value.IsEnabled(Lightning.Name) && Lightning.CanBeCasted() && (!Remnant.CanBeCasted() || Owner.Distance2D(target) >= Remnant.GetAbilityData("static_remnant_radius")) && (!Vortex.CanBeCasted(target) || Owner.Distance2D(target) <= UltDistance) //Don't cast ult if theres a remnant that can kill our target. && !inUltimate && (RemnantAutokillableTar == null || ActiveRemnant == false)) //todo: alternate check for aghanims { var l = (this.Owner.Distance2D(target)); var posA = this.Owner.Position; var posB = target.Position; var x = (posA.X + (l * posB.X)) / (1 + 1); var y = (posA.Y + (l * posB.Y)) / (1 + 1); var position = new Vector3((int)x, (int)y, posA.Z); //var l = (this.Owner.Distance2D(target) - sliderValue) / sliderValue; //var posA = this.Owner.Position; //var posB = target.Position; //var x = (posA.X + (l * posB.X)) / (1 + l); //var y = (posA.Y + (l * posB.Y)) / (1 + l); //var position = new Vector3((int)x, (int)y, posA.Z); Lightning.UseAbility(EnsagePredict.InFront(Owner, 50)); //TargetPosition this.Owner.Position Game.MousePosition EnsagePredict.InFront(Owner, 50) int delay = (int)((Lightning.FindCastPoint() + Owner.GetTurnTime(EnsagePredict.InFront(Owner, 50))) * 1250.0 + Game.Ping); Log.Debug($"{delay}ms to wait."); await Task.Delay(delay); } } if (this.BloodThorn != null && this.BloodThorn.IsValid && target != null && this.BloodThorn.CanBeCasted(target) && this.Config.ItemToggler.Value.IsEnabled(this.BloodThorn.Name)) { Log.Debug("Using Bloodthorn"); this.BloodThorn.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } if (this.SheepStick != null && this.SheepStick.IsValid && target != null && this.SheepStick.CanBeCasted(target) && this.Config.ItemToggler.Value.IsEnabled("item_sheepstick")) { Log.Debug("Using Sheepstick"); this.SheepStick.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } if (this.Orchid != null && this.Orchid.IsValid && target != null && this.Orchid.CanBeCasted(target) && this.Config.ItemToggler.Value.IsEnabled("item_orchid")) { Log.Debug("Using Orchid"); this.Orchid.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } if (this.RodofAtos != null && this.RodofAtos.IsValid && target != null && this.RodofAtos.CanBeCasted(target) && this.Config.ItemToggler.Value.IsEnabled("item_rod_of_atos")) { Log.Debug("Using RodofAtos"); this.RodofAtos.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } if (this.VeilofDiscord != null && this.VeilofDiscord.IsValid && target != null && this.VeilofDiscord.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_veil_of_discord")) { Log.Debug("Using VeilofDiscord"); this.VeilofDiscord.UseAbility(target.Position); await Await.Delay(this.GetItemDelay(target), token); } if (this.Medallion != null && this.Medallion.IsValid && target != null && this.Medallion.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_medallion_of_courage")) { Log.Debug("Using Medallion Of Courage"); this.Medallion.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } if (this.ShivasGuard != null && this.ShivasGuard.IsValid && target != null && this.ShivasGuard.CanBeCasted() && Owner.Distance2D(target) <= 900 && this.Config.ItemToggler.Value.IsEnabled("item_shivas_guard")) { Log.Debug("Using Shiva's Guard"); this.ShivasGuard.UseAbility(); await Await.Delay((int)Game.Ping + 20, token); } if (this.Mjollnir != null && this.Mjollnir.IsValid && target != null && this.Mjollnir.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_mjollnir")) { Log.Debug("Using Mjollnir"); this.Mjollnir.UseAbility(Owner); await Await.Delay(this.GetItemDelay(target), token); } if (this.SolarCrest != null && this.SolarCrest.IsValid && target != null && this.SolarCrest.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_solar_crest")) { Log.Debug("Using Solar Crest"); this.SolarCrest.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } if (this.Orbwalker.OrbwalkTo(target)) { return; } await Await.Delay(125, token); }