Esempio n. 1
0
        private void OnUpdate(EventArgs args)
        {
            if (!Game.IsInGame || Game.IsPaused || !Menu.ArmletAutoToggle)
            {
                return;
            }

            if (!Hero.IsAlive || !Hero.CanUseItems())
            {
                return;
            }

            var nearEnemies =
                ObjectManager.GetEntitiesParallel <Unit>()
                .Where(
                    x =>
                    x.IsValid && x.IsAlive && x.IsSpawned && x.AttackCapability != AttackCapability.None &&
                    x.Team != HeroTeam && x.Distance2D(Hero) < x.GetAttackRange() + 200);

            foreach (var enemy in nearEnemies.Where(x => x.AttackCapability == AttackCapability.Melee))
            {
                if (enemy.IsAttacking() && !attackStart.Sleeping(enemy))
                {
                    attacking.Sleep((float)UnitDatabase.GetAttackPoint(enemy) * 1000, enemy);
                    attackStart.Sleep(enemy.AttacksPerSecond * 1000 - Game.Ping, enemy);
                }
                else if (!enemy.IsAttacking() && attackStart.Sleeping(enemy))
                {
                    attackStart.Reset(enemy);
                    attacking.Sleep((float)UnitDatabase.GetAttackBackswing(enemy) * 1000, enemy);
                }
            }

            if (Sleeper.Sleeping)
            {
                return;
            }

            var heroProjectiles =
                ObjectManager.TrackingProjectiles.Where(x => x?.Target is Hero && x.Target.Equals(Hero)).ToList();

            var noProjectile =
                heroProjectiles.All(
                    x =>
                    x.Position.Distance2D(Hero) / x.Speed > 0.30 ||
                    x.Position.Distance2D(Hero) / x.Speed < Game.Ping / 1000);

            var noAutoAttack = nearEnemies.All(x => x.FindRelativeAngle(Hero.Position) > 0.5 || !attacking.Sleeping(x));

            if (Hero.Health < Menu.ArmetHpThreshold && noProjectile && noAutoAttack &&
                (nearEnemies.Any() || heroProjectiles.Any()))
            {
                Use(null, null);
            }
        }
Esempio n. 2
0
        public void OnUpdate()
        {
            if (!Game.IsInGame || Game.IsPaused || !Menu.Hotkeys.EnabledEvader)
            {
                return;
            }

            if (Menu.Debug.DrawMap && debugPath.Any() && !sleeper.Sleeping(debugPath))
            {
                debugPath.Clear();
            }

            if (Menu.Settings.PathfinderEffect && heroPathfinderEffect != null && !sleeper.Sleeping("avoiding"))
            {
                heroPathfinderEffect.Dispose();
                heroPathfinderEffect = null;
            }

            foreach (var ability in abilityUpdater.EvadableAbilities)
            {
                if (!ability.Enabled)
                {
                    continue;
                }

                ability.Check();

                if (ability.IsStopped())
                {
                    ability.End();

                    if (sleeper.Sleeping(ability))
                    {
                        sleeper.Reset(ability);
                        sleeper.Reset("avoiding");

                        if (!Hero.IsChanneling() && !Hero.IsInvul())
                        {
                            Debugger.WriteLine("Hero stop");
                            Hero.Stop();
                        }
                    }
                }

                if (ability.Obstacle != null && Math.Abs(ability.GetRemainingTime()) > 60)
                {
                    ability.End();
                    throw new Exception(
                              "Broken ability => " + ability.GetType().Name + " (" + ability.AbilityOwner.Name + " // "
                              + ability.Name + " // " + ability.GetRemainingTime() + ")");
                }
            }

            if (Menu.Settings.InvisIgnore && Hero.IsInvisible() && !Hero.IsVisibleToEnemies)
            {
                return;
            }

            var heroCanCast     = Hero.CanCast();
            var heroCanUseItems = Hero.CanUseItems();

            var allies =
                ObjectManager.GetEntitiesParallel <Hero>()
                .Where(
                    x =>
                    x.Equals(Hero) ||
                    (Menu.AlliesSettings.HelpAllies && Menu.AlliesSettings.Enabled(x.StoredName()) && x.IsValid &&
                     x.Team == HeroTeam && x.IsAlive && !x.IsIllusion && x.Distance2D(Hero) < 3000));

            foreach (var ability in abilityUpdater.EvadableAbilities)
            {
                if (!ability.Enabled)
                {
                    continue;
                }

                var modifierAbility = ability as IModifier;

                if (modifierAbility != null && !sleeper.Sleeping(ability.Handle) && modifierAbility.CanBeCountered())
                {
                    var enemyCounterList = ability.ModifierEnemyCounter;
                    if (Menu.Settings.ModifierEnemyCounter && enemyCounterList.Any())
                    {
                        var enemy = ability.AbilityOwner;
                        var modifierRemainingTime = modifierAbility.GetModiferRemainingTime();

                        var modifierEnemyCounterAbilities = from abilityName in enemyCounterList
                                                            join usableAbility in abilityUpdater.UsableAbilities on
                                                            abilityName equals usableAbility.Name
                                                            where
                                                            usableAbility.CanBeUsedOnEnemy &&
                                                            Menu.UsableAbilities.Enabled(
                            abilityName,
                            usableAbility.Type) &&
                                                            (usableAbility.IsItem && heroCanUseItems ||
                                                             !usableAbility.IsItem && heroCanCast)
                                                            select usableAbility;

                        foreach (var modifierEnemyCounterAbility in modifierEnemyCounterAbilities)
                        {
                            if (!modifierEnemyCounterAbility.CanBeCasted(ability, enemy))
                            {
                                continue;
                            }

                            var requiredTime = modifierEnemyCounterAbility.GetRequiredTime(ability, enemy)
                                               + Game.Ping / 1000;

                            if (requiredTime <= modifierRemainingTime)
                            {
                                modifierEnemyCounterAbility.Use(ability, enemy);
                                sleeper.Sleep(modifierRemainingTime * 1000, ability.Handle);

                                Debugger.WriteLine(">>>>>>>>>>>>>>>");
                                Debugger.WriteLine(
                                    "modifier enemy counter: " + modifierEnemyCounterAbility.Name + " => "
                                    + ability.Name);
                                Debugger.WriteLine("remaining time: " + modifierRemainingTime);
                                Debugger.WriteLine("required time: " + requiredTime);
                                return;
                            }
                        }
                    }

                    var allyCounterList = ability.ModifierAllyCounter;
                    if (Menu.Settings.ModifierAllyCounter && allyCounterList.Any())
                    {
                        var ally = modifierAbility.GetModifierHero(allies);

                        if (ally != null)
                        {
                            var modifierRemainingTime = modifierAbility.GetModiferRemainingTime();
                            var allyIsMe = ally.Equals(Hero);

                            var modifierAllyCounterAbilities = from abilityName in allyCounterList
                                                               join usableAbility in abilityUpdater.UsableAbilities on
                                                               abilityName equals usableAbility.Name
                                                               where
                                                               Menu.UsableAbilities.Enabled(
                                abilityName,
                                usableAbility.Type) &&
                                                               (usableAbility.IsItem && heroCanUseItems ||
                                                                !usableAbility.IsItem && heroCanCast)
                                                               select usableAbility;

                            foreach (var modifierCounterAbility in modifierAllyCounterAbilities)
                            {
                                if (!allyIsMe && !modifierCounterAbility.CanBeUsedOnAlly)
                                {
                                    continue;
                                }

                                if (!modifierCounterAbility.CanBeCasted(ability, ally))
                                {
                                    continue;
                                }

                                var requiredTime = modifierCounterAbility.GetRequiredTime(ability, ally)
                                                   + Game.Ping / 1000;

                                if (requiredTime <= modifierRemainingTime)
                                {
                                    modifierCounterAbility.Use(ability, ally);
                                    sleeper.Sleep(modifierRemainingTime * 1000, ability.Handle);

                                    Debugger.WriteLine(">>>>>>>>>>>>>>>");
                                    Debugger.WriteLine(
                                        "modifier counter: " + modifierCounterAbility.Name + " => " + ability.Name);
                                    Debugger.WriteLine("ally: " + ally.GetName());
                                    Debugger.WriteLine("remaining time: " + modifierRemainingTime);
                                    Debugger.WriteLine("required time: " + requiredTime);
                                    return;
                                }
                            }
                        }
                    }
                }
            }

            if (!Hero.IsAlive)
            {
                return;
            }

            if (Menu.Hotkeys.ForceBlink)
            {
                var blinkDagger =
                    abilityUpdater.UsableAbilities.FirstOrDefault(x => x.ClassID == ClassID.CDOTA_Item_BlinkDagger) as
                    BlinkDagger;

                if (blinkDagger != null && blinkDagger.CanBeCasted(null, null) && heroCanUseItems)
                {
                    blinkDagger.UseInFront();
                }
            }

            if (Hero.IsChanneling())
            {
                return;
            }

            foreach (var projectile in ObjectManager.TrackingProjectiles.Where(x => x?.Target is Hero))
            {
                var source = projectile.Source;
                if (source == null)
                {
                    var predictedAbilities =
                        abilityUpdater.EvadableAbilities.OfType <Projectile>()
                        .Where(
                            x =>
                            (int)x.GetProjectileSpeed() == projectile.Speed &&
                            (x.TimeSinceCast() < 1.5 || !x.AbilityOwner.IsVisible))
                        .ToList();
                    if (predictedAbilities.Count == 1)
                    {
                        Debugger.WriteLine(
                            "predicted: " + predictedAbilities.First().Name + " => "
                            + ((Hero)projectile.Target).GetName(),
                            Debugger.Type.Projectiles);
                        predictedAbilities.First().SetProjectile(projectile.Position, (Hero)projectile.Target);
                    }
                    continue;
                }

                if (!source.IsValid || source.Team == HeroTeam)
                {
                    continue;
                }

                var ability =
                    abilityUpdater.EvadableAbilities.OfType <Projectile>()
                    .FirstOrDefault(
                        x =>
                        x.OwnerClassID == source.ClassID && (int)x.GetProjectileSpeed() == projectile.Speed &&
                        x.TimeSinceCast() < 1.5);

                if (ability != null)
                {
                    Debugger.WriteLine(
                        "projectile: " + ability.Name + " => " + ((Hero)projectile.Target).GetName(),
                        Debugger.Type.Projectiles);
                    ability.SetProjectile(projectile.Position, (Hero)projectile.Target);
                }
            }

            var allyIntersections = allies.ToDictionary(x => x, x => Pathfinder.GetIntersectingObstacles(x));

            if (Menu.AlliesSettings.HelpAllies && Menu.AlliesSettings.MultiIntersectionEnemyDisable)
            {
                var multiIntersection =
                    allyIntersections.SelectMany(x => x.Value).GroupBy(x => x).SelectMany(x => x.Skip(1));

                foreach (var obstacle in multiIntersection)
                {
                    var ability =
                        abilityUpdater.EvadableAbilities.FirstOrDefault(x => x.Obstacle == obstacle && x.IsDisable) as
                        AOE;

                    if (ability != null)
                    {
                        if (sleeper.Sleeping(ability))
                        {
                            continue;
                        }

                        if (Menu.Debug.LogIntersection)
                        {
                            foreach (
                                var hero in allyIntersections.Where(x => x.Value.Contains(obstacle)).Select(x => x.Key))
                            {
                                Debugger.Write(hero.GetName() + " ", Debugger.Type.Intersectons);
                            }
                            Debugger.WriteLine("intersecting: " + ability.Name, Debugger.Type.Intersectons);
                        }

                        var abilityOwner     = ability.AbilityOwner;
                        var disableAbilities = from abilityName in ability.DisableAbilities
                                               join usableAbility in abilityUpdater.UsableAbilities on abilityName
                                               equals usableAbility.Name
                                               where
                                               usableAbility.Type == AbilityType.Disable &&
                                               Menu.UsableAbilities.Enabled(abilityName, AbilityType.Disable) &&
                                               (usableAbility.IsItem && heroCanUseItems ||
                                                !usableAbility.IsItem && heroCanCast)
                                               select usableAbility;

                        foreach (var disableAbility in disableAbilities)
                        {
                            if (!disableAbility.CanBeCasted(ability, abilityOwner))
                            {
                                continue;
                            }

                            var requiredTime = disableAbility.GetRequiredTime(ability, abilityOwner) + Game.Ping / 1000;

                            var remainingDisableTime = ability.GetRemainingDisableTime();

                            var ignoreRemainingTime = ability.IgnoreRemainingTime(disableAbility, remainingDisableTime);

                            if (requiredTime > remainingDisableTime && !ignoreRemainingTime)
                            {
                                continue;
                            }

                            if (remainingDisableTime - requiredTime <= 0.10 || ignoreRemainingTime)
                            {
                                disableAbility.Use(ability, abilityOwner);
                                sleeper.Sleep(ability.GetSleepTime(), ability);

                                Debugger.WriteLine(">>>>>>>>>>>>>>>");
                                Debugger.WriteLine(
                                    "multi intersection disable: " + disableAbility.Name + " => " + ability.Name);
                                Debugger.Write("allies: ");
                                foreach (var hero in
                                         allyIntersections.Where(x => x.Value.Contains(obstacle)).Select(x => x.Key))
                                {
                                    Debugger.Write(hero.GetName() + " ");
                                }
                                Debugger.WriteLine();
                                Debugger.WriteLine("remaining time: " + remainingDisableTime);
                                Debugger.WriteLine("required time: " + requiredTime);
                            }
                            return;
                        }
                    }
                }
            }

            foreach (var intersection in allyIntersections.OrderByDescending(x => x.Key.Equals(Hero)))
            {
                var ally            = intersection.Key;
                var allyLinkens     = ally.IsLinkensProtected();
                var allyMagicImmune = ally.IsMagicImmune();
                var allyIsMe        = ally.Equals(Hero);
                var allyHp          = ally.Health;
                //var heroMp = Hero.Mana;

                foreach (var ability in
                         intersection.Value.Select(
                             x =>
                             abilityUpdater.EvadableAbilities.FirstOrDefault(
                                 z => z.Obstacle == x && (z.AllyHpIgnore <= 0 || allyHp < z.AllyHpIgnore)
                                 //&& (z.HeroMpIgnore <= 0 || heroMp > z.HeroMpIgnore)
                                 && (z.AbilityLevelIgnore <= 0 || z.Level > z.AbilityLevelIgnore)))
                         .Where(x => x != null)
                         .OrderByDescending(x => x.IsDisable))
                {
                    if (ability != null)
                    {
                        if (sleeper.Sleeping(ability))
                        {
                            continue;
                        }

                        Debugger.WriteLine(
                            ally.GetName() + " intersecting: " + ability.Name,
                            Debugger.Type.Intersectons);

                        if ((allyLinkens && (ability is Projectile || ability is LinearTarget)) ||
                            (!ability.PiercesMagicImmunity && allyMagicImmune))
                        {
                            continue;
                        }

                        var abilityOwner  = ability.AbilityOwner;
                        var remainingTime = ability.GetRemainingTime(ally);

                        foreach (var priority in
                                 ability.UseCustomPriority ? ability.Priority : Menu.Settings.DefaultPriority)
                        {
                            switch (priority)
                            {
                            case Priority.Walk:
                                if (allyIsMe && !ability.IgnorePathfinder && Menu.Hotkeys.EnabledPathfinder &&
                                    Hero.CanMove())
                                {
                                    var remainingWalkTime = remainingTime - 0.1f;

                                    if (sleeper.Sleeping("block"))
                                    {
                                        continue;
                                    }

                                    bool           success;
                                    List <Vector3> path;

                                    if (Hero.IsMoving && !movePosition.IsZero)
                                    {
                                        if (ability.ObstacleStays && remainingWalkTime <= 0)
                                        {
                                            remainingWalkTime = ability.ObstacleRemainingTime();
                                        }

                                        if (remainingWalkTime <= 0)
                                        {
                                            continue;
                                        }

                                        if (Pathfinder.GetIntersectingObstacles(movePosition, Hero.HullRadius).Any() ||
                                            Pathfinder.GetIntersectingObstacles(
                                                Hero.NetworkPosition,
                                                Hero.HullRadius).Any())
                                        {
                                            Debugger.WriteLine("moving into obstacle");

                                            var tempPath =
                                                Pathfinder.CalculatePathFromObstacle(
                                                    movePosition,
                                                    remainingWalkTime,
                                                    out success).ToList();

                                            debugPath =
                                                Pathfinder.CalculateDebugPathFromObstacle(remainingWalkTime)
                                                .ToList();

                                            if (success)
                                            {
                                                movePosition = tempPath.Last();
                                            }
                                            else
                                            {
                                                continue;
                                            }
                                        }

                                        path = Pathfinder.CalculateLongPath(movePosition, out success).ToList();

                                        if (success)
                                        {
                                            var time = 0.1f;
                                            for (var i = 0; i < path.Count; i++)
                                            {
                                                Hero.Move(path[i], i != 0);
                                                time += Hero.NetworkPosition.Distance2D(path[i])
                                                        / Hero.MovementSpeed;
                                            }

                                            //  sleeper.Sleep(ability.ObstacleRemainingTime() * 1000, "avoiding");
                                            sleeper.Sleep(200, "block");
                                            sleeper.Sleep(Math.Min(time, 1) * 1000, ability);
                                            sleeper.Sleep(Math.Min(time, 1) * 1000, "avoiding");
                                            sleeper.Sleep(1000, debugPath);

                                            if (Menu.Settings.PathfinderEffect)
                                            {
                                                heroPathfinderEffect =
                                                    new ParticleEffect(
                                                        @"particles/units/heroes/hero_oracle/oracle_fortune_purge.vpcf",
                                                        Hero);
                                            }

                                            Debugger.WriteLine(">>>>>>>>>>>>>>>");
                                            Debugger.WriteLine("avoid while moving: " + ability.Name);
                                            Debugger.WriteLine("remaining time: " + remainingWalkTime);
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        path =
                                            Pathfinder.CalculatePathFromObstacle(remainingWalkTime, out success)
                                            .ToList();

                                        if (success)
                                        {
                                            debugPath =
                                                Pathfinder.CalculateDebugPathFromObstacle(remainingWalkTime)
                                                .ToList();
                                            var time = 0.1f;

                                            for (var i = 0; i < path.Count; i++)
                                            {
                                                Hero.Move(path[i], i != 0);
                                                time += Hero.NetworkPosition.Distance2D(path[i])
                                                        / Hero.MovementSpeed;
                                            }

                                            //   sleeper.Sleep(ability.ObstacleRemainingTime() * 1000, "avoiding");
                                            sleeper.Sleep(Math.Min(time, 1) * 1000, "avoiding");
                                            sleeper.Sleep(Math.Min(time, 1) * 1000, ability);
                                            sleeper.Sleep(1000, debugPath);

                                            if (Menu.Settings.PathfinderEffect)
                                            {
                                                heroPathfinderEffect =
                                                    new ParticleEffect(
                                                        @"particles/units/heroes/hero_oracle/oracle_fortune_purge.vpcf",
                                                        Hero);
                                            }

                                            Debugger.WriteLine(">>>>>>>>>>>>>>>");
                                            Debugger.WriteLine("avoid while standing: " + ability.Name);
                                            Debugger.WriteLine("remaining time: " + remainingTime);
                                            return;
                                        }
                                    }
                                }

                                break;

                            case Priority.Blink:
                                if (!allyIsMe)
                                {
                                    continue;
                                }

                                var blinkAbilities = from abilityName in ability.BlinkAbilities
                                                     join usableAbility in abilityUpdater.UsableAbilities on
                                                     abilityName equals usableAbility.Name
                                                     where
                                                     usableAbility.Type == AbilityType.Blink &&
                                                     Menu.UsableAbilities.Enabled(
                                    abilityName,
                                    AbilityType.Blink) &&
                                                     (usableAbility.IsItem && heroCanUseItems ||
                                                      !usableAbility.IsItem && heroCanCast)
                                                     select usableAbility;

                                foreach (var blinkAbility in blinkAbilities)
                                {
                                    if (!blinkAbility.CanBeCasted(ability, fountain))
                                    {
                                        continue;
                                    }

                                    var requiredTime = blinkAbility.GetRequiredTime(ability, fountain)
                                                       + Game.Ping / 1000 + 0.05f;

                                    var time = remainingTime - requiredTime;

                                    var ignoreRemainingTime = ability.IgnoreRemainingTime(blinkAbility, time);

                                    if (requiredTime > remainingTime && !ignoreRemainingTime)
                                    {
                                        continue;
                                    }

                                    if (time <= 0.10 && time > 0 || ignoreRemainingTime)
                                    {
                                        Debugger.WriteLine(">>>>>>>>>>>>>>>");

                                        if (!Menu.Randomiser.Enabled ||
                                            (Menu.Randomiser.NukesOnly && ability.IsDisable) ||
                                            (randomiser.Next(99) > Menu.Randomiser.FailChance))
                                        {
                                            blinkAbility.Use(ability, fountain);
                                        }
                                        else
                                        {
                                            Debugger.WriteLine("you got rekt by randomiser!");
                                        }

                                        sleeper.Sleep(Math.Min(ability.GetSleepTime(), 1000), ability);

                                        Debugger.WriteLine("blink: " + blinkAbility.Name + " => " + ability.Name);
                                        Debugger.WriteLine("ally: " + ally.GetName());
                                        Debugger.WriteLine("remaining time: " + remainingTime);
                                        Debugger.WriteLine("required time: " + requiredTime);
                                    }

                                    return;
                                }

                                break;

                            case Priority.Counter:
                                var counterAbilities = from abilityName in ability.CounterAbilities
                                                       join usableAbility in abilityUpdater.UsableAbilities on
                                                       abilityName equals usableAbility.Name
                                                       where
                                                       usableAbility.Type == AbilityType.Counter &&
                                                       Menu.UsableAbilities.Enabled(
                                    abilityName,
                                    AbilityType.Counter) &&
                                                       (usableAbility.IsItem && heroCanUseItems ||
                                                        !usableAbility.IsItem && heroCanCast)
                                                       select usableAbility;

                                foreach (var counterAbility in counterAbilities)
                                {
                                    var targetEnemy = !counterAbility.CanBeUsedOnAlly &&
                                                      counterAbility.CanBeUsedOnEnemy;

                                    if (!counterAbility.CanBeUsedOnAlly && !allyIsMe && !targetEnemy ||
                                        !targetEnemy && !counterAbility.CanBeCasted(ability, ally) ||
                                        targetEnemy && !counterAbility.CanBeCasted(ability, abilityOwner))
                                    {
                                        continue;
                                    }

                                    var requiredTime = counterAbility.GetRequiredTime(
                                        ability,
                                        targetEnemy ? abilityOwner : ally) + Game.Ping / 1000 + 0.05f;

                                    var ignoreRemainingTime = false;

                                    var time = remainingTime - requiredTime;

                                    if (counterAbility.Name == AbilityNames.SleightOfFist)
                                    {
                                        var projectile = ability as Projectile;
                                        if (projectile != null)
                                        {
                                            ignoreRemainingTime = projectile.ProjectileLaunched();
                                        }
                                    }
                                    else
                                    {
                                        ignoreRemainingTime = ability.IgnoreRemainingTime(counterAbility, time);
                                    }

                                    if (requiredTime > remainingTime && !ignoreRemainingTime)
                                    {
                                        continue;
                                    }

                                    if (time <= 0.10 && time > 0 || ignoreRemainingTime)
                                    {
                                        Debugger.WriteLine(">>>>>>>>>>>>>>>");

                                        if (!Menu.Randomiser.Enabled ||
                                            (Menu.Randomiser.NukesOnly && ability.IsDisable) ||
                                            (randomiser.Next(99) > Menu.Randomiser.FailChance))
                                        {
                                            counterAbility.Use(ability, targetEnemy ? abilityOwner : ally);
                                        }
                                        else
                                        {
                                            Debugger.WriteLine("you got rekt by randomiser!");
                                        }

                                        sleeper.Sleep(ability.GetSleepTime(), ability);
                                        sleeper.Sleep(200, ability.Handle);     // for modifier

                                        Debugger.WriteLine(
                                            "counter: " + counterAbility.Name + " => " + ability.Name);
                                        Debugger.WriteLine("ally: " + ally.GetName());
                                        Debugger.WriteLine("remaining time: " + remainingTime);
                                        Debugger.WriteLine("required time: " + requiredTime);
                                    }

                                    return;
                                }

                                break;

                            case Priority.Disable:
                                if (abilityOwner.IsMagicImmune() || abilityOwner.IsInvul())
                                {
                                    continue;
                                }

                                var disableAbilities = from abilityName in ability.DisableAbilities
                                                       join usableAbility in abilityUpdater.UsableAbilities on
                                                       abilityName equals usableAbility.Name
                                                       where
                                                       usableAbility.Type == AbilityType.Disable &&
                                                       Menu.UsableAbilities.Enabled(
                                    abilityName,
                                    AbilityType.Disable) &&
                                                       (usableAbility.IsItem && heroCanUseItems ||
                                                        !usableAbility.IsItem && heroCanCast)
                                                       select usableAbility;

                                foreach (var disableAbility in disableAbilities)
                                {
                                    if (!disableAbility.CanBeCasted(ability, abilityOwner))
                                    {
                                        continue;
                                    }

                                    var requiredTime = disableAbility.GetRequiredTime(ability, abilityOwner)
                                                       + Game.Ping / 1000;

                                    var remainingDisableTime = ability.GetRemainingDisableTime();

                                    var ignoreRemainingTime = ability.IgnoreRemainingTime(
                                        disableAbility,
                                        remainingDisableTime);

                                    if (requiredTime > remainingDisableTime && !ignoreRemainingTime)
                                    {
                                        continue;
                                    }

                                    if (remainingDisableTime - requiredTime <= 0.10 || ignoreRemainingTime)
                                    {
                                        Debugger.WriteLine(">>>>>>>>>>>>>>>");

                                        if (!Menu.Randomiser.Enabled ||
                                            (Menu.Randomiser.NukesOnly && ability.IsDisable) ||
                                            (randomiser.Next(99) > Menu.Randomiser.FailChance))
                                        {
                                            disableAbility.Use(ability, abilityOwner);
                                        }
                                        else
                                        {
                                            Debugger.WriteLine("you got rekt by randomiser!");
                                        }

                                        sleeper.Sleep(ability.GetSleepTime(), ability);

                                        Debugger.WriteLine(
                                            "disable: " + disableAbility.Name + " => " + ability.Name);
                                        Debugger.WriteLine("ally: " + ally.GetName());
                                        Debugger.WriteLine("remaining time: " + remainingDisableTime);
                                        Debugger.WriteLine("required time: " + requiredTime);
                                    }
                                    return;
                                }

                                break;
                            }
                        }
                    }

                    if (allyIsMe)
                    {
                        return;
                    }
                }
            }
        }