if myHero.charName ~= "Jinx" then return end require 'VPrediction' --local variables local enemies = {} local minions = {} local jungleMinions = {} local DrakeBaronDmg = 0 local DrakeBaronTime = 0 local Wcast = 0 local teleporttime = 0 local tickCount = 0 local windUpTime = 0 local startAttackTime = 0 local SAC = false local SX = false local MMA = false local interrupts = { Katarina = { spell = "KatarinaR" }, Tresh = { spell = "ThreshQ" }, Velkoz = { spell = "VelkozR" }, Warwick = { spell = "InfiniteDuress" }, Galio = { spell = "GalioIdolOfDurand" }, Malzahar = { spell = "AlZaharNetherGrasp" }, Lux = { spell = "LuxMaliceCannon" }, Blitzcrank = { spell = "RocketGrabMissile" }, Caitlyn = { spell = "CaitlynPiltoverPeacemaker" }, MissFortune = { spell = "MissFortuneBulletTime" }, Ezreal = { spell = "EzrealTrueshotBarrage" } } local Spells = { Q = { ready = false, mana = 0, range = 0 }, W = { ready = false, mana = 0, range = 1500, delay = 0.6, width=60, speed = 3300}, E = { ready = false, mana = 0, range = 900, delay = 1.2, width=1, speed=1750}, R = { ready = false, mana = 0, range = 3000, delay = 0.7, width=140, speed = 1500} } --hooks function OnLoad() loadOrbwalker() variables() menu() end function OnTick() check() if SAC then QBefore() end if checkTick(0) then if config.rconfig.rconfigjungle.Rjungle and Spells.R.ready then JungleStealer() end if GetInGameTimer() - teleporttime < 4 and teleportpos ~= nil and config.econfig.telE then CastSpell(_E, teleportpos.x, teleportpos.z) end end if checkTick(1) then if Spells.E.ready then ELogic() end end if checkTick(2) then if Spells.Q.ready then QLogic() end end if checkTick(3) then if Spells.W.ready and config.wconfig.autoW then WLogic() end end if checkTick(4) then if config.rconfig.manualR and Spells.R.ready then local target = targetSelector(Spells.R.range, DAMAGE_PHYSICAL) if ValidTarget(target) then local CastPosition = VP:GetLineCastPosition(target, Spells.R.delay, Spells.R.width, Spells.R.range, Spells.R.speed, myHero, false) CastSpell(_R, CastPosition.x, CastPosition.z) end end if Spells.R.ready and config.rconfig.autoR then RLogic() end end end function isWindingUp() if windUpTime > GetInGameTimer() - startAttackTime then return true end return false end function OnCreateObj(obj) if obj.name == "global_ss_teleport_target_red.troy" then teleporttime = GetInGameTimer() teleportpos = obj.pos end end function OnProcessSpell(object, spell) if config.econfig.opsE and object.team ~= myHero.team and interruptWithE(object, spell.name) and ValidTarget(object, Spells.E.range) then CastSpell(_E, object.pos.x, object.pos.z) end if object.isMe and spell.name == "JinxW" then Wcast = GetInGameTimer() end end function OnProcessAttack(unit, spell) if unit.isMe then startAttackTime = GetInGameTimer() windUpTime = spell.windUpTime end end function QBefore() local target = targetSelector(bonusRange() + 60, DAMAGE_PHYSICAL) if Spells.Q.ready and fishBoneActive and ValidTarget(target) then if isCombo() and getRealDistance(target) < getRealPowPowRange(target) and (myHero.mana < (Spells.R.mana + Spells.W.mana + 20) or myHero:CalcDamage(target, myHero.totalDamage) * 3 < target.health) then CastSpell(_Q) elseif farm and (getRealDistance(target) > bonusRange() or getRealDistance(target) < getRealPowPowRange(target) or myHero.mana < (Spells.R.mana + Spells.E.mana + (Spells.W.mana*2))) then CastSpell(_Q) end end if Spells.Q.ready and isLaneClear() and not fishBoneActive and myHero.mana < (Spells.R.mana + Spells.E.mana + Spells.W.mana + 30) then minions:update() for _, minion in pairs(minions.objects) do if isInAutoAttackRange(minion) and minion.health < myHero:CalcDamage(minion, myHero.totalDamage) then for _, minion2 in pairs(minions.objects) do if minion2.health < myHero:CalcDamage(minion, myHero.totalDamage) and GetDistance(minion, minion2) < 150 and minion2.pos ~= minion.pos then CastSpell(_Q) end end end end end end --spells logic function QLogic() if farm and config.farmQ and myHero.mana > (Spells.R.mana + Spells.E.mana + Spells.W.mana + 10) and not fishBoneActive then farmWithQ() end local target = targetSelector(bonusRange() + 60, DAMAGE_PHYSICAL) if ValidTarget(target) then local distance = getRealDistance(target) local powPowRange = getRealPowPowRange(target) if not fishBoneActive and not isInAutoAttackRange(target) then if isCombo() and (myHero.mana > (Spells.R.mana + Spells.W.mana + 20) or myHero:CalcDamage(target, myHero.totalDamage)*2 > target.health) then CastSpell(_Q) elseif isHarass() and myHero.mana > (Spells.R.mana + Spells.E.mana + Spells.W.mana + 20) and (distance < (bonusRange() + getHitBox(myHero) + getHitBox(target))) then CastSpell(_Q) elseif isLaneClear() and not UnderTurret(myHero) and myHero.mana > (Spells.R.mana + Spells.E.mana + (Spells.W.mana*2) + 20) and distance < bonusRange() then CastSpell(_Q) end end elseif not fishBoneActive and isCombo() and myHero.mana > (Spells.R.mana + Spells.W.mana + 20) and CountEnemyHeroInRange(2000) > 0 then CastSpell(_Q) elseif fishBoneActive and isCombo() and myHero.mana < (Spells.R.mana + Spells.W.mana + 20) then CastSpell(_Q) elseif fishBoneActive and isCombo() and CountEnemyHeroInRange(2000) == 0 then CastSpell(_Q) elseif fishBoneActive and farm then CastSpell(_Q) end end function WLogic() if isWindingUp() == true then return end local wait = false for _, enemy in ipairs(enemies) do if ValidTarget(enemy, Spells.W.range) then local predictedHealth = enemy.health + enemy.hpRegen * 2 local Wdmg = getDmg("W", enemy, myHero) if Wdmg > predictedHealth or Wdmg > enemy.health then wait=true local CastPosition, HitChance, Position = VP:GetLineCastPosition(enemy, Spells.W.delay, Spells.W.width, Spells.W.range, Spells.W.speed, myHero, true) if CastPosition and HitChance >= 2 and not isInAutoAttackRange(enemy) and CountEnemyHeroInRange(400) == 0 and config.wconfig.ksW then CastSpell(_W, CastPosition.x, CastPosition.z) end end end end local target = targetSelector(Spells.W.range, DAMAGE_PHYSICAL) if ValidTarget(target) and not wait then local CastPosition, HitChance, Position = VP:GetLineCastPosition(target, Spells.W.delay, Spells.W.width, Spells.W.range, Spells.W.speed, myHero, true) if CastPosition and HitChance >= 2 and isCombo() and myHero.mana > (Spells.R.mana + Spells.W.mana + 10) and CountEnemyHeroInRange(getRealPowPowRange(target)) == 0 and getRealDistance(target) > bonusRange() - 50 then CastSpell(_W, CastPosition.x, CastPosition.z) elseif CastPosition and HitChance >= 2 and (farm and myHero.mana > (Spells.R.mana + Spells.E.mana + (Spells.W.mana*2) + 40)) and config.wconfig["haras"..target.charName] and not UnderTurret(myHero) and CountEnemyHeroInRange(bonusRange()) == 0 then CastSpell(_W, CastPosition.x, CastPosition.z) elseif CastPosition and HitChance >= 2 and (farm or isCombo()) and myHero.mana > (Spells.R.mana + Spells.W.mana) and CountEnemyHeroInRange(getRealPowPowRange(target)) == 0 then for _, enemy in ipairs(enemies) do if enemy.canMove or TargetHaveBuff("Recall", target) then CastSpell(_W, CastPosition.x, CastPosition.z) end end end end end function ELogic() if myHero.mana > (Spells.R.mana + Spells.W.mana) and config.econfig.autoE then for _, target in ipairs(enemies) do if ValidTarget(target, Spells.E.range+100) then local TargetDashing, CanHit, DashPosition = VP:IsDashing(target, Spells.E.delay, Spells.E.width, Spells.E.speed, myHero) local CastPosition, HitChance, Position = VP:GetCircularCastPosition(target, 0.25, Spells.E.width, Spells.E.range, Spells.E.speed, myHero, false) local TargetCastPosition, TargetHitChance, TargetPosition = VP:GetCircularCastPosition(target, 1.2, Spells.E.width, Spells.E.range, 3000, myHero, false) if TargetDashing and GetDistance(DashPosition) < 300 and config.econfig.AGC then CastSpell(_E, DashPosition.x, DashPosition.z) elseif (target.canMove ~= false or (HitChance >= 3 and HitChance <= 5)) and myHero.mana > (Spells.R.mana + Spells.E.mana + Spells.W.mana) then CastSpell(_E, CastPosition.x, CastPosition.z) elseif config.econfig.comboE and isCombo() then local PlayerCastPosition, PlayerHitChance, PlayerPosition = VP:GetCircularCastPosition(myHero, Spells.E.delay, Spells.E.width, Spells.E.range, Spells.E.speed, myHero, false) if GetDistance(TargetCastPosition, target) > 350 and GetDistance(PlayerPosition, myHero) > 100 then if GetDistance(myHero, TargetCastPosition) > GetDistance(myHero, target) then if GetDistance(target, PlayerCastPosition) < GetDistance(target, myHero) then CastSpell(_E, TargetCastPosition.x, TargetCastPosition.z) end else if GetDistance(target, PlayerCastPosition) > GetDistance(target, myHero) then CastSpell(_E, TargetCastPosition.x, TargetCastPosition.z) end end end end end end end end function RLogic() if isWindingUp() == true then return end for _, target in ipairs(enemies) do if ValidTarget(target, Spells.R.range) and validUltTarget(target) and (GetInGameTimer() - Wcast > 1) then local predictedHealth = target.health + target.hpRegen * 2 local Rdmg = getDmg("R", target, myHero) if Rdmg > predictedHealth then local CastPosition, HitChance, Position = VP:GetLineCastPosition(target, Spells.R.delay, Spells.R.width, Spells.R.range, Spells.R.speed, myHero, false) if CastPosition and (HitChance >= 2 and HitChance <= 5) and getRealDistance(target) > (bonusRange() + 300 + getHitBox(target)) and countAllyInRangeOfUnit(600, target) == 0 and CountEnemyHeroInRange(400) == 0 and not checkCollisionWithHeroes(target, CastPosition) and isFacing(target) ~= true then CastSpell(_R, CastPosition.x, CastPosition.z) elseif CastPosition and (HitChance >= 2 and HitChance <= 5) and CountEnemyHeroInRange(200, target) > 2 and getRealDistance(target) > (bonusRange() + 200 + getHitBox(target)) then CastSpell(_R, CastPosition.x, CastPosition.z) end end end end end --calculations function isFacing(tar) local TargetCastPosition = VP:GetPredictedPos(tar, 1, 1750, myHero, false) --local PlayerCastPosition, PlayerHitChance = VPrediction:GetPredictedPos(myHero, 1, 1750, myHero, false) if GetDistance(myHero, TargetCastPosition) >= GetDistance(myHero, tar) then return false end return true end function checkTick(tick) if tickCount == tick then tickCount = tickCount + 1 if tickCount >= 5 then tickCount = 0 end return true end return false end function JungleStealer() jungleMinions:update() for _, mob in ipairs(jungleMinions.objects) do if ((mob.charName == "SRU_Dragon" and config.rconfig.rconfigjungle.Rdragon) or (mob.charName == "SRU_Baron" and config.rconfig.rconfigjungle.Rbaron)) and countAllyInRangeOfUnit(1000, mob) == 0 and mob.health < mob.maxHealth and GetDistance(myHero, mob) > 1000 then if DrakeBaronDmg == 0 then DrakeBaronDmg = mob.health end if GetInGameTimer() - DrakeBaronTime > 4 then if DrakeBaronDmg - mob.health > 0 then DrakeBaronDmg = mob.health end DrakeBaronTime = GetInGameTimer() else local dmgPerSec = (DrakeBaronDmg - mob.health) * (math.abs(DrakeBaronTime - GetInGameTimer()) / 4) if DrakeBaronDmg - mob.health > 0 then local timeTravel = getUltTravelTime(myHero, Spells.R.speed, Spells.R.delay, mob.pos) local timeR = (mob.health - (250 + (100 * myHero:GetSpellData(_R).level) + myHero.totalDamage + 300)) / (dmgPerSec / 4 ) if timeTravel > timeR then CastSpell(_R, mob.pos.x, mob.pos.z) end else DrakeBaronDmg = mob.health end end end end end function debugMsg(msg) PrintChat(tostring(msg)) end function getUltTravelTime(source, speed, delay, pos) local distance = GetDistance(source, pos) local missileSpeed = speed if source.charName == "Jinx" and distance > 1350 then local accelRate = 0.3 local accelDif = distance - 1350 if accelDif > 150 then accelDif = 150 end local dif = distance - 1500 missileSpeed = (1350 * speed + accelDif * (speed + accelRate * accelDif) + dif * 2200) / distance end return (distance / missileSpeed + delay) end function countAllyInRangeOfUnit(range, unit) local count = 0 for i = 1, heroManager.iCount do local hero = heroManager:GetHero(i) if hero.team == myHero.team and GetDistance(hero, unit) < range then count = count + 1 end end return count end function checkCollisionWithHeroes(tar, castPos) for _, enemy in ipairs(enemies) do if enemy.networkID ~= tar.networkID then if VP:CheckCol(tar, enemy, castPos, Spells.R.delay, Spells.R.width, Spells.R.range, Spells.R.speed, myHero, false) then return true end end end return false end function interruptWithE(object, spellName) if interrupts[object.charName] ~= nil and interrupts[object.charName].spell == spellName then return true end return false end function check() Spells.Q.ready, Spells.W.ready, Spells.E.ready, Spells.R.ready = (myHero:CanUseSpell(_Q) == READY), (myHero:CanUseSpell(_W) == READY), (myHero:CanUseSpell(_E) == READY), (myHero:CanUseSpell(_R) == READY) Spells.Q.mana, Spells.W.mana, Spells.E.mana, Spells.R.mana = 20, (40 + (myHero:GetSpellData(_W).level * 10 )), 50, 100 fishBoneActive = (myHero.range > 525.5) farm = (isLaneClear() or isHarass() or isLastHit()) if not Spells.R.ready then Spells.R.mana = Spells.W.mana - myHero.mpRegen * myHero:GetSpellData(_W).currentCd else Spells.R.mana = 100 end if myHero.health < myHero.maxHealth * 0.2 then Spells.Q.mana, Spells.W.mana, Spells.E.mana, Spells.R.ready = 0, 0, 0, 0 end end function farmWithQ() minions:update() for _, minion in pairs(minions.objects) do if not isInAutoAttackRange(minion) and minion.health < myHero:CalcDamage(minion, myHero.totalDamage) and getRealPowPowRange(minion) < getRealDistance(minion) and bonusRange() < getRealDistance(minion) then CastSpell(_Q) return end end end function validUltTarget(tar) if tar.dead or TargetHaveBuff("sionpassivezombie", tar) then return false end return true end function getHitBox(unit) return unit.boundingRadius end function bonusRange() return 670 + getHitBox(myHero) + 25 * myHero:GetSpellData(_Q).level end function getRealDistance(tar) return GetDistance(tar) + getHitBox(myHero) + getHitBox(tar) end function getRealPowPowRange(tar) return 650 + getHitBox(myHero) + getHitBox(tar) end function isInAutoAttackRange(tar) return (myHero.range + getHitBox(myHero) + getHitBox(tar) > GetDistance(tar)) end function targetSelector(range, dmgType) local tarsel = TargetSelector(ts.mode, range, dmgType) tarsel:update() return tarsel.target end function isCombo() if SX then return SxOrb.isFight elseif SAC then return _G.AutoCarry.Keys.AutoCarry elseif MMA then return _G.MMA_IsOrbwalking() end end function isHarass() if SX then return SxOrb.isHarass elseif SAC then return _G.AutoCarry.Keys.MixedMode elseif MMA then return _G.MMA_IsDualCarrying() end end function isLaneClear() if SX then return SxOrb.isLaneClear elseif SAC then return _G.AutoCarry.Keys.LaneClear elseif MMA then return _G.MMA_IsClearing() end end function isLastHit() if SX then return SxOrb.isLastHit elseif SAC then return _G.AutoCarry.Keys.LastHit elseif MMA then return _G.MMA_IsLasthitting() end end --variables/menu/drawings function menu() -- menu config = scriptConfig("NeXtGen Jinx", "Jinx") config:addSubMenu("Draw", "draw") config.draw:addParam("notification", "Show text and lines", SCRIPT_PARAM_ONOFF, true) config.draw:addParam("onlyRdy", "Draw spells range only if ready", SCRIPT_PARAM_ONOFF, true) config.draw:addParam("qRange", "Draw Q range circle", SCRIPT_PARAM_ONOFF, false) config.draw:addParam("wRange", "Draw W range circle", SCRIPT_PARAM_ONOFF, false) config.draw:addParam("eRange", "Draw E range circle", SCRIPT_PARAM_ONOFF, false) config.draw:addParam("rRange", "Draw R range circle", SCRIPT_PARAM_ONOFF, false) config:addSubMenu("Config W", "wconfig") config.wconfig:addParam("autoW", "Auto W", SCRIPT_PARAM_ONOFF, true) config.wconfig:addParam("ksW", "Kill steal with W", SCRIPT_PARAM_ONOFF, true) for _, enemy in pairs(enemies) do config.wconfig:addParam("haras"..enemy.charName, "Harass"..enemy.charName, SCRIPT_PARAM_ONOFF, true) end config:addSubMenu("Config E", "econfig") config.econfig:addParam("autoE", "Auto E", SCRIPT_PARAM_ONOFF, true) config.econfig:addParam("comboE", "Auto E in Combo", SCRIPT_PARAM_ONOFF, true) config.econfig:addParam("AGC", "Use E on gapclosers", SCRIPT_PARAM_ONOFF, true) config.econfig:addParam("opsE", "Interrupt important spells with E", SCRIPT_PARAM_ONOFF, true) config.econfig:addParam("telE", "Auto E on teleport casts", SCRIPT_PARAM_ONOFF, true) config:addSubMenu("Config R", "rconfig") config.rconfig:addParam("autoR", "Auto R", SCRIPT_PARAM_ONOFF, true) config.rconfig:addParam("manualR", "Key to manually cast R", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("T")) config.rconfig:addSubMenu("R jungle stealer", "rconfigjungle") config.rconfig.rconfigjungle:addParam("Rjungle", "R jungle stealer", SCRIPT_PARAM_ONOFF, true) config.rconfig.rconfigjungle:addParam("Rdragon", "Try to steal Dragon", SCRIPT_PARAM_ONOFF, true) config.rconfig.rconfigjungle:addParam("Rbaron", "Try to steal Baron", SCRIPT_PARAM_ONOFF, true) config:addParam("farmQ", "Farm with Q", SCRIPT_PARAM_ONOFF, true) if SX then config:addSubMenu("SxOrbWalker", "orbwalker") SxOrb:LoadToMenu(config.orbwalker) end config:addTS(ts) ts.name = "TargetSelector" end function loadOrbwalker() if _G.Reborn_Initialised then SAC = true elseif _G.Reborn_Loaded and not _G.Reborn_Initialised then DelayAction(function() loadOrbwalker() end, 1) elseif _G.MMA_Loaded ~= nil and _G.MMA_Loaded then MMA = true else SX = true if FileExist(LIB_PATH .. "/SxOrbWalk.lua") then require 'SxOrbWalk' end end if not SAC and not SX and not MMA then print ("This script requires SAC:R or SxOrb or MMA to work!") end end function variables() --variables ts = TargetSelector(TARGET_LOW_HP,1000) VP = VPrediction() enemies = GetEnemyHeroes() minions = minionManager(MINION_ENEMY, bonusRange() + 30, myHero, MINION_SORT_MAXHEALTH_ASC) jungleMinions = minionManager(MINION_JUNGLE, math.huge, myHero, MINION_SORT_MAXHEALTH_DES) if SX then SxOrb:RegisterBeforeAttackCallback(QBefore) end if MMA then _G.MMA_RegisterCallback('BeforeAttackCallbacks', QBefore) end --if SAC then _G.AutoCarry.Plugins:RegisterPreAttack(QBefore) end if SX then PrintChat ("NeXtGen Jinx Loaded with SxOrbWalker!") elseif SAC then PrintChat ("NeXtGen Jinx Loaded with SAC:Reborn!") elseif MMA then PrintChat ("NeXtGen Jinx Loaded with MMA!") end end function OnDraw() --draw if config.draw.qRange then if not fishBoneActive then DrawCircle3D(myHero.x, myHero.y, myHero.z, 590 + myHero.boundingRadius, 1, RGB(255,20,147)) else DrawCircle3D(myHero.x, myHero.y, myHero.z, bonusRange() - 40, 1, RGB(255, 20, 147)) end end if config.draw.wRange then if config.draw.onlyRdy then if Spells.W.ready then DrawCircle3D(myHero.x, myHero.y, myHero.z, Spells.W.range, 1, RGB(0,255,255)) end else DrawCircle3D(myHero.x, myHero.y, myHero.z, Spells.W.range, 1, RGB(0,255,255)) end end if config.draw.eRange then if config.draw.onlyRdy then if Spells.E.ready then DrawCircle3D(myHero.x, myHero.y, myHero.z, Spells.E.range, 1, RGB(0,255,255)) end else DrawCircle3D(myHero.x, myHero.y, myHero.z, Spells.E.range, 1, RGB(0,255,255)) end end if config.draw.RRange then if config.draw.onlyRdy then if Spells.R.ready then DrawCircle3D(myHero.x, myHero.y, myHero.z, Spells.R.range, 1, RGB(0,255,255)) end else DrawCircle3D(myHero.x, myHero.y, myHero.z, Spells.R.range, 1, RGB(0,255,255)) end end if config.draw.notification then local target = targetSelector(Spells.R.range, DAMAGE_PHYSICAL) if ValidTarget(target) and Spells.R.ready and getDmg("R", target, myHero) > (target.health + target.hpRegen) then DrawText3D("Can kill "..target.charName.." with R", myHero.x-190, myHero.y-150, myHero.z, 32, RGB(255,0,0), center) DrawLine3D(myHero.x, myHero.y, myHero.z, target.x, target.y, target.z, 3, RGB(255,0,0)) elseif ValidTarget(target, 2000) and Spells.W.ready and getDmg("W", target, myHero) > (target.health + target.hpRegen) then DrawText3D("Can kill "..target.charName.." with W", myHero.x-190, myHero.y-150, myHero.z, 32, RGB(255,0,0), center) DrawLine3D(myHero.x, myHero.y, myHero.z, target.x, target.y, target.z, 3, RGB(255,0,0)) end end end