public static List <Vector2> GetMinionsPredictedPositions(List <Obj_AI_Base> minions, float delay, float width, float speed, Vector3 from, float range, bool collision, SkillshotType stype, Vector3 rangeCheckFrom = new Vector3()) { from = from.To2D2().IsValid() ? from : ObjectManager.Player.ServerPosition; return((from minion in minions select Prediction2.GetPrediction( new PredictionInput { Unit = minion, Delay = delay, Radius = width, Speed = speed, From = @from, Range = range, Collision = collision, Type = stype, RangeCheckFrom = rangeCheckFrom }) into pos where pos.Hitchance >= HitChance.High select pos.UnitPosition.To2D2()).ToList()); }
public static PredictionOutput GetPrediction(PredictionInput input) { var mainTargetPrediction = Prediction2.GetPrediction(input, false, true); var posibleTargets = new List <PossibleTarget> { new PossibleTarget { Position = mainTargetPrediction.UnitPosition.To2D2(), 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.To2D2()) < input.Range * input.Range) { return(new PredictionOutput { AoeTargetsHit = posibleTargets.Select(h => (AIHeroClient)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); }
public PredictionOutput GetPrediction(Obj_AI_Base unit, bool aoe = false, float overrideRange = -1, CollisionableObjects[] collisionable = null) { return (Prediction2.GetPrediction( new PredictionInput { Unit = unit, Delay = Delay, Radius = Width, Speed = Speed, From = From, Range = (overrideRange > 0) ? overrideRange : Range, Collision = Collision, Type = Type, RangeCheckFrom = RangeCheckFrom, Aoe = aoe, CollisionObjects = collisionable ?? new[] { CollisionableObjects.Heroes, CollisionableObjects.Minions } })); }
internal static List <PossibleTarget> GetPossibleTargets(PredictionInput input) { var result = new List <PossibleTarget>(); var originalUnit = input.Unit; foreach (var enemy in EntityManager.Heroes.Enemies.FindAll( h => h.NetworkId != originalUnit.NetworkId && h.IsValidTarget((input.Range + 200 + input.RealRadius), true, input.RangeCheckFrom))) { input.Unit = enemy; var prediction = Prediction2.GetPrediction(input, false, false); if (prediction.Hitchance >= HitChance.High) { result.Add(new PossibleTarget { Position = prediction.UnitPosition.To2D2(), Unit = enemy }); } } return(result); }
/// <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.RangeCheckFrom))) { input.Unit = minion; var minionPrediction = Prediction2.GetPrediction(input, false, false); if ( minionPrediction.UnitPosition.To2D2() .Distance(input.From.To2D2(), position.To2D2(), true, true) <= Math.Pow((input.Radius + 15 + minion.BoundingRadius), 2)) { result.Add(minion); } } break; case CollisionableObjects.Heroes: foreach (var hero in EntityManager.Heroes.Enemies.FindAll( hero => hero.IsValidTarget( Math.Min(input.Range + input.Radius + 100, 2000), true, input.RangeCheckFrom)) ) { input.Unit = hero; var prediction = Prediction2.GetPrediction(input, false, false); if ( prediction.UnitPosition.To2D2() .Distance(input.From.To2D2(), position.To2D2(), true, true) <= Math.Pow((input.Radius + 50 + hero.BoundingRadius), 2)) { result.Add(hero); } } break; case CollisionableObjects.Allies: foreach (var hero in EntityManager.Heroes.Allies.FindAll( hero => Vector3.Distance(ObjectManager.Player.ServerPosition, hero.ServerPosition) <= Math.Min(input.Range + input.Radius + 100, 2000)) ) { input.Unit = hero; var prediction = Prediction2.GetPrediction(input, false, false); if ( prediction.UnitPosition.To2D2() .Distance(input.From.To2D2(), position.To2D2(), 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.To2D2().Extend2(position.To2D2(), 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.To2D2() - _yasuoWallCastedPos).Normalized2().Perpendicular2(); var wallStart = wall.Position.To2D2() + wallWidth / 2f * wallDirection; var wallEnd = wallStart - wallWidth * wallDirection; if (wallStart.Intersection2(wallEnd, position.To2D2(), input.From.To2D2()).Intersects) { var t = Utils.TickCount + (wallStart.Intersection2(wallEnd, position.To2D2(), input.From.To2D2()) .Point.Distance8(input.From) / input.Speed + input.Delay) * 1000; if (t < _wallCastT + 4000) { result.Add(ObjectManager.Player); } } break; } } } return(result.Distinct().ToList()); }
public static PredictionOutput GetPrediction(PredictionInput input) { var mainTargetPrediction = Prediction2.GetPrediction(input, false, true); var posibleTargets = new List <PossibleTarget> { new PossibleTarget { Position = mainTargetPrediction.UnitPosition.To2D2(), 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.To2D2(), 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.To2D2(), candidate, (input.Radius + input.Unit.BoundingRadius / 3 - 10), new List <Vector2> { posibleTargets[0].Position }).Count() == 1) { var hits = GetHits(input.From.To2D2(), 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.To2D2(); var endP = bestCandidate; var proj1 = positionsList[i].ProjectOn2(startP, endP); var proj2 = positionsList[j].ProjectOn2(startP, endP); var dist = Vector2.DistanceSquared(bestCandidateHitPoints[i], proj1.LinePoint) + Vector2.DistanceSquared(bestCandidateHitPoints[j], proj2.LinePoint); if (dist >= maxDistance && (proj1.LinePoint - positionsList[i]).AngleBetween2( 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); }
public static PredictionOutput GetPrediction(PredictionInput input) { var mainTargetPrediction = Prediction2.GetPrediction(input, false, true); var posibleTargets = new List <PossibleTarget> { new PossibleTarget { Position = mainTargetPrediction.UnitPosition.To2D2(), 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.To2D2(); } 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; } } if (bestCandidateHits > 1 && input.From.To2D2().Distance7(bestCandidate, true) > 50 * 50) { return(new PredictionOutput { Hitchance = mainTargetPrediction.Hitchance, _aoeTargetsHitCount = bestCandidateHits, UnitPosition = mainTargetPrediction.UnitPosition, CastPosition = bestCandidate.To3D(), Input = input }); } } return(mainTargetPrediction); }