context: #region License
  
  /*
   Copyright 2014 - 2015 Nikita Bernthaler
   Varus.cs is part of SFXChallenger.
  
   SFXChallenger 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.
  
   SFXChallenger 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 SFXChallenger. If not, see <http://www.gnu.org/licenses/>.
  */
  
  #endregion License
  
  #region
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using LeagueSharp;
  using LeagueSharp.Common;
  using SFXChallenger.Abstracts;
  using SFXChallenger.Args;
  using SFXChallenger.Enumerations;
  using SFXChallenger.Helpers;
  using SFXChallenger.Library;
  using SFXChallenger.Library.Logger;
  using SFXChallenger.Managers;
  using SharpDX;
  using Collision = LeagueSharp.Common.Collision;
  using Color = System.Drawing.Color;
  using MinionManager = SFXChallenger.Library.MinionManager;
  using MinionOrderTypes = SFXChallenger.Library.MinionOrderTypes;
  using MinionTeam = SFXChallenger.Library.MinionTeam;
  using MinionTypes = SFXChallenger.Library.MinionTypes;
  
  using Spell = SFXChallenger.Wrappers.Spell;
  using TargetSelector = SFXChallenger.SFXTargetSelector.TargetSelector;
  using Utils = SFXChallenger.Helpers.Utils;
  
  #endregion
  
  using EloBuddy; namespace SFXChallenger.Champions
  {
      internal class Varus : Abstracts.Champion
      {
          private float _lastLaneClearQStart;
          private float _rSpreadRadius = 450f;
          private MenuItem _wStacks;
  
          protected override ItemFlags ItemFlags
          {
              get { return ItemFlags.Offensive | ItemFlags.Defensive | ItemFlags.Flee; }
          }
  
          protected override ItemUsageType ItemUsage
          {
              get { return ItemUsageType.AfterAttack; }
          }
  
          protected override void OnLoad()
          {
              GapcloserManager.OnGapcloser += OnEnemyGapcloser;
              Drawing.OnDraw += OnDrawingDraw;
          }
  
          protected override void SetupSpells()
          {
              Q = new Spell(SpellSlot.Q, 925f);
              Q.SetSkillshot(0.25f, 70f, 1800f, false, SkillshotType.SkillshotLine);
              Q.SetCharged(925, 1700, 1.5f);
  
              W = new Spell(SpellSlot.W, 0f, DamageType.Magical);
  
              E = new Spell(SpellSlot.E, 950f);
              E.SetSkillshot(0.25f, 250f, 1500f, false, SkillshotType.SkillshotCircle);
  
              R = new Spell(SpellSlot.R, 1075f);
              R.SetSkillshot(0.25f, 120f, 1950f, false, SkillshotType.SkillshotLine);
  
              Ultimate = new UltimateManager
              {
                  Combo = true,
                  Assisted = true,
                  Auto = true,
                  Flash = false,
                  Required = true,
                  Force = true,
                  Gapcloser = true,
                  GapcloserDelay = false,
                  Interrupt = false,
                  InterruptDelay = false,
                  Spells = Spells,
                  DamageCalculation =
                      (hero, resMulti, rangeCheck) =>
                          CalcComboDamage(
                              hero, resMulti, rangeCheck, Menu.Item(Menu.Name + ".combo.q").GetValue<bool>(),
                              Menu.Item(Menu.Name + ".combo.e").GetValue<bool>(), true)
              };
          }
  
          protected override void AddToMenu()
          {
              var ultimateMenu = Ultimate.AddToMenu(Menu);
  
              ultimateMenu.AddItem(
                  new MenuItem(ultimateMenu.Name + ".range", "Range").SetValue(new Slider((int) R.Range, 500, 1200)))
                  .ValueChanged +=
                  delegate(object sender, OnValueChangeEventArgs args) { R.Range = args.GetNewValue<Slider>().Value; };
  
              R.Range = Menu.Item(ultimateMenu.Name + ".range").GetValue<Slider>().Value;
  
              ultimateMenu.AddItem(
                  new MenuItem(ultimateMenu.Name + ".radius", "Spread Radius").SetValue(new Slider(450, 100, 600)))
                  .ValueChanged +=
                  delegate(object sender, OnValueChangeEventArgs args)
                  {
                      _rSpreadRadius = args.GetNewValue<Slider>().Value;
                  };
  
              _rSpreadRadius = Menu.Item(Menu.Name + ".ultimate.radius").GetValue<Slider>().Value;
  
              var comboMenu = Menu.AddSubMenu(new Menu("Combo", Menu.Name + ".combo"));
              HitchanceManager.AddToMenu(
                  comboMenu.AddSubMenu(new Menu("Hitchance", comboMenu.Name + ".hitchance")), "combo",
                  new Dictionary<string, HitChance>
                  {
                      { "Q", HitChance.VeryHigh },
                      { "E", HitChance.High },
                      { "R", HitChance.VeryHigh }
                  });
  
              var comboQMenu = comboMenu.AddSubMenu(new Menu("Q Settings", comboMenu.Name + ".q-settings"));
              comboQMenu.AddItem(new MenuItem(comboQMenu.Name + ".always", "Cast Always").SetValue(true));
              comboQMenu.AddItem(
                  new MenuItem(comboQMenu.Name + ".fast-cast-min", "Fast Cast Health <= %").SetValue(new Slider(20)));
              comboQMenu.AddItem(new MenuItem(comboQMenu.Name + ".separator", string.Empty));
              comboQMenu.AddItem(new MenuItem(comboQMenu.Name + ".stacks", "Min. Stacks")).SetValue(new Slider(3, 1, 3));
              comboQMenu.AddItem(new MenuItem(comboQMenu.Name + ".or", "OR"));
              comboQMenu.AddItem(new MenuItem(comboQMenu.Name + ".min", "Min. Hits").SetValue(new Slider(2, 1, 5)));
  
              var comboEMenu = comboMenu.AddSubMenu(new Menu("E Settings", comboMenu.Name + ".e-settings"));
              comboEMenu.AddItem(new MenuItem(comboEMenu.Name + ".always", "Cast Always").SetValue(false));
              comboEMenu.AddItem(new MenuItem(comboEMenu.Name + ".separator", string.Empty));
              comboEMenu.AddItem(new MenuItem(comboEMenu.Name + ".stacks", "Min. Stacks")).SetValue(new Slider(3, 1, 3));
              comboEMenu.AddItem(new MenuItem(comboEMenu.Name + ".or", "OR"));
              comboEMenu.AddItem(new MenuItem(comboEMenu.Name + ".min", "Min. Hits").SetValue(new Slider(3, 1, 5)));
  
              comboMenu.AddItem(new MenuItem(comboMenu.Name + ".q", "Use Q").SetValue(true));
              comboMenu.AddItem(new MenuItem(comboMenu.Name + ".e", "Use E").SetValue(true));
  
              var harassMenu = Menu.AddSubMenu(new Menu("Harass", Menu.Name + ".harass"));
              HitchanceManager.AddToMenu(
                  harassMenu.AddSubMenu(new Menu("Hitchance", harassMenu.Name + ".hitchance")), "harass",
                  new Dictionary<string, HitChance> { { "Q", HitChance.High }, { "E", HitChance.High } });
              ResourceManager.AddToMenu(
                  harassMenu,
                  new ResourceManagerArgs(
                      "harass", ResourceType.Mana, ResourceValueType.Percent, ResourceCheckType.Minimum)
                  {
                      DefaultValue = 30
                  });
  
              var harassQMenu = harassMenu.AddSubMenu(new Menu("Q Settings", harassMenu.Name + ".q-settings"));
              harassQMenu.AddItem(new MenuItem(harassQMenu.Name + ".always", "Cast Always").SetValue(true));
              harassQMenu.AddItem(
                  new MenuItem(harassQMenu.Name + ".fast-cast-min", "Fast Cast Health <= %").SetValue(new Slider(25)));
              harassQMenu.AddItem(new MenuItem(harassQMenu.Name + ".separator", string.Empty));
              harassQMenu.AddItem(new MenuItem(harassQMenu.Name + ".stacks", "Min. Stacks")).SetValue(new Slider(3, 1, 3));
              harassQMenu.AddItem(new MenuItem(harassQMenu.Name + ".or", "OR"));
              harassQMenu.AddItem(new MenuItem(harassQMenu.Name + ".min", "Min. Hits").SetValue(new Slider(2, 1, 5)));
  
              var harassEMenu = harassMenu.AddSubMenu(new Menu("E Settings", harassMenu.Name + ".e-settings"));
              harassEMenu.AddItem(new MenuItem(harassEMenu.Name + ".always", "Cast Always").SetValue(true));
              harassEMenu.AddItem(new MenuItem(harassEMenu.Name + ".separator", string.Empty));
              harassEMenu.AddItem(new MenuItem(harassEMenu.Name + ".stacks", "Min. Stacks")).SetValue(new Slider(2, 1, 3));
              harassEMenu.AddItem(new MenuItem(harassEMenu.Name + ".or", "OR"));
              harassEMenu.AddItem(new MenuItem(harassEMenu.Name + ".min", "Min. Hits").SetValue(new Slider(3, 1, 5)));
  
              harassMenu.AddItem(new MenuItem(harassMenu.Name + ".q", "Use Q").SetValue(true));
              harassMenu.AddItem(new MenuItem(harassMenu.Name + ".e", "Use E").SetValue(true));
  
              var laneClearMenu = Menu.AddSubMenu(new Menu("Lane Clear", Menu.Name + ".lane-clear"));
              ResourceManager.AddToMenu(
                  laneClearMenu,
                  new ResourceManagerArgs(
                      "lane-clear-q", ResourceType.Mana, ResourceValueType.Percent, ResourceCheckType.Minimum)
                  {
                      Prefix = "Q",
                      Advanced = true,
                      LevelRanges = new SortedList<int, int> { { 1, 6 }, { 6, 12 }, { 12, 18 } },
                      DefaultValues = new List<int> { 50, 30, 30 }
                  });
              ResourceManager.AddToMenu(
                  laneClearMenu,
                  new ResourceManagerArgs(
                      "lane-clear-e", ResourceType.Mana, ResourceValueType.Percent, ResourceCheckType.Minimum)
                  {
                      Prefix = "E",
                      Advanced = true,
                      LevelRanges = new SortedList<int, int> { { 1, 6 }, { 6, 12 }, { 12, 18 } },
                      DefaultValues = new List<int> { 50, 30, 30 }
                  });
              laneClearMenu.AddItem(new MenuItem(laneClearMenu.Name + ".q", "Use Q").SetValue(true));
              laneClearMenu.AddItem(new MenuItem(laneClearMenu.Name + ".e", "Use E").SetValue(true));
              laneClearMenu.AddItem(new MenuItem(laneClearMenu.Name + ".min", "Min. Hits").SetValue(new Slider(3, 1, 5)));
  
              var jungleClearMenu = Menu.AddSubMenu(new Menu("Jungle Clear", Menu.Name + ".jungle-clear"));
              ResourceManager.AddToMenu(
                  jungleClearMenu,
                  new ResourceManagerArgs(
                      "jungle-clear-q", ResourceType.Mana, ResourceValueType.Percent, ResourceCheckType.Minimum)
                  {
                      Prefix = "Q",
                      Advanced = true,
                      LevelRanges = new SortedList<int, int> { { 1, 6 }, { 6, 12 }, { 12, 18 } },
                      DefaultValues = new List<int> { 30, 10, 10 }
                  });
              ResourceManager.AddToMenu(
                  jungleClearMenu,
                  new ResourceManagerArgs(
                      "jungle-clear-e", ResourceType.Mana, ResourceValueType.Percent, ResourceCheckType.Minimum)
                  {
                      Prefix = "E",
                      Advanced = true,
                      LevelRanges = new SortedList<int, int> { { 1, 6 }, { 6, 12 }, { 12, 18 } },
                      DefaultValues = new List<int> { 30, 10, 10 }
                  });
              jungleClearMenu.AddItem(new MenuItem(jungleClearMenu.Name + ".q", "Use Q").SetValue(true));
              jungleClearMenu.AddItem(new MenuItem(jungleClearMenu.Name + ".e", "Use E").SetValue(true));
  
              var fleeMenu = Menu.AddSubMenu(new Menu("Flee", Menu.Name + ".flee"));
              fleeMenu.AddItem(new MenuItem(fleeMenu.Name + ".e", "Use E").SetValue(true));
  
              var killstealMenu = Menu.AddSubMenu(new Menu("Killsteal", Menu.Name + ".killsteal"));
              killstealMenu.AddItem(new MenuItem(killstealMenu.Name + ".q", "Use Q").SetValue(true));
  
              var miscMenu = Menu.AddSubMenu(new Menu("Misc", Menu.Name + ".miscellaneous"));
  
              var eGapcloserMenu = miscMenu.AddSubMenu(new Menu("E Gapcloser", miscMenu.Name + "e-gapcloser"));
              GapcloserManager.AddToMenu(
                  eGapcloserMenu,
                  new HeroListManagerArgs("e-gapcloser")
                  {
                      IsWhitelist = false,
                      Allies = false,
                      Enemies = true,
                      DefaultValue = false
                  }, true);
              BestTargetOnlyManager.AddToMenu(eGapcloserMenu, "e-gapcloser");
  
              TargetSelector.Weights.Register(
                  new TargetSelector.Weights.Item(
                      "w-stacks", "W Stacks", 5, false, t => GetWStacks(t), "High amount of W Stacks = Higher Weight"));
  
              IndicatorManager.AddToMenu(DrawingManager.Menu, true);
              IndicatorManager.Add("Q", hero => Q.IsReady() ? Q.GetDamage(hero, 1) : 0);
              IndicatorManager.Add(E);
              IndicatorManager.Add(R);
              IndicatorManager.Finale();
  
              _wStacks = DrawingManager.Add("W Stacks", true);
          }
  
          protected override void OnPreUpdate() {}
  
          protected override void OnPostUpdate()
          {
              Orbwalker.SetAttack(!Q.IsCharging);
              if (Ultimate.IsActive(UltimateModeType.Assisted) && R.IsReady())
              {
                  if (Ultimate.ShouldMove(UltimateModeType.Assisted))
                  {
                      Orbwalking.MoveTo(Game.CursorPos);
                  }
  
                  if (!RLogic(UltimateModeType.Assisted, R.GetHitChance("combo"), TargetSelector.GetTarget(R)))
                  {
                      RLogicSingle(UltimateModeType.Assisted, R.GetHitChance("combo"));
                  }
              }
  
              if (Ultimate.IsActive(UltimateModeType.Auto) && R.IsReady())
              {
                  if (!RLogic(UltimateModeType.Auto, R.GetHitChance("combo"), TargetSelector.GetTarget(R)))
                  {
                      RLogicSingle(UltimateModeType.Auto, R.GetHitChance("combo"));
                  }
              }
          }
  
          private void OnEnemyGapcloser(object sender, GapcloserManagerArgs args)
          {
              try
              {
                  if (args.UniqueId.Equals("e-gapcloser") && E.IsReady() &&
                      BestTargetOnlyManager.Check("e-gapcloser", E, args.Hero))
                  {
                      if (args.End.Distance(Player.Position) <= E.Range)
                      {
                          E.Cast(args.End);
                      }
                  }
                  if (string.IsNullOrEmpty(args.UniqueId))
                  {
                      if (Ultimate.IsActive(UltimateModeType.Gapcloser, args.Hero) &&
                          BestTargetOnlyManager.Check("r-gapcloser", R, args.Hero))
                      {
                          RLogic(UltimateModeType.Gapcloser, HitChance.High, args.Hero);
                      }
                  }
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
          }
  
          protected override void Combo()
          {
              var q = Menu.Item(Menu.Name + ".combo.q").GetValue<bool>();
              var e = Menu.Item(Menu.Name + ".combo.e").GetValue<bool>();
              var r = Ultimate.IsActive(UltimateModeType.Combo);
  
              if (e && !Q.IsCharging && E.IsReady())
              {
                  var target = TargetSelector.GetTarget(E);
                  if (target != null)
                  {
                      var stacks = W.Level == 0 &&
                                   Menu.Item(Menu.Name + ".combo.e-settings.stacks").GetValue<Slider>().Value > 0;
                      if (Menu.Item(Menu.Name + ".combo.e-settings.always").GetValue<bool>() || stacks ||
                          GetWStacks(target) >= Menu.Item(Menu.Name + ".combo.e-settings.stacks").GetValue<Slider>().Value ||
                          E.IsKillable(target) ||
                          CPrediction.Circle(E, target, E.GetHitChance("combo")).TotalHits >=
                          Menu.Item(Menu.Name + ".combo.e-settings.min").GetValue<Slider>().Value)
                      {
                          ELogic(target, E.GetHitChance("combo"));
                      }
                  }
              }
  
gt:             if (q && Q.IsReady())