Esempio n. 1
0
        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);
        }