예제 #1
0
            public virtual AttackableUnit GetTarget()
            {
                AttackableUnit result = null;

                var mode = ActiveMode;

                if (ActiveMode == OrbwalkingMode.Flee || ActiveMode == OrbwalkingMode.WallJump)
                {
                    return(null);
                }

                if ((mode == OrbwalkingMode.Mixed || mode == OrbwalkingMode.LaneClear) &&
                    !Menu.Item("PriorizeFarm").GetValue <bool>())
                {
                    var target = TargetSelector.GetTarget(-1, TargetSelector.DamageType.Physical);

                    if (target != null && InAutoAttackRange(target))
                    {
                        return(target);
                    }
                }

                var attackGankPlankBarrels = Menu.Item("AttackGPBarrel").GetValue <StringList>().SelectedIndex;

                if (attackGankPlankBarrels != 2 &&
                    (attackGankPlankBarrels == 0 || mode == OrbwalkingMode.LaneClear || mode == OrbwalkingMode.Mixed ||
                     mode == OrbwalkingMode.LastHit || mode == OrbwalkingMode.Freeze))
                {
                    var enemyGangPlank =
                        HeroManager.Enemies.FirstOrDefault(
                            e => e.ChampionName.Equals("gangplank", StringComparison.InvariantCultureIgnoreCase));

                    if (enemyGangPlank != null)
                    {
                        var barrels =
                            Get <Obj_AI_Minion>()
                            .Where(
                                minion =>
                                minion.Team == GameObjectTeam.Neutral &&
                                minion.CharData.BaseSkinName == "gangplankbarrel" && minion.IsHPBarRendered &&
                                minion.IsValidTarget() && InAutoAttackRange(minion));

                        var objAiMinions = barrels as Obj_AI_Minion[] ?? barrels.ToArray();

                        foreach (var barrel in objAiMinions)
                        {
                            if (barrel.Health <= 1f)
                            {
                                return(barrel);
                            }

                            var t = (int)(player.AttackCastDelay * 1000) + Game.Ping / 2 +
                                    1000 * (int)Math.Max(0, player.Distance(barrel) - player.BoundingRadius) /
                                    (int)GetMyProjectileSpeed();
                            var barrelBuff =
                                barrel.Buffs.FirstOrDefault(
                                    b =>
                                    b.Name.Equals("gangplankebarrelactive",
                                                  StringComparison.InvariantCultureIgnoreCase));

                            if (barrelBuff != null && barrel.Health <= 2f)
                            {
                                var healthDecayRate = enemyGangPlank.Level >= 13
                                    ? 0.5f
                                    : (enemyGangPlank.Level >= 7 ? 1f : 2f);
                                var nextHealthDecayTime = Game.Time < barrelBuff.StartTime + healthDecayRate
                                    ? barrelBuff.StartTime + healthDecayRate
                                    : barrelBuff.StartTime + healthDecayRate * 2;

                                if (nextHealthDecayTime <= Game.Time + t / 1000f)
                                {
                                    return(barrel);
                                }
                            }
                        }

                        if (objAiMinions.Any())
                        {
                            return(null);
                        }
                    }
                }

                if (mode == OrbwalkingMode.LaneClear || mode == OrbwalkingMode.Mixed || mode == OrbwalkingMode.LastHit ||
                    mode == OrbwalkingMode.Freeze)
                {
                    var MinionList = Get <Obj_AI_Minion>()
                                     .Where(minion => minion.IsValidTarget() && InAutoAttackRange(minion))
                                     .OrderByDescending(minion => minion.CharData.BaseSkinName.Contains("Siege"))
                                     .ThenBy(minion => minion.CharData.BaseSkinName.Contains("Super"))
                                     .ThenBy(minion => minion.Health)
                                     .ThenByDescending(minion => minion.MaxHealth);

                    foreach (var minion in MinionList)
                    {
                        var t = (int)(player.AttackCastDelay * 1000) - 100 + Game.Ping / 2 +
                                1000 * (int)Math.Max(0, player.Distance(minion) - player.BoundingRadius) /
                                (int)GetMyProjectileSpeed();

                        if (mode == OrbwalkingMode.Freeze)
                        {
                            t += 200 + Game.Ping / 2;
                        }

                        var predHealth = HealthPrediction.GetHealthPrediction(minion, t, FarmDelay);

                        if (minion.Team != GameObjectTeam.Neutral && ShouldAttackMinion(minion))
                        {
                            var damage   = player.GetAutoAttackDamage(minion, true);
                            var killable = predHealth <= damage;

                            if (mode == OrbwalkingMode.Freeze)
                            {
                                if (minion.Health < 50 || predHealth <= 50)
                                {
                                    return(minion);
                                }
                            }
                            else
                            {
                                if (predHealth <= 0)
                                {
                                    FireOnNonKillableMinion(minion);
                                }

                                if (killable)
                                {
                                    return(minion);
                                }
                            }
                        }
                    }
                }

                if (_forcedTarget.IsValidTarget() && InAutoAttackRange(_forcedTarget))
                {
                    return(_forcedTarget);
                }

                if (mode == OrbwalkingMode.LaneClear &&
                    (!Menu.Item("FocusMinionsOverTurrets").GetValue <KeyBind>().Active ||
                     !MinionManager.GetMinions(ObjectManager.Player.Position,
                                               GetRealAutoAttackRange(ObjectManager.Player)).Any()))
                {
                    foreach (var turret in Get <Obj_AI_Turret>().Where(t => t.IsValidTarget() && InAutoAttackRange(t)))
                    {
                        return(turret);
                    }

                    foreach (
                        var turret in Get <Obj_BarracksDampener>().Where(t => t.IsValidTarget() && InAutoAttackRange(t)))
                    {
                        return(turret);
                    }

                    foreach (var nexus in Get <Obj_HQ>().Where(t => t.IsValidTarget() && InAutoAttackRange(t)))
                    {
                        return(nexus);
                    }
                }

                if (mode != OrbwalkingMode.LastHit)
                {
                    if (mode != OrbwalkingMode.LaneClear || !ShouldWait())
                    {
                        var target = TargetSelector.GetTarget(-1, TargetSelector.DamageType.Physical);

                        if (target.IsValidTarget() && InAutoAttackRange(target))
                        {
                            return(target);
                        }
                    }
                }

                if (mode == OrbwalkingMode.LaneClear || mode == OrbwalkingMode.Mixed)
                {
                    var jminions =
                        Get <Obj_AI_Minion>()
                        .Where(
                            mob =>
                            mob.IsValidTarget() && mob.Team == GameObjectTeam.Neutral &&
                            InAutoAttackRange(mob) && mob.CharData.BaseSkinName != "gangplankbarrel" &&
                            mob.Name != "WardCorpse");

                    result = Menu.Item("Smallminionsprio").GetValue <bool>()
                        ? jminions.MinOrDefault(mob => mob.MaxHealth)
                        : jminions.MaxOrDefault(mob => mob.MaxHealth);

                    if (result != null)
                    {
                        return(result);
                    }
                }

                if (mode == OrbwalkingMode.LaneClear || mode == OrbwalkingMode.Mixed || mode == OrbwalkingMode.LastHit ||
                    mode == OrbwalkingMode.Freeze)
                {
                    var closestTower =
                        Get <Obj_AI_Turret>()
                        .MinOrDefault(t => t.IsAlly && !t.IsDead ? player.Distance(t, true) : float.MaxValue);

                    if (closestTower != null && player.Distance(closestTower, true) < 1500 * 1500)
                    {
                        Obj_AI_Minion farmUnderTurretMinion = null;
                        Obj_AI_Minion noneKillableMinion    = null;

                        var minions = MinionManager.GetMinions(player.Position, player.AttackRange + 200)
                                      .Where(minion => InAutoAttackRange(minion) && closestTower.Distance(minion, true) < 900 * 900)
                                      .OrderByDescending(minion => minion.CharData.BaseSkinName.Contains("Siege"))
                                      .ThenBy(minion => minion.CharData.BaseSkinName.Contains("Super"))
                                      .ThenByDescending(minion => minion.MaxHealth)
                                      .ThenByDescending(minion => minion.Health);

                        if (minions.Any())
                        {
                            var turretMinion =
                                minions.FirstOrDefault(
                                    minion =>
                                    minion is Obj_AI_Minion &&
                                    HealthPrediction.HasTurretAggro((Obj_AI_Minion)minion));

                            if (turretMinion != null)
                            {
                                var hpLeftBeforeDie   = 0;
                                var hpLeft            = 0;
                                var turretAttackCount = 0;
                                var turretStarTick    = HealthPrediction.TurretAggroStartTick(turretMinion as Obj_AI_Minion);
                                var turretLandTick    = turretStarTick + (int)(closestTower.AttackCastDelay * 1000) +
                                                        1000 *
                                                        Math.Max(0,
                                                                 (int)
                                                                 (turretMinion.Distance(closestTower) -
                                                                  closestTower.BoundingRadius)) /
                                                        (int)(closestTower.BasicAttack.MissileSpeed + 70);

                                for (float i = turretLandTick + 50;
                                     i < turretLandTick + 10 * closestTower.AttackDelay * 1000 + 50;
                                     i = i + closestTower.AttackDelay * 1000)
                                {
                                    var time   = (int)i - Utils.GameTimeTickCount + Game.Ping / 2;
                                    var predHP =
                                        (int)
                                        HealthPrediction.LaneClearHealthPrediction(turretMinion, time > 0 ? time : 0);

                                    if (predHP > 0)
                                    {
                                        hpLeft             = predHP;
                                        turretAttackCount += 1;

                                        continue;
                                    }

                                    hpLeftBeforeDie = hpLeft;
                                    hpLeft          = 0;

                                    break;
                                }

                                if (hpLeft == 0 && turretAttackCount != 0 && hpLeftBeforeDie != 0)
                                {
                                    var damage        = (int)player.GetAutoAttackDamage(turretMinion, true);
                                    var hits          = hpLeftBeforeDie / damage;
                                    var timeBeforeDie = turretLandTick +
                                                        (turretAttackCount + 1) * (int)(closestTower.AttackDelay * 1000) -
                                                        Utils.GameTimeTickCount;
                                    var timeUntilAttackReady = LastAATick + (int)(player.AttackDelay * 1000) >
                                                               Utils.GameTimeTickCount + Game.Ping / 2 + 25
                                        ? LastAATick + (int)(player.AttackDelay * 1000) -
                                                               (Utils.GameTimeTickCount + Game.Ping / 2 + 25)
                                        : 0;
                                    var timeToLandAttack = player.IsMelee
                                        ? player.AttackCastDelay * 1000
                                        : player.AttackCastDelay * 1000 +
                                                           1000 * Math.Max(0, turretMinion.Distance(player) - player.BoundingRadius) /
                                                           player.BasicAttack.MissileSpeed;

                                    if (hits >= 1 &&
                                        hits * player.AttackDelay * 1000 + timeUntilAttackReady + timeToLandAttack <
                                        timeBeforeDie)
                                    {
                                        farmUnderTurretMinion = turretMinion as Obj_AI_Minion;
                                    }
                                    else if (hits >= 1 &&
                                             hits * player.AttackDelay * 1000 + timeUntilAttackReady + timeToLandAttack >
                                             timeBeforeDie)
                                    {
                                        noneKillableMinion = turretMinion as Obj_AI_Minion;
                                    }
                                }
                                else if (hpLeft == 0 && turretAttackCount == 0 && hpLeftBeforeDie == 0)
                                {
                                    noneKillableMinion = turretMinion as Obj_AI_Minion;
                                }

                                if (ShouldWaitUnderTurret(noneKillableMinion))
                                {
                                    return(null);
                                }

                                if (farmUnderTurretMinion != null)
                                {
                                    return(farmUnderTurretMinion);
                                }

                                foreach (
                                    var minion in
                                    minions.Where(
                                        x =>
                                        x.NetworkId != turretMinion.NetworkId && x is Obj_AI_Minion &&
                                        !HealthPrediction.HasMinionAggro((Obj_AI_Minion)x)))
                                {
                                    var playerDamage = (int)player.GetAutoAttackDamage(minion);
                                    var turretDamage = (int)closestTower.GetAutoAttackDamage(minion, true);
                                    var leftHP       = (int)minion.Health % turretDamage;

                                    if (leftHP > playerDamage)
                                    {
                                        return(minion);
                                    }
                                }

                                var lastminion =
                                    minions.LastOrDefault(
                                        x =>
                                        x.NetworkId != turretMinion.NetworkId && x is Obj_AI_Minion &&
                                        !HealthPrediction.HasMinionAggro((Obj_AI_Minion)x));

                                if (lastminion != null && minions.Count() >= 2)
                                {
                                    if (1f / player.AttackDelay >= 1f &&
                                        (int)(turretAttackCount * closestTower.AttackDelay / player.AttackDelay) *
                                        player.GetAutoAttackDamage(lastminion) > lastminion.Health)
                                    {
                                        return(lastminion);
                                    }

                                    if (minions.Count() >= 5 && 1f / player.AttackDelay >= 1.2)
                                    {
                                        return(lastminion);
                                    }
                                }
                            }
                            else
                            {
                                if (ShouldWaitUnderTurret(noneKillableMinion))
                                {
                                    return(null);
                                }

                                foreach (
                                    var minion in
                                    minions.Where(
                                        x =>
                                        x is Obj_AI_Minion &&
                                        !HealthPrediction.HasMinionAggro((Obj_AI_Minion)x)))
                                {
                                    {
                                        var playerDamage = (int)player.GetAutoAttackDamage(minion);
                                        var turretDamage = (int)closestTower.GetAutoAttackDamage(minion, true);
                                        var leftHP       = (int)minion.Health % turretDamage;

                                        if (leftHP > playerDamage)
                                        {
                                            return(minion);
                                        }
                                    }
                                }

                                var lastminion =
                                    minions.LastOrDefault(
                                        x =>
                                        x is Obj_AI_Minion &&
                                        !HealthPrediction.HasMinionAggro((Obj_AI_Minion)x));

                                if (lastminion == null || minions.Count() < 2)
                                {
                                    return(null);
                                }

                                if (minions.Count() >= 5 && 1f / player.AttackDelay >= 1.2)
                                {
                                    return(lastminion);
                                }
                            }
                            return(null);
                        }
                    }
                }

                if (mode == OrbwalkingMode.LaneClear)
                {
                    if (!ShouldWait())
                    {
                        if (_prevMinion.IsValidTarget() && InAutoAttackRange(_prevMinion))
                        {
                            var predHealth = HealthPrediction.LaneClearHealthPrediction(_prevMinion,
                                                                                        (int)(player.AttackDelay * 1000 * LaneClearWaitTimeMod), FarmDelay);

                            if (predHealth >= 2 * player.GetAutoAttackDamage(_prevMinion) ||
                                Math.Abs(predHealth - _prevMinion.Health) < float.Epsilon)
                            {
                                return(_prevMinion);
                            }
                        }

                        result = Get <Obj_AI_Minion>()
                                 .Where(
                            minion =>
                            minion.IsValidTarget() && InAutoAttackRange(minion) &&
                            ShouldAttackMinion(minion))
                                 .Select(
                            minion =>
                            new
                        {
                            minion,
                            predHealth =
                                HealthPrediction.LaneClearHealthPrediction(minion,
                                                                           (int)(player.AttackDelay * 1000 * LaneClearWaitTimeMod), FarmDelay)
                        })
                                 .Where(
                            t =>
                            t.predHealth >= 2 * player.GetAutoAttackDamage(t.minion) ||
                            Math.Abs(t.predHealth - t.minion.Health) < float.Epsilon)
                                 .Select(t => t.minion)
                                 .MaxOrDefault(m => !MinionManager.IsMinion(m, true) ? float.MaxValue : m.Health);

                        if (result != null)
                        {
                            _prevMinion = (Obj_AI_Minion)result;
                        }
                    }
                }

                return(result);
            }