_G.Orbwalker = MenuElement({type = MENU, id = "Orbwalker", name = "Orbwalker", leftIcon = "http://goldenorbpublications.com/images/goldenord-small-logo.png"})
Orbwalker:MenuElement({id = "Enabled", name = "Enabled", value = true})
Orbwalker:MenuElement({id = "Combo", name = "Combo", key = string.byte(" ")})
Orbwalker:MenuElement({id = "Harass", name = "Harass", key = string.byte("C")})
Orbwalker:MenuElement({id = "Farm", name = "Farm", key = string.byte("V")})
Orbwalker:MenuElement({id = "LastHit", name = "LastHit", key = string.byte("X")})
Orbwalker:MenuElement({id = "PreAADelay", name = "Compensate Delay", value = 0.16, min = 0, max = 0.5, step = 0.01})
Orbwalker:MenuElement({type = MENU, id = "Drawings", name = "Drawings"})
Orbwalker.Drawings:MenuElement({id = "Enabled", name = "Enabled", value = true})
Orbwalker.Drawings:MenuElement({id = "MyHeroRange", name = "My Champion Range", value = true})
Orbwalker.Drawings:MenuElement({id = "LastHitMarker", name = "Last Hit Marker", value = true})
local lastMove, lastAttack = os.clock(), os.clock()
local state = -1
local isMoving = false
local attackData = myHero.attackData
local clock = os.clock()
local latency = Game.Latency() * 0.001 + 0.1
local myMinions, myMinionCount = {}, 0
local myRange = myHero.range + myHero.boundingRadius * 2
local max, ceil = math.max, math.ceil
local server_tick = 30
local function RoundToServerTime(delta)
return ceil(server_tick * delta) / server_tick
end
local function GetPredictedHealth(minion)
local health = minion.health + minion.shieldAD
local minionHandle = minion.handle
local timeToReachMinion = RoundToServerTime(attackData.windUpTime + (myHero.range<=425 and 0 or max(0, myHero.pos:DistanceTo(minion.pos) - minion.boundingRadius) / attackData.projectileSpeed) + Game.Latency() * 0.001 + 0.07)
for i = 1, myMinionCount do
local attacker = myMinions[i].minion
local tAttackData = attacker.attackData
if tAttackData.target == minionHandle then
local sCharName = attacker.charName
if sCharName:find("Melee") or sCharName:find("Super") then
if tAttackData.state == STATE_WINDUP then
if RoundToServerTime(tAttackData.endTime - Game.Timer()) < timeToReachMinion then
health = health - (attacker.totalDamage * (1 + attacker.bonusDamagePercent) - minion.flatDamageReduction)
end
elseif tAttackData.state == STATE_WINDDOWN then -- assume reattack
if RoundToServerTime(tAttackData.windUpTime - (tAttackData.endTime - Game.Timer())) < timeToReachMinion then
health = health - (attacker.totalDamage * (1 + attacker.bonusDamagePercent) - minion.flatDamageReduction)
end
end
else
local timeToHit = RoundToServerTime(max(0, attacker.pos:DistanceTo(minion.pos) - minion.boundingRadius) / tAttackData.projectileSpeed)
if tAttackData.state == STATE_WINDUP then
local remainingWindUpTime = RoundToServerTime(tAttackData.endTime - Game.Timer())
if remainingWindUpTime + timeToHit < timeToReachMinion then
health = health - (attacker.totalDamage * (1 + attacker.bonusDamagePercent) - minion.flatDamageReduction)
end
elseif tAttackData.state == STATE_WINDDOWN then
local remainingWindDownTime = RoundToServerTime(tAttackData.endTime - Game.Timer())
local attackedBefore = RoundToServerTime(tAttackData.windDownTime - remainingWindDownTime)
if timeToHit > attackedBefore and timeToHit - attackedBefore < timeToReachMinion then -- attack is flying
health = health - (attacker.totalDamage * (1 + attacker.bonusDamagePercent) - minion.flatDamageReduction)
end
end
end
end
end
for i = 1, Game.HeroCount() do
local attacker = Game.Hero(i)
if attacker and attacker.valid and attacker.isAlly then
local tAttackData = attacker.attackData
if tAttackData.target == minionHandle then
if attacker.range<425 then
if tAttackData.state == STATE_WINDUP then
if tAttackData.endTime-Game.Timer() < timeToReachMinion then
health = health - (attacker.totalDamage * (1 + attacker.bonusDamagePercent) - minion.flatDamageReduction)
end
end
else
local timeToHit = (attacker.pos:DistanceTo(minion.pos) - attacker.boundingRadius) / tAttackData.projectileSpeed
if tAttackData.state == STATE_WINDUP then
local remainingWindUpTime = (tAttackData.endTime-Game.Timer())
if remainingWindUpTime + timeToHit < timeToReachMinion then
health = health - (attacker.totalDamage * (1 + attacker.bonusDamagePercent) - minion.flatDamageReduction)
end
elseif tAttackData.state == STATE_WINDDOWN then
local remainingWindDownTime = (tAttackData.endTime-Game.Timer())
if timeToHit - (tAttackData.windDownTime - remainingWindDownTime) < timeToReachMinion then
health = health - (attacker.totalDamage * (1 + attacker.bonusDamagePercent) - minion.flatDamageReduction)
end
end
end
end
end
end
return health
end
Callback.Add("Tick", function()
if Orbwalker.Enabled:Value() == false then return end
if not Game.IsOnTop() or Game.IsChatOpen() or myHero.dead then return end
attackData = myHero.attackData
clock = os.clock()
latency = Game.Latency() * 0.001 + 0.1
myRange = myHero.range + myHero.boundingRadius * 2
myDamage = myHero.totalDamage
myMinions, myMinionCount = {}, 0
for i = 1, Game.MinionCount() do
local minion = Game.Minion(i)
if minion and minion.valid and minion.visible then
local dist = minion.pos:DistanceTo(myHero.pos)
myMinionCount = myMinionCount + 1
myMinions[myMinionCount] = {minion = minion, canAttack = dist <= myRange and minion.isEnemy} --
end
end
for i = 1, myMinionCount do
local v = myMinions[i]
if v.canAttack then
myMinions[i].health = GetPredictedHealth(v.minion)
myMinions[i].canLastHit = myMinions[i].health < myDamage - 1
end
end
if lastAttack > clock then return end
if (attackData.endTime - Orbwalker.PreAADelay:Value()) < Game.Timer() then
if Orbwalker.LastHit:Value() or Orbwalker.Farm:Value() or Orbwalker.Harass:Value() then
if Orbwalker.LastHit:Value() then
for i = 1, myMinionCount do
local v = myMinions[i]
if v.canLastHit then
lastAttack = clock + latency
Control.Attack(v.minion)
return;
end
end
end
if Orbwalker.Farm:Value() then
for i = 1, myMinionCount do
local v = myMinions[i]
if v.canLastHit then
lastAttack = clock + latency
Control.Attack(v.minion)
return;
end
end
for i = 1, myMinionCount do
local v = myMinions[i]
if v.canAttack then
lastAttack = clock + latency
Control.Attack(v.minion)
return;
end
end
end
if Orbwalker.Harass:Value() then
for i = 1, myMinionCount do
local v = myMinions[i]
if v.canLastHit then
lastAttack = clock + latency
Control.Attack(v.minion)
return;
end
end
for i = 1, Game.HeroCount() do
local hero = Game.Hero(i)
if hero and hero.valid and hero.visible and hero.isEnemy and hero.pos:DistanceTo(myHero.pos) < myHero.range + myHero.boundingRadius then
lastAttack = clock + latency
Control.Attack(hero)
return;
end
end
end
for i = 1, Game.TurretCount() do
local turret = Game.Turret(i)
if turret and turret.valid and turret.isEnemy and turret.pos:DistanceTo(myHero.pos) < myHero.range + myHero.boundingRadius then
lastAttack = clock + latency
Control.Attack(turret)
return;
end
end
end
if Orbwalker.Combo:Value() then
for i = 1, Game.HeroCount() do
local hero = Game.Hero(i)
if hero and hero.valid and hero.visible and hero.isEnemy and hero.pos:DistanceTo(myHero.pos) < myHero.range + myHero.boundingRadius then
lastAttack = clock + latency
Control.Attack(hero)
return;
end
end
end
end
if attackData.state ~= STATE_WINDUP and (Orbwalker.LastHit:Value() or Orbwalker.Farm:Value() or Orbwalker.Combo:Value() or Orbwalker.Harass:Value()) then
local posTo = myHero.posTo
if lastMove < clock and mousePos:DistanceTo(myHero.pos) > myHero.boundingRadius * 2 and (posTo:DistanceTo(myHero.pos) < myHero.boundingRadius or math.abs(posTo:Compare(mousePos)) > 55) then
lastMove = clock + latency + 0.07
Control.Move()
end
end
end)
Callback.Add("Draw", function()
if Orbwalker.Enabled:Value() == false then return end
if Orbwalker.Drawings.Enabled:Value() == false then return end
if myHero.dead then return end
if Orbwalker.Drawings.MyHeroRange:Value() then
Draw.Circle(myHero.pos, myHero.range + myHero.boundingRadius, 3, Draw.Color(255, 0x5a, 0x5f, 0xbe))
end
for i = 1, myMinionCount do
local v = myMinions[i]
if v.canLastHit then
if Orbwalker.Drawings.LastHitMarker:Value() then
Draw.Circle(v.minion.pos, v.minion.boundingRadius, 3, Draw.Color(255, 0, 255, 0))
end
end
end
end)