if myHero.charName ~= "Blitzcrank" then return end local version = "2.02" local AUTOUPDATE = true local UPDATE_NAME = "Blitzcrank" local UPDATE_HOST = "bitbucket.org" local UPDATE_PATH = "/honda7/bol/raw/master/Blitzcrank.lua".."?rand="..math.random(1,10000) local UPDATE_FILE_PATH = SCRIPT_PATH..GetCurrentEnv().FILE_NAME local UPDATE_URL = "https://"..UPDATE_HOST..UPDATE_PATH function AutoupdaterMsg(msg) print(""..UPDATE_NAME..": "..msg..".") end if AUTOUPDATE then local ServerData = GetWebResult(UPDATE_HOST, UPDATE_PATH) if ServerData then local ServerVersion = string.match(ServerData, "local version = \"%d+.%d+\"") ServerVersion = string.match(ServerVersion and ServerVersion or "", "%d+.%d+") if ServerVersion then ServerVersion = tonumber(ServerVersion) if tonumber(version) < ServerVersion then AutoupdaterMsg("New version available"..ServerVersion) AutoupdaterMsg("Updating, please don't press F9") DownloadFile(UPDATE_URL, UPDATE_FILE_PATH, function () AutoupdaterMsg("Successfully updated. ("..version.." => "..ServerVersion.."), press F9 twice to load the updated version.") end) else AutoupdaterMsg("You have got the latest version ("..ServerVersion..")") end end else AutoupdaterMsg("Error downloading version info") end end --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- require "VPrediction" local Qrange2, Qrange, Qwidth, Qspeed, Qdelay = 1000, 1000, 70, 1800, 0.25 local Rrange = 600 local SelectedTarget local spells = { {name = "CaitlynAceintheHole", menuname = "Caitlyn (R)"}, {name = "Crowstorm", menuname = "Fiddlesticks (R)"}, {name = "DrainChannel", menuname = "Fiddlesticks (W)"}, {name = "GalioIdolOfDurand", menuname = "Galio (R)"}, {name = "KatarinaR", menuname = "Katarina (R)"}, {name = "InfiniteDuress", menuname = "WarWick (R)"}, {name = "AbsoluteZero", menuname = "Nunu (R)"}, {name = "MissFortuneBulletTime", menuname = "Miss Fortune (R)"}, {name = "AlZaharNetherGrasp", menuname = "Malzahar (R)"}, } local LastCastedSpell = {} local Stats = {CastedQs = 0, LandedQ = 0, LandedQs = {}, LandedQchampions=0, LandedQminions = 0} local pid local pidtime = 0 local wayPointManager = WayPointManager() function OnLoad()--ASk thresh to add lantern-grab Menu = scriptConfig("Blitzcrank", "Blitzcrank") Menu:addParam("Grab", "Grab!", SCRIPT_PARAM_ONKEYDOWN, false, 32) Menu:addParam("AutoE", "Auto-E after grab", SCRIPT_PARAM_ONOFF, true) Menu:addParam("Move", "Move to mouse", SCRIPT_PARAM_ONOFF, false) Menu:addSubMenu("Auto-Interrupt", "AutoInterrupt") for i, spell in ipairs(spells) do Menu.AutoInterrupt:addParam(spell.name, spell.menuname, SCRIPT_PARAM_ONOFF, true) end Menu:addSubMenu("Auto-Grab", "AutoGrab") Menu.AutoGrab:addParam("AutoD", "Auto-Grab dashing enemies", SCRIPT_PARAM_ONOFF, true) Menu.AutoGrab:addParam("AutoS", "Auto-Grab immobile enemies", SCRIPT_PARAM_ONOFF, true) Menu.AutoGrab:addParam("DAG", "Don't auto grab if my health < %", SCRIPT_PARAM_SLICE, 0, 0, 100) Menu:addSubMenu("Targets", "Targets") for i, enemy in ipairs(GetEnemyHeroes()) do Menu.Targets:addParam(enemy.charName, enemy.charName, SCRIPT_PARAM_LIST, 3, {"Don't grab", "Normal grab", "Normal + Auto-grab"}) end Menu:addSubMenu("Drawing", "Drawing") Menu.Drawing:addParam("ShowStats", "Draw stats on the side", SCRIPT_PARAM_ONOFF, true) Menu.Drawing:addParam("Qrange", "Draw Q range", SCRIPT_PARAM_ONOFF, true) Menu.Drawing:addParam("DrawWP", "Draw selected target waypoints", SCRIPT_PARAM_ONOFF, true) Menu.Drawing:addParam("DrawWPR", "Draw selected target waypoint rate", SCRIPT_PARAM_ONOFF, true) VP = VPrediction() end function CheckBLHeroCollision(Pos) for i, enemy in ipairs(GetEnemyHeroes()) do if ValidTarget(enemy) and GetDistance(enemy) < Qrange * 1.5 and Menu.Targets[enemy.charName] == 1 then local proj1, pointLine, isOnSegment = VectorPointProjectionOnLineSegment(Vector(myHero), Pos, Vector(enemy)) if (GetDistanceSqr(enemy, proj1) <= (VP:GetHitBox(enemy) * 2 + Qwidth) ^ 2) then return true end end end return false end function OnTick() if myHero:CanUseSpell(_Q) == READY then local HitChance2Targets = {} local SelectedTargetInRange = false local MinPercentageHP = myHero.health / myHero.maxHealth * 100 for i, ally in ipairs(GetAllyHeroes()) do local mp = ally.health / ally.maxHealth * 100 if mp <= MinPercentageHP and not ally.dead and GetDistance(ally) < 700 then MinPercentageHP = mp end end for i, enemy in ipairs(GetEnemyHeroes()) do if ValidTarget(enemy, 1500) and Menu.Targets[enemy.charName] >= 1 then local CastPosition, HitChance, HeroPosition = VP:GetLineCastPosition(enemy, Qdelay, Qwidth, Qrange, Qspeed, myHero, true) if MinPercentageHP > Menu.AutoGrab.DAG and HitChance == 5 and Menu.AutoGrab.AutoD and Menu.Targets[enemy.charName] == 3 and GetDistance(myHero.visionPos, CastPosition) < Qrange then if not CheckBLHeroCollision(CastPosition) then CastSpell(_Q, CastPosition.x, CastPosition.z) end elseif MinPercentageHP > Menu.AutoGrab.DAG and HitChance == 4 and Menu.AutoGrab.AutoS and Menu.Targets[enemy.charName] == 3 and GetDistance(myHero.visionPos, CastPosition) < Qrange then if GetDistance(CastPosition) > 300 and not CheckBLHeroCollision(CastPosition) then CastSpell(_Q, CastPosition.x, CastPosition.z) end elseif HitChance == 2 and GetDistance(myHero.visionPos, CastPosition) < Qrange then if Menu.Targets[enemy.charName] > 1 then HitChance2Targets[enemy.networkID] = {unit = enemy, CastPosition = CastPosition} end if Menu.Grab and SelectedTarget and enemy.networkID == SelectedTarget.networkID then CastSpell(_Q, CastPosition.x, CastPosition.z) end end if SelectedTarget and enemy.networkID == SelectedTarget.networkID then SelectedTargetInRange = true end end end if not SelectedTargetInRange and Menu.Grab then local BestTarget = nil local MinL = math.huge for nid, target in pairs(HitChance2Targets) do local L = target.unit.health / myHero:CalcMagicDamage(target.unit, 100) if L < MinL then BestTarget = target.unit MinL = L end end if BestTarget then if not CheckBLHeroCollision(HitChance2Targets[BestTarget.networkID].CastPosition) then CastSpell(_Q, HitChance2Targets[BestTarget.networkID].CastPosition.x, HitChance2Targets[BestTarget.networkID].CastPosition.z) end end end end if Menu.Move and Menu.Grab then myHero:MoveTo(mousePos.x, mousePos.z) end if myHero:CanUseSpell(_R) == READY then for i, spell in ipairs(spells) do if Menu.AutoInterrupt[spell.name] then for j, LastCast in pairs(LastCastedSpell) do if LastCast.name == spell.name:lower() and (os.clock() - LastCast.time) < 3 and GetDistance(LastCast.caster.visionPos, myHero.visionPos) < Rrange and ValidTarget(LastCast.caster) then CastSpell(_R, myHero.x, myHero.z) break end end end end end end function OnProcessSpell(unit, spell) if unit.team ~= myHero.team and unit.type == myHero.type then LastCastedSpell[unit.networkID] = {name = spell.name:lower(), time = os.clock(), caster = unit} end end function OnDraw() if Menu.Drawing.Qrange then DrawCircle2(myHero.x, myHero.y, myHero.z, Qrange, ARGB(255, 0, 255, 0)) end if SelectedTarget ~= nil then DrawCircle2(SelectedTarget.x, SelectedTarget.y, SelectedTarget.z, 100, ARGB(255, 255, 0, 0)) if Menu.Drawing.DrawWP then wayPointManager:DrawWayPoints(SelectedTarget) end if Menu.Drawing.DrawWPR then DrawText3D(tostring(wayPointManager:GetWayPointChangeRate(SelectedTarget)), SelectedTarget.x, SelectedTarget.y, SelectedTarget.z, 30, ARGB(255,0,255,0), true) end end if Menu.Drawing.ShowStats and Stats.CastedQs > 0 then DrawText("Stats", 17, 10, 10, ARGB(255,225,255,255)) local Ratio = Stats.LandedQchampions / Stats.CastedQs DrawText("Landed Q's (Total): "..Stats.LandedQ.."/"..Stats.CastedQs.." "..math.floor(Stats.LandedQ/Stats.CastedQs * 100).."%", 13, 10, 30, ARGB(255,255,255,255)) DrawText("Landed Q's (Champions): "..Stats.LandedQchampions.."/"..Stats.CastedQs.." "..math.floor(Stats.LandedQchampions/Stats.CastedQs * 100).."%", 13, 10, 45, ARGB(255,255,255,255)) DrawText("Landed Q's (Minions): "..Stats.LandedQminions.."/"..Stats.CastedQs.." "..math.floor(Stats.LandedQminions/Stats.CastedQs * 100).."%", 13, 10, 60, ARGB(255,255,255,255)) local i = 1 for name, times in ipairs(Stats.LandedQs) do DrawText("Landed Q's ("..name.."): "..times, 13, 10, 60 + i * 15, ARGB(255,255,255,255)) i = i + 1 end end end function DrawCircleNextLvl(x, y, z, radius, width, color, chordlength) radius = radius or 300 quality = math.max(8,math.floor(180/math.deg((math.asin((chordlength/(2*radius))))))) quality = 2 * math.pi / quality radius = radius*.92 local points = {} for theta = 0, 2 * math.pi + quality, quality do local c = WorldToScreen(D3DXVECTOR3(x + radius * math.cos(theta), y, z - radius * math.sin(theta))) points[#points + 1] = D3DXVECTOR2(c.x, c.y) end DrawLines2(points, width or 1, color or 4294967295) end function DrawCircle2(x, y, z, radius, color) local vPos1 = Vector(x, y, z) local vPos2 = Vector(cameraPos.x, cameraPos.y, cameraPos.z) local tPos = vPos1 - (vPos1 - vPos2):normalized() * radius local sPos = WorldToScreen(D3DXVECTOR3(tPos.x, tPos.y, tPos.z)) if OnScreen({ x = sPos.x, y = sPos.y }, { x = sPos.x, y = sPos.y }) then DrawCircleNextLvl(x, y, z, radius, 1, color, 75) end end function OnWndMsg(Msg, Key) if Msg == WM_LBUTTONDOWN then local minD = 0 local starget = nil for i, enemy in ipairs(GetEnemyHeroes()) do if ValidTarget(enemy) then if GetDistance(enemy, mousePos) <= minD or starget == nil then minD = GetDistance(enemy, mousePos) starget = enemy end end end if starget and minD < 500 then if SelectedTarget and starget.charName == SelectedTarget.charName then SelectedTarget = nil else SelectedTarget = starget print("Blitzcrank: New target selected: "..starget.charName.."") end end end end function OnRecvPacket(p) if p.header == 0xB4 then p.pos = 1 local b1 = p:DecodeF() p.pos = p.size - 25 local b2 = p:Decode1() p.pos = p.size - 44 local b3 = p:Decode1() if b1 == myHero.networkID and b2 == 43 and b3 ~= 0 then Stats.CastedQs = Stats.CastedQs + 1 p.pos = 37 pid = p:DecodeF() pidtime = os.clock() end elseif p.header == 0x25 then p.pos = 1 local pr = p:DecodeF() if pr == pid and (os.clock() - pidtime) < 5 then p.pos = p.pos + 2 local h = objManager:GetObjectByNetworkId(p:DecodeF()) if h and h.valid then Stats.LandedQ = Stats.LandedQ + 1 if h.type == myHero.type then if myHero:CanUseSpell(_E) == READY then CastSpell(_E) myHero:Attack(h) end Stats.LandedQchampions = Stats.LandedQchampions + 1 Stats.LandedQs[h.charName] = (Stats.LandedQs[h.charName] and Stats.LandedQs[h.charName] or 0 ) + 1 else Stats.LandedQminions = Stats.LandedQminions + 1 end end end end end