--[[
          _____                    _____                    _____                _____                    _____                    _____          
         /\    \                  /\    \                  /\    \              /\    \                  /\    \                  /\    \         
        /::\____\                /::\    \                /::\____\            /::\    \                /::\    \                /::\    \        
       /:::/    /               /::::\    \              /::::|   |            \:::\    \              /::::\    \               \:::\    \       
      /:::/    /               /::::::\    \            /:::::|   |             \:::\    \            /::::::\    \               \:::\    \      
     /:::/    /               /:::/\:::\    \          /::::::|   |              \:::\    \          /:::/\:::\    \               \:::\    \     
    /:::/____/               /:::/__\:::\    \        /:::/|::|   |               \:::\    \        /:::/__\:::\    \               \:::\    \    
   /::::\    \              /::::\   \:::\    \      /:::/ |::|   |               /::::\    \      /::::\   \:::\    \              /::::\    \   
  /::::::\    \   _____    /::::::\   \:::\    \    /:::/  |::|   | _____        /::::::\    \    /::::::\   \:::\    \    ____    /::::::\    \  
 /:::/\:::\    \ /\    \  /:::/\:::\   \:::\    \  /:::/   |::|   |/\    \      /:::/\:::\    \  /:::/\:::\   \:::\    \  /\   \  /:::/\:::\    \ 
/:::/  \:::\    /::\____\/:::/__\:::\   \:::\____\/:: /    |::|   /::\____\    /:::/  \:::\____\/:::/  \:::\   \:::\____\/::\   \/:::/  \:::\____\
\::/    \:::\  /:::/    /\:::\   \:::\   \::/    /\::/    /|::|  /:::/    /   /:::/    \::/    /\::/    \:::\  /:::/    /\:::\  /:::/    \::/    /
 \/____/ \:::\/:::/    /  \:::\   \:::\   \/____/  \/____/ |::| /:::/    /   /:::/    / \/____/  \/____/ \:::\/:::/    /  \:::\/:::/    / \/____/ 
          \::::::/    /    \:::\   \:::\    \              |::|/:::/    /   /:::/    /                    \::::::/    /    \::::::/    /          
           \::::/    /      \:::\   \:::\____\             |::::::/    /   /:::/    /                      \::::/    /      \::::/____/           
           /:::/    /        \:::\   \::/    /             |:::::/    /    \::/    /                       /:::/    /        \:::\    \           
          /:::/    /          \:::\   \/____/              |::::/    /      \/____/                       /:::/    /          \:::\    \          
         /:::/    /            \:::\    \                  /:::/    /                                    /:::/    /            \:::\    \         
        /:::/    /              \:::\____\                /:::/    /                                    /:::/    /              \:::\____\        
        \::/    /                \::/    /                \::/    /                                     \::/    /                \::/    /        
         \/____/                  \/____/                  \/____/                                       \/____/                  \/____/         
                                                                                                                                                  
          _____                    _____                    _____                    _____                    _____            _____              
         /\    \                  /\    \                  /\    \                  /\    \                  /\    \          /\    \             
        /::\    \                /::\____\                /::\____\                /::\    \                /::\____\        /::\    \            
       /::::\    \              /:::/    /               /::::|   |               /::::\    \              /:::/    /       /::::\    \           
      /::::::\    \            /:::/    /               /:::::|   |              /::::::\    \            /:::/    /       /::::::\    \          
     /:::/\:::\    \          /:::/    /               /::::::|   |             /:::/\:::\    \          /:::/    /       /:::/\:::\    \         
    /:::/__\:::\    \        /:::/    /               /:::/|::|   |            /:::/  \:::\    \        /:::/    /       /:::/__\:::\    \        
   /::::\   \:::\    \      /:::/    /               /:::/ |::|   |           /:::/    \:::\    \      /:::/    /       /::::\   \:::\    \       
  /::::::\   \:::\    \    /:::/    /      _____    /:::/  |::|   | _____    /:::/    / \:::\    \    /:::/    /       /::::::\   \:::\    \      
 /:::/\:::\   \:::\ ___\  /:::/____/      /\    \  /:::/   |::|   |/\    \  /:::/    /   \:::\ ___\  /:::/    /       /:::/\:::\   \:::\    \     
/:::/__\:::\   \:::|    ||:::|    /      /::\____\/:: /    |::|   /::\____\/:::/____/     \:::|    |/:::/____/       /:::/__\:::\   \:::\____\    
\:::\   \:::\  /:::|____||:::|____\     /:::/    /\::/    /|::|  /:::/    /\:::\    \     /:::|____|\:::\    \       \:::\   \:::\   \::/    /    
 \:::\   \:::\/:::/    /  \:::\    \   /:::/    /  \/____/ |::| /:::/    /  \:::\    \   /:::/    /  \:::\    \       \:::\   \:::\   \/____/     
  \:::\   \::::::/    /    \:::\    \ /:::/    /           |::|/:::/    /    \:::\    \ /:::/    /    \:::\    \       \:::\   \:::\    \         
   \:::\   \::::/    /      \:::\    /:::/    /            |::::::/    /      \:::\    /:::/    /      \:::\    \       \:::\   \:::\____\        
    \:::\  /:::/    /        \:::\__/:::/    /             |:::::/    /        \:::\  /:::/    /        \:::\    \       \:::\   \::/    /        
     \:::\/:::/    /          \::::::::/    /              |::::/    /          \:::\/:::/    /          \:::\    \       \:::\   \/____/         
      \::::::/    /            \::::::/    /               /:::/    /            \::::::/    /            \:::\    \       \:::\    \             
       \::::/    /              \::::/    /               /:::/    /              \::::/    /              \:::\____\       \:::\____\            
        \::/____/                \::/____/                \::/    /                \::/____/                \::/    /        \::/    /            
         ~~                       ~~                       \/____/                  ~~                       \/____/          \/____/             
                                                                                                                                                  
--]]
--ver. 0.61
if myHero.charName ~= "Renekton" and myHero.charName ~= "JarvanIV" and myHero.charName ~= "Talon" and myHero.charName ~= "Olaf" and myHero.charName ~= "Heimerdinger" 
 and myHero.charName ~= "Nocturne" then
  return
end

local version = "0.61"
local LocalVersion = 0.61
local scriptname = "Hentai Bundle"
local developer = "remembermyhentai"
local contact = "skype xd_kikass"

local ATTACKED = false

local FONTAN = false
local lowBase = {["x"] = 406, ["z"] = 424}
local upBase = {["x"] = 14322, ["z"] = 14394}
local REGEN = false
local POTS = {"ItemCrystalFlask", "RegenerationPotion", "ItemMiniRegenPotion", "ItemCrystalFlaskJungle", "ItemDarkCrystalFlask"}
local YOLO = {}

SUPRESSED = false
SUPR_BUFF = ""
buff_count = 0
buff_list = {}

function CheckFountain()
  if not GetGame().map.index == 15 then return end
  if myHero.team == 100 then
    local rastoyanieDown = math.sqrt((myHero.x-lowBase.x)*(myHero.x-lowBase.x) + (myHero.z-lowBase.z)*(myHero.z-lowBase.z))
    if rastoyanieDown < 900 then
      FONTAN = true
    else
      FONTAN = false
    end
  elseif myHero.team == 200 then
    local rastoyanieUp = math.sqrt((myHero.x-upBase.x)*(myHero.x-upBase.x) + (myHero.z-upBase.z)*(myHero.z-upBase.z))
    if rastoyanieUp < 900 then
      FONTAN = true
    else
      FONTAN = false
    end
  end
end

local SMITELIST = {"summonersmite", "s5_summonersmiteplayerganker", "s5_summonersmiteduel"}
local SMITEFOCUS = {"SRU_Blue1.1.1", "SRU_Blue7.1.1", "SRU_Murkwolf2.1.1", "SRU_Murkwolf8.1.1", "SRU_Gromp13.1.1", "SRU_Gromp14.1.1", "Sru_Crab16.1.1", 
"Sru_Crab15.1.1", "SRU_Red10.1.1", "SRU_Red4.1.1", "SRU_Krug11.1.2", "SRU_Krug5.1.2", "SRU_Razorbeak9.1.1", "SRU_Razorbeak3.1.1", "SRU_Dragon6.1.1", 
"SRU_Baron12.1.1", "TT_NWraith1.1.1", "TT_NGolem2.1.1", "TT_NWolf3.1.1", "TT_NWraith4.1.1", "TT_NGolem5.1.1", "TT_NWolf6.1.1", "TT_Spiderboss8.1.1"}
local SMITE, ATTACKSMITE = false

function CastSmite(target)
  if CanCast(SMITESLOT) then
    CastSpell(SMITESLOT, target)
  end
end

function GetAttackSmiteDamage(unit)
  if SMITE and ATTACKSMITE then
    SmiteDmg = 20 + 8*myHero.level
    return SmiteDmg
  end
end

function GetSmiteDamage(unit)
  if SMITE then
    local SmiteDamage
    if myHero.level <= 4 then
      SmiteDamage = 370 + (myHero.level*20)
    end
    if myHero.level > 4 and myHero.level <= 9 then
      SmiteDamage = 330 + (myHero.level*30)
    end
    if myHero.level > 9 and myHero.level <= 14 then
      SmiteDamage = 240 + (myHero.level*40)
    end
    if myHero.level > 14 then
      SmiteDamage = 100 + (myHero.level*50)
    end
    return SmiteDamage
  end
end

function GetSmiteSlot()
  for i=1, 3 do
    if FindSlotByName(SMITELIST[i]) ~= nil then
      SMITESLOT = FindSlotByName(SMITELIST[i])
      SMITE = true
      if i == 2 or i == 3 then
        ATTACKSMITE = true
      else
        ATTACKSMITE = false
      end
    end
  end
end

function AutoSmite()
  local SmiteDmg = GetSmiteDamage()
  for _, minion in pairs(minionManager(MINION_JUNGLE, 500, myHero, MINION_SORT_MAXHEALTH_DEC).objects) do
    if not minion.dead and minion.visible and ValidTarget(minion, 500) then
      if Menu.Smite[minion.charName:gsub("_", "")] or string.lower(minion.charName):find("dragon") then
        if CanCast(SMITESLOT) and GetRastoyanie(myHero, minion) <= 500 and SmiteDmg >= minion.health then
          CastSpell(SMITESLOT, minion)
        end
      end
    end
  end
end

function DrawSmiteable()
  local SmiteDmg = GetSmiteDamage()
  for _, minion in pairs(minionManager(MINION_JUNGLE, 500, myHero, MINION_SORT_MAXHEALTH_DEC).objects) do
    for j = 1, #SMITEFOCUS do
      if minion.name == SMITEFOCUS[j] then
        if not minion.dead and minion.visible and ValidTarget(minion, 500) then
          if CanCast(SMITESLOT) and GetRastoyanie(myHero, minion) <= 500 and SmiteDmg >= minion.health then
            local posMinion = WorldToScreen(D3DXVECTOR3(minion.x, minion.y, minion.z))
            DrawText("SMITE!", 20, posMinion.x, posMinion.y, ARGB(255,255,0,0))
          end
        end
      end
    end
  end
end

function SmiteKS()
  if not Menu.KS.UseSmiteKS then return end
  for i,enemy in pairs(GetEnemyHeroes()) do
    if not CheckInvul(enemy) and isValid(enemy) then
      if GetRastoyanie(myHero, enemy) <= 500 then
        if SMITE and ATTACKSMITE then
          local SmiteDmg = GetAttackSmiteDamage()
          if SmiteDmg >= enemy.health and CanCast(SMITESLOT) and not enemy.dead then
            CastSmite(enemy)
          end
        end
      end
    end
  end
end

local ATTACKITEMS = {"ItemTiamatCleave", "ItemTitanicHydraCleave", "BilgewaterCutlass", "YoumusBlade", "HextechGunblade", "ItemSwordOfFeastAndFamine"}
local TIAMAT, TITANIC, CUTLASS, YOUMU, GUNBLADE, BOTRK, QSS, DERVISH = false
local TIAMATSLOT, TITANICSLOT, CUTLASSSLOT, YOUMUSLOT, GUNBLADESLOT, BOTRKSLOT, QSSSLOT, DERVISHSLOT, SMITESLOT
local ANTICCITEMS = {"QuicksilverSash", "ItemDervishBlade"}
local CCSPELLS = {"MordekaiserChildrenOfTheGrave", "SkarnerImpale", "LuxLightBindingMis", "Wither", "SonaCrescendo", "DarkBindingMissile", "CurseoftheSadMummy",
"EnchantedCrystalArrow", "AhriSeduce", "CassiopeiaPetrifyingGaze", "Terrify", "HowlingGale", "JaxCounterStrike", "KennenShurikenStorm",
"LeblancSoulShackle", "LeonaSolarFlare", "LissandraR", "AlZaharNetherGrasp", "MonkeyKingDecoy", "NamiQ", "OrianaDetonateCommand", "Pantheon_LeapBash", "PuncturingTaunt",
"SejuaniGlacialPrisonStart", "SwainShadowGrasp", "Imbue", "ThreshQ", "UrgotSwap2", "VarusR", "VeigarEventHorizon", "ViR", "InfiniteDuress", "ZyraGraspingRoots",
"paranoiamisschance", "puncturingtauntarmordebuff", "surpression", "zedulttargetmark", "enchantedcrystalarrow"}

function FindItems()
  if (Menu.Item.AttackItem.UseTiamat) then
    GetTiamat()
  end
  if (Menu.Item.AttackItem.UseTitanic) then
    GetTitanic()
  end
  if (Menu.Item.AttackItem.UseBOTRK) then
    GetBOTRK()
  end
  if (Menu.Item.AttackItem.UseCutlass) then
    GetCutlass()
  end
  if (Menu.Item.AttackItem.UseYoumu) then
    GetYoumu()
  end
  if (Menu.Item.AttackItem.UseGunblade) then
    GetGunblade()
  end
  if (Menu.Item.DefItem.UseQSS) then
    GetQSS()
  end
  if (Menu.Item.DefItem.UseDervish) then
    GetDervish()
  end
end

function GetTiamat()
  local slot = GetItem(ATTACKITEMS[1])
  if (slot ~= nil) then
    TIAMAT = true
    TIAMATSLOT = slot
  else
    TIAMAT = false
  end
end

function GetTitanic()
  local slot = GetItem(ATTACKITEMS[2])
  if (slot ~= nil) then
    TITANIC = true
    TITANICSLOT = slot
  else
    TITANIC = false
  end
end

function GetCutlass()
  local slot = GetItem(ATTACKITEMS[3])
  if (slot ~= nil) then
    CUTLASS = true
    CUTLASSSLOT = slot
  else
    CUTLASS = false
  end
end

function GetYoumu()
  local slot = GetItem(ATTACKITEMS[4])
  if (slot ~= nil) then
    YOUMU = true
    YOUMUSLOT = slot
  else
    YOUMU = false
  end
end

function GetGunblade()
  local slot = GetItem(ATTACKITEMS[5])
  if (slot ~= nil) then
    GUNBLADE = true
    GUNBLADESLOT = slot
  else
    GUNBLADE = false
  end
end

function GetBOTRK()
  local slot = GetItem(ATTACKITEMS[6])
  if (slot ~= nil) then
    BOTRK = true
    BOTRKSLOT = slot
  else
    BOTRK = false
  end
end

function GetQSS()
  local slot = GetItem(ANTICCITEMS[1])
  if (slot ~= nil) then
    QSS = true
    QSSSLOT = slot
  else
    QSS = false
  end
end

function GetDervish()
  local slot = GetItem(ANTICCITEMS[2])
  if (slot ~= nil) then
    DERVISH = true
    DERVISHSLOT = slot
  else
    DERVISH = false
  end
end

function CastTiamat()
  if TIAMAT then
    if (CanCast(TIAMATSLOT)) then
      CastSpell(TIAMATSLOT)
    end
  end
end

function CastYoumu()
  if YOUMU then
    if (CanCast(YOUMUSLOT)) then
      CastSpell(YOUMUSLOT)
    end
  end
end

function CastBOTRK(target)
  if BOTRK then
    if (CanCast(BOTRKSLOT)) then
      CastSpell(BOTRKSLOT, target)
    end
  end
end

function CastTITANIC()
  if TITANIC then
    if (CanCast(TITANICSLOT)) then
      CastSpell(TITANICSLOT)
      OrbsReset()
    end
  end
end

function CastCutlass(target)
  if CUTLASS then
    if (CanCast(CUTLASSSLOT)) then
      CastSpell(CUTLASSSLOT, target)
    end
  end
end

function CastGunblade(target)
  if GUNBLADE then
    if (CanCast(GUNBLADESLOT)) then
      CastSpell(GUNBLADESLOT, target)
    end
  end
end

function CastQSS()
  if QSS then
    if CanCast(QSSSLOT) then
      CastSpell(QSSSLOT)
    end
  end
end

function CastDervish()
  if DERVISH then
    if CanCast(DERVISHSLOT) then
      CastSpell(DERVISHSLOT)
    end
  end
end

function GetTiamatDamage(unit)
  local Dmg = myHero:CalcDamage(unit, myHero.totalDamage*0.6)
  return Dmg
end

function GetBOTRKDamage(unit)
  local Dmg = myHero:CalcDamage(unit, unit.maxHealth*0.1)
  return Dmg
end

function GetCutlassDamage(unit)
  local Dmg = myHero:CalcMagicDamage(unit, 100)
  return Dmg
end

function GetGunbladeDamage(unit)
  local Dmg = myHero:CalcMagicDamage(unit, 150+myHero.ap*0.4)
  return Dmg
end

function ItemKS()
  if not Menu.KS.UseItems then return end
  for i,enemy in pairs(GetEnemyHeroes()) do
    if not CheckInvul(enemy) and isValid(enemy) then
      if GetRastoyanie(myHero, enemy) <= 400 then
        if TIAMAT and Menu.KS.UseItems then
          local TiamatDamage = GetTiamatDamage(enemy)
          if TiamatDamage >= enemy.health and CanCast(TIAMATSLOT) and not enemy.dead then
            CastTiamat()
          end
        end
      end
      if GetRastoyanie(myHero, enemy) <= 550 then
        if BOTRK and Menu.KS.UseItems then
          local BOTRKDamage = GetBOTRKDamage(enemy)
          if BOTRKDamage >= enemy.health and CanCast(BOTRKSLOT) and not enemy.dead then
            CastBOTRK(enemy)
          end
        end
        if CUTLASS and Menu.KS.UseItems then
          local CutlassDamage = GetCutlassDamage(enemy)
          if CutlassDamage >= enemy.health and CanCast(CUTLASSSLOT) and not enemy.dead then
            CastCutlass(enemy)
          end
        end
      end
      if GetRastoyanie(myHero, enemy) <= 700 then
        if GUNBLADE and Menu.KS.UseItems then
          local GunbladeDamage = GetGunbladeDamage(enemy)
          if GunbladeDamage >= enemy.health and CanCast(GUNBLADESLOT) and not enemy.dead then
            CastGunblade(enemy)
          end
        end
      end
    end
  end
end

  FAKER = {["AkaliMota"] = {delay = 0.1, ult = false, tricky = false},
  ["Headbutt"] = {delay = 0.1, ult = false, tricky = false},
  ["CaitlynAceintheHole"] = {delay = 1, ult = false, tricky = true},
  ["Feast"] = {delay = 0.1, ult = true, tricky = false},
  ["DariusExecute"] = {delay = 0.1, ult = true, tricky = true},
  ["VolibearW"] = {delay = 0.1, ult = false, tricky = false},
  ["GarenR"] = {delay = 0.1, ult = true, tricky = false},
  ["JudicatorReckoning"] = {delay = 0.1, ult = false, tricky = false},
  ["DianaTeleport"] = {delay = 0.1, ult = false, tricky = false},
  ["Terrify"] = {delay = 0, ult = false, tricky = true},
  ["FiddlesticksDarkWind"] = {delay = 0.1, ult = false, tricky = false},
  ["TristanaR"] = {delay = 0.1, ult = false, tricky = false},
  ["TristanaE"] = {delay = 0.1, ult = false, tricky = false},
  ["KhazixQ"] = {delay = 0.1, ult = false, tricky = false},
  ["LuluWTwo"] = {delay = 0.1, ult = false, tricky = true},
  ["khazixqlong"] = {delay = 0.1, ult = false, tricky = false},
  ["TwoShivPoison"] = {delay = 0.1, ult = false, tricky = false},
  ["BlindMonkRKick"] = {delay = 0.1, ult = false, tricky = true},
  ["AlZaharNetherGrasp"] = {delay = 0, ult = false, tricky = true},
  ["LissandraR"] = {delay = 0.1, ult = true, tricky = true},
  ["MaokaiUnstableGrowth"] = {delay = 0.1, ult = false, tricky = true},
  ["MordekaiserChildrenOfTheGrave"] = {delay = 0, ult = false, tricky = false},
  ["NasusW"] = {delay = 0.1, ult = false, tricky = false},
  ["NocturneUnspeakableHorror"] = {delay = 0, ult = false, tricky = false},
  ["IceBlast"] = {delay = 0.1, ult = false, tricky = false},
  ["OlafRecklessStrike"] = {delay = 0.1, ult = false, tricky = false},
  ["PantheonW"] = {delay = 0.1, ult = false, tricky = true},
  ["PuncturingTaunt"] = {delay = 0, ult = false, tricky = false},
  ["RyzeW"] = {delay = 0, ult = false, tricky = true},
  ["BrandWildfire"] = {delay = 0.1, ult = false, tricky = false},
  ["Fling"] = {delay = 0, ult = false, tricky = false},
  ["SkarnerImpale"] = {delay = 0.1, ult = false, tricky = true},
  ["IreliaEquilibriumStrike"] = {delay = 0.1, ult = false, tricky = true},
  ["JayceThunderingBlow"] = {delay = 0, ult = false, tricky = false},
  ["LeblancChaosOrb"] = {delay = 0.1, ult = false, tricky = true},
  ["LeblancChaosOrbM"] = {delay = 0.1, ult = false, tricky = false},
  ["tahmkenchw"] = {delay = 0.1, ult = false, tricky = false},
  ["SyndraR"] = {delay = 0.1, ult = false, tricky = false},
  ["Dazzle"] = {delay = 0.1, ult = false, tricky = false},
  ["BlindingDart"] = {delay = 0.1, ult = false, tricky = false},
  ["bluecardpreattack"] = {delay = 0.1, ult = false, tricky = false},
  ["redcardpreattack"] = {delay = 0.1, ult = false, tricky = false},
  ["VayneCondemn"] = {delay = 0.1, ult = false, tricky = true},
  ["VeigarPrimordialBurst"] = {delay = 0.1, ult = true, tricky = false},
  ["InfiniteDuress"] = {delay = 0, ult = false, tricky = false},
  ["zedult"] = {delay = 0.74, ult = true, tricky = false},
  ["Parley"] = {delay = 0.1, ult = false, tricky = false},
  ["KarthusFallenOne"] = {delay = 2.5, ult = false, tricky = true},
  ["Disintegrate"] = {delay = 0.1, ult = false, tricky = false},
  ["ViR"] = {delay = 0.1, ult = false, tricky = true}
  }

function AutoIgnite()
  if igniteslot == nil then return end
  for i,enemy in pairs(GetEnemyHeroes()) do
    if not enemy.dead and enemy.visible then
      local rastoyanie = math.sqrt((enemy.x-myHero.x)*(enemy.x-myHero.x) + (enemy.z-myHero.z)*(enemy.z-myHero.z))
      if rastoyanie <= 600 then
        if ((50 + (20*myHero.level)) >= enemy.health and igniteslot ~= nil and myHero:CanUseSpell(igniteslot) == READY and
          ValidTarget(enemy, 600)) then 
          CastSpell(igniteslot, enemy)
        end
      end
    end
  end
end

function AutoPotion()
  for i=1, 5 do
    local pot = GetItem(POTS[i])
    if (pot ~= nil) then
      if (((myHero.health*100)/myHero.maxHealth) <= Menu.Auto.autoPotsHealth and not REGEN) then
        CastSpell(pot)
      end
    end
  end
end

function AutoHeal()
  if healslot == nil then return end
  if ((myHero.health*100)/myHero.maxHealth) <= Menu.Auto.autoHealHealth and CanCast(healslot) and ATTACKED then
    CastSpell(healslot)
  end
end

function AutoBarrier()
  if barrierslot == nil then return end
  if ((myHero.health*100)/myHero.maxHealth) <= Menu.Auto.autoBarrierHealth and CanCast(barrierslot) and ATTACKED then
    CastSpell(barrierslot)
  end
end

local AttackResets = {"dariusnoxiantacticsonh", "fioraflurry", "garenq", "hecarimrapidslash", "jaxempowertwo", "jaycehypercharge", "leonashieldofdaybreak", 
"luciane", "lucianq", "lucianw", "monkeykingdoubleattack", "mordekaisermaceofspades", "nasusq", "nautiluspiercinggaze", "netherblade", "parley", 
"poppydevastatingblow", "powerfist", "renektonpreexecute", "rengarq", "shyvanadoubleattack", "sivirw", "takedown", "talonnoxiandiplomacy", "trundletrollsmash", 
"vaynetumble", "vie", "volibearq", "xenzhaocombotarget", "yorickspectral", "reksaiq"}
local NoAttacks = {"jarvanivcataclysmattack", "monkeykingdoubleattack", "shyvanadoubleattack", "shyvanadoubleattackdragon", "zyragraspingplantattack", 
"zyragraspingplantattack2", "zyragraspingplantattackfire", "zyragraspingplantattack2fire", "viktorpowertransfer", "sivirwattackbounce"}
local Attacks = {"caitlynheadshotmissile", "frostarrow", "garenslash2", "kennenmegaproc", "lucianpassiveattack", "masteryidoublestrike", "quinnwenhanced", 
"renektonexecute", "renektonsuperexecute", "rengarnewpassivebuffdash", "trundleq", "xenzhaothrust", "xenzhaothrust2", "xenzhaothrust3", "viktorqbuff"}

function isAutoAttack(name)
  local lName = string.lower(name)
  return (string.find(lName, "attack") and not table.contains(NoAttacks,lName)) or table.contains(Attacks,lName)
end

local PussyOut = 
{
["KatarinaR"] = true,
["AlZaharNetherGrasp"] = true,
["TwistedFateR"] = true,
["VelkozR"] = true,
["InfiniteDuress"] = true,
["JhinR"] = true,
["CaitlynAceintheHole"] = true,
["UrgotSwap2"] = true,
["LucianR"] = true,
["GalioIdolOfDurand"] = true,
["MissFortuneBulletTime"] = true,
["XerathLocusPulse"] = true
}

function GetRastoyanie(a, b)
  if not b then
    return GetRastoyanie(myHero,a)
  end
  local rastoyanie = math.sqrt((b.x-a.x)*(b.x-a.x) + (b.z-a.z)*(b.z-a.z))
  return rastoyanie
end

function CanCast(spell)
  return myHero:CanUseSpell(spell) == READY
end

function FindSlotByName(name)
  if name ~= nil then
    for i=0, 12 do
      if string.lower(myHero:GetSpellData(i).name) == string.lower(name) then
        return i
      end
    end
  end  
  return nil
end

function GetItem(name)
  local slot = FindSlotByName(name)
  return slot 
end

function OnWndMsg(msg, key)
  if msg == WM_LBUTTONDOWN and Menu.Combo.focus and not myHero.dead then
    for i, pussy in ipairs(GetEnemyHeroes()) do
      if GetRastoyanie(mousePos, pussy) <= 120 and isValid(pussy) and not CheckInvul(pussy) then
        if FOCUSED ~= pussy then
          FOCUSED = pussy
          print("<font color = \"#B13070\">[HENTAI BUNDLE]</font> focus "..pussy.charName)
        else
          FOCUSED = nil
          print("<font color = \"#B13070\">[HENTAI BUNDLE]</font> stop focus "..pussy.charName)
        end
      end
    end
  end
end

local invul = {"undyingrage", "sionpassivezombie", "aatroxpassivedeath", "chronoshift", "judicatorintervention"}

function CheckInvul(unit)
  for i,buff in pairs(invul) do
    if TargetHaveBuff(buff, unit) then
      return true
    end
  end
    return false
end

function DrawSelectedTarget()
  if not Menu.Combo.focus then return end
  local target = FOCUSED
  if target == nil then return end
  if (target ~= nil and target.type == myHero.type and target.team ~= myHero.team) then
    DrawFPSCircle(target.x, target.z, 150, ARGB(255,255,0,0), 4)
    local posMinion = WorldToScreen(D3DXVECTOR3(target.x, target.y, target.z))
    DrawText("FOCUS!", 20, posMinion.x, posMinion.y, ARGB(255,255,255,255))
  end
end

function GetHentaiTarget(range)
  local selectedTarget = FOCUSED
  if selectedTarget ~= nil and Menu.Combo.focus then
    if selectedTarget.type == myHero.type and selectedTarget.team ~= myHero.team and isValid(selectedTarget, range + 100) and not CheckInvul(enemy) then
      return selectedTarget
    end
  end
  local hentaiTarget = nil
  local lessCast = 0
  for i = 1, #GetEnemyHeroes() do
    local enemy = GetEnemyHeroes()[i]
    if isValid(enemy, range) and not CheckInvul(enemy) then
      local kArmor = (100+enemy.armor)/100
      local kKillable = kArmor*enemy.health
      if kKillable <= lessCast or lessCast == 0 then
        hentaiTarget = enemy
        lessCast = kKillable
      end
    end
  end
  return hentaiTarget
end

function GetHentaiTargetMagic(range)
  local selectedTarget = FOCUSED
  if selectedTarget ~= nil and Menu.Combo.focus then
    if selectedTarget.type == myHero.type and selectedTarget.team ~= myHero.team and isValid(selectedTarget, range + 100) and not CheckInvul(enemy) then
      return selectedTarget
    end
  end
  local hentaiTarget = nil
  local lessCast = 0
  for i = 1, #GetEnemyHeroes() do
    local enemy = GetEnemyHeroes()[i]
    if isValid(enemy, range) and not CheckInvul(enemy) then
      local kArmor = (100+enemy.magicArmor)/100
      local kKillable = kArmor*enemy.health
      if kKillable <= lessCast or lessCast == 0 then
        hentaiTarget = enemy
        lessCast = kKillable
      end
    end
  end
  return hentaiTarget
end

function isValid(object, range)
  return object ~= nil and object.valid and object.visible and not object.dead and object.bInvulnerable == 0
   and object.bTargetable and (range == nil or GetRastoyanie(object, myHero) <= range)
end

local BuffTypes = {
[25] = "Blind",
[31] = "Disarm",
[8] = "ForcedAction",
[11] = "Root",
[7] = "Silence",
[10] = "Slow",
[5] = "Stun",
[999] = "Suspension",
[24] = "Suppression", 
}

function DrawLineA(x1, y1, x2, y2, color)
  DrawLine(x1, y1, x2, y2, 1, color)
end

function DrawFPSCircle(xCoordinate, zCoordinate, radius, color, quality)
  DrawCircle3D(xCoordinate, myHero.y, zCoordinate, radius, 2, color, quality)
end

function GetHPBarPos(enemy)
  enemy.barData = {PercentageOffset = {x = -0.05, y = 0}}
  local barPos = GetUnitHPBarPos(enemy)
  local barPosOffset = GetUnitHPBarOffset(enemy)
  local barOffset = { x = enemy.barData.PercentageOffset.x, y = enemy.barData.PercentageOffset.y }
  local barPosPercentageOffset = { x = enemy.barData.PercentageOffset.x, y = enemy.barData.PercentageOffset.y }
  local BarPosOffsetX = -50
  local BarPosOffsetY = 46
  local CorrectionY = 39
  local StartHpPos = 31 
  barPos.x = math.floor(barPos.x + (barPosOffset.x - 0.5 + barPosPercentageOffset.x) * BarPosOffsetX + StartHpPos)
  barPos.y = math.floor(barPos.y + (barPosOffset.y - 0.5 + barPosPercentageOffset.y) * BarPosOffsetY + CorrectionY)
  local StartPos = Vector(barPos.x , barPos.y, 0)
  local EndPos = Vector(barPos.x + 108 , barPos.y , 0)    
  return Vector(StartPos.x, StartPos.y, 0), Vector(EndPos.x, EndPos.y, 0)
end

function DrawLineHPBar(damage, text, unit, enemyteam)
  if unit.dead or not unit.visible then return end
  local p = WorldToScreen(D3DXVECTOR3(unit.x, unit.y, unit.z))
  if not OnScreen(p.x, p.y) then return end
  local thedmg = 0
  local line = 2
  local linePosA  = {x = 0, y = 0 }
  local linePosB  = {x = 0, y = 0 }
  local TextPos   = {x = 0, y = 0 }

  if damage >= unit.health then
    thedmg = unit.health - 1
    text = "KILLABLE!"
  else
    thedmg = damage
    text = "Possible Damage"
  end

  thedmg = math.round(thedmg)

  local StartPos, EndPos = GetHPBarPos(unit)
  local Real_X = StartPos.x + 24
  local Offs_X = (Real_X + ((unit.health - thedmg) / unit.maxHealth) * (EndPos.x - StartPos.x - 2))
  if Offs_X < Real_X then Offs_X = Real_X end 
  local mytrans = 350 - math.round(255*((unit.health-thedmg)/unit.maxHealth))
  if mytrans >= 255 then mytrans=254 end
  local my_bluepart = math.round(400*((unit.health-thedmg)/unit.maxHealth))
  if my_bluepart >= 255 then my_bluepart=254 end

  if enemyteam then
    linePosA.x = Offs_X-150
    linePosA.y = (StartPos.y-(30+(line*15)))    
    linePosB.x = Offs_X-150
    linePosB.y = (StartPos.y-10)
    TextPos.x = Offs_X-148
    TextPos.y = (StartPos.y-(30+(line*15)))
  else
    linePosA.x = Offs_X-125
    linePosA.y = (StartPos.y-(30+(line*15)))    
    linePosB.x = Offs_X-125
    linePosB.y = (StartPos.y-15)

    TextPos.x = Offs_X-122
    TextPos.y = (StartPos.y-(30+(line*15)))
  end

  DrawLine(linePosA.x, linePosA.y, linePosB.x, linePosB.y , 2, ARGB(mytrans, 255, my_bluepart, 0))
  DrawText(tostring(thedmg).." "..tostring(text), 15, TextPos.x, TextPos.y , ARGB(mytrans, 255, my_bluepart, 0))
end

function Five_Buff_Add(unit, target, buff)
  for i=1, 5 do
    if (buff.name == POTS[i] and unit.isMe) then
      REGEN = true
    end
  end
  for j = 1, #CCSPELLS do
    if target then
      if target.isMe and buff.name == CCSPELLS[j] then
        UNDERCC = true
      end
    end
  end
end

function Five_Buff_Rem(unit, buff)
  for i=1, 5 do
    if (buff.name == POTS[i] and unit.isMe) then
      REGEN = false
    end
  end
  for j = 1, #CCSPELLS do
    if unit.isMe and buff.name == CCSPELLS[j] then
      UNDERCC = false
    end
  end
end

function OnProcessSpell(unit, spell)
  local topkek = false
  if spell ~= nil and spell.target ~= nil and unit ~= nil then
    if spell.target.isMe and unit.team ~= myHero.team then
      ATTACKED = true
      DelayAction(function() ATTACKED = false end, 1)
    end
  end
end

function OnProcessAttack(unit, spell)
  if unit ~= nil and spell ~= nil then
    if GetRastoyanie(myHero, unit) <= 1000 then
      if spell.target == myHero then
        ATTACKED = true
        DelayAction(function() ATTACKED = false end, 1)
      end
    end
  end
end

function GetBestLineFarmPosition(range, width, objects)
  local BestPos 
  local BestHit = 0
  for i, object in ipairs(objects) do
    local EndPos = Vector(myHero.pos) + range * (Vector(object) - Vector(myHero.pos)):normalized()
    local hit = CountObjectsOnLineSegment(myHero.pos, EndPos, width, objects)
    if hit > BestHit then
      BestHit = hit
      BestPos = Vector(object)
      if BestHit == #objects then
        break
      end
    end
  end
  return BestPos, BestHit
end

function CountObjectsOnLineSegment(StartPos, EndPos, width, objects)
  local n = 0
  for i, object in ipairs(objects) do
    local pointSegment, pointLine, isOnSegment = VectorPointProjectionOnLineSegment(StartPos, EndPos, object)
    if isOnSegment and GetDistanceSqr(pointSegment, object) < width * width then
      n = n + 1
    end
  end
  return n
end

function GetBestCircularFarmPosition(range, radius, objects)
  local BestPos 
  local BestHit = 0
  for i, object in ipairs(objects) do
    local hit = CountObjectsNearPos(object.pos or object, range, radius, objects)
    if hit > BestHit then
      BestHit = hit
      BestPos = Vector(object)
      if BestHit == #objects then
        break
      end
    end
  end
  return BestPos, BestHit
end

function CountObjectsNearPos(pos, range, radius, objects)
  local n = 0
  for i, object in ipairs(objects) do
    if GetDistanceSqr(pos, object) <= radius * radius then
      n = n + 1
    end
  end
  return n
end


function OnLoad()
  AddApplyBuffCallback(Five_Buff_Add)
  AddRemoveBuffCallback(Five_Buff_Rem)

  KatarinaUpdate(
    Version,
    'raw.githubusercontent.com', 
    '/remembermyhentai/BoL/master/Bundle/HentaiBundle.version',
    '/remembermyhentai/BoL/master/Bundle/HentaiBundle.lua', 
    SCRIPT_PATH.._ENV.FILE_NAME, 
    function() PrintChat('<font color = \"#B13070\">[HENTAI BUNDLE]</font> <font color = \"#4DFF4D\">SCRIPT UPDATED. RESTART BOL (2xF9)</font>') end, 
    function() PrintChat('<font color = \"#B13070\">[HENTAI BUNDLE]</font> <font color = \"#4DFF4D\">LOADED VERSION //</font>'..version) end, 
    function() PrintChat(Menu.update and '<font color = \"#B13070\">[HENTAI BUNDLE]</font> <font color = \"#4DFF4D\">NEW VERSION, WAIT...</font>' or
     '<font color = \"#B13070\">[HENTAI BUNDLE]</font> <font color = \"#4DFF4D\">NEW VERSION, DOWNLOAD IT MANUALLY FROM FORUM</font>') end, 
    function() PrintChat('<font color = \"#B13070\">[HENTAI BUNDLE]</font> <font color = \"#4DFF4D\">UPDATE ERROR, DOWNLOAD IT MANUALLY FROM FORUM</font>') end)

  
  igniteslot = FindSlotByName("summonerdot")
  healslot = FindSlotByName("summonerheal")
  barrierslot = FindSlotByName("summonerbarrier")

  
  Menu = scriptConfig("[Hentai Bundle]", "HentaiFive")

  Menu:addSubMenu("[Key Binds]", "Key")

  Menu:addSubMenu("[Combo]", "Combo")
  Menu.Combo:addParam("focus", "Focus selected target", SCRIPT_PARAM_ONOFF, true)

  Menu:addSubMenu("[Harras]", "Harras")

  Menu:addSubMenu("[Farm]", "Farm")

  Menu:addSubMenu("[Prediction]", "Prediction")

  Menu:addSubMenu("[Killsteal]", "KS")
  Menu.KS:addParam("UseSmiteKS", "Use Smite in Killsteal", SCRIPT_PARAM_ONOFF, true)
  if igniteslot ~= nil then
    Menu.KS:addParam("ksIgnite", "Use Ignite for killsteal", SCRIPT_PARAM_ONOFF, true)
  end
  Menu.KS:addParam("UseItems", "Use Items in Killsteal", SCRIPT_PARAM_ONOFF, true)

  Menu:addSubMenu("[Smite Usage]", "Smite")
  Menu.Smite:addParam("UseSmite", "Enable Smite usage", SCRIPT_PARAM_ONKEYTOGGLE, true, string.byte("N"))
  Menu.Smite:addParam("UseSmiteCombo", "Use Smite in combo", SCRIPT_PARAM_ONKEYTOGGLE, true, string.byte("M"))
  Menu.Smite:addParam("SRUBaron", "Smite Baron", SCRIPT_PARAM_ONOFF, true)
  Menu.Smite:addParam("SRUDragon", "Smite Dragon", SCRIPT_PARAM_ONOFF, true)
  Menu.Smite:addParam("SRURed", "Smite Red Buff", SCRIPT_PARAM_ONOFF, true)
  Menu.Smite:addParam("SRUBlue", "Smite Blue Buff", SCRIPT_PARAM_ONOFF, true)
  Menu.Smite:addParam("SRURazorbeak", "Smite Wraith", SCRIPT_PARAM_ONOFF, false)
  Menu.Smite:addParam("SRUMurkwolf", "Smite Wolf", SCRIPT_PARAM_ONOFF, false)
  Menu.Smite:addParam("SRUKrug", "Smite Golem", SCRIPT_PARAM_ONOFF, false)
  Menu.Smite:addParam("SRUGromp", "Smite Gromp", SCRIPT_PARAM_ONOFF, false)

  Menu:addSubMenu("[Item Usage]", "Item")
  Menu.Item:addParam("UseItem", "Enable Item Usage", SCRIPT_PARAM_ONOFF, true)
  Menu.Item:addSubMenu("[Offensive Items]", "AttackItem")
  Menu.Item.AttackItem:addParam("UseTiamat", "Use Tiamat/Hydra", SCRIPT_PARAM_ONOFF, true)
  Menu.Item.AttackItem:addParam("UseTitanic", "Use Titanic Hydra", SCRIPT_PARAM_ONOFF, true)
  Menu.Item.AttackItem:addParam("UseCutlass", "Use Bilgewater Cutlass", SCRIPT_PARAM_ONOFF, true)
  Menu.Item.AttackItem:addParam("UseBOTRK", "Use BOTRK", SCRIPT_PARAM_ONOFF, true)
  Menu.Item.AttackItem:addParam("UseYoumu", "Use Youmus Blade", SCRIPT_PARAM_ONOFF, true)
  Menu.Item.AttackItem:addParam("UseGunblade", "Use Hextech Gunblade", SCRIPT_PARAM_ONOFF, true)
  Menu.Item:addSubMenu("[Anti CC]", "DefItem")
  Menu.Item.DefItem:addParam("EnableACC", "Enable AntiCC", SCRIPT_PARAM_ONOFF, true)
  Menu.Item.DefItem:addParam("UseQSS", "Use Quicksilver Sash", SCRIPT_PARAM_ONOFF, true)
  Menu.Item.DefItem:addParam("UseDervish", "Use Dervish Blade", SCRIPT_PARAM_ONOFF, true)

  Menu:addSubMenu("[Draws]", "Draws")
  Menu.Draws:addParam("drawTarget", "Draw Selected Target", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("DrawSmite", "Draw Smite range", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("DrawSmiteable", "Draw if jungle mob is Smiteable ", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("DrawSmiteStatus", "Draw Smite Status on window", SCRIPT_PARAM_ONOFF, true)

  Menu:addSubMenu("[Auto]", "Auto")
  Menu.Auto:addParam("autoPots", "Auto Potions usage", SCRIPT_PARAM_ONOFF, false)
  Menu.Auto:addParam("autoPotsHealth", "% Health for autopots", SCRIPT_PARAM_SLICE, 75, 0, 100, 0)
  if healslot ~= nil then
    Menu.Auto:addParam("autoHeal", "Auto Heal usage", SCRIPT_PARAM_ONOFF, true)
    Menu.Auto:addParam("autoHealHealth", "% Health for Heal usage", SCRIPT_PARAM_SLICE, 10, 0, 100, 0)
  end
  if barrierslot ~= nil then
    Menu.Auto:addParam("autoBarrier", "Auto Barrier usage", SCRIPT_PARAM_ONOFF, true)
    Menu.Auto:addParam("autoBarrierHealth", "% Health for Barrier usage", SCRIPT_PARAM_SLICE, 10, 0, 100, 0)
  end

  Menu:addParam("info1", "", SCRIPT_PARAM_INFO, "")
  Menu:addParam("info2", ""..scriptname.." [ver. "..version.."]", SCRIPT_PARAM_INFO, "")
  Menu:addParam("update", "Enable Auto Update", SCRIPT_PARAM_ONOFF, true)
  Menu:addParam("info5", "", SCRIPT_PARAM_INFO, "")
  Menu:addParam("info3", "Created by "..developer.."", SCRIPT_PARAM_INFO, "")
  Menu:addParam("info4", "Contact me: "..contact.."", SCRIPT_PARAM_INFO, "")

  if _G.Reborn_Loaded ~= nil then
    SAC = true
    PrintChat("<font color = \"#B13070\">HENTAI BUNDLE</font> <font color = \"#4DFF4D\">SAC FOUND</font>")
  end
  
  if _G.MMA_IsLoaded then
    MMA = true
    PrintChat("<font color = \"#B13070\">HENTAI BUNDLE</font> <font color = \"#4DFF4D\">MMA FOUND</font>")
  end
  if _G.NebelwolfisOrbWalkerInit then
    WOLFY = true
    PrintChat("<font color = \"#B13070\">HENTAI BUNDLE</font> <font color = \"#4DFF4D\">NEBELWOLFI FOUND</font>")
  end
  if _Pewalk then
    PEW = true
    PrintChat("<font color = \"#B13070\">HENTAI BUNDLE</font> <font color = \"#4DFF4D\">PEWALK FOUND</font>")
  end
  if _G.SxOrb ~= nil then
    SXORB = true
    PrintChat("<font color = \"#B13070\">HENTAI BUNDLE</font> <font color = \"#4DFF4D\">SXORB FOUND</font>")
  end

  if myHero.charName == "Renekton" then
    AddLoadCallback(Renekton_Load)
    AddTickCallback(Renekton_Tick)
    AddDrawCallback(Renekton_Draw)
  end

  if myHero.charName == "JarvanIV" then
    AddLoadCallback(Jarvan_Load)
    AddTickCallback(Jarvan_Tick)
    AddDrawCallback(Jarvan_Draw)
    AddCreateObjCallback(Jarvan_OnCreateObj)
    AddDeleteObjCallback(Jarvan_OnDeleteObj)
    AddProcessSpellCallback(Jarvan_OnProcessSpell)
  end

  if myHero.charName == "Talon" then
    AddLoadCallback(Talon_Load)
    AddTickCallback(Talon_Tick)
    AddDrawCallback(Talon_Draw)
    AddProcessSpellCallback(Talon_OnProcessSpell)
  end

  if myHero.charName == "Olaf" then
    AddLoadCallback(Olaf_Load)
    AddTickCallback(Olaf_Tick)
    AddDrawCallback(Olaf_Draw)
  end

  if myHero.charName == "Heimerdinger" then
    AddLoadCallback(Heimer_Load)
  end

  if myHero.charName == "Nocturne" then
    AddLoadCallback(Nocturne_Load)
  end
end

function OnTick()

  if FOCUSED ~= nil then
    if FOCUSED.dead or not FOCUSED.visible then
      FOCUSED = nil
    end
  end
  
  GetSmiteSlot()
  if SMITE then
    SmiteKS()
    if Menu.Smite.UseSmite then
      AutoSmite()
    end
  end
  
  if Menu.Item.UseItem then
    FindItems()
  end
  
  CheckFountain()
  if (Menu.Auto.autoPots and not REGEN) and not FONTAN then
    AutoPotion()
  end
  
  if Menu.Auto.autoHeal then
    AutoHeal()
  end
  if Menu.Auto.autoBarrier then
    AutoBarrier()
  end
  
  if UNDERCC and Menu.Item.UseItem and Menu.Item.DefItem.EnableACC then
    if Menu.Item.DefItem.UseQSS and QSS then
      CastQSS()
    end
    if Menu.Item.DefItem.UseDervish and DERVISH then
      CastDervish()
    end
  end
  
  ItemKS()
  
  if igniteslot ~= nil and Menu.KS.ksIgnite then
    AutoIgnite()
  end
end

function OnDraw()
  if not myHero.dead then
    if SMITE then
      if Menu.Smite.UseSmite then
        if Menu.Draws.DrawSmiteStatus then
          if Menu.Smite.UseSmite then
            DrawText ("USE SMITE [N]", 20, 150, 120, 0xFF00FF00)
          end
          if Menu.Smite.UseSmiteCombo then
            DrawText ("USE SMITE in SBTW [M]", 20, 150, 100, 0xFF00FF00)
          else
            DrawText ("DON'T USE SMITE in SBTW [M]", 20, 150, 100, 0xFFFF0000)
          end
        end
        if Menu.Draws.DrawSmite then
          DrawFPSCircle(myHero.x, myHero.z, 500, ARGB(255,193,61,255), 24)
        end
        if Menu.Draws.DrawSmiteable then
          DrawSmiteable()
        end
      else
        DrawText ("DON'T USE SMITE [N]", 20, 150, 120, 0xFFFF0000)
      end
    end
    if Menu.Draws.drawTarget then
      DrawSelectedTarget()
    end
  end
end

function OrbsOff()
  if SAC then
    _G.AutoCarry.MyHero:MovementEnabled(false)
    _G.AutoCarry.MyHero:AttacksEnabled(false)
    DelayAction(function()
      _G.AutoCarry.MyHero:MovementEnabled(true)
      _G.AutoCarry.MyHero:AttacksEnabled(true)
    end, 0.1)
  end
  if MMA then
    _G.MMA_AvoidMovement(false)
    _G.MMA_StopAttacks(false)
    DelayAction(function()
      _G.MMA_AvoidMovement()
      _G.MMA_StopAttacks()
    end, 0.1)
  end
  if WOLFY then
    _G.NebelwolfisOrbWalker:SetOrb(false)
    DelayAction(function()
      _G.NebelwolfisOrbWalker:SetOrb(true)
    end, 0.1)
  end
  if PEW then
    _Pewalk.AllowAttack(false)
    _Pewalk.AllowMove(false)
    DelayAction(function()
      _Pewalk.AllowAttack(true)
      _Pewalk.AllowMove(true)
    end, 0.1)
  end
  if SXORB then
    SxOrb:DisableAttacks()
    SxOrb:DisableMove()
    DelayAction(function()
      SxOrb:EnableMove()
      SxOrb:EnableAttacks()
    end, 0.1)
  end
end

function OrbsReset(unit)
  if SAC then
    _G.AutoCarry.Orbwalker:ResetAttackTimer()
  end
  if WOLFY then
    _G.NebelwolfisOrbWalker:ResetAA()
  end
  if MMA then
    _G.MMA_ResetAutoAttack()
  end
  if SXORB then
    _G.SxOrb:ResetAA()
  end
end

function Renekton_Load()
  WOMBOCOMBO = false

  AddProcessAttackCallback(Renekton_ProcessAttack)

  RENEKTON_VARS = {
    AA = {RANGE = 125},
    Q = {RADIUS = 310},
    W = {RANGE = 185},
    E = {RANGE = 425, WIDTH = 100}
  }

  Menu.Key:addParam("combo", "Combo", SCRIPT_PARAM_ONKEYDOWN, false, string.byte(" "))
  Menu.Key:addParam("harras", "Harras", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("C"))
  Menu.Key:addParam("lasthit", "Lasthit", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("X"))
  Menu.Key:addParam("laneclear", "Laneclear/Jungleclear", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("V"))

  Menu.Combo:addParam("comboMode", "Burst combo", SCRIPT_PARAM_ONKEYTOGGLE, false, string.byte("T"))
  Menu.Combo:addParam("useGC", "Use E to gapclose", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useWpref", "Prefer empowered W", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useE", "Use E", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useEclose", "Use 2ndE even if enemy too close", SCRIPT_PARAM_ONOFF, true)

  Menu.Harras:addParam("useHR", "Hit n Run harras", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useGC", "Use 2E to gapclose (doesnt work in hit n run)", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useE", "Use E", SCRIPT_PARAM_ONOFF, true)

  Menu.Farm:addSubMenu("[Lasthit]", "Lasthit")
  Menu.Farm.Lasthit:addParam("lasthitQ", "Use Q for lasthit", SCRIPT_PARAM_ONOFF, false)
  Menu.Farm:addSubMenu("[Clear]", "Laneclear")
  Menu.Farm.Laneclear:addParam("laneclearQ", "Use Q for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearW", "Use W for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearE", "Use E for clear", SCRIPT_PARAM_ONOFF, true)

  Menu.Draws:addParam("drawHP", "Draw damage on HP Bar", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawQ", "Draw Q range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("drawE", "Draw E range", SCRIPT_PARAM_ONOFF, true)

  Menu.Prediction:addParam("info1", "No pred for croco Q_Q", SCRIPT_PARAM_INFO, "")

  Menu.KS:addParam("ksQ", "Use Q for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksW", "Use W for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksE", "Use E for killsteal", SCRIPT_PARAM_ONOFF, true)

  Menu.Auto:addParam("autoR", "Auto R usage", SCRIPT_PARAM_ONOFF, true)
  Menu.Auto:addParam("autoRHealth", "% Health for R", SCRIPT_PARAM_SLICE, 50, 0, 100, 0)

end

function Renekton_Tick()
  if Menu.Key.combo then
    Renekton_Combo()
  end
  
  if Menu.Key.harras then
    Renekton_Harras()
  end
  
  if Menu.Key.lasthit then
    Renekton_Lasthit()
  end
  
  if Menu.Key.laneclear then
    Renekton_Clear()
  end
  
  Renekton_Killsteal()
  
  Renekton_AutoR()
end

function Renekton_Draw()
  if Menu.Draws.drawHP then
    Renekton_DrawHP()
  end
  if Menu.Draws.drawQ then
    DrawFPSCircle(myHero.x, myHero.z, RENEKTON_VARS.Q.RADIUS, ARGB(255,193,61,255), 24)
  end
  if Menu.Draws.drawE then
    DrawFPSCircle(myHero.x, myHero.z, RENEKTON_VARS.E.RANGE, ARGB(255,193,61,255), 24)
  end
end

function Renekton_Combo()
  local flag = true
  if Menu.Combo.comboMode then
    local target = GetHentaiTarget(RENEKTON_VARS.E.RANGE*2)
    if target ~= nil then
      local rastoyanie = GetRastoyanie(myHero, target)
      if rastoyanie > 300 and Menu.Combo.useGC then
        Renekton_Gapclose(target)
      end
      if (CanCast(_W) or TargetHaveBuff("RenektonPreExecute", myHero)) and rastoyanie <= 200 and Menu.Combo.useW then
        Renekton_CastW()
        OrbsOff()
        myHero:Attack(target)
        flag = true
      else
        flag = false
      end
      if rastoyanie < RENEKTON_VARS.Q.RADIUS and (not flag or not TargetHaveBuff("RenektonPreExecute", myHero)) then
        if Menu.Combo.useWpref and myHero.mana >= 50 and CanCast(_W) then
          do return end
        end
        Renekton_CastQ()
      end
      if Menu.Combo.useEclose and rastoyanie < RENEKTON_VARS.E.RANGE and myHero.mana < 50 then
        CastSpell(_E, target.x, target.z)
      end
    end
  else
    local target = GetHentaiTarget(RENEKTON_VARS.E.RANGE*2)
    if target ~= nil then
      local rastoyanie = GetRastoyanie(myHero, target)
      if rastoyanie > 200 and Menu.Combo.useGC then
        Renekton_Gapclose(target)
      end
      if Menu.Combo.useEclose and rastoyanie < RENEKTON_VARS.E.RANGE and myHero.mana < 50 then
        CastSpell(_E, target.x, target.z)
      end
      if (CanCast(_W) or TargetHaveBuff("RenektonPreExecute", myHero)) and rastoyanie <= 200 and Menu.Combo.useW then
        OrbsOff()
        myHero:Attack(target)
        flag = true
      else
        flag = false
      end
      if rastoyanie < RENEKTON_VARS.Q.RADIUS and (not flag or not TargetHaveBuff("RenektonPreExecute", myHero)) then
        if Menu.Combo.useWpref and myHero.mana >= 50 and CanCast(_W) then
          do return end
        end
        Renekton_CastQ()
      end
    end
  end
  if Menu.Item.UseItem then
    local target = GetHentaiTarget(500)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= 200 then
        CastYoumu()
      end
      if Menu.Smite.UseSmiteCombo then
        if SMITE and ATTACKSMITE then
          CastSmite(target)
        end
      end
      CastBOTRK(target)
      CastGunblade(target)
      CastCutlass(target)
    end
  end
end

flagA = false
flagB = false

function Renekton_Harras()
  if Menu.Harras.useHR then
    local target = GetHentaiTarget(RENEKTON_VARS.E.RANGE)
    if target ~= nil then
      local rastoyanie = GetRastoyanie(myHero, target)
      if not flagA and CanCast(_E) and myHero:GetSpellData(_E).name ~= "RenektonDice" then
        runPos = Vector(myHero.x, myHero.y, myHero.z)
        flagA = true
      end
      if CanCast(_E) and myHero:GetSpellData(_E).name ~= "RenektonDice" then
        CastSpell(_E, target.x, target.z)
      end
      if (CanCast(_W) or TargetHaveBuff("RenektonPreExecute", myHero)) and rastoyanie <= 200 and Menu.Harras.useW then
        OrbsOff()
        myHero:Attack(target)
        flag = true
      else
        flag = false
      end
      if rastoyanie < RENEKTON_VARS.Q.RADIUS and (not flag or not TargetHaveBuff("RenektonPreExecute", myHero)) then
        Renekton_CastQ()
      end
      if myHero:GetSpellData(_E).name == "RenektonDice" and not CanCast(_Q) and flagB then
        local rastoyanieA = GetRastoyanie(myHero, runPos)
        local a = (runPos.x - myHero.x)/rastoyanieA * RENEKTON_VARS.E.RANGE + myHero.x
        local b = (runPos.z - myHero.z)/rastoyanieA * RENEKTON_VARS.E.RANGE + myHero.z
        CastSpell(_E, a, b)
        DelayAction(function() flagA = false end, 2)
      end
    end
  else
    local target = GetHentaiTarget(RENEKTON_VARS.E.RANGE*2)
    if target ~= nil then
      local rastoyanie = GetRastoyanie(myHero, target)
      if rastoyanie > 200 and Menu.Harras.useGC then
        Renekton_Gapclose(target)
      end
      if Menu.Harras.useEclose and rastoyanie < RENEKTON_VARS.E.RANGE and myHero.mana < 50 then
        CastSpell(_E, target.x, target.z)
      end
      if (CanCast(_W) or TargetHaveBuff("RenektonPreExecute", myHero)) and rastoyanie <= 200 and Menu.Harras.useW then
        OrbsOff()
        myHero:Attack(target)
        flag = true
      else
        flag = false
      end
      if rastoyanie < RENEKTON_VARS.Q.RADIUS and (not flag or not TargetHaveBuff("RenektonPreExecute", myHero)) then
        if Menu.Harras.useWpref and myHero.mana >= 50 and CanCast(_W) then
          do return end
        end
        Renekton_CastQ()
      end
    end
  end
end

function Renekton_Killsteal()
  for i,enemy in pairs(GetEnemyHeroes()) do
    if not CheckInvul(enemy) and isValid(enemy) then
      local QDmg = Renekton_GetQDamage(enemy)
      local EDmg = Renekton_GetEDamage(enemy)
      if QDmg >= enemy.health and GetRastoyanie(myHero, enemy) <= RENEKTON_VARS.Q.RADIUS then
        Renekton_CastQ()
      end
      if EDmg >= enemy.health and GetRastoyanie(myHero, enemy) <= RENEKTON_VARS.E.RANGE then
        CastSpell(_E, enemy.x, enemy.z)
      end
    end
  end
end

function Renekton_Wcheck()
  return CanCast(_W) or TargetHaveBuff("RenektonPreExecute", myHero)
end

function Renekton_ProcessAttack(unit,spell)
  if unit and unit.isMe and spell then
    if string.lower(spell.name) == "renektonexecute" or string.lower(spell.name) == "renektonsuperexecute" then
      flagB = true
      DelayAction(function() flagB = false end, 2)
    end
  end
  if unit and unit.isMe and spell and TIAMAT then
    if string.lower(spell.name) == "renektonexecute" or string.lower(spell.name) == "renektonsuperexecute" then
      CastTiamat()
    end
  end
  if unit and unit.isMe and spell and TITANIC then
    if string.lower(spell.name) == "renektonexecute" or string.lower(spell.name) == "renektonsuperexecute" then
      CastTITANIC()
      OrbsOff()
      myHero:Attack(spell.target)
    end
  end
  if not unit.isMe then return end
  if isAutoAttack(spell.name) and spell.target and spell.target.type ~= myHero.type and Menu.Key.laneclear then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if not spell.target.dead and not (AADmg >= spell.target.health) and Menu.Farm.Laneclear.laneclearW then
      Renekton_CastW()
      OrbsReset(spell.target)
    end
  end
  if isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.combo then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if not spell.target.dead then
      Renekton_CastW()
      OrbsReset(spell.target)
    end
  end
  if isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.harras then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if not spell.target.dead then
      Renekton_CastW()
      OrbsReset(spell.target)
    end
  end
end

function Renekton_Gapclose(unit)
  if not CanCast(_E) then return end
  local rastoyanie = GetRastoyanie(myHero, unit)
  if rastoyanie < RENEKTON_VARS.E.RANGE then
    if rastoyanie > 250 then
      local a = (unit.x - myHero.x)/rastoyanie * RENEKTON_VARS.E.RANGE + myHero.x
      local b = (unit.z - myHero.z)/rastoyanie * RENEKTON_VARS.E.RANGE + myHero.z
      CastSpell(_E, a, b)
    end
  end
  if rastoyanie < RENEKTON_VARS.E.RANGE*1.85 and myHero:GetSpellData(_E).name ~= "RenektonDice" then
    local rasta = GetRastoyanie(myHero, unit) 
    local minionFocus = nil
    for _, minion in pairs(minionManager(MINION_ENEMY, RENEKTON_VARS.E.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects) do
      if isValid(minion, RENEKTON_VARS.E.RANGE) then
        local rastaA = GetRastoyanie(unit, minion)
        if rasta > rastaA then
          rasta = rastaA
          minionFocus = minion
        end
      end
    end
    if minionFocus ~= nil then
      local a = (minionFocus.x - myHero.x)/rastoyanie * RENEKTON_VARS.E.RANGE + myHero.x
      local b = (minionFocus.z - myHero.z)/rastoyanie * RENEKTON_VARS.E.RANGE + myHero.z
      local dibilBlyat = Vector(a, myHero.y, b)
      if GetRastoyanie(unit, dibilBlyat) <= GetRastoyanie(myHero, unit) then
        CastSpell(_E, a, b)
      end
    end
  end
end

function Renekton_Clear()
  if CanCast(_E) and Menu.Farm.Laneclear.laneclearE then
    local CastPosition1, NumHit1 = GetBestLineFarmPosition(RENEKTON_VARS.E.RANGE, RENEKTON_VARS.E.WIDTH, minionManager(MINION_ENEMY, RENEKTON_VARS.E.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects)
    if CastPosition1 ~= nil then
      CastSpell(_E, CastPosition1.x, CastPosition1.z)
    end
    local CastPositionJgl2, NumHitJgl2 = GetBestLineFarmPosition(RENEKTON_VARS.E.RANGE, RENEKTON_VARS.E.WIDTH, minionManager(MINION_JUNGLE, RENEKTON_VARS.E.RANGE, myHero, MINION_SORT_MAXHEALTH_DEC).objects)
    if CastPositionJgl2 ~= nil then
      CastSpell(_E, CastPositionJgl2.x, CastPositionJgl2.z)
    end
  end
  if CanCast(_Q) and Menu.Farm.Laneclear.laneclearQ then
    for _, minion in pairs(minionManager(MINION_ENEMY, RENEKTON_VARS.Q.RADIUS, myHero, MINION_SORT_HEALTH_ASC).objects) do
      if isValid(minion, RENEKTON_VARS.Q.RADIUS) then
        Renekton_CastQ()
      end
    end
    for _, minion in pairs(minionManager(MINION_JUNGLE, RENEKTON_VARS.Q.RADIUS, myHero, MINION_SORT_MAXHEALTH_DEC).objects) do
      if isValid(minion, RENEKTON_VARS.Q.RADIUS) then
        Renekton_CastQ()
      end
    end
  end
end

function Renekton_Lasthit()
  if CanCast(_Q) and Menu.Farm.Lasthit.lasthitQ then
    for _, minion in pairs(minionManager(MINION_ENEMY, RENEKTON_VARS.Q.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects) do
      local QDmg = Renekton_GetQDamage(minion)
      if isValid(minion) and QDmg >= minion.health then
        Renekton_CastQ()
      end
    end
  end
end

function Renekton_AutoR()
  if not CanCast(_R) or not Menu.Auto.autoR then return end
  if ((myHero.health*100)/myHero.maxHealth) <= Menu.Auto.autoRHealth and ATTACKED then
    Renekton_CastR()
  end
end

function Renekton_CastQ()
  CastSpell(_Q)
end

function Renekton_CastW()
  CastSpell(_W)
end

function Renekton_CastR()
  CastSpell(_R)
end

function Renekton_GetQDamage(unit)
  if myHero.mana >= 50 then
    local Qlvl = myHero:GetSpellData(_Q).level
    if Qlvl < 1 then return 0 end
    local QDmg = {90, 135, 180, 225, 270}
    local DmgRaw = QDmg[Qlvl] + ((myHero.totalDamage - myHero.damage)*1.2)
    local Dmg = myHero:CalcDamage(unit, DmgRaw)
    return Dmg
  else
    local Qlvl = myHero:GetSpellData(_Q).level
    if Qlvl < 1 then return 0 end
    local QDmg = {60, 90, 120, 150, 180}
    local DmgRaw = QDmg[Qlvl] + ((myHero.totalDamage - myHero.damage)*0.8)
    local Dmg = myHero:CalcDamage(unit, DmgRaw)
    return Dmg
  end 
end

function Renekton_GetEDamage(unit)
  local Elvl = myHero:GetSpellData(_E).level
  if Elvl < 1 then return 0 end
  local EDmg = {30, 60, 90, 120, 150}
  local DmgRaw = EDmg[Elvl] + ((myHero.totalDamage - myHero.damage)*0.9)
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function Renekton_GetWDamage(unit)
  if myHero.mana >= 50 then
    local Wlvl = myHero:GetSpellData(_W).level
    if Wlvl < 1 then return 0 end
    local WDmg = {15, 45, 75, 105, 135}
    local WDmgMod = 2.25
    local DmgRaw = WDmg[Wlvl] + myHero.totalDamage * WDmgMod
    local Dmg = myHero:CalcDamage(unit, DmgRaw)
    return Dmg
  else  
    local Wlvl = myHero:GetSpellData(_W).level
    if Wlvl < 1 then return 0 end
    local WDmg = {10, 30, 50, 70, 90}
    local WDmgMod = 1.5
    local DmgRaw = WDmg[Wlvl] + myHero.totalDamage * WDmgMod
    local Dmg = myHero:CalcDamage(unit, DmgRaw)
    return Dmg
  end
end

function Renekton_DrawHP()
  for i, HPbarEnemyChamp in pairs(GetEnemyHeroes()) do
    if not HPbarEnemyChamp.dead and HPbarEnemyChamp.visible then
      local dmg = myHero:CalcDamage(HPbarEnemyChamp, myHero.totalDamage)
      if myHero:CanUseSpell(_Q) == READY and not HPbarEnemyChamp.dead then
        dmg = dmg + Renekton_GetQDamage(HPbarEnemyChamp)
      end
      if CanCast(_W) then
        dmg = dmg + Renekton_GetWDamage(HPbarEnemyChamp)
      end
      if myHero:CanUseSpell(_E) == READY and not HPbarEnemyChamp.dead then
        dmg = dmg + Renekton_GetEDamage(HPbarEnemyChamp)
      end
      DrawLineHPBar(dmg, "", HPbarEnemyChamp, HPbarEnemyChamp.team)
    end
  end
end

function Jarvan_Load()
  require "VPrediction"
  VP = VPrediction()
  CATACLYSM = false

  AddProcessAttackCallback(Jarvan_ProcessAttack)

  JARVAN_VARS = {
    AA = {RANGE = 175},
    Q = {RANGE = 770, WIDTH = 70, DELAY = 0.5, SPEED = math.huge},
    W = {RADIUS = 300},
    E = {RANGE = 830-60, DELAY = 0.5, SPEED = math.huge, RADIUS = 50},
    R = {RANGE = 650, RADIUS = 325}
  }

  YOLO = {}

  Menu.Key:addParam("combo", "Combo", SCRIPT_PARAM_ONKEYDOWN, false, string.byte(" "))
  Menu.Key:addParam("harras", "Harras", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("C"))
  Menu.Key:addParam("lasthit", "Lasthit", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("X"))
  Menu.Key:addParam("laneclear", "Laneclear/Jungleclear", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("V"))
  Menu.Key:addParam("flee", "Flee", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("Z"))

  Menu.Combo:addParam("useEQ", "Use EQ", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("rangeEQ", "Dont use EQ in close range", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("saveEQ", "Force save EQ", SCRIPT_PARAM_ONOFF, false)
  Menu.Combo:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useE", "Use E", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useR", "Use R", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("burstR", "Use Burst R", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addSubMenu("[R whitelist]", "whitelistR")
  for i,enemy in pairs(GetEnemyHeroes()) do
    table.insert(YOLO, enemy.charName)
  end
  for i = 1, #YOLO do
    local a1 = "a"..i
    local a2 = ""..YOLO[i]
    Menu.Combo.whitelistR:addParam(a1, "Cast R on "..a2, SCRIPT_PARAM_ONOFF, true)
  end

  Menu.Harras:addParam("useEQ", "Use EQ", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("rangeEQ", "Dont use EQ in close range", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("saveEQ", "Force save EQ", SCRIPT_PARAM_ONOFF, false)
  Menu.Harras:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useE", "Use E", SCRIPT_PARAM_ONOFF, true)

  Menu.Farm:addSubMenu("[Lasthit]", "Lasthit")
  Menu.Farm.Lasthit:addParam("lasthitQ", "Use Q for lasthit", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Lasthit:addParam("lasthitQmana", "% Mana for lasthit", SCRIPT_PARAM_SLICE, 60, 0, 100, 0)
  Menu.Farm:addSubMenu("[Clear]", "Laneclear")
  Menu.Farm.Laneclear:addParam("laneclearQ", "Use Q for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearMana", "% Mana for clear", SCRIPT_PARAM_SLICE, 50, 0, 100, 0)

  Menu.Draws:addParam("drawQ", "Draw Q range", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawE", "Draw E range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("drawR", "Draw R range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("drawHP", "Draw damage on HP bars", SCRIPT_PARAM_ONOFF, true)

  Menu.KS:addParam("ksQ", "Use Q for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksE", "Use E for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksR", "Use R for killsteal", SCRIPT_PARAM_ONOFF, true)
end

function Jarvan_Tick()
  if FOCUSED ~= nil then
    if FOCUSED.dead or not FOCUSED.visible then
      FOCUSED = nil
    end
  end
  
  if Menu.Key.combo then
    Jarvan_Combo()
  end
  
  if Menu.Key.harras then
    Jarvan_Harras()
  end
  
  if Menu.Key.lasthit then
    Jarvan_Lasthit()
  end
  
  if Menu.Key.laneclear then
    Jarvan_Clear()
  end
  
  Jarvan_Killsteal()
  
  if Menu.Key.flee then
    Jarvan_Flee()
  end
end

function Jarvan_Combo()
  if CanCast(_E) and CanCast(_Q) and Menu.Combo.useEQ then
    local target = GetHentaiTarget(JARVAN_VARS.E.RANGE)
    if target ~= nil then
      if Menu.Combo.rangeEQ then
        if GetRastoyanie(myHero, target) <= 300 then
          if TITANIC and CanCast(_R) then
            CastTITANIC()
          end
          Jarvan_CastQ(target)
        else
          if TITANIC and CanCast(_R) then
            CastTITANIC()
          end
          Jarvan_CastEQ(target)
        end
      else
        if TITANIC and CanCast(_R) then
          CastTITANIC()
        end
        Jarvan_CastEQ(target)
      end
    end
  end
  if CanCast(_Q) and Menu.Combo.rangeEQ and Menu.Combo.useQ then
    local target = GetHentaiTarget(JARVAN_VARS.Q.RANGE)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= 300 then
        Jarvan_CastQ(target)
      end
    end
  end
  if CanCast(_Q) and (not Menu.Combo.saveEQ or not CanCast(_E)) and Menu.Combo.useQ then
    local target = GetHentaiTarget(JARVAN_VARS.Q.RANGE)
    if target ~= nil then
      Jarvan_CastQ(target)
    end
  end
  if CanCast(_W) and Menu.Combo.useW then
    local target = GetHentaiTarget(JARVAN_VARS.W.RADIUS)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= JARVAN_VARS.W.RADIUS then
        Jarvan_CastW() 
      end
    end
  end
  if CanCast(_R) and Menu.Combo.useR and not CATACLYSM and Menu.Combo.burstR then
    local target = GetHentaiTarget(JARVAN_VARS.R.RANGE)
    if target ~= nil then
      if isWhitelistedforR(target) then
        Jarvan_CastR(target)
      end
    end
  end
  if Menu.Item.UseItem then
    local target = GetHentaiTarget(500)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= 200 then
        CastYoumu()
        CastTiamat()
      end
      CastBOTRK(target)
      CastGunblade(target)
      CastCutlass(target)
    end
  end
end

function Jarvan_Harras()
  if CanCast(_E) and CanCast(_Q) and Menu.Harras.useEQ then
    local target = GetHentaiTarget(JARVAN_VARS.E.RANGE)
    if target ~= nil then
      if Menu.Harras.rangeEQ then
        if GetRastoyanie(myHero, target) <= 300 then
          
        else
          Jarvan_CastEQ(target)
        end
      else
        Jarvan_CastEQ(target)
      end
    end
  end
  if CanCast(_Q) and Menu.Harras.rangeEQ and Menu.Harras.useQ then
    local target = GetHentaiTarget(JARVAN_VARS.Q.RANGE)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= 300 then
        Jarvan_CastQ(target)
      end
    end
  end
  if CanCast(_Q) and (not Menu.Harras.saveEQ or not CanCast(_E)) and Menu.Harras.useQ then
    local target = GetHentaiTarget(JARVAN_VARS.Q.RANGE)
    if target ~= nil then
      Jarvan_CastQ(target)
    end
  end
  if CanCast(_W) and Menu.Harras.useW then
    local target = GetHentaiTarget(JARVAN_VARS.W.RADIUS)
    if target ~= nil then
      Jarvan_CastW()
    end
  end
end

function Jarvan_Lasthit()
  if not Menu.Farm.Lasthit.lasthitQ  then return end
  if ((myHero.mana*100)/myHero.maxMana) <= Menu.Farm.Lasthit.lasthitQmana then return end 
  for _, minion in pairs(minionManager(MINION_ENEMY, JARVAN_VARS.Q.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects) do
    if ValidTarget(minion, JARVAN_VARS.Q.RANGE) then
      local QDmg = Jarvan_GetQDamage(minion)
      if QDmg >= minion.health and CanCast(_Q) then
        Jarvan_CastQ(minion)
      end
    end
  end
end

function Jarvan_Clear()
  if ((myHero.mana*100)/myHero.maxMana) <= Menu.Farm.Laneclear.laneclearMana then return end
  for _, minion in pairs(minionManager(MINION_ENEMY, JARVAN_VARS.Q.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects) do
    if ValidTarget(minion, JARVAN_VARS.Q.RANGE) then
      if CanCast(_Q) and Menu.Farm.Laneclear.laneclearQ then
        local CastPosition1, NumHit1 = GetBestLineFarmPosition(JARVAN_VARS.Q.RANGE, JARVAN_VARS.Q.WIDTH, minionManager(MINION_ENEMY, JARVAN_VARS.Q.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects)
        if CastPosition1 ~= nil then
          CastSpell(_Q, CastPosition1.x, CastPosition1.z)
        end
      end
    end
  end
  for _, minion in pairs(minionManager(MINION_JUNGLE, JARVAN_VARS.Q.RANGE, myHero, MINION_SORT_MAXHEALTH_DEC).objects) do
    if ValidTarget(minion, JARVAN_VARS.Q.RANGE) then
      if CanCast(_Q) and Menu.Farm.Laneclear.laneclearQ then
        Jarvan_CastQ(minion)
      end
    end
  end
end

function Jarvan_Killsteal()
  for i,enemy in pairs(GetEnemyHeroes()) do
    if isValid(enemy, JARVAN_VARS.E.RANGE) and not CheckInvul(enemy) then
      local QDmg = Jarvan_GetQDamage(enemy)
      local EDmg = Jarvan_GetEDamage(enemy)
      local RDmg = Jarvan_GetRDamage(enemy)
      if CanCast(_Q) and Menu.KS.ksQ and QDmg >= enemy.health and not enemy.dead then
        Jarvan_CastQ(enemy)
      end
      if CanCast(_E) and Menu.KS.ksE and EDmg >= enemy.health and not enemy.dead then
        Jarvan_CastE(enemy)
      end
      if CanCast(_R) and Menu.KS.ksR and RDmg >= enemy.health and not enemy.dead and not CATACLYSM then
        Jarvan_CastR(enemy)
      end
    end
  end
end

function Jarvan_Flee()
  if GetRastoyanie(mousePos, myHero) > 300 then
    local a = (mousePos.x - myHero.x)/GetRastoyanie(mousePos, myHero) * 300 + myHero.x
    local b = (mousePos.z - myHero.z)/GetRastoyanie(mousePos, myHero) * 300 + myHero.z
    myHero:MoveTo(a, b)
  else
    myHero:MoveTo(mousePos.x, mousePos.z)
  end
  if CanCast(_Q) and CanCast(_E) then
    if GetRastoyanie(mousePos, myHero) > JARVAN_VARS.E.RANGE then
      local a = (mousePos.x - myHero.x)/GetRastoyanie(mousePos, myHero) * JARVAN_VARS.E.RANGE + myHero.x
      local b = (mousePos.z - myHero.z)/GetRastoyanie(mousePos, myHero) * JARVAN_VARS.E.RANGE + myHero.z
      CastSpell(_E, a, b)
      CastSpell(_Q, a, b)
    else
      CastSpell(_E, mousePos.x, mousePos.z)
      CastSpell(_Q, mousePos.x, mousePos.z)
    end
  end
end

function isWhitelistedforR(enemy)
  local index = whitelistIndex(enemy)
  if index == 1 then
    if Menu.Combo.whitelistR.a1 then
      return true
    else
      return false
    end
  end
  if index == 2 then
    if Menu.Combo.whitelistR.a2 then
      return true
    else
      return false
    end
  end
  if index == 3 then
    if Menu.Combo.whitelistR.a3 then
      return true
    else
      return false
    end
  end
  if index == 4 then
    if Menu.Combo.whitelistR.a4 then
      return true
    else
      return false
    end
  end
  if index == 5 then
    if Menu.Combo.whitelistR.a5 then
      return true
    else
      return false
    end
  end
end

function whitelistIndex(enemy)
  for i = 1, #YOLO do
    if enemy.charName == YOLO[i] then
      return i
    end
  end
end

function Jarvan_GetQDamage(unit)
  local Qlvl = myHero:GetSpellData(_Q).level
  if Qlvl < 1 then return 0 end
  local QDmg = {70, 115, 160, 205, 250}
  local bonusAD = myHero.totalDamage - myHero.damage
  local QDmgMod = 1.2
  local DmgRaw = QDmg[Qlvl] + bonusAD * QDmgMod
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function Jarvan_GetEDamage(unit)
  local Elvl = myHero:GetSpellData(_E).level
  if Elvl < 1 then return 0 end
  local EDmg = {60, 105, 150, 195, 240}
  local EDmgMod = 0.8
  local DmgRaw = EDmg[Elvl] + myHero.ap * EDmgMod
  local Dmg = myHero:CalcMagicDamage(unit, DmgRaw)
  return Dmg
end

function Jarvan_GetRDamage(unit)
  local Rlvl = myHero:GetSpellData(_R).level
  if Rlvl < 1 then return 0 end
  local RDmg = {200, 325, 450}
  local RDmgMod = 1.5
  local DmgRaw = RDmg[Rlvl] + myHero.totalDamage * RDmgMod
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function Jarvan_CastQ(unit)
  if unit == nil then
    return
  end
  local CastPosition, HitChance = VP:GetLineCastPosition(unit, JARVAN_VARS.Q.DELAY, JARVAN_VARS.Q.WIDTH, JARVAN_VARS.Q.RANGE, JARVAN_VARS.Q.SPEED, myHero, false)
  if HitChance >= 2 then
    CastSpell(_Q, CastPosition.x, CastPosition.z)
  end
end

function Jarvan_CastW()
  CastSpell(_W)
end

function Jarvan_CastE(unit)
  if unit == nil then
    return
  end
  local CastPosition, HitChance = VP:GetCircularCastPosition(unit, JARVAN_VARS.E.DELAY, JARVAN_VARS.E.RADIUS, JARVAN_VARS.E.RANGE, JARVAN_VARS.E.SPEED, myHero, false)
  if HitChance >= 2 then
    CastSpell(_E, CastPosition.x, CastPosition.z)
  end
end

function Jarvan_CastEQ(unit)
  if unit == nil then
    return
  end
  local CastPosition, HitChance = VP:GetCircularCastPosition(unit, JARVAN_VARS.E.DELAY, JARVAN_VARS.E.RADIUS, JARVAN_VARS.E.RANGE, JARVAN_VARS.E.SPEED, myHero, false)
  if HitChance >= 2 then
    local rastoyanie = GetRastoyanie(myHero, CastPosition)
    local a = (CastPosition.x - myHero.x)/rastoyanie * (rastoyanie + 50) + myHero.x
    local b = (CastPosition.z - myHero.z)/rastoyanie * (rastoyanie + 50) + myHero.z
    if CanCast(_R) then
      CastTITANIC()
    end
    CastSpell(_E, a, b)
    CastSpell(_Q, a, b)
  end
end

function Jarvan_CastR(unit)
  if unit ~= nil then
    CastSpell(_R, unit)
  end
end

function Jarvan_DrawHPbar()
  for i, HPbarEnemyChamp in pairs(GetEnemyHeroes()) do
    if not HPbarEnemyChamp.dead and HPbarEnemyChamp.visible then
      local dmg = myHero:CalcDamage(HPbarEnemyChamp, myHero.totalDamage)
      if myHero:CanUseSpell(_Q) == READY and not HPbarEnemyChamp.dead then
        dmg = dmg + Jarvan_GetQDamage(HPbarEnemyChamp)
      end
      if myHero:CanUseSpell(_R) == READY and not HPbarEnemyChamp.dead then
        dmg = dmg + Jarvan_GetRDamage(HPbarEnemyChamp)
      end
      if myHero:CanUseSpell(_E) == READY and not HPbarEnemyChamp.dead then
        dmg = dmg + Jarvan_GetEDamage(HPbarEnemyChamp)
      end
      DrawLineHPBar(dmg, "", HPbarEnemyChamp, HPbarEnemyChamp.team)
    end
  end
end

function Jarvan_Draw()
  if Menu.Draws.drawQ then
    DrawFPSCircle(myHero.x, myHero.z, JARVAN_VARS.Q.RANGE, ARGB(255,193,61,255), 24)
  end
  if Menu.Draws.drawE then
    DrawFPSCircle(myHero.x, myHero.z, JARVAN_VARS.E.RANGE, ARGB(255,193,61,255), 24)
  end
  if Menu.Draws.drawR then
    DrawFPSCircle(myHero.x, myHero.z, JARVAN_VARS.R.RANGE, ARGB(255,193,61,255), 24)
  end
  if Menu.Draws.drawHP then
    Jarvan_DrawHPbar()
  end
end

function Jarvan_OnProcessSpell(unit, spell)
  if spell ~= nil and spell.target ~= nil and unit ~= nil then
    if FAKER[spell.name] ~= nil and spell.target.isMe and CanCast(_W) then
      Jarvan_CastW()
    end
  end
end

function Jarvan_OnCreateObj(obj)
  if obj ~= nil then
    if obj.name == "JarvanIVWall" then
      CATACLYSM = true
    end
  end
end

function Jarvan_OnDeleteObj(obj)
  if obj ~= nil then
    if obj.name == "JarvanIVWall" then
      CATACLYSM = false
    end
  end
end

function Jarvan_ProcessAttack(unit, spell)
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type ~= myHero.type and Menu.Key.laneclear then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    local reseted = false
    if AADmg < spell.target.health and TITANIC and not reseted then
      if CanCast(TITANICSLOT) then
        CastTITANIC()
        if SAC then
          _G.AutoCarry.MyHero:MovementEnabled(false)
          _G.AutoCarry.MyHero:AttacksEnabled(false)
          myHero:Attack(spell.target)
          DelayAction(function()
            _G.AutoCarry.MyHero:MovementEnabled(true)
            _G.AutoCarry.MyHero:AttacksEnabled(true)
          end, 0.1)
        end
        reseted = true
      end
    end
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.combo then
    local reseted = false
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if Menu.Combo.useR and isWhitelistedforR(spell.target) then
      Jarvan_CastR(spell.target)
    end
    if AADmg < spell.target.health and TITANIC and not reseted then
      if CanCast(TITANICSLOT) then
        CastTITANIC()
        if SAC then
          _G.AutoCarry.MyHero:MovementEnabled(false)
          _G.AutoCarry.MyHero:AttacksEnabled(false)
          myHero:Attack(spell.target)
          DelayAction(function()
            _G.AutoCarry.MyHero:MovementEnabled(true)
            _G.AutoCarry.MyHero:AttacksEnabled(true)
          end, 0.1)
        end
        reseted = true
      end
    end
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.harras then
    local reseted = false
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if AADmg < spell.target.health and TITANIC and not reseted then
      if CanCast(TITANICSLOT) then
        CastTITANIC()
        if SAC then
          _G.AutoCarry.MyHero:MovementEnabled(false)
          _G.AutoCarry.MyHero:AttacksEnabled(false)
          myHero:Attack(spell.target)
          DelayAction(function()
            _G.AutoCarry.MyHero:MovementEnabled(true)
            _G.AutoCarry.MyHero:AttacksEnabled(true)
          end, 0.1)
        end
        reseted = true
      end
    end
  end
end

function Talon_Load()
  require "VPrediction"
  VP = VPrediction()

  AddProcessAttackCallback(Talon_ProcessAttack)

  ATTACKQ = false
  ULTPOS = nil
  TALON_VARS = {
    AA = {RANGE = 125},
    Q = {RANGE = 550, MRANGE = 170},
    W = {RANGE = 850, SPEED = 2300, DELAY = 0.25, WIDTH = 75},
    R = {RADIUS = 600, RANGE = 600}
  }

  Menu.Key:addParam("combo", "Combo", SCRIPT_PARAM_ONKEYDOWN, false, string.byte(" "))
  Menu.Key:addParam("harras", "Harras", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("C"))
  Menu.Key:addParam("lasthit", "Lasthit", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("X"))
  Menu.Key:addParam("laneclear", "Laneclear/Jungleclear", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("V"))

  Menu.Combo:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useR", "Use R", SCRIPT_PARAM_ONOFF, true)

  Menu.Harras:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("harrasMana", "% Mana for harras", SCRIPT_PARAM_SLICE, 50, 0, 100, 0)

  Menu.Farm:addSubMenu("[Lasthit]", "Lasthit")
  Menu.Farm.Lasthit:addParam("lasthitQ", "Use Q for lasthit", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Lasthit:addParam("lasthitQmana", "% Mana for lasthit", SCRIPT_PARAM_SLICE, 60, 0, 100, 0)
  Menu.Farm:addSubMenu("[Clear]", "Laneclear")
  Menu.Farm.Laneclear:addParam("laneclearQ", "Use Q for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearW", "Use W for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearMana", "% Mana for clear", SCRIPT_PARAM_SLICE, 30, 0, 100, 0)
  Menu.Farm:addSubMenu("[Jungle Clear]", "JLaneclear")
  Menu.Farm.JLaneclear:addParam("laneclearQ", "Use Q for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.JLaneclear:addParam("laneclearW", "Use W for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.JLaneclear:addParam("laneclearMana", "% Mana for clear", SCRIPT_PARAM_SLICE, 30, 0, 100, 0)

  Menu.Draws:addParam("drawW", "Draw W range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("drawQ", "Draw Q range", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawR", "Draw R range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("drawHP", "Draw damage on HP bars", SCRIPT_PARAM_ONOFF, true)

  Menu.KS:addParam("ksQ", "Use Q for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksW", "Use W for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksR1", "Use R1 for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksR2", "Use R2 for killsteal", SCRIPT_PARAM_ONOFF, true)
end

function Talon_Tick()
  if FOCUSED ~= nil then
    if FOCUSED.dead or not FOCUSED.visible then
      FOCUSED = nil
    end
  end
  
  Talon_Killsteal()
  
  if Menu.Key.combo then
    Talon_Combo()
  end
  
  if Menu.Key.harras then
    Talon_Harras()
  end
  
  if Menu.Key.lasthit then
    Talon_Lasthit()
  end
  
  if Menu.Key.laneclear then
    Talon_Laneclear()
  end
end

function Talon_Draw()
  if not myHero.dead then
    if Menu.Draws.drawW then
      DrawFPSCircle(myHero.x, myHero.z, TALON_VARS.W.RANGE, ARGB(255,193,61,255), 24)
    end
    if Menu.Draws.drawQ then
      DrawFPSCircle(myHero.x, myHero.z, TALON_VARS.Q.RANGE, ARGB(255,193,61,255), 24)
    end
    if Menu.Draws.drawR then
      DrawFPSCircle(myHero.x, myHero.z, TALON_VARS.R.RADIUS, ARGB(255,193,61,255), 24)
    end
    if Menu.Draws.drawTarget then
      DrawSelectedTarget()
    end
    if Menu.Draws.drawHP then
      DrawHP()
    end
  end
end

function DrawHP()
  for i, enemy in pairs(GetEnemyHeroes()) do
    if enemy.visible and not enemy.dead then
      local totalDMG = 0  
      local dmg = myHero:CalcDamage(enemy, myHero.totalDamage)
      totalDMG = totalDMG + dmg
      if CanCast(_Q) then
        totalDMG = totalDMG + Talon_GetQDamage(enemy)
      end
      if CanCast(_W) then
        totalDMG = totalDMG + Talon_GetWDamage(enemy)
      end
      if CanCast(_R) then
        totalDMG = totalDMG + 2*Talon_GetRDamage(enemy)
      end
      DrawLineHPBar(totalDMG+totalDMG*0.13, "", enemy, enemy.team)
    end
  end
end

function Talon_Killsteal()
  for i,enemy in pairs(GetEnemyHeroes()) do
    if not CheckInvul(enemy) then
      local rastoyanie = GetRastoyanie(myHero, enemy)
      if (ValidTarget(enemy, TALON_VARS.W.RANGE)) then
        local QDmg = Talon_GetQDamage(enemy)
        local WDmg = Talon_GetWDamage(enemy)
        local RDmg = Talon_GetRDamage(enemy)
        if rastoyanie <= TALON_VARS.W.RANGE and WDmg >= enemy.health and Menu.KS.ksW and CanCast(_W) then
          Talon_CastW(enemy)
        end
        if rastoyanie <= TALON_VARS.Q.RANGE and CanCast(_Q) and QDmg >= enemy.health and Menu.KS.ksQ then
          Talon_CastQ(enemy)
        end
        if rastoyanie <= TALON_VARS.R.RADIUS and RDmg >= enemy.health and Menu.KS.ksR1 and not TargetHaveBuff("talonrstealth", myHero) and CanCast(_R) then
          Talon_CastR()
        end
        if ULTPOS then
          if GetRastoyanie(ULTPOS, enemy) <= (TALON_VARS.R.RADIUS+50) and RDmg >= enemy.health and Menu.KS.ksR2 and TargetHaveBuff("talonrstealth", myHero) and CanCast(_R) then
            Talon_CastR()
          end
        end
      end
    end
  end
end

function Talon_Combo()
  local target = GetHentaiTarget(TALON_VARS.Q.RANGE)
  if target then
    if not CanCast(_Q) then
      if CanCast(_W) and Menu.Combo.useW then
        Talon_CastW(target)
      end
      if CanCast(_R) and Menu.Combo.useR and not TargetHaveBuff("talonrstealth", myHero) and GetRastoyanie(target) <= (TALON_VARS.R.RANGE-50) then
        Talon_CastR()
      end
    end
    if GetRastoyanie(myHero, target) <= 600 then
      if CanCast(_W) and Menu.Combo.useW then
        Talon_CastW(target)
      end
      if CanCast(_Q) and Menu.Combo.useQ then
        Talon_CastQ(target)
      end
      if Menu.Item.UseItem then
        if GetRastoyanie(myHero, target) <= 250 then
          CastYoumu()
        end
        CastBOTRK(target)
        CastGunblade(target)
        CastCutlass(target)
      end
    else
      if CanCast(_Q) and Menu.Combo.useQ then
        Talon_CastQ(target)
      end
      if CanCast(_W) and Menu.Combo.useW then
        Talon_CastW(target)
      end
      if Menu.Item.UseItem then
        if GetRastoyanie(myHero, target) <= 250 then
          CastYoumu()
        end
        CastBOTRK(target)
        CastGunblade(target)
        CastCutlass(target)
      end
    end
  end
  local target = GetHentaiTarget(TALON_VARS.W.RANGE)
  if target and not TargetHaveBuff("talonrstealth", myHero) then
    if CanCast(_W) and Menu.Combo.useW then
      Talon_CastW(target)
    end
  end
end

function Talon_Harras()
  if ((myHero.mana*100)/myHero.maxMana) < Menu.Harras.harrasMana then return end
  local target = GetHentaiTarget(TALON_VARS.Q.RANGE)
  if target then
    if GetRastoyanie(myHero, target) <= 600 then
      if CanCast(_W) and Menu.Harras.useW then
        Talon_CastW(target)
      end
      if CanCast(_Q) and Menu.Harras.useQ then
        Talon_CastQ(target)
      end
      if Menu.Item.UseItem then
        CastCutlass(target)
      end
    else
      if CanCast(_Q) and Menu.Harras.useQ then
        Talon_CastQ(target)
      end
      if CanCast(_W) and Menu.Harras.useW then
        Talon_CastW(target)
      end
      if Menu.Item.UseItem then
        CastCutlass(target)
      end
    end
  end
  local target = GetHentaiTarget(TALON_VARS.W.RANGE)
  if target and not TargetHaveBuff("talonrstealth", myHero) then
    if CanCast(_W) and Menu.Combo.useW then
      Talon_CastW(target)
    end
  end
end

function Talon_Lasthit()
  if ((myHero.mana*100)/myHero.maxMana) <= Menu.Farm.Lasthit.lasthitQmana then return end
  for _, minion in pairs(minionManager(MINION_ENEMY, 225, myHero, MINION_SORT_HEALTH_ASC).objects) do
    local QDmg = Talon_GetQDamage(minion)
    if QDmg >= minion.health and Menu.Farm.Lasthit.lasthitQ and ATTACKQ then
      Talon_CastQ(minion)
    end
  end
end

function Talon_Laneclear()
  if ((myHero.mana*100)/myHero.maxMana) <= Menu.Farm.Laneclear.laneclearMana then return end
  if CanCast(_W) and Menu.Farm.Laneclear.laneclearW then
    local CastPosition, NumHit = GetBestLineFarmPosition(TALON_VARS.W.RANGE, TALON_VARS.W.WIDTH, minionManager(MINION_ENEMY, TALON_VARS.W.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects)
    if CastPosition ~= nil then
      CastSpell(_W, CastPosition.x, CastPosition.z)
    end
  end
  if CanCast(_W) and Menu.Farm.JLaneclear.laneclearW then
    local CastPositionJgl, NumHitJgl = GetBestLineFarmPosition(TALON_VARS.W.RANGE, TALON_VARS.W.WIDTH, minionManager(MINION_JUNGLE, TALON_VARS.W.RANGE, myHero, MINION_SORT_MAXHEALTH_DEC).objects)
    if CastPositionJgl ~= nil then
      CastSpell(_W, CastPositionJgl.x, CastPositionJgl.z)
    end
  end
end


function Talon_ProcessAttack(unit,spell)
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type ~= myHero.type and Menu.Key.lasthit then
    ATTACKQ = true
    DelayAction(function() ATTACKQ = false end, 1)
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type ~= myHero.type and Menu.Key.laneclear then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if CanCast(_Q) and AADmg < spell.target.health and ((myHero.mana*100)/myHero.maxMana) >= Menu.Farm.Laneclear.laneclearMana then
      if Menu.Farm.Laneclear.laneclearQ then
        Talon_CastQ(spell.target)
      end
    end
    if AADmg < spell.target.health and not CanCast(_Q) then
      CastTITANIC()
    end
    if not CanCast(_Q) then
      CastTiamat()
    end
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.combo then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if CanCast(_Q) and AADmg < spell.target.health then
      if Menu.Combo.useQ then
        Talon_CastQ(spell.target)
      end
    end
    if not CanCast(_Q) then
      CastTiamat()
    end
    if Menu.Combo.useR and CanCast(_R) and not CanCast(_W) and not CanCast(_E) and not TargetHaveBuff("talonnoxiandiplomacybuff") then
      Talon_CastR()
    end
    if string.lower(spell.name) == "talonnoxiandiplomacyattack" then
      CastTiamat()
      if Menu.Combo.useR and CanCast(_R) then
        DelayAction(function() Talon_CastR() end, 0.9)
      end
    end
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.harras then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if CanCast(_Q) and AADmg < spell.target.health then
      if Menu.Combo.useQ then
        Talon_CastQ(spell.target)
      end
    end
    if not CanCast(_Q) then
      CastTiamat()
    end
  end
end

function Talon_GetQDamage(unit)
  local Qlvl = myHero:GetSpellData(_Q).level
  if Qlvl < 1 then return 0 end
  local QDmg = {80, 100, 120, 140, 160}
  local DmgRaw = QDmg[Qlvl] + (myHero.totalDamage - myHero.damage)*1
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function Talon_GetWDamage(unit)
   local Wlvl = myHero:GetSpellData(_W).level
  if Wlvl < 1 then return 0 end
  local WDmg = {110, 150, 190, 230, 270}
  local WDmgMod = 1.1
  local DmgRaw = WDmg[Wlvl] + (myHero.totalDamage - myHero.damage) * WDmgMod
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function Talon_GetRDamage(unit)
  local Rlvl = myHero:GetSpellData(_R).level
  if Rlvl < 1 then return 0 end
  local RDmg = {80, 120, 160}
  local RDmgMod = 0.8
  local DmgRaw = RDmg[Rlvl] + (myHero.totalDamage - myHero.damage) * RDmgMod
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function Talon_CastQ(unit)
  CastSpell(_Q, unit)
  OrbsReset()
end

function Talon_CastW(unit)
  if VP ~= nil then
    local CastPosition, HitChance = VP:GetLineCastPosition(unit, TALON_VARS.W.DELAY, TALON_VARS.W.WIDTH, TALON_VARS.W.RANGE, TALON_VARS.W.SPEED, myHero, false)
    if HitChance >= 2 then
      CastSpell(_W, CastPosition.x, CastPosition.z)
    end
  end
end

function Talon_CastR()
  CastSpell(_R)
end

function Olaf_Load()
	FHPred = false

	AddProcessAttackCallback(Olaf_ProcessAttack)
	AddApplyBuffCallback(olaf_buff_add)
	AddRemoveBuffCallback(olaf_buff_del)
  AddCreateObjCallback(olaf_CreateObj)
  AddDeleteObjCallback(olaf_DeleteObj)

	OLAF_VARS = {
		AA = {RANGE = 125},
		Q = {RANGE = 1000, SPEED = 1600, DELAY = 0.25, WIDTH = 85},
		E = {RANGE = 325}
	}
	olafQ = {range = OLAF_VARS.Q.RANGE, speed = OLAF_VARS.Q.SPEED, delay = OLAF_VARS.Q.DELAY, radius = OLAF_VARS.Q.WIDTH, type = "DelayLine", width = OLAF_VARS.Q.WIDTH}

  Menu.Key:addParam("combo", "Combo", SCRIPT_PARAM_ONKEYDOWN, false, string.byte(" "))
  Menu.Key:addParam("harras", "Harras", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("C"))
  Menu.Key:addParam("laneclear", "Laneclear/Jungleclear", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("V"))

  Menu.Prediction:addParam("activePred", "Prediction (require reload)", SCRIPT_PARAM_LIST, 1, {"VPred", "FHPred"})
  if Menu.Prediction.activePred == 1 then
    if FileExist(LIB_PATH .. "VPrediction.lua") then
      require "VPrediction"
      VP = VPrediction()
      Menu.Prediction:addParam("QVPHC", "Q HitChance", SCRIPT_PARAM_SLICE, 2, 1, 5, 0)
    end
  elseif Menu.Prediction.activePred == 2 then
  	if FileExist(LIB_PATH.."FHPrediction.lua") then
      require("FHPrediction")
      FHPred = true
      PrintChat("Hentai Bundle: FHPrediction found")
      Menu.Prediction:addParam("infoFH", "FHPrediction found", SCRIPT_PARAM_INFO, "")
    else
      PrintChat("Something wrong with FHPred, contact developer")
    end
  end

  Menu.Combo:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("useE", "Use E", SCRIPT_PARAM_ONOFF, true)

  Menu.Harras:addParam("useQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("useW", "Use W", SCRIPT_PARAM_ONOFF, false)
  Menu.Harras:addParam("useE", "Use E", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("harrasMana", "% Mana for harras", SCRIPT_PARAM_SLICE, 50, 0, 100, 0)

  Menu.Farm:addSubMenu("[Clear]", "Laneclear")
  Menu.Farm.Laneclear:addParam("laneclearQ", "Use Q for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearW", "Use W for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearE", "Use E for clear", SCRIPT_PARAM_ONOFF, true)
  Menu.Farm.Laneclear:addParam("laneclearMana", "% Mana for clear", SCRIPT_PARAM_SLICE, 30, 0, 100, 0)
  
  Menu.Draws:addParam("drawQ", "Draw Q range", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawAxe", "Draw Axe pos", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawE", "Draw E range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("drawHP", "Draw damage on HP bars", SCRIPT_PARAM_ONOFF, true)

  Menu.KS:addParam("ksQ", "Use Q for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksE", "Use E for killsteal", SCRIPT_PARAM_ONOFF, true)

  Menu.Auto:addParam("autoOlafR", "Auto R usage", SCRIPT_PARAM_ONOFF, true)
end

function Olaf_Tick()
	if FOCUSED ~= nil then
    if FOCUSED.dead or not FOCUSED.visible then
      FOCUSED = nil
    end
  end

  Olaf_Killsteal()

  if Menu.Key.combo then
    Olaf_Combo()
  end

  if Menu.Key.harras then
    Olaf_Harras()
  end

  if Menu.Key.laneclear then
    Olaf_Laneclear()
  end

  if Menu.Auto.autoOlafR then
  	olaf_auto_r()
  end
end

function Olaf_Draw()
  if not myHero.dead then
    if Menu.Draws.drawQ then
    	DrawFPSCircle(myHero.x, myHero.z, OLAF_VARS.Q.RANGE, ARGB(255,193,61,255), 24)
  	end
    if Menu.Draws.drawAxe and olaf_axe then
      DrawFPSCircle(olaf_axe.x, olaf_axe.z, 60, ARGB(255,230,61,255), 24)
      DrawFPSCircle(olaf_axe.x, olaf_axe.z, 80, ARGB(255,230,61,255), 24)
    end
    if Menu.Draws.drawE then
      DrawFPSCircle(myHero.x, myHero.z, OLAF_VARS.E.RANGE, ARGB(255,193,61,255), 24)
    end
    if Menu.Draws.drawHP then
      Olaf_DrawHP()
    end
  end
end

function olaf_CreateObj(obj)
  if obj then
    if obj.name == "Olaf_Base_Q_Axe_Ally.troy" then
      olaf_axe = obj
    end
  end
end

function olaf_DeleteObj(obj)
  if obj then
    if obj.name == "Olaf_Base_Q_Axe_Ally.troy" then
      olaf_axe = nil
    end
  end
end

function Olaf_DrawHP()
	for i, HPbarEnemyChamp in pairs(GetEnemyHeroes()) do
    if not HPbarEnemyChamp.dead and HPbarEnemyChamp.visible then
      local dmg = myHero:CalcDamage(HPbarEnemyChamp, myHero.totalDamage)
      if CanCast(_Q) and not HPbarEnemyChamp.dead then
        dmg = dmg + Olaf_GetQDamage(HPbarEnemyChamp)
      end
      if CanCast(_E) and not HPbarEnemyChamp.dead then
        dmg = dmg + Olaf_GetEDamage(HPbarEnemyChamp)
      end
      DrawLineHPBar(dmg, "", HPbarEnemyChamp, HPbarEnemyChamp.team)
    end
  end
end

function Olaf_Combo()
	if Menu.Combo.useE then
		local target = GetHentaiTarget(OLAF_VARS.E.RANGE)
		if target and CanCast(_E) then
			Olaf_CastE(target)
		end
	end
	if Menu.Item.UseItem then
    local target = GetHentaiTarget(500)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= 200 then
        CastYoumu()
        CastTiamat()
      end
      CastBOTRK(target)
      CastGunblade(target)
      CastCutlass(target)
    end
  end
  if Menu.Combo.useW then
  	local target = GetHentaiTarget(OLAF_VARS.AA.RANGE + 100)
  	if target and CanCast(_W) then
  		Olaf_CastW()
  	end
  end
  if Menu.Combo.useQ then
  	local target = GetHentaiTarget(OLAF_VARS.Q.RANGE)
  	if target and CanCast(_Q) then
  		Olaf_CastQ(target)
  	end
  end
end

function Olaf_Harras()
	if Menu.Harras.useE then
		local target = GetHentaiTarget(OLAF_VARS.E.RANGE)
		if target and CanCast(_E) then
			Olaf_CastE(target)
		end
	end
	if ((myHero.mana*100)/myHero.maxMana) < Menu.Harras.harrasMana then return end
	if Menu.Item.UseItem then
    local target = GetHentaiTarget(500)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= 200 then
        CastYoumu()
        CastTiamat()
      end
      CastCutlass(target)
    end
  end
  if Menu.Harras.useW then
  	local target = GetHentaiTarget(OLAF_VARS.AA.RANGE + 100)
  	if target and CanCast(_W) then
  		Olaf_CastW()
  	end
  end
  if Menu.Harras.useQ then
  	local target = GetHentaiTarget(OLAF_VARS.Q.RANGE)
  	if target and CanCast(_Q) then
  		Olaf_CastQ(target)
  	end
  end
end

function Olaf_Killsteal()
	for i,enemy in pairs(GetEnemyHeroes()) do
    if not CheckInvul(enemy) and isValid(enemy) then
    	if CanCast(_Q) and Menu.KS.ksQ and Olaf_GetQDamage(enemy) >= enemy.health and GetRastoyanie(myHero, enemy) <= OLAF_VARS.Q.RANGE then
    		Olaf_CastQ(enemy)
    	end
    	if CanCast(_E) and Menu.KS.ksE and Olaf_GetEDamage(enemy) >= enemy.health and GetRastoyanie(myHero, enemy) <= OLAF_VARS.E.RANGE then
    		Olaf_CastE(enemy)
    	end
    	if CanCast(_Q) and CanCast(_E) and Menu.KS.ksQ and Menu.KS.ksE and (Olaf_GetQDamage(enemy) + Olaf_GetEDamage(enemy)) >= enemy.health
    	 and GetRastoyanie(myHero, enemy) <= OLAF_VARS.E.RANGE then
    		Olaf_CastQ(enemy)
    	end
    end
  end
end

function Olaf_Laneclear()
	for _, minion in pairs(minionManager(MINION_ENEMY, OLAF_VARS.E.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects) do
    if ValidTarget(minion, OLAF_VARS.E.RANGE) and CanCast(_E) and Menu.Farm.Laneclear.laneclearE then
    	Olaf_CastE(minion)
    end
  end
  for _, minion in pairs(minionManager(MINION_JUNGLE, OLAF_VARS.E.RANGE, myHero, MINION_SORT_MAXHEALTH_DEC).objects) do
    if ValidTarget(minion, OLAF_VARS.E.RANGE) and CanCast(_E) and Menu.Farm.Laneclear.laneclearE then
    	Olaf_CastE(minion)
    end
  end
  if ((myHero.mana*100)/myHero.maxMana) <= Menu.Farm.Laneclear.laneclearMana then return end
	if CanCast(_Q) and Menu.Farm.Laneclear.laneclearQ then
		local CastPosition, NumHit = GetBestLineFarmPosition(OLAF_VARS.Q.RANGE, OLAF_VARS.Q.WIDTH, minionManager(MINION_ENEMY, OLAF_VARS.Q.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects)
		if CastPosition ~= nil then
      CastSpell(_Q, CastPosition.x, CastPosition.z)
    end
    local CastPositionJgl, NumHitJgl = GetBestLineFarmPosition(OLAF_VARS.Q.RANGE, OLAF_VARS.Q.WIDTH, minionManager(MINION_JUNGLE, OLAF_VARS.Q.RANGE, myHero, MINION_SORT_MAXHEALTH_DEC).objects)
    if CastPositionJgl ~= nil then
      CastSpell(_Q, CastPositionJgl.x, CastPositionJgl.z)
    end
	end
end

function olaf_auto_r()
	if (buff_count >= 3 or UNDERCC or SUPRESSED) and CanCast(_R) then
		Olaf_CastR()
	end
end

function olaf_buff_add(unit, target, buff)
  if target then
  	if BuffTypes[buff.type] and target.isMe then
  		table.insert(buff_list, buff)
  		buff_count = buff_count + 1
  	end
  	if buff.type == 24 and target.isMe then
  		SUPRESSED = true
  		SUPR_BUFF = buff.name
  	end
  end
end

function olaf_buff_del(unit, buff)
  for i=1, #buff_list do
  	if buff_list[i] then
  		if buff_list[i].name == buff.name then
	  		table.remove(buff_list, i)
	  		buff_count = buff_count - 1
  		end
  	end
  end
  if buff and unit then
  	if unit.isMe and buff.name == SUPR_BUFF then
  		SUPRESSED = false
  	end
  end
end

function Olaf_CastQ(unit)
	if unit == nil then return end
	if VP then
		local CastPosition, HitChance = VP:GetLineCastPosition(unit, OLAF_VARS.Q.DELAY, OLAF_VARS.Q.WIDTH, OLAF_VARS.Q.RANGE, OLAF_VARS.Q.SPEED, myHero, false)
    if HitChance >= Menu.Prediction.QVPHC then
      CastSpell(_Q, CastPosition.x, CastPosition.z)
    end
	end
	if FHPred and Menu.Prediction.activePred == 2 then
		if FHPrediction == nil then 
			print "Something wrong with FHPred, use VPred instead and contact developer"
			return
		end
    local CastPosition, hc, info = FHPrediction.GetPrediction(olafQ, unit)
    if hc > 0 and CastPosition ~= nil then
      CastSpell(_Q, CastPosition.x, CastPosition.z)
    end
  end
end

function Olaf_CastW()
  CastSpell(_W)
end

function Olaf_CastE(unit)
	if unit == nil then return end
	CastSpell(_E, unit)
end

function Olaf_CastR()
  CastSpell(_R)
end

function Olaf_GetQDamage(unit)
  local Qlvl = myHero:GetSpellData(_Q).level
  if Qlvl < 1 then return 0 end
  local QDmg = {70, 115, 160, 205, 250}
  local bonusAD = myHero.totalDamage - myHero.damage
  local QDmgMod = 1
  local DmgRaw = QDmg[Qlvl] + bonusAD * QDmgMod
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function Olaf_GetEDamage()
  local Elvl = myHero:GetSpellData(_E).level
  if Elvl < 1 then return 0 end
  local EDmg = {70, 115, 160, 205, 250}
  local EDmgMod = 0.4
  local DmgRaw = EDmg[Elvl] + myHero.totalDamage * EDmgMod
  return DmgRaw
end

function Olaf_ProcessAttack(unit, spell)
	if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type ~= myHero.type and Menu.Key.laneclear then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    local reseted = false
    if AADmg < spell.target.health and Menu.Farm.Laneclear.laneclearW and CanCast(_W) then
    	Olaf_CastW()
    end
    if AADmg < spell.target.health and TITANIC and not reseted then
      if CanCast(TITANICSLOT) then
        CastTITANIC()
        reseted = true
      end
    end
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.combo then
  	local reseted = false
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if AADmg < spell.target.health and TITANIC and not reseted then
	    if CanCast(TITANICSLOT) then
	      CastTITANIC()
	      reseted = true
	    end
	  end
	  if AADmg < spell.target.health and TIAMAT and not reseted then
	    if CanCast(TIAMATSLOT) then 
	      CastTiamat()
	    end
	  end
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.harras then
    local reseted = false
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if AADmg < spell.target.health and TITANIC and not reseted then
      if CanCast(TITANICSLOT) then
        CastTITANIC()
        reseted = true
      end
      if AADmg < spell.target.health and TIAMAT and not reseted then
		    if CanCast(TIAMATSLOT) then 
		      CastTiamat()
		    end
		  end
    end
  end
end

function Heimer_Load()
  AddTickCallback(heimer_tick)
  AddDrawCallback(heimer_draw)
  AddApplyBuffCallback(heimer_buff_add)
  AddRemoveBuffCallback(heimer_buff_del)

  VP, FHPred, KPred = false
  EMPOWERED = false

  HEIMER_VARS = {
    Q = {RANGE = 300},
    W = {RANGE = 1100, WIDTH = 20, SPEED = 3000, DELAY = 0.5},
    E = {RANGE = 925, SPEED = 1200, WIDTH = 135, DELAY = 0.5},
    E2 = {RANGE = 925 + 500, SPEED = 1200, WIDTH = 250, DELAY = 0.25}
  }

  heimerW = {range = HEIMER_VARS.W.RANGE, speed = HEIMER_VARS.W.SPEED, delay = HEIMER_VARS.W.DELAY, radius = HEIMER_VARS.W.WIDTH, type = "DelayLine", width = HEIMER_VARS.W.WIDTH, collision = true}
  heimerE = {range = HEIMER_VARS.E.RANGE, speed = HEIMER_VARS.E.SPEED, delay = HEIMER_VARS.E.DELAY, radius = HEIMER_VARS.E.WIDTH, type = "DelayCircle", width = HEIMER_VARS.E.WIDTH}
  heimerE2 = {range = HEIMER_VARS.E2.RANGE, speed = HEIMER_VARS.E2.SPEED, delay = HEIMER_VARS.E2.DELAY, radius = HEIMER_VARS.E2.WIDTH, type = "DelayLine", width = HEIMER_VARS.E2.WIDTH}

  Menu.Key:addParam("heimerCombo", "Combo", SCRIPT_PARAM_ONKEYDOWN, false, string.byte(" "))
  Menu.Key:addParam("heimerHarras", "Harras", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("C"))
  Menu.Key:addParam("heimerLaneclear", "Laneclear/Jungleclear", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("V"))

  Menu.Prediction:addParam("activePred", "Prediction (require reload)", SCRIPT_PARAM_LIST, 1, {"VPred", "FHPred"})
  if Menu.Prediction.activePred == 1 then
    if FileExist(LIB_PATH .. "VPrediction.lua") then
      require "VPrediction"
      VP = VPrediction()
      Menu.Prediction:addParam("WVPHC", "W HitChance", SCRIPT_PARAM_SLICE, 2, 1, 5, 0)
      Menu.Prediction:addParam("EVPHC", "E HitChance", SCRIPT_PARAM_SLICE, 2, 1, 5, 0)
    end
  elseif Menu.Prediction.activePred == 2 then
    if FileExist(LIB_PATH.."FHPrediction.lua") then
      require("FHPrediction")
      FHPred = true
      PrintChat("Hentai Bundle: FHPrediction found")
      Menu.Prediction:addParam("infoFH", "FHPrediction found", SCRIPT_PARAM_INFO, "")
    else
      PrintChat("Something wrong with FHPred, contact developer")
    end
  end

  Menu.Combo:addParam("heimerQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("heimerW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("heimerE", "Use E", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("heimerR", "Use R", SCRIPT_PARAM_ONOFF, true)

  Menu.Harras:addParam("heimerQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("heimerW", "Use W", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("heimerE", "Use E", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("harrasMana", "% Mana for harras", SCRIPT_PARAM_SLICE, 50, 0, 100, 0)

  Menu.Farm:addSubMenu("[Clear]", "Laneclear")
  Menu.Farm.Laneclear:addParam("heimerW", "Use W for clear", SCRIPT_PARAM_ONOFF, false)
  Menu.Farm.Laneclear:addParam("heimerE", "Use E for clear", SCRIPT_PARAM_ONOFF, false)
  Menu.Farm.Laneclear:addParam("laneclearMana", "% Mana for clear", SCRIPT_PARAM_SLICE, 65, 0, 100, 0)

  Menu.Draws:addParam("heimerQ", "Draw Q range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("heimerW", "Draw W range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("heimerE", "Draw E range", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawHP", "Draw damage on HP bars", SCRIPT_PARAM_ONOFF, true)

  Menu.KS:addParam("heimerW", "Use W for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("heimerE", "Use E for killsteal", SCRIPT_PARAM_ONOFF, true)
end

function heimer_tick()
  if Menu.Key.heimerCombo then
    heimer_combo()
  end

  if Menu.Key.heimerHarras then
    heimer_harras()
  end

  if Menu.Key.heimerLaneclear then
    heimer_farm()
  end

  if CanCast(_W) or CanCast(_E) then
    heimer_killsteal()
  end
end

function heimer_draw()
  if Menu.Draws.heimerQ then
    DrawFPSCircle(myHero.x, myHero.z, HEIMER_VARS.Q.RANGE, ARGB(255,193,61,255), 24)
  end
  if Menu.Draws.heimerW then
    DrawFPSCircle(myHero.x, myHero.z, HEIMER_VARS.W.RANGE, ARGB(255,193,61,255), 24)
  end
  if Menu.Draws.heimerE then
    DrawFPSCircle(myHero.x, myHero.z, HEIMER_VARS.E.RANGE, ARGB(255,193,61,255), 24)
  end
  if Menu.Draws.drawHP then
    heimer_hpbars()
  end
end

function heimer_hpbars()
  for i, HPbarEnemyChamp in pairs(GetEnemyHeroes()) do
    if not HPbarEnemyChamp.dead and HPbarEnemyChamp.visible then
      local dmg = myHero:CalcDamage(HPbarEnemyChamp, myHero.totalDamage)
      dmg = heimer_get_combo_damage(HPbarEnemyChamp)
      DrawLineHPBar(dmg, "", HPbarEnemyChamp, HPbarEnemyChamp.team)
    end
  end
end

function heimer_combo()
  local target = GetHentaiTargetMagic(HEIMER_VARS.E.RANGE)
  if target and not Menu.Combo.heimerR and not EMPOWERED then
    if CanCast(_E) and Menu.Combo.heimerE then
      heimer_caste(target)
    end
    if CanCast(_W) and Menu.Combo.heimerW then
      heimer_castw(target)
    end
  end
  if target and not CanCast(_R) and not EMPOWERED then
    if CanCast(_E) and Menu.Combo.heimerE then
      heimer_caste(target)
    end
    if CanCast(_W) and Menu.Combo.heimerW then
      heimer_castw(target)
    end
  end
  if target and ((CanCast(_R) and Menu.Combo.heimerR) or EMPOWERED) then
    if EMPOWERED then
      if heimer_count() <= 2 and CanCast(_W) and Menu.Combo.heimerW then
        heimer_castw(target)
      end
      if (heimer_count() > 2 or not CanCast(_W)) and Menu.Combo.heimerQ then
        if GetRastoyanie(target) <= HEIMER_VARS.Q.RANGE then
          heimer_castq(target.x, target.z)
        end
        local a = (target.x - myHero.x)/GetRastoyanie(target) * HEIMER_VARS.Q.RANGE + myHero.x
        local b = (target.z - myHero.z)/GetRastoyanie(target) * HEIMER_VARS.Q.RANGE  + myHero.z
        heimer_castq(a, b)
      end
      if CanCast(_E) and Menu.Combo.heimerE and not CanCast(_Q) and not CanCast(_W) then
        heimer_caste(target)
      end
    else
      if CanCast(_E) and Menu.Combo.heimerE and not CanCast(_W) then
        heimer_caste(target)
      end
      if CanCast(_R) and Menu.Combo.heimerR then
        heimer_castr()
      end
    end
  end
  if target and not CanCast(_W) and not CanCast(_E) and CanCast(_Q) then
    if GetRastoyanie(target) <= HEIMER_VARS.Q.RANGE then
      heimer_castq(target.x, target.z)
    end
    local a = (target.x - myHero.x)/GetRastoyanie(target) * HEIMER_VARS.Q.RANGE + myHero.x
    local b = (target.z - myHero.z)/GetRastoyanie(target) * HEIMER_VARS.Q.RANGE  + myHero.z
    heimer_castq(a, b)
  end
end

function heimer_harras()
  if ((myHero.mana*100)/myHero.maxMana) < Menu.Harras.harrasMana then return end
  local target = GetHentaiTargetMagic(HEIMER_VARS.E.RANGE)
  if target then
    if CanCast(_E) and Menu.Harras.heimerE then
      heimer_caste(target)
    end
    if CanCast(_W) and Menu.Harras.heimerW then
      heimer_castw(target)
    end
    if not CanCast(_W) and not CanCast(_E) and CanCast(_Q) and Menu.Harras.heimerQ then
      if GetRastoyanie(target) <= HEIMER_VARS.Q.RANGE then
        heimer_castq(target.x, target.z)
      end
      local a = (target.x - myHero.x)/GetRastoyanie(target) * HEIMER_VARS.Q.RANGE + myHero.x
      local b = (target.z - myHero.z)/GetRastoyanie(target) * HEIMER_VARS.Q.RANGE  + myHero.z
      heimer_castq(a, b)
    end
  end
end

function heimer_farm()
  if ((myHero.mana*100)/myHero.maxMana) <= Menu.Farm.Laneclear.laneclearMana then return end
  if CanCast(_W) and Menu.Farm.Laneclear.heimerW then
    local CastPosition, NumHit = GetBestLineFarmPosition(HEIMER_VARS.W.RANGE, HEIMER_VARS.W.WIDTH, minionManager(MINION_ENEMY, HEIMER_VARS.W.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects)
    if CastPosition ~= nil then
      CastSpell(_W, CastPosition.x, CastPosition.z)
    end
    local CastPositionJgl, NumHitJgl = GetBestLineFarmPosition(HEIMER_VARS.W.RANGE, HEIMER_VARS.W.WIDTH, minionManager(MINION_JUNGLE, HEIMER_VARS.W.RANGE, myHero, MINION_SORT_MAXHEALTH_DEC).objects)
    if CastPositionJgl ~= nil then
      CastSpell(_W, CastPositionJgl.x, CastPositionJgl.z)
    end
  end
  if CanCast(_E) and Menu.Farm.Laneclear.heimerE then
    local CastPosition, NumHit = GetBestCircularFarmPosition(HEIMER_VARS.E.RANGE, HEIMER_VARS.E.WIDTH, minionManager(MINION_ENEMY, HEIMER_VARS.E.RANGE, myHero, MINION_SORT_HEALTH_ASC).objects)
    if CastPosition ~= nil then
      CastSpell(_E, CastPosition.x, CastPosition.z)
    end
    local CastPositionJgl, NumHit = GetBestCircularFarmPosition(HEIMER_VARS.E.RANGE, HEIMER_VARS.E.WIDTH, minionManager(MINION_JUNGLE, HEIMER_VARS.Q.RANGE, myHero, MINION_SORT_MAXHEALTH_DEC).objects)
    if CastPositionJgl ~= nil then
      CastSpell(_E, CastPositionJgl.x, CastPositionJgl.z)
    end
  end
end

function heimer_killsteal()
  for i,enemy in pairs(GetEnemyHeroes()) do
    if isValid(enemy, HEIMER_VARS.W.RANGE) and not CheckInvul(enemy) then
      local wdmg = heimer_get_w_damage(enemy)
      if wdmg >= enemy.health and CanCast(_W) and Menu.KS.heimerW then
        heimer_castw(enemy)
      end
    end
  end
end

function heimer_buff_add(unit, target, buff)
  if not unit.isMe then return end
  if buff.name == "heimerdingerr" then
    EMPOWERED = true
  end
end

function heimer_buff_del(unit, buff)
  if not unit.isMe then return end
  if buff.name == "heimerdingerr" then
    EMPOWERED = false
  end
end

function heimer_castq(a, b)
  CastSpell(_Q, a, b)
end

function heimer_castw(unit)
  if not unit then return end
  if VP then
    local CastPosition, HitChance = VP:GetLineCastPosition(unit, HEIMER_VARS.W.DELAY, HEIMER_VARS.W.WIDTH, HEIMER_VARS.W.RANGE, HEIMER_VARS.W.SPEED, myHero, true)
    if HitChance >= Menu.Prediction.WVPHC then
      CastSpell(_W, CastPosition.x, CastPosition.z)
    end
  end
  if FHPred and Menu.Prediction.activePred == 2 then
    if FHPrediction == nil then 
      print "Something wrong with FHPred, use VPred instead and contact developer"
      return
    end
    local CastPosition, hc, info = FHPrediction.GetPrediction(heimerW, unit)
    if hc > 0 and CastPosition ~= nil and not info.collision then
      CastSpell(_W, CastPosition.x, CastPosition.z)
    end
  end
end

function heimer_caste(unit)
  if not unit then return end
  if VP then
    local CastPosition, HitChance = VP:GetCircularCastPosition(unit, HEIMER_VARS.E.DELAY, HEIMER_VARS.E.WIDTH, HEIMER_VARS.E.RANGE, HEIMER_VARS.E.SPEED, myHero, false)
    if HitChance >= Menu.Prediction.EVPHC then
      CastSpell(_E, CastPosition.x, CastPosition.z)
    end
  end
  if FHPred and Menu.Prediction.activePred == 2 then
    local CastPosition, hc, info = FHPrediction.GetPrediction(heimerE, unit)
    if hc > 0 and CastPosition ~= nil then
      CastSpell(_E, CastPosition.x, CastPosition.z)
    end
  end
end

function heimer_castr()
  CastSpell(_R)
end

function heimer_get_w_damage(unit)
  local Wlvl = myHero:GetSpellData(_W).level
  if Wlvl < 1 then return 0 end
  local WDmg = {60, 90, 120, 150, 180}
  local WDmg2 = {12, 18, 24, 30, 36}
  local WDmgMod = 0.45
  local WDmgMod2 = 0.09
  local DmgRaw = (WDmg[Wlvl] + myHero.ap * WDmgMod) + (WDmg2[Wlvl] + myHero.ap * WDmgMod2)*4
  local Dmg = myHero:CalcMagicDamage(unit, DmgRaw)
  return Dmg
end

function heimer_get_empw_damage(unit)
  local Wlvl = myHero:GetSpellData(_R).level
  if Wlvl < 1 then return 0 end
  local WDmg = {135, 180, 225}
  local WDmg2 = {27, 36, 45}
  local WDmgMod = 0.45
  local WDmgMod2 = 0.09
  local DmgRaw = (WDmg[Wlvl] + myHero.ap * WDmgMod) + (WDmg2[Wlvl] + myHero.ap * WDmgMod2)*4
  local Dmg = myHero:CalcMagicDamage(unit, DmgRaw)
  return Dmg*2.5
end

function heimer_get_e_damage(unit)
  local Elvl = myHero:GetSpellData(_E).level
  if Elvl < 1 then return 0 end
  local EDmg = {60, 100, 140, 180, 220}
  local EDmgMod = 0.6
  local DmgRaw = EDmg[Elvl] + myHero.ap * EDmgMod
  local Dmg = myHero:CalcMagicDamage(unit, DmgRaw)
  return Dmg
end

function heimer_get_combo_damage(unit)
  Dmg = 0
  if CanCast(_W) and CanCast(_R) then
    Dmg = Dmg + heimer_get_empw_damage(unit)
  elseif CanCast(_W) and not CanCast(_R) then
    Dmg = Dmg + heimer_get_w_damage(unit)
  end
  if CanCast(_E) then
    Dmg = Dmg + heimer_get_e_damage(unit)
  end
  return Dmg
end

function heimer_count()
  local count = 0
  for i,enemy in pairs(GetEnemyHeroes()) do
    if isValid(enemy, VARS.E.RANGE) then
      count = count + 1
    end
  end
  return count
end

function Nocturne_Load()
  AddTickCallback(nocturne_tick)
  AddDrawCallback(nocturne_draw)
  AddProcessAttackCallback(nocturne_pa)
  AddProcessSpellCallback(noc_onprocspell)


  VP, FHPred, KPred = false

  NOCTURNE_VARS = {
    q = {range = 1100, speed = 1400, width = 50, delay = 0.25, type = "DelayLine", radius = 50},
    e = {range = 400}
  }

  r_range = 0

  Menu.Key:addParam("Combo", "Combo", SCRIPT_PARAM_ONKEYDOWN, false, string.byte(" "))
  Menu.Key:addParam("Harras", "Harras", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("C"))
  Menu.Key:addParam("Laneclear", "Laneclear/Jungleclear", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("V"))

  Menu.Prediction:addParam("activePred", "Prediction (require reload)", SCRIPT_PARAM_LIST, 1, {"VPred", "FHPred"})
  if Menu.Prediction.activePred == 1 then
    if FileExist(LIB_PATH .. "VPrediction.lua") then
      require "VPrediction"
      VP = VPrediction()
      Menu.Prediction:addParam("QVPHC", "Q HitChance", SCRIPT_PARAM_SLICE, 2, 1, 5, 0)
    end
  elseif Menu.Prediction.activePred == 2 then
    if FileExist(LIB_PATH.."FHPrediction.lua") then
      require("FHPrediction")
      FHPred = true
      PrintChat("Hentai Bundle: FHPrediction found")
      Menu.Prediction:addParam("infoFH", "FHPrediction found", SCRIPT_PARAM_INFO, "")
    else
      PrintChat("Something wrong with FHPred, contact developer")
    end
  end

  Menu.Combo:addParam("nocturneQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("nocturneE", "Use E", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("nocturneR", "Use R", SCRIPT_PARAM_ONOFF, true)
  Menu.Combo:addParam("nocsmartR", "Use R only on killable enemy", SCRIPT_PARAM_ONOFF, true)

  Menu.Harras:addParam("nocturneQ", "Use Q", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("nocturneE", "Use E", SCRIPT_PARAM_ONOFF, true)
  Menu.Harras:addParam("harrasMana", "% Mana for harras", SCRIPT_PARAM_SLICE, 50, 0, 100, 0)

  Menu.Farm:addSubMenu("[Clear]", "Laneclear")
  Menu.Farm.Laneclear:addParam("nocturneQ", "Use Q for clear", SCRIPT_PARAM_ONOFF, false)
  Menu.Farm.Laneclear:addParam("laneclearMana", "% Mana for clear", SCRIPT_PARAM_SLICE, 65, 0, 100, 0)

  Menu.Auto:addParam("nocturneW", "Auto shield", SCRIPT_PARAM_ONOFF, true)

  Menu.Draws:addParam("nocturneQ", "Draw Q range", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("nocturneE", "Draw E range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("nocturneR", "Draw R range", SCRIPT_PARAM_ONOFF, false)
  Menu.Draws:addParam("drawHP", "Draw damage on HP bars", SCRIPT_PARAM_ONOFF, true)

  Menu.KS:addParam("nocturneQ", "Use Q for killsteal", SCRIPT_PARAM_ONOFF, true)
end

function nocturne_tick()
  r_range = nocturne_get_ult_range()

  if Menu.Key.Combo then
    nocturne_combo()
  end

  if Menu.Key.Harras then
    nocturne_harras()
  end

  if Menu.Key.Laneclear then
    nocturne_farm()
  end

  if CanCast(_W) or CanCast(_E) then
    nocturne_killsteal()
  end
end

function nocturne_draw()
  if not myHero.dead then
    DrawSelectedTarget()
    if Menu.Draws.drawHP then
      nocturne_drawHP()
    end
    if Menu.Draws.nocturneQ then
      DrawFPSCircle(myHero.x, myHero.z, NOCTURNE_VARS.q.range, ARGB(255,193,61,255), 24)
    end
    if Menu.Draws.nocturneE then
      DrawFPSCircle(myHero.x, myHero.z, NOCTURNE_VARS.e.range, ARGB(255,193,61,255), 24)
    end
    if Menu.Draws.nocturneR then
      DrawFPSCircle(myHero.x, myHero.z, r_range, ARGB(255,193,61,255), 24)
    end
  end
end

function nocturne_drawHP()
  for i, HPbarEnemyChamp in pairs(GetEnemyHeroes()) do
    if not HPbarEnemyChamp.dead and HPbarEnemyChamp.visible then
      local dmg = myHero:CalcDamage(HPbarEnemyChamp, myHero.totalDamage)
      dmg = nocturne_get_combo_damage(HPbarEnemyChamp)
      DrawLineHPBar(dmg, "", HPbarEnemyChamp, HPbarEnemyChamp.team)
    end
  end
end

function nocturne_combo()
  if CanCast(_R) and Menu.Combo.nocturneR then
    local target = GetHentaiTarget(r_range - 150)
    if target then
      if myHero:GetSpellData(_R).name == "NocturneParanoia2" then
        CastSpell(_R, target)
      end
      if Menu.Combo.nocsmartR and target then
        if (nocturne_get_combo_damage(target) - target.health) >= ((target.health * 5)/100) and GetRastoyanie(target) > (NOCTURNE_VARS.q.range - 150) then
          nocturne_castr()
        end
      end
      if target and not Menu.Combo.nocsmartR and GetRastoyanie(target) > (NOCTURNE_VARS.q.range - 150) then
        nocturne_castr()
      end
    end
  end

  local target = GetHentaiTarget(NOCTURNE_VARS.q.range)
  if target and CanCast(_Q) and Menu.Combo.nocturneQ then
    nocturne_castq(target)
  end
  if target and GetRastoyanie(target) <= NOCTURNE_VARS.e.range and CanCast(_E) and Menu.Combo.nocturneE then
    nocturne_caste(target)
  end

  if Menu.Item.UseItem then
    local target = GetHentaiTarget(500)
    if target ~= nil then
      if GetRastoyanie(myHero, target) <= 200 then
        CastYoumu()
      end
      CastBOTRK(target)
      CastGunblade(target)
      CastCutlass(target)
    end
  end
end

function nocturne_harras()
  if ((myHero.mana*100)/myHero.maxMana) < Menu.Harras.harrasMana then return end
  local target = GetHentaiTarget(NOCTURNE_VARS.q.range)
  if target and CanCast(_Q) and Menu.Harras.nocturneQ then
    nocturne_castq(target)
    if GetRastoyanie(target) <= NOCTURNE_VARS.e.range and CanCast(_E) and Menu.Harras.nocturneE then
      nocturne_caste(target)
    end
  end
end

function nocturne_farm()
  if ((myHero.mana*100)/myHero.maxMana) <= Menu.Farm.Laneclear.laneclearMana then return end
  if CanCast(_Q) and Menu.Farm.Laneclear.nocturneQ then
    local CastPosition, NumHit = GetBestLineFarmPosition(NOCTURNE_VARS.q.range, NOCTURNE_VARS.q.width, minionManager(MINION_ENEMY, NOCTURNE_VARS.q.range, myHero, MINION_SORT_HEALTH_ASC).objects)
    if CastPosition ~= nil then
      CastSpell(_Q, CastPosition.x, CastPosition.z)
    end
    local CastPositionJgl, NumHitJgl = GetBestLineFarmPosition(NOCTURNE_VARS.q.range, NOCTURNE_VARS.q.width, minionManager(MINION_JUNGLE, NOCTURNE_VARS.q.range, myHero, MINION_SORT_MAXHEALTH_DEC).objects)
    if CastPositionJgl ~= nil then
      CastSpell(_Q, CastPositionJgl.x, CastPositionJgl.z)
    end
  end
end

function nocturne_killsteal()
  for i,enemy in pairs(GetEnemyHeroes()) do
    if isValid(enemy, NOCTURNE_VARS.q.range) and not CheckInvul(enemy) then
      local qdmg = nocturne_get_q_damage(enemy)
      if qdmg >= enemy.health and CanCast(_Q) and Menu.KS.nocturneQ then
        nocturne_castq(enemy)
      end
    end
  end
end

function noc_onprocspell(unit, spell)
  if spell ~= nil and spell.target ~= nil and unit ~= nil then
    if FAKER[spell.name] and spell.target.isMe and Menu.Auto.nocturneW then
      DelayAction(function() nocturne_castw() end, FAKER[spell.name].delay)
    end
  end
end

function nocturne_castq(unit)
  if not unit then return end
  if VP then
    local CastPosition, HitChance = VP:GetLineCastPosition(unit, NOCTURNE_VARS.q.delay, NOCTURNE_VARS.q.width, NOCTURNE_VARS.q.range, NOCTURNE_VARS.q.speed, myHero, false)
    if HitChance >= Menu.Prediction.QVPHC then
      CastSpell(_Q, CastPosition.x, CastPosition.z)
    end
  end
  if FHPred and Menu.Prediction.activePred == 2 then
    if FHPrediction == nil then 
      print "Something wrong with FHPred, use VPred instead and contact developer"
      return
    end
    local CastPosition, hc, info = FHPrediction.GetPrediction(NOCTURNE_VARS.q, unit)
    if hc > 0 and CastPosition ~= nil then
      CastSpell(_Q, CastPosition.x, CastPosition.z)
    end
  end
end

function nocturne_castw()
  CastSpell(_W)
end

function nocturne_caste(unit)
  if not unit then return end
  CastSpell(_E, unit)
end

function nocturne_castr()
  CastSpell(_R)
end

function nocturne_get_q_damage(unit)
  local Qlvl = myHero:GetSpellData(_Q).level
  if Qlvl < 1 then return 0 end
  local QDmg = {60, 105, 150, 195, 240}
  local bonusAD = myHero.totalDamage - myHero.damage
  local QDmgMod = 0.75
  local DmgRaw = QDmg[Qlvl] + bonusAD * QDmgMod
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function nocturne_get_e_damage(unit)
  local Elvl = myHero:GetSpellData(_E).level
  if Elvl < 1 then return 0 end
  local EDmg = {80, 125, 170, 215, 260}
  local EDmgMod = 1
  local DmgRaw = EDmg[Elvl] + myHero.ap * EDmgMod
  local Dmg = myHero:CalcMagicDamage(unit, DmgRaw)
  return Dmg
end

function nocturne_get_r_damage(unit)
  local Rlvl = myHero:GetSpellData(_R).level
  if Rlvl < 1 then return 0 end
  local RDmg = {150, 250, 350}
  local bonusAD = myHero.totalDamage - myHero.damage
  local RDmgMod = 1.2
  local DmgRaw = RDmg[Rlvl] + bonusAD * RDmgMod
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function nocturne_get_combo_damage(unit)
  dmg = myHero:CalcDamage(unit, myHero.totalDamage)*3
  if CanCast(_Q) then
    dmg = dmg + nocturne_get_q_damage(unit)
  end
  if CanCast(_E) then
    dmg = dmg + nocturne_get_e_damage(unit)
  end
  if CanCast(_R) then
    dmg = dmg + nocturne_get_r_damage(unit)
  end
  return dmg
end

function nocturne_pa(unit, spell)
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type ~= myHero.type and Menu.Key.Laneclear then
    local AADmg = myHero:CalcDamage(spell.target, myHero.totalDamage)
    if AADmg < spell.target.health then
      CastTITANIC()
      CastTiamat()
    end
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.Combo then
    CastTiamat()
    CastTITANIC()
  end
  if unit == myHero and isAutoAttack(spell.name) and spell.target and spell.target.type == myHero.type and Menu.Key.Harras then
    local reseted = false
    if not reseted then
      CastTiamat()
      reseted = true
    end
  end
end

function nocturne_get_ult_range()
  local Rlvl = myHero:GetSpellData(_R).level
  if Rlvl < 1 then return 0 end
  local Rrange = {2500, 3250, 4000}
  return Rrange[Rlvl]
end

class 'KatarinaUpdate'
  
function KatarinaUpdate:__init(LocalVersion, Host, VersionPath, ScriptPath, SavePath, CallbackUpdate, CallbackNoUpdate, CallbackNewVersion, CallbackError) 
  self.LocalVersion = LocalVersion
  self.Host = Host
  self.VersionPath = '/BoL/TCPUpdater/GetScript5.php?script='..self:Base64Encode(self.Host..VersionPath)..'&rand='..math.random(99999999)
  self.ScriptPath = '/BoL/TCPUpdater/GetScript5.php?script='..self:Base64Encode(self.Host..ScriptPath)..'&rand='..math.random(99999999)
  self.SavePath = SavePath
  self.CallbackUpdate = CallbackUpdate
  self.CallbackNoUpdate = CallbackNoUpdate
  self.CallbackNewVersion = CallbackNewVersion
  self.CallbackError = CallbackError
  self:CreateSocket(self.VersionPath)
  self.DownloadStatus = 'Connect to Server for VersionInfo'
  AddTickCallback(function() self:GetOnlineVersion() end)
end

function KatarinaUpdate:OnDraw()
  local bP = {['x1'] = WINDOW_W - (WINDOW_W - 390),['x2'] = WINDOW_W - (WINDOW_W - 20),['y1'] = WINDOW_H / 2,['y2'] = (WINDOW_H / 2) + 20,}
  local text = 'Download Status: '..(self.DownloadStatus or 'Unknown')
  DrawLine(bP.x1, bP.y1 + 10, bP.x2,  bP.y1 + 10, 18, ARGB(0x7D,0xE1,0xE1,0xE1))
  local xOff
  if self.File and self.Size then
    local c = math.round(100/self.Size*self.File:len(),2)/100
    xOff = c < 1 and math.ceil(370 * c) or 370
  else
    xOff = 0
  end
  DrawLine(bP.x2 + xOff, bP.y1 + 10, bP.x2, bP.y1 + 10, 18, ARGB(255, 5, 117, 1))
  DrawLines2({D3DXVECTOR2(bP.x1, bP.y1),D3DXVECTOR2(bP.x2, bP.y1),D3DXVECTOR2(bP.x2, bP.y2),D3DXVECTOR2(bP.x1, bP.y2),D3DXVECTOR2(bP.x1, bP.y1),}, 3, ARGB(255, 86, 6, 62))
  DrawText(text, 16, WINDOW_W - (WINDOW_W - 205) - (GetTextArea(text, 16).x / 2), bP.y1 + 2, ARGB(255, 8, 224, 52))
end

function KatarinaUpdate:CreateSocket(url)
    if not self.LuaSocket then
        self.LuaSocket = require("socket")
    else
        self.Socket:close()
        self.Socket = nil
        self.Size = nil
        self.RecvStarted = false
    end
    self.LuaSocket = require("socket")
    self.Socket = self.LuaSocket.tcp()
    self.Socket:settimeout(0, 'b')
    self.Socket:settimeout(99999999, 't')
    self.Socket:connect('sx-bol.eu', 80)
    self.Url = url
    self.Started = false
    self.LastPrint = ""
    self.File = ""
end

function KatarinaUpdate:Base64Encode(data)
    local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    return ((data:gsub('.', function(x)
        local r,b='',x:byte()
        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
        return r;
    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
        if (#x < 6) then return '' end
        local c=0
        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
        return b:sub(c+1,c+1)
    end)..({ '', '==', '=' })[#data%3+1])
end

function KatarinaUpdate:GetOnlineVersion()
    if self.GotScriptVersion then return end

    self.Receive, self.Status, self.Snipped = self.Socket:receive(1024)
    if self.Status == 'timeout' and not self.Started then
        self.Started = true
        self.Socket:send("GET "..self.Url.." HTTP/1.1\r\nHost: sx-bol.eu\r\n\r\n")
    end
    if (self.Receive or (#self.Snipped > 0)) and not self.RecvStarted then
        self.RecvStarted = true
        self.DownloadStatus = 'Downloading VersionInfo (0%)'
    end

    self.File = self.File .. (self.Receive or self.Snipped)
    if self.File:find('</s'..'ize>') then
        if not self.Size then
            self.Size = tonumber(self.File:sub(self.File:find('<si'..'ze>')+6,self.File:find('</si'..'ze>')-1))
        end
        if self.File:find('<scr'..'ipt>') then
            local _,ScriptFind = self.File:find('<scr'..'ipt>')
            local ScriptEnd = self.File:find('</scr'..'ipt>')
            if ScriptEnd then ScriptEnd = ScriptEnd - 1 end
            local DownloadedSize = self.File:sub(ScriptFind+1,ScriptEnd or -1):len()
            self.DownloadStatus = 'Downloading VersionInfo ('..math.round(100/self.Size*DownloadedSize,2)..'%)'
        end
    end
    if self.File:find('</scr'..'ipt>') then
        self.DownloadStatus = 'Downloading VersionInfo (100%)'
        local a,b = self.File:find('\r\n\r\n')
        self.File = self.File:sub(a,-1)
        self.NewFile = ''
        for line,content in ipairs(self.File:split('\n')) do
            if content:len() > 5 then
                self.NewFile = self.NewFile .. content
            end
        end
        local HeaderEnd, ContentStart = self.File:find('<scr'..'ipt>')
        local ContentEnd, _ = self.File:find('</scr'..'ipt>')
        if not ContentStart or not ContentEnd then
            if self.CallbackError and type(self.CallbackError) == 'function' then
                self.CallbackError()
            end
        else
            self.OnlineVersion = (Base64Decode(self.File:sub(ContentStart + 1,ContentEnd-1)))
            self.OnlineVersion = tonumber(self.OnlineVersion)
            if self.OnlineVersion and self.OnlineVersion > LocalVersion then
                if self.CallbackNewVersion and type(self.CallbackNewVersion) == 'function' then
                    self.CallbackNewVersion(self.OnlineVersion,self.LocalVersion)
                end
        if not Menu.update then return end
        AddDrawCallback(function() self:OnDraw() end)
                self:CreateSocket(self.ScriptPath)
                self.DownloadStatus = 'Connect to Server for ScriptDownload'
                AddTickCallback(function() self:DownloadUpdate() end)
            else
                if self.CallbackNoUpdate and type(self.CallbackNoUpdate) == 'function' then
                    self.CallbackNoUpdate(self.LocalVersion)
                end
            end
        end
        self.GotScriptVersion = true
    end
end

function KatarinaUpdate:DownloadUpdate()
    if self.GotScriptUpdate then return end
    self.Receive, self.Status, self.Snipped = self.Socket:receive(1024)
    if self.Status == 'timeout' and not self.Started then
        self.Started = true
        self.Socket:send("GET "..self.Url.." HTTP/1.1\r\nHost: sx-bol.eu\r\n\r\n")
    end
    if (self.Receive or (#self.Snipped > 0)) and not self.RecvStarted then
        self.RecvStarted = true
        self.DownloadStatus = 'Downloading Script (0%)'
    end

    self.File = self.File .. (self.Receive or self.Snipped)
    if self.File:find('</si'..'ze>') then
        if not self.Size then
            self.Size = tonumber(self.File:sub(self.File:find('<si'..'ze>')+6,self.File:find('</si'..'ze>')-1))
        end
        if self.File:find('<scr'..'ipt>') then
            local _,ScriptFind = self.File:find('<scr'..'ipt>')
            local ScriptEnd = self.File:find('</scr'..'ipt>')
            if ScriptEnd then ScriptEnd = ScriptEnd - 1 end
            local DownloadedSize = self.File:sub(ScriptFind+1,ScriptEnd or -1):len()
            self.DownloadStatus = 'Downloading Script ('..math.round(100/self.Size*DownloadedSize,2)..'%)'
        end
    end
    if self.File:find('</scr'..'ipt>') then
        self.DownloadStatus = 'Downloading Script (100%)'
        local a,b = self.File:find('\r\n\r\n')
        self.File = self.File:sub(a,-1)
        self.NewFile = ''
        for line,content in ipairs(self.File:split('\n')) do
            if content:len() > 5 then
                self.NewFile = self.NewFile .. content
            end
        end
        local HeaderEnd, ContentStart = self.NewFile:find('<scr'..'ipt>')
        local ContentEnd, _ = self.NewFile:find('</scr'..'ipt>')
        if not ContentStart or not ContentEnd then
            if self.CallbackError and type(self.CallbackError) == 'function' then
        print('Error1')
        self.CallbackError()
            end
        else
            local newf = self.NewFile:sub(ContentStart+1,ContentEnd-1)
            local newf = newf:gsub('\r','')
            if newf:len() ~= self.Size then
                if self.CallbackError and type(self.CallbackError) == 'function' then
          print('Error2')
                    self.CallbackError()
                end
                return
            end
            local newf = Base64Decode(newf)
            if not self.isSprite and type(load(newf)) ~= 'function' then
                if self.CallbackError and type(self.CallbackError) == 'function' then
          print('Error2')
                    self.CallbackError()
                end
            else
                local f = io.open(self.SavePath,"w+b")
        if f then
          f:write(newf)
          f:close()
          if self.CallbackUpdate and type(self.CallbackUpdate) == 'function' then
            self.CallbackUpdate(self.OnlineVersion,self.LocalVersion)
          end
        end
            end
        end
        self.GotScriptUpdate = true
    end
end

class "SxWebResulter"

function SxWebResulter:__init(Host, Path, cbComplete, cbError)
    self.Host = Host
    self.Path = Path
    self.Callback = cbComplete
  self.Error = cbError
    self.LuaSocket = require("socket")

    self.Socket = self.LuaSocket.connect(Host, 80)
    self.Socket:send("GET "..self.Path.." HTTP/1.0\r\nHost: "..Host.."\r\n\r\n")
    self.Socket:settimeout(0, 'b')
    self.Socket:settimeout(99999999, 't')

    self.LastPrint = ""
    self.File = ""
    AddDrawCallback(function() self:GetResult() end)
end

function SxWebResulter:GetResult()
    if self.Status == 'closed' then return end
    self.Receive, self.Status, self.Snipped = self.Socket:receive(1024)
    if self.Receive then
        if self.LastPrint ~= self.Receive then
            self.LastPrint = self.Receive
            self.File = self.File .. self.Receive
        end
    end

    if self.Snipped ~= "" and self.Snipped then
        self.File = self.File .. self.Snipped
    end
    if self.Status == 'closed' then
        local HeaderEnd, ContentStart = self.File:find('\r\n\r\n')
        if HeaderEnd and ContentStart then
            self.Callback(self.File:sub(ContentStart + 1))
        else
            self.Error()
        end
    end
end