context: // Copyright 2014 - 2014 Esk0r
  // Program.cs is part of Evade.
  // 
  // Evade is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  // 
  // Evade is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  // GNU General Public License for more details.
  // 
  // You should have received a copy of the GNU General Public License
  // along with Evade. If not, see <http://www.gnu.org/licenses/>.
  
  #region
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using EvadeYas.Pathfinding;
  using LeagueSharp;
  using LeagueSharp.Common;
  using SharpDX;
  using YasuoPro;
  using Color = System.Drawing.Color;
  using GamePath = System.Collections.Generic.List<SharpDX.Vector2>;
  
  #endregion
  
  using EloBuddy; namespace EvadeYas
  {
      internal class Program
      {
          public static SpellList<Skillshot> DetectedSkillshots = new SpellList<Skillshot>();
  
          private static bool _evading;
  
          private static Vector2 _evadePoint;
  
          public static bool NoSolutionFound = false;
  
          public static Vector2 EvadeToPoint = new Vector2();
  
          private static bool _followPath = false;
  
          public static bool FollowPath
          {
              get
              {
                  return _followPath;
              }
  
              set
              {
                  _followPath = value;
                  if (!_followPath)
                  {
                      PathFollower.Stop();
                  }
              }
          }
  
          public static bool Keepfollowing { get; set; }
  
          public static int LastWardJumpAttempt = 0;
  
          public static Vector2 PreviousTickPosition = new Vector2();
          public static Vector2 PlayerPosition = new Vector2();
  
          public static string PlayerChampionName;
  
          private static readonly Random RandomN = new Random();
          private static int LastSentMovePacketT = 0;
          private static int LastSentMovePacketT2 = 0;
  
          private static int LastSMovePacketT = 0;
  
          public static bool Evading
          {
              get { return _evading; } //
              set
              {
                  if (value == true)
                  {
                      LastSentMovePacketT = 0;
                      ObjectManager.Player.SendMovePacket(EvadePoint);
                  }
  
                  if (value == false)
                  {
                      FollowPath = true;
                      Keepfollowing = true;
                  }
  
                  _evading = value;
              }
          }
  
          public static Vector2 EvadePoint
          {
              get { return _evadePoint; }
              set
              {
                  if (value.IsValid())
                  {
                      ObjectManager.Player.SendMovePacket(value);
                  }
                  _evadePoint = value;
              }
          }
  
          
          public static void Init()
          {
              PlayerChampionName = ObjectManager.Player.ChampionName;
  
              //Add the game events.
               Game.OnUpdate += Game_OnOnGameUpdate;
              //EloBuddy.Player.OnIssueOrder += ObjAiHeroOnOnIssueOrder;
              //Spellbook.OnCastSpell += Spellbook_OnCastSpell;
              //Set up the OnDetectSkillshot Event.
              SkillshotDetector.OnDetectSkillshot += OnDetectSkillshot;
              SkillshotDetector.OnDeleteMissile += SkillshotDetectorOnOnDeleteMissile;
  
              //For skillshot drawing.
              if (Helper.Debug && Helper.GetBool("Drawing.SS"))
              {
                  Drawing.OnDraw += Drawing_OnDraw;
              }
  
              //Ondash event.
              //CustomEvents.Unit.OnDash += UnitOnOnDash;
  
              DetectedSkillshots.OnAdd += DetectedSkillshots_OnAdd;
  
              //Create the menu to allow the user to change the config.
              Config.CreateMenu();
  
              Config.AttachToMenu();
  
              //Initialze the collision
              Collision.Init();
  
              //Chat.Print("Evade Loaded");
              
              if (Config.PrintSpellData)
              {
                  foreach (var hero in ObjectManager.Get<AIHeroClient>())
                  {
                      foreach (var spell in hero.Spellbook.Spells)
                      {
                   /*       Console.WriteLine(
                               "Slot  " + spell.Slot + " " + spell.SData.Name + " w:" + spell.SData.LineWidth + " s:" + spell.SData.MissileSpeed + " r: " +
                              spell.SData.CastRangeArray[0]);*/
                      }
                  }
                  Console.WriteLine(ObjectManager.Player.Spellbook.GetSpell(SpellSlot.W).Name);
              }
          }
          private static void DetectedSkillshots_OnAdd(object sender, EventArgs e)
          {
              Evading = false;
          }
  
          private static void SkillshotDetectorOnOnDeleteMissile(Skillshot skillshot, MissileClient missile)
          {
              if (skillshot.SpellData.SpellName == "VelkozQ")
              {
                  var spellData = SpellDatabase.GetByName("VelkozQSplit");
                  var direction = skillshot.Direction.Perpendicular();
                  if (DetectedSkillshots.Count(s => s.SpellData.SpellName == "VelkozQSplit") == 0)
                  {
                      for (var i = -1; i <= 1; i = i + 2)
                      {
                          var skillshotToAdd = new Skillshot(
                              DetectionType.ProcessSpell, spellData, Utils.TickCount, missile.Position.To2D(),
                              missile.Position.To2D() + i * direction * spellData.Range, skillshot.Unit);
                          DetectedSkillshots.Add(skillshotToAdd);
                      }
                  }
              }
          }
  
          private static void OnDetectSkillshot(Skillshot skillshot)
          {
              //Check if the skillshot is already added.
              var alreadyAdded = false;
  
              if (!Helper.GetBool("Evade.FOW") && !skillshot.Unit.IsVisible)
              {
                  return;
              }
                  
              foreach (var item in DetectedSkillshots)
              {
                  if (item.SpellData.SpellName == skillshot.SpellData.SpellName &&
                      (item.Unit.NetworkId == skillshot.Unit.NetworkId &&
                       (skillshot.Direction).AngleBetween(item.Direction) < 5 &&
                       (skillshot.Start.Distance(item.Start) < 100 || skillshot.SpellData.FromObjects.Length == 0)))
                  {
                      alreadyAdded = true;
                  }
              }
  
              //Check if the skillshot is from an ally.
              if (skillshot.Unit.Team == ObjectManager.Player.Team && !Config.TestOnAllies)
              {
                  return;
              }
  
              //Check if the skillshot is too far away.
              if (skillshot.Start.Distance(PlayerPosition) >
                  (skillshot.SpellData.Range + skillshot.SpellData.Radius + 1000) * 1.5)
              {
                  return;
              }
  
              //Add the skillshot to the detected skillshot list.
              if (!alreadyAdded || skillshot.SpellData.DontCheckForDuplicates)
              {
                  //Multiple skillshots like twisted fate Q.
  
gt:                 if (skillshot.DetectionType == DetectionType.ProcessSpell)