context: // --------------------------------------------------------------------------------------------------------------------
  // <copyright file="MoonDraven.cs" company="ChewyMoon">
  //   Copyright (C) 2015 ChewyMoon
  //   
  //   This program 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.
  //   
  //   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
  // </copyright>
  // <summary>
  //   The MoonDraven class.
  // </summary>
  // --------------------------------------------------------------------------------------------------------------------
  
  using EloBuddy; 
   using LeagueSharp.Common; 
   namespace MoonDraven
  {
      using System;
      using System.Collections.Generic;
      using System.Diagnostics.CodeAnalysis;
      using System.Linq;
  
      using LeagueSharp;
      using LeagueSharp.Common;
  
      using SharpDX;
  
      using Color = System.Drawing.Color;
  
      /// <summary>
      ///     The MoonDraven class.
      /// </summary>
      [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly",
          Justification = "Reviewed. Suppression is OK here.")]
      internal class MoonDraven
      {
          #region Public Properties
  
          /// <summary>
          ///     Gets or sets the e.
          /// </summary>
          /// <value>
          ///     The e.
          /// </value>
          public Spell E { get; set; }
  
          /// <summary>
          ///     Gets the mana percent.
          /// </summary>
          /// <value>
          ///     The mana percent.
          /// </value>
          public float ManaPercent
          {
              get
              {
                  return this.Player.Mana / this.Player.MaxMana * 100;
              }
          }
  
          /// <summary>
          ///     Gets or sets the menu.
          /// </summary>
          /// <value>
          ///     The menu.
          /// </value>
          public Menu Menu { get; set; }
  
          /// <summary>
          ///     Gets or sets the orbwalker.
          /// </summary>
          /// <value>
          ///     The orbwalker.
          /// </value>
          public Orbwalking.Orbwalker Orbwalker { get; set; }
  
          /// <summary>
          ///     Gets the player.
          /// </summary>
          /// <value>
          ///     The player.
          /// </value>
          public AIHeroClient Player
          {
              get
              {
                  return ObjectManager.Player;
              }
          }
  
          /// <summary>
          ///     Gets or sets the q.
          /// </summary>
          /// <value>
          ///     The q.
          /// </value>
          public Spell Q { get; set; }
  
          /// <summary>
          ///     Gets the q count.
          /// </summary>
          /// <value>
          ///     The q count.
          /// </value>
          public int QCount
          {
              get
              {
                  return (this.Player.HasBuff("dravenspinning") ? 1 : 0)
                         + (this.Player.HasBuff("dravenspinningleft") ? 1 : 0) + this.QReticles.Count;
              }
          }
  
          /// <summary>
          ///     Gets or sets the q reticles.
          /// </summary>
          /// <value>
          ///     The q reticles.
          /// </value>
          public List<QRecticle> QReticles { get; set; }
  
          /// <summary>
          ///     Gets or sets the r.
          /// </summary>
          /// <value>
          ///     The r.
          /// </value>
          public Spell R { get; set; }
  
          /// <summary>
          ///     Gets or sets the w.
          /// </summary>
          /// <value>
          ///     The w.
          /// </value>
          public Spell W { get; set; }
  
          #endregion
  
          #region Properties
  
          /// <summary>
          ///     Gets or sets the last axe move time.
          /// </summary>
          private int LastAxeMoveTime { get; set; }
  
          #endregion
  
          #region Public Methods and Operators
  
          /// <summary>
          ///     Loads this instance.
          /// </summary>
          public void Load()
          {
              // Create spells
              this.Q = new Spell(SpellSlot.Q, Orbwalking.GetRealAutoAttackRange(this.Player));
              this.W = new Spell(SpellSlot.W);
              this.E = new Spell(SpellSlot.E, 1050);
              this.R = new Spell(SpellSlot.R);
  
              this.E.SetSkillshot(0.25f, 130, 1400, false, SkillshotType.SkillshotLine);
              this.R.SetSkillshot(0.4f, 160, 2000, true, SkillshotType.SkillshotLine);
  
              this.QReticles = new List<QRecticle>();
  
              this.CreateMenu();
  
              Chat.Print("<font color=\"#7CFC00\"><b>MoonDraven:</b></font> Loaded");
  
              //Obj_AI_Base.OnNewPath += this.Obj_AI_Base_OnNewPath;
              GameObject.OnCreate += this.GameObjectOnOnCreate;
              GameObject.OnDelete += this.GameObjectOnOnDelete;
              AntiGapcloser.OnEnemyGapcloser += this.AntiGapcloserOnOnEnemyGapcloser;
              Interrupter2.OnInterruptableTarget += this.Interrupter2OnOnInterruptableTarget;
              Drawing.OnDraw += this.DrawingOnOnDraw;
              Game.OnUpdate += this.GameOnOnUpdate;
          }
  
          #endregion
  
          #region Methods
  
          /// <summary>
          ///     Called on an enemy gapcloser.
          /// </summary>
          /// <param name="gapcloser">The gapcloser.</param>
          private void AntiGapcloserOnOnEnemyGapcloser(ActiveGapcloser gapcloser)
          {
              if (!this.Menu.Item("UseEGapcloser").IsActive() || !this.E.IsReady()
                  || !gapcloser.Sender.IsValidTarget(this.E.Range))
              {
                  return;
              }
  
              this.E.Cast(gapcloser.Sender);
          }
  
          /// <summary>
          ///     Catches the axe.
          /// </summary>
          private void CatchAxe()
          {
              var catchOption = this.Menu.Item("AxeMode").GetValue<StringList>().SelectedIndex;
  
              if (((catchOption == 0 && this.Orbwalker.ActiveMode == Orbwalking.OrbwalkingMode.Combo)
                   || (catchOption == 1 && this.Orbwalker.ActiveMode != Orbwalking.OrbwalkingMode.None))
                  || catchOption == 2)
              {
                  var bestReticle =
                      this.QReticles.Where(
                          x =>
                          x.Object.Position.Distance(Game.CursorPos)
                          < this.Menu.Item("CatchAxeRange").GetValue<Slider>().Value)
                          .OrderBy(x => x.Position.Distance(this.Player.ServerPosition))
                          .ThenBy(x => x.Position.Distance(Game.CursorPos))
                          .ThenBy(x => x.ExpireTime)
                          .FirstOrDefault();
  
                  if (bestReticle != null && bestReticle.Object.Position.Distance(this.Player.ServerPosition) > 100)
                  {
                      var eta = 1000 * (this.Player.Distance(bestReticle.Position) / this.Player.MoveSpeed);
                      var expireTime = bestReticle.ExpireTime - Environment.TickCount;
  
                      if (eta >= expireTime && this.Menu.Item("UseWForQ").IsActive())
                      {
                          this.W.Cast();
                      }
  
                      if (this.Menu.Item("DontCatchUnderTurret").IsActive())
                      {
                          // If we're under the turret as well as the axe, catch the axe
                          if (this.Player.UnderTurret(true) && bestReticle.Object.Position.UnderTurret(true))
                          {
                              if (this.Orbwalker.ActiveMode == Orbwalking.OrbwalkingMode.None)
                              {
                                  EloBuddy.Player.IssueOrder(GameObjectOrder.MoveTo, bestReticle.Position);
                              }
                              else
                              {
                                  this.Orbwalker.SetOrbwalkingPoint(bestReticle.Position);
                              }
                          }
                          else if (!bestReticle.Position.UnderTurret(true))
                          {
                              if (this.Orbwalker.ActiveMode == Orbwalking.OrbwalkingMode.None)
                              {
                                  EloBuddy.Player.IssueOrder(GameObjectOrder.MoveTo, bestReticle.Position);
                              }
                              else
                              {
                                  this.Orbwalker.SetOrbwalkingPoint(bestReticle.Position);
                              }
                          }
                      }
                      else
                      {
                          if (this.Orbwalker.ActiveMode == Orbwalking.OrbwalkingMode.None)
                          {
                              EloBuddy.Player.IssueOrder(GameObjectOrder.MoveTo, bestReticle.Position);
                          }
                          else
                          {
                              this.Orbwalker.SetOrbwalkingPoint(bestReticle.Position);
                          }
                      }
                  }
                  else
                  {
                      this.Orbwalker.SetOrbwalkingPoint(Game.CursorPos);
                  }
              }
              else
              {
                  this.Orbwalker.SetOrbwalkingPoint(Game.CursorPos);
              }
          }
  
          /// <summary>
          ///     Does the combo.
          /// </summary>
          private void Combo()
          {
              var target = TargetSelector.GetTarget(this.E.Range, TargetSelector.DamageType.Physical);
  
              if (!target.IsValidTarget())
              {
                  return;
              }
  
              var useQ = this.Menu.Item("UseQCombo").IsActive();
              var useW = this.Menu.Item("UseWCombo").IsActive();
              var useE = this.Menu.Item("UseECombo").IsActive();
              var useR = this.Menu.Item("UseRCombo").IsActive();
  
              if (useQ && this.QCount < this.Menu.Item("MaxAxes").GetValue<Slider>().Value - 1 && this.Q.IsReady()
                  && this.Orbwalker.InAutoAttackRange(target) && !this.Player.Spellbook.IsAutoAttacking)
              {
                  this.Q.Cast();
              }
  
              if (useW && this.W.IsReady()
                  && this.ManaPercent > this.Menu.Item("UseWManaPercent").GetValue<Slider>().Value)
              {
                  if (this.Menu.Item("UseWSetting").IsActive())
                  {
                      this.W.Cast();
                  }
                  else
                  {
                      if (!this.Player.HasBuff("dravenfurybuff"))
                      {
                          this.W.Cast();
                      }
                  }
              }
  
              if (useE && this.E.IsReady())
              {
                  this.E.Cast(target);
              }
  
              if (!useR || !this.R.IsReady())
              {
                  return;
              }
  
              // Patented Advanced Algorithms D321987
              var killableTarget = HeroManager.Enemies.Where(x => x.IsValidTarget(2000)).FirstOrDefault(x => this.Player.GetSpellDamage(x, SpellSlot.R) * 2 > x.Health);
  
              if (killableTarget != null)
              {
                  this.R.Cast(killableTarget);
              }
          }
  
          /// <summary>
          ///     Creates the menu.
          /// </summary>
          private void CreateMenu()
          {
              this.Menu = new Menu("MoonDraven", "cmMoonDraven", true);
  
              // Target Selector
              var tsMenu = new Menu("Target Selector", "ts");
              TargetSelector.AddToMenu(tsMenu);
              this.Menu.AddSubMenu(tsMenu);
  
              // Orbwalker
              var orbwalkMenu = new Menu("Orbwalker", "orbwalker");
              this.Orbwalker = new Orbwalking.Orbwalker(orbwalkMenu);
              this.Menu.AddSubMenu(orbwalkMenu);
  
              // Combo
              var comboMenu = new Menu("Combo", "combo");
              comboMenu.AddItem(new MenuItem("UseQCombo", "Use Q").SetValue(true));
              comboMenu.AddItem(new MenuItem("UseWCombo", "Use W").SetValue(true));
              comboMenu.AddItem(new MenuItem("UseECombo", "Use E").SetValue(true));
              comboMenu.AddItem(new MenuItem("UseRCombo", "Use R").SetValue(true));
              this.Menu.AddSubMenu(comboMenu);
  
              // Harass
  
gt:             var harassMenu = new Menu("Harass", "harass");