public static bool AnalyzeQ(PredictionInput input, PredictionOutput output)
 {
     var posList = new List<Vector3> { ObjectManager.Player.ServerPosition, output.CastPosition };
     var collision = Collision.GetCollision(posList, input);
     var minions = collision.Count(collisionObj => collisionObj.IsMinion);
     return minions > 1;
 }
Example #2
0
        /// <summary>
        ///     The get updated prediction.
        /// </summary>
        /// <param name="input">
        ///     The input.
        /// </param>
        /// <returns>
        ///     The <see cref="PredictionOutput" />.
        /// </returns>
        internal static PredictionOutput GetUpdatedPrediction(PredictionInput input)
        {
            if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon)
            {
                input.Speed = 90000;
            }

            var toTarget = Vector3.Normalize(input.Unit.ServerPosition - input.From);
            var targetVelocity = CalculateVelocity(
                input.Unit.ServerPosition,
                input.Unit.Path.LastOrDefault(),
                input.Unit.MoveSpeed);

            var a = Vector3.Dot(targetVelocity, targetVelocity) - (input.Speed * input.Speed);
            var b = 2 * Vector3.Dot(targetVelocity, toTarget);
            var c = Vector3.Dot(toTarget, toTarget);

            var p = -b / (2 * a);
            var q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

            var theorem1 = p - q;
            var theorem2 = p + q;
            var t = (theorem1 > theorem2 && theorem2 > 0) ? theorem2 : theorem1;

            var result = new PredictionOutput()
                             {
                                 CastPosition = input.Unit.ServerPosition + targetVelocity * (t + input.Delay),
                                 UnitPosition = input.Unit.ServerPosition, Hitchance = HitChance.VeryHigh
                             };

            // 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.Radius * 3 / 4, 2))
                {
                    result.Hitchance = HitChance.Medium;
                }

                if (input.RangeCheckFrom.Distance(result.UnitPosition, true)
                    > Math.Pow(input.Range + (input.Type == SkillshotType.SkillshotCircle ? input.Radius : 0), 2))
                {
                    result.Hitchance = HitChance.OutOfRange;
                }
            }

            // Check for collision
            if (input.Collision)
            {
                var positions = new List<Vector3> { result.UnitPosition, result.CastPosition, input.Unit.Position };
                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;
        }
Example #3
0
 static void Game_OnGameLoad(EventArgs args)
 {
     if(ObjectManager.Player.ChampionName != "Blitzcrank") return;
     config = new Menu("AutoGrab", "grab", true);
     Menu menuTS = new Menu("Selector: ", "targ");
     SimpleTs.AddToMenu(menuTS);
     config.AddSubMenu(menuTS);
     config.AddItem(new MenuItem("grabem", "Pull While AA'ing")).SetValue(new KeyBind(32, KeyBindType.Press));
     config.AddToMainMenu();
     p = new PredictionInput {Delay = .25f, Radius = 35, Speed = 1800};
     Game.OnGameProcessPacket += Game_OnGameProcessPacket;
 }
Example #4
0
        static bool CollisionCheckerino(Obj_AI_Hero source, Obj_AI_Hero target, float width)
        {
            var input = new PredictionInput
            {
                Radius = width,
                Unit = source,
            };

            input.CollisionObjects[0] = CollisionableObjects.Heroes;
            input.CollisionObjects[1] = CollisionableObjects.YasuoWall;

            return !Collision.GetCollision(new List<Vector3> { target.ServerPosition }, input).Where(x => x.NetworkId != x.NetworkId).Any();
        }
Example #5
0
        internal static List<Obj_AI_Base> getCollisionMinions(Obj_AI_Hero source, SharpDX.Vector3 targetPos, float predDelay, float predWidth, float predSpeed)
        {
            var input = new PredictionInput
            {
                Unit = source,
                Radius = predWidth,
                Delay = predDelay,
                Speed = predSpeed,
            };

            input.CollisionObjects[0] = CollisionableObjects.Minions;

            return Collision.GetCollision(new List<SharpDX.Vector3> { targetPos }, input).OrderBy(obj => obj.Distance(source, false)).ToList();
        }
Example #6
0
        /// <summary>
        ///     Gets the list of minions currently between the source and target
        /// </summary>
        /// <param name="source">
        ///     The Source
        /// </param>
        /// <param name="targetPosition">
        ///     The Target Position
        /// </param>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Obj_AI_Base> GetCollisionMinions(AIHeroClient source, Vector3 targetPosition)
        {
            var input = new PredictionInput
            {
                Unit = source,
                Radius = SpellManager.Spell[SpellSlot.Q].Width,
                Delay = SpellManager.Spell[SpellSlot.Q].Delay,
                Speed = SpellManager.Spell[SpellSlot.Q].Speed,
                CollisionObjects = new[] { CollisionableObjects.Minions }
            };

            return
                Collision.GetCollision(new List<Vector3> { targetPosition }, input)
                    .OrderBy(x => x.Distance(source))
                    .ToList();
        }
Example #7
0
        public static IEnumerable<Obj_AI_Base> QGetCollisionMinions(Vector3 source, Vector3 targetposition, float width, float range, CollisionableObjects[] collisionObjects)
        {
            PredictionInput input = new PredictionInput {From = source, Radius = width, Range = range};

            if (collisionObjects.Length > 0)
            {
                for (int i = 0; collisionObjects.Length != 0; i ++)
                {
                    input.CollisionObjects[i] = collisionObjects[i];
                }
            }
            else
            {
                input.CollisionObjects[0] = CollisionableObjects.Minions;
            }

            return
                Collision.GetCollision(new List<Vector3> {targetposition}, input).OrderBy(obj => obj.Distance(source)).ToList();
        }
Example #8
0
			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;
			}
Example #9
0
			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.VeryHigh
					};
				}

				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)
				{
					var d = input.Delay * speed - input.RealRadius;
					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;
							var p = pos + input.RealRadius * direction;

							if (input.Type == SkillshotType.SkillshotLine && false)
							{
								var alpha = (input.From.To2D() - p).AngleBetween(a - b);
								if (alpha > 30 && alpha < 180 - 30)
								{
									var beta = (float)Math.Asin(input.RealRadius / 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
				};
			}
Example #10
0
			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*/
				};
			}
Example #11
0
			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 / 13) - (totalDelay * 2);
				float backToFront = moveArea * 1.5f;
				float pathMinLen = 1000f;

				if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d)
				{
					pathMinLen = 700f + 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 (GetAngle(input.From, input.Unit) < angleMove)
					{
						result.Hitchance = HitChance.VeryHigh;
						return result;

					}
				}

				// CIRCLE NEW PATH ///////////////////////////////////////////////////////////////////////////////////

				if (input.Type == SkillshotType.SkillshotCircle)
				{
					if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d && distanceFromToUnit < input.Range - fixRange && distanceUnitToWaypoint > fixRange)
					{
						result.Hitchance = HitChance.VeryHigh;
						return result;
					}
				}
				//Program.debug("PRED: NO DETECTION");

				return result;
			}
Example #12
0
			public static PredictionOutput GetPrediction(PredictionInput input) {
				return GetPrediction(input, true, true);
			}
Example #13
0
        /// <summary>
        ///     Gets the collision minions
        /// </summary>
        /// <param name="source">
        ///     the source
        /// </param>
        /// <param name="targetPosition">
        ///     the target position
        /// </param>
        /// <returns>
        ///     The list of minions
        /// </returns>
        private IEnumerable<Obj_AI_Base> GetCollisionMinions(Obj_AI_Base source, Vector3 targetPosition)
        {
            var input = new PredictionInput
                            {
                                Unit = source, Radius = this.spells[SpellSlot.Q].Width, 
                                Delay = this.spells[SpellSlot.Q].Delay, Speed = this.spells[SpellSlot.Q].Speed
                            };

            input.CollisionObjects[0] = CollisionableObjects.Minions;

            return
                Collision.GetCollision(new List<Vector3> { targetPosition }, input)
                    .OrderBy(obj => obj.Distance(source))
                    .ToList();
        }
Example #14
0
 private List<Obj_AI_Base> QGetCollisions(Obj_AI_Hero source, Vector3 targetposition)
 {
     try
     {
         var input = new PredictionInput { Unit = source, Radius = Q.Width, Delay = Q.Delay, Speed = Q.Speed };
         input.CollisionObjects[0] = CollisionableObjects.Minions;
         return
             Collision.GetCollision(new List<Vector3> { targetposition }, input)
                 .OrderBy(obj => obj.Distance(source))
                 .ToList();
     }
     catch (Exception ex)
     {
         Global.Logger.AddItem(new LogItem(ex));
     }
     return new List<Obj_AI_Base>();
 }
Example #15
0
        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.05f;

                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;
                }

                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;
                    }
                }
            }

            //Check for collision
            if (checkCollision && input.Collision)
            {
                var positions = new List <Vector3> {
                    result.UnitPosition, result.CastPosition, input.Unit.Position
                };
                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);
        }
Example #16
0
 public static PredictionOutput GetPrediction(PredictionInput input, int method = 0)
 {
     return(GetPrediction(input, true, true, method));
 }
Example #17
0
				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;
				}
Example #18
0
        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);

            if (result.Hitchance >= HitChance.High && input.Unit is Obj_AI_Hero) {}

            return result;
        }
Example #19
0
        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.VeryHigh
                });
            }

            var pLength = path.PathLength();

            //Skillshots with only a delay
            if (pLength >= input.Delay * speed - input.RealRadius && input.Speed == float.MaxValue)
            {
                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 =
                                PathTracker.GetCurrentPath(input.Unit).Time < 0.1d ? HitChance.VeryHigh : 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(Math.Max(0, input.Delay * speed - input.RealRadius));
                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)
                    {
                        var p = pos + input.RealRadius * direction;

                        if (input.Type == SkillshotType.SkillshotLine)
                        {
                            var alpha = (input.From.To2D() - p).AngleBetween(a - b);
                            if (alpha > 30 && alpha < 180 - 30)
                            {
                                var beta = (float)Math.Asin(input.RealRadius / 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 =
                                PathTracker.GetCurrentPath(input.Unit).Time < 0.1d ? HitChance.VeryHigh : HitChance.High,
                        });
                    }
                    tT += tB;
                }
            }

            var position = path.Last();

            return(new PredictionOutput
            {
                Input = input,
                CastPosition = position.To3D(),
                UnitPosition = position.To3D(),
                Hitchance = HitChance.Medium,
            });
        }
Example #20
0
        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.VeryHigh
                });
            }

            var pLength = path.PathLength();

            //Skillshots with only a delay
            if (pLength >= input.Delay * speed - input.RealRadius && input.Speed == float.MaxValue)
            {
                var tDistance = input.Delay * speed - input.RealRadius;

                return(new PredictionOutput
                {
                    Input = input,
                    CastPosition = path.PCutPath(tDistance).Item1.To3D(),
                    UnitPosition = path.PCutPath(tDistance + input.RealRadius).Item1.To3D(),
                    Hitchance =
                        PathTracker.GetCurrentPath(input.Unit).Time < 0.1d ? HitChance.VeryHigh : HitChance.High
                });
            }

            //Skillshot with a delay and speed.
            if (pLength >= input.Delay * speed - input.RealRadius && input.Speed != float.MaxValue)
            {
                var path2 = new List <Vector2>();
                path2.AddRange(path);
                path2[0] = path[0] + input.RealRadius * (path[0] - path[1]);

                var pp  = CalcPositionOnPath(path, speed, input.Speed, input.From.To2D(), input.Delay, 6);
                var cpp = CalcPositionOnPath(path2, speed, input.Speed, input.From.To2D(), input.Delay, 6);



                if (cpp.Item3)
                {
                    return(new PredictionOutput
                    {
                        Input = input,
                        CastPosition = cpp.Item1.To3D(),
                        UnitPosition = pp.Item1.To3D(),
                        Hitchance =
                            PathTracker.GetCurrentPath(input.Unit).Time < 0.1d ? HitChance.VeryHigh : HitChance.High
                    });
                }
            }

            var position = path.Last();

            return(new PredictionOutput
            {
                Input = input,
                CastPosition = position.To3D(),
                UnitPosition = position.To3D(),
                Hitchance = HitChance.Medium
            });
        }
Example #21
0
        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.06f;

                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;
                }

                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;
                    }
                }
            }

            //Check for collision
            if (checkCollision && input.Collision)
            {
                var positions = new List<Vector3> { result.UnitPosition, result.CastPosition, input.Unit.Position };
                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;
        }
Example #22
0
            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;
                        }
                    }

                    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);
            }
Example #23
0
        /// <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 = Prediction.GetPrediction(input, false, false);
                                if (
                                    minionPrediction.UnitPosition.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();
        }
Example #24
0
            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);
            }
Example #25
0
			/// <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
									{
										var bonus = 30;
										if (minion.ServerPosition.To2D().Distance(input.From.To2D()) < input.Radius)
											result.Add(minion);
										else if (minion.ServerPosition.To2D().Distance(input.From.To2D(), position.To2D(), true, true) <=
											Math.Pow((input.Radius + bonus + 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();
			}
Example #26
0
        /// <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 = Prediction.GetPrediction(input, false, false);
                            if (
                                minionPrediction.UnitPosition.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
                            ObjectManager.Get <Obj_AI_Hero>()
                            .Where(
                                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 (Environment.TickCount - _wallCastT > 4000)
                        {
                            break;
                        }

                        GameObject wall = null;
                        foreach (
                            var gameObject in
                            ObjectManager.Get <GameObject>()
                            .Where(
                                gameObject =>
                                gameObject.IsValid &&
                                System.Text.RegularExpressions.Regex.IsMatch(
                                    gameObject.Name, "_w_windwall_enemy_0.\\.troy",
                                    System.Text.RegularExpressions.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 / 2 * wallDirection;
                        var wallEnd       = wallStart - wallWidth * wallDirection;

                        if (wallStart.Intersection(wallEnd, position.To2D(), input.From.To2D()).Intersects)
                        {
                            var t = Environment.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());
        }
Example #27
0
			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;
						}
					}
				}

				//Set hit chance
				if (result.Hitchance == HitChance.High || result.Hitchance == HitChance.VeryHigh)
				{
					result = WayPointAnalysis(result, input);
					//.debug(input.Unit.BaseSkinName + result.Hitchance);
				}

				//Check for collision
				if (checkCollision && input.Collision && result.Hitchance > HitChance.Impossible)
				{
					var positions = new List<Vector3> { result.CastPosition, result.UnitPosition };

					result.CollisionObjects = Collision.GetCollision(positions, input);
					result.Hitchance = result.CollisionObjects.Count > 0 ? HitChance.Collision : result.Hitchance;
				}


				return result;
			}
Example #28
0
 public static PredictionOutput GetPrediction(PredictionInput input)
 {
     return(GetPrediction(input, true, true));
 }
Example #29
0
			internal static PredictionOutput GetDashingPrediction(PredictionInput input) {
				var dashData = input.Unit.GetDashInfo();
				var result = new PredictionOutput { Input = input };
				//Normal dashes.
				if (!dashData.IsBlink)
				{
					//Mid air:
					var endP = dashData.Path.Last();
					var dashPred = GetPositionOnPath(
						input, new List<Vector2> { input.Unit.ServerPosition.To2D(), endP }, dashData.Speed);
					if (dashPred.Hitchance >= HitChance.High && dashPred.UnitPosition.To2D().Distance(input.Unit.Position.To2D(), endP, true) < 200)
					{
						dashPred.CastPosition = dashPred.UnitPosition;
						dashPred.Hitchance = HitChance.Dashing;
						return dashPred;
					}

					//At the end of the dash:
					if (dashData.Path.PathLength() > 200)
					{
						var timeToPoint = input.Delay / 2f + input.From.To2D().Distance(endP) / input.Speed - 0.25f;
						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;
			}
Example #30
0
        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.Where(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.Where(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;
                            }
                        }
                    }
                }
            }
        }
Example #31
0
			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);
			}
Example #32
0
 private Vector3 AssistedQLogic(out int hits)
 {
     try
     {
         if (Ball.IsMoving)
         {
             hits = 0;
             return Vector3.Zero;
         }
         var center = Vector2.Zero;
         float radius = -1;
         var count = 0;
         var range = (Q.Range + R.Width) * 1.5f;
         var input = new PredictionInput
         {
             Collision = false,
             From = Ball.Position,
             RangeCheckFrom = Ball.Position,
             Delay = (Q.Delay + R.Delay) - 0.1f,
             Range = Q.Range + R.Width / 2f,
             Speed = Q.Speed,
             Radius = R.Width,
             Type = R.Type
         };
         var points = new List<Vector2>();
         foreach (var enemy in GameObjects.EnemyHeroes.Where(t => t.IsValidTarget(range)))
         {
             input.Unit = enemy;
             var pred = Prediction.GetPrediction(input);
             if (pred.Hitchance >= HitChance.Low)
             {
                 points.Add(pred.UnitPosition.To2D());
             }
         }
         if (points.Any())
         {
             var possibilities = ListExtensions.ProduceEnumeration(points).Where(p => p.Count > 1).ToList();
             if (possibilities.Any())
             {
                 foreach (var possibility in possibilities)
                 {
                     var mec = MEC.GetMec(possibility);
                     if (mec.Radius < R.Width && Player.Distance(mec.Center) < range)
                     {
                         if (possibility.Count > count || possibility.Count == count && mec.Radius < radius)
                         {
                             center = mec.Center;
                             radius = mec.Radius;
                             count = possibility.Count;
                         }
                     }
                 }
                 if (!center.Equals(Vector2.Zero))
                 {
                     hits = count;
                     return center.To3D();
                 }
             }
             var dTarget = GameObjects.EnemyHeroes.FirstOrDefault(t => t.IsValidTarget(range));
             if (dTarget != null)
             {
                 hits = 1;
                 return dTarget.Position;
             }
         }
     }
     catch (Exception ex)
     {
         Global.Logger.AddItem(new LogItem(ex));
     }
     hits = 0;
     return Vector3.Zero;
 }
Example #33
0
			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();
			}
        private bool ELogic(Obj_AI_Hero mainTarget, List<Obj_AI_Base> targets, HitChance hitChance, int minHits)
        {
            try
            {
                var input = new PredictionInput
                {
                    Range = ELength,
                    Delay = E.Delay,
                    Radius = E.Width,
                    Speed = E.Speed,
                    Type = E.Type
                };
                var input2 = new PredictionInput
                {
                    Range = E.Range + ELength,
                    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(E.Range + ELength + 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 = 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))
                {
                    if (startPos.Distance(Player.Position) > E.Range)
                    {
                        startPos = Player.Position.Extend(startPos, E.Range);
                    }
                    if (startPos.Distance(endPos) > ELength)
                    {
                        endPos = startPos.Extend(endPos, ELength);
                    }
                    E.Cast(startPos, endPos);
                    return true;
                }
            }
            catch (Exception ex)
            {
                Global.Logger.AddItem(new LogItem(ex));
            }
            return false;
        }
Example #35
0
				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;
				}
Example #36
0
        public override void Execute()
        {
            // Jodus please...
            //if (Player.ManaPercent < Settings.MinMana)
            if (((Player.Mana / Player.MaxMana) * 100) < Settings.MinMana)
            {
                return;
            }

            // Precheck
            if (!(Settings.UseQ && Q.IsReady()) &&
                !(Settings.UseE && E.IsReady()))
            {
                return;
            }

            // Minions around
            var minions = MinionManager.GetMinions(Q.Range, MinionTypes.All, MinionTeam.Enemy, MinionOrderTypes.MaxHealth);
            if (minions.Count == 0)
            {
                return;
            }

            #region Q usage

            if (Settings.UseQ && Q.IsReady() && !Player.IsDashing())
            {
                // Validate available minions
                if (minions.Count >= Settings.MinNumberQ)
                {
                    // Get only killable minions
                    var killable = minions.Where(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 >= Settings.MinNumberQ && !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 >= Settings.MinNumberQ)
                                        {
                                            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;
                        }
                    }
                }
            }

            #endregion

            #region E usage

            if (Settings.UseE && E.IsReady())
            {
                // Get minions in E range
                var minionsInRange = minions.Where(m => E.IsInRange(m));

                // Validate available minions
                if (minionsInRange.Count() >= Settings.MinNumberE)
                {
                    // 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 >= Settings.MinNumberE)
                            {
                                if (E.Cast(true))
                                    return;

                                break;
                            }
                        }
                    }
                }
            }

            #endregion
        }
Example #37
0
				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;
				}
Example #38
0
 private static double CheckForHit(Obj_AI_Hero hero)
 {
     List<IncomingDamage> damageList = Damages[Damages.Last().Key];
     double maxDamage = 0;
     foreach (IncomingDamage incomingDamage in damageList)
     {
         var pred = new PredictionInput();
         pred.Type = SkillshotType.SkillshotLine;
         pred.Radius = 50;
         pred.From = incomingDamage.StartPos;
         pred.RangeCheckFrom = incomingDamage.StartPos;
         pred.Range = incomingDamage.StartPos.Distance(incomingDamage.EndPos);
         pred.Collision = false;
         pred.Unit = hero;
         if (Prediction.GetPrediction(pred).Hitchance >= HitChance.Low)
             maxDamage += incomingDamage.Dmg;
     }
     return maxDamage;
 }