--[[
 ▄         ▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄▄        ▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄▄▄ 
▐░▌       ▐░▌▐░░░░░░░░░░░▌▐░░▌      ▐░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌
▐░▌       ▐░▌▐░█▀▀▀▀▀▀▀▀▀ ▐░▌░▌     ▐░▌ ▀▀▀▀█░█▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌ ▀▀▀▀█░█▀▀▀▀ 
▐░▌       ▐░▌▐░▌          ▐░▌▐░▌    ▐░▌     ▐░▌     ▐░▌       ▐░▌     ▐░▌     
▐░█▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░▌ ▐░▌   ▐░▌     ▐░▌     ▐░█▄▄▄▄▄▄▄█░▌     ▐░▌     
▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░▌  ▐░▌  ▐░▌     ▐░▌     ▐░░░░░░░░░░░▌     ▐░▌     
▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀▀▀ ▐░▌   ▐░▌ ▐░▌     ▐░▌     ▐░█▀▀▀▀▀▀▀█░▌     ▐░▌     
▐░▌       ▐░▌▐░▌          ▐░▌    ▐░▌▐░▌     ▐░▌     ▐░▌       ▐░▌     ▐░▌     
▐░▌       ▐░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░▌     ▐░▐░▌     ▐░▌     ▐░▌       ▐░▌ ▄▄▄▄█░█▄▄▄▄ 
▐░▌       ▐░▌▐░░░░░░░░░░░▌▐░▌      ▐░░▌     ▐░▌     ▐░▌       ▐░▌▐░░░░░░░░░░░▌
 ▀         ▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀        ▀▀       ▀       ▀         ▀  ▀▀▀▀▀▀▀▀▀▀▀                                                                          
 ▄▄▄▄▄▄▄▄▄▄▄  ▄         ▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄▄        ▄                           
▐░░░░░░░░░░░▌▐░▌       ▐░▌▐░░░░░░░░░░░▌▐░░▌      ▐░▌                          
▐░█▀▀▀▀▀▀▀▀▀ ▐░▌       ▐░▌▐░█▀▀▀▀▀▀▀▀▀ ▐░▌░▌     ▐░▌                          
▐░▌          ▐░▌       ▐░▌▐░▌          ▐░▌▐░▌    ▐░▌                          
▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░▌ ▐░▌   ▐░▌                          
▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░▌  ▐░▌  ▐░▌                          
 ▀▀▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀▀▀ ▐░▌   ▐░▌ ▐░▌                          
          ▐░▌▐░▌       ▐░▌▐░▌          ▐░▌    ▐░▌▐░▌                          
 ▄▄▄▄▄▄▄▄▄█░▌▐░▌       ▐░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░▌     ▐░▐░▌                          
▐░░░░░░░░░░░▌▐░▌       ▐░▌▐░░░░░░░░░░░▌▐░▌      ▐░░▌                          
 ▀▀▀▀▀▀▀▀▀▀▀  ▀         ▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀        ▀▀                                                                                                      
--]]
--ver 0.53

if myHero.charName ~= "Shen" then return end
require ("VPrediction")

local version = "0.53"
local LocalVersion = 0.53
local scriptname = "Hentai Shen"
local developer = "remembermyhentai"
local contact = "skype xd_kikass"
local REGEN = false
local FONTAN = false
local lowBase = {["x"] = 406, ["z"] = 424}
local upBase = {["x"] = 14322, ["z"] = 14394}
local FOCUSED = nil
local YOLO = {}
local KEYS = {112, 113, 114, 115}
local TEXTPOS = {160, 180, 200, 220}

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
}
local SHENQ, SHENDASH = false
local POTS = {"ItemCrystalFlask", "RegenerationPotion", "ItemMiniRegenPotion", "ItemCrystalFlaskJungle", "ItemDarkCrystalFlask"}
local ATTACKITEMS = {"ItemTiamatCleave", "ItemTitanicHydraCleave", "BilgewaterCutlass", "YoumusBlade", "HextechGunblade", "ItemSwordOfFeastAndFamine"}
local ANTICCITEMS = {"QuicksilverSash", "ItemDervishBlade"}
local TIAMAT, TITANIC, CUTLASS, YOUMU, GUNBLADE, BOTRK, QSS, DERVISH = false
local TIAMATSLOT, TITANICSLOT, CUTLASSSLOT, YOUMUSLOT, GUNBLADESLOT, BOTRKSLOT, QSSSLOT, DERVISHSLOT, SMITESLOT
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
local UNDERCC = false
local CCSPELLS = {"MordekaiserChildrenOfTheGrave", "SkarnerImpale", "LuxLightBindingMis", "Wither", "SonaCrescendo", "DarkBindingMissile", "CurseoftheSadMummy",
"EnchantedCrystalArrow", "BlindingDart", "LuluWTwo", "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", "nasusw"}
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"}
local VARS = {
  AA = {RANGE = 125},
  E = {RANGE = 600, DELAY = 0.25, SPEED = math.huge, WIDTH = 130}
}

function OnLoad()
  VP = VPrediction()
  
  AddApplyBuffCallback(Buff_Add)
  AddRemoveBuffCallback(Buff_Rem)
  AddProcessAttackCallback(Shen_ProcessAttack)

  KatarinaUpdate(
    Version,
    'raw.githubusercontent.com', 
    '/remembermyhentai/BoL/master/Shen/HentaiShen.version',
    '/remembermyhentai/BoL/master/Shen/HentaiShen.lua', 
    SCRIPT_PATH.._ENV.FILE_NAME, 
    function() PrintChat('<font color = \"#B13070\">[HENTAI SHEN]</font> <font color = \"#4DFF4D\">SCRIPT UPDATED. RESTART BOL (2xF9)</font>') end, 
    function() PrintChat('<font color = \"#B13070\">[HENTAI SHEN]</font> <font color = \"#4DFF4D\">LOADED VERSION //</font>'..version) end, 
    function() PrintChat(Menu.update and '<font color = \"#B13070\">[HENTAI SHEN]</font> <font color = \"#4DFF4D\">NEW VERSION, WAIT...</font>' or
     '<font color = \"#B13070\">[HENTAI SHEN]</font> <font color = \"#4DFF4D\">NEW VERSION, DOWNLOAD IT MANUALLY FROM FORUM</font>') end, 
    function() PrintChat('<font color = \"#B13070\">[HENTAI SHEN]</font> <font color = \"#4DFF4D\">UPDATE ERROR, DOWNLOAD IT MANUALLY FROM FORUM</font>') end)
  
  Menu = scriptConfig("[Hentai Shen]", "HentaiShen")
  Menu:addSubMenu("[Key Binds]", "Key")
  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:addSubMenu("[Combo]", "Combo")
  Menu.Combo:addParam("focus", "Focus selected target/stick", 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("useE", "Use E", SCRIPT_PARAM_ONOFF, true)

  Menu:addSubMenu("[Harras]", "Harras")
  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:addSubMenu("[Ult Assist]", "Assister")
  Menu.Assister:addSubMenu("[Keys]", "Key")
  for i,enemy in pairs(GetAllyHeroes()) do
    table.insert(YOLO, enemy.charName)
  end
  for i = 1, #YOLO do
    local a1 = "a"..i
    local a2 = ""..YOLO[i]
    Menu.Assister:addParam(a1, "Cast R on "..a2, SCRIPT_PARAM_ONOFF, true)
    Menu.Assister.Key:addParam(a1, "Cast R on "..a2, SCRIPT_PARAM_ONKEYDOWN, false, KEYS[i])
  end

  Menu:addSubMenu("[Farm]", "Farm")
  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, 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("[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("[Draws]", "Draws")
  Menu.Draws:addParam("drawTarget", "Draw Selected Target", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawE", "Draw E range", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawR", "Draw R helper", SCRIPT_PARAM_ONOFF, true)
  Menu.Draws:addParam("drawHP", "Draw damage on HP bars", 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("autoInterrupt", "Auto Interrupt important enemy spells", SCRIPT_PARAM_ONOFF, true)
  Menu.Auto:addParam("autoPots", "Auto Potions usage", SCRIPT_PARAM_ONOFF, true)
  Menu.Auto:addParam("autoPotsHealth", "% Health for autopots", SCRIPT_PARAM_SLICE, 75, 0, 100, 0)

  Menu:addSubMenu("[Killsteal]", "KS")
  Menu.KS:addParam("ksE", "Use E for killsteal", SCRIPT_PARAM_ONOFF, true)
  Menu.KS:addParam("ksIgnite", "Use Ignite for killsteal", SCRIPT_PARAM_ONOFF, true)

  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, "")

  igniteslot = FindSlotByName("summonerdot")
  flashslot = FindSlotByName("summonerflash")
  
  PrintChat("<font color = \"#B13070\">[HENTAI SHEN]</font> <font color = \"#4DFF4D\">LOADED</font>")
end

function OnTick()
  if FOCUSED ~= nil then
    if FOCUSED.dead or not FOCUSED.visible then
      FOCUSED = nil
    end
  end
  if CanCast(_R) then
    UltAssist()
  end
  if igniteslot ~= nil then
    AutoIgnite()
  end
  Killsteal()
  
  if Menu.Key.flashE then
    FlashEngage()
  end
  
  if Menu.Key.combo then
    Combo()
  end
  
  if Menu.Key.harras then
    Harras()
  end
  
  if Menu.Key.lasthit then
    Lasthit()
  end
  
  if Menu.Key.laneclear then
    Laneclear()
  end
  
  if Menu.Auto.autoPots then
    CheckFountain()
  end
  if Menu.Auto.autoPots and not REGEN and not FONTAN then
    AutoPotion()
  end 
  
  if Menu.Item.UseItem then
    FindItems()
  end
  
  GetSmiteSlot()
  if SMITE then
    if Menu.Smite.UseSmite then
      AutoSmite()
    end
  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
end

function OnDraw()
  if not myHero.dead then
    if Menu.Draws.drawE then
      DrawFPSCircle(myHero.x, myHero.z, VARS.E.RANGE, ARGB(255,193,61,255), 24)
    end
    if Menu.Draws.drawTarget then
      DrawSelectedTarget()
    end
    if Menu.Draws.drawHP then
      DrawHP()
    end
    if Menu.Draws.drawR then
      local percent = 0
      for i = 1, #YOLO do
        if YOLO[i] ~= nil then
          local a7 = "a"..i
          if CanCast(_R) then
            for j,enemy in pairs(GetAllyHeroes()) do
              if enemy.charName == YOLO[i] then
                percent = math.round(((enemy.health*100)/enemy.maxHealth))
              end
            end
            if percent > 70 then
              DrawText (""..YOLO[i].." ".."["..percent.."]".." ".."[F"..i.."]", 20, 150, TEXTPOS[i], 0xFF00FF00)
            elseif percent > 35 then
              DrawText (""..YOLO[i].." ".."["..percent.."]".." ".."[F"..i.."]", 20, 150, TEXTPOS[i], 0xFFFFFF00)
            elseif percent <= 35 and percent ~= 0 then
              DrawText (""..YOLO[i].." ".."["..percent.."]".." ".."[F"..i.."]", 20, 150, TEXTPOS[i], 0xFFFF0000)
            elseif percent == 0 then
              DrawText (""..YOLO[i].." ".."["..percent.."]".." ".."[F"..i.."]", 20, 150, TEXTPOS[i], 0xFFFFFFFF)
            end
          end
        end
      end
    end
    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
  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 + GetQDamage(enemy)
      end
      if CanCast(_E) then
        totalDMG = totalDMG + GetEDamage(enemy)
      end
      if TIAMAT then
        if CanCast(TIAMATSLOT) then
          totalDMG = totalDMG + GetTiamatDamage(enemy)
        end
      end
      if CUTLASS then
        if CanCast(CUTLASSSLOT) then
          totalDMG = totalDMG + GetCutlassDamage(enemy)
        end
      end
      if BOTRK then
        if CanCast(BOTRKSLOT) then
          totalDMG = totalDMG + GetBOTRKDamage(enemy)
        end
      end
      if GUNBLADE then
        if CanCast(GUNBLADESLOT) then
          totalDMG = totalDMG + GetGunbladeDamage(enemy)
        end
      end
      if SMITE and ATTACKSMITE then
        if CanCast(SMITESLOT) then
          totalDMG = totalDMG + GetAttackSmiteDamage()
        end
      end
      if igniteslot ~= nil then
        if CanCast(igniteslot) then
          totalDMG = totalDMG + (50 + 20*myHero.level)
        end
      end
      DrawLineHPBar(totalDMG, "", enemy, enemy.team)
    end
  end
end

function Combo()
  if CanCast(_E) and Menu.Combo.useE then
    local target = GetHentaiTarget(VARS.E.RANGE)
    if target ~= nil then
      CastE(target)
    end
  end
  if SHENQ and CanCast(_W) and Menu.Combo.useW then
    CastW()
  end
  if CanCast(_Q) and Menu.Combo.useQ then
    local target = GetHentaiTarget(VARS.AA.RANGE+75)
    if target ~= nil then
      CastQ()
    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.Smite.UseSmiteCombo then
    local target = GetHentaiTarget(300)
    if target ~= nil then
      if SMITE and ATTACKSMITE then
        CastSmite(target)
      end
    end
  end
end

function Harras()
  if CanCast(_E) and Menu.Harras.useE then
    local target = GetHentaiTarget(VARS.E.RANGE)
    if target ~= nil then
      CastE(target)
    end
  end
  if SHENQ and CanCast(_W) and Menu.Harras.useW then
    CastW()
  end
  if CanCast(_Q) and Menu.Harras.useQ then
    local target = GetHentaiTarget(VARS.AA.RANGE+75)
    if target ~= nil then
      CastQ()
    end
  end
end

function Laneclear()
  for _, minion in pairs(minionManager(MINION_ENEMY, 250, myHero, MINION_SORT_HEALTH_ASC).objects) do
    if ValidTarget(minion, 250) then
      if CanCast(_W) and Menu.Farm.Laneclear.laneclearW and SHENQ then
        CastW()
      end
      if CanCast(_Q) and Menu.Farm.Laneclear.laneclearQ then
        CastQ()
      end
    end
  end
  for _, minion in pairs(minionManager(MINION_JUNGLE, 250, myHero, MINION_SORT_MAXHEALTH_DEC).objects) do
    if ValidTarget(minion, 250) then
      if CanCast(_W) and Menu.Farm.Laneclear.laneclearW and SHENQ then
        CastW()
      end
      if CanCast(_Q) and Menu.Farm.Laneclear.laneclearQ then
        CastQ()
      end
    end
  end
end

function Killsteal()
  for i,enemy in pairs(GetEnemyHeroes()) do
    if isValid(enemy, 700) and not CheckInvul(enemy) then
      if GetRastoyanie(myHero, enemy) <= VARS.E.RANGE then
        local EDmg = GetEDamage(enemy)
        if EDmg >= enemy.health then
          CastE(enemy)
        end
      end
      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) <= 500 then
        if SMITE and ATTACKSMITE and Menu.KS.UseSmiteKS then
          local SmiteDmg = GetAttackSmiteDamage()
          if SmiteDmg >= enemy.health and CanCast(SMITESLOT) and not enemy.dead then
            CastSmite(enemy)
          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

function UltAssist()
  if Menu.Assister.Key.a1 ~= nil then
    if Menu.Assister.Key.a1 and Menu.Assister.a1 and CanCast(_R) then
      for i,enemy in pairs(GetAllyHeroes()) do
        if isValid(enemy, 25000) and enemy.charName == YOLO[1] then
          CastR(enemy)
        end
      end
    end
  end
  if Menu.Assister.Key.a2 ~= nil then
    if Menu.Assister.Key.a2 and Menu.Assister.a2 and CanCast(_R) then
      for i,enemy in pairs(GetAllyHeroes()) do
        if isValid(enemy, 25000) and enemy.charName == YOLO[2] then
          CastR(enemy)
        end
      end
    end
  end
  if Menu.Assister.Key.a3 ~= nil then
    if Menu.Assister.Key.a3 and Menu.Assister.a3 and CanCast(_R) then
      for i,enemy in pairs(GetAllyHeroes()) do
        if isValid(enemy, 25000) and enemy.charName == YOLO[3] then
          CastR(enemy)
        end
      end
    end
  end
  if Menu.Assister.Key.a4 ~= nil then
    if Menu.Assister.Key.a4 and Menu.Assister.a4 and CanCast(_R) then
      for i,enemy in pairs(GetAllyHeroes()) do
        if isValid(enemy, 25000) and enemy.charName == YOLO[4] then
          CastR(enemy)
        end
      end
    end
  end
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 SHEN]</font> focus "..pussy.charName)
        else
          FOCUSED = nil
          print("<font color = \"#B13070\">[HENTAI SHEN]</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 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

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 OnProcessSpell(unit, spell)
  if Menu.Auto.autoInterrupt and unit and spell and CanCast(_E) then
    if unit.team ~= myHero.team and PussyOut[spell.name] ~= nil then
      if GetRastoyanie(myHero, unit) < VARS.E.RANGE then
        CastE(unit)
      end
    end
  end
end

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)
    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 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 Shen_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.Orbwalker:ResetAttackTimer()
        end
        if WOLFY then
          _G.NebelwolfisOrbWalker:ResetAA()
        end
        if PEW then
          _Pewalk.AllowAttack(false)
          _Pewalk.AllowMove(false)
          myHero:Attack(spell.target)
          DelayAction(function()
            _Pewalk.AllowAttack(true)
            _Pewalk.AllowMove(true)
          end, 0.1)
        end
        if MMA then
          _G.MMA_ResetAutoAttack()
        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 AADmg < spell.target.health and TITANIC and not reseted then
      if CanCast(TITANICSLOT) then
        CastTITANIC()
        if SAC then
          _G.AutoCarry.Orbwalker:ResetAttackTimer()
        end
        if WOLFY then
          _G.NebelwolfisOrbWalker:ResetAA()
        end
        if PEW then
          _Pewalk.AllowAttack(false)
          _Pewalk.AllowMove(false)
          myHero:Attack(spell.target)
          DelayAction(function()
            _Pewalk.AllowAttack(true)
            _Pewalk.AllowMove(true)
          end, 0.1)
        end
        if MMA then
          _G.MMA_ResetAutoAttack()
        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.Orbwalker:ResetAttackTimer()
        end
        if WOLFY then
          _G.NebelwolfisOrbWalker:ResetAA()
        end
        if PEW then
          _Pewalk.AllowAttack(false)
          _Pewalk.AllowMove(false)
          myHero:Attack(spell.target)
          DelayAction(function()
            _Pewalk.AllowAttack(true)
            _Pewalk.AllowMove(true)
          end, 0.1)
        end
        if MMA then
          _G.MMA_ResetAutoAttack()
        end
        reseted = true
      end
    end
  end
end

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

function isWhitelisted(enemy)
  local index = whitelistIndex(enemy)
  if index == 1 then
    if Menu.Assister.a1 then
      return true
    else
      return false
    end
  end
  if index == 2 then
    if Menu.Assister.a2 then
      return true
    else
      return false
    end
  end
  if index == 3 then
    if Menu.Assister.a3 then
      return true
    else
      return false
    end
  end
  if index == 4 then
    if Menu.Assister.a4 then
      return true
    else
      return false
    end
  end
  if index == 5 then
    if Menu.Assister.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 GetQDamage(unit)
  local Qlvl = myHero:GetSpellData(_Q).level
  if Qlvl < 1 then return 0 end
  local QDmg = {3, 3.5, 4, 4.5, 5}
  local DmgRaw = 3*((QDmg[Qlvl]/100)*unit.maxHealth)
  local Dmg = myHero:CalcMagicDamage(unit, DmgRaw)
  return Dmg
end

function GetEDamage(unit)
  local BaseHealth = {540, 593, 648, 705, 766, 828, 894, 962, 1032, 1105, 1181, 1259, 1339, 1423, 1508, 1597, 1688, 1781}
  local Elvl = myHero:GetSpellData(_E).level
  if Elvl < 1 then return 0 end
  local EDmg = {50, 85, 120, 155, 190}
  local DmgRaw = EDmg[Elvl] + ((myHero.maxHealth - BaseHealth[myHero.level])*0.12)
  local Dmg = myHero:CalcDamage(unit, DmgRaw)
  return Dmg
end

function CastQ()
  CastSpell(_Q)
end

function CastW()
  CastSpell(_W)
end

function CastE(unit)
  if unit == nil then return end
  local CastPosition, HitChance, Position = VP:GetLineCastPosition(unit, VARS.E.DELAY, VARS.E.WIDTH, VARS.E.RANGE, VARS.E.SPEED, myHero, false)
  if HitChance >= 2 then
    CastSpell(_E, CastPosition.x, CastPosition.z)
    if Menu.Combo.useQ and CanCast(_Q) and Menu.Key.combo then
      CastQ()
    end
    if Menu.Harras.useQ and CanCast(_Q) and Menu.Key.harras then
      CastQ()
    end
  end
end

function CastR(unit)
  if unit == nil then return end
  CastSpell(_R, unit)
end

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

function Buff_Rem(unit, buff)
  if unit.isMe and buff.name == "shenqbuff" then
    SHENQ = false
  end
  if unit.isMe and buff.name == "shenedash" then
    SHENDASH = false
  end
  for j = 1, #CCSPELLS do
    if unit.isMe and buff.name == CCSPELLS[j] then
      UNDERCC = false
    end
  end
  for i=1, 5 do
    if (buff.name == POTS[i] and unit.isMe) then
      REGEN = false
    end
  end
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 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 GetRastoyanie(a, b)
  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 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

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