public bool DoEvade(AIHeroClient hero = null, Vector3[] desiredPath = null) { if (!EvadeEnabled || Player.Instance.IsDead) { LastEvadeResult = null; AutoPathing.StopPath(); return false; } hero = hero ?? Player.Instance; if (IsHeroInDanger(hero)) { if (LastEvadeResult != null && (!IsPointSafe(LastEvadeResult.EvadePoint) || LastEvadeResult.Expired())) { LastEvadeResult = null; } var evade = CalculateEvade(LastIssueOrderPos); if (evade.IsValid && evade.EnoughTime) { if (LastEvadeResult == null || (LastEvadeResult.EvadePoint.Distance(evade.EvadePoint, true) > 300.Pow())) { LastEvadeResult = evade; } if (IsHeroPathSafe(evade, desiredPath)) { LastEvadeResult = null; } } else { if (!evade.EnoughTime && LastEvadeResult == null && !IsHeroPathSafe(evade, desiredPath)) { return EvadeSpellManager.ProcessFlash(this); } } if (LastEvadeResult != null) { if (!hero.IsMovingTowards(LastEvadeResult.EvadePoint)) { AutoPathing.StopPath(); Player.IssueOrder(GameObjectOrder.MoveTo, LastEvadeResult.EvadePoint.To3DWorld(), false); } return true; } } else if (!IsPathSafe(hero.RealPath()) || (desiredPath != null && !IsPathSafe(desiredPath))) { var path = GetPath(hero.Position.To2D(), LastIssueOrderPos); if (path.Length > 0 && AutoPathing.Destination.Distance(path.Last(), true) > 50.Pow()) { AutoPathing.DoPath(path); } LastEvadeResult = null; return true; } else { AutoPathing.StopPath(); LastEvadeResult = null; } return false; }