Esempio n. 1
0
        /// <summary>
        ///     Returns the missile position after time time.
        /// </summary>
        public Vector2 GlobalGetMissilePosition(int time)
        {
            var t = Math.Max(0, System.Environment.TickCount + time - StartTick - SkillshotData.Delay);

            t = (int)Math.Max(0, Math.Min(EndPosition.Distance(StartPosition), t * SkillshotData.MissileSpeed / 1000));
            return(StartPosition + Direction * t);
        }
Esempio n. 2
0
        /// <summary>
        ///     Returns if the skillshot will hit the unit if the unit follows the path.
        /// </summary>
        public SafePathResult IsSafePath(List <Vector2> path,
                                         int timeOffset,
                                         int speed        = -1,
                                         int delay        = 0,
                                         Obj_AI_Base unit = null)
        {
            var Distance = 0f;

            timeOffset += Game.Ping / 2;

            speed = (speed == -1) ? (int)ObjectManager.Player.MoveSpeed : speed;

            if (unit == null)
            {
                unit = ObjectManager.Player;
            }

            var allIntersections = new List <FoundIntersection>();

            for (var i = 0; i <= path.Count - 2; i++)
            {
                var from = path[i];
                var to   = path[i + 1];
                var segmentIntersections = new List <FoundIntersection>();

                for (var j = 0; j <= Polygon.Points.Count - 1; j++)
                {
                    var sideStart = Polygon.Points[j];
                    var sideEnd   = Polygon.Points[j == (Polygon.Points.Count - 1) ? 0 : j + 1];

                    var intersection = from.Intersection(to, sideStart,
                                                         sideEnd);

                    if (intersection.Intersects)
                    {
                        segmentIntersections.Add(
                            new FoundIntersection(
                                Distance + intersection.Point.Distance(from),
                                (int)((Distance + intersection.Point.Distance(from)) * 1000 / speed),
                                intersection.Point, from));
                    }
                }

                var sortedList = segmentIntersections.OrderBy(o => o.Distance).ToList();
                allIntersections.AddRange(sortedList);

                Distance += from.Distance(to);
            }

            //Skillshot with missile.
            if (SkillshotData.Type == SkillShotType.SkillshotMissileLine ||
                SkillshotData.Type == SkillShotType.SkillshotMissileCone)
            {
                //Outside the skillshot
                if (IsSafe(ObjectManager.Player.ServerPosition.To2D()))
                {
                    //No intersections -> Safe
                    if (allIntersections.Count == 0)
                    {
                        return(new SafePathResult(true, new FoundIntersection()));
                    }

                    for (var i = 0; i <= allIntersections.Count - 1; i = i + 2)
                    {
                        var enterIntersection           = allIntersections[i];
                        var enterIntersectionProjection = enterIntersection.Point.ProjectOn(StartPosition, EndPosition).SegmentPoint;

                        //Intersection with no exit point.
                        if (i == allIntersections.Count - 1)
                        {
                            var missilePositionOnIntersection =
                                GetMissilePosition(enterIntersection.Time - timeOffset);
                            return
                                (new SafePathResult(
                                     (EndPosition.Distance(missilePositionOnIntersection) + 50 <=
                                      EndPosition.Distance(enterIntersectionProjection)) &&
                                     ObjectManager.Player.MoveSpeed < SkillshotData.MissileSpeed, allIntersections[0]));
                        }


                        var exitIntersection           = allIntersections[i + 1];
                        var exitIntersectionProjection = exitIntersection.Point.ProjectOn(StartPosition, EndPosition).SegmentPoint;

                        var missilePosOnEnter = GetMissilePosition(enterIntersection.Time - timeOffset);
                        var missilePosOnExit  = GetMissilePosition(exitIntersection.Time + timeOffset);

                        //Missile didnt pass.
                        if (missilePosOnEnter.Distance(EndPosition) + 50 > enterIntersectionProjection.Distance(EndPosition))
                        {
                            if (missilePosOnExit.Distance(EndPosition) <= exitIntersectionProjection.Distance(EndPosition))
                            {
                                return(new SafePathResult(false, allIntersections[0]));
                            }
                        }
                    }

                    return(new SafePathResult(true, allIntersections[0]));
                }
                //Inside the skillshot.
                if (allIntersections.Count == 0)
                {
                    return(new SafePathResult(false, new FoundIntersection()));
                }

                if (allIntersections.Count > 0)
                {
                    //Check only for the exit point
                    var exitIntersection           = allIntersections[0];
                    var exitIntersectionProjection = exitIntersection.Point.ProjectOn(StartPosition, EndPosition).SegmentPoint;

                    var missilePosOnExit = GetMissilePosition(exitIntersection.Time + timeOffset);
                    if (missilePosOnExit.Distance(EndPosition) <= exitIntersectionProjection.Distance(EndPosition))
                    {
                        return(new SafePathResult(false, allIntersections[0]));
                    }
                }
            }


            if (IsSafe(ObjectManager.Player.ServerPosition.To2D()))
            {
                if (allIntersections.Count == 0)
                {
                    return(new SafePathResult(true, new FoundIntersection()));
                }

                if (SkillshotData.DontCross)
                {
                    return(new SafePathResult(false, allIntersections[0]));
                }
            }
            else
            {
                if (allIntersections.Count == 0)
                {
                    return(new SafePathResult(false, new FoundIntersection()));
                }
            }

            var timeToExplode = (SkillshotData.DontAddExtraDuration ? 0 : SkillshotData.ExtraDuration) +
                                SkillshotData.Delay +
                                (int)(1000 * StartPosition.Distance(EndPosition) / SkillshotData.MissileSpeed) -
                                (Environment.TickCount - StartTick);


            var myPositionWhenExplodes = path.PositionAfter(timeToExplode, speed, delay);

            if (!IsSafe(myPositionWhenExplodes))
            {
                return(new SafePathResult(false, allIntersections[0]));
            }

            var myPositionWhenExplodesWithOffset = path.PositionAfter(timeToExplode, speed, timeOffset);

            return(new SafePathResult(IsSafe(myPositionWhenExplodesWithOffset), allIntersections[0]));
        }