/// <summary> /// Returns the best target candidate. /// </summary> /// <param name="modeArg"> /// The requested mode /// </param> /// <returns> /// The <see cref="AttackableUnit" />. /// </returns> public static AttackableUnit GetTarget(OrbwalkerMode?modeArg) { var mode = modeArg ?? ActiveMode; if (mode == OrbwalkerMode.Orbwalk || mode == OrbwalkerMode.None || (mode == OrbwalkerMode.Hybrid && !Menu["advanced"]["miscPriorizeFarm"].GetValue <MenuBool>().Value)) { var target = TargetSelector.GetTarget(); if (target != null) { return(target); } } if (mode == OrbwalkerMode.LaneClear || mode == OrbwalkerMode.Hybrid || mode == OrbwalkerMode.LastHit) { foreach (var minion in GameObjects.EnemyMinions.Where( m => m.IsValidTarget(m.GetRealAutoAttackRange()) && m.Health < 2 * GameObjects.Player.TotalAttackDamage).OrderByDescending(m => m.MaxHealth)) { var time = (int) ((GameObjects.Player.AttackCastDelay * 1000) + (GameObjects.Player.Distance(minion) / GameObjects.Player.GetProjectileSpeed() * 1000) + (Game.Ping / 2f)); var healthPrediction = Health.GetPrediction(minion, time, 100); if (healthPrediction <= 0) { InvokeAction( new OrbwalkerActionArgs { Position = minion.Position, Target = minion, Process = true, Type = OrbwalkerType.NonKillableMinion }); } if (healthPrediction > 0 && healthPrediction <= GameObjects.Player.GetAutoAttackDamage(minion, true)) { return(minion); } } } if (mode == OrbwalkerMode.LaneClear) { foreach (var turret in GameObjects.EnemyTurrets.Where(t => t.IsValidTarget(t.GetRealAutoAttackRange()))) { return(turret); } foreach ( var inhibitor in GameObjects.EnemyInhibitors.Where(i => i.IsValidTarget(i.GetRealAutoAttackRange())) ) { return(inhibitor); } if (GameObjects.EnemyNexus.IsValidTarget(GameObjects.EnemyNexus.GetRealAutoAttackRange())) { return(GameObjects.EnemyNexus); } } if (mode != OrbwalkerMode.LastHit) { var target = TargetSelector.GetTarget(); if (target != null) { return(target); } } if (ActiveMode == OrbwalkerMode.LaneClear) { var shouldWait = GameObjects.EnemyMinions.Any( m => m.IsValidTarget(m.GetRealAutoAttackRange()) && Health.GetPrediction(m, (int)((GameObjects.Player.AttackDelay * 1000) * 2f), 100) <= GameObjects.Player.GetAutoAttackDamage(m, true)); if (!shouldWait) { var mob = (GameObjects.JungleLegendary.FirstOrDefault(j => j.IsValidTarget(j.GetRealAutoAttackRange())) ?? GameObjects.JungleSmall.FirstOrDefault( j => j.IsValidTarget(j.GetRealAutoAttackRange()) && j.Name.Contains("Mini") && j.Name.Contains("SRU_Razorbeak")) ?? GameObjects.JungleLarge.FirstOrDefault(j => j.IsValidTarget(j.GetRealAutoAttackRange()))) ?? GameObjects.JungleSmall.FirstOrDefault(j => j.IsValidTarget(j.GetRealAutoAttackRange())); if (mob != null) { return(mob); } if (LastMinion.IsValidTarget(LastMinion.GetRealAutoAttackRange())) { var predHealth = Health.GetPrediction( LastMinion, (int)((GameObjects.Player.AttackDelay * 1000) * 2f), 100); if (predHealth >= 2 * GameObjects.Player.GetAutoAttackDamage(LastMinion, true) || System.Math.Abs(predHealth - LastMinion.Health) < float.Epsilon) { return(LastMinion); } } var minion = (from m in GameObjects.EnemyMinions.Where(m => m.IsValidTarget(m.GetRealAutoAttackRange())) let predictedHealth = Health.GetPrediction(m, (int)((GameObjects.Player.AttackDelay * 1000) * 2f), 100) where predictedHealth >= 2 * GameObjects.Player.GetAutoAttackDamage(m, true) || System.Math.Abs(predictedHealth - m.Health) < float.Epsilon select m).MaxOrDefault(m => m.Health); if (minion != null) { return(LastMinion = minion); } // TODO: Add special minions (zyra plants, donger turrets, etc). } } return(null); }
internal static AttackableUnit GetTarget(OrbwalkingMode?modeArg) { var mode = modeArg ?? ActiveMode; if ((mode == OrbwalkingMode.LaneClear || mode == OrbwalkingMode.Hybrid) && !Program.MainMenu["Orbwalker"]["Advanced"]["PriorizeFarm"]) { var target = Variables.TargetSelector.GetTarget(-1, DamageType.Physical); if (target != null) { return(target); } } if (mode == OrbwalkingMode.LaneClear || mode == OrbwalkingMode.Hybrid || mode == OrbwalkingMode.LastHit) { foreach (var minion in GameObjects.EnemyMinions.Where(m => m.InAutoAttackRange() && Minion.IsMinion(m)) .OrderByDescending(m => m.GetMinionType() == MinionTypes.Siege) .ThenBy(m => m.GetMinionType() == MinionTypes.Super) .ThenBy(m => m.Health) .ThenByDescending(m => m.MaxHealth)) { var time = (int) (Program.Player.AttackCastDelay * 1000 + Math.Max(0, Program.Player.Distance(minion) - Program.Player.BoundingRadius) / Program.Player.GetProjectileSpeed() * 1000 - 100 + Game.Ping / 2f); var healthPrediction = Health.GetPrediction(minion, time, FarmDelay); if (healthPrediction <= 0) { InvokeAction( new OrbwalkerActionArgs { Position = minion.Position, Target = minion, Process = true, Type = OrbwalkingType.NonKillableMinion }); } if (healthPrediction > 0 && healthPrediction <= Program.Player.GetAutoAttackDamage(minion, true)) { return(minion); } } } if (mode == OrbwalkingMode.LaneClear) { foreach (var turret in GameObjects.EnemyTurrets.Where(t => t.InAutoAttackRange())) { return(turret); } foreach (var inhibitor in GameObjects.EnemyInhibitors.Where(i => i.InAutoAttackRange())) { return(inhibitor); } if (GameObjects.EnemyNexus.InAutoAttackRange()) { return(GameObjects.EnemyNexus); } } if (mode != OrbwalkingMode.LastHit) { var target = Variables.TargetSelector.GetTarget(-1, DamageType.Physical); if (target != null) { return(target); } } if (ActiveMode == OrbwalkingMode.LaneClear) { var shouldWait = GameObjects.EnemyMinions.Any( m => m.InAutoAttackRange() && Minion.IsMinion(m) && Health.GetPrediction(m, (int)(Program.Player.AttackDelay * 1000 * 2f), FarmDelay) <= Program.Player.GetAutoAttackDamage(m, true)); if (!shouldWait) { foreach (var specialMinion in GameObjects.EnemyMinions.Where( m => m.InAutoAttackRange() && SpecialMinions.Any(i => i.Equals(m.CharData.BaseSkinName)))) { return(specialMinion); } var mob = GameObjects.JungleLegendary.FirstOrDefault(j => j.InAutoAttackRange()) ?? GameObjects.JungleSmall.FirstOrDefault( j => j.InAutoAttackRange() && j.Name.Contains("Mini") && j.Name.Contains("SRU_Razorbeak")) ?? GameObjects.JungleLarge.FirstOrDefault(j => j.InAutoAttackRange()) ?? GameObjects.JungleSmall.FirstOrDefault(j => j.InAutoAttackRange()); if (mob != null) { return(mob); } foreach (var sentinel in GameObjects.EnemyMinions.Where( m => m.InAutoAttackRange() && m.CharData.BaseSkinName == "kalistaspawn")) { return(sentinel); } if (LastMinion.InAutoAttackRange()) { var predHealth = Health.GetPrediction( LastMinion, (int)(Program.Player.AttackDelay * 1000 * 2f), FarmDelay); if (predHealth >= 2 * Program.Player.GetAutoAttackDamage(LastMinion, true) || Math.Abs(predHealth - LastMinion.Health) < float.Epsilon) { return(LastMinion); } } var minion = (from m in GameObjects.EnemyMinions.Where(m => m.InAutoAttackRange() && Minion.IsMinion(m)) let predictedHealth = Health.GetPrediction(m, (int)(Program.Player.AttackDelay * 1000 * 2f), FarmDelay) where predictedHealth >= 2 * Program.Player.GetAutoAttackDamage(m, true) || Math.Abs(predictedHealth - m.Health) < float.Epsilon select m).MaxOrDefault(m => m.Health); if (minion != null) { return(LastMinion = minion); } return (GameObjects.EnemyMinions.FirstOrDefault( m => m.InAutoAttackRange() && (m.CharData.BaseSkinName == "elisespiderling" || m.CharData.BaseSkinName == "teemomushroom"))); } } return(null); }