local version = "0.11" --[[ Changelog v0.01 - release v0.02 - jungle farm and manual Q added v0.03 - Q cancel added (default button = 'C') v0.04 - Ward casting bug fixed v0.05 - Revamped support added v0.06 - Changed manual Q logic slightly. MAKE SURE YOU HOLD THE BUTTON FOR AIM. v0.07 - Added failsafes for enemy going out of range, should now cast if enemy goes back into range while Q is charging (if they were initially out of range) v0.08 - now will use E when killable and not wait for a reset. v0.09 - autoupdater v0.1 - 2nd cast E stuff v0.11 - Packet update for 4.18 ]]-- if myHero.charName ~= "Vi" then return end local AUTOUPDATE = true local UPDATE_HOST = "raw.github.com" local UPDATE_PATH = "/Dienofail/BoL/master/common/SidasAutoCarryPlugin%20-%20Vi.lua".."?rand="..math.random(1,10000) local UPDATE_FILE_PATH = LIB_PATH.."SidasAutoCarryPlugin - Vi.lua" local UPDATE_URL = "https://"..UPDATE_HOST..UPDATE_PATH function AutoupdaterMsg(msg) print("SAC VI: "..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 "Collision" require "VPrediction" function PluginOnLoad() --Menu mainLoad() mainMenu() end function CastSpellQ1(posx, posz) if myHero:CanUseSpell(_Q) == READY then if not isPressedQ then --CastSpell(_Q, x, z) Packet("S_CAST", {spellId = _Q, x = posx, y = posz}):send() qTick = GetTickCount() --PrintChat("Cast phase 1") end end end function CastSpellQ2(x, y) if isPressedQ then qTick = GetTickCount() --PrintChat("2nd phase called") Send2ndQPacket(x, y) end end function CheckQstatus() if isPressedQ then --PrintChat('Q is pressed Q current casttime is ' .. tostring(Qcasttime) .. ' Qstart time is ' .. tostring(Qstartcasttime)) end end function CheckQCastTime() if os.clock() - Qstartcasttime > 1.250 then Qcasttime = 1.250 end if os.clock() - Qstartcasttime > 5 then Qcasttime = 0 isPressedQ = false end end function ConvertQCastTime() if isPressedQ then --PrintChat("Q is being updated!") range = 250 if Qcasttime < 0.250 then range = 250 end if Qcasttime > 1.250 then range = 715 end if Qcasttime > 0.250 and Qcasttime < 1.250 then --PrintChat("Middle calculation being done!") range = (Qcasttime - 0.250 / 1.250)*465 + 250 --PrintChat("middle calculation result " .. tostring(range)) end return range end end function UpdateQCasttime() if isPressedQ then Qcasttime = os.clock() - Qstartcasttime end if not isPressedQ then Qcasttime = 0 end end function PluginOnTick() Checks() UpdateQCasttime() CheckQCastTime() CheckQstatus() JungleClear() CurrentRange = ConvertQCastTime(Qcasttime) if Menu.manualQ then --PrintChat('Current range is ' .. tostring(CurrentRange)) CastSpellQ1(myHero.x, myHero.z) end if Target and Menu.manualQ and ValidTarget(Target) and isPressedQ then --print('Manual q part 2 getting called') local CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, 0.483, 55, CurrentRange, qSpeed, myHero, false) if GetDistance(CastPosition) < CurrentRange and HitChance > 0 then CastSpellQ2(CastPosition.x, CastPosition.z) end end --PrintChat(tostring(isPressedQ)) if Menu.CancelQ then local CastPosition, HitChance, Position = nil if ValidTarget(Target) then CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, 0.483, 55, CurrentRange, qSpeed, myHero, false) end if CastPosition ~= nil and GetDistance(CastPosition) < CurrentRange and ValidTarget(Target) then CastSpellQ2(CastPosition.x, CastPosition.z) else CastSpellQ2(mousePos.x, mousePos.z) end end if Target and AutoCarry.MainMenu.AutoCarry then if getDmg("E", Target, myHero) > Target.health and EREADY and GetDistance(Target) < 250 then CastSpell(_E, Target) end if not isPressedQ then local CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, 1, 55, 725, qSpeed, myHero) if QREADY and GetDistance(CastPosition) < 700 and GetDistance(Target) > Menu.qdistance and HitChance > 1 then CastSpellQ1(CastPosition.x, CastPosition.z) end end if isPressedQ then --PrintChat('2nd part ready') local CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, 0.483, 55, CurrentRange, qSpeed, myHero) --PrintChat(tostring(HitChance) .. ' ' .. tostring(CastPosition.x) .. ' ' .. tostring(CastPosition.z)) if GetDistance(CastPosition) < CurrentRange and HitChance > 0 then CastSpellQ2(CastPosition.x, CastPosition.z) end end --if QREADY and Menu.useQ and GetDistance(Target) < 800 and GetDistance(Target) > 300 and not isPressedQ and AutoCarry.MainMenu.AutoCarry and Qcasttime == 0 then --print("Debug") --PrintChat('Calculating Q') --calculating delay = sample every value from 0 --> 500 ms --[[for i=0, qtotalcasttime, 10 do current_range = (qmaxRange - qminRange)/ (i/qtotalcasttime) current_range = current_range + qminRange current_cast_time = i + 250 / 1000 CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, current_cast_time, 55, current_range, qSpeed) if HitChance > min_hit_chance then CastSpell(_Q, CastPosition.x, CastPosition.z) CastSpell(10) end end]] --CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, current_cast_time, 55, current_range, qSpeed) --CastSpell(_Q, Target.x, Target.z) --isPressedQ = true --end --if isPressedQ then --print("Debug2") --[[PrintChat(tostring(Qcasttime)) --check to see if current cast time and position intersects with enemy vector if Qcasttime > qtotalcasttime then Qcasttime = qtotalcasttime else Qcasttime = os.clock() - Qstarttime end print("Debug3") current_range = qminRange + Qcasttime*(qmaxRange-qminRange/qtotalcasttime) CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, 0.250, 55, current_range, qSpeed) if HitChance > min_hit_chance then Qshouldcast = true PrintChat("Sending packet") Send2ndQPacket(myHero.networkID, CastPosition.x, CastPosition.z) end]] --else --Qshouldcast = false --end if RREADY and Menu.useR and GetDistance(Target) < rRange and AutoCarry.MainMenu.AutoCarry and Menu.useRfirst then CastSpell(_R, Target) end if RREADY and GetDistance(Target) < rRange and killsteal and GetDmg("R", Target, myHero) > Target.health then CastSpell(_R, Target) end if AutoCarry.MainMenu.AutoCarry and EREADY and GetDistance(Target) < eRange and Menu.useE then if IsSACReborn then SkillE:Cast(Target) else AutoCarry.CastSkillshot(SkillE, Target) end end end if isPressedQ and not AutoCarry.MainMenu.AutoCarry and not Menu.manualQ and ValidTarget(Target, 800) and not IsKeyDown(KeyQ) then local CastPosition, HitChance, Position = nil if ValidTarget(Target) then CastPosition, HitChance, Position = VP:GetLineCastPosition(Target, 0.483, 55, CurrentRange, qSpeed, myHero) end if CastPosition ~= nil and GetDistance(CastPosition) < CurrentRange and ValidTarget(Target) then CastSpellQ2(CastPosition.x, CastPosition.z) else CastSpellQ2(mousePos.x, mousePos.z) end end end function JungleClear() if IsSACReborn then JungleMob = AutoCarry.Jungle:GetAttackableMonster() else JungleMob = AutoCarry.GetMinionTarget() end if JungleMob ~= nil then if Menu.JungleKey and GetDistance(JungleMob) < 250 then AutoCarry.Orbwalker:Orbwalk(JungleMob) if IsSACReborn then SkillE:Cast(JungleMob) else AutoCarry.CastSkillshot(SkillE, JungleMob) end if QREADY and not isPressedQ then CastSpell(_Q, JungleMob.x, JungleMob.z) end if isPressedQ then CastSpell(_Q, JungleMob.x, JungleMob.z) end end end end function mainLoad() VP = VPrediction() if AutoCarry.Skills then IsSACReborn = true else IsSACReborn = false end if IsSACReborn then AutoCarry.Skills:DisableAll() end Carry = AutoCarry.MainMenu min_hit_chance = 1 Menu = AutoCarry.PluginMenu qtotalcasttime = 400 --not sure about this value yet qmaxRange = 715 qminRange = 250 qWidth = 55 qSpeed = 1500 eRange = 300 rRange = 800 QREADY = false EREADY = false RREADY = false isPressedQ = false Qcasttime = 0 Qstartcasttime = 0 Qbeingcast = false Qshouldcast = false invisibleTime = 300 Qstarttime = 0 buffer = 0 qTick = 0 if IsSACReborn then SkillE = AutoCarry.Skills:NewSkill(false, _E, qRange, "Vi E", AutoCarry.SPELL_TARGETED, 0, true, true, math.huge, 240, 0, 0) else SkillE = {spellKey = _E, range = 250, speed = math.huge, delay = 0, width = 0, configName = "ViE", displayName = "ViE", enabled = true, skillShot = false, minions = true, reset = true, reqTarget = true } end ignite = ((myHero:GetSpellData(SUMMONER_1).name:find("SummonerDot") and SUMMONER_1) or (myHero:GetSpellData(SUMMONER_2).name:find("SummonerDot") and SUMMONER_2) or nil) PrintChat("Sidas Autocarry Vi Plugin by Dienofail loaded v0.09") if VIP_USER then AdvancedCallback:bind('OnGainBuff', function(unit, buff) OnGainBuff(unit, buff) end) AdvancedCallback:bind('OnLoseBuff', function(unit, buff) OnLoseBuff(unit, buff) end) AdvancedCallback:bind('OnCreateObj', function(unit, buff) OnCreateObj(unit, buff) end) AdvancedCallback:bind('OnDeleteObj', function(unit, buff) OnDeleteObj(unit, buff) end) end if IsSACReborn then AutoCarry.Crosshair:SetSkillCrosshairRange(900) else AutoCarry.SkillsCrosshair.range = 900 end -- Set the spell target selector range end function mainMenu() HKC = string.byte("T") HKX = string.byte("X") HKV = string.byte("C") KeyQ = string.byte("Q") Menu:addParam("useQ", "Use (Q)", SCRIPT_PARAM_ONOFF, true) Menu:addParam("useE", "Use (E)", SCRIPT_PARAM_ONOFF, true) Menu:addParam("useR", "Use (R)", SCRIPT_PARAM_ONOFF, true) Menu:addParam("useRfirst", "Use (R) first", SCRIPT_PARAM_ONOFF, false) Menu:addParam("qdistance", "Use (Q) Chase Distance", SCRIPT_PARAM_SLICE, 150, 0, 715, 150) Menu:addParam("killsteal", "Kill Steal with R", SCRIPT_PARAM_ONOFF, true) Menu:addParam("drawQ", "Draw (Q)", SCRIPT_PARAM_ONOFF, true) Menu:addParam("drawR", "Draw (R)", SCRIPT_PARAM_ONOFF, true) --Menu:addParam("manualQ", "Q PREDICTION KEY", SCRIPT_PARAM_ONKEYDOWN, false, ) Menu:addParam("manualQ","Manual Cast Q (YOU MUST HOLD THIS)", SCRIPT_PARAM_ONKEYDOWN, false, HKC) Menu:addParam("JungleKey","Jungle Clear", SCRIPT_PARAM_ONKEYDOWN, false, HKX) Menu:addParam("CancelQ","Emergency Release Q", SCRIPT_PARAM_ONKEYDOWN, false, HKV) end function OnGainBuff(unit, buff) if unit.isMe and buff.name == 'ViQ' then --PrintChat("Gained") isPressedQ = true Qstartcasttime = os.clock() end end function OnLoseBuff(unit, buff) if unit.isMe and buff.name == 'ViQ' then --PrintChat("Lost") isPressedQ = false Qcasttime = 0 end end --[[function OnCreateObj(object) if object.name == "Vi_Q_Channel_L.troy" then iPressedQ = true PrintChat("Object Gained") Qstarttime = os.clock() Qcasttime = 0 end end]] function PluginOnDeleteObj(object) if object.name == "Vi_Q_Channel_L.troy" then iPressedQ = false Qcasttime = 0 end end --Copied from function Send2ndQPacket(xpos, zpos) --PrintChat("Packet Called!") packet = CLoLPacket(0xE6) packet:EncodeF(myHero.networkID) packet:Encode1(190) packet:Encode1(0) packet:EncodeF(xpos) packet:EncodeF(myHero.y) packet:EncodeF(zpos) packet.dwArg1 = 1 packet.dwArg2 = 0 SendPacket(packet) --PrintChat("Packet Sent!") --nID, spell, x, y, z end function PluginOnSendPacket(packet) -- New handler for SAC: Reborn local p = Packet(packet) --if p:get("spellId") == SkillE.spellKey and not (AutoCarry.MainMenu.AutoCarry or AutoCarry.MainMenu.LaneClear or AutoCarry.MainMenu.MixedMode or AutoCarry.PluginMenu.SlowE) then --p:block() --end if Menu.CancelQ == false then if packet.header == 0xE6 and AutoCarry.MainMenu.AutoCarry then --and Cast then -- 2nd cast of channel spells packet2 packet.pos = 5 spelltype = packet:Decode1() if spelltype == 0x80 then -- 0x80 == Q packet.pos = 1 packet:Block() --PrintChat("Packet blocked") end end if packet.header == 0xE6 and isPressedQ and Menu.manualQ then --and Cast then -- 2nd cast of channel spells packet2 packet.pos = 5 spelltype = packet:Decode1() if spelltype == 0x80 then -- 0x80 == Q packet.pos = 1 packet:Block() --PrintChat("Packet blocked") end end end end function Checks() QREADY = (myHero:CanUseSpell(_Q) == READY) WREADY = (myHero:CanUseSpell(_W) == READY) EREADY = (myHero:CanUseSpell(_E) == READY) RREADY = (myHero:CanUseSpell(_R) == READY) if myHero:GetSpellData(SUMMONER_1).name:find("SummonerDot") then ignite = SUMMONER_1 elseif myHero:GetSpellData(SUMMONER_2).name:find("SummonerDot") then ignite = SUMMONER_2 end IGNITEReady = (ignite ~= nil and myHero:CanUseSpell(ignite) == READY) if IsSACReborn then Target = AutoCarry.Crosshair:GetTarget() else Target = AutoCarry.GetAttackTarget() end end