public static PositionInfo GetBestPosition() { var posChecked = 0; var maxPosToCheck = 50; var posRadius = 50; var radiusIndex = 0; var extraDelayBuffer = ObjectCache.MenuCache.Cache["ExtraPingBuffer"].As <MenuSlider>().Value; var extraEvadeDistance = ObjectCache.MenuCache.Cache["ExtraEvadeDistance"].As <MenuSlider>().Value; SpellDetector.UpdateSpells(); CalculateEvadeTime(); if (ObjectCache.MenuCache.Cache["CalculateWindupDelay"].Enabled) { var extraWindupDelay = Evade.LastWindupTime - Environment.TickCount; if (extraWindupDelay > 0) { extraDelayBuffer += (int)extraWindupDelay; } } extraDelayBuffer += (int)Evade.AvgCalculationTime; if (ObjectCache.MenuCache.Cache["HigherPrecision"].Enabled) { maxPosToCheck = 150; posRadius = 25; } var heroPoint = ObjectCache.MyHeroCache.ServerPos2D; var lastMovePos = Game.CursorPos.To2D(); var lowestEvadeTime = SpellDetector.GetLowestEvadeTime(out var lowestEvadeTimeSpell); var fastestPositions = GetFastestPositions(); var posTable = fastestPositions.Select(pos => InitPositionInfo(pos, extraDelayBuffer, extraEvadeDistance, lastMovePos, lowestEvadeTimeSpell)).ToList(); while (posChecked < maxPosToCheck) { radiusIndex++; var curRadius = radiusIndex * 2 * posRadius; var curCircleChecks = (int)Math.Ceiling(2 * Math.PI * curRadius / (2 * (double)posRadius)); for (var i = 1; i < curCircleChecks; i++) { posChecked++; var cRadians = 2 * Math.PI / (curCircleChecks - 1) * i; //check decimals var pos = new Vector2((float)Math.Floor(heroPoint.X + curRadius * Math.Cos(cRadians)), (float)Math.Floor(heroPoint.Y + curRadius * Math.Sin(cRadians))); posTable.Add(InitPositionInfo(pos, extraDelayBuffer, extraEvadeDistance, lastMovePos, lowestEvadeTimeSpell)); } } IOrderedEnumerable <PositionInfo> sortedPosTable; if (ObjectCache.MenuCache.Cache["EvadeMode"].As <MenuList>().SelectedItem == "Fastest") { sortedPosTable = posTable.OrderBy(p => p.IsDangerousPos).ThenByDescending(p => p.IntersectionTime).ThenBy(p => p.PosDangerLevel).ThenBy(p => p.PosDangerCount); FastEvadeMode = true; } else if (FastEvadeMode) { sortedPosTable = posTable.OrderBy(p => p.IsDangerousPos).ThenByDescending(p => p.IntersectionTime).ThenBy(p => p.PosDangerLevel).ThenBy(p => p.PosDangerCount); } else if (ObjectCache.MenuCache.Cache["FastEvadeActivationTime"].As <MenuSlider>().Value > 0 && ObjectCache.MenuCache.Cache["FastEvadeActivationTime"].As <MenuSlider>().Value + ObjectCache.GamePing + extraDelayBuffer > lowestEvadeTime) { sortedPosTable = posTable.OrderBy(p => p.IsDangerousPos).ThenByDescending(p => p.IntersectionTime).ThenBy(p => p.PosDangerLevel).ThenBy(p => p.PosDangerCount); FastEvadeMode = true; } else { sortedPosTable = posTable.OrderBy(p => p.RejectPosition).ThenBy(p => p.PosDangerLevel).ThenBy(p => p.PosDangerCount).ThenBy(p => p.DistanceToMouse); if (sortedPosTable.First().PosDangerCount != 0) //if can't dodge smoothly, dodge fast { var sortedPosTableFastest = posTable.OrderBy(p => p.IsDangerousPos).ThenByDescending(p => p.IntersectionTime).ThenBy(p => p.PosDangerLevel).ThenBy(p => p.PosDangerCount); if (sortedPosTableFastest.First().PosDangerCount == 0) { sortedPosTable = sortedPosTableFastest; FastEvadeMode = true; } } } foreach (var posInfo in sortedPosTable) { if (CheckPathCollision(MyHero, posInfo.Position)) { continue; } if (FastEvadeMode) { posInfo.Position = GetExtendedSafePosition(ObjectCache.MyHeroCache.ServerPos2D, posInfo.Position, extraEvadeDistance); return(CanHeroWalkToPos(posInfo.Position, ObjectCache.MyHeroCache.MoveSpeed, ObjectCache.GamePing, 0)); } if (!PositionInfoStillValid(posInfo)) { continue; } if (posInfo.Position.CheckDangerousPos(extraEvadeDistance)) //extra evade distance, no multiple skillshots { posInfo.Position = GetExtendedSafePosition(ObjectCache.MyHeroCache.ServerPos2D, posInfo.Position, extraEvadeDistance); } return(posInfo); } return(PositionInfo.SetAllUndodgeable()); }