Ejemplo n.º 1
0
 public SafePathResult(bool isSafe, FoundIntersection intersection)
 {
     Intersection = intersection;
     IsSafe       = isSafe;
 }
Ejemplo n.º 2
0
 public SafePathResult(bool isSafe, FoundIntersection intersection)
 {
     Intersection = intersection;
     IsSafe = isSafe;
 }
Ejemplo n.º 3
0
        /// <summary>
        ///     Returns if the skillshot will hit the Caster if the Caster follows the path.
        /// </summary>
        public SafePathResult IsSafePath(List <Vector2> path, int timeOffset, int speed = -1, int delay = 0)
        {
            var distance = 0f;

            timeOffset += Game.Ping / 2;

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

            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.LSDistance(from),
                                (int)((distance + intersection.Point.LSDistance(from)) * 1000 / speed),
                                intersection.Point, from));
                    }
                }

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

                distance += from.LSDistance(to);
            }

            //Skillshot with missile.
            if (SpellData.Type == SkillShotType.SkillshotMissileLine ||
                SpellData.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.PointVector2.ProjectOn(Start, End).SegmentPoint;

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


                        var exitIntersection           = allIntersections[i + 1];
                        var exitIntersectionProjection =
                            exitIntersection.PointVector2.ProjectOn(Start, End).SegmentPoint;

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

                        //Missile didnt pass.
                        if (missilePosOnEnter.LSDistance(End) + 50 > enterIntersectionProjection.LSDistance(End))
                        {
                            if (missilePosOnExit.LSDistance(End) <= exitIntersectionProjection.LSDistance(End))
                            {
                                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
                    FoundIntersection exitIntersection           = allIntersections[0];
                    Vector2           exitIntersectionProjection = exitIntersection.PointVector2.ProjectOn(Start, End).SegmentPoint;

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


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

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

            var timeToExplode = (SpellData.DontAddExtraDuration ? 0 : SpellData.ExtraDuration) + SpellData.Delay +
                                (int)(1000 * Start.LSDistance(End) / SpellData.MissileSpeed) -
                                (Environment.TickCount - StartTick);


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

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

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

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