Exemple #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>
 public static Prediction.Result GetPrediction(Obj_AI_Base target, float width, float delay, float missileSpeed, float range, bool collisionable, List <Vector2> path, float avgt, float movt, float avgp, Vector2 from, Vector2 rangeCheckFrom)
 {
     return(Prediction.GetPrediction(target, width, delay, missileSpeed, range, collisionable, SkillshotType.SkillshotLine, path, avgt, movt, avgp, from, rangeCheckFrom));
 }
Exemple #2
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, Vector2 from, Vector2 rangeCheckFrom)
        {
            Prediction.AssertInitializationMode();

            Result result = new Result();

            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 || !predMenu.Item("SPREDWINDUP").GetValue <bool>())) //if target is not moving, easy to hit (and not aaing)
                {
                    result.HitChance       = HitChance.VeryHigh;
                    result.CastPosition    = target.ServerPosition.To2D();
                    result.UnitPosition    = result.CastPosition;
                    result.CollisionResult = Collision.GetCollisions(from, result.CastPosition, width, delay, missileSpeed);

                    if (collisionable && (result.CollisionResult.Objects.HasFlag(Collision.Flags.Minions) || result.CollisionResult.Objects.HasFlag(Collision.Flags.YasuoWall)))
                    {
                        result.HitChance = HitChance.Collision;
                    }

                    if (from.Distance(result.CastPosition) > range - GetArrivalTime(from.Distance(result.CastPosition), delay, missileSpeed) * target.MoveSpeed * (100 - predMenu.Item("SPREDMAXRANGEIGNORE").GetValue <Slider>().Value) / 100f)
                    {
                        result.HitChance = HitChance.OutOfRange;
                    }

                    return(result);
                }

                if (target is AIHeroClient)
                {
                    if (((AIHeroClient)target).IsChannelingImportantSpell())
                    {
                        result.HitChance       = HitChance.VeryHigh;
                        result.CastPosition    = target.ServerPosition.To2D();
                        result.UnitPosition    = result.CastPosition;
                        result.CollisionResult = Collision.GetCollisions(from, result.CastPosition, width, delay, missileSpeed);

                        //check collisions
                        if (collisionable && (result.CollisionResult.Objects.HasFlag(Collision.Flags.Minions) || result.CollisionResult.Objects.HasFlag(Collision.Flags.YasuoWall)))
                        {
                            result.HitChance = HitChance.Collision;
                        }

                        //check if target can dodge with moving backward
                        if (from.Distance(result.CastPosition) > range - GetArrivalTime(from.Distance(result.CastPosition), delay, missileSpeed) * target.MoveSpeed * (100 - predMenu.Item("SPREDMAXRANGEIGNORE").GetValue <Slider>().Value) / 100f)
                        {
                            result.HitChance = HitChance.OutOfRange;
                        }

                        return(result);
                    }

                    if (Environment.TickCount - PathTracker.EnemyInfo[target.NetworkId].LastAATick < 300 && predMenu.Item("SPREDWINDUP").GetValue <bool>())
                    {
                        if (target.AttackCastDelay * 1000 + PathTracker.EnemyInfo[target.NetworkId].AvgOrbwalkTime + avgt - width / 2f / target.MoveSpeed >= GetArrivalTime(target.ServerPosition.To2D().Distance(from), delay, missileSpeed))
                        {
                            result.HitChance       = HitChance.High;
                            result.CastPosition    = target.ServerPosition.To2D();
                            result.UnitPosition    = result.CastPosition;
                            result.CollisionResult = Collision.GetCollisions(from, result.CastPosition, width, delay, missileSpeed);

                            //check collisions
                            if (collisionable && (result.CollisionResult.Objects.HasFlag(Collision.Flags.Minions) || result.CollisionResult.Objects.HasFlag(Collision.Flags.YasuoWall)))
                            {
                                result.HitChance = HitChance.Collision;
                            }

                            return(result);
                        }
                    }

                    //to do: find a fuking logic
                    if (avgp < 400 && movt < 100 && path.PathLength() <= avgp)
                    {
                        result.HitChance       = HitChance.High;
                        result.CastPosition    = path.Last();
                        result.UnitPosition    = result.CastPosition;
                        result.CollisionResult = Collision.GetCollisions(from, result.CastPosition, width, delay, missileSpeed);

                        //check collisions
                        if (collisionable && (result.CollisionResult.Objects.HasFlag(Collision.Flags.Minions) || result.CollisionResult.Objects.HasFlag(Collision.Flags.YasuoWall)))
                        {
                            result.HitChance = HitChance.Collision;
                        }

                        //check if target can dodge with moving backward
                        if (from.Distance(result.CastPosition) > range - GetArrivalTime(from.Distance(result.CastPosition), delay, missileSpeed) * target.MoveSpeed * (100 - predMenu.Item("SPREDMAXRANGEIGNORE").GetValue <Slider>().Value) / 100f)
                        {
                            result.HitChance = HitChance.OutOfRange;
                        }

                        return(result);
                    }
                }

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

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

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

                //check collisions
                if (collisionable && (result.CollisionResult.Objects.HasFlag(Collision.Flags.Minions) || result.CollisionResult.Objects.HasFlag(Collision.Flags.YasuoWall)))
                {
                    result.HitChance = HitChance.Collision;
                }

                //check if target can dodge with moving backward
                if (from.Distance(result.CastPosition) > range - GetArrivalTime(from.Distance(result.CastPosition), delay, missileSpeed) * target.MoveSpeed * (100 - predMenu.Item("SPREDMAXRANGEIGNORE").GetValue <Slider>().Value) / 100f)
                {
                    result.HitChance = HitChance.OutOfRange;
                }

                return(result);
            }
            finally
            {
                //check if movement changed while prediction calculations
                if (!target.GetWaypoints().SequenceEqual(path))
                {
                    result.HitChance = HitChance.Medium;
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Gets prediction result
        /// </summary>
        /// <param name="target">Target</param>
        /// <param name="width">Vector width</param>
        /// <param name="delay">Spell delay</param>
        /// <param name="vectorSpeed">Vector speed</param>
        /// <param name="range">Spell range</param>
        /// <param name="vectorLenght">Vector lenght</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="rangeCheckFrom"></param>
        /// <returns>Prediction result as <see cref="Prediction.Vector.Result"/></returns>
        public static Result GetPrediction(Obj_AI_Base target, float width, float delay, float vectorSpeed, float range, float vectorLenght, List <Vector2> path, float avgt, float movt, float avgp, Vector2 rangeCheckFrom)
        {
            Prediction.AssertInitializationMode();

            Result result = new Result();

            Vector2 immobileFrom = rangeCheckFrom + (target.ServerPosition.To2D() - rangeCheckFrom).Normalized() * range;

            if (path.Count <= 1) //if target is not moving, easy to hit
            {
                result.HitChance          = HitChance.VeryHigh;
                result.CastTargetPosition = target.ServerPosition.To2D();
                result.UnitPosition       = result.CastTargetPosition;
                result.CollisionResult    = Collision.GetCollisions(immobileFrom, result.CastTargetPosition, width, delay, vectorSpeed);


                if (immobileFrom.Distance(result.CastTargetPosition) > vectorLenght - Prediction.GetArrivalTime(immobileFrom.Distance(result.CastTargetPosition), delay, vectorSpeed) * target.MoveSpeed)
                {
                    result.HitChance = HitChance.OutOfRange;
                }

                return(result);
            }

            if (target is AIHeroClient)
            {
                if (((AIHeroClient)target).IsChannelingImportantSpell())
                {
                    result.HitChance          = HitChance.VeryHigh;
                    result.CastTargetPosition = target.ServerPosition.To2D();
                    result.UnitPosition       = result.CastTargetPosition;
                    result.CollisionResult    = Collision.GetCollisions(immobileFrom, result.CastTargetPosition, width, delay, vectorSpeed);

                    //check if target can dodge with moving backward
                    if (immobileFrom.Distance(result.CastTargetPosition) > range - Prediction.GetArrivalTime(immobileFrom.Distance(result.CastTargetPosition), delay, vectorSpeed) * target.MoveSpeed)
                    {
                        result.HitChance = HitChance.OutOfRange;
                    }

                    return(result);
                }

                //to do: find a fuking logic
                if (avgp < 400 && movt < 100)
                {
                    result.HitChance          = HitChance.High;
                    result.CastTargetPosition = target.ServerPosition.To2D();
                    result.UnitPosition       = result.CastTargetPosition;
                    result.CollisionResult    = Collision.GetCollisions(immobileFrom, result.CastTargetPosition, width, delay, vectorSpeed);

                    //check if target can dodge with moving backward
                    if (immobileFrom.Distance(result.CastTargetPosition) > range - Prediction.GetArrivalTime(immobileFrom.Distance(result.CastTargetPosition), delay, vectorSpeed) * target.MoveSpeed)
                    {
                        result.HitChance = HitChance.OutOfRange;
                    }

                    return(result);
                }
            }

            if (target.IsDashing())
            {
                return(Prediction.GetDashingPrediction(target, width, delay, vectorSpeed, range, false, SkillshotType.SkillshotLine, immobileFrom).AsVectorResult(immobileFrom));
            }

            if (SPrediction.Utility.IsImmobileTarget(target))
            {
                return(Prediction.GetImmobilePrediction(target, width, delay, vectorSpeed, range, false, SkillshotType.SkillshotLine, immobileFrom).AsVectorResult(immobileFrom));
            }

            for (int i = 0; i < path.Count - 1; i++)
            {
                Vector2           point = Geometry.ClosestCirclePoint(rangeCheckFrom, range, path[i], path[i + 1]);
                Prediction.Result res   = Prediction.WaypointAnlysis(target, width, delay, vectorSpeed, vectorLenght, false, SkillshotType.SkillshotLine, path, avgt, movt, avgp, point);
                if (res.HitChance >= HitChance.Low)
                {
                    return(res.AsVectorResult(point));
                }
            }

            result.CastSourcePosition = immobileFrom;
            result.CastTargetPosition = target.ServerPosition.To2D();
            result.HitChance          = HitChance.Impossible;
            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Gets Aoe Prediction result
        /// </summary>
        /// <param name="width">Spell width</param>
        /// <param name="delay">Spell delay</param>
        /// <param name="vectorSpeed">Vector speed</param>
        /// <param name="range">Spell range</param>
        /// <param name="vectorLenght">Vector lenght</param>
        /// <param name="rangeCheckFrom"></param>
        /// <returns>Prediction result as <see cref="Prediction.AoeResult"/></returns>
        public static AoeResult GetAoePrediction(float width, float delay, float vectorSpeed, float range, float vectorLenght, Vector2 rangeCheckFrom)
        {
            AoeResult result  = new AoeResult();
            var       enemies = HeroManager.Enemies.Where(p => p.IsValidTarget() && Prediction.GetFastUnitPosition(p, delay, 0, rangeCheckFrom).Distance(rangeCheckFrom) < range);

            foreach (AIHeroClient enemy in enemies)
            {
                List <Vector2> path = enemy.GetWaypoints();
                if (path.Count <= 1)
                {
                    Vector2          from      = rangeCheckFrom + (enemy.ServerPosition.To2D() - rangeCheckFrom).Normalized() * range;
                    Vector2          to        = from + (enemy.ServerPosition.To2D() - from).Normalized() * vectorLenght;
                    Collision.Result colResult = Collision.GetCollisions(from, to, width, delay, vectorSpeed);

                    if (colResult.Objects.HasFlag(Collision.Flags.EnemyChampions))
                    {
                        int collisionCount = colResult.Units.Count(p => p.IsEnemy && p.IsChampion());
                        if (collisionCount > result.HitCount)
                        {
                            result = new AoeResult
                            {
                                CastSourcePosition = from,
                                CastTargetPosition = enemy.ServerPosition.To2D(),
                                HitCount           = collisionCount,
                                CollisionResult    = colResult
                            };
                        }
                    }
                }
                else
                {
                    if (!enemy.IsDashing())
                    {
                        for (int i = 0; i < path.Count - 1; i++)
                        {
                            Vector2           point      = Geometry.ClosestCirclePoint(rangeCheckFrom, range, path[i], path[i + 1]);
                            Prediction.Result prediction = Prediction.GetPrediction(enemy, width, delay, vectorSpeed, vectorLenght, false, SkillshotType.SkillshotLine, path, enemy.AvgMovChangeTime(), enemy.LastMovChangeTime(), enemy.AvgPathLenght(), point, rangeCheckFrom);
                            if (prediction.HitChance > HitChance.Medium)
                            {
                                Vector2          to        = point + (prediction.CastPosition - point).Normalized() * vectorLenght;
                                Collision.Result colResult = Collision.GetCollisions(point, to, width, delay, vectorSpeed, false);
                                if (colResult.Objects.HasFlag(Collision.Flags.EnemyChampions))
                                {
                                    int collisionCount = colResult.Units.Count(p => p.IsEnemy && p.IsChampion());
                                    if (collisionCount > result.HitCount)
                                    {
                                        result = new AoeResult
                                        {
                                            CastSourcePosition = point,
                                            CastTargetPosition = prediction.CastPosition,
                                            HitCount           = collisionCount,
                                            CollisionResult    = colResult
                                        };
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(result);
        }
Exemple #5
0
 public static float AvgMovChangeTime(this AIHeroClient t)
 {
     Prediction.AssertInitializationMode();
     return(PathTracker.EnemyInfo[t.NetworkId].AvgTick + Prediction.IgnoreReactionDelay);
 }
Exemple #6
0
 public static float AvgPathLenght(this AIHeroClient t)
 {
     Prediction.AssertInitializationMode();
     return(PathTracker.EnemyInfo[t.NetworkId].AvgPathLenght);
 }
Exemple #7
0
 public static int LastMovChangeTime(this AIHeroClient t)
 {
     Prediction.AssertInitializationMode();
     return(Environment.TickCount - PathTracker.EnemyInfo[t.NetworkId].LastWaypointTick);
 }
Exemple #8
0
 public static int MovImmobileTime(this AIHeroClient t)
 {
     Prediction.AssertInitializationMode();
     return(PathTracker.EnemyInfo[t.NetworkId].IsStopped ? Environment.TickCount - PathTracker.EnemyInfo[t.NetworkId].StopTick : 0);
 }
Exemple #9
0
        /// <summary>
        /// Gets collided units & flags
        /// </summary>
        /// <param name="from">Start position</param>
        /// <param name="to">End position</param>
        /// <param name="width">Rectangle scale</param>
        /// <param name="delay">Spell delay</param>
        /// <param name="missileSpeed">Spell missile speed</param>
        /// <returns>Collision result as <see cref="Collision.Result"/></returns>
        public static Result GetCollisions(Vector2 from, Vector2 to, float width, float delay, float missileSpeed = 0, bool isArc = false)
        {
            List <Obj_AI_Base> collidedUnits = new List <Obj_AI_Base>();
            var spellHitBox = ClipperWrapper.MakePaths(ClipperWrapper.DefineRectangle(from, to, width));

            if (isArc)
            {
                spellHitBox = ClipperWrapper.MakePaths(new MidlaneSharp.Geometry.Polygon(
                                                           ClipperWrapper.DefineArc(from - new Vector2(875 / 2f, 20), to, (float)Math.PI * (to.Distance(from) / 875f), 410, 200 * (to.Distance(from) / 875f)),
                                                           ClipperWrapper.DefineArc(from - new Vector2(875 / 2f, 20), to, (float)Math.PI * (to.Distance(from) / 875f), 410, 320 * (to.Distance(from) / 875f))));
            }
            Flags _colFlags = Flags.None;

            var collidedMinions = MinionManager.GetMinions(from.Distance(to) + 250, MinionTypes.All, MinionTeam.NotAlly, MinionOrderTypes.None).AsParallel().Where(p => ClipperWrapper.IsIntersects(ClipperWrapper.MakePaths(ClipperWrapper.DefineCircle(Prediction.GetFastUnitPosition(p, delay, missileSpeed), p.BoundingRadius + 10)), spellHitBox));
            var collidedEnemies = HeroManager.Enemies.AsParallel().Where(p => ClipperWrapper.IsIntersects(ClipperWrapper.MakePaths(ClipperWrapper.DefineCircle(Prediction.GetFastUnitPosition(p, delay, missileSpeed), p.BoundingRadius)), spellHitBox));
            var collidedAllies  = HeroManager.Allies.AsParallel().Where(p => ClipperWrapper.IsIntersects(ClipperWrapper.MakePaths(ClipperWrapper.DefineCircle(Prediction.GetFastUnitPosition(p, delay, missileSpeed), p.BoundingRadius)), spellHitBox));

            if (collidedMinions != null && collidedMinions.Count() != 0)
            {
                collidedUnits.AddRange(collidedMinions);
                _colFlags |= Flags.Minions;
            }

            if (collidedEnemies != null && collidedEnemies.Count() != 0)
            {
                collidedUnits.AddRange(collidedEnemies);
                _colFlags |= Flags.EnemyChampions;
            }

            if (collidedAllies != null && collidedAllies.Count() != 0)
            {
                collidedUnits.AddRange(collidedAllies);
                _colFlags |= Flags.AllyChampions;
            }

            if (CheckWallCollision(from, to))
            {
                _colFlags |= Flags.Wall;
            }

            if (CheckYasuoWallCollision(from, to, width))
            {
                _colFlags |= Flags.YasuoWall;
            }

            return(new Result(collidedUnits, _colFlags));
        }
Exemple #10
0
        /// <summary>
        /// Checks enemy hero collisions
        /// </summary>
        /// <param name="from">Start position</param>
        /// <param name="to">End position</param>
        /// <param name="width">Rectangle scale</param>
        /// <param name="delay">Spell delay</param>
        /// <param name="missileSpeed">Spell missile speed</param>
        /// <param name="isArc">Checks collision for arc spell</param>
        /// <returns>true if collision found</returns>
        public static bool CheckAllyHeroCollision(Vector2 from, Vector2 to, float width, float delay, float missileSpeed = 0, bool isArc = false)
        {
            var spellHitBox = ClipperWrapper.MakePaths(ClipperWrapper.DefineRectangle(from, to, width));

            if (isArc)
            {
                spellHitBox = ClipperWrapper.MakePaths(new MidlaneSharp.Geometry.Polygon(
                                                           ClipperWrapper.DefineArc(from - new Vector2(875 / 2f, 20), to, (float)Math.PI * (to.Distance(from) / 875f), 410, 200 * (to.Distance(from) / 875f)),
                                                           ClipperWrapper.DefineArc(from - new Vector2(875 / 2f, 20), to, (float)Math.PI * (to.Distance(from) / 875f), 410, 320 * (to.Distance(from) / 875f))));
            }
            return(HeroManager.Allies.AsParallel().Any(p => ClipperWrapper.IsIntersects(ClipperWrapper.MakePaths(ClipperWrapper.DefineCircle(Prediction.GetFastUnitPosition(p, delay, missileSpeed), p.BoundingRadius)), spellHitBox)));
        }
Exemple #11
0
        /// <summary>
        /// Gets Aoe Prediction result
        /// </summary>
        /// <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="from">Spell casted position</param>
        /// <param name="rangeCheckFrom"></param>
        /// <returns>Prediction result as <see cref="Prediction.AoeResult"/></returns>
        public static Prediction.AoeResult GetAoePrediction(float width, float delay, float missileSpeed, float range, Vector2 from, Vector2 rangeCheckFrom)
        {
            Prediction.AoeResult result = new Prediction.AoeResult();
            result.HitCount = 0;
            var enemies = HeroManager.Enemies.Where(p => p.IsValidTarget() && Prediction.GetFastUnitPosition(p, delay, 0, from).Distance(rangeCheckFrom) < range);

            foreach (AIHeroClient enemy in enemies)
            {
                Prediction.Result prediction = GetPrediction(enemy, width, delay, missileSpeed, range, false, enemy.GetWaypoints(), enemy.AvgMovChangeTime(), enemy.LastMovChangeTime(), enemy.AvgPathLenght(), from, rangeCheckFrom);
                if (prediction.HitChance > HitChance.Medium)
                {
                    Vector2 to              = from + (prediction.CastPosition - from).Normalized() * range;
                    var     spellHitBox     = ClipperWrapper.DefineSector(from, to, width, range);
                    var     collidedEnemies = HeroManager.Enemies.AsParallel().Where(p => !ClipperWrapper.IsOutside(spellHitBox, Prediction.GetFastUnitPosition(p, delay, missileSpeed, from)));
                    int     collisionCount  = collidedEnemies.Count();
                    if (collisionCount > result.HitCount)
                    {
                        result = prediction.ToAoeResult(collisionCount, new Collision.Result(collidedEnemies.ToList <Obj_AI_Base>(), Collision.Flags.EnemyChampions));
                    }
                }
            }

            return(result);
        }