Example #1
0
 private static PredictionOutput GetDashingPrediction(this PredictionInput input)
 {
     var dashData = input.Unit.GetDashInfo();
     var result = new PredictionOutput { Input = input };
     if (!dashData.IsBlink)
     {
         var endP = dashData.Path.Last();
         var dashPred = input.GetPositionOnPath(
             new List<Vector2> { input.Unit.ServerPosition.ToVector2(), endP },
             dashData.Speed);
         if (dashPred.Hitchance >= HitChance.High
             && dashPred.UnitPosition.ToVector2().Distance(input.Unit.Position.ToVector2(), endP, true) < 200)
         {
             dashPred.CastPosition = dashPred.UnitPosition;
             dashPred.Hitchance = HitChance.Dashing;
             return dashPred;
         }
         if (dashData.Path.PathLength() > 200)
         {
             var timeToPoint = input.Delay / 2 + input.From.Distance(endP) / input.Speed - 0.25;
             if (timeToPoint
                 <= input.Unit.Distance(endP) / dashData.Speed + input.RealRadius / input.Unit.MoveSpeed)
             {
                 return new PredictionOutput
                            {
                                CastPosition = endP.ToVector3(), UnitPosition = endP.ToVector3(),
                                Hitchance = HitChance.Dashing
                            };
             }
         }
         result.CastPosition = dashData.Path.Last().ToVector3();
         result.UnitPosition = result.CastPosition;
     }
     return result;
 }
Example #2
0
        /// <summary>
        ///     Returns Calculated Prediction based off given data values.
        /// </summary>
        /// <param name="input">
        ///     <see cref="PredictionInput" /> input
        /// </param>
        /// <param name="ft">Add Delay</param>
        /// <param name="checkCollision">Check Collision</param>
        /// <returns>
        ///     <see cref="PredictionOutput" /> output
        /// </returns>
        internal static PredictionOutput GetPrediction(PredictionInput input, bool ft, bool checkCollision)
        {
            if (!input.Unit.LSIsValidTarget(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(Cluster.GetAoEPrediction(input));
                }
            }

            // Target too far away.
            if (Math.Abs(input.Range - float.MaxValue) > float.Epsilon &&
                input.Unit.LSDistanceSquared(input.RangeCheckFrom) > Math.Pow(input.Range * 1.5, 2))
            {
                return(new PredictionOutput {
                    Input = input
                });
            }

            PredictionOutput result = null;

            // 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.LSDistanceSquared(input.Unit.Position)
                    > Math.Pow(input.Range + input.RealRadius * 3 / 4, 2))
                {
                    result.Hitchance = HitChance.Medium;
                }

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

                if (input.RangeCheckFrom.LSDistanceSquared(result.CastPosition) > Math.Pow(input.Range, 2) &&
                    result.Hitchance != HitChance.OutOfRange)
                {
                    result.CastPosition = input.RangeCheckFrom
                                          + input.Range
                                          * (result.UnitPosition - input.RangeCheckFrom).ToVector2()
                                          .LSNormalized()
                                          .ToVector3();
                }
            }

            // Check for collision
            if (checkCollision && input.Collision && Math.Abs(input.Speed - float.MaxValue) > float.Epsilon)
            {
                var positions = new List <Vector3> {
                    result.UnitPosition, input.Unit.Position
                };
                result.CollisionObjects = Collision.GetCollision(positions, input);
                result.CollisionObjects.RemoveAll(x => x.Compare(input.Unit));

                if (result.CollisionObjects.Count > 0)
                {
                    result.Hitchance = HitChance.Collision;
                }
            }

            // Calc hitchance again
            if (result.Hitchance == HitChance.High)
            {
                result.Hitchance = GetHitChance(input);
            }

            return(result);
        }
Example #3
0
        /// <summary>
        ///     Returns Immobile Prediction
        /// </summary>
        /// <param name="input">
        ///     <see cref="PredictionInput" /> input
        /// </param>
        /// <param name="remainingImmobileT">Remaining Immobile Time</param>
        /// <returns><see cref="PredictionOutput" /> output</returns>
        internal static PredictionOutput GetImmobilePrediction(PredictionInput input, double remainingImmobileT)
        {
            var result = new PredictionOutput
            {
                Input = input,
                CastPosition = input.Unit.ServerPosition,
                UnitPosition = input.Unit.ServerPosition,
                Hitchance = HitChance.High
            };
            var timeToReachTargetPosition = input.Delay
                                            + (Math.Abs(input.Speed - float.MaxValue) > float.Epsilon
                                                   ? input.Unit.Distance(input.From) / input.Speed
                                                   : 0);

            if (timeToReachTargetPosition <= remainingImmobileT + input.RealRadius / input.Unit.MoveSpeed)
            {
                result.UnitPosition = input.Unit.Position;
                result.Hitchance = HitChance.Immobile;
            }

            return result;
        }
Example #4
0
        /// <summary>
        ///     Returns Dashing Prediction
        /// </summary>
        /// <param name="input">
        ///     <see cref="PredictionInput" /> input
        /// </param>
        /// <returns><see cref="PredictionOutput" /> output</returns>
        internal static PredictionOutput GetDashingPrediction(PredictionInput input)
        {
            var dashData = input.Unit.GetDashInfo();
            var result = new PredictionOutput { Input = input, Hitchance = HitChance.Medium };

            // Normal dashes.
            if (!dashData.IsBlink)
            {
                var endP = dashData.EndPos.ToVector3();

                // Mid air:
                var dashPred = GetPositionOnPath(
                    input,
                    new List<Vector3> { input.Unit.ServerPosition, endP }.ToVector2(),
                    dashData.Speed);

                if (dashPred.Hitchance >= HitChance.High
                    && dashPred.UnitPosition.ToVector2()
                           .Distance(input.Unit.Position.ToVector2(), endP.ToVector2(), true) < 200)
                {
                    dashPred.CastPosition = dashPred.UnitPosition;
                    dashPred.Hitchance = HitChance.Dashing;
                    return dashPred;
                }

                // At the end of the dash:
                if (dashData.Path.LSPathLength() > 200)
                {
                    var timeToPoint = input.Delay / 2f
                                      + (Math.Abs(input.Speed - float.MaxValue) > float.Epsilon
                                             ? input.From.Distance(endP) / input.Speed
                                             : 0) - 0.25f;

                    if (timeToPoint
                        <= input.Unit.Distance(endP) / dashData.Speed + input.RealRadius / input.Unit.MoveSpeed)
                    {
                        return new PredictionOutput
                        {
                            Input = input,
                            CastPosition = endP,
                            UnitPosition = endP,
                            Hitchance = HitChance.Dashing
                        };
                    }
                }

                result.CastPosition = endP;
                result.UnitPosition = result.CastPosition;

                // Figure out where the unit is going.
            }

            return result;
        }
Example #5
0
        /// <summary>
        ///     Returns Dashing Prediction
        /// </summary>
        /// <param name="input">
        ///     <see cref="PredictionInput" /> input
        /// </param>
        /// <returns><see cref="PredictionOutput" /> output</returns>
        internal static PredictionOutput GetDashingPrediction(PredictionInput input)
        {
            var dashData = input.Unit.GetDashInfo();
            var result = new PredictionOutput { Input = input };
            input.Delay += 0.1f;

            // Normal dashes.
            if (!dashData.IsBlink)
            {
                // Mid air:
                var dashPred = GetPositionOnPath(
                    input,
                    new List<Vector2> { input.Unit.ServerPosition.ToVector2(), dashData.Path.Last() },
                    dashData.Speed);
                if (dashPred.Hitchance >= HitChance.High)
                {
                    dashPred.CastPosition = dashPred.UnitPosition;
                    dashPred.Hitchance = HitChance.Dashing;
                    return dashPred;
                }

                // At the end of the dash:
                if (dashData.Path.PathLength() > 200)
                {
                    var endP = dashData.Path.Last();
                    var timeToPoint = input.Delay + (input.From.Distance(endP) / input.Speed);
                    if (timeToPoint
                        <= (input.Unit.Distance(endP) / dashData.Speed) + (input.RealRadius / input.Unit.MoveSpeed))
                    {
                        return new PredictionOutput
                                   {
                                       CastPosition = endP.ToVector3(), UnitPosition = endP.ToVector3(),
                                       Hitchance = HitChance.Dashing
                                   };
                    }
                }

                result.CastPosition = dashData.Path.Last().ToVector3();
                result.UnitPosition = result.CastPosition;

                // Figure out where the unit is going.
            }

            return result;
        }
Example #6
0
 private static PredictionOutput WayPointAnalysis(this PredictionInput input, PredictionOutput result)
 {
     var heroUnit = input.Unit as Obj_AI_Hero;
     if (heroUnit == null || input.Radius.Equals(1))
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     /*if (UnitTracker.GetLastSpecialSpellTime(heroUnit) > 0 || heroUnit.IsRecalling())
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     var lastWaypoint = heroUnit.GetWaypoints().Last();
     var distUnitToWaypoint = heroUnit.Distance(lastWaypoint);
     var distFromToWaypoint = input.From.Distance(lastWaypoint);
     var distUnitToFrom = heroUnit.Distance(input.From);
     var speedDelay = distUnitToFrom / input.Speed;
     if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon)
     {
         speedDelay = 0;
     }
     var totalDelay = speedDelay + input.Delay;
     var moveArea = heroUnit.MoveSpeed * totalDelay;
     var fixRange = moveArea * 0.5f;
     var moveAngle = 30 + input.Radius / 17 - totalDelay * 2;
     var minPath = 900f;
     if (moveAngle < 31)
     {
         moveAngle = 31;
     }
     if (input.Type == SkillshotType.SkillshotCircle)
     {
         fixRange -= input.Radius / 2;
     }
     if (UnitTracker.CanCalcWaypoints(heroUnit))
     {
         result.Hitchance = distUnitToFrom < input.Range - fixRange ? HitChance.VeryHigh : HitChance.High;
         return result;
     }
     if (UnitTracker.GetLastVisableTime(heroUnit) < 0.1)
     {
         result.Hitchance = HitChance.Medium;
         return result;
     }
     if (distUnitToFrom < 300 || distFromToWaypoint < 200)
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (distUnitToWaypoint > minPath)
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (distFromToWaypoint > fixRange && input.From.GetAngle(heroUnit) < moveAngle)
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (distFromToWaypoint <= distUnitToFrom && distUnitToFrom > input.Range - fixRange)
     {
         result.Hitchance = HitChance.Medium;
         return result;
     }
     if (UnitTracker.GetLastAttackTime(heroUnit) < 0.1)
     {
         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;
     }
     if (heroUnit.IsWindingUp)
     {
         result.Hitchance = HitChance.High;
         return result;
     }
     if (heroUnit.Path.Length == 0 && !heroUnit.IsMoving)
     {
         if (distUnitToFrom > input.Range - fixRange)
         {
             result.Hitchance = HitChance.Medium;
         }
         else if (UnitTracker.GetLastStopMoveTime(heroUnit) > 0.8)
         {
             result.Hitchance = HitChance.High;
         }
         else
         {
             result.Hitchance = HitChance.VeryHigh;
         }
         return result;
     }
     if (input.Type == SkillshotType.SkillshotLine && heroUnit.Path.Length > 0 && heroUnit.IsMoving
         && GamePath.PathTracker.GetCurrentPath(heroUnit).Time < 0.1 && input.From.GetAngle(heroUnit) < moveAngle
         && distUnitToWaypoint > moveArea * 0.6)
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (input.Type == SkillshotType.SkillshotCircle && GamePath.PathTracker.GetCurrentPath(heroUnit).Time < 0.1
         && distUnitToWaypoint > fixRange && distUnitToFrom < input.Range - fixRange)
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }*/
     return result;
 }
Example #7
0
 private static PredictionOutput WayPointAnalysis(this PredictionInput input, PredictionOutput result)
 {
     var heroUnit = input.Unit as Obj_AI_Hero;
     if (heroUnit == null || input.Radius.Equals(1))
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (UnitTracker.GetLastSpecialSpellTime(heroUnit) > 0 || heroUnit.IsRecalling())
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (UnitTracker.GetLastVisableTime(heroUnit) < 0.1)
     {
         result.Hitchance = HitChance.Medium;
         return result;
     }
     result.Hitchance = HitChance.Medium;
     var lastWaypoint = heroUnit.GetWaypoints().Last();
     var distUnitToWaypoint = heroUnit.Distance(lastWaypoint);
     var distFromToWaypoint = input.From.Distance(lastWaypoint);
     var distUnitToFrom = heroUnit.Distance(input.From);
     var angle = input.From.GetAngle(heroUnit);
     var speedDelay = distUnitToFrom / input.Speed;
     if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon)
     {
         speedDelay = 0;
     }
     var totalDelay = speedDelay + input.Delay;
     var moveArea = heroUnit.MoveSpeed * totalDelay;
     var fixRange = moveArea * 0.4f;
     var minPath = 900 + moveArea;
     var moveAngle = Math.Max(30 + input.Radius / 17d - totalDelay - input.Delay * 2, 31);
     if (GamePath.PathTracker.GetCurrentPath(heroUnit).Time < 0.1)
     {
         result.Hitchance = HitChance.High;
         fixRange = moveArea * 0.3f;
         minPath = 600 + moveArea;
         moveAngle += 2;
     }
     if (input.Type == SkillshotType.SkillshotCircle)
     {
         fixRange -= input.Radius / 2;
     }
     if (distFromToWaypoint <= distUnitToFrom && distUnitToFrom > input.Range - fixRange)
     {
         result.Hitchance = HitChance.Medium;
         return result;
     }
     if (UnitTracker.CanCalcWaypoints(heroUnit))
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (UnitTracker.SpamSamePlace(heroUnit))
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (distUnitToFrom < 250 || heroUnit.MoveSpeed < 200 || distFromToWaypoint < 100)
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (distUnitToWaypoint > minPath)
     {
         result.Hitchance = HitChance.VeryHigh;
         return result;
     }
     if (angle < moveAngle)
     {
         if (distUnitToWaypoint > fixRange && GamePath.PathTracker.GetCurrentPath(heroUnit).Time < 0.1)
         {
             result.Hitchance = HitChance.VeryHigh;
             return result;
         }
         if (Program.Player.IsMoving
             && (Program.Player.IsFacing(heroUnit)
                     ? !heroUnit.IsFacing(Program.Player)
                     : heroUnit.IsFacing(Program.Player)))
         {
             result.Hitchance = HitChance.VeryHigh;
             return result;
         }
     }
     if (UnitTracker.GetLastAttackTime(heroUnit) < 0.1)
     {
         if (input.Type == SkillshotType.SkillshotLine && totalDelay < 0.4 + input.Radius * 0.002)
         {
             result.Hitchance = HitChance.VeryHigh;
             return result;
         }
         if (input.Type == SkillshotType.SkillshotCircle && totalDelay < 0.6 + input.Radius * 0.002)
         {
             result.Hitchance = HitChance.VeryHigh;
             return result;
         }
         result.Hitchance = HitChance.High;
     }
     else if (heroUnit.Path.Length == 0 || !heroUnit.IsMoving)
     {
         if (heroUnit.IsWindingUp)
         {
             result.Hitchance = HitChance.High;
         }
         else if (UnitTracker.GetLastStopMoveTime(heroUnit) < 0.5)
         {
             result.Hitchance = HitChance.High;
         }
         else
         {
             result.Hitchance = HitChance.VeryHigh;
         }
         return result;
     }
     if (input.Type == SkillshotType.SkillshotCircle && GamePath.PathTracker.GetCurrentPath(heroUnit).Time < 0.1
         && distUnitToWaypoint > fixRange)
     {
         result.Hitchance = HitChance.VeryHigh;
     }
     return result;
 }
Example #8
0
        /// <summary>
        ///     Returns Calculated Prediction based off given data values.
        /// </summary>
        /// <param name="input">
        ///     <see cref="PredictionInput" /> input
        /// </param>
        /// <param name="ft">Add Delay</param>
        /// <param name="checkCollision">Check Collision</param>
        /// <returns>
        ///     <see cref="PredictionOutput" /> output
        /// </returns>
        internal static PredictionOutput GetPrediction(PredictionInput input, bool ft, bool checkCollision)
        {
            if (!input.Unit.IsValidTarget(float.MaxValue, false))
            {
                return(new PredictionOutput());
            }

            if (ft)
            {
                input.Delay += Game.Ping / 2000f + 0.05f;

                if (input.AoE)
                {
                    return(Cluster.GetAoEPrediction(input));
                }
            }

            // Target too far away.
            if (Math.Abs(input.Range - float.MaxValue) > float.Epsilon &&
                input.Unit.DistanceSquared(input.RangeCheckFrom) > Math.Pow(input.Range * 1.5, 2))
            {
                return(new PredictionOutput {
                    Input = input
                });
            }

            PredictionOutput result = null;

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

            if (!((Player.Instance).Distance(input.Unit, true) < input.Range * input.Range))
            {
                result.Hitchance = HitChance.OutOfRange;
            }

            // Check for collision
            if (checkCollision && input.Collision && Math.Abs(input.Speed - float.MaxValue) > float.Epsilon)
            {
                var positions = new List <Vector3> {
                    result.UnitPosition, input.Unit.Position
                };
                result.CollisionObjects = Collision.GetCollision(positions, input);
                result.CollisionObjects.RemoveAll(x => x.Compare(input.Unit));

                if (result.CollisionObjects.Count > 0)
                {
                    result.Hitchance = HitChance.Collision;
                }
            }

            // Calc hitchance again
            if (result.Hitchance == HitChance.High)
            {
                result.Hitchance = GetHitChance(input);
            }

            return(result);
        }
Example #9
0
        public static PredictionOutput GetBadaoPrediction(this Spell spell, Obj_AI_Base target, bool collideyasuowall = true)
        {
            PredictionOutput result = null;

            if (!target.IsValidTarget(float.MaxValue, false))
            {
                return new PredictionOutput();
            }
            if (target.IsDashing())
            {
                var dashDtata = target.GetDashInfo();
                result = spell.GetBadaoStandarPrediction(target,
                    new List<Vector2>() { target.ServerPosition.ToVector2(), dashDtata.Path.Last() }, dashDtata.Speed);
                if (result.Hitchance >= HitChance.High)
                    result.Hitchance = HitChance.Dashing;
            }
            else
            {
                //Unit is immobile.
                var remainingImmobileT = UnitIsImmobileUntil(target);
                if (remainingImmobileT >= 0d)
                {
                    var timeToReachTargetPosition = spell.Delay + target.Position.ToVector2().Distance(spell.From.ToVector2()) / spell.Speed;
                    if (spell.RangeCheckFrom.ToVector2().Distance(target.Position.ToVector2()) <= spell.Range)
                    {
                        if (timeToReachTargetPosition <=
                            remainingImmobileT + (target.BoundingRadius + spell.Width - 40) / target.MoveSpeed)
                        {
                            result = new PredictionOutput
                            {
                                CastPosition = target.ServerPosition,
                                UnitPosition = target.ServerPosition,
                                Hitchance = HitChance.Immobile
                            };
                        }

                        else result = new PredictionOutput
                        {
                            CastPosition = target.ServerPosition,
                            UnitPosition = target.ServerPosition,
                            Hitchance = HitChance.High
                            /*timeToReachTargetPosition - remainingImmobileT + input.RealRadius / input.Unit.MoveSpeed < 0.4d ? HitChance.High : HitChance.Medium*/
                        };
                    }
                    else
                    {
                        result = new PredictionOutput();
                    }
                }
            }
            //Normal prediction
            if (result == null)
            {
                result = spell.GetBadaoStandarPrediction(target, target.GetWaypoints());
            }
            //Check for collision
            if (spell.Collision)
            {
                var positions = new List<Vector3> { result.UnitPosition, result.CastPosition, target.Position };
                var originalUnit = target;
                result.CollisionObjects = spell.GetCollision(positions);
                result.CollisionObjects.RemoveAll(x => x.NetworkId == originalUnit.NetworkId);
                result.Hitchance = result.CollisionObjects.Count > 0 ? HitChance.Collision : result.Hitchance;
            }
            //Check yasuo wall collision
            else if (collideyasuowall)
            {
                var positions = new List<Vector3> { result.UnitPosition, result.CastPosition, target.Position };
                var originalUnit = target;
                result.CollisionObjects = spell.GetCollision(positions);
                result.CollisionObjects.Any(x => x.NetworkId == ObjectManager.Player.NetworkId);
                result.Hitchance = result.CollisionObjects.Any(x => x.NetworkId == ObjectManager.Player.NetworkId) ? HitChance.Collision : result.Hitchance;
            }
            return result;
        }