/// Returns the posible evade points. public static List <Vector2> GetEvadePoints(int speed = -1, int delay = 0, bool isBlink = false, bool onlyGood = false) { speed = speed == -1 ? (int)ObjectManager.Player.MoveSpeed : speed; var goodCandidates = new List <Vector2>(); var badCandidates = new List <Vector2>(); var polygonList = new List <Geometry.Polygon>(); var takeClosestPath = false; foreach (var skillshot in Program.DetectedSkillshots) { if (skillshot.Evade()) { if (skillshot.SpellData.TakeClosestPath && skillshot.IsDanger(Program.PlayerPosition)) { takeClosestPath = true; } polygonList.Add(skillshot.EvadePolygon); } } //Create the danger polygon: var dangerPolygons = Geometry.ClipPolygons(polygonList).ToPolygons(); var myPosition = Program.PlayerPosition; //Scan the sides of each polygon to find the safe point. foreach (var poly in dangerPolygons) { for (var i = 0; i <= poly.Points.Count - 1; i++) { var sideStart = poly.Points[i]; var sideEnd = poly.Points[(i == poly.Points.Count - 1) ? 0 : i + 1]; var originalCandidate = myPosition.ProjectOn(sideStart, sideEnd).SegmentPoint; var distanceToEvadePoint = Vector2.DistanceSquared(originalCandidate, myPosition); if (distanceToEvadePoint < 600 * 600) { var sideDistance = Vector2.DistanceSquared(sideEnd, sideStart); var direction = (sideEnd - sideStart).Normalized(); var s = (distanceToEvadePoint < 200 * 200 && sideDistance > 90 * 90) ? Config.DiagonalEvadePointsCount : 0; for (var j = -s; j <= s; j++) { //bool foundWall; var candidate = (originalCandidate + j * Config.DiagonalEvadePointsStep * direction) /*.CutVectorWall(myPosition, out foundWall)*/; var pathToPoint = Orbwalking.GetPath(candidate.To3D()).To2DList(); if (!isBlink) { if (Program.IsSafePath(pathToPoint, Config.EvadingFirstTimeOffset, speed, delay).IsSafe) { goodCandidates.Add(candidate); } if (Program.IsSafePath(pathToPoint, Config.EvadingSecondTimeOffset, speed, delay).IsSafe&& j == 0) { badCandidates.Add(candidate); } } else { if (Program.IsSafeToBlink(pathToPoint[pathToPoint.Count - 1], Config.EvadingFirstTimeOffset, delay)) { goodCandidates.Add(candidate); } if (Program.IsSafeToBlink(pathToPoint[pathToPoint.Count - 1], Config.EvadingSecondTimeOffset, delay)) { badCandidates.Add(candidate); } } } } } } if (takeClosestPath) { if (goodCandidates.Count > 0) { goodCandidates = new List <Vector2> { goodCandidates.MinOrDefault(vector2 => ObjectManager.Player.Distance(vector2, true)) } } ; if (badCandidates.Count > 0) { badCandidates = new List <Vector2> { badCandidates.MinOrDefault(vector2 => ObjectManager.Player.Distance(vector2, true)) } } ; } return((goodCandidates.Count > 0) ? goodCandidates : (onlyGood ? new List <Vector2>() : badCandidates)); }