Exemple #1
0
        public SafePathResult IsSafePath(GamePath 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)GameObjects.Player.MoveSpeed : speed;

            if (unit == null)
            {
                unit = GameObjects.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);
            }

            if (SpellData.Type == SkillShotType.SkillshotMissileLine || SpellData.Type == SkillShotType.SkillshotMissileCone || SpellData.Type == SkillShotType.SkillshotArc)
            {
                if (IsSafe(Common.Evade.Evade.PlayerPosition))
                {
                    if (allIntersections.Count == 0)
                    {
                        return(new SafePathResult(true, new FoundIntersection()));
                    }

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

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

                        if (i == allIntersections.Count - 1)
                        {
                            var missilePositionOnIntersection = GetMissilePosition(enterIntersection.Time - timeOffset);

                            return(new SafePathResult((End.Distance(missilePositionOnIntersection) + 50 <= End.Distance(enterIntersectionProjection)) && GameObjects.Player.MoveSpeed < SpellData.MissileSpeed, allIntersections[0]));
                        }

                        var exitIntersection           = allIntersections[i + 1];
                        var exitIntersectionProjection = exitIntersection.Point.ProjectOn(Start, End).SegmentPoint;
                        var missilePosOnEnter          = GetMissilePosition(enterIntersection.Time - timeOffset);
                        var missilePosOnExit           = GetMissilePosition(exitIntersection.Time + timeOffset);

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

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

                if (allIntersections.Count == 0)
                {
                    return(new SafePathResult(false, new FoundIntersection()));
                }

                if (allIntersections.Count > 0)
                {
                    var exitIntersection           = allIntersections[0];
                    var exitIntersectionProjection = exitIntersection.Point.ProjectOn(Start, End).SegmentPoint;
                    var missilePosOnExit           = GetMissilePosition(exitIntersection.Time + timeOffset);

                    if (missilePosOnExit.Distance(End) <= exitIntersectionProjection.Distance(End))
                    {
                        return(new SafePathResult(false, allIntersections[0]));
                    }
                }
            }

            if (IsSafe(Common.Evade.Evade.PlayerPosition))
            {
                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.Distance(End) / SpellData.MissileSpeed) - (Utils.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]));
        }