public static void CastSpell(Spell.Skillshot qwer, Obj_AI_Base target) { var predInput2 = new PredictionInput { Speed = qwer.Speed, Delay = qwer.CastDelay, Range = qwer.Range, From = Player.Instance.ServerPosition, Radius = qwer.Width, Unit = target, Type = SkillshotType.SkillshotLine }; var poutput2 = P.GetPrediction(predInput2); if (poutput2.Hitchance >= HitChance.Low) qwer.Cast(poutput2.CastPosition); }
private static void CastSpell(Spell.Skillshot qwer, Obj_AI_Base target) { var predInput2 = new PredictionInput { Speed = qwer.Speed, Delay = qwer.CastDelay, Range = qwer.Range, From = Player.Instance.ServerPosition, Radius = qwer.Width, Unit = target, Type = SkillshotType.SkillshotLine }; var poutput2 = P.GetPrediction(predInput2); var Standard = qwer.GetPrediction(target); if(Standard.HitChance >= EloBuddy.SDK.Enumerations.HitChance.Medium) { qwer.Cast(S.Q.GetPrediction(target).CastPosition); } }
public static void CastSpell(Spell QWER, Obj_AI_Base target) { switch (GetStringValue("PredictionMode")) { case 0: { const SkillshotType coreType2 = SkillshotType.SkillshotLine; var predInput2 = new PredictionInput { Collision = QWER.Collision, Speed = QWER.Speed, Delay = QWER.Delay, Range = QWER.Range, From = Player.ServerPosition, Radius = QWER.Width, Unit = target, Type = coreType2 }; var poutput2 = Prediction.GetPrediction(predInput2); // if (poutput2 == null) return; if (poutput2.Hitchance >= HitChance.High || poutput2.Hitchance == HitChance.Immobile || poutput2.Hitchance == HitChance.Dashing) { QWER.Cast(poutput2.CastPosition); } break; } case 1: var pred = Q.GetPrediction(target); if (pred.Hitchance >= LeagueSharp.Common.HitChance.High || pred.Hitchance == LeagueSharp.Common.HitChance.Immobile) { if (pred.CollisionObjects.Count == 0) Q.Cast(pred.CastPosition); } break; } }
private async Task ExecuteAsync(CancellationToken token) { try { if (Game.IsPaused || !Owner.IsValid || !Owner.IsAlive || Owner.IsStunned()) { return; } if (Menu.AutoKillWhenComboItem && Menu.ComboKeyItem) { return; } var damageCalculation = DamageCalculation.DamageList.Where(x => (x.GetHealth - x.GetDamage) / x.GetTarget.MaximumHealth <= 0.0f).ToList(); Damage = damageCalculation.OrderByDescending(x => x.GetHealth).OrderByDescending(x => x.GetTarget.Player.Kills).FirstOrDefault(); if (Damage == null) { return; } if (!UpdateHandler.IsEnabled) { UpdateHandler.IsEnabled = true; } var target = Damage.GetTarget; if (!Cancel(target) || Extensions.ComboBreaker(target, false)) { return; } if (!target.IsBlockingAbilities()) { // Veil var veil = Main.Veil; if (veil != null && Menu.AutoKillStealToggler.Value.IsEnabled(veil.ToString()) && veil.CanBeCasted && veil.CanHit(target)) { veil.UseAbility(target.Position); await Task.Delay(veil.GetCastDelay(target.Position), token); } // Ethereal var ethereal = Main.Ethereal; if (ethereal != null && Menu.AutoKillStealToggler.Value.IsEnabled(ethereal.ToString()) && ethereal.CanBeCasted && ethereal.CanHit(target)) { ethereal.UseAbility(target); MultiSleeper.Sleep(ethereal.GetHitTime(target), "ethereal"); await Task.Delay(ethereal.GetCastDelay(target), token); } // Shivas var shivas = Main.Shivas; if (shivas != null && Menu.AutoKillStealToggler.Value.IsEnabled(shivas.ToString()) && shivas.CanBeCasted && shivas.CanHit(target)) { shivas.UseAbility(); await Task.Delay(shivas.GetCastDelay(), token); } if (!MultiSleeper.Sleeping("ethereal") || target.IsEthereal()) { // Dagon var dagon = Main.Dagon; if (dagon != null && Menu.AutoKillStealToggler.Value.IsEnabled("item_dagon_5") && dagon.CanBeCasted && dagon.CanHit(target)) { dagon.UseAbility(target); await Task.Delay(dagon.GetCastDelay(target), token); } } } else { LinkenBreaker.Handler.RunAsync(); } if (!MultiSleeper.Sleeping("ethereal") || target.IsEthereal()) { // Overwhelming Odds var overwhelmingOdds = Main.OverwhelmingOdds; if (Menu.AutoKillStealToggler.Value.IsEnabled(overwhelmingOdds.ToString()) && overwhelmingOdds.CanBeCasted) { var input = new PredictionInput { Owner = Owner, AreaOfEffect = overwhelmingOdds.HasAreaOfEffect, AreaOfEffectTargets = UpdateMode.OverwhelmingOddsUnits, CollisionTypes = overwhelmingOdds.CollisionTypes, Delay = overwhelmingOdds.CastPoint + overwhelmingOdds.ActivationDelay, Speed = overwhelmingOdds.Speed, Range = overwhelmingOdds.CastRange, Radius = overwhelmingOdds.Radius, PredictionSkillshotType = overwhelmingOdds.PredictionSkillshotType }; var castPosition = overwhelmingOdds.GetPredictionOutput(input.WithTarget(target)).CastPosition; if (Owner.Distance2D(castPosition) <= overwhelmingOdds.CastRange) { overwhelmingOdds.UseAbility(castPosition); await Task.Delay(overwhelmingOdds.GetCastDelay(castPosition), token); } } } } catch (TaskCanceledException) { // canceled } catch (Exception e) { Main.Log.Error(e); } }
public void Harass() { List <Obj_AI_Base> shadows = GetShadows(); if (!shadows.Any() || (!q.UseOnHarass && !e.UseOnHarass) || (!q.IsReady() && !e.IsReady())) { return; } List <Obj_AI_Hero> blackList = zedMenu.GetBlockList(BlockListType.Harass); foreach (Obj_AI_Base objAiBase in shadows) { if (((q.UseOnHarass && !q.IsReady()) || !q.UseOnHarass) && ((e.UseOnHarass && !e.IsReady()) || !e.UseOnHarass)) { break; } if (q.UseOnHarass && q.IsReady()) { Obj_AI_Hero target = TargetSelector.GetTarget( q.Range, q.DamageType, true, blackList, objAiBase.Position); if (target != null) { PredictionInput predictionInput = new PredictionInput(); predictionInput.Range = q.Range; predictionInput.RangeCheckFrom = objAiBase.Position; predictionInput.From = objAiBase.Position; predictionInput.Delay = q.Delay; predictionInput.Speed = q.Speed; predictionInput.Unit = target; predictionInput.Type = SkillshotType.SkillshotLine; predictionInput.Collision = false; PredictionOutput predictionOutput = Prediction.GetPrediction(predictionInput); if (predictionOutput.Hitchance >= HitChance.Medium) { q.Cast(predictionOutput.CastPosition); //Console.WriteLine("shadow haras q 1"); } } } if (e.UseOnHarass && e.IsReady()) { Obj_AI_Hero target = TargetSelector.GetTarget(e.Range, e.DamageType, true, blackList, objAiBase.Position); if (target != null) { e.Cast(); //Console.WriteLine("shadow haras e 2"); } } } }
internal static PredictionOutput GetStandardPrediction(PredictionInput input) { var speed = input.Unit.MoveSpeed; if (input.Unit.Distance(input.From, true) < 200 * 200) { //input.Delay /= 2; speed /= 1.5f; } var result = GetPositionOnPath(input, input.Unit.GetWaypoints(), speed); return result; }
public static PredictionOutput GetPrediction(PredictionInput input) { var mainTargetPrediction = Prediction.GetPrediction(input, false, true); var posibleTargets = new List<PossibleTarget> { new PossibleTarget { Position = mainTargetPrediction.UnitPosition.To2D(), Unit = input.Unit } }; if (mainTargetPrediction.Hitchance >= HitChance.Medium) { //Add the posible targets in range: posibleTargets.AddRange(GetPossibleTargets(input)); } while (posibleTargets.Count > 1) { var mecCircle = MEC.GetMec(posibleTargets.Select(h => h.Position).ToList()); if (mecCircle.Radius <= input.RealRadius - 10 && Vector2.DistanceSquared(mecCircle.Center, input.RangeCheckFrom.To2D()) < input.Range * input.Range) { return new PredictionOutput { AoeTargetsHit = posibleTargets.Select(h => (Obj_AI_Hero)h.Unit).ToList(), CastPosition = mecCircle.Center.To3D(), UnitPosition = mainTargetPrediction.UnitPosition, Hitchance = mainTargetPrediction.Hitchance, Input = input, _aoeTargetsHitCount = posibleTargets.Count }; } float maxdist = -1; var maxdistindex = 1; for (var i = 1; i < posibleTargets.Count; i++) { var distance = Vector2.DistanceSquared(posibleTargets[i].Position, posibleTargets[0].Position); if (distance > maxdist || maxdist.CompareTo(-1) == 0) { maxdistindex = i; maxdist = distance; } } posibleTargets.RemoveAt(maxdistindex); } return mainTargetPrediction; }
internal static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input) { if (!input.Unit.IsValid<Obj_AI_Hero>() || input.Radius == 1) { result.Hitchance = HitChance.VeryHigh; return result; } //Program.debug("PRED: FOR CHAMPION " + input.Unit.BaseSkinName); // CAN'T MOVE SPELLS /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetSpecialSpellEndTime(input.Unit) > 0 || input.Unit.HasBuff("Recall")) { result.Hitchance = HitChance.VeryHigh; return result; } // PREPARE MATH /////////////////////////////////////////////////////////////////////////////////// result.Hitchance = HitChance.Medium; var lastWaypiont = input.Unit.GetWaypoints().Last().To3D(); var distanceUnitToWaypoint = lastWaypiont.Distance(input.Unit.ServerPosition); var distanceFromToUnit = input.From.Distance(input.Unit.ServerPosition); var distanceFromToWaypoint = lastWaypiont.Distance(input.From); float speedDelay = distanceFromToUnit / input.Speed; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) speedDelay = 0; else speedDelay = distanceFromToUnit / input.Speed; float totalDelay = speedDelay + input.Delay; float moveArea = input.Unit.MoveSpeed * totalDelay; float fixRange = moveArea * 0.5f; double angleMove = 30 + (input.Radius / 17) - (totalDelay * 2); float backToFront = moveArea * 1.5f; float pathMinLen = 900f; if (angleMove < 31) angleMove = 31; if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d) { pathMinLen = 600f + backToFront; result.Hitchance = HitChance.High; } if (input.Type == SkillshotType.SkillshotCircle) { fixRange -= input.Radius / 2; } // SPAM CLICK /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.PathCalc(input.Unit)) { if (distanceFromToUnit < input.Range - fixRange) { result.Hitchance = HitChance.VeryHigh; return result; } result.Hitchance = HitChance.High; return result; } // NEW VISABLE /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetLastVisableTime(input.Unit) < 0.08d) { result.Hitchance = HitChance.Medium; return result; } // SPECIAL CASES /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToUnit < 300 || distanceFromToWaypoint < 200) { result.Hitchance = HitChance.VeryHigh; return result; } // LONG CLICK DETECTION /////////////////////////////////////////////////////////////////////////////////// if (distanceUnitToWaypoint > pathMinLen) { result.Hitchance = HitChance.VeryHigh; return result; } // RUN IN LANE DETECTION /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToWaypoint > distanceFromToUnit + fixRange && GetAngle(input.From, input.Unit) < angleMove) { result.Hitchance = HitChance.VeryHigh; return result; } // FIX RANGE /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToWaypoint <= input.Unit.Distance(input.From) && distanceFromToUnit > input.Range - fixRange) { //debug("PRED: FIX RANGE"); result.Hitchance = HitChance.Medium; return result; } // AUTO ATTACK LOGIC /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetLastAutoAttackTime(input.Unit) < 0.1d) { if (input.Type == SkillshotType.SkillshotLine && totalDelay < 0.6 + (input.Radius * 0.001)) result.Hitchance = HitChance.VeryHigh; else if (input.Type == SkillshotType.SkillshotCircle && totalDelay < 0.7 + (input.Radius * 0.001)) result.Hitchance = HitChance.VeryHigh; else result.Hitchance = HitChance.High; return result; } // STOP LOGIC /////////////////////////////////////////////////////////////////////////////////// else { if (input.Unit.IsWindingUp) { result.Hitchance = HitChance.High; return result; } else if (input.Unit.Path.Count() == 0 && !input.Unit.IsMoving) { if (distanceFromToUnit > input.Range - fixRange) result.Hitchance = HitChance.Medium; else if (UnitTracker.GetLastStopMoveTime(input.Unit) < 0.8d) result.Hitchance = HitChance.High; else result.Hitchance = HitChance.VeryHigh; return result; } } // ANGLE HIT CHANCE /////////////////////////////////////////////////////////////////////////////////// if (input.Type == SkillshotType.SkillshotLine && input.Unit.Path.Count() > 0 && input.Unit.IsMoving) { if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d && GetAngle(input.From, input.Unit) < angleMove && distanceUnitToWaypoint > moveArea * 0.6) { result.Hitchance = HitChance.VeryHigh; return result; } } // CIRCLE NEW PATH /////////////////////////////////////////////////////////////////////////////////// if (input.Type == SkillshotType.SkillshotCircle) { if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d && distanceUnitToWaypoint > fixRange && distanceFromToUnit < input.Range - fixRange && distanceUnitToWaypoint > fixRange) { result.Hitchance = HitChance.VeryHigh; return result; } } //Program.debug("PRED: NO DETECTION"); return result; }
internal static PredictionOutput GetDashingPrediction(PredictionInput input) { var dashData = input.Unit.GetDashInfo(); var result = new PredictionOutput { Input = input }; input.Delay += 0.1f; //Normal dashes. if (!dashData.IsBlink) { //Mid air: var dashPred = GetPositionOnPath( input, new List<Vector2> { input.Unit.ServerPosition.To2D(), dashData.Path.Last() }, dashData.Speed); if (dashPred.Hitchance >= HitChance.High) { dashPred.CastPosition = dashPred.UnitPosition; dashPred.Hitchance = HitChance.Dashing; return dashPred; } //At the end of the dash: if (dashData.Path.PathLength() > 200) { var endP = dashData.Path.Last(); var timeToPoint = input.Delay + input.From.To2D().Distance(endP) / input.Speed; if (timeToPoint <= input.Unit.Distance(endP) / dashData.Speed + input.RealRadius / input.Unit.MoveSpeed) { return new PredictionOutput { CastPosition = endP.To3D(), UnitPosition = endP.To3D(), Hitchance = HitChance.Dashing }; } } result.CastPosition = dashData.Path.Last().To3D(); result.UnitPosition = result.CastPosition; //Figure out where the unit is going. } return result; }
public override void ExecuteLaneClear() { var prepareMinions = GetValue <StringList>("UseE.Prepare.Lane").SelectedIndex; if (prepareMinions != 0) { List <Obj_AI_Minion> list = new List <Obj_AI_Minion>(); IEnumerable <Obj_AI_Minion> minions = from m in ObjectManager.Get <Obj_AI_Minion>() .Where( m => m.Health > ObjectManager.Player.TotalAttackDamage && m.IsValidTarget(Orbwalking.GetRealAutoAttackRange(null) + 65)) select m; if (prepareMinions == 2) { minions = minions.Where(m => m.IsUnderAllyTurret()); } var objAiMinions = minions as Obj_AI_Minion[] ?? minions.ToArray(); foreach (var m in objAiMinions) { if (m.GetBuffCount(kalistaEBuffName) >= 0) { Render.Circle.DrawCircle(m.Position, 105f, Color.Blue); list.Add(m); } else { list.Remove(m); } } var enemy = HeroManager.Enemies.Find(e => e.IsValidTarget(Orbwalking.GetRealAutoAttackRange(null) + 65)); if (enemy == null) { foreach (var l in objAiMinions.Except(list).ToList()) { Program.ChampionClass.Orbwalker.ForceTarget(l); } } else { Program.ChampionClass.Orbwalker.ForceTarget(enemy); } } if (Q.IsReady()) { var qCount = GetValue <StringList>("UseQ.Lane").SelectedIndex; if (qCount != 0) { var minions = MinionManager.GetMinions( ObjectManager.Player.ServerPosition, Q.Range, MinionTypes.All, MinionTeam.Enemy); foreach (var minion in minions.Where(x => x.Health <= Q.GetDamage(x))) { var killableMinionCount = 0; foreach ( var colminion in qGetCollisionMinions( ObjectManager.Player, ObjectManager.Player.ServerPosition.Extend(minion.ServerPosition, Q.Range))) { if (colminion.Health <= Q.GetDamage(colminion)) { if (GetValue <StringList>("UseQ.Mode.Lane").SelectedIndex == 1 && colminion.Distance(ObjectManager.Player) > Orbwalking.GetRealAutoAttackRange(null) + 65) { killableMinionCount++; } else { killableMinionCount++; } } else { break; } } if (killableMinionCount >= qCount) { if (!ObjectManager.Player.IsWindingUp && !ObjectManager.Player.IsDashing()) { Q.Cast(minion.ServerPosition); break; } } } } } if (E.IsReady()) { var minECount = GetValue <StringList>("UseE.Lane").SelectedIndex; if (minECount != 0) { var killableMinionCount = 0; foreach (var m in MinionManager.GetMinions(ObjectManager.Player.ServerPosition, E.Range) .Where(x => E.CanCast(x) && x.Health < E.GetDamage(x))) { if (m.SkinName.ToLower().Contains("siege") || m.SkinName.ToLower().Contains("super")) { killableMinionCount += 2; } else { killableMinionCount++; } } if (killableMinionCount >= minECount && E.IsReady() && ObjectManager.Player.ManaPercent > E.ManaCost * 2) { E.Cast(); } } } // Don't miss minion if (GetValue <bool>("UseE.LaneNon")) { var minions = MinionManager.GetMinions(ObjectManager.Player.ServerPosition, E.Range * 1); foreach (var n in minions) { var xH = HealthPrediction.GetHealthPrediction(n, (int)(ObjectManager.Player.AttackCastDelay * 1000), Game.Ping / 2 + 100); if (xH < 0) { if (n.Health < E.GetDamage(n) && E.CanCast(n)) { E.Cast(n); } else if (Q.IsReady() && Q.CanCast(n) && n.Distance(ObjectManager.Player.Position) < Orbwalking.GetRealAutoAttackRange(null) + 75) { xH = HealthPrediction.GetHealthPrediction(n, (int)(ObjectManager.Player.AttackCastDelay * 1000), (int)Q.Speed); if (xH < 0) { var input = new PredictionInput { Unit = ObjectManager.Player, Radius = Q.Width, Delay = Q.Delay, Speed = Q.Speed, }; input.CollisionObjects[0] = CollisionableObjects.Minions; int count = Collision.GetCollision(new List <Vector3> { n.Position }, input) .OrderBy(obj => obj.Distance(ObjectManager.Player)) .Count(obj => obj.NetworkId != n.NetworkId); if (count == 0) { Q.Cast(n); } } } } } } }
public static bool GetCollision(List<Vector3> positions, PredictionInput input) { foreach (var position in positions) { foreach (var objectType in input.CollisionObjects) { switch (objectType) { case CollisionableObjects.Minions: foreach (var minion in MinionManager.GetMinions(input.From, Math.Min(input.Range + input.Radius + 100, 2000))) { input.Unit = minion; var distanceFromToUnit = minion.ServerPosition.Distance(input.From); if (distanceFromToUnit < input.Radius) { if (MinionIsDead(input, minion, distanceFromToUnit)) continue; else return true; } else if (minion.ServerPosition.Distance(position) < input.Unit.BoundingRadius) { if (MinionIsDead(input, minion, distanceFromToUnit)) continue; else return true; } else { var minionPos = minion.ServerPosition; int bonusRadius = 20; if (minion.IsMoving) { minionPos = Prediction.GetPrediction(input, false, false).CastPosition; bonusRadius = 100; } if (minionPos.To2D().Distance(input.From.To2D(), position.To2D(), true, true) <= Math.Pow((input.Radius + bonusRadius + minion.BoundingRadius), 2)) { if (MinionIsDead(input, minion, distanceFromToUnit)) continue; else return true; } } } break; case CollisionableObjects.Heroes: foreach (var hero in HeroManager.Enemies.FindAll( hero => hero.IsValidTarget( Math.Min(input.Range + input.Radius + 100, 2000), true, input.RangeCheckFrom)) ) { input.Unit = hero; var prediction = Prediction.GetPrediction(input, false, false); if ( prediction.UnitPosition.To2D() .Distance(input.From.To2D(), position.To2D(), true, true) <= Math.Pow((input.Radius + 50 + hero.BoundingRadius), 2)) { return true; } } break; case CollisionableObjects.Walls: var step = position.Distance(input.From) / 20; for (var i = 0; i < 20; i++) { var p = input.From.To2D().Extend(position.To2D(), step * i); if (NavMesh.GetCollisionFlags(p.X, p.Y).HasFlag(CollisionFlags.Wall)) { return true; } } break; } } } return false; }
internal static resultPred GetPrediction(Obj_AI_Hero target, Spell isSpell) { resultPred result = new resultPred(new Vector3(), 0); if (target != null & target.IsValidTarget(LeeSin.Q.Range + LeeSin.W.Range)) { Vector3[] path = target.Path; if (path.Count() == 1) { if (path[0].Distance(LeeSin.myHero.ServerPosition) < isSpell.Range) { result.Hitchance = 8; } result.predPos = path[0]; } else if (path.Count() >= 2) { if (GetNow() - newPath[target.NetworkId] < 100 || GetNow() > 3000) { float timeToHit = (LeeSin.myHero.ServerPosition.Distance(target.ServerPosition) / isSpell.Speed) + (isSpell.Delay / 1000); float DistanceRun = target.MoveSpeed * timeToHit; Vector3 pos = path[1]; pos = target.ServerPosition.Extend(path[1], (DistanceRun - (isSpell.Width / 2) - target.BoundingRadius)); if (pos.Distance(LeeSin.myHero.ServerPosition) < isSpell.Range) { if (DistanceRun > 500) { result.Hitchance = 3; } else if (DistanceRun > 400) { result.Hitchance = 4; } else if (DistanceRun > 300) { result.Hitchance = 5; } else if (DistanceRun > 200) { result.Hitchance = 6; } else if (DistanceRun < 200) { result.Hitchance = 7; } result.predPos = pos; } } } PredictionInput predInput = new PredictionInput { From = LeeSin.myHero.ServerPosition, Radius = isSpell.Width, Range = isSpell.Range }; predInput.CollisionObjects[0] = CollisionableObjects.Heroes; predInput.CollisionObjects[1] = CollisionableObjects.Minions; IEnumerable <Obj_AI_Base> rCol = Collision.GetCollision(new List <Vector3> { result.predPos }, predInput).ToArray(); IEnumerable <Obj_AI_Base> rObjCol = rCol as Obj_AI_Base[] ?? rCol.ToArray(); if (rObjCol.Count() > 0) { result.Hitchance = 0; } } return(result); }
private static void CastSpell(Spell.Skillshot QWER, Obj_AI_Base target, HitChance hitchance, int MaxRange) { var coreType2 = SkillshotType.SkillshotLine; var aoe2 = false; if ((int)QWER.Type == (int)SkillshotType.SkillshotCircle) { coreType2 = SkillshotType.SkillshotCircle; aoe2 = true; } if (QWER.Width > 80 && QWER.AllowedCollisionCount < 100) { aoe2 = true; } var predInput2 = new PredictionInput { Aoe = aoe2, Collision = QWER.AllowedCollisionCount < 100, Speed = QWER.Speed, Delay = QWER.CastDelay, Range = MaxRange, From = Player.ServerPosition, Radius = QWER.Radius, Unit = target, Type = coreType2 }; var poutput2 = Prediction.GetPrediction(predInput2); if (QWER.Speed < float.MaxValue && Utils.CollisionYasuo(Player.ServerPosition, poutput2.CastPosition)) { return; } if (hitchance == HitChance.VeryHigh) { if (poutput2.Hitchance >= HitChance.VeryHigh) { QWER.Cast(poutput2.CastPosition); } else if (predInput2.Aoe && poutput2.AoeTargetsHitCount > 1 && poutput2.Hitchance >= HitChance.High) { QWER.Cast(poutput2.CastPosition); } } else if (hitchance == HitChance.High) { if (poutput2.Hitchance >= HitChance.High) { QWER.Cast(poutput2.CastPosition); } } else if (hitchance == HitChance.Medium) { if (poutput2.Hitchance >= HitChance.Medium) { QWER.Cast(poutput2.CastPosition); } } else if (hitchance == HitChance.Low) { if (poutput2.Hitchance >= HitChance.Low) { QWER.Cast(poutput2.CastPosition); } } }
private static void Harass() { foreach (var enemyInRange in ObjectManager.Get <AIHeroClient>() .Where( enemy => enemy.IsValidTarget(_q.Range) && Config.Item("Harass-" + enemy.ChampionName).GetValue <bool>())) { var qPred = _q.GetPrediction(enemyInRange); var wPred = _w.GetPrediction(enemyInRange); var manaPercent = (Player.Mana / Player.MaxMana) * 100; if (Config.Item("Harass-Use-Q").GetValue <bool>() && _q.IsReady() && manaPercent >= Config.Item("Harass-Mana-Q").GetValue <Slider>().Value&& qPred.Hitchance >= HarassHitChance) { _q.Cast(qPred.CastPosition); } if (Config.Item("Harass-Use-W").GetValue <bool>() && _w.IsReady() && manaPercent >= Config.Item("Harass-Mana-W").GetValue <Slider>().Value&& Player.Distance(enemyInRange) < _w.Range && wPred.Hitchance >= HarassHitChance) { _w.Cast(enemyInRange); } if (!_e.IsReady() || !_q.IsReady() || qPred.Hitchance > HitChance.Impossible || Player.Distance(enemyInRange) > _q.Range || Player.Mana <= (ObjectManager.Player.Spellbook.GetSpell(SpellSlot.E).SData.Mana + ObjectManager.Player.Spellbook.GetSpell(SpellSlot.Q).SData.Mana) || !Config.Item("Harass-Use-E").GetValue <bool>() || manaPercent < Config.Item("Harass-Mana-E").GetValue <Slider>().Value) { return; } var c = new Geometry.Circle(Player.Position.To2D(), 490); var point = c.ToPolygon().Points.OrderByDescending(vector2 => vector2.Distance(enemyInRange.Position.To2D())).Reverse(); for (var i = 1; i < 3; i++) { var pointTo = point.ElementAt(i).To3D(); if (pointTo.IsWall() || pointTo.UnderTurret(true) || ObjectManager.Get <AIHeroClient>().Any(enemy => enemy != enemyInRange && enemy.IsValidTarget(300, true, pointTo))) { continue; } var qNewPred = new PredictionInput { Unit = enemyInRange, Radius = _q.Width, From = pointTo, Aoe = false, Delay = 0.5f, Range = _q.Range, Speed = _q.Speed, Type = SkillshotType.SkillshotLine, Collision = true }; var qHit = Prediction.GetPrediction(qNewPred); if (qHit.Hitchance < HarassHitChance || !_e.IsReady() || !_q.IsReady()) { continue; } _e.Cast(pointTo); break; } } }
private async Task ExecuteAsync(CancellationToken token) { try { if (Game.IsPaused || !owner.IsValid || !owner.IsAlive || owner.IsStunned()) { return; } var heroes = EntityManager <Hero> .Entities.Where(x => x.IsValidTarget()); foreach (var target in heroes) { if (killStealSettingsMenu.UseBasicAttackItem.Value && this.orbwalker.CanAttack(target) && this.owner.IsInAttackRange(target) && (int)target.Health - (int)DamageCalculationHelper.GetAttackDamage(target) <= 0) { this.orbwalker.Attack(target); return; } var iceShards = abilities.IceShards; if (killStealSettingsMenu.KillStealAbilitiesItem.Value.IsEnabled(iceShards.Ability.Name) && target.IsValidTarget() && iceShards.CanBeCasted && iceShards.CanHit(target) && (int)target.Health - iceShards.GetDamage(target) <= 0) { var predictionInput = new PredictionInput { Owner = this.owner, Delay = iceShards.CastPoint + iceShards.ActivationDelay, Range = iceShards.CastRange, Radius = iceShards.Radius, }; var predictionOutput = prediction.GetPrediction(predictionInput.WithTarget(target)); var castPosition = predictionOutput.CastPosition; Vector3 position; if (target.NetworkActivity == NetworkActivity.Move) { var castRange = iceShards.CastRange - 200; var distance = Vector2.Distance(owner.NetworkPosition.To2D(), castPosition.To2D() + target.Direction2D(target.MovementSpeed)); var time = (distance / iceShards.Speed); position = castPosition + target.Direction2D(time < 1 ? 75 + target.MovementSpeed * time : (target.MovementSpeed) * time).ToVector3(); if (this.owner.NetworkPosition.Distance(position) < castRange) { iceShards.UseAbility(position); await Task.Delay(iceShards.GetCastDelay(position), token); } } } var walrusKick = abilities.WalrusKick; if (killStealSettingsMenu.KillStealAbilitiesItem.Value.IsEnabled(walrusKick.Ability.Name) && !walrusKick.Ability.IsHidden && walrusKick.CanBeCasted && walrusKick.CanHit(target) && (int)target.Health - (int)walrusKick.GetDamage(target) <= 0) { if (owner.Animation.Name.Contains("cast")) { owner.Stop(); } walrusKick.UseAbility(target); await Task.Delay(walrusKick.GetCastDelay(target), token); } var walrusPunch = abilities.WalrusPunch; if (killStealSettingsMenu.KillStealAbilitiesItem.Value.IsEnabled(walrusPunch.Ability.Name) && target.IsValidTarget() && walrusPunch.CanBeCasted && walrusPunch.CanHit(target) && (int)target.Health - walrusPunch.GetDamage(target) <= 0) { if (owner.Animation.Name.Contains("cast")) { owner.Stop(); } walrusPunch.UseAbility(target); await Task.Delay(walrusPunch.GetCastDelay(target), token); } } } catch (TaskCanceledException) { } catch (Exception ex) { LogService.Log(LogType.Error, ex); } }
private void OnUpdate() { var heroes = EntityManager <Hero> .Entities.Where(x => x.IsValid && !x.IsIllusion).ToList(); DamageList.Clear(); foreach (var target in heroes.Where(x => x.IsAlive && x.IsEnemy(Owner)).ToList()) { List <BaseAbility> abilities = new List <BaseAbility>(); var damageOdds = 0.0f; var readyDamageOdds = 0.0f; var totalDamageOdds = 0.0f; if (target.IsVisible) { // Veil var veil = Main.Veil; if (veil != null && veil.Ability.IsValid && Menu.AutoKillStealToggler.Value.IsEnabled(veil.ToString())) { abilities.Add(veil); } // Ethereal var ethereal = Main.Ethereal; if (ethereal != null && ethereal.Ability.IsValid && Menu.AutoKillStealToggler.Value.IsEnabled(ethereal.ToString())) { abilities.Add(ethereal); } // Shivas var shivas = Main.Shivas; if (shivas != null && shivas.Ability.IsValid && Menu.AutoKillStealToggler.Value.IsEnabled(shivas.ToString())) { abilities.Add(shivas); } // Dagon var dagon = Main.Dagon; if (dagon != null && dagon.Ability.IsValid && Menu.AutoKillStealToggler.Value.IsEnabled("item_dagon_5")) { abilities.Add(dagon); } // Overwhelming Odds var overwhelmingOdds = Main.OverwhelmingOdds; if (overwhelmingOdds.Ability.Level > 0 && Menu.AutoKillStealToggler.Value.IsEnabled(overwhelmingOdds.ToString())) { var input = new PredictionInput { Owner = Owner, AreaOfEffect = overwhelmingOdds.HasAreaOfEffect, AreaOfEffectTargets = UpdateMode.OverwhelmingOddsUnits, CollisionTypes = overwhelmingOdds.CollisionTypes, Delay = overwhelmingOdds.CastPoint + overwhelmingOdds.ActivationDelay, Speed = overwhelmingOdds.Speed, Range = float.MaxValue, Radius = overwhelmingOdds.Radius, PredictionSkillshotType = overwhelmingOdds.PredictionSkillshotType }; var castPosition = overwhelmingOdds.GetPredictionOutput(input.WithTarget(target)).CastPosition; var damageUnits = overwhelmingOdds.GetDamage(castPosition, target); if (overwhelmingOdds.IsReady && !Owner.IsStunned() && !Owner.IsMuted() && !Owner.IsSilenced()) { if (Owner.Distance2D(castPosition) <= overwhelmingOdds.CastRange) { damageOdds += damageUnits; } readyDamageOdds += damageUnits; } totalDamageOdds += damageUnits; } } var damageCalculation = new Combo(abilities.ToArray()); var damageReduction = -DamageReduction(target, heroes); var damageBlock = MagicalDamageBlock(target, heroes); var livingArmor = LivingArmor(target, heroes, damageCalculation.Abilities); var damage = DamageHelpers.GetSpellDamage((damageCalculation.GetDamage(target) + damageOdds) + damageBlock, 0, damageReduction) - livingArmor; var readyDamage = DamageHelpers.GetSpellDamage((damageCalculation.GetDamage(target, true, false) + readyDamageOdds) + damageBlock, 0, damageReduction) - livingArmor; var totalDamage = DamageHelpers.GetSpellDamage((damageCalculation.GetDamage(target, false, false) + totalDamageOdds) + damageBlock, 0, damageReduction) - livingArmor; if (target.IsInvulnerable() || target.HasAnyModifiers(BlockModifiers)) { damage = 0.0f; readyDamage = 0.0f; } DamageList.Add(new Damage(target, damage, readyDamage, totalDamage, target.Health)); } }
public override async Task ExecuteAsync(CancellationToken token) { var target = Config.UpdateMode.Target; if (target == null || Menu.BladeMailItem && target.HasModifier("modifier_item_blade_mail_reflect")) { Orbwalker.Move(Game.MousePosition); return; } // Blink var blink = Abilities.Blink; if (blink != null && Menu.ItemToggler.Value.IsEnabled(blink.ToString()) && Owner.Distance2D(Game.MousePosition) > Menu.BlinkActivationItem && Owner.Distance2D(target) > 600 && blink.CanBeCasted) { var blinkPos = target.Position.Extend(Game.MousePosition, Menu.BlinkDistanceEnemyItem); if (Owner.Distance2D(blinkPos) < blink.CastRange) { blink.UseAbility(blinkPos); await Await.Delay(blink.GetCastDelay(blinkPos), token); } } if (Extensions.Cancel(target) && StartCombo(target)) { if (!target.IsBlockingAbilities()) { var comboBreaker = Extensions.ComboBreaker(target); var stunDebuff = target.Modifiers.FirstOrDefault(x => x.IsStunDebuff); var hexDebuff = target.Modifiers.FirstOrDefault(x => x.Name == "modifier_sheepstick_debuff"); // Hex var hex = Abilities.Hex; if (hex != null && Menu.ItemToggler.Value.IsEnabled(hex.ToString()) && hex.CanBeCasted && hex.CanHit(target) && !comboBreaker && (stunDebuff == null || !stunDebuff.IsValid || stunDebuff.RemainingTime <= 0.3f) && (hexDebuff == null || !hexDebuff.IsValid || hexDebuff.RemainingTime <= 0.3f)) { hex.UseAbility(target); await Await.Delay(hex.GetCastDelay(target), token); } // Orchid var orchid = Abilities.Orchid; if (orchid != null && Menu.ItemToggler.Value.IsEnabled(orchid.ToString()) && orchid.CanBeCasted && orchid.CanHit(target) && !comboBreaker) { orchid.UseAbility(target); await Await.Delay(orchid.GetCastDelay(target), token); } // Bloodthorn var bloodthorn = Abilities.Bloodthorn; if (bloodthorn != null && Menu.ItemToggler.Value.IsEnabled(bloodthorn.ToString()) && bloodthorn.CanBeCasted && bloodthorn.CanHit(target) && !comboBreaker) { bloodthorn.UseAbility(target); await Await.Delay(bloodthorn.GetCastDelay(target), token); } // MysticFlare var mysticFlare = Abilities.MysticFlare; if (Menu.AbilityToggler.Value.IsEnabled(mysticFlare.ToString()) && Menu.MinHealthToUltItem <= ((float)target.Health / target.MaximumHealth) * 100 && mysticFlare.CanBeCasted && mysticFlare.CanHit(target) && !comboBreaker && (BadUlt(target) || Extensions.Active(target))) { var enemies = EntityManager <Hero> .Entities.Where(x => x.IsValid && x.IsVisible && x.IsAlive && !x.IsIllusion && x.IsEnemy(Owner) && x.Distance2D(Owner) <= mysticFlare.CastRange).ToList(); var dubleMysticFlare = Owner.HasAghanimsScepter() && enemies.Count() == 1; var input = new PredictionInput { Owner = Owner, Range = mysticFlare.CastRange, Radius = dubleMysticFlare ? -250 : -100 }; var output = Prediction.GetPrediction(input.WithTarget(target)); mysticFlare.UseAbility(output.CastPosition); await Await.Delay(mysticFlare.GetCastDelay(output.CastPosition), token); } // Nullifier var nullifier = Abilities.Nullifier; if (nullifier != null && Menu.ItemToggler.Value.IsEnabled(nullifier.ToString()) && nullifier.CanBeCasted && nullifier.CanHit(target) && !comboBreaker && (stunDebuff == null || !stunDebuff.IsValid || stunDebuff.RemainingTime <= 0.5f) && (hexDebuff == null || !hexDebuff.IsValid || hexDebuff.RemainingTime <= 0.5f)) { nullifier.UseAbility(target); await Await.Delay(nullifier.GetCastDelay(target), token); } // RodofAtos var atosDebuff = target.Modifiers.Any(x => x.IsValid && x.Name == "modifier_rod_of_atos_debuff" && x.RemainingTime > 0.5f); var rodofAtos = Abilities.RodofAtos; if (rodofAtos != null && Menu.ItemToggler.Value.IsEnabled(rodofAtos.ToString()) && rodofAtos.CanBeCasted && rodofAtos.CanHit(target) && !atosDebuff && (stunDebuff == null || !stunDebuff.IsValid || stunDebuff.RemainingTime <= 0.5f)) { rodofAtos.UseAbility(target); await Await.Delay(rodofAtos.GetCastDelay(target), token); } // AncientSeal var ancientSeal = Abilities.AncientSeal; if (Menu.AbilityToggler.Value.IsEnabled(ancientSeal.ToString()) && ancientSeal.CanBeCasted && ancientSeal.CanHit(target) && !comboBreaker) { ancientSeal.UseAbility(target); await Await.Delay(ancientSeal.GetCastDelay(target), token); return; } // Veil var veil = Abilities.Veil; if (veil != null && Menu.ItemToggler.Value.IsEnabled(veil.ToString()) && veil.CanBeCasted && veil.CanHit(target)) { veil.UseAbility(target.Position); await Await.Delay(veil.GetCastDelay(target.Position), token); } // Ethereal var ethereal = Abilities.Ethereal; if (ethereal != null && Menu.ItemToggler.Value.IsEnabled(ethereal.ToString()) && ethereal.CanBeCasted && ethereal.CanHit(target) && !comboBreaker) { ethereal.UseAbility(target); MultiSleeper.Sleep(ethereal.GetHitTime(target), "ethereal"); await Await.Delay(ethereal.GetCastDelay(target), token); } // Shivas var shivas = Abilities.Shivas; if (shivas != null && Menu.ItemToggler.Value.IsEnabled(shivas.ToString()) && shivas.CanBeCasted && shivas.CanHit(target)) { shivas.UseAbility(); await Await.Delay(shivas.GetCastDelay(), token); } if (!MultiSleeper.Sleeping("ethereal") || target.IsEthereal()) { // ConcussiveShot var concussiveShot = Abilities.ConcussiveShot; if (Menu.AbilityToggler.Value.IsEnabled(concussiveShot.ToString()) && Extensions.ConcussiveShotTarget(target, concussiveShot.TargetHit) && concussiveShot.CanBeCasted && concussiveShot.CanHit(target)) { concussiveShot.UseAbility(); await Await.Delay(concussiveShot.GetCastDelay(), token); } // ArcaneBolt var arcaneBolt = Abilities.ArcaneBolt; if (Menu.AbilityToggler.Value.IsEnabled(arcaneBolt.ToString()) && arcaneBolt.CanBeCasted && arcaneBolt.CanHit(target)) { arcaneBolt.UseAbility(target); UpdateManager.BeginInvoke(() => { MultiSleeper.Sleep(arcaneBolt.GetHitTime(target) - (arcaneBolt.GetCastDelay(target) + 350), $"arcanebolt_{ target.Name }"); }, arcaneBolt.GetCastDelay(target) + 50); await Await.Delay(arcaneBolt.GetCastDelay(target), token); return; } // Dagon var dagon = Abilities.Dagon; if (dagon != null && Menu.ItemToggler.Value.IsEnabled("item_dagon_5") && dagon.CanBeCasted && dagon.CanHit(target) && !comboBreaker) { dagon.UseAbility(target); await Await.Delay(dagon.GetCastDelay(target), token); return; } } // UrnOfShadows var urnOfShadows = Abilities.UrnOfShadows; if (urnOfShadows != null && Menu.ItemToggler.Value.IsEnabled(urnOfShadows.ToString()) && urnOfShadows.CanBeCasted && urnOfShadows.CanHit(target) && !comboBreaker) { urnOfShadows.UseAbility(target); await Await.Delay(urnOfShadows.GetCastDelay(target), token); } // SpiritVessel var spiritVessel = Abilities.SpiritVessel; if (spiritVessel != null && Menu.ItemToggler.Value.IsEnabled(spiritVessel.ToString()) && spiritVessel.CanBeCasted && spiritVessel.CanHit(target) && !comboBreaker) { spiritVessel.UseAbility(target); await Await.Delay(spiritVessel.GetCastDelay(target), token); } } else { Config.LinkenBreaker.Handler.RunAsync(); } } if (target.IsInvulnerable() || target.IsAttackImmune()) { Orbwalker.Move(Game.MousePosition); } else { if (Menu.OrbwalkerItem.Value.SelectedValue.Contains("Default")) { Orbwalker.OrbwalkTo(target); } else if (Menu.OrbwalkerItem.Value.SelectedValue.Contains("Distance")) { var ownerDis = Math.Min(Owner.Distance2D(Game.MousePosition), 230); var ownerPos = Owner.Position.Extend(Game.MousePosition, ownerDis); var pos = target.Position.Extend(ownerPos, Menu.MinDisInOrbwalkItem); Orbwalker.OrbwalkingPoint = pos; Orbwalker.OrbwalkTo(target); Orbwalker.OrbwalkingPoint = Vector3.Zero; } else if (Menu.OrbwalkerItem.Value.SelectedValue.Contains("Free")) { if (Owner.Distance2D(target) < Owner.AttackRange(target) && target.Distance2D(Game.MousePosition) < Owner.AttackRange(target)) { Orbwalker.OrbwalkTo(target); } else { Orbwalker.Move(Game.MousePosition); } } else if (Menu.OrbwalkerItem.Value.SelectedValue.Contains("Only Attack")) { Orbwalker.Attack(target); } else if (Menu.OrbwalkerItem.Value.SelectedValue.Contains("No Move")) { if (Owner.Distance2D(target) < Owner.AttackRange(target)) { Orbwalker.Attack(target); } } } }
public override async Task ExecuteAsync(CancellationToken token) { var target = this.TargetSelector.Active.GetTargets().FirstOrDefault(x => !x.IsInvulnerable() && x.Distance2D(this.Owner) <= this.Owner.AttackRange * 2); var silenced = UnitExtensions.IsSilenced(this.Owner); var sliderValue = this.Config.UseBlinkPrediction.Item.GetValue <Slider>().Value; var modifier = Ensage.SDK.Extensions.UnitExtensions.HasModifier(this.Owner, HurricanePike.ModifierName); if ((this.BlinkDagger != null) && (this.BlinkDagger.Item.IsValid) && target != null && Owner.Distance2D(target) <= 1200 + sliderValue && !(Owner.Distance2D(target) <= 400) && this.BlinkDagger.Item.CanBeCasted(target) && this.Config.ItemToggler.Value.IsEnabled(this.BlinkDagger.Item.Name)) { 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); Log.Debug("Using BlinkDagger"); this.BlinkDagger.UseAbility(position); await Await.Delay(this.GetItemDelay(target), token); } if (!silenced) { try { var targets = EntityManager <Hero> .Entities.Where( x => x.IsValid && x.Team != this.Owner.Team && !x.IsIllusion && x.Distance2D(this.Owner) <= 700) .ToList(); var me = this.Owner as Hero; foreach (var ultiTarget in targets) { if (this.Config.AbilityToggler.Value.IsEnabled(this.Ulti.Name) && this.Ulti.CanBeCasted(ultiTarget)) { var ultiDamage = Math.Floor( this.Ulti.GetAbilitySpecialData("damage_multiplier") * (me.TotalIntelligence - ultiTarget.TotalIntelligence) * (1 - ultiTarget.MagicDamageResist)); if (ultiTarget.Health > ultiDamage) { continue; } var delay = this.GetAbilityDelay(ultiTarget, this.Ulti); var radius = this.Ulti.GetAbilitySpecialData("radius"); var input = new PredictionInput( this.Owner, ultiTarget, delay, float.MaxValue, 700, radius, PredictionSkillshotType.SkillshotCircle, true) { CollisionTypes = CollisionTypes.None }; // Log.Debug($"Owner: {input.Owner.Name}"); // Log.Debug($"Delay: {input.Delay}"); // Log.Debug($"Range: {input.Range}"); // Log.Debug($"Speed: {input.Speed}"); // Log.Debug($"Radius: {input.Radius}"); // Log.Debug($"Type: {input.PredictionSkillshotType}"); var output = this.Prediction.GetPrediction(input); var amount = output.AoeTargetsHit.Count; // Log.Debug($"{output.HitChance}"); if (output.HitChance >= HitChance.Medium && this.Config.MinimumTargetToUlti.Item.GetValue <int>() >= amount) { Log.Debug( $"Using Ulti on {amount}!"); this.Ulti.UseAbility(output.CastPosition); await Await.Delay(delay + (int)Game.Ping, token); } } } } catch (Exception e) { Log.Debug($"{e}"); } if (this.Orb != null && this.Orb.IsValid && this.Config.AbilityToggler.Value.IsEnabled(this.Orb.Name) && this.Orb.CanBeCasted(target) && !this.Orb.IsAutoCastEnabled) { Log.Debug($"Toggling Arcane Orb on because {target != null}"); this.Orb.ToggleAutocastAbility(); await Await.Delay(100 + (int)Game.Ping, token); } // Toggle off if target is null else if (this.Orb != null && this.Orb.IsValid && this.Config.AbilityToggler.Value.IsEnabled(this.Orb.Name) && target == null && this.Orb.IsAutoCastEnabled) { Log.Debug($"Toggling Arcane Orb off because target is null"); this.Orb.ToggleAutocastAbility(); await Await.Delay(100 + (int)Game.Ping, token); } } if ((this.BloodThorn != null) && this.BloodThorn.Item.IsValid && target != null && this.BloodThorn.Item.CanBeCasted(target) && this.Config.ItemToggler.Value.IsEnabled(this.BloodThorn.Item.Name)) { Log.Debug("Using Bloodthorn"); this.BloodThorn.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); } if ((this.SheepStick != null) && this.SheepStick.Item.IsValid && target != null && this.SheepStick.Item.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.Item.IsValid && target != null && this.Orchid.Item.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.Item.IsValid && target != null && this.RodofAtos.Item.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.Item.IsValid && target != null && this.VeilofDiscord.Item.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.HurricanePike != null) { if (modifier) { this.Owner.Attack(target); await Task.Delay(100, token); return; } if ((double)(this.Owner.Health / this.Owner.MaximumHealth) * 100 <= (double)Config.HurricanePercentage.Item.GetValue <Slider>().Value&& this.HurricanePike.Item.IsValid && target != null && this.HurricanePike.Item.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_hurricane_pike")) { Log.Debug("Using HurricanePike"); this.HurricanePike.UseAbility(target); await Await.Delay(this.GetItemDelay(target), token); return; } } if ((this.ShivasGuard != null) && this.ShivasGuard.Item.IsValid && target != null && this.Owner.Distance2D(target) <= 900 && this.ShivasGuard.Item.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_shivas_guard")) { Log.Debug("Using Shivas"); this.ShivasGuard.UseAbility(); await Await.Delay(20 + (int)Game.Ping, token); } if (this.Orbwalker.OrbwalkTo(target)) { return; } await Await.Delay(125, token); }
public static bool CanCastSpellPred(Spell QWER, Obj_AI_Base target) { int predIndex = 0; HitChance hitchance = HitChance.Low; if (QWER.Slot == SpellSlot.Q) { predIndex = MainMenu.Item("Qpred", true).GetValue <StringList>().SelectedIndex; if (MainMenu.Item("QHitChance", true).GetValue <StringList>().SelectedIndex == 0) { hitchance = HitChance.VeryHigh; } else if (MainMenu.Item("QHitChance", true).GetValue <StringList>().SelectedIndex == 1) { hitchance = HitChance.High; } else if (MainMenu.Item("QHitChance", true).GetValue <StringList>().SelectedIndex == 2) { hitchance = HitChance.Medium; } } else if (QWER.Slot == SpellSlot.W) { predIndex = MainMenu.Item("Wpred", true).GetValue <StringList>().SelectedIndex; if (MainMenu.Item("WHitChance", true).GetValue <StringList>().SelectedIndex == 0) { hitchance = HitChance.VeryHigh; } else if (MainMenu.Item("WHitChance", true).GetValue <StringList>().SelectedIndex == 1) { hitchance = HitChance.High; } else if (MainMenu.Item("WHitChance", true).GetValue <StringList>().SelectedIndex == 2) { hitchance = HitChance.Medium; } } else if (QWER.Slot == SpellSlot.E) { predIndex = MainMenu.Item("Epred", true).GetValue <StringList>().SelectedIndex; if (MainMenu.Item("EHitChance", true).GetValue <StringList>().SelectedIndex == 0) { hitchance = HitChance.VeryHigh; } else if (MainMenu.Item("EHitChance", true).GetValue <StringList>().SelectedIndex == 1) { hitchance = HitChance.High; } else if (MainMenu.Item("EHitChance", true).GetValue <StringList>().SelectedIndex == 2) { hitchance = HitChance.Medium; } } else if (QWER.Slot == SpellSlot.R) { predIndex = MainMenu.Item("Rpred", true).GetValue <StringList>().SelectedIndex; if (MainMenu.Item("RHitChance", true).GetValue <StringList>().SelectedIndex == 0) { hitchance = HitChance.VeryHigh; } else if (MainMenu.Item("RHitChance", true).GetValue <StringList>().SelectedIndex == 1) { hitchance = HitChance.High; } else if (MainMenu.Item("RHitChance", true).GetValue <StringList>().SelectedIndex == 2) { hitchance = HitChance.Medium; } } if (predIndex == 3) { SkillshotType CoreType2 = SkillshotType.SkillshotLine; bool aoe2 = false; if (QWER.Width > 80 && !QWER.Collision) { aoe2 = true; } var predInput2 = new PredictionInput { Aoe = aoe2, Collision = QWER.Collision, Speed = QWER.Speed, Delay = QWER.Delay, Range = QWER.Range, From = Player.ServerPosition, Radius = QWER.Width, Unit = target, Type = CoreType2 }; var poutput2 = Prediction.GetPrediction(predInput2); if (QWER.Speed != float.MaxValue && OktwCommon.CollisionYasuo(Player.ServerPosition, poutput2.CastPosition)) { return(false); } if ((int)hitchance == 6) { if (poutput2.Hitchance >= HitChance.VeryHigh) { return(true); } else if (predInput2.Aoe && poutput2.AoeTargetsHitCount > 1 && poutput2.Hitchance >= HitChance.High) { return(true); } } else if ((int)hitchance == 5) { if (poutput2.Hitchance >= HitChance.High) { return(true); } } else if ((int)hitchance == 4) { if (poutput2.Hitchance >= HitChance.Medium) { return(true); } } } else if (predIndex == 1) { SkillshotType CoreType2 = SkillshotType.SkillshotLine; bool aoe2 = false; if (QWER.Type == SkillshotType.SkillshotCircle) { CoreType2 = SkillshotType.SkillshotCircle; aoe2 = true; } if (QWER.Width > 80 && !QWER.Collision) { aoe2 = true; } var predInput2 = new PredictionInput { Aoe = aoe2, Collision = QWER.Collision, Speed = QWER.Speed, Delay = QWER.Delay, Range = QWER.Range, From = Player.ServerPosition, Radius = QWER.Width, Unit = target, Type = CoreType2 }; var poutput2 = Prediction.GetPrediction(predInput2); //var poutput2 = QWER.GetPrediction(target); if (QWER.Speed != float.MaxValue && OktwCommon.CollisionYasuo(Player.ServerPosition, poutput2.CastPosition)) { return(false); } if ((int)hitchance == 6) { if (poutput2.Hitchance >= HitChance.VeryHigh) { return(true); } else if (predInput2.Aoe && poutput2.AoeTargetsHitCount > 1 && poutput2.Hitchance >= HitChance.High) { return(true); } } else if ((int)hitchance == 5) { if (poutput2.Hitchance >= HitChance.High) { return(true); } } else if ((int)hitchance == 4) { if (poutput2.Hitchance >= HitChance.Medium) { return(true); } } if (Game.Time - DrawSpellTime > 0.5) { DrawSpell = QWER; DrawSpellTime = Game.Time; } DrawSpellPos = poutput2; } else if (predIndex == 0) { return(QWER.GetPrediction(target).Hitchance >= hitchance); } else if (predIndex == 2) { return(QWER.GetPrediction(target).Hitchance >= HitChance.High); } return(false); }
public override async Task ExecuteAsync(CancellationToken token) { var Target = Config.UpdateMode.Target; if (Target != null && (!Config.BladeMailItem || !Target.HasModifier("modifier_item_blade_mail_reflect"))) { var StunDebuff = Target.Modifiers.FirstOrDefault(x => x.IsStunDebuff); var HexDebuff = Target.Modifiers.FirstOrDefault(x => x.IsValid && x.Name == "modifier_sheepstick_debuff"); var AtosDebuff = Target.Modifiers.FirstOrDefault(x => x.IsValid && x.Name == "modifier_rod_of_atos_debuff"); if (!Target.IsMagicImmune() && !Target.IsInvulnerable() && !Target.HasModifier("modifier_winter_wyvern_winters_curse")) { if (!Target.IsLinkensProtected() && !Config.LinkenBreaker.AntimageShield(Target)) { // Hex var Hex = Main.Hex; if (Hex != null && Config.ItemsToggler.Value.IsEnabled(Hex.ToString()) && Hex.CanBeCasted && Hex.CanHit(Target) && (StunDebuff == null || StunDebuff.RemainingTime <= 0.3) && (HexDebuff == null || HexDebuff.RemainingTime <= 0.3)) { Hex.UseAbility(Target); await Await.Delay(Hex.GetCastDelay(Target), token); } // Orchid var Orchid = Main.Orchid; if (Orchid != null && Config.ItemsToggler.Value.IsEnabled(Orchid.ToString()) && Orchid.CanBeCasted && Orchid.CanHit(Target)) { Main.Orchid.UseAbility(Target); await Await.Delay(Main.Orchid.GetCastDelay(Target), token); } // Bloodthorn var Bloodthorn = Main.Bloodthorn; if (Bloodthorn != null && Config.ItemsToggler.Value.IsEnabled(Bloodthorn.ToString()) && Bloodthorn.CanBeCasted && Bloodthorn.CanHit(Target)) { Bloodthorn.UseAbility(Target); await Await.Delay(Bloodthorn.GetCastDelay(Target), token); } // RodofAtos var RodofAtos = Main.RodofAtos; if (RodofAtos != null && Config.ItemsToggler.Value.IsEnabled(RodofAtos.ToString()) && RodofAtos.CanBeCasted && RodofAtos.CanHit(Target) && (StunDebuff == null || StunDebuff.RemainingTime <= 0.5) && (AtosDebuff == null || AtosDebuff.RemainingTime <= 0.5)) { RodofAtos.UseAbility(Target); await Await.Delay(RodofAtos.GetCastDelay(Target), token); } // CurseOfSilent var CurseOfSilent = Main.CurseOfSilent; if (Config.AbilityToggler.Value.IsEnabled(CurseOfSilent.ToString()) && CurseOfSilent.CanBeCasted && CurseOfSilent.CanHit(Target)) { var Targets = EntityManager <Hero> .Entities.Where( x => !x.IsIllusion && x.IsValid && x.IsVisible && x.IsAlive && x.IsEnemy(Owner)); var Input = new PredictionInput( Owner, Target, 1, float.MaxValue, CurseOfSilent.CastRange, CurseOfSilent.Radius, PredictionSkillshotType.SkillshotCircle, true, Targets.ToList()) { CollisionTypes = CollisionTypes.None }; var Output = Prediction.GetPrediction(Input); CurseOfSilent.UseAbility(Output.CastPosition); await Await.Delay(CurseOfSilent.GetCastDelay(Output.CastPosition), token); } // LastWord var LastWord = Main.LastWord; if (Config.AbilityToggler.Value.IsEnabled(LastWord.ToString()) && LastWord.CanBeCasted && LastWord.CanHit(Target)) { LastWord.UseAbility(Target); await Await.Delay(LastWord.GetCastDelay(Target), token); } // HurricanePike var HurricanePike = Main.HurricanePike; if (HurricanePike != null && Config.ItemsToggler.Value.IsEnabled(HurricanePike.ToString()) && HurricanePike.CanBeCasted && Owner.Distance2D(Target) < 400) { HurricanePike.UseAbility(Target); await Await.Delay(HurricanePike.GetCastDelay(Target), token); } // HeavensHalberd var HeavensHalberd = Main.HeavensHalberd; if (HeavensHalberd != null && Config.ItemsToggler.Value.IsEnabled(HeavensHalberd.ToString()) && HeavensHalberd.CanBeCasted && HeavensHalberd.CanHit(Target)) { HeavensHalberd.UseAbility(Target); await Await.Delay(HeavensHalberd.GetCastDelay(Target), token); } // Veil var Veil = Main.Veil; if (Veil != null && Config.ItemsToggler.Value.IsEnabled(Veil.ToString()) && Veil.CanBeCasted && Veil.CanHit(Target)) { Veil.UseAbility(Target.Position); await Await.Delay(Veil.GetCastDelay(Target.Position), token); } // Shivas var Shivas = Main.Shivas; if (Shivas != null && Config.ItemsToggler.Value.IsEnabled(Shivas.ToString()) && Shivas.CanBeCasted && Owner.Distance2D(Target) <= Shivas.Radius) { Shivas.UseAbility(); await Await.Delay(Shivas.GetCastDelay(), token); } // Ethereal var Ethereal = Main.Ethereal; if (Ethereal != null && Config.ItemsToggler.Value.IsEnabled(Ethereal.ToString()) && Ethereal.CanBeCasted && Ethereal.CanHit(Target)) { Ethereal.UseAbility(Target); await Await.Delay(Ethereal.GetCastDelay(Target), token); } // Dagon var Dagon = Main.Dagon; if (Dagon != null && Config.ItemsToggler.Value.IsEnabled("item_dagon_5") && Dagon.CanBeCasted && Dagon.CanHit(Target) && (Ethereal == null || (Target.IsEthereal() && !Ethereal.CanBeCasted) || !Config.ItemsToggler.Value.IsEnabled(Ethereal.ToString()))) { Dagon.UseAbility(Target); await Await.Delay(Dagon.GetCastDelay(Target), token); } } else { Config.LinkenBreaker.Handler.RunAsync(); } } if (Target.IsInvulnerable() || Target.IsAttackImmune()) { if (!Orbwalker.Settings.Move) { Orbwalker.Settings.Move.Item.SetValue(true); } Orbwalker.Move(Game.MousePosition); } else { if (Owner.Distance2D(Target) <= Config.MinDisInOrbwalkItem && Target.Distance2D(Game.MousePosition) <= Config.MinDisInOrbwalkItem) { if (Orbwalker.Settings.Move) { Orbwalker.Settings.Move.Item.SetValue(false); } } else { if (!Orbwalker.Settings.Move) { Orbwalker.Settings.Move.Item.SetValue(true); } } if (!GlaivesOfWisdomCast(Target)) { Orbwalker.OrbwalkTo(Target); } } } else { if (!Orbwalker.Settings.Move) { Orbwalker.Settings.Move.Item.SetValue(true); } Orbwalker.Move(Game.MousePosition); } }
internal static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input) { if (!input.Unit.IsValid<Obj_AI_Hero>()) { result.Hitchance = HitChance.VeryHigh; return result; } if (UnitTracker.GetSpecialSpellEndTime(input.Unit) > 0 ) { result.Hitchance = HitChance.VeryHigh; return result; } result.Hitchance = HitChance.High; var lastWaypiont = input.Unit.GetWaypoints().Last().To3D(); var distanceUnitToWaypoint = lastWaypiont.Distance(input.Unit.ServerPosition); var distanceFromToUnit = input.From.Distance(input.Unit.ServerPosition); var distanceFromToWaypoint = lastWaypiont.Distance(input.From); float speedDelay = distanceFromToUnit / input.Speed; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) speedDelay = 0; else speedDelay = distanceFromToUnit / input.Speed; float totalDelay = speedDelay + input.Delay; float moveArea = input.Unit.MoveSpeed * totalDelay; float fixRange = moveArea * 0.6f; double angleMove = 30 + (input.Radius / 10) - (input.Delay * 5); float backToFront = moveArea * 1.5f; float pathMinLen = 700f + backToFront; if (UnitTracker.PathCalc(input.Unit)) { if (distanceFromToUnit < input.Range - fixRange) { result.Hitchance = HitChance.VeryHigh; return result; } result.Hitchance = HitChance.High; return result; } if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d) { fixRange = moveArea * (0.2f + input.Delay); backToFront = moveArea; } if (input.Type == SkillshotType.SkillshotCircle) { fixRange -= input.Radius / 2; } if (distanceUnitToWaypoint > pathMinLen) { result.Hitchance = HitChance.VeryHigh; } else if (input.Type == SkillshotType.SkillshotLine) { if (input.Unit.Path.Count() > 0) { if (GetAngle(input.From, input.Unit) < angleMove) { result.Hitchance = HitChance.VeryHigh; } else if (UnitTracker.GetLastNewPathTime(input.Unit) > 0.1d) result.Hitchance = HitChance.High; } } if (input.Unit.Path.Count() == 0 && input.Unit.Position == input.Unit.ServerPosition) { if (UnitTracker.GetLastStopMoveTime(input.Unit) < 0.5d) result.Hitchance = HitChance.High; else if (distanceFromToUnit > input.Range - fixRange) result.Hitchance = HitChance.Medium; else result.Hitchance = HitChance.VeryHigh; } else if (distanceFromToWaypoint <= input.Unit.Distance(input.From)) { if (distanceFromToUnit > input.Range - fixRange) result.Hitchance = HitChance.Medium; } if (UnitTracker.GetLastAutoAttackTime(input.Unit) < 0.1d) { if (input.Type == SkillshotType.SkillshotLine && totalDelay < 0.8 + (input.Radius * 0.001)) result.Hitchance = HitChance.VeryHigh; else if (input.Type == SkillshotType.SkillshotCircle && totalDelay < 0.6 + (input.Radius * 0.001)) result.Hitchance = HitChance.VeryHigh; else result.Hitchance = HitChance.Medium; } if (input.Type == SkillshotType.SkillshotCircle) { if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d) result.Hitchance = HitChance.VeryHigh; else if (distanceFromToUnit < input.Range - fixRange) result.Hitchance = HitChance.VeryHigh; } if (result.Hitchance != HitChance.Medium) { if (input.Unit.IsWindingUp && UnitTracker.GetLastAutoAttackTime(input.Unit) > 0.1d) result.Hitchance = HitChance.Medium; else if (input.Unit.Path.Count() == 0 && input.Unit.Position != input.Unit.ServerPosition) result.Hitchance = HitChance.Medium; else if (input.Unit.Path.Count() > 0 && distanceUnitToWaypoint < backToFront) { result.Hitchance = HitChance.Medium; } else if (input.Unit.Path.Count() > 1) result.Hitchance = HitChance.Medium; else if (UnitTracker.GetLastVisableTime(input.Unit) < 0.05d) { result.Hitchance = HitChance.Medium; } } if (distanceFromToWaypoint > input.Unit.Distance(input.From) && GetAngle(input.From, input.Unit) > angleMove) result.Hitchance = HitChance.VeryHigh; if (input.Unit.Distance(input.From) < 400 || distanceFromToWaypoint < 300 || input.Unit.MoveSpeed < 200f) result.Hitchance = HitChance.VeryHigh; return result; }
public PredictionOutput GetPrediction(PredictionInput input, bool ft, bool checkCollision) => GetPrediction(input);
public static PredictionOutput GetPrediction(PredictionInput input) { var mainTargetPrediction = Prediction.GetPrediction(input, false, true); var posibleTargets = new List<PossibleTarget> { new PossibleTarget { Position = mainTargetPrediction.UnitPosition.To2D(), Unit = input.Unit } }; if (mainTargetPrediction.Hitchance >= HitChance.Medium) { //Add the posible targets in range: posibleTargets.AddRange(GetPossibleTargets(input)); } if (posibleTargets.Count > 1) { var candidates = new List<Vector2>(); foreach (var target in posibleTargets) { var targetCandidates = GetCandidates( input.From.To2D(), target.Position, (input.Radius), input.Range); candidates.AddRange(targetCandidates); } var bestCandidateHits = -1; var bestCandidate = new Vector2(); var bestCandidateHitPoints = new List<Vector2>(); var positionsList = posibleTargets.Select(t => t.Position).ToList(); foreach (var candidate in candidates) { if ( GetHits( input.From.To2D(), candidate, (input.Radius + input.Unit.BoundingRadius / 3 - 10), new List<Vector2> { posibleTargets[0].Position }).Count() == 1) { var hits = GetHits(input.From.To2D(), candidate, input.Radius, positionsList).ToList(); var hitsCount = hits.Count; if (hitsCount >= bestCandidateHits) { bestCandidateHits = hitsCount; bestCandidate = candidate; bestCandidateHitPoints = hits.ToList(); } } } if (bestCandidateHits > 1) { float maxDistance = -1; Vector2 p1 = new Vector2(), p2 = new Vector2(); //Center the position for (var i = 0; i < bestCandidateHitPoints.Count; i++) { for (var j = 0; j < bestCandidateHitPoints.Count; j++) { var startP = input.From.To2D(); var endP = bestCandidate; var proj1 = positionsList[i].ProjectOn(startP, endP); var proj2 = positionsList[j].ProjectOn(startP, endP); var dist = Vector2.DistanceSquared(bestCandidateHitPoints[i], proj1.LinePoint) + Vector2.DistanceSquared(bestCandidateHitPoints[j], proj2.LinePoint); if (dist >= maxDistance && (proj1.LinePoint - positionsList[i]).AngleBetween( proj2.LinePoint - positionsList[j]) > 90) { maxDistance = dist; p1 = positionsList[i]; p2 = positionsList[j]; } } } return new PredictionOutput { Hitchance = mainTargetPrediction.Hitchance, _aoeTargetsHitCount = bestCandidateHits, UnitPosition = mainTargetPrediction.UnitPosition, CastPosition = ((p1 + p2) * 0.5f).To3D(), Input = input }; } } return mainTargetPrediction; }
private void IdlePrediction(ref PredictionOutput result, PredictionInput input) { result.UnitPosition = input.Unit.Position3D(); result.CastPosition = input.Unit.Position3D(); }
internal static PredictionOutput GetPositionOnPath(PredictionInput input, List<Vector2> path, float speed = -1) { speed = (Math.Abs(speed - (-1)) < float.Epsilon) ? input.Unit.MoveSpeed : speed; if (path.Count <= 1) { return new PredictionOutput { Input = input, UnitPosition = input.Unit.ServerPosition, CastPosition = input.Unit.ServerPosition, Hitchance = HitChance.High }; } var pLength = path.PathLength(); //Skillshots with only a delay if (pLength >= input.Delay * speed - input.RealRadius && Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) { var tDistance = input.Delay * speed - input.RealRadius; for (var i = 0; i < path.Count - 1; i++) { var a = path[i]; var b = path[i + 1]; var d = a.Distance(b); if (d >= tDistance) { var direction = (b - a).Normalized(); var cp = a + direction * tDistance; var p = a + direction * ((i == path.Count - 2) ? Math.Min(tDistance + input.RealRadius, d) : (tDistance + input.RealRadius)); return new PredictionOutput { Input = input, CastPosition = cp.To3D(), UnitPosition = p.To3D(), Hitchance = HitChance.High }; } tDistance -= d; } } //Skillshot with a delay and speed. if (pLength >= input.Delay * speed - input.RealRadius && Math.Abs(input.Speed - float.MaxValue) > float.Epsilon) { path = path.CutPath(input.Delay * speed - input.RealRadius); var distanceToTarget = input.From.Distance(input.Unit.ServerPosition); var m = distanceToTarget > input.Unit.BoundingRadius ? distanceToTarget / (distanceToTarget - input.Unit.BoundingRadius) : 1; var sp = m * input.Speed; var tT = 0f; for (var i = 0; i < path.Count - 1; i++) { var a = path[i]; var b = path[i + 1]; var tB = a.Distance(b) / speed; var direction = (b - a).Normalized(); a = a - speed * tT * direction; var sol = Geometry.VectorMovementCollision(a, b, speed, input.From.To2D(), sp, tT); var t = (float)sol[0]; var pos = (Vector2)sol[1]; if (pos.IsValid() && t >= tT && t <= tT + tB) { var p = pos + input.RealRadius * direction; if (input.Type == SkillshotType.SkillshotLine && false) { var alpha = (input.From.To2D() - p).AngleBetween(a - b); if (alpha > 50 && alpha < 180 - 50) { var beta = (float)Math.Asin(input.RealRadius * 0.85f / p.Distance(input.From)); var cp1 = input.From.To2D() + (p - input.From.To2D()).Rotated(beta); var cp2 = input.From.To2D() + (p - input.From.To2D()).Rotated(-beta); pos = cp1.Distance(pos, true) < cp2.Distance(pos, true) ? cp1 : cp2; } } return new PredictionOutput { Input = input, CastPosition = pos.To3D(), UnitPosition = p.To3D(), Hitchance = HitChance.High }; } tT += tB; } } var position = path.Last(); return new PredictionOutput { Input = input, CastPosition = position.To3D(), UnitPosition = position.To3D(), Hitchance = HitChance.Medium }; }
public PredictionOutput GetPrediction(PredictionInput input) { return(this.GetPrediction(input, false, true)); }
public static PredictionOutput GetPrediction(PredictionInput input) { switch (input.Type) { case SkillshotType.SkillshotCircle: return Circle.GetPrediction(input); case SkillshotType.SkillshotCone: return Cone.GetPrediction(input); case SkillshotType.SkillshotLine: return Line.GetPrediction(input); } return new PredictionOutput(); }
public PredictionOutput GetImmobilePrediction(PredictionInput input) { throw new NotImplementedException(); }
public static PredictionOutput GetPrediction(PredictionInput input) { var mainTargetPrediction = Prediction.GetPrediction(input, false, true); var posibleTargets = new List<PossibleTarget> { new PossibleTarget { Position = mainTargetPrediction.UnitPosition.To2D(), Unit = input.Unit } }; if (mainTargetPrediction.Hitchance >= HitChance.Medium) { //Add the posible targets in range: posibleTargets.AddRange(GetPossibleTargets(input)); } if (posibleTargets.Count > 1) { var candidates = new List<Vector2>(); foreach (var target in posibleTargets) { target.Position = target.Position - input.From.To2D(); } for (var i = 0; i < posibleTargets.Count; i++) { for (var j = 0; j < posibleTargets.Count; j++) { if (i != j) { var p = (posibleTargets[i].Position + posibleTargets[j].Position) * 0.5f; if (!candidates.Contains(p)) { candidates.Add(p); } } } } var bestCandidateHits = -1; var bestCandidate = new Vector2(); var positionsList = posibleTargets.Select(t => t.Position).ToList(); foreach (var candidate in candidates) { var hits = GetHits(candidate, input.Range, input.Radius, positionsList); if (hits > bestCandidateHits) { bestCandidate = candidate; bestCandidateHits = hits; } } bestCandidate = bestCandidate + input.From.To2D(); if (bestCandidateHits > 1 && input.From.To2D().Distance(bestCandidate, true) > 50 * 50) { return new PredictionOutput { Hitchance = mainTargetPrediction.Hitchance, _aoeTargetsHitCount = bestCandidateHits, UnitPosition = mainTargetPrediction.UnitPosition, CastPosition = bestCandidate.To3D(), Input = input }; } } return mainTargetPrediction; }
public PredictionOutput GetMovementPrediction(PredictionInput input, bool checkCollision) { var predictedPosition = Vector3.Zero; var result = new PredictionOutput { Input = input, HitChance = HitChance.VeryHigh }; var paths = input.Unit.Path; if (input.AoE || input.Type == SkillshotType.Circle) { input.Radius /= 2f; } for (var i = 0; i < paths.Length - 1; i++) { var previousPath = paths[i]; var currentPath = paths[i + 1]; var passedPath = previousPath.Distance(input.Unit.ServerPosition); var remainingPath = input.Unit.ServerPosition.Distance(currentPath); var pathRatio = passedPath / remainingPath; var direction = (currentPath - previousPath).Normalized(); var delays = Game.Ping / 1000f + input.Delay; predictedPosition = input.Unit.ServerPosition + direction * (delays * input.Unit.MoveSpeed); var unitPositionImpactTime = input.From.Distance(predictedPosition) / input.Speed; result.UnitPosition = input.Unit.ServerPosition + direction * (unitPositionImpactTime * input.Unit.MoveSpeed); if (input.From.Distance(result.UnitPosition) + input.Delay * input.Unit.MoveSpeed > input.Range) { result.HitChance = HitChance.OutOfRange; } var toUnit = (result.UnitPosition - input.From).Normalized(); var castDirection = (direction + toUnit) / 2f; predictedPosition = result.UnitPosition - castDirection * (input.Unit.BoundingRadius + input.Radius); castDirection *= pathRatio; predictedPosition = predictedPosition + castDirection * input.Radius; if (input.From.Distance(predictedPosition) > input.Range) { result.HitChance = HitChance.OutOfRange; } var toPredictionPosition = (predictedPosition - input.From).Normalized(); var cosTheta = Vector3.Dot(toUnit, toPredictionPosition); var distance = input.From.Distance(predictedPosition); var a = Vector3.Dot(direction, direction) - (Math.Abs(input.Speed - float.MaxValue) <= 0 ? float.MaxValue : (float)Math.Pow(input.Speed, 2)); var b = 2 * distance * input.Unit.MoveSpeed * cosTheta; var c = (float)Math.Pow(distance, 2); var discriminant = b * b - 4f * a * c; if (discriminant < 0) { result.HitChance = HitChance.OutOfRange; } var impactTime = 2f * c / ((float)Math.Sqrt(discriminant) - b); if (remainingPath / input.Unit.MoveSpeed < impactTime) { continue; } result.CastPosition = input.Unit.ServerPosition + direction * (impactTime * input.Unit.MoveSpeed); } if (!checkCollision || !input.Collision) { return(result); } var collisionObjects = Collision.GetCollision( new List <Vector3> { input.Unit.ServerPosition, result.UnitPosition, result.CastPosition }, input); if (collisionObjects.Count > 0) { result.HitChance = HitChance.Collision; } return(result); }
public void Combo() { List <Obj_AI_Base> shadows = GetShadows(); if (!shadows.Any() || (!q.UseOnCombo && !e.UseOnCombo) || (!q.IsReady() && !e.IsReady())) //Console.WriteLine("shadow combo 1"); { return; } foreach (Obj_AI_Base objAiBase in shadows) { if (((q.UseOnCombo && !q.IsReady()) || !q.UseOnCombo) && ((e.UseOnCombo && !e.IsReady()) || !e.UseOnCombo)) { break; } if (q.UseOnCombo && q.IsReady()) { Obj_AI_Hero target = TargetSelector.GetTarget( q.Range, q.DamageType, true, null, objAiBase.Position); if (target != null) { PredictionInput predictionInput = new PredictionInput(); predictionInput.Range = q.Range; predictionInput.RangeCheckFrom = objAiBase.Position; predictionInput.From = objAiBase.Position; predictionInput.Delay = q.Delay; predictionInput.Speed = q.Speed; predictionInput.Unit = target; predictionInput.Type = SkillshotType.SkillshotLine; predictionInput.Collision = false; PredictionOutput predictionOutput = Prediction.GetPrediction(predictionInput); if (predictionOutput.Hitchance >= HitChance.Medium) { q.Cast(predictionOutput.CastPosition); //Console.WriteLine("combo shadow 2 q"); } } } if (e.UseOnCombo && e.IsReady()) { Obj_AI_Hero target = TargetSelector.GetTarget(e.Range, e.DamageType, true, null, objAiBase.Position); if (target != null) { e.Cast(); //Console.WriteLine("combo shadow use e 3"); } } } }
internal static PredictionOutput GetStandardPrediction(PredictionInput input) { var speed = input.Unit.MoveSpeed; if (input.Unit.Distance(input.From, true) < 200 * 200) { //input.Delay /= 2; speed /= 1.5f; } var result = GetPositionOnPath(input, input.Unit.GetWaypoints(), speed); var totalDelay = input.From.Distance(input.Unit.ServerPosition) / input.Speed + input.Delay; var fixRange = (input.Unit.MoveSpeed * totalDelay) / 2; var LastWaypiont = input.Unit.GetWaypoints().Last().To3D(); if (input.Type == SkillshotType.SkillshotLine) { if (PathTracker.GetAngle(input.From, input.Unit) < 32 + 1) result.Hitchance = HitChance.VeryHigh; else result.Hitchance = HitChance.High; } else if (input.Type == SkillshotType.SkillshotCircle) { if (totalDelay < 0.35 && (PathTracker.GetCurrentPath(input.Unit).Time < 0.1d || input.Unit.IsWindingUp)) result.Hitchance = HitChance.VeryHigh; } if (input.Unit.HasBuffOfType(BuffType.Slow) || input.Unit.Distance(input.From) < 300 || LastWaypiont.Distance(input.From) < 300) result.Hitchance = HitChance.VeryHigh; if (LastWaypiont.Distance(input.Unit.ServerPosition) > 700) { if (input.From.Distance(input.Unit.ServerPosition) < input.Range - fixRange) result.Hitchance = HitChance.VeryHigh; } //BAD PREDICTION if (input.Unit.Path.Count() == 0 && input.Unit.Position == input.Unit.ServerPosition) { if (input.From.Distance(input.Unit.ServerPosition) > input.Range - fixRange) result.Hitchance = HitChance.High; } else if (LastWaypiont.Distance(input.From) <= input.Unit.Distance(input.From)) { if (input.From.Distance(input.Unit.ServerPosition) > input.Range - fixRange) result.Hitchance = HitChance.High; } if (totalDelay > 0.5 && input.Unit.IsWindingUp) { result.Hitchance = HitChance.Medium; } if (input.Unit.Path.Count() > 1) { result.Hitchance = HitChance.Medium; } return result; }
internal static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input) { if (!input.Unit.IsValid<AIHeroClient>() || input.Radius == 1) { result.Hitchance = HitChance.VeryHigh; return result; } // CAN'T MOVE SPELLS /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetSpecialSpellEndTime(input.Unit) > 100 || input.Unit.HasBuff("Recall") || (UnitTracker.GetLastStopMoveTime(input.Unit) < 100 && input.Unit.IsRooted)) { OktwCommon.debug("CAN'T MOVE SPELLS"); result.Hitchance = HitChance.VeryHigh; result.CastPosition = input.Unit.Position; return result; } // NEW VISABLE /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetLastVisableTime(input.Unit) < 100) { OktwCommon.debug("PRED: NEW VISABLE"); result.Hitchance = HitChance.Medium; return result; } // PREPARE MATH /////////////////////////////////////////////////////////////////////////////////// result.Hitchance = HitChance.Medium; var lastWaypiont = input.Unit.GetWaypoints().Last().To3D(); var distanceUnitToWaypoint = lastWaypiont.LSDistance(input.Unit.ServerPosition); var distanceFromToUnit = input.From.LSDistance(input.Unit.ServerPosition); var distanceFromToWaypoint = lastWaypiont.LSDistance(input.From); var getAngle = GetAngle(input.From, input.Unit); float speedDelay = distanceFromToUnit / input.Speed; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) speedDelay = 0; float totalDelay = speedDelay + input.Delay; float moveArea = input.Unit.MoveSpeed * totalDelay; float fixRange = moveArea * 0.35f; float pathMinLen = 800 + moveArea; double angleMove = 32; if (input.Type == SkillshotType.SkillshotCircle) { fixRange -= input.Radius / 2; } // FIX RANGE /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToWaypoint <= distanceFromToUnit) { if (distanceFromToUnit > input.Range - fixRange) { result.Hitchance = HitChance.Medium; return result; } } var points = OktwCommon.CirclePoints(15, 450, input.Unit.Position).Where(x => x.LSIsWall()); if (points.Count() > 2) { var runOutWall = true; foreach (var point in points) { if (input.Unit.Position.LSDistance(point) > lastWaypiont.LSDistance(point)) { Render.Circle.DrawCircle(point, 50, System.Drawing.Color.Orange, 1); runOutWall = false; } } if (runOutWall) { OktwCommon.debug("PRED: RUN OUT WALL"); result.Hitchance = HitChance.VeryHigh; return result; } } if (input.Unit.GetWaypoints().Count == 1) { if (UnitTracker.GetLastStopMoveTime(input.Unit) < 600) { //OktwCommon.debug("PRED: STOP HIGH"); result.Hitchance = HitChance.High; return result; } else { OktwCommon.debug("PRED: STOP LOGIC"); result.Hitchance = HitChance.VeryHigh; } } // SPAM POSITION /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.SpamSamePlace(input.Unit)) { OktwCommon.debug("PRED: SPAM POSITION"); result.Hitchance = HitChance.VeryHigh; return result; } // SPECIAL CASES /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToUnit < 250) { OktwCommon.debug("PRED: SPECIAL CASES NEAR"); result.Hitchance = HitChance.VeryHigh; return result; } else if (input.Unit.MoveSpeed < 250) { OktwCommon.debug("PRED: SPECIAL CASES SLOW"); result.Hitchance = HitChance.VeryHigh; return result; } else if (distanceFromToWaypoint < 250) { OktwCommon.debug("PRED: SPECIAL CASES ON WAY"); result.Hitchance = HitChance.VeryHigh; return result; } // LONG CLICK DETECTION /////////////////////////////////////////////////////////////////////////////////// if (distanceUnitToWaypoint > pathMinLen) { OktwCommon.debug("PRED: LONG CLICK DETECTION"); result.Hitchance = HitChance.VeryHigh; return result; } // LOW HP DETECTION /////////////////////////////////////////////////////////////////////////////////// if (input.Unit.HealthPercent < 20 || ObjectManager.Player.HealthPercent < 20) { result.Hitchance = HitChance.VeryHigh; return result; } // RUN IN LANE DETECTION /////////////////////////////////////////////////////////////////////////////////// if (getAngle < angleMove && UnitTracker.GetLastNewPathTime(input.Unit) < 100) { OktwCommon.debug(GetAngle(input.From, input.Unit) + " PRED: ANGLE " + angleMove + " DIS " + distanceUnitToWaypoint); result.Hitchance = HitChance.VeryHigh; return result; } // CIRCLE NEW PATH /////////////////////////////////////////////////////////////////////////////////// if (input.Type == SkillshotType.SkillshotCircle) { if (UnitTracker.GetLastNewPathTime(input.Unit) < 100 && distanceUnitToWaypoint > fixRange) { OktwCommon.debug("PRED: CIRCLE NEW PATH"); result.Hitchance = HitChance.VeryHigh; return result; } } //Program.debug("PRED: NO DETECTION"); return result; }
private bool ELogic(Obj_AI_Hero mainTarget, List <Obj_AI_Base> targets, HitChance hitChance, int minHits, float overrideExtendedDistance = -1) { try { var input = new PredictionInput { Range = ELength, Delay = E.Delay, Radius = E.Width, Speed = E.Speed, Type = E.Type }; var input2 = new PredictionInput { Range = MaxERange, Delay = E.Delay, Radius = E.Width, Speed = E.Speed, Type = E.Type }; var startPos = Vector3.Zero; var endPos = Vector3.Zero; var hits = 0; targets = targets.Where(t => t.IsValidTarget(MaxERange + E.Width * 1.1f)).ToList(); var targetCount = targets.Count; foreach (var target in targets) { bool containsTarget; var lTarget = target; if (target.Distance(Player.Position) <= E.Range) { containsTarget = mainTarget == null || lTarget.NetworkId == mainTarget.NetworkId; var cCastPos = target.Position; foreach (var t in targets.Where(t => t.NetworkId != lTarget.NetworkId)) { var count = 1; var cTarget = t; input.Unit = t; input.From = cCastPos; input.RangeCheckFrom = cCastPos; var pred = Prediction.GetPrediction(input); if (pred.Hitchance >= (hitChance - 1)) { count++; if (!containsTarget) { containsTarget = t.NetworkId == mainTarget.NetworkId; } var rect = new Geometry.Polygon.Rectangle( cCastPos.To2D(), cCastPos.Extend(pred.CastPosition, ELength).To2D(), E.Width); foreach (var c in targets.Where( c => c.NetworkId != cTarget.NetworkId && c.NetworkId != lTarget.NetworkId)) { input.Unit = c; var cPredPos = c.Type == GameObjectType.obj_AI_Minion ? c.Position : Prediction.GetPrediction(input).UnitPosition; if ( new Geometry.Polygon.Circle( cPredPos, (c.Type == GameObjectType.obj_AI_Minion && c.IsMoving ? (c.BoundingRadius / 2f) : (c.BoundingRadius) * 0.9f)).Points.Any(p => rect.IsInside(p))) { count++; if (!containsTarget && c.NetworkId == mainTarget.NetworkId) { containsTarget = true; } } } if (count > hits && containsTarget) { hits = count; startPos = cCastPos; endPos = cCastPos.Extend(pred.CastPosition, ELength); if (hits == targetCount) { break; } } } } if (endPos.Equals(Vector3.Zero) && containsTarget) { startPos = target.IsFacing(Player) && IsSpellUpgraded(E) ? Player.Position.Extend(cCastPos, Player.Distance(cCastPos) - (ELength / 10f)) : cCastPos; endPos = Player.Position.Extend(cCastPos, ELength); hits = 1; } } else { input2.Unit = lTarget; var castPos = Prediction.GetPrediction(input2).CastPosition; var sCastPos = Player.Position.Extend(castPos, E.Range); var extDist = overrideExtendedDistance > 0 ? overrideExtendedDistance : (ELength / 4f); var circle = new Geometry.Polygon.Circle(Player.Position, sCastPos.Distance(Player.Position), 45).Points .Where(p => p.Distance(sCastPos) < extDist).OrderBy(p => p.Distance(lTarget)); foreach (var point in circle) { input2.From = point.To3D(); input2.RangeCheckFrom = point.To3D(); input2.Range = ELength; var pred2 = Prediction.GetPrediction(input2); if (pred2.Hitchance >= hitChance) { containsTarget = mainTarget == null || lTarget.NetworkId == mainTarget.NetworkId; var count = 1; var rect = new Geometry.Polygon.Rectangle( point, point.To3D().Extend(pred2.CastPosition, ELength).To2D(), E.Width); foreach (var c in targets.Where(t => t.NetworkId != lTarget.NetworkId)) { input2.Unit = c; var cPredPos = c.Type == GameObjectType.obj_AI_Minion ? c.Position : Prediction.GetPrediction(input2).UnitPosition; if ( new Geometry.Polygon.Circle( cPredPos, (c.Type == GameObjectType.obj_AI_Minion && c.IsMoving ? (c.BoundingRadius / 2f) : (c.BoundingRadius) * 0.9f)).Points.Any(p => rect.IsInside(p))) { count++; if (!containsTarget && c.NetworkId == mainTarget.NetworkId) { containsTarget = true; } } } if (count > hits && containsTarget || count == hits && containsTarget && mainTarget != null && point.Distance(mainTarget.Position) < startPos.Distance(mainTarget.Position)) { hits = count; startPos = point.To3D(); endPos = startPos.Extend(pred2.CastPosition, ELength); if (hits == targetCount) { break; } } } } } if (hits == targetCount) { break; } } if (hits >= minHits && !startPos.Equals(Vector3.Zero) && !endPos.Equals(Vector3.Zero)) { E.Cast(startPos, endPos); return(true); } } catch (Exception ex) { Global.Logger.AddItem(new LogItem(ex)); } return(false); }
internal static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input) { if (!input.Unit.IsValid<Obj_AI_Hero>() || input.Radius == 1) { result.Hitchance = HitChance.VeryHigh; return result; } // CAN'T MOVE SPELLS /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetSpecialSpellEndTime(input.Unit) > 0 || input.Unit.HasBuff("Recall")) { result.Hitchance = HitChance.VeryHigh; return result; } // NEW VISABLE /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetLastVisableTime(input.Unit) < 0.1d) { Program.debug("PRED: NEW VISABLE"); result.Hitchance = HitChance.Medium; return result; } // PREPARE MATH /////////////////////////////////////////////////////////////////////////////////// result.Hitchance = HitChance.Medium; var lastWaypiont = input.Unit.GetWaypoints().Last().To3D(); var distanceUnitToWaypoint = lastWaypiont.Distance(input.Unit.ServerPosition); var distanceFromToUnit = input.From.Distance(input.Unit.ServerPosition); var distanceFromToWaypoint = lastWaypiont.Distance(input.From); var getAngle = GetAngle(input.From, input.Unit); float speedDelay = distanceFromToUnit / input.Speed; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) speedDelay = 0; float totalDelay = speedDelay + input.Delay; float moveArea = input.Unit.MoveSpeed * totalDelay; float fixRange = moveArea * 0.4f; float pathMinLen = 900 + +moveArea; double angleMove = 30 + (input.Radius / 17) - totalDelay - (input.Delay * 2); if (angleMove < 31) angleMove = 31; if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d) { result.Hitchance = HitChance.High; pathMinLen = 600f + moveArea; angleMove += 2; fixRange = moveArea * 0.3f; } if (input.Type == SkillshotType.SkillshotCircle) { fixRange -= input.Radius / 2; } // FIX RANGE /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToWaypoint <= distanceFromToUnit && distanceFromToUnit > input.Range - fixRange) { //debug("PRED: FIX RANGE"); result.Hitchance = HitChance.Medium; return result; } // SPAM CLICK /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.PathCalc(input.Unit)) { Program.debug("PRED: SPAM CLICK"); result.Hitchance = HitChance.VeryHigh; return result; } // SPAM POSITION /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.SpamSamePlace(input.Unit)) { Program.debug("PRED: SPAM POSITION"); result.Hitchance = HitChance.VeryHigh; return result; } // SPECIAL CASES /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToUnit < 250 || input.Unit.MoveSpeed < 200 || distanceFromToWaypoint < 100) { Program.debug("PRED: SPECIAL CASES"); result.Hitchance = HitChance.VeryHigh; return result; } // LONG CLICK DETECTION /////////////////////////////////////////////////////////////////////////////////// if (distanceUnitToWaypoint > pathMinLen) { Program.debug("PRED: LONG CLICK DETECTION"); result.Hitchance = HitChance.VeryHigh; return result; } // RUN IN LANE DETECTION /////////////////////////////////////////////////////////////////////////////////// if ( getAngle < angleMove) { if (distanceUnitToWaypoint > fixRange && UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d) { Program.debug(GetAngle(input.From, input.Unit) + " PRED: ANGLE " + angleMove); result.Hitchance = HitChance.VeryHigh; return result; } if (ObjectManager.Player.IsMoving) { if (ObjectManager.Player.IsFacing(input.Unit)) { if (!input.Unit.IsFacing(ObjectManager.Player)) { Program.debug(" PRED:TRY CATCH"); result.Hitchance = HitChance.VeryHigh; return result; } } else { if (input.Unit.IsFacing(ObjectManager.Player)) { Program.debug(" PRED:TRY CATCH 2"); result.Hitchance = HitChance.VeryHigh; return result; } } } } // AUTO ATTACK LOGIC /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetLastAutoAttackTime(input.Unit) < 0.1d) { if (input.Type == SkillshotType.SkillshotLine && totalDelay < 0.4 + (input.Radius * 0.002)) { Program.debug("PRED: AUTO ATTACK DETECTION 1"); result.Hitchance = HitChance.VeryHigh; return result; } else if (input.Type == SkillshotType.SkillshotCircle && totalDelay < 0.6 + (input.Radius * 0.002)) { Program.debug("PRED: AUTO ATTACK DETECTION 2"); result.Hitchance = HitChance.VeryHigh; return result; } else { result.Hitchance = HitChance.High; Program.debug("PRED: AUTO ATTACK DETECTION HIGH"); } } // STOP LOGIC /////////////////////////////////////////////////////////////////////////////////// else if (input.Unit.Path.Count() == 0 || !input.Unit.IsMoving) { if (input.Unit.IsWindingUp) result.Hitchance = HitChance.High; else if (UnitTracker.GetLastStopMoveTime(input.Unit) < 0.5d) result.Hitchance = HitChance.High; else { Program.debug("PRED: STOP LOGIC"); result.Hitchance = HitChance.VeryHigh; } return result; } // CIRCLE NEW PATH /////////////////////////////////////////////////////////////////////////////////// if (input.Type == SkillshotType.SkillshotCircle) { if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d && distanceUnitToWaypoint > fixRange) { Program.debug("PRED: CIRCLE NEW PATH"); result.Hitchance = HitChance.VeryHigh; return result; } } //Program.debug("PRED: NO DETECTION"); return result; }
private void OnUpdate() { var Targets = EntityManager <Hero> .Entities.Where( x => x.IsValid && x.Team != Context.Owner.Team && !x.IsIllusion).ToList(); foreach (var Target in Targets) { var Input = new PredictionInput( Context.Owner, Target, 0.5f, float.MaxValue, float.MaxValue, 410, PredictionSkillshotType.SkillshotCircle, true, Targets.Where(x => x.IsVisible).ToList()) { CollisionTypes = CollisionTypes.None }; var Output = Prediction.GetPrediction(Input); if (Output.Unit.IsVisible && Output.AoeTargetsHit.Count >= (Config.AmountItem.Value == 1 ? 2 : Config.AmountItem.Value)) { Context.Particle.AddOrUpdate( Context.Owner, $"Radius{Output.Unit.Handle}", "particles/ui_mouseactions/drag_selected_ring.vpcf", ParticleAttachment.AbsOrigin, RestartType.None, 0, Output.CastPosition, 1, Color.Aqua, 2, 420 * -1.1f); /*Context.Particle.AddOrUpdate( * Context.Owner, * $"Text{Output.Unit.Handle}", * "materials/ensage_ui/particle_textures/combo.vpcf", * ParticleAttachment.AbsOrigin, * RestartType.FullRestart, * 0, * Output.CastPosition, * 1, * new Vector3(Output.AoeTargetsHit.Count, 0, 0), * 2, * new Vector3(200, 255, 0), * 3, * new Vector3(255, 255, 255));*/ } else { Context.Particle.Remove($"Radius{Output.Unit.Handle}"); Context.Particle.Remove($"Text{Output.Unit.Handle}"); } } OffOutput = null; if (Config.TargetItem.Value.SelectedValue.Contains("Lock") && TargetSelector.IsActive && (Main.ReversePolarity != null && Main.ReversePolarity.Ability.IsInAbilityPhase)) { OffTarget = TargetSelector.Active.GetTargets().OrderBy(x => x.Distance2D(Context.Owner)).FirstOrDefault() as Hero; } else if (Config.TargetItem.Value.SelectedValue.Contains("Lock") && TargetSelector.IsActive && (!Config.ComboKeyItem || OffTarget == null || !OffTarget.IsValid || !OffTarget.IsAlive)) { OffTarget = TargetSelector.Active.GetTargets().FirstOrDefault( x => x.Distance2D(Game.MousePosition) <= 500) as Hero; } else if (Config.TargetItem.Value.SelectedValue.Contains("Default") && TargetSelector.IsActive) { OffTarget = TargetSelector.Active.GetTargets().FirstOrDefault( x => x.Distance2D(Game.MousePosition) <= 500) as Hero; } if (OffTarget != null) { var Input = new PredictionInput( Context.Owner, OffTarget, 0.5f, float.MaxValue, float.MaxValue, 410, PredictionSkillshotType.SkillshotCircle, true, Targets.Where(x => x.IsVisible).ToList()) { CollisionTypes = CollisionTypes.None }; OffOutput = Prediction.GetPrediction(Input); if (OffOutput != null) { Context.Particle.DrawTargetLine( Context.Owner, "Target", RP() ? (OffOutput.AoeTargetsHit.Count < 2 ? OffOutput.Unit.Position : OffOutput.CastPosition) : OffOutput.Unit.Position, Config.ComboKeyItem ? Color.Red : Color.Aqua); } else { Context.Particle.Remove("Target"); } } else { Context.Particle.Remove("Target"); } if (Config.ComboRadiusItem && Main.Blink != null) { Context.Particle.DrawRange( Context.Owner, "ComboRadius", Main.Blink.CastRange, Color.Aqua); } else { Context.Particle.Remove("ComboRadius"); } }
/// <summary> /// Calculates the position to cast a spell according to unit movement. /// </summary> /// <param name="input">PredictionInput type</param> /// <param name="additionalSpeed">Additional Speed (Multiplicative)</param> /// <returns>The <see cref="PredictionOutput" /></returns> internal static PredictionOutput GetAdvancedPrediction(PredictionInput input, float additionalSpeed = 0) { var speed = Math.Abs(additionalSpeed) < float.Epsilon ? input.Speed : input.Speed * additionalSpeed; if (Math.Abs(speed - int.MaxValue) < float.Epsilon) { speed = 90000; } var unit = input.Unit; var position = PositionAfter(unit, 1, unit.MoveSpeed - 100); var prediction = position + speed * (unit.Direction.To2D().Perpendicular().Normalized() / 2.5f * (input.Delay / 1000)) * input.Radius / unit.Distance(Player); var hitChance = HitChance.VeryHigh; var fixedPred = Player.ServerPosition.Extend(prediction.To3D(), unit.Distance(Player)); if (Player.Distance(unit) > input.Range) { hitChance = HitChance.Impossible; } if (!unit.CanMove) { hitChance = HitChance.Immobile; } // Check if by the time the spell arrives the unit will still be in range var spellArrivalTime = Player.Distance(fixedPred) / input.Speed * 1000 + input.Delay / 1000; var positionAfterArrival = PositionAfter(unit, spellArrivalTime / 1000, unit.MoveSpeed); if (Player.Distance(positionAfterArrival) > input.Range) { hitChance = HitChance.OutOfRange; } if (!input.Collision) { return(new PredictionOutput() { UnitPosition = new Vector3(position.X, position.Y, unit.ServerPosition.Z), CastPosition = new Vector3(fixedPred.X, fixedPred.Y, unit.ServerPosition.Z), Hitchance = hitChance }); } // A circle/cone that has collision...? if (input.Collision && input.Type != SkillshotType.SkillshotLine) { return(new PredictionOutput() { UnitPosition = new Vector3(position.X, position.Y, unit.ServerPosition.Z), CastPosition = new Vector3(fixedPred.X, fixedPred.Y, unit.ServerPosition.Z), Hitchance = hitChance }); } var positions = new List <Vector3> { position.To3D2(), fixedPred, unit.ServerPosition }; var collision = LeagueSharp.Common.Collision.GetCollision(positions, input); collision.RemoveAll(x => x.NetworkId == input.Unit.NetworkId); hitChance = collision.Count > 0 ? HitChance.Collision : hitChance; return(new PredictionOutput() { UnitPosition = new Vector3(position.X, position.Y, unit.ServerPosition.Z), CastPosition = new Vector3(fixedPred.X, fixedPred.Y, unit.ServerPosition.Z), Hitchance = hitChance }); }
public static void OnWaveClear() { // Mana check if (player.ManaPercentage() < Config.SliderLinks["waveMana"].Value.Value) { return; } // Check spells if (!Q.IsEnabledAndReady(Mode.WAVE) && !E.IsEnabledAndReady(Mode.WAVE)) { return; } // Minions around var minions = MinionManager.GetMinions(Q.Range, MinionTypes.All, MinionTeam.Enemy, MinionOrderTypes.MaxHealth); if (minions.Count == 0) { return; } // Q usage if (Q.IsEnabledAndReady(Mode.WAVE) && !player.IsDashing()) { int hitNumber = Config.SliderLinks["waveNumQ"].Value.Value; // Validate available minions if (minions.Count >= hitNumber) { // Get only killable minions var killable = minions.FindAll(m => m.Health < Q.GetDamage(m)); if (killable.Count > 0) { // Prepare prediction input for Collision check var input = new PredictionInput() { From = Q.From, Collision = Q.Collision, Delay = Q.Delay, Radius = Q.Width, Range = Q.Range, RangeCheckFrom = Q.RangeCheckFrom, Speed = Q.Speed, Type = Q.Type, CollisionObjects = new[] { CollisionableObjects.Heroes, CollisionableObjects.Minions, CollisionableObjects.YasuoWall } }; // Helpers var currentHitNumber = 0; var castPosition = Vector3.Zero; // Validate the collision foreach (var target in killable) { // Update unit in the input input.Unit = target; // Get colliding objects var colliding = LeagueSharp.Common.Collision.GetCollision(new List <Vector3>() { player.ServerPosition.Extend(Prediction.GetPrediction(input).UnitPosition, Q.Range) }, input) .MakeUnique() .OrderBy(e => e.Distance(player, true)) .ToList(); // Validate collision if (colliding.Count >= hitNumber && !colliding.Contains(player)) { // Calculate hit number int i = 0; foreach (var collide in colliding) { // Break loop here since we can't kill the target if (Q.GetDamage(collide) < collide.Health) { if (currentHitNumber < i && i >= hitNumber) { currentHitNumber = i; castPosition = Q.GetPrediction(collide).CastPosition; } break; } // Increase hit count i++; } } } // Check if we have a valid target with enough targets being killed if (castPosition != Vector3.Zero) { if (Q.Cast(castPosition)) { return; } } } } } // General E usage if (E.IsEnabledAndReady(Mode.WAVE)) { int hitNumber = Config.SliderLinks["waveNumE"].Value.Value; // Get minions in E range var minionsInRange = minions.FindAll(m => E.IsInRange(m)); // Validate available minions if (minionsInRange.Count >= hitNumber) { // Check if enough minions die with E int killableNum = 0; foreach (var minion in minionsInRange) { if (minion.IsRendKillable()) { // Increase kill number killableNum++; // Cast on condition met if (killableNum >= hitNumber) { if (E.Cast(true)) { return; } break; } } } } } }
/// <summary> /// Returns the list of the units that the skillshot will hit before reaching the set positions. /// </summary> /// private static bool MinionIsDead(PredictionInput input, Obj_AI_Base minion , float distance) { float delay = (distance / input.Speed) + input.Delay; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) delay = input.Delay; int convert = (int)(delay * 1000); if (HealthPrediction.LaneClearHealthPrediction(minion, convert, 0) <= 0) { return true; } else { return false; } }
public override async Task ExecuteAsync(CancellationToken token) { Target = this.TargetSelector.Active.GetTargets().FirstOrDefault(x => !x.IsInvulnerable()); var allTargets = this.TargetSelector.Active.GetTargets().FirstOrDefault(); var silenced = UnitExtensions.IsSilenced(this.Owner); var sliderValue = this.Config.UseBlinkPrediction.Item.GetValue <Slider>().Value; var myHpThreshold = this.Config.SelfHPDrain.Item.GetValue <Slider>().Value; var postDrainHp = this.Config.PostDrainHP.Item.GetValue <Slider>().Value; var allyPostDrain = this.Config.HealAllyTo.Item.GetValue <Slider>().Value; var healThreshold = this.Config.DrainHP.Item.GetValue <Slider>().Value; var wardTars = this.Config.WardTargets.Item.GetValue <Slider>().Value; //warnings if (myHpThreshold < postDrainHp && this.Config.AbilityToggler.Value.IsEnabled(this.Drain.Name)) { Log.Debug( "Post drain hp is higher than your hp threshold to begin healing, please change this or the script won't work."); return; } if (healThreshold > allyPostDrain && this.Config.AbilityToggler.Value.IsEnabled(this.Drain.Name)) { Log.Debug("Your ally's post heal threshold is lower than their heal threshold, please fix this."); return; } if (!silenced) { try { var tempHealTarget = EntityManager <Hero> .Entities.FirstOrDefault( x => x.IsAlive && x.Team == this.Owner.Team && x != Owner && !x.IsIllusion && ((float)x.Health / (float)x.MaximumHealth) * 100 < healThreshold && !UnitExtensions.IsMagicImmune(x) && Config.HealTargetHeroes.Value.IsEnabled(x.Name)); var myHealth = (float)Owner.Health / (float)Owner.MaximumHealth * 100; if (tempHealTarget != null) { HealTarget = tempHealTarget; } if (HealTarget != null) { if (HealTarget != null && this.Config.AbilityToggler.Value.IsEnabled(this.Drain.Name) && !UnitExtensions.IsChanneling(Owner) && myHealth >= myHpThreshold && HealTarget.Distance2D(this.Owner) <= Drain.CastRange && HealTarget.HealthPercent() * 100 < healThreshold) { this.Drain.UseAbility(HealTarget); IsHealing = true; await Await.Delay(GetAbilityDelay(HealTarget, Drain), token); } //Stop Healing; There is no hidden modifier/any way to check if we are healing a target. if ((UnitExtensions.IsChanneling(Owner) && myHealth <= postDrainHp) && IsHealing) { Owner.Stop(); IsHealing = false; } if (HealTarget != null && IsHealing && (HealTarget.HealthPercent() >= ((float)allyPostDrain / 100))) { Owner.Stop(); IsHealing = false; } if (HealTarget == null && IsHealing) { Owner.Stop(); IsHealing = false; } } } catch (Exception) { // ignore } } if (IsHealing) { return; } if ((this.BlinkDagger != null) && (this.BlinkDagger.Item.IsValid) && Target != null && Owner.Distance2D(Target) <= 1200 + sliderValue && !(Owner.Distance2D(Target) <= 400) && this.BlinkDagger.Item.CanBeCasted(Target) && this.Config.ItemToggler.Value.IsEnabled(this.BlinkDagger.Item.Name) && !UnitExtensions.IsChanneling(Owner)) { 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); Log.Debug("Using BlinkDagger"); this.BlinkDagger.UseAbility(position); await Await.Delay(this.GetItemDelay(position) + (int)Game.Ping, token); } if (!silenced && Target != null) { var targets = EntityManager <Hero> .Entities.Where( x => x.IsValid && x.Team != this.Owner.Team && !x.IsIllusion && !UnitExtensions.IsMagicImmune(x) && x.Distance2D(this.Owner) <= Ward.GetAbilityData("radius")) .ToList(); if (targets.Count >= wardTars && this.Ward.CanBeCasted() && !UnitExtensions.IsChanneling(Owner) && this.Config.AbilityToggler.Value.IsEnabled(this.Ward.Name)) { Log.Debug($"Using Ward"); Ward.UseAbility(Owner.NetworkPosition); await Await.Delay(GetAbilityDelay(Owner, Ward), token); } try { // var thresholdTars = this.Config.WardTargets.Item.GetValue<Slider>(); var manaDecrepify = Decrepify.GetManaCost(Decrepify.Level - 1); var manaBlast = Blast.GetManaCost(Blast.Level - 1); // var manaDrain = Drain.GetManaCost(Drain.Level - 1); if (Decrepify.CanBeCasted() && Target != null && Decrepify.CanHit(Target) && this.Config.AbilityToggler.Value.IsEnabled(this.Decrepify.Name) && this.Owner.Mana >= manaBlast + manaDecrepify && !UnitExtensions.IsChanneling(Owner) && Target.IsAlive) { this.Decrepify.UseAbility(Target); await Await.Delay(GetAbilityDelay(Target, Decrepify), token); } if (this.Blast.CanBeCasted() && this.Config.AbilityToggler.Value.IsEnabled(this.Blast.Name) && (!this.Decrepify.CanBeCasted() || manaBlast > Owner.Mana - manaDecrepify) && !UnitExtensions.IsChanneling(Owner) && Target != null && Target.IsAlive) { var delay = Blast.GetAbilityData("delay") + Blast.GetCastPoint(); var blastTargets = EntityManager <Hero> .Entities.OrderBy(x => x == allTargets).Where( x => x.IsValid && x.IsVisible && x.Team != Owner.Team && !x.IsIllusion && !UnitExtensions.IsMagicImmune(x)).ToList(); var blastCastRange = Blast.CastRange; if (blastTargets == null) { return; } var input = new PredictionInput( Owner, Target, delay, float.MaxValue, blastCastRange, 400, PredictionSkillshotType.SkillshotCircle, true, blastTargets) { CollisionTypes = CollisionTypes.None }; var output = Prediction.GetPrediction(input); if (output.HitChance >= HitChance.Medium) { Log.Debug($"Using Blast"); this.Blast.UseAbility(output.CastPosition); await Await.Delay(GetAbilityDelay(Target.Position, this.Blast), token); } } } catch (Exception) { // ignored } } if (this.BloodThorn != null && this.BloodThorn.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.BloodThorn.Item.CanBeCasted(Target) && this.Config.ItemToggler.Value.IsEnabled(this.BloodThorn.Item.Name)) { Log.Debug("Using Bloodthorn"); this.BloodThorn.UseAbility(Target); await Await.Delay(this.GetItemDelay(Target), token); } if ((this.SheepStick != null) && (this.SheepStick.Item.IsValid) && Target != null && !UnitExtensions.IsChanneling(Owner) && this.SheepStick.Item.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.Dagon != null && this.Dagon.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.Dagon.Item.CanBeCasted(Target) && this.Config.ItemToggler.Value.IsEnabled(Dagon5.Item.Name)) { Log.Debug("Using Dagon"); this.Dagon.UseAbility(Target); await Await.Delay(this.GetItemDelay(Target), token); } if (this.Orchid != null && this.Orchid.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.Orchid.Item.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.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.RodofAtos.Item.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.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.VeilofDiscord.Item.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.HurricanePike != null && this.HurricanePike.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.HurricanePike.Item.CanBeCasted() && this.Config.ItemToggler.Value.IsEnabled("item_hurricane_pike")) { Log.Debug("Using HurricanePike"); this.HurricanePike.UseAbility(Target); await Await.Delay(this.GetItemDelay(Target), token); } if (this.ShivasGuard != null && this.ShivasGuard.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.ShivasGuard.Item.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, token); } if (this.Mjollnir != null && this.Mjollnir.Item.IsValid && Target != null && !UnitExtensions.IsChanneling(Owner) && this.Mjollnir.Item.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.Config.AbilityToggler.Value.IsEnabled(this.Blast.Name) && this.Config.AbilityToggler.Value.IsEnabled(this.Decrepify.Name)) { if (!silenced && this.Drain.CanBeCasted() && !this.Blast.CanBeCasted() && !this.Decrepify.CanBeCasted() && this.Config.AbilityToggler.Value.IsEnabled(this.Drain.Name) && !UnitExtensions.IsChanneling(Owner) && Target != null && Target.IsAlive) { Log.Debug($"Using Drain 1"); this.Drain.UseAbility(Target); await Await.Delay(GetAbilityDelay(Target, Drain) + 50, token); } } else { if (!silenced && this.Drain.CanBeCasted() && this.Config.AbilityToggler.Value.IsEnabled(this.Drain.Name) && !UnitExtensions.IsChanneling(Owner) && Target != null && Target.IsAlive) { Log.Debug($"Using Drain 2"); this.Drain.UseAbility(Target); await Await.Delay(GetAbilityDelay(Target, Drain) + 50, token); } } if (Target != null && !Owner.IsValidOrbwalkingTarget(Target) && !UnitExtensions.IsChanneling(this.Owner)) { Orbwalker.Move(Game.MousePosition); await Await.Delay(50, token); } else { Orbwalker.OrbwalkTo(Target); } await Await.Delay(50, token); }
private static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input) { if (!input.Unit.IsValid<Obj_AI_Hero>()) { result.Hitchance = HitChance.VeryHigh; return result; } var totalDelay = input.From.Distance(input.Unit.ServerPosition) / input.Speed + input.Delay; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) totalDelay = input.Delay; var fixRange = (input.Unit.MoveSpeed * totalDelay) * 0.6; var LastWaypiont = input.Unit.GetWaypoints().Last().To3D(); float pathMinLen = 550f; double angleMove = 30 + (input.Radius / 10); float BackToFront = input.Unit.MoveSpeed * totalDelay; if (PathTracker.GetCurrentPath(input.Unit).Time < 0.1d) { //pathMinLen = BackToFront * 2; angleMove += 5; fixRange = (input.Unit.MoveSpeed * totalDelay) * 0.4; } if (input.Type == SkillshotType.SkillshotCircle) { fixRange -= input.Radius / 2; } if (input.Type == SkillshotType.SkillshotLine) { if (input.Unit.Path.Count() > 0) { if (GetAngle(input.From, input.Unit) < angleMove) { result.Hitchance = HitChance.VeryHigh; } else result.Hitchance = HitChance.High; } } else if (input.Type == SkillshotType.SkillshotCircle) { if (totalDelay < 0.7 && OnProcessSpellDetection.GetLastAutoAttackTime(input.Unit) < 0.1d) result.Hitchance = HitChance.VeryHigh; else if (totalDelay < 1.1 && PathTracker.GetCurrentPath(input.Unit).Time < 0.1d) result.Hitchance = HitChance.VeryHigh; } if (input.Unit.MoveSpeed < 250f) { result.Hitchance = HitChance.VeryHigh; } if (LastWaypiont.Distance(input.Unit.ServerPosition) > pathMinLen) { result.Hitchance = HitChance.VeryHigh; } if (totalDelay < 0.7 + (input.Radius / 500) && OnProcessSpellDetection.GetLastAutoAttackTime(input.Unit) < 0.1d) { result.Hitchance = HitChance.VeryHigh; } if (input.Unit.Path.Count() == 0 && input.Unit.Position == input.Unit.ServerPosition && !input.Unit.IsWindingUp) { if (input.From.Distance(input.Unit.ServerPosition) > input.Range - fixRange) result.Hitchance = HitChance.High; else result.Hitchance = HitChance.VeryHigh; return result; } else if (LastWaypiont.Distance(input.From) <= input.Unit.Distance(input.From)) { if (input.From.Distance(input.Unit.ServerPosition) > input.Range - fixRange) { result.Hitchance = HitChance.High; } } if (input.Unit.Path.Count() > 0) { if (input.Unit.Distance(LastWaypiont) < BackToFront && PathTracker.GetCurrentPath(input.Unit).Time > 0.1d) { result.Hitchance = HitChance.Medium; } } if (totalDelay > 0.7 + (input.Radius / 500) && input.Unit.IsWindingUp) { result.Hitchance = HitChance.Medium; } if (input.Unit.Distance(input.From) < 300 || LastWaypiont.Distance(input.From) < 250 || input.Unit.MoveSpeed < 200f) { result.Hitchance = HitChance.VeryHigh; } return result; }
private static void UseItem(string name, int itemId, float range, bool targeted = false) { if (!Items.HasItem(itemId) || !Items.CanUseItem(itemId)) { return; } if (!_mainMenu.Item("use" + name).GetValue <bool>()) { return; } if (OC.CurrentTarget.Distance(Me.Position) <= range) { var eHealthPercent = (int)((OC.CurrentTarget.Health / OC.CurrentTarget.MaxHealth) * 100); var aHealthPercent = (int)((Me.Health / OC.CurrentTarget.MaxHealth) * 100); if (eHealthPercent <= _mainMenu.Item("use" + name + "Pct").GetValue <Slider>().Value&& _mainMenu.Item("ouseOn" + OC.CurrentTarget.SkinName).GetValue <bool>()) { if (targeted && itemId == 3092) { var pi = new PredictionInput { Aoe = true, Collision = false, Delay = 0.0f, From = Me.Position, Radius = 250f, Range = 850f, Speed = 1500f, Unit = OC.CurrentTarget, Type = SkillshotType.SkillshotCircle }; var po = Prediction.GetPrediction(pi); if (po.Hitchance >= HitChance.Medium) { Items.UseItem(itemId, po.CastPosition); OC.Logger(OC.LogType.Action, "Used " + name + " near " + po.CastPosition.CountEnemiesInRange(300) + " enemies!"); } } else if (targeted) { Items.UseItem(itemId, OC.CurrentTarget); OC.Logger(Program.LogType.Action, "Used " + name + " (Targeted Enemy HP) on " + OC.CurrentTarget.SkinName); } else { Items.UseItem(itemId); OC.Logger(Program.LogType.Action, "Used " + name + " (Self Enemy HP) on " + OC.CurrentTarget.SkinName); } } else if (aHealthPercent <= _mainMenu.Item("use" + name + "Me").GetValue <Slider>().Value&& _mainMenu.Item("ouseOn" + OC.CurrentTarget.SkinName).GetValue <bool>()) { if (targeted) { Items.UseItem(itemId, OC.CurrentTarget); } else { Items.UseItem(itemId); } OC.Logger(Program.LogType.Action, "Used " + name + " (Low My HP) on " + OC.CurrentTarget.SkinName); } } }
/// <summary> /// Returns the list of the units that the skillshot will hit before reaching the set positions. /// </summary> public static List<Obj_AI_Base> GetCollision(List<Vector3> positions, PredictionInput input) { var result = new List<Obj_AI_Base>(); foreach (var position in positions) { foreach (var objectType in input.CollisionObjects) { switch (objectType) { case CollisionableObjects.Minions: foreach (var minion in ObjectManager.Get<Obj_AI_Minion>().Where(minion => minion.IsValidTarget(Math.Min(input.Range + input.Radius + 100, 2000), true, input.From))) { input.Unit = minion; if (minion.ServerPosition.To2D().Distance(input.From.To2D()) < input.Radius) result.Add(minion); else { var minionPos = minion.ServerPosition; int bonusRadius = 20; if (minion.IsMoving) { minionPos = Prediction.GetPrediction(input, false, false).CastPosition; bonusRadius = 100; } if (minionPos.To2D().Distance(input.From.To2D(), position.To2D(), true, true) <= Math.Pow((input.Radius + bonusRadius + minion.BoundingRadius), 2)) { result.Add(minion); } } } break; case CollisionableObjects.Heroes: foreach (var hero in HeroManager.Enemies.FindAll( hero => hero.IsValidTarget( Math.Min(input.Range + input.Radius + 100, 2000), true, input.RangeCheckFrom)) ) { input.Unit = hero; var prediction = Prediction.GetPrediction(input, false, false); if ( prediction.UnitPosition.To2D() .Distance(input.From.To2D(), position.To2D(), true, true) <= Math.Pow((input.Radius + 50 + hero.BoundingRadius), 2)) { result.Add(hero); } } break; case CollisionableObjects.Walls: var step = position.Distance(input.From) / 20; for (var i = 0; i < 20; i++) { var p = input.From.To2D().Extend(position.To2D(), step * i); if (NavMesh.GetCollisionFlags(p.X, p.Y).HasFlag(CollisionFlags.Wall)) { result.Add(ObjectManager.Player); } } break; } } } return result.Distinct().ToList(); }
//Returns if the skillshot is about to hit the unit in the next time seconds. public bool IsAboutToHit(int time, Obj_AI_Base unit, Obj_AI_Base caster) { if (SkillshotData.Type == SkillShotType.SkillshotMissileLine) { if (!SkillshotData.IsDangerous) { time = time / 2; } var missilePos = GetMissilePosition(0); var missilePosAfterT = GetMissilePosition(time); /* * * * var collision = false; * foreach (var prob in * ObjectManager.Get<Obj_AI_Base>() * .Where( * o => * o.Health > 5 && o.NetworkId != unit.NetworkId && !o.IsDead && o.Team == unit.Team && * o.LSIsValidTarget(caster.LSDistance(unit), false, missilePos.To3D2()) && * CheckUnitCollision(o) != CollisionObjectTypes.Null && * SkillshotData.CollisionObjects.Any(c => c == CheckUnitCollision(o)))) * { * var mp = prob.ServerPosition.LSTo2D().ProjectOn(missilePos, unit.ServerPosition.LSTo2D()); * if (mp.IsOnSegment && mp.SegmentPoint.LSDistance(unit.ServerPosition) < SkillshotData.Radius) * { * collision = true; * break; * } * }*/ var input = new PredictionInput { Collision = true, Aoe = false, Delay = missilePos.LSDistance(StartPosition) < 1 ? SkillshotData.Delay : 0, From = missilePos.To3D2(), Radius = SkillshotData.Radius, Range = missilePos.LSDistance(missilePosAfterT), Speed = SkillshotData.MissileSpeed, Type = SkillshotType.SkillshotLine, Unit = unit, CollisionObjects = GetColisionObj() }; var collisions = LeagueSharp.Common.Collision.GetCollision( new List <Vector3> { StartPosition.To3D2(), missilePosAfterT.To3D2() }, input); var projection = unit.ServerPosition.LSTo2D().ProjectOn(missilePos, missilePosAfterT); var pred = Prediction.GetPrediction(input); var poly = CombatHelper.GetPolyFromVector( missilePos.To3D2(), missilePosAfterT.To3D2(), SkillshotData.Radius); if (((projection.IsOnSegment && projection.SegmentPoint.LSDistance(unit.ServerPosition) < SkillshotData.Radius) || poly.IsInside(pred.UnitPosition)) && collisions.Count(c => c.NetworkId != unit.NetworkId) == 0) { return(true); } return(false); } if (!IsSafe(unit.ServerPosition.LSTo2D())) { var timeToExplode = SkillshotData.ExtraDuration + SkillshotData.Delay + (int)(1000 * StartPosition.LSDistance(EndPosition) / SkillshotData.MissileSpeed) - (System.Environment.TickCount - StartTick); if (timeToExplode <= time) { return(true); } } return(false); }
internal static PredictionOutput GetStandardPrediction(PredictionInput input) { var speed = input.Unit.MoveSpeed; if (input.Unit.Distance(input.From, true) < 200 * 200) { //input.Delay /= 2; speed /= 1.5f; } if (input.Unit.IsValid<Obj_AI_Hero>() && UnitTracker.PathCalc(input.Unit)) { return GetPositionOnPath(input, UnitTracker.GetPathWayCalc(input.Unit), speed); } else return GetPositionOnPath(input, input.Unit.GetWaypoints(), speed); }
public override void ExecuteLane() { if (Q.IsReady()) { var qCount = GetValue <StringList>("UseQ.Lane").SelectedIndex; if (qCount != 0) { var minions = MinionManager.GetMinions( ObjectManager.Player.ServerPosition, Q.Range, MinionTypes.All, MinionTeam.Enemy); foreach (var minion in minions.Where(x => x.Health <= Q.GetDamage(x))) { var killableMinionCount = 0; foreach ( var colminion in qGetCollisionMinions( ObjectManager.Player, ObjectManager.Player.ServerPosition.Extend(minion.ServerPosition, Q.Range))) { if (colminion.Health <= Q.GetDamage(colminion)) { if (GetValue <StringList>("UseQ.Mode.Lane").SelectedIndex == 1 && colminion.Distance(ObjectManager.Player) > Orbwalking.GetRealAutoAttackRange(null) + 65) { killableMinionCount++; } else { killableMinionCount++; } } else { break; } } if (killableMinionCount >= qCount) { if (!ObjectManager.Player.IsWindingUp && !ObjectManager.Player.IsDashing()) { Q.Cast(minion.ServerPosition); break; } } } } } if (E.IsReady()) { var minECount = GetValue <StringList>("UseE.Lane").SelectedIndex; if (minECount != 0) { var killableMinionCount = 0; foreach (var m in MinionManager.GetMinions(ObjectManager.Player.ServerPosition, E.Range) .Where(x => E.CanCast(x) && x.Health < E.GetDamage(x))) { if (m.SkinName.ToLower().Contains("siege") || m.SkinName.ToLower().Contains("super")) { killableMinionCount += 2; } else { killableMinionCount++; } } if (killableMinionCount >= minECount && E.IsReady() && ObjectManager.Player.ManaPercent > E.ManaCost * 2) { E.Cast(); } } } // Don't miss minion if (GetValue <bool>("UseE.LaneNon")) { var minions = MinionManager.GetMinions(ObjectManager.Player.ServerPosition, E.Range * 1); foreach (var n in minions) { var xH = HealthPrediction.GetHealthPrediction(n, (int)(ObjectManager.Player.AttackCastDelay * 1000), Game.Ping / 2 + 100); if (xH < 0) { if (n.Health < E.GetDamage(n) && E.CanCast(n)) { E.Cast(n); } else if (Q.IsReady() && Q.CanCast(n) && n.Distance(ObjectManager.Player.Position) < Orbwalking.GetRealAutoAttackRange(null) + 75) { xH = HealthPrediction.GetHealthPrediction(n, (int)(ObjectManager.Player.AttackCastDelay * 1000), (int)Q.Speed); if (xH < 0) { var input = new PredictionInput { Unit = ObjectManager.Player, Radius = Q.Width, Delay = Q.Delay, Speed = Q.Speed, }; input.CollisionObjects[0] = CollisionableObjects.Minions; int count = Collision.GetCollision(new List <Vector3> { n.Position }, input) .OrderBy(obj => obj.Distance(ObjectManager.Player)) .Count(obj => obj.NetworkId != n.NetworkId); if (count == 0) { Q.Cast(n); } } } } } } }
public static PredictionOutput GetPrediction(PredictionInput input) { return GetPrediction(input, true, true); }
internal static PredictionOutput GetPositionOnPath(PredictionInput input, List<Vector2> path, float speed = -1) { if (input.Unit.LSDistance(input.From, true) < 250 * 250) { //input.Delay /= 2; speed /= 1.5f; } speed = (Math.Abs(speed - (-1)) < float.Epsilon) ? input.Unit.MoveSpeed : speed; if (path.Count <= 1 || (input.Unit.Spellbook.IsAutoAttacking && !input.Unit.LSIsDashing())) { return new PredictionOutput { Input = input, UnitPosition = input.Unit.ServerPosition, CastPosition = input.Unit.ServerPosition, Hitchance = HitChance.High }; } var pLength = path.LSPathLength(); //Skillshots with only a delay if (pLength >= input.Delay * speed - input.RealRadius && Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) { var tDistance = input.Delay * speed - input.RealRadius; for (var i = 0; i < path.Count - 1; i++) { var a = path[i]; var b = path[i + 1]; var d = a.LSDistance(b); if (d >= tDistance) { var direction = (b - a).LSNormalized(); var cp = a + direction * tDistance; var p = a + direction * ((i == path.Count - 2) ? Math.Min(tDistance + input.RealRadius, d) : (tDistance + input.RealRadius)); return new PredictionOutput { Input = input, CastPosition = cp.To3D(), UnitPosition = p.To3D(), Hitchance = HitChance.High }; } tDistance -= d; } } //Skillshot with a delay and speed. if (pLength >= input.Delay * speed - input.RealRadius && Math.Abs(input.Speed - float.MaxValue) > float.Epsilon) { var d = input.Delay * speed - input.RealRadius; if (input.Type == SkillshotType.SkillshotLine || input.Type == SkillshotType.SkillshotCone) { if (input.From.LSDistance(input.Unit.ServerPosition, true) < 200 * 200) { d = input.Delay * speed; } } path = path.CutPath(d); var tT = 0f; for (var i = 0; i < path.Count - 1; i++) { var a = path[i]; var b = path[i + 1]; var tB = a.LSDistance(b) / speed; var direction = (b - a).LSNormalized(); a = a - speed * tT * direction; var sol = Geometry.VectorMovementCollision(a, b, speed, input.From.LSTo2D(), input.Speed, tT); var t = (float)sol[0]; var pos = (Vector2)sol[1]; if (pos.IsValid() && t >= tT && t <= tT + tB) { if (pos.LSDistance(b, true) < 20) break; var p = pos + input.RealRadius * direction; if (input.Type == SkillshotType.SkillshotLine && false) { var alpha = (input.From.LSTo2D() - p).LSAngleBetween(a - b); if (alpha > 30 && alpha < 180 - 30) { var beta = (float)Math.Asin(input.RealRadius / p.LSDistance(input.From)); var cp1 = input.From.LSTo2D() + (p - input.From.LSTo2D()).LSRotated(beta); var cp2 = input.From.LSTo2D() + (p - input.From.LSTo2D()).LSRotated(-beta); pos = cp1.LSDistance(pos, true) < cp2.LSDistance(pos, true) ? cp1 : cp2; } } return new PredictionOutput { Input = input, CastPosition = pos.To3D(), UnitPosition = p.To3D(), Hitchance = HitChance.High }; } tT += tB; } } var position = path.Last(); return new PredictionOutput { Input = input, CastPosition = position.To3D(), UnitPosition = position.To3D(), Hitchance = HitChance.Medium }; }
internal static PredictionOutput GetImmobilePrediction(PredictionInput input, double remainingImmobileT) { var timeToReachTargetPosition = input.Delay + input.Unit.Distance(input.From) / input.Speed; if (timeToReachTargetPosition <= remainingImmobileT + input.RealRadius / input.Unit.MoveSpeed) { return new PredictionOutput { CastPosition = input.Unit.ServerPosition, UnitPosition = input.Unit.Position, Hitchance = HitChance.Immobile }; } return new PredictionOutput { Input = input, CastPosition = input.Unit.ServerPosition, UnitPosition = input.Unit.ServerPosition, Hitchance = HitChance.High /*timeToReachTargetPosition - remainingImmobileT + input.RealRadius / input.Unit.MoveSpeed < 0.4d ? HitChance.High : HitChance.Medium*/ }; }
internal static PredictionOutput GetPrediction(PredictionInput input, bool ft, bool checkCollision) { PredictionOutput result = null; if (!input.Unit.LSIsValidTarget(float.MaxValue, false) || !input.Unit.IsVisible || !input.Unit.IsHPBarRendered) { return new PredictionOutput(); } if (ft) { //Increase the delay due to the latency and server tick: input.Delay += EloBuddy.Game.Ping / 2000f + 0.06f; if (input.Aoe) { return AoePrediction.GetPrediction(input); } } //Target too far away. if (Math.Abs(input.Range - float.MaxValue) > float.Epsilon && input.Unit.LSDistance(input.RangeCheckFrom, true) > Math.Pow(input.Range * 1.5, 2)) { return new PredictionOutput { Input = input }; } //Unit is dashing. if (input.Unit.LSIsDashing()) { result = GetDashingPrediction(input); } else { //Unit is immobile. var remainingImmobileT = UnitIsImmobileUntil(input.Unit); if (remainingImmobileT >= 0d) { result = GetImmobilePrediction(input, remainingImmobileT); } } //Normal prediction if (result == null) { result = GetPositionOnPath(input, input.Unit.GetWaypoints(), input.Unit.MoveSpeed); } //Check if the unit position is in range if (Math.Abs(input.Range - float.MaxValue) > float.Epsilon) { if (result.Hitchance >= HitChance.High && input.RangeCheckFrom.LSDistance(input.Unit.ServerPosition, true) > Math.Pow(input.Range + input.RealRadius * 3 / 4, 2)) { result.Hitchance = HitChance.Medium; } if (input.RangeCheckFrom.LSDistance(result.UnitPosition, true) > Math.Pow(input.Range + (input.Type == SkillshotType.SkillshotCircle ? input.RealRadius : 0), 2)) { result.Hitchance = HitChance.OutOfRange; } /* This does not need to be handled for the updated predictions, but left as a reference.*/ if (input.RangeCheckFrom.LSDistance(result.CastPosition, true) > Math.Pow(input.Range, 2)) { if (result.Hitchance != HitChance.OutOfRange) { result.CastPosition = input.RangeCheckFrom + input.Range * (result.UnitPosition - input.RangeCheckFrom).LSTo2D().LSNormalized().To3D(); } else { result.Hitchance = HitChance.OutOfRange; } } } //Check for collision if (checkCollision && input.Collision && result.Hitchance > HitChance.Impossible) { var positions = new List<Vector3> { result.CastPosition }; var originalUnit = input.Unit; if (Collision.GetCollision(positions, input)) result.Hitchance = HitChance.Collision; } //Set hit chance if (result.Hitchance == HitChance.High || result.Hitchance == HitChance.VeryHigh) { result = WayPointAnalysis(result, input); //.debug(input.Unit.BaseSkinName + result.Hitchance); } if (result.Hitchance >= HitChance.VeryHigh && input.Unit is EloBuddy.AIHeroClient && input.Radius > 1) { var lastWaypiont = input.Unit.GetWaypoints().Last().To3D(); var distanceUnitToWaypoint = lastWaypiont.LSDistance(input.Unit.ServerPosition); var distanceFromToUnit = input.From.LSDistance(input.Unit.ServerPosition); var distanceFromToWaypoint = lastWaypiont.LSDistance(input.From); float speedDelay = distanceFromToUnit / input.Speed; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) speedDelay = 0; float totalDelay = speedDelay + input.Delay; float moveArea = input.Unit.MoveSpeed * totalDelay; float fixRange = moveArea * 0.35f; float pathMinLen = 800 + moveArea; OktwCommon.debug(input.Radius + " RES Ways: " + input.Unit.GetWaypoints().Count + " W " + input.Unit.Spellbook.IsAutoAttacking + " D " + distanceUnitToWaypoint + " T " + UnitTracker.GetLastNewPathTime(input.Unit) + " " + result.Hitchance); } return result; }
internal static PredictionOutput GetPrediction(PredictionInput input, bool ft, bool checkCollision) { PredictionOutput result = null; if (!input.Unit.IsValidTarget(float.MaxValue, false)) { return new PredictionOutput(); } if (ft) { //Increase the delay due to the latency and server tick: input.Delay += Game.Ping / 2000f + 0.07f; if (input.Aoe) { return AoePrediction.GetPrediction(input); } } //Target too far away. if (Math.Abs(input.Range - float.MaxValue) > float.Epsilon && input.Unit.Distance(input.RangeCheckFrom, true) > Math.Pow(input.Range * 1.5, 2)) { return new PredictionOutput { Input = input }; } //Unit is dashing. if (input.Unit.IsDashing()) { result = GetDashingPrediction(input); } else { //Unit is immobile. var remainingImmobileT = UnitIsImmobileUntil(input.Unit); if (remainingImmobileT >= 0d) { result = GetImmobilePrediction(input, remainingImmobileT); } } //Normal prediction if (result == null) { result = GetStandardPrediction(input); } //Check if the unit position is in range if (Math.Abs(input.Range - float.MaxValue) > float.Epsilon) { if (result.Hitchance >= HitChance.High && input.RangeCheckFrom.Distance(input.Unit.Position, true) > Math.Pow(input.Range + input.RealRadius * 3 / 4, 2)) { result.Hitchance = HitChance.Medium; } if (input.RangeCheckFrom.Distance(result.UnitPosition, true) > Math.Pow(input.Range + (input.Type == SkillshotType.SkillshotCircle ? input.RealRadius : 0), 2)) { result.Hitchance = HitChance.OutOfRange; } /* This does not need to be handled for the updated predictions, but left as a reference.*/ if (input.RangeCheckFrom.Distance(result.CastPosition, true) > Math.Pow(input.Range, 2)) { if (result.Hitchance != HitChance.OutOfRange) { result.CastPosition = input.RangeCheckFrom + input.Range * (result.UnitPosition - input.RangeCheckFrom).To2D().Normalized().To3D(); } else { result.Hitchance = HitChance.OutOfRange; } } } if (result.Hitchance > HitChance.Medium) WayPointAnalysis(result, input); //Check for collision if (checkCollision && input.Collision && result.Hitchance > HitChance.Impossible) { var positions = new List<Vector3> { result.CastPosition }; var originalUnit = input.Unit; result.CollisionObjects = Collision.GetCollision(positions, input); result.CollisionObjects.RemoveAll(x => x.NetworkId == originalUnit.NetworkId); result.Hitchance = result.CollisionObjects.Count > 0 ? HitChance.Collision : result.Hitchance; } return result; }
public static bool GetCollision(List<Vector3> positions, PredictionInput input) { foreach (var position in positions) { foreach (var objectType in input.CollisionObjects) { switch (objectType) { case CollisionableObject.Minions: foreach (var minion in Cache.GetMinions(input.From, Math.Min(input.Range + input.Radius + 100, 2000))) { var distanceFromToUnit = minion.ServerPosition.LSDistance(input.From); if (distanceFromToUnit < 10 + minion.BoundingRadius) { if (MinionIsDead(input, minion, distanceFromToUnit)) continue; else return true; } else if (minion.ServerPosition.LSDistance(position) < minion.BoundingRadius) { if (MinionIsDead(input, minion, distanceFromToUnit)) continue; else return true; } else { var minionPos = minion.ServerPosition; int bonusRadius = 15; if (minion.IsMoving) { var predInput2 = new PredictionInput { Collision = false, Speed = input.Speed, Delay = input.Delay, Range = input.Range, From = input.From, Radius = input.Radius, Unit = minion, Type = input.Type }; minionPos = Prediction.GetPrediction(predInput2).CastPosition; bonusRadius = 50 + (int)input.Radius; } if (minionPos.LSTo2D().LSDistance(input.From.LSTo2D(), position.LSTo2D(), true, true) <= Math.Pow((input.Radius + bonusRadius + minion.BoundingRadius), 2)) { if (MinionIsDead(input, minion, distanceFromToUnit)) continue; else return true; } } } break; case CollisionableObject.Heroes: foreach (var hero in HeroManager.Enemies.FindAll(hero => hero.LSIsValidTarget(Math.Min(input.Range + input.Radius + 100, 2000), true, input.RangeCheckFrom) && hero.IsVisible && hero.IsHPBarRendered) ) { input.Unit = hero; var prediction = Prediction.GetPrediction(input, false, false); if ( prediction.UnitPosition.LSTo2D() .LSDistance(input.From.LSTo2D(), position.LSTo2D(), true, true) <= Math.Pow((input.Radius + 50 + hero.BoundingRadius), 2)) { return true; } } break; case CollisionableObject.Walls: var step = position.LSDistance(input.From) / 20; for (var i = 0; i < 20; i++) { var p = input.From.LSTo2D().LSExtend(position.LSTo2D(), step * i); if (EloBuddy.NavMesh.GetCollisionFlags(p.X, p.Y).HasFlag(EloBuddy.CollisionFlags.Wall)) { return true; } } break; default: // do the default action break; } } } return false; }
private static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input) { var totalDelay = input.From.Distance(input.Unit.ServerPosition) / input.Speed + input.Delay; var fixRange = (input.Unit.MoveSpeed * totalDelay) / 2; var LastWaypiont = input.Unit.GetWaypoints().Last().To3D(); if (input.Type == SkillshotType.SkillshotCircle) { fixRange -= input.Radius / 2; } if (input.Unit.Path.Count() == 0 && input.Unit.Position == input.Unit.ServerPosition && !input.Unit.IsWindingUp) { if (input.From.Distance(input.Unit.ServerPosition) > input.Range - fixRange) result.Hitchance = HitChance.High; else result.Hitchance = HitChance.VeryHigh; return result; } else if (LastWaypiont.Distance(input.From) <= input.Unit.Distance(input.From)) { if (input.From.Distance(input.Unit.ServerPosition) > input.Range - fixRange) { result.Hitchance = HitChance.High; return result; } } if (input.Unit.HasBuffOfType(BuffType.Slow) || input.Unit.Distance(input.From) < 300 || LastWaypiont.Distance(input.From) < 250) { result.Hitchance = HitChance.VeryHigh; return result; } if (LastWaypiont.Distance(input.Unit.ServerPosition) > 800) { result.Hitchance = HitChance.VeryHigh; } if (input.Type == SkillshotType.SkillshotLine) { if (input.Unit.Path.Count() > 0) { if (GetAngle(input.From, input.Unit) < 36) { result.Hitchance = HitChance.VeryHigh; return result; } else result.Hitchance = HitChance.High; } } else if (input.Type == SkillshotType.SkillshotCircle) { if (totalDelay < 1.2) { if (totalDelay < 0.7 && OnProcessSpellDetection.GetLastAutoAttackTime(input.Unit) < 0.1d) result.Hitchance = HitChance.VeryHigh; if (PathTracker.GetCurrentPath(input.Unit).Time < 0.1d) result.Hitchance = HitChance.VeryHigh; } } float BackToFront = ((input.Unit.MoveSpeed * input.Delay) + (input.From.Distance(input.Unit.ServerPosition) / input.Speed)); if (input.Unit.Path.Count() > 0) { if (input.Unit.Distance(LastWaypiont) < BackToFront) { result.Hitchance = HitChance.Medium; return result; } } if (totalDelay > 0.8 && input.Unit.IsWindingUp) { result.Hitchance = HitChance.Medium; } if (input.Unit.Path.Count() > 1 && input.Type == SkillshotType.SkillshotLine) { result.Hitchance = HitChance.Medium; } return result; }
internal static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input) { if (!(input.Unit is EloBuddy.AIHeroClient) || input.Radius == 1) { result.Hitchance = HitChance.VeryHigh; return result; } OktwCommon.debug("WAIT....."); // CAN'T MOVE SPELLS /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetSpecialSpellEndTime(input.Unit) > 100 || input.Unit.HasBuff("Recall") || (UnitTracker.GetLastStopMoveTime(input.Unit) < 100 && input.Unit.IsRooted)) { OktwCommon.debug("CAN'T MOVE SPELLS"); result.Hitchance = HitChance.VeryHigh; result.CastPosition = input.Unit.ServerPosition; return result; } // PREPARE MATH /////////////////////////////////////////////////////////////////////////////////// var path = input.Unit.GetWaypoints(); var lastWaypiont = path.Last().To3D(); var distanceUnitToWaypoint = lastWaypiont.LSDistance(input.Unit.ServerPosition); var distanceFromToUnit = input.From.LSDistance(input.Unit.ServerPosition); var distanceFromToWaypoint = lastWaypiont.LSDistance(input.From); Vector2 pos1 = lastWaypiont.LSTo2D() - input.Unit.Position.LSTo2D(); Vector2 pos2 = input.From.LSTo2D() - input.Unit.Position.LSTo2D(); var getAngle = pos1.LSAngleBetween(pos2); float speedDelay = distanceFromToUnit / input.Speed; if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) speedDelay = 0; float totalDelay = speedDelay + input.Delay; float moveArea = input.Unit.MoveSpeed * totalDelay; float fixRange = moveArea * 0.35f; float pathMinLen = 1000; if (input.Type == SkillshotType.SkillshotCircle) { fixRange -= input.Radius / 2; } // FIX RANGE /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToWaypoint <= distanceFromToUnit && distanceFromToUnit > input.Range - fixRange) { result.Hitchance = HitChance.Medium; return result; } if (distanceUnitToWaypoint > 0) { // RUN IN LANE DETECTION /////////////////////////////////////////////////////////////////////////////////// if (getAngle < 20 || getAngle > 160 || (getAngle > 130 && distanceUnitToWaypoint > 400)) { OktwCommon.debug("PRED: ANGLE " + getAngle); result.Hitchance = HitChance.VeryHigh; return result; } // WALL LOGIC /////////////////////////////////////////////////////////////////////////////////// var points = OktwCommon.CirclePoints(15, 350, input.Unit.ServerPosition).Where(x => x.LSIsWall()); if (points.Count() > 2) { var runOutWall = true; foreach (var point in points) { if (input.Unit.ServerPosition.LSDistance(point) > lastWaypiont.LSDistance(point)) { runOutWall = false; } } if (runOutWall) { OktwCommon.debug("PRED: RUN OUT WALL"); result.Hitchance = HitChance.VeryHigh; return result; } } } // SHORT CLICK DETECTION /////////////////////////////////////////////////////////////////////////////////// if (distanceUnitToWaypoint > 0 && distanceUnitToWaypoint < 100) { OktwCommon.debug("PRED: SHORT CLICK DETECTION"); result.Hitchance = HitChance.Medium; return result; } if (input.Unit.GetWaypoints().Count == 1) { if (UnitTracker.GetLastAutoAttackTime(input.Unit) < 0.1d && totalDelay < 0.7) { OktwCommon.debug("PRED: AA try"); result.Hitchance = HitChance.VeryHigh; return result; } if (input.Unit.Spellbook.IsAutoAttacking) { result.Hitchance = HitChance.High; return result; } else if (UnitTracker.GetLastStopMoveTime(input.Unit) < 800) { //OktwCommon.debug("PRED: STOP HIGH"); result.Hitchance = HitChance.High; return result; } else { OktwCommon.debug("PRED: STOP LOGIC"); result.Hitchance = HitChance.VeryHigh; return result; } } // SPAM POSITION /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.SpamSamePlace(input.Unit)) { result.Hitchance = HitChance.VeryHigh; return result; } // SPECIAL CASES /////////////////////////////////////////////////////////////////////////////////// if (distanceFromToUnit < 250) { OktwCommon.debug("PRED: SPECIAL CASES NEAR"); result.Hitchance = HitChance.VeryHigh; return result; } else if (input.Unit.MoveSpeed < 250) { OktwCommon.debug("PRED: SPECIAL CASES SLOW"); result.Hitchance = HitChance.VeryHigh; return result; } else if (distanceFromToWaypoint < 250) { OktwCommon.debug("PRED: SPECIAL CASES ON WAY"); result.Hitchance = HitChance.VeryHigh; return result; } // LONG TIME /////////////////////////////////////////////////////////////////////////////////// if (UnitTracker.GetLastNewPathTime(input.Unit) > 250) { OktwCommon.debug("PRED: LONG TIME"); result.Hitchance = HitChance.VeryHigh; return result; } // LONG CLICK DETECTION /////////////////////////////////////////////////////////////////////////////////// if (distanceUnitToWaypoint > pathMinLen) { OktwCommon.debug("PRED: LONG CLICK DETECTION"); result.Hitchance = HitChance.VeryHigh; return result; } // LOW HP DETECTION /////////////////////////////////////////////////////////////////////////////////// if (input.Unit.HealthPercent < 20 || EloBuddy.ObjectManager.Player.HealthPercent < 20) { result.Hitchance = HitChance.VeryHigh; OktwCommon.debug("Low hp"); return result; } // CIRCLE NEW PATH /////////////////////////////////////////////////////////////////////////////////// if (input.Type == SkillshotType.SkillshotCircle) { if (UnitTracker.GetLastNewPathTime(input.Unit) < 100 && distanceUnitToWaypoint > fixRange) { OktwCommon.debug("PRED: CIRCLE NEW PATH"); result.Hitchance = HitChance.VeryHigh; return result; } } //Program.debug("PRED: NO DETECTION"); return result; }
internal static List<PossibleTarget> GetPossibleTargets(PredictionInput input) { var result = new List<PossibleTarget>(); var originalUnit = input.Unit; foreach (var enemy in HeroManager.Enemies.FindAll( h => h.NetworkId != originalUnit.NetworkId && h.IsValidTarget((input.Range + 200 + input.RealRadius), true, input.RangeCheckFrom))) { input.Unit = enemy; var prediction = Prediction.GetPrediction(input, false, false); if (prediction.Hitchance >= HitChance.High) { result.Add(new PossibleTarget { Position = prediction.UnitPosition.To2D(), Unit = enemy }); } } return result; }
private Tuple <List <Obj_AI_Hero>, Vector3> GetMaxRHits(HitChance hitChance, Vector3 fromCheck = default(Vector3)) { if (fromCheck.Equals(default(Vector3))) { fromCheck = ObjectManager.Player.Position; } var input = new PredictionInput { Collision = true, CollisionObjects = new[] { CollisionableObjects.YasuoWall }, From = fromCheck, RangeCheckFrom = fromCheck, Type = R.Type, Radius = R.Width, Delay = R.Delay, Speed = R.Speed, Range = R.Range, Aoe = true }; var castPosition = Vector3.Zero; var totalHits = new List <Obj_AI_Hero>(); try { var positions = new List <CPrediction.Position>(); foreach (var t in GameObjects.EnemyHeroes) { if (t.IsValidTarget(R.Range * 1.5f, true, fromCheck)) { input.Unit = t; var prediction = Prediction.GetPrediction(input); if (prediction.Hitchance >= hitChance) { positions.Add(new CPrediction.Position(t, prediction.UnitPosition)); } } } var circle = new Geometry.Polygon.Circle(fromCheck, R.Range).Points; foreach (var point in circle) { var hits = new List <Obj_AI_Hero>(); foreach (var position in positions) { R.UpdateSourcePosition(fromCheck, fromCheck); if (R.WillHit(position.UnitPosition, point.To3D())) { hits.Add(position.Hero); } R.UpdateSourcePosition(); } if (hits.Count > totalHits.Count) { castPosition = point.To3D(); totalHits = hits; } } } catch (Exception ex) { Global.Logger.AddItem(new LogItem(ex)); } return(new Tuple <List <Obj_AI_Hero>, Vector3>(totalHits, castPosition)); }
/// <summary> /// Returns the list of the units that the skillshot will hit before reaching the set positions. /// </summary> public static List<Obj_AI_Base> GetCollision(List<Vector3> positions, PredictionInput input) { var result = new List<Obj_AI_Base>(); foreach (var position in positions) { foreach (var objectType in input.CollisionObjects) { switch (objectType) { case CollisionableObjects.Minions: foreach (var minion in ObjectManager.Get<Obj_AI_Minion>().Where(minion => minion.IsValidTarget(Math.Min(input.Range + input.Radius + 100, 2000), true, input.From))) { input.Unit = minion; if (minion.Path.Count() > 0) { var minionPrediction = Prediction.GetPrediction(input, true, false); if (minionPrediction.CastPosition.To2D().Distance(input.From.To2D(), position.To2D(), true, true) <= Math.Pow((input.Radius + 20 + minion.Path.Count() * minion.BoundingRadius), 2)) { result.Add(minion); } } else { if (minion.ServerPosition.To2D() .Distance(input.From.To2D(), position.To2D(), true, true) <= Math.Pow((input.Radius + 15 + minion.BoundingRadius), 2)) { result.Add(minion); } } } break; case CollisionableObjects.Heroes: foreach (var hero in HeroManager.Enemies.FindAll( hero => hero.IsValidTarget( Math.Min(input.Range + input.Radius + 100, 2000), true, input.RangeCheckFrom)) ) { input.Unit = hero; var prediction = Prediction.GetPrediction(input, false, false); if ( prediction.UnitPosition.To2D() .Distance(input.From.To2D(), position.To2D(), true, true) <= Math.Pow((input.Radius + 50 + hero.BoundingRadius), 2)) { result.Add(hero); } } break; case CollisionableObjects.Walls: var step = position.Distance(input.From) / 20; for (var i = 0; i < 20; i++) { var p = input.From.To2D().Extend(position.To2D(), step * i); if (NavMesh.GetCollisionFlags(p.X, p.Y).HasFlag(CollisionFlags.Wall)) { result.Add(ObjectManager.Player); } } break; case CollisionableObjects.YasuoWall: if (Utils.TickCount - _wallCastT > 4000) { break; } GameObject wall = null; foreach (var gameObject in ObjectManager.Get<GameObject>() .Where( gameObject => gameObject.IsValid && Regex.IsMatch( gameObject.Name, "_w_windwall_enemy_0.\\.troy", RegexOptions.IgnoreCase)) ) { wall = gameObject; } if (wall == null) { break; } var level = wall.Name.Substring(wall.Name.Length - 6, 1); var wallWidth = (300 + 50 * Convert.ToInt32(level)); var wallDirection = (wall.Position.To2D() - _yasuoWallCastedPos).Normalized().Perpendicular(); var wallStart = wall.Position.To2D() + wallWidth / 2f * wallDirection; var wallEnd = wallStart - wallWidth * wallDirection; if (wallStart.Intersection(wallEnd, position.To2D(), input.From.To2D()).Intersects) { var t = Utils.TickCount + (wallStart.Intersection(wallEnd, position.To2D(), input.From.To2D()) .Point.Distance(input.From) / input.Speed + input.Delay) * 1000; if (t < _wallCastT + 4000) { result.Add(ObjectManager.Player); } } break; } } } return result.Distinct().ToList(); }
static Vector3 GetPositionOnPath(PredictionInput input, List <Vector2> path, float speed = -1) { speed = (Math.Abs(speed - (-1)) < float.Epsilon) ? Prediction.SpeedFromVelocity(input.Unit) : speed; var pLength = path.PathLength(); if (pLength < 5) { return(input.Unit.ServerPosition); } var realRadius = input.Radius + input.Unit.BoundingRadius; //Skillshots with only a delay var tDistance = input.Delay * speed - (input.Radius * 0.75f); if (pLength >= tDistance && Math.Abs(input.Speed - float.MaxValue) < float.Epsilon) { for (var i = 0; i < path.Count - 1; i++) { var a = path[i]; var b = path[i + 1]; var d = a.Distance(b); if (d >= tDistance) { var direction = (b - a).Normalized(); var cp = a + direction * tDistance; return(cp.To3D()); } tDistance -= d; } } //Skillshot with a delay and speed. if (pLength >= tDistance && Math.Abs(input.Speed - float.MaxValue) > float.Epsilon) { var d = tDistance; if (input.Type == SkillshotType.SkillshotLine || input.Type == SkillshotType.SkillshotCone) { if (input.From.Distance(input.Unit.ServerPosition, true) < 200 * 200) { d = input.Delay * speed; } } path = path.CutPath(d); var tT = 0f; for (var i = 0; i < path.Count - 1; i++) { var a = path[i]; var b = path[i + 1]; var tB = a.Distance(b) / speed; var direction = (b - a).Normalized(); a = a - speed * tT * direction; var sol = Geometry.VectorMovementCollision(a, b, speed, input.From.To2D(), input.Speed, tT); var t = (float)sol[0]; var pos = (Vector2)sol[1]; if (pos.IsValid() && t >= tT && t <= tT + tB) { if (pos.Distance(b, true) < 20) { break; } return(pos.To3D()); } tT += tB; } } var position = path.Last(); return(position.To3D()); }
public static PredictionOutput GetPrediction(PredictionInput input) { MinMaxValues values; if (!MIN_MAX.TryGetValue(input.Slot, out values)) { values = new MinMaxValues(); MIN_MAX[input.Slot] = values; } var positionOnPath = GetPositionOnPath(input, input.Unit.GetWaypoints(), Prediction.SpeedFromVelocity(input.Unit)); var pathInput = new AIPredictionInput { input = input, CastPosition = positionOnPath }; // var pathValues = pathInput.GetValues(); // Console.WriteLine("Inputs: " + pathValues.Length); // // for (var i = 0; i < pathValues.Length; i++) // { // Console.Write(pathValues[i] + ", "); // } // // Console.WriteLine(); var positionInput = new AIPredictionInput { input = input, CastPosition = input.Unit.ServerPosition }; var outputPath = (input.Type == SkillshotType.SkillshotLine ? LinePathModel : CirclePathModel).Predict( pathInput.GetValues()); // var outputPosition = // (input.Type == SkillshotType.SkillshotLine ? LinePositionModel : CirclePositionModel).Predict( // positionInput.GetValues()); float hitchance; Vector3 castPosition; // if (outputPosition[0] > outputPath[0]) // { // castPosition = input.Unit.ServerPosition; // hitchance = outputPosition[0]; // } // else // { castPosition = positionOnPath; hitchance = outputPath[0]; // } var normalized = values.Normalized(hitchance); var output = new PredictionOutput { HitchanceFloat = normalized, CastPosition = castPosition }; Console.WriteLine(input.Slot + " == " + normalized + " ! " + outputPath[0] + " || " + pathInput.GetDelay()); if (input.Collision) { var maxCollisions = 0; if (HeroManager.Player.ChampionName == "Lux") { maxCollisions = 1; } var positions = new List <Vector3> { output.CastPosition }; output.CollisionObjects = Collision.GetCollision(positions, input); output.CollisionObjects.RemoveAll(x => x.NetworkId == input.Unit.NetworkId); if (output.CollisionObjects.Count > maxCollisions) { output.HitchanceFloat = 0.0f; output.Hitchance = HitChance.Collision; } } return(output); }
public override async Task ExecuteAsync(CancellationToken token) { if (!await this.ShouldExecute(token)) { return; } this.MaxTargetRange = Math.Max(this.MaxTargetRange, Snapfire.Kiss.CastRange * 1.1f); if ((this.CurrentTarget == null) || !this.CurrentTarget.IsVisible) { this.Snapfire.Context.Orbwalker.Active.OrbwalkTo(null); return; } if (this.CurrentTarget.IsIllusion) { this.OrbwalkToTarget(); return; } try { if (!Ensage.SDK.Extensions.UnitExtensions.HasModifier(this.Owner, "modifier_snapfire_mortimer_kisses")) { var linkens = UnitExtensions.IsLinkensProtected(this.CurrentTarget); await BreakLinken(token); var veil = this.Snapfire.VeilOfDiscord; if (veil != null && veil.CanBeCasted && veil.CanHit(CurrentTarget)) { veil.UseAbility(CurrentTarget.Position); await Task.Delay(veil.GetCastDelay(), token); } var hex = this.Snapfire.Sheepstick; if (hex != null && hex.CanBeCasted && hex.CanHit(CurrentTarget) && !linkens && this.Snapfire.HexHeroes.Value.IsEnabled(CurrentTarget.Name)) { hex.UseAbility(CurrentTarget); await Task.Delay(hex.GetCastDelay(this.CurrentTarget), token); } var atos = this.Snapfire.RodOfAtos; if (atos != null && atos.CanBeCasted && atos.CanHit(CurrentTarget) && !linkens) { atos.UseAbility(CurrentTarget); await Task.Delay(atos.GetCastDelay(CurrentTarget), token); } var bloodthorn = this.Snapfire.BloodThorn; if (bloodthorn != null && bloodthorn.CanBeCasted && bloodthorn.CanHit(CurrentTarget) && !linkens && this.Snapfire.OrchidHeroes.Value.IsEnabled(this.CurrentTarget.Name)) { bloodthorn.UseAbility(CurrentTarget); await Task.Delay(bloodthorn.GetCastDelay(CurrentTarget), token); } var orchid = this.Snapfire.Orchid; if (orchid != null && orchid.CanBeCasted && orchid.CanHit(CurrentTarget) && !linkens && this.Snapfire.OrchidHeroes.Value.IsEnabled(this.CurrentTarget.Name)) { orchid.UseAbility(CurrentTarget); await Task.Delay(orchid.GetCastDelay(CurrentTarget), token); } var scatterblast = this.Snapfire.Scatterblast; if (scatterblast.CanBeCasted && EntityExtensions.Distance2D(this.Owner, this.CurrentTarget) <= scatterblast.CastRange) { var input = scatterblast.GetPredictionInput(this.CurrentTarget); var output = this.Snapfire.Context.Prediction.GetPrediction(input); if (output.HitChance >= HitChance.Medium) { scatterblast.UseAbility(output.CastPosition); await Task.Delay(scatterblast.GetCastDelay(output.CastPosition), token); } } var cookie = this.Snapfire.Cookie; if (cookie.CanBeCasted) { var allies = EntityManager <Unit> .Entities.Where(x => x.IsValid && cookie.CanHit(x) && x.Team == this.Owner.Team && x.Distance2D(this.Owner) <= cookie.CastRange && x.Distance2D(this.CurrentTarget) <= 600 && x.Distance2D(this.CurrentTarget) >= 150).OrderBy(x => x.Distance2D(this.Owner)).ToList(); foreach (var ally in allies) { if (Ensage.Common.Extensions.UnitExtensions.InFront(ally, 450).Distance2D(this.CurrentTarget) >= 200) { continue; } var input = new PredictionInput(this.Owner, ally, ally == this.Owner ? 0.3f : this.Owner.Distance2D(ally) / 1000, 1000, 450, 350); var output = this.Snapfire.Context.Prediction.GetPrediction(input); if (output.HitChance >= HitChance.Medium) { if (cookie.UseAbility(ally)) { await Task.Delay(cookie.GetCastDelay(ally), token); break; } } } } var E = this.Snapfire.Shredder; if (E.CanBeCasted && this.CurrentTarget.Distance2D(this.Owner) <= (this.Owner.AttackRange + this.Snapfire.Shredder.Ability.GetAbilitySpecialData("attack_range_bonus")) - 150) { if (E.UseAbility()) { await Task.Delay(E.GetCastDelay(), token); } } var nullifier = this.Snapfire.Nullifier; if (nullifier != null && nullifier.CanBeCasted && nullifier.CanHit(CurrentTarget) && !linkens && this.Snapfire.NullifierHeroes.Value.IsEnabled(CurrentTarget.Name)) { nullifier.UseAbility(CurrentTarget); await Task.Delay(nullifier.GetCastDelay(), token); } var solarCrest = this.Snapfire.SolarCrest; if (solarCrest != null && solarCrest.CanBeCasted && solarCrest.CanHit(CurrentTarget) && !linkens) { nullifier.UseAbility(CurrentTarget); await Task.Delay(nullifier.GetCastDelay(), token); } //if (Ensage.SDK.Extensions.UnitExtensions.HasModifier(this.Owner, "modifier_snapfire_lil_shredder_buff")) //{ // this.Snapfire.Context.Orbwalker.Attack(this.CurrentTarget); // return; //} } } catch (TaskCanceledException) { // ignore } catch (Exception e) { Log.Debug($"{e}"); } //if (!Ensage.SDK.Extensions.UnitExtensions.HasModifier(this.Owner, "modifier_snapfire_lil_shredder_buff")) //{ this.OrbwalkToTarget(); //} }