Modules
pred
pred.trace.linear.hardlock(input, seg, obj)
Parameters
table input
seg seg
obj obj
Return Value
boolean returns true if obj is hard crowd controlled
pred.trace.linear.hardlockmove(input, seg, obj)
Parameters
table input
seg seg
obj obj
Return Value
boolean returns true if obj is hard crowd controlled by taunts, fears or charms
pred.trace.circular.hardlock(input, seg, obj)
Parameters
table input
seg seg
obj obj
Return Value
boolean returns true if obj is hard crowd controlled
pred.trace.circular.hardlockmove(input, seg, obj)
Parameters
table input
seg seg
obj obj
Return Value
boolean returns true if obj is hard crowd controlled by taunts, fears or charms
pred.trace.newpath(obj, t1, t2)
Parameters
obj obj
number t1
number t2
Return Value
boolean returns true if obj path has updated less than t1 seconds ago or more than t2 seconds ago
pred.core.lerp(path, delay, speed)
Parameters
path.obj path
number delay
number speed
Return Value
vec2 returns interpolated position along path
number returns path index of vec2
boolean returns true if vec2 is the end of path
local pred = module.internal('pred')
local function on_tick()
if player.path.active and player.path.count>0 then
local res, res_i, res_b = pred.core.lerp(player.path, 0.5, player.moveSpeed)
print(('%.2f-%.2f on index %u'):format(res.x, res.y, res_i), res_b)
end
end
cb.add(cb.tick, on_tick)pred.core.project(pos, path, delay, projectileSpeed, pathSpeed)
Parameters
vec2 pos
path.obj path
number delay
number projectileSpeed
number pathSpeed
Return Value
vec2 returns projected position along path
number returns path index of vec2
boolean returns true if vec2 is the end of path
local pred = module.internal('pred')
local function on_tick()
if player.path.active and player.path.count>0 then
local res, res_i, res_b = pred.core.project(mousePos2D, player.path, 0.5, 1200, player.moveSpeed)
print(('%.2f-%.2f on index %u'):format(res.x, res.y, res_i), res_b)
end
end
cb.add(cb.tick, on_tick)pred.core.project_off(pos, path, delay, projectileSpeed, pathSpeed, offset)
Parameters
vec2 pos
path.obj path
number delay
number projectileSpeed
number pathSpeed
vec2 offset
Return Value
vec2 returns projected position along path
number returns path index of vec2
boolean returns true if vec2 is the end of path
local pred = module.internal('pred')
local function on_tick()
if player.path.active and player.path.count>0 then
--same as core.project, but the path is offset
local res, res_i, res_b = pred.core.project_off(mousePos2D, player.path, 0.5, 1200, player.moveSpeed, vec2(0,100))
print(('%.2f-%.2f on index %u'):format(res.x, res.y, res_i), res_b)
end
end
cb.add(cb.tick, on_tick)pred.core.get_pos_after_time(obj, time)
Parameters
obj obj
number time
Return Value
vec2 returns position of obj after time
local pred = module.internal('pred')
local function on_tick()
local res = pred.core.get_pos_after_time(player, 0.5)
print(('%.2f-%.2f'):format(res.x, res.y))
end
cb.add(cb.tick, on_tick)pred.linear.get_prediction(input, tar, src)
Parameters
table input
obj tar
obj src [optional]
Return Value
seg returns a line segment
--this example is based on caitlyn q
local orb = module.internal('orb')
local ts = module.internal('TS')
local pred = module.internal('pred')
local pred_input = {
delay = 0.625,
speed = 2200,
width = 60,
range = 1150,
boundingRadiusMod = 1,
collision = {
wall = true,
},
}
local function trace_filter(seg, obj)
if seg.startPos:dist(seg.endPos) > pred_input.range then return false end
if pred.trace.linear.hardlock(pred_input, seg, obj) then
return true
end
if pred.trace.linear.hardlockmove(pred_input, seg, obj) then
return true
end
if pred.trace.newpath(obj, 0.033, 0.500) then
return true
end
end
local function target_filter(res, obj, dist)
if dist > 1500 then return false end
local seg = pred.linear.get_prediction(pred_input, obj)
if not seg then return false end
if not trace_filter(seg, obj) then return false end
res.pos = seg.endPos
return true
end
local function on_tick()
if player:spellSlot(0).state~=0 then return end
local res = ts.get_result(target_filter)
if res.pos then
player:castSpell('pos', 0, vec3(res.pos.x, mousePos.y, res.pos.y))
orb.core.set_server_pause()
return true
end
end
cb.add(cb.tick, on_tick)pred.circular.get_prediction(input, tar, src)
Parameters
table input
obj tar
obj src [optional]
Return Value
seg returns a line segment
--this example is based on xerath w
local orb = module.internal('orb')
local ts = module.internal('TS')
local pred = module.internal('pred')
local pred_input = {
delay = 0.75,
radius = 275,
speed = math.huge,
boundingRadiusMod = 0,
}
local function trace_filter(seg, obj)
if seg.startPos:dist(seg.endPos) > 950 then return false end
if pred.trace.circular.hardlock(pred_input, seg, obj) then
return true
end
if pred.trace.circular.hardlockmove(pred_input, seg, obj) then
return true
end
if pred.trace.newpath(obj, 0.033, 0.500) then
return true
end
end
local function target_filter(res, obj, dist)
if dist > 1500 then return false end
local seg = pred.circular.get_prediction(pred_input, obj)
if not seg then return false end
if not trace_filter(seg, obj) then return false end
res.pos = seg.endPos
return true
end
local function on_tick()
if player:spellSlot(1).state~=0 then return end
local res = ts.get_result(target_filter)
if res.pos then
player:castSpell('pos', 1, vec3(res.pos.x, mousePos.y, res.pos.y))
orb.core.set_server_pause()
return true
end
end
cb.add(cb.tick, on_tick)pred.present.get_source_pos(obj)
Parameters
obj obj
Return Value
vec2 returns server pos of obj
pred.present.get_prediction(input, tar, src)
Parameters
table input
obj tar
obj src [optional]
Return Values
vec2
--this example is based on kindred e
local orb = module.internal('orb')
local ts = module.internal('TS')
local pred = module.internal('pred')
local pred_input = {
delay = 0,
radius = player.attackRange,
dashRadius = 0,
boundingRadiusModSource = 1,
boundingRadiusModTarget = 1,
}
local function target_filter(res, obj, dist)
if dist>800 then return false end
if not pred.present.get_prediction(pred_input, obj) then return false end
res.obj = obj
return true
end
local function invoke()
if player:spellSlot(2).state~=0 then return end
local res = ts.get_result(target_filter)
if res.obj then
player:castSpell('obj', 2, res.obj)
orb.core.set_server_pause()
return true
end
endpred.collision.get_prediction(input, pred_result, ign_obj)
Parameters
table input
seg pred_result
obj ign_obj [optional]
Return Values
table returns a table of objects that pred_result will collide with or nil if no collision is detected
--this example is based on morgana q
local orb = module.internal('orb')
local ts = module.internal('TS')
local pred = module.internal('pred')
local pred_input = {
delay = 0.25,
speed = 1200,
width = 70,
boundingRadiusMod = 1,
range = 1100,
collision = {
minion = true, --checks collision for minions
hero = false, --no need to check for hero collision
-- checks all collisions: YasuoWall/SamiraWall/BraumWall/PantheonWall/MelWall
wall = true,
-- or checks specific collisions
-- wall = { yasuo = true, samira = true, braum = false, pantheon = false, mel = false },
},
}
local function trace_filter(seg, obj, dist)
if seg.startPos:dist(seg.endPos) > pred_input.range then
return false
end
if pred.trace.newpath(obj, 0.033, 0.500) and dist < 600 then
return true
end
if pred.trace.linear.hardlock(pred_input, seg, obj) then
return true
end
if pred.trace.linear.hardlockmove(pred_input, seg, obj) then
return true
end
end
local function target_filter(res, obj, dist)
if dist > pred_input.range then return false end
local seg = pred.linear.get_prediction(pred_input, obj)
if not seg then return false end
if not trace_filter(seg, obj, dist) then return false end
--pass obj as third arg, it will then be ignored from collision checks
if pred.collision.get_prediction(pred_input, seg, obj) then return false end
res.pos = seg.endPos
return true
end
local function on_tick()
if player:spellSlot(0).state~=0 then return end
local res = ts.get_result(target_filter)
if res.pos then
player:castSpell('pos', 0, vec3(res.pos.x, mousePos.y, res.pos.y))
orb.core.set_server_pause()
return true
end
end
cb.add(cb.tick, on_tick)orb
orb.core.akshan_should_double_attack
Return Value
boolean
local orb = module.internal('orb')
if xxx then
orb.core.akshan_should_double_attack = true -- set it in your AIO logic
endorb.core.cur_attack_target
Return Value
obj readonly, the current attack target
orb.core.cur_attack_name
Return Value
string readonly, the current AA spell name
orb.core.cur_attack_start_client
Return Value
number readonly, the time when current attack started, based on os.clock()
orb.core.cur_attack_start_server
Return Value
number readonly, the server time when current attack started, based on os.clock()
orb.core.cur_attack_speed_mod
Return Value
number readonly, the attack speed mod for current attack
orb.core.next_attack
Return Value
number readonly, time for next attack
orb.core.next_action
Return Value
number readonly, time for next action
orb.core.next_action
Return Value
number readonly, time for next action
orb.core.reset()
Return Value
void
local orb = module.internal('orb')
orb.core.reset() --resets the orbwalks attack cooldownorb.core.can_action()
Return Value
boolean returns true if player can move or cast spells
local orb = module.internal('orb')
local function on_tick()
print(orb.core.can_action() and 'can action' or 'can not action')
end
cb.add(cb.tick, on_tick)orb.core.can_move()
Return Value
boolean returns true if player can move
orb.core.can_attack()
Return Value
boolean returns true if player can attack
local orb = module.internal('orb')
local function on_tick()
print(orb.core.can_attack() and 'can attack' or 'can not attack')
end
cb.add(cb.tick, on_tick)orb.core.can_cast_spell(spellSlot, ignore_can_action_check)
Return Value
boolean returns true if player can cast spell
orb.core.is_paused()
Return Value
boolean returns true if the orb is paused (will not issue any orders)
local orb = module.internal('orb')
local function on_tick()
print(orb.core.is_paused() and 'is paused' or 'is not paused')
end
cb.add(cb.tick, on_tick)orb.core.is_move_paused()
Return Value
boolean returns true if the orb movement is paused (will not issue move orders)
local orb = module.internal('orb')
local function on_tick()
print(orb.core.is_move_paused() and 'move is paused' or 'move is not paused')
end
cb.add(cb.tick, on_tick)orb.core.is_attack_paused()
Return Value
boolean returns true if the orb attacks are paused (will not issue attack orders)
local orb = module.internal('orb')
local function on_tick()
print(orb.core.is_attack_paused() and 'attack is paused' or 'attack is not paused')
end
cb.add(cb.tick, on_tick)orb.core.is_spell_locked()
Return Value
boolean returns true if spells are paused
orb.core.is_winding_up_attack()
Return Value
boolean returns true if winding up
orb.core.set_pause(t)
Parameters
number t
Return Value
void
local orb = module.internal('orb')
local function on_process_spell(spell)
if spell.owner==player and spell.name=='AnnieQ' then
orb.core.set_pause(0.25)
end
end
cb.add(cb.spell, on_process_spell)orb.core.set_pause_move(t)
Parameters
number t
Return Value
void
orb.core.set_pause_attack(t)
Parameters
number t
Return Value
void
local orb = module.internal('orb')
local function on_process_spell(spell)
if spell.owner==player and spell.name=='XayahR' then
orb.core.set_pause_attack(1.5)
end
end
cb.add(cb.spell, on_process_spell)orb.core.set_server_pause()
Return Value
void
local orb = module.internal('orb')
local function on_tick()
if orb.core.is_paused() or not orb.core.can_action() or orb.core.is_move_paused() then return end
if player:spellSlot(0).state~=0 then return end
player:castSpell('pos', 0, mousePos)
orb.core.set_server_pause()
end
cb.add(cb.tick, on_tick)orb.core.set_server_pause_attack()
Return Value
void
orb.core.set_pause_spell_lock()
Return Value
void
orb.core.set_server_pause_spell_lock()
Return Value
void
orb.core.set_pause_strict_limitation(t)
The anti-disconnect feature of orbwalker in CN region is based on facing direction, while during some special spell casting like MelQ, facing direction will be changed very quickly. So we add this API to pause the strict anti-disconnect feature
DANGER
But shits anti-cheat in CN will not fix this. You maybe got banned/kicked out from game by pause this feature, and which is also the reason why normal players are banned (like VarusQ).
Parameters
number t
Return Value
void
orb.core.on_after_attack(callback)
Parameters
function callabck
Register a callback, which will be triggered once after a attack windup.
orb.core.on_player_attack(callback)
Parameters
function callabck
Register a callback, which will be triggered when a attack is responsed by server
orb.core.on_advanced_after_attack(callback)
Parameters
function callabck
Register a callback, which will be triggered when last attack is finished and could action now (called continuously after windup until attack ready again).
orb.core.time_to_next_attack()
Return Value
number the left seconds to issue next attack
orb.core.is_waiting_for_server_response(spellSlot)
Return Value
boolean
orb.core.is_waitting_for_cooldown(spellSlot)
Return Value
boolean
orb.combat.is_active()
Return Value
boolean returns true if combat mode is active
local orb = module.internal('orb')
local function on_tick()
if orb.combat.is_active() then
print('combat active')
end
end
cb.add(cb.tick, on_tick)orb.combat.target
Return Value
hero.obj the current attack hero (valid only for current tick)
local orb = module.internal('orb')
local function on_tick()
if orb.combat.is_active() and your_logic() then
orb.combat.target = your_logic_target()
end
end
cb.add(cb.tick, on_tick)orb.combat.pos
Return Value
hero.obj the prefer position (valid only for current tick) will orbwalker to
orb.combat.get_target()
orb.combat.set_target(t)
orb.combat.get_pos()
orb.combat.set_pos(t)
orb.combat.get_active()
orb.combat.set_active(t)
orb.combat.register_f_pre_attack(func)
Parameters
function func
Return Value
void
local orb = module.internal('orb')
local function on_pre_attack()
print('will attack', orb.combat.target)
-- you can set to new target
-- orb.combat.target = xxxx
end
orb.combat.register_f_pre_attack(on_pre_attack)orb.combat.register_f_after_attack(func)
Parameters
function func
Return Value
void
local orb = module.internal('orb')
local function on_after_attack()
print('attack is on cooldown')
-- you can return true to block other callbacks (Like callbacks registered by other plugin/module)
-- return true
-- [on_after_attack] is called continuously, set bool to false can stop subsequent calls for the current attack.
-- orb.combat.set_invoke_after_attack(bool)
end
orb.combat.register_f_after_attack(on_after_attack)orb.combat.register_f_out_of_range(func)
Parameters
function func
Return Value
void
local orb = module.internal('orb')
local function out_of_range()
print('there is no target in aa range')
-- you can return true to block other callbacks
-- return true
end
orb.combat.register_f_out_of_range(out_of_range)orb.combat.register_f_pre_tick(func)
Parameters
function func
Return Value
void
local orb = module.internal('orb')
local function on_tick() --this fucntion is triggered prior to the orbs tick
-- you can return true to block other callbacks
-- return true
end
orb.combat.register_f_pre_tick(on_tick)orb.combat.set_invoke_after_attack(val)
Parameters
boolean val
Return Value
void
set to false, then orb will stop triggering [register_f_after_attack] events
local orb = module.internal('orb')
local function after_attack()
print('attack is on cooldown')
orb.combat.set_invoke_after_attack(false)
-- you can return true to block other callbacks
-- return true
end
orb.combat.register_f_after_attack(after_attack)orb.farm.clear_target
Return Value
obj the orbs current lane clear target
local orb = module.internal('orb')
local function on_tick()
if orb.farm.clear_target then
print(orb.farm.clear_target.charName)
end
end
cb.add(cb.tick, on_tick)orb.farm.lane_clear_wait()
Return Value
boolean returns true if the orb is currently waiting to attack a minion that is soon to die (or waiting for siege)
local orb = module.internal('orb')
local function on_tick()
if orb.farm.lane_clear_wait() then
print('lane clear is waiting to attack a minion')
end
end
cb.add(cb.tick, on_tick)orb.farm.lane_clear_wait_target
Return Value
obj the orbs current lane clear wait target
orb.farm.predict_hp(obj, time)
Parameters
minion.obj obj
number time
Return Value
number returns the minions health after time (seconds)
local orb = module.internal('orb')
local function on_tick()
for i=0, objManager.minions.size[TEAM_ENEMY]-1 do
local obj = objManager.minions[TEAM_ENEMY][i]
if obj.isVisible then
local hp = orb.farm.predict_hp(obj, 0.25)
print(obj.charName, obj.health, hp)
end
end
end
cb.add(cb.tick, on_tick)orb.farm.set_ignore(obj, time)
Parameters
minion.obj obj
number time
Return Value
void
orb.farm.skill_farm_linear(input)
Parameters
table input
Return Value
seg returns a line segment
minion.obj returns the minion object
--based on mundo q
local orb = module.internal('orb')
local input = {
delay = 0.25,
speed = 2000,
width = 60,
boundingRadiusMod = 1,
range = 1050,
collision = {
minion=true,
walls=true,
hero=true,
},
damage = function(m)
local q_level = player:spellSlot(0).level
return math.min(250 + 50*q_level, math.max(30 + 50*q_level, m.health*(.125 + .025*q_level)))
end,
}
local function on_tick()
local seg, obj = orb.farm.skill_farm_linear(input)
if seg then
player:castSpell('pos', 0, seg.endPos)
end
end
cb.add(cb.tick, on_tick)orb.farm.skill_clear_linear(input)
Parameters
table input
Return Value
seg returns a line segment
minion.obj returns the minion object
--based on mundo q
local orb = module.internal('orb')
local input = {
delay = 0.25,
speed = 2000,
width = 60,
boundingRadiusMod = 1,
range = 1050,
collision = {
minion=true,
walls=true,
hero=true,
},
damage = function(m)
local q_level = player:spellSlot(0).level
return math.min(250 + 50*q_level, math.max(30 + 50*q_level, m.health*(.125 + .025*q_level)))
end,
}
local function on_tick()
local seg, obj = orb.farm.skill_clear_linear(input)
if seg then
player:castSpell('pos', 0, seg.endPos)
end
end
cb.add(cb.tick, on_tick)orb.farm.skill_farm_circular(input)
Parameters
table input
Return Value
seg returns a line segment
minion.obj returns the minion object
--based on karthus q
local orb = module.internal('orb')
local input = {
delay = 0.75,
speed = math.huge,
radius = 200,
boundingRadiusMod = 0,
range = 874,
damage = function(m)
return 20*player:spellSlot(0).level + 30 + .3*(player.flatMagicDamageMod*player.percentMagicDamageMod)
end,
}
local function on_tick()
local seg, obj = orb.farm.skill_farm_circular(input)
if seg then
player:castSpell('pos', 0, seg.endPos)
end
end
cb.add(cb.tick, on_tick)orb.farm.skill_clear_circular(input)
Parameters
table input
Return Value
seg returns a line segment
minion.obj returns the minion object
--based on karthus q
local orb = module.internal('orb')
local input = {
delay = 0.75,
speed = math.huge,
radius = 200,
boundingRadiusMod = 0,
range = 874,
damage = function(m)
return 20*player:spellSlot(0).level + 30 + .3*(player.flatMagicDamageMod*player.percentMagicDamageMod)
end,
}
local function on_tick()
local seg, obj = orb.farm.skill_clear_circular(input)
if seg then
player:castSpell('pos', 0, seg.endPos)
end
end
cb.add(cb.tick, on_tick)orb.farm.skill_farm_target(input)
Parameters
table input
Return Value
seg returns a line segment
minion.obj returns the minion object
--based on pantheon q (****2019 version****)
local orb = module.internal('orb')
local input = {
delay = 0.25,
speed = 1500,
range = 468,
damage = function(target)
return 35 + 40*player:spellSlot(0).level + 1.4*((player.baseAttackDamage + player.flatPhysicalDamageMod)*player.percentPhysicalDamageMod - player.baseAttackDamage)
end,
}
local function on_tick()
local seg, obj = orb.farm.skill_farm_target(input)
if obj then
player:castSpell('obj', 0, obj)
end
end
cb.add(cb.tick, on_tick)orb.farm.skill_clear_target(input)
Parameters
table input
Return Value
seg returns a line segment
minion.obj returns the minion object
--based on pantheon q
local orb = module.internal('orb')
local input = {
delay = 0.25,
speed = 1500,
range = 468,
damage = function(target)
return 35 + 40*player:spellSlot(0).level + 1.4*((player.baseAttackDamage + player.flatPhysicalDamageMod)*player.percentPhysicalDamageMod - player.baseAttackDamage)
end,
}
local function on_tick()
local seg, obj = orb.farm.skill_clear_target(input)
if obj then
player:castSpell('obj', 0, obj)
end
end
cb.add(cb.tick, on_tick)orb.farm.set_clear_target(obj)
Parameters
minion.obj obj
Return Value
void
orb.utility.get_missile_speed(obj)
Parameters
obj obj
Return Value
number returns the obj attack missile speed
orb.utility.get_wind_up_time(obj)
Parameters
obj obj
Return Value
number returns the obj attacks wind up time
orb.utility.get_damage_mod(obj)
Parameters
obj obj
Return Value
number returns the obj damage mod (wards ex)
orb.utility.get_damage(source, target, add_bonus)
Parameters
obj source
obj target
boolean add_bonus
Return Value
number returns attack damage done to target by source
orb.utility.get_hit_time(source, target)
Parameters
obj source
obj target
Return Value
number returns time in seconds for an attack from source to hit target
orb.ts
Return Value
TS returns the orbs target selector instance
orb.menu.combat.key:get()
Return Value
boolean returns true if combat mode is active
orb.menu.lane_clear.key:get()
Return Value
boolean returns true lane clear mode is active
orb.menu.last_hit.key:get()
Return Value
boolean returns true last hit mode is active
orb.menu.hybrid.key:get()
Return Value
boolean returns true if hybrid mode is active
evade
use os.clock()
evade.core.set_server_pause()
Return Value
void
this is deprecated, use evade.core.set_pause instead
evade.core.set_pause(t)
Parameters
number t
Return Value
void
pauses evade from issuing movement orders (will still update orbs path)
local evade = module.seek('evade')
if evade then
evade.core.set_pause(3) --pauses the evade from taking action for 3 seconds
endevade.core.is_paused()
Return Value
boolean returns true if evade is currently paused
evade.core.is_active()
Return Value
boolean returns true if evade is currently evading a spell
should be checked before casting any movement impairing spells
evade.core.is_action_safe(v1, speed, delay)
Parameters
vec2\vec3 v1
number speed
number delay
Return Value
boolean returns true if action is safe
--this example is based on vayne q
local evade = module.seek('evade')
local function on_tick()
if player:spellSlot(0).state~=0 then return end
local pos = player.path.serverPos2D + (mousePos2D - player.path.serverPos2D):norm()*300
if evade and evade.core.is_action_safe(pos, 500 + player.moveSpeed, 0) then
player:castSpell('pos', 0, vec3(pos.x, mousePos.y, pos.y))
end
end
cb.add(cb.tick, on_tick)evade.core.get_anchor()
Return Value
void returns the anchor for current evading direction
evade.core.get_pos()
Return Value
pos, valid = evade.core.get_pos()
pos:vec3— the target position of the current evading.valid:boolean— whetherposbelongs to the current situation.
valid tells whether pos belongs to the current situation. It is false when:
- there is nothing to dodge (no active skillshots), or the player already left the danger area — even if Evade is still finishing its evade movement (
evade.core.is_active()can still betrue); - the evade tick has not evaluated the threat yet: the first frames of a new skillshot, including the whole configured dodge delay (humanizer) window, and any state where Evade cannot act (dodging disabled, paused, right after an evading ability was used, unstoppable/stasis, dead);
- Evade found no evade target for the active threat.
For backward compatibility, when valid is false pos still holds the last known evade position (which may be stale), matching the previous API behavior. Always check valid before using pos (for example to drive a dash/blink dodge).
local pos, valid = evade.core.get_pos()
if valid then
-- pos is a safe dodge target for the current threat
endevade.core.is_dodgeable()
Return Value
dodgeable = evade.core.is_dodgeable()
dodgeable:boolean— whether the merged danger of ALL active skillshots can currently be dodged by normal movement (walking).
This is a global flag: it merges every active skillshot and asks whether a safe walking path still exists. Even when each spell is individually walk-dodgeable, their overlapping danger areas can combine into a zone that walking cannot solve — this flag reflects that combined situation. It returns true when there is nothing to dodge. It is recorded as a byproduct of the normal evade tick (no extra computation), so it costs nothing to read.
Notes:
- The data comes from Evade's own tick, so it is only refreshed while Evade is actually allowed to act. There is no fresh data while dodging is disabled or paused (including your own
evade.core.set_pause), during the configured dodge delay (humanizer) window right after a new threat appears, briefly after an evading ability was used, and while the player is unstoppable/in stasis or dead. Without fresh data the flag returnstrue(nothing for it to report) — use the per-spellspell.dodgeableflag (computed on demand) when you need an answer inside those windows, and checkevade.core.is_paused()if your script pauses Evade. - It reflects Evade's active configuration (e.g. max dodge angle), i.e. what Evade actually evaluated this tick — it stays
truewhile Evade briefly waits for an attack windup it has verified can be finished safely before walking out.
Use the per-spell spell.dodgeable flag when you need to know whether one specific spell can be walked out of (for example to decide when a mobility ability should handle that spell).
if not evade.core.is_dodgeable() then
-- Walking cannot solve the current combined threat; consider a dash/blink/flash/move-speed ability.
endevade.core.get_safe_pos()
Return Value
pos, valid, walkable = evade.core.get_safe_pos()
pos:vec3— the best safe target position for the current merged threat.valid:boolean—falsewhen there is no current threat (or no safe spot could be found).walkable:boolean— whether normal movement can reachposin time.
Unlike get_pos(), this always aims for the best safe position even when normal movement is not fast enough (for example the player is slowed or too far). When walkable is false, pos is the nearest suitable safe spot Evade found (already filtered against walls, enemy turrets and the fountain) that a dash/blink/flash/move-speed ability can reach — ideal for champion-specific mobility dodging. Like the other dodge APIs it is read from the evade tick's snapshot (no extra computation), so it only carries data while Evade is actually allowed to act. While dodging is disabled or paused, during the dodge delay (humanizer) window of a new threat, briefly after an evading ability was used, or while the player is unstoppable/in stasis or dead, valid is false.
local pos, valid, walkable = evade.core.get_safe_pos()
if valid and not walkable then
-- Walking is not enough; Evade may use a dash/blink/flash methods to reach pos.
endevade.damage
local ad_damage, ap_damage, true_damage, buff_list = evade.damage.count(player)
--these are reduced/modified by armor/buffs
--buff_list contains an array of all incoming buff typesevade.core.skillshots
Not recommended, prefer evade.core.register_on_create_spell
for i=evade.core.skillshots.n, 1, -1 do
local spell = evade.core.skillshots[i]
-- spell.name : string
-- spell.data : The static data of this skillshot
-- spell.owner : AIBaseClient
-- spell.valid : boolean
-- spell.start_time : number (os.clock() based)
-- spell.end_time : number (os.clock() based)
-- spell.start_pos : vec2
-- spell.end_pos : vec2
-- spell.direction : vec2
-- spell.perpendicular : vec2
-- spell.danger_level : number (can be set to override)
-- spell.damage : number (total damage)
-- spell.radius_sqr : number (range + extra evade distance)
-- spell.width_sqr : number (hit area width + extra area distance)
-- spell.missile : missile.obj (nil if not missile-based)
-- spell.target : base.obj (for targeted spells)
-- spell.dodgeable : boolean (dynamic, per-spell; true if the player can currently walk out of THIS spell in time; false while the spell is ignored by Evade or not threatening the player)
-- Damage Calculation
-- Returns: ad_damage, ap_damage, true_damage, buff_list
local ad_damage, ap_damage, true_damage, buff_list = spell:get_damage(player)
-- Checks if a position or object is within the spell area. Returns boolean.
if spell:contains(game.mousePos2D) then
-- Mouse position is inside the spell area
end
if spell:contains(player) then
-- Player is inside the spell area (accounts for bounding radius)
end
-- Path Intersection, checks if a line segment intersects the spell area. Returns boolean.
if spell:intersection(player.pos2D, game.mousePos2D) then
-- Line segment from player to mouse intersects the spell
end
-- Timing Methods
-- spell:get_hit_time(pos2D/obj)
local hit_time = spell:get_hit_time(player) -- Time when player will be hit
-- spell:get_hit_remaining_time(pos2D/obj)
local remaining_time = spell:get_hit_remaining_time(player) -- Remaining time until hit
-- Screen Check
if spell:is_on_screen() then
-- Spell is visible on screen
end
-- Danger Area Polygons (Evade 3.0)
-- spell:get_polygons() returns a table of polygons; each polygon is a table of vec2 world points.
-- Both the outer table and each polygon have an `n` count field.
-- Note: for ring-shaped spells the inner hole is returned as an additional polygon whose interior
-- is SAFE. Use spell:contains(pos) to classify a point instead of a naive point-in-any-polygon test.
local polygons = spell:get_polygons()
for pi = 1, polygons.n do
local poly = polygons[pi]
for vi = 1, poly.n do
local point = poly[vi] -- vec2 on the danger area outline
end
end
-- Dodgeable Flag (Evade 3.0)
-- Dynamic, per-spell boolean: true only while THIS spell threatens the player AND the player can
-- still walk out of it in time. It looks at this skillshot alone (ignores other spells) and uses the
-- current move speed (incl. boosts/slows), the spell's hit time and latency. It is computed on
-- demand (not taken from the evade tick), so it keeps working while Evade itself cannot act (dodge
-- delay, pause) and is independent of orbwalker/attack state — it reflects physical dodgeability
-- rather than what Evade would do now. It returns false while the spell is ignored by Evade
-- (menu rules, double-click ignore, targeted spells) or does not threaten the player.
if spell:contains(player) and not spell.dodgeable then
-- Cannot be escaped by walking; a champion script could still escape with a dash/blink,
-- using spell:get_polygons() to compute a safe destination.
end
endevade.core.skillshots[i].data
Static metadata object (read-only). Available on evade.core.skillshots[i].data and evade.core.targeted[i].data. This attribute is updated to Evade3 spelldata.obj
local d = spell.data
-- d.name : string
-- d.menu_name : string
-- d.slot : integer
-- d.spell_type : string
-- d.missile_names (removed)
-- d.delay : number (seconds)
-- d.length : number
-- d.radius / d.width : number
-- d.speed : number
-- d.fixed_range : boolean
-- d.is_cc : boolean
-- d.update : boolean (can change postion or not, for example the Orianna R)
-- d.applies_on_hit : boolean (is a missile)
-- d.add_bbox_length : boolean (range/length)
-- d.add_bbox_radius : boolean
-- d.add_bbox_width : boolean
-- d.collision : integer (bitmask)
-- function d:damage(source, target) -> ad, ap, true, buff_or_nilINFO
Notes:
radiusandwidthare aliases for hit width/radius.add_bbox_length/add_bbox_radius/add_bbox_widthcontrol whether target hitbox is included in distance/width calculations.collisionis a bitmask of collision types.- The 4th return of
d:damage(source, target)is the first related buff ornil; for a full buff list, usespell:get_damage.
evade.core.targeted
Not recommended, prefer evade.core.register_on_create_spell
for i=evade.core.targeted.n, 1, -1 do
local spell = evade.core.targeted[i]
--spell.name
--spell.start_time
--spell.end_time
--spell.owner
--spell.target
--spell.missile
--spell.data -- assorted static data
endevade.core.register_on_create_spell
evade.core.register_on_create_spell(function (skillshot)
if not skillshot:contains(player) then
return
end
local ad_damage,ap_damage,true_damage,buff_list = skillshot:get_damage(player) -- show damage to self
print('create skillshot: ',
skillshot.name,
skillshot.owner and skillshot.owner.charName or "nil",
"time: ",
string.format("%.2f", skillshot.start_time),
string.format("%.2f", skillshot.end_time), -- This is only an approximate time
"target: ",
skillshot.target and skillshot.target.charName or "nil",
"damage: ",
ad_damage,ap_damage,true_damage,#buff_list
)
-- example for anti ViR:
if skillshot.name == "ViR" then
delay_action(skillshot.end_time - os.clock() - 0.1, function() use_zhonya() end)
end
end)evade.damage.count
local ad_damage, ap_damage, true_damage, buff_list = evade.damage.count(player)damagelib
damagelib.handlers
Insert your own handlers if internal damagelib is not ok.
local damagelib = module.internal('damagelib')
local handlers = damagelib.handlers
local FlashFrost = game.spellhash('FlashFrost')
local TotalPassthroughDamage = game.fnvhash('TotalPassthroughDamage')
local TotalExplosionDamage = game.fnvhash('TotalExplosionDamage')
handlers[FlashFrost] = function (source, target, is_raw_damage, stage)
print('FlashFrost: lua handlers called')
local spell_slot = source:spellSlot(0)
if not spell_slot then
return damage_result(0, 0, 0)
end
local raw_damage = spell_slot:calculate(0, TotalPassthroughDamage) + spell_slot:calculate(0, TotalExplosionDamage)
if is_raw_damage or not target or not target.valid then
return damage_result(0, raw_damage, 0)
end
-- return damage: ad,ap,true
return damage_result(0, damagelib.calc_magical_damage(source, target, raw_damage), 0)
end
-- print damage
local total_damage, ad_damage, ap_damage, true_damage = damagelib.get_spell_damage('FlashFrost', 0, player, g_target, true, 0)
print(total_damage, ad_damage, ap_damage, true_damage)damagelib.get_spell_damage(spellName, spellSlot, source, target, isRawDamage, stage)
Parameters
string spellName
number spellSlot
obj source
obj target
boolean isRawDamage, true = only spell damage, false = include runes/items/buffs/armors/shieds
number stage
Return Value
number,number,number,number total,ad,ap,true
local damagelib = module.internal('damagelib')
-- Briar
print('Passive min', damagelib.get_spell_damage('BriarP', 63, player, g_target, false, 0))
print('Passive max', damagelib.get_spell_damage('BriarP', 63, player, g_target, false, 1))
print('Q', damagelib.get_spell_damage('BriarQ', 0, player, g_target, false, 0))
print('W', damagelib.get_spell_damage('BriarW', 1, player, g_target, false, 0))
print('W2', damagelib.get_spell_damage('BriarWAttackSpell', 1, player, g_target, false, 0)) -- available when W2 ready
print('E', damagelib.get_spell_damage('BriarE', 2, player, g_target, false, 0))
print('R', damagelib.get_spell_damage('BriarR', 3, player, g_target, false, 0))damagelib.calc_aa_damage(source, target, includeOnHit)
Calc the real damage after shields, etc.
Parameters
obj source
obj target
boolean include calc_on_hit_damage or not
Return Value
number
damagelib.calc_physical_damage(source, target, rawDamage)
Calc the real damage after shields, etc.
Parameters
obj source
obj target
number rawDamage
Return Value
number
damagelib.calc_magical_damage(source, target, rawDamage)
Calc the real damage after shields, etc.
Parameters
obj source
obj target
number rawDamage
Return Value
number
damagelib.calc_on_hit_damage(source, target, isAutoAttack)
Calc the extra on hit damage by passive/buffs/items/perks.
Parameters
obj source
obj target
boolean isAutoAttack
Return Value
number,number,number,number total,ad,ap,true
local total_damage,ad_damage,ap_damage,true_damage = damagelib.calc_on_hit_damage(player, target, true)TS
TS.get_result(func, filter, ign_sel, hard)
Parameters
function func
table filter[optional]
boolean ign_sel[optional]
boolean hard[optional]
Return Value
table
--this example is based on annie q
local ts = module.internal('TS')
local pred = module.internal('pred')
local input = {
delay = 0,
radius = 505,
dashRadius = 0,
boundingRadiusModSource = 1,
boundingRadiusModTarget = 1,
}
local function ts_filter(res, obj, dist)
--return false for any objects much too far away
if dist > 800 then return false end
--pred.present.get_prediction checks that obj is in range for q
if pred.present.get_prediction(input, obj) then
--res.obj is arbitrary and could be named anything
--additionally, anything you like can be added to the res table
res.obj = obj
return true
end
end
local function on_tick()
--check that q is ready
if player:spellSlot(0).state~=0 then return end
--ts.get_result loops through all valid enemies
--simple usage
local res = ts.get_result(ts_filter)
if res.obj then
player:castSpell('obj', 0, res.obj)
end
--alternative usages
local res = ts.get_result(ts_filter, ts.filter_set[2]) --uses filter LESS_CAST_AD_PRIO (overrides menu)
local res = ts.get_result(ts_filter, nil, true) --ignores ts selected target
local res = ts.get_result(ts_filter, nil, nil, true) --forces ts selected target to be returned (overrides menu)
end
cb.add(cb.tick, on_tick)TS.get_active_filter()
Return Value
table
local ts = module.internal('TS')
print(ts.get_active_filter().name)TS.loop(func, filter)
Parameters
function func
table filter[optional]
Return Value
table
local ts = module.internal('TS')
local function loop_filter(res, obj, dist)
-- any condition can be set here
if dist < 800 then
table.insert(res, obj)
end
end
local function on_tick()
local res = ts.loop(loop_filter)
--res will contain all valid enemies within 800 units
end
cb.add(cb.tick, on_tick)TS.loop_allies(func, filter)
Parameters
function func
table filter[optional]
Return Value
table
local ts = module.internal('TS')
local function loop_filter(res, obj, dist)
-- any condition can be set here
if dist < 800 then
table.insert(res, obj)
end
end
local function on_tick()
local res = ts.loop_allies(loop_filter)
--res will contain all valid allies within 800 units
end
cb.add(cb.tick, on_tick)TS.filter.new()
Return Value
table
local ts = module.internal('TS')
local my_filter = ts.filter.new()
my_filter.name = 'LEAST_MANA'
my_filter.rank = {0.33, 0.66, 1.0, 1.33, 1.66} --these correspond to character priorities set in the menu, the lower the ratio the higher priority will be given
my_filter.index = function(obj, rank_val)
return obj.par
--alternatively, this will return the target with the least mana adjusted by priority
-- return obj.par * rank_value
end
local function ts_filter(res, obj, dist)
if dist < 800 then
res.obj = obj
return true
end
end
local res = ts.get_result(ts_filter, my_filter)TS.filter_set
Return Value
table
local ts = module.internal('TS')
for Nebelwolfi=1, #ts.filter_set do
print(ts.filter_set[Nebelwolfi].name)
endTS.selected
Return Value
obj current selected obj