Esempio n. 1
0
        /// <summary>
        ///     Gets Prediction result
        /// </summary>
        /// <param name="target">Target for spell</param>
        /// <param name="width">Spell width</param>
        /// <param name="delay">Spell delay</param>
        /// <param name="missileSpeed">Spell missile speed</param>
        /// <param name="range">Spell range</param>
        /// <param name="collisionable">Spell collisionable</param>
        /// <param name="type">Spell skillshot type</param>
        /// <param name="path">Waypoints of target</param>
        /// <param name="avgt">Average reaction time (in ms)</param>
        /// <param name="movt">Passed time from last movement change (in ms)</param>
        /// <param name="avgp">Average Path Lenght</param>
        /// <param name="from">Spell casted position</param>
        /// <param name="rangeCheckFrom"></param>
        /// <returns>Prediction result as <see cref="Prediction.Result" /></returns>
        internal static Result GetPrediction(Obj_AI_Base target, float width, float delay, float missileSpeed, float range, bool collisionable, SkillshotType type, List <Vector2> path, float avgt, float movt, float avgp, float anglediff, Vector2 from, Vector2 rangeCheckFrom)
        {
            Prediction.AssertInitializationMode();

            Result result = new Result();

            result.Input = new Input(target, delay, missileSpeed, width, range, collisionable, type, from.To3D2(), rangeCheckFrom.To3D2());
            result.Unit  = target;

            try
            {
                if (type == SkillshotType.SkillshotCircle)
                {
                    range += width;
                }

                //to do: hook logic ? by storing average movement direction etc
                if (path.Count <= 1 && movt > 100 && (Environment.TickCount - PathTracker.EnemyInfo[target.NetworkId].LastAATick > 300 || !ConfigMenu.CheckAAWindUp)) //if target is not moving, easy to hit (and not aaing)
                {
                    result.HitChance    = HitChance.VeryHigh;
                    result.CastPosition = target.ServerPosition.LSTo2D();
                    result.UnitPosition = result.CastPosition;
                    result.Lock();

                    return(result);
                }

                if (target is AIHeroClient)
                {
                    if (((AIHeroClient)target).IsChannelingImportantSpell())
                    {
                        result.HitChance    = HitChance.VeryHigh;
                        result.CastPosition = target.ServerPosition.LSTo2D();
                        result.UnitPosition = result.CastPosition;
                        result.Lock();

                        return(result);
                    }

                    if (Environment.TickCount - PathTracker.EnemyInfo[target.NetworkId].LastAATick < 300 && ConfigMenu.CheckAAWindUp)
                    {
                        if (target.AttackCastDelay * 1000 + PathTracker.EnemyInfo[target.NetworkId].AvgOrbwalkTime + avgt - width / 2f / target.MoveSpeed >= GetArrivalTime(target.ServerPosition.LSTo2D().LSDistance(from), delay, missileSpeed))
                        {
                            result.HitChance    = HitChance.High;
                            result.CastPosition = target.ServerPosition.LSTo2D();
                            result.UnitPosition = result.CastPosition;
                            result.Lock();

                            return(result);
                        }
                    }

                    //to do: find a fuking logic
                    if (avgp < 400 && movt < 100 && path.LSPathLength() <= avgp)
                    {
                        result.HitChance    = HitChance.High;
                        result.CastPosition = path.Last();
                        result.UnitPosition = result.CastPosition;
                        result.Lock();

                        return(result);
                    }
                }

                if (target.LSIsDashing()) //if unit is dashing
                {
                    return(GetDashingPrediction(target, width, delay, missileSpeed, range, collisionable, type, from, rangeCheckFrom));
                }

                if (Utility.IsImmobileTarget(target)) //if unit is immobile
                {
                    return(GetImmobilePrediction(target, width, delay, missileSpeed, range, collisionable, type, from, rangeCheckFrom));
                }

                result = WaypointAnlysis(target, width, delay, missileSpeed, range, collisionable, type, path, avgt, movt, avgp, anglediff, from);

                float d = result.CastPosition.LSDistance(target.ServerPosition.LSTo2D());
                if (d >= (avgt - movt) * target.MoveSpeed && d >= avgp)
                {
                    result.HitChance = HitChance.Medium;
                }

                result.Lock();

                return(result);
            }
            finally
            {
                //check if movement changed while prediction calculations
                if (!target.GetWaypoints().SequenceEqual(path))
                {
                    result.HitChance = HitChance.Medium;
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        ///     Get Position on Unit's Path.
        /// </summary>
        /// <param name="input">
        ///     <see cref="PredictionInput" /> input
        /// </param>
        /// <param name="path">Path in Vector2 List</param>
        /// <param name="speed">Unit Speed</param>
        /// <returns><see cref="PredictionOutput" /> output</returns>
        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.LSPathLength();
            var dist    = input.Delay * speed - input.RealRadius;

            // Skillshots with only a delay
            if (pLength >= dist && Math.Abs(input.Speed - float.MaxValue) < float.Epsilon)
            {
                var tDistance = dist;

                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).LSNormalized();
                        var cp        = a + direction * tDistance;
                        var p         = a
                                        + direction
                                        * (i == path.Count - 2
                                       ? Math.Min(tDistance + input.RealRadius, d)
                                       : tDistance + input.RealRadius);

                        return(new PredictionOutput
                        {
                            Input = input,
                            CastPosition = cp.ToVector3(),
                            UnitPosition = p.ToVector3(),
                            Hitchance = HitChance.High
                        });
                    }

                    tDistance -= d;
                }
            }

            // Skillshot with a delay and speed.
            if (pLength >= dist && Math.Abs(input.Speed - float.MaxValue) > float.Epsilon)
            {
                var tDistance = dist;

                if ((input.Type == SkillshotType.SkillshotLine || input.Type == SkillshotType.SkillshotCone) &&
                    input.Unit.LSDistanceSquared(input.From) < 200 * 200)
                {
                    tDistance += input.RealRadius;
                }

                path = path.CutPath(tDistance);
                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).LSNormalized();
                    a = a - speed * tT * direction;
                    var sol = a.VectorMovementCollision(b, speed, input.From.ToVector2(), input.Speed, tT);
                    var t   = (float)sol[0];
                    var pos = (Vector2)sol[1];

                    if (pos.IsValid() && t >= tT && t <= tT + tB)
                    {
                        if (pos.LSDistanceSquared(b) < 20)
                        {
                            break;
                        }

                        var p = pos + input.RealRadius * direction;

                        /*if (input.Type == SkillshotType.SkillshotLine)
                         * {
                         *  var alpha = (input.From.ToVector2() - 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.ToVector2() + (p - input.From.ToVector2()).Rotated(beta);
                         *      var cp2 = input.From.ToVector2() + (p - input.From.ToVector2()).Rotated(-beta);
                         *
                         *      pos = cp1.LSDistanceSquared(pos) < cp2.LSDistanceSquared(pos) ? cp1 : cp2;
                         *  }
                         * }*/

                        return(new PredictionOutput
                        {
                            Input = input,
                            CastPosition = pos.ToVector3(),
                            UnitPosition = p.ToVector3(),
                            Hitchance = HitChance.High
                        });
                    }

                    tT += tB;
                }
            }

            var position = path.Last().ToVector3();

            return(new PredictionOutput
            {
                Input = input, CastPosition = position, UnitPosition = position, Hitchance = HitChance.Medium
            });
        }
Esempio n. 3
0
        /// <summary>
        /// OnNewPath event for average reaction time calculations
        /// </summary>
        private static void AIHeroClient_OnNewPath(Obj_AI_Base sender, GameObjectNewPathEventArgs args)
        {
            if (!sender.IsEnemy || !sender.IsChampion() || args.IsDash)
            {
                return;
            }

            EnemyData enemy = EnemyInfo[sender.NetworkId];


            if (args.Path.Length < 2)
            {
                if (!enemy.IsStopped)
                {
                    enemy.StopTick         = Environment.TickCount;
                    enemy.LastWaypointTick = Environment.TickCount;
                    enemy.IsStopped        = true;
                    enemy.Count            = 0;
                    enemy.AvgTick          = 0;
                    enemy.AvgPathLenght    = 0;
                    enemy.LastAngleDiff    = 360;
                }
            }
            else
            {
                List <Vector2> wp      = args.Path.Select(p => p.LSTo2D()).ToList();
                List <Vector2> sample1 = new List <Vector2>();
                wp.Insert(0, sender.ServerPosition.LSTo2D());

                for (int i = 0; i < wp.Count - 1; i++)
                {
                    Vector2 direction = (wp[i + 1] - wp[i]).Normalized();
                    sample1.Add(direction);
                }

                List <Vector2> sample2 = new List <Vector2>();
                for (int i = 0; i < enemy.LastWaypoints.Count - 1; i++)
                {
                    Vector2 direction = (enemy.LastWaypoints[i + 1] - enemy.LastWaypoints[i]).Normalized();
                    sample2.Add(direction);
                }

                if (sample1.Count() > 0 && sample2.Count() > 0)
                {
                    float sample1_avg = sample1.Average(p => p.AngleBetween(Vector2.Zero));
                    float sample2_avg = sample2.Average(p => p.AngleBetween(Vector2.Zero));
                    enemy.LastAngleDiff = Math.Abs(sample2_avg - sample1_avg);
                }
                if (!enemy.LastWaypoints.SequenceEqual(wp))
                {
                    if (!enemy.IsStopped)
                    {
                        enemy.AvgTick       = (enemy.Count * enemy.AvgTick + (Environment.TickCount - enemy.LastWaypointTick)) / ++enemy.Count;
                        enemy.AvgPathLenght = ((enemy.Count - 1) * enemy.AvgPathLenght + wp.LSPathLength()) / enemy.Count;
                    }
                    enemy.LastWaypointTick = Environment.TickCount;
                    enemy.IsStopped        = false;
                    enemy.LastWaypoints    = wp;

                    if (!enemy.IsWindupChecked)
                    {
                        if (Environment.TickCount - enemy.LastAATick < 300)
                        {
                            enemy.AvgOrbwalkTime = (enemy.AvgOrbwalkTime * enemy.OrbwalkCount + (enemy.LastWaypointTick - enemy.LastWindupTick)) / ++enemy.OrbwalkCount;
                        }
                        enemy.IsWindupChecked = true;
                    }
                }
            }

            EnemyInfo[sender.NetworkId] = enemy;
        }
Esempio n. 4
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.LSPathLength();

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

                for (var i = 0; i < path.Count - 1; i++)
                {
                    var a = path[i];
                    var b = path[i + 1];
                    var d = a.LSDistance(b);

                    if (d >= tDistance)
                    {
                        var direction = (b - a).LSNormalized();

                        var cp = a + direction * tDistance;
                        var p = a +
                                direction *
                                ((i == path.Count - 2)
                                    ? Math.Min(tDistance + input.RealRadius, d)
                                    : (tDistance + input.RealRadius));

                        return new PredictionOutput
                        {
                            Input = input,
                            CastPosition = cp.To3D(),
                            UnitPosition = p.To3D(),
                            Hitchance = HitChance.High
                        };
                    }

                    tDistance -= d;
                }
            }

            //Skillshot with a delay and speed.
            if (pLength >= input.Delay * speed - input.RealRadius &&
                Math.Abs(input.Speed - float.MaxValue) > float.Epsilon)
            {
                var d = input.Delay * speed - input.RealRadius;
                if (input.Type == SkillshotType.SkillshotLine || input.Type == SkillshotType.SkillshotCone)
                {
                    if (input.From.LSDistance(input.Unit.ServerPosition, true) < 200 * 200)
                    {
                        d = input.Delay * speed;
                    }
                }

                path = path.CutPath(d);
                var tT = 0f;
                for (var i = 0; i < path.Count - 1; i++)
                {
                    var a = path[i];
                    var b = path[i + 1];
                    var tB = a.LSDistance(b) / speed;
                    var direction = (b - a).LSNormalized();
                    a = a - speed * tT * direction;
                    var sol = Geometry.VectorMovementCollision(a, b, speed, input.From.LSTo2D(), input.Speed, tT);
                    var t = (float)sol[0];
                    var pos = (Vector2)sol[1];

                    if (pos.IsValid() && t >= tT && t <= tT + tB)
                    {
                        if (pos.LSDistance(b, true) < 20)
                            break;
                        var p = pos + input.RealRadius * direction;

                        if (input.Type == SkillshotType.SkillshotLine && false)
                        {
                            var alpha = (input.From.LSTo2D() - p).LSAngleBetween(a - b);
                            if (alpha > 30 && alpha < 180 - 30)
                            {
                                var beta = (float)Math.Asin(input.RealRadius / p.LSDistance(input.From));
                                var cp1 = input.From.LSTo2D() + (p - input.From.LSTo2D()).LSRotated(beta);
                                var cp2 = input.From.LSTo2D() + (p - input.From.LSTo2D()).LSRotated(-beta);

                                pos = cp1.LSDistance(pos, true) < cp2.LSDistance(pos, true) ? cp1 : cp2;
                            }
                        }

                        return new PredictionOutput
                        {
                            Input = input,
                            CastPosition = pos.To3D(),
                            UnitPosition = p.To3D(),
                            Hitchance = HitChance.High
                        };
                    }
                    tT += tB;
                }
            }

            var position = path.Last();
            return new PredictionOutput
            {
                Input = input,
                CastPosition = position.To3D(),
                UnitPosition = position.To3D(),
                Hitchance = HitChance.Medium
            };
        }
Esempio n. 5
0
        /// <summary>
        ///     Gets Prediction result
        /// </summary>
        /// <param name="target">Target for spell</param>
        /// <param name="width">Spell width</param>
        /// <param name="delay">Spell delay</param>
        /// <param name="missileSpeed">Spell missile speed</param>
        /// <param name="range">Spell range</param>
        /// <param name="collisionable">Spell collisionable</param>
        /// <param name="type">Spell skillshot type</param>
        /// <param name="path">Waypoints of target</param>
        /// <param name="avgt">Average reaction time (in ms)</param>
        /// <param name="movt">Passed time from last movement change (in ms)</param>
        /// <param name="avgp">Average Path Lenght</param>
        /// <param name="from">Spell casted position</param>
        /// <param name="rangeCheckFrom"></param>
        /// <returns>Prediction result as <see cref="Prediction.Result" /></returns>
        internal static Result GetPrediction(Obj_AI_Base target, float width, float delay, float missileSpeed, float range, bool collisionable, SkillshotType type, List<Vector2> path, float avgt, float movt, float avgp, float anglediff, Vector2 from, Vector2 rangeCheckFrom)
        {
            Prediction.AssertInitializationMode();

            Result result = new Result();
            result.Input = new Input(target, delay, missileSpeed, width, range, collisionable, type, from.To3D2(), rangeCheckFrom.To3D2());
            result.Unit = target;

            try
            {
                if (type == SkillshotType.SkillshotCircle)
                    range += width;

                //to do: hook logic ? by storing average movement direction etc
                if (path.Count <= 1 && movt > 100 && (Environment.TickCount - PathTracker.EnemyInfo[target.NetworkId].LastAATick > 300 || !ConfigMenu.CheckAAWindUp)) //if target is not moving, easy to hit (and not aaing)
                {
                    result.HitChance = EloBuddy.SDK.Enumerations.HitChance.High;
                    result.CastPosition = target.ServerPosition.LSTo2D();
                    result.UnitPosition = result.CastPosition;
                    result.Lock();

                    return result;
                }

                if (target is AIHeroClient)
                {
                    if (((AIHeroClient)target).IsChannelingImportantSpell())
                    {
                        result.HitChance = EloBuddy.SDK.Enumerations.HitChance.High;
                        result.CastPosition = target.ServerPosition.LSTo2D();
                        result.UnitPosition = result.CastPosition;
                        result.Lock();

                        return result;
                    }

                    if (Environment.TickCount - PathTracker.EnemyInfo[target.NetworkId].LastAATick < 300 && ConfigMenu.CheckAAWindUp)
                    {
                        if (target.AttackCastDelay * 1000 + PathTracker.EnemyInfo[target.NetworkId].AvgOrbwalkTime + avgt - width / 2f / target.MoveSpeed >= GetArrivalTime(target.ServerPosition.LSTo2D().LSDistance(from), delay, missileSpeed))
                        {
                            result.HitChance = EloBuddy.SDK.Enumerations.HitChance.High;
                            result.CastPosition = target.ServerPosition.LSTo2D();
                            result.UnitPosition = result.CastPosition;
                            result.Lock();

                            return result;
                        }
                    }

                    //to do: find a fuking logic
                    if (avgp < 400 && movt < 100 && path.LSPathLength() <= avgp)
                    {
                        result.HitChance = EloBuddy.SDK.Enumerations.HitChance.High;
                        result.CastPosition = path.Last();
                        result.UnitPosition = result.CastPosition;
                        result.Lock();

                        return result;
                    }
                }

                if (target.LSIsDashing()) //if unit is dashing
                    return GetDashingPrediction(target, width, delay, missileSpeed, range, collisionable, type, from, rangeCheckFrom);

                if (Utility.IsImmobileTarget(target)) //if unit is immobile
                    return GetImmobilePrediction(target, width, delay, missileSpeed, range, collisionable, type, from, rangeCheckFrom);

                result = WaypointAnlysis(target, width, delay, missileSpeed, range, collisionable, type, path, avgt, movt, avgp, anglediff, from);

                float d = result.CastPosition.LSDistance(target.ServerPosition.LSTo2D());
                if (d >= (avgt - movt) * target.MoveSpeed && d >= avgp)
                    result.HitChance = EloBuddy.SDK.Enumerations.HitChance.Medium;

                result.Lock();

                return result;
            }
            finally
            {
                //check if movement changed while prediction calculations
                if (!target.GetWaypoints().SequenceEqual(path))
                    result.HitChance = EloBuddy.SDK.Enumerations.HitChance.Medium;
            }
        }