Appearance
Prediction
Using Prediction SDK
WARNING
Before using the SDK you need to instantiate it using sdk_init::prediction() - example provided on this page
Prediction Enums
cpp
enum hitchance: int {
automatic = -1,
any = 0,
low = 30,
medium = 50,
high = 70,
very_high = 85,
guaranteed_hit = 100,
};
enum class hit_type: uint8_t {
normal = 0,
undodgeable,
cast,
zhonyas,
cc,
cc_hard,
dash,
};
enum class spell_type: uint8_t {
linear = 0,
targetted,
circular,
vector,
};
/*
basic attack range from edge to edge
targeted skill range from center to center (mainly not always)
skillshot range from center to edge (mainly not always)
and the range of self-centered area of effects are from the center of the source (blitz R, diana R..)
*/
enum class targetting_type: uint8_t {
center = 0,
center_to_edge,
edge_to_edge,
};
enum class collision_type: uint8_t {
unit = 0,
hero,
turret,
terrain,
yasuo_wall,
braum_wall,
};enum hitchance: int {
automatic = -1,
any = 0,
low = 30,
medium = 50,
high = 70,
very_high = 85,
guaranteed_hit = 100,
};
enum class hit_type: uint8_t {
normal = 0,
undodgeable,
cast,
zhonyas,
cc,
cc_hard,
dash,
};
enum class spell_type: uint8_t {
linear = 0,
targetted,
circular,
vector,
};
/*
basic attack range from edge to edge
targeted skill range from center to center (mainly not always)
skillshot range from center to edge (mainly not always)
and the range of self-centered area of effects are from the center of the source (blitz R, diana R..)
*/
enum class targetting_type: uint8_t {
center = 0,
center_to_edge,
edge_to_edge,
};
enum class collision_type: uint8_t {
unit = 0,
hero,
turret,
terrain,
yasuo_wall,
braum_wall,
};Spell Data
INFO
This is the data that needs to be fed to most prediction functions
cpp
class spell_data {
public:
spell_type spell_type{};
targetting_type targetting_type{};
int expected_hitchance = hitchance::automatic; // the expected hitchance
game_object* source{}; // source object, if none player will be taken
math::vector3 source_position{}; // position where the skillshot originates from, if none player position will be taken
bool bypass_anti_buffering{}; // allows casting spells while other spells are being casted (allow spell buffering)
int spell_slot = -1; // will be used to check for CD if expected_hitchance is automatic, if the CD of the spell is low we can spam it more
float range{}; // max range of the spell
float radius{}; // circle is the same as linear, use * 0.5f of the TOTAL radius (so only distance from player to one side)
float cast_range{}; // the cast range of the spell for vector types: viktor E, ruble R..
float delay{}; // cast delay
float proc_delay{}; // delay until the spell hits, for example syndra Q is static 0.6
float projectile_speed = FLT_MAX; // projectile speed if any, FLT_MAX if the spell has no projectiles
float extension_override{}; // if we want to override the prediction extension
std::vector< collision_type > forbidden_collisions{}; // things we dont want to skillshot to collide with
std::vector< hit_type > expected_hit_types{}; // if we want special hit types only, fill them in here
std::function< bool( game_object* ) > additional_target_selection_checks{}; // custom function for target selection checks, example: target with specific buff(s) only
};class spell_data {
public:
spell_type spell_type{};
targetting_type targetting_type{};
int expected_hitchance = hitchance::automatic; // the expected hitchance
game_object* source{}; // source object, if none player will be taken
math::vector3 source_position{}; // position where the skillshot originates from, if none player position will be taken
bool bypass_anti_buffering{}; // allows casting spells while other spells are being casted (allow spell buffering)
int spell_slot = -1; // will be used to check for CD if expected_hitchance is automatic, if the CD of the spell is low we can spam it more
float range{}; // max range of the spell
float radius{}; // circle is the same as linear, use * 0.5f of the TOTAL radius (so only distance from player to one side)
float cast_range{}; // the cast range of the spell for vector types: viktor E, ruble R..
float delay{}; // cast delay
float proc_delay{}; // delay until the spell hits, for example syndra Q is static 0.6
float projectile_speed = FLT_MAX; // projectile speed if any, FLT_MAX if the spell has no projectiles
float extension_override{}; // if we want to override the prediction extension
std::vector< collision_type > forbidden_collisions{}; // things we dont want to skillshot to collide with
std::vector< hit_type > expected_hit_types{}; // if we want special hit types only, fill them in here
std::function< bool( game_object* ) > additional_target_selection_checks{}; // custom function for target selection checks, example: target with specific buff(s) only
};Prediction Data
INFO
This is the data returned by most prediction functions
cpp
struct collision_data
{
game_object* object{};
math::vector3 collided_position{};
};
struct collision_ret
{
bool collided{};
std::vector< collision_data > collided_units{};
};
class pred_data {
public:
bool is_valid{}; // if this is true, prediction was successful we are assured that we can use all the members
game_object* target{}; // the target prediction is aiming at
int hitchance{}; // use expected_hitchance field inside spell_data if you only want to check > hitchance
math::vector3 predicted_position{}; // predicted position of the target **use cast_position** if you want to cast a spell
math::vector3 predicted_dodge_position{}; // predicted dodge position (usually on the side of the target)
math::vector3 cast_position{}; // position to use when casting the spell (second cast if vector type)
math::vector3 first_cast_position{}; // for vector types: viktor E, ruble R..
float intersection_time{}; // time until the skillshot will hit the player
math::vector3 collision_pos{}; // the point where the spell collided
std::vector< collision_data > collided_units{}; // the forbidden_collisions that the spell collided with
pred_data() {};
pred_data( game_object* target )
{
this->target = target;
}
};struct collision_data
{
game_object* object{};
math::vector3 collided_position{};
};
struct collision_ret
{
bool collided{};
std::vector< collision_data > collided_units{};
};
class pred_data {
public:
bool is_valid{}; // if this is true, prediction was successful we are assured that we can use all the members
game_object* target{}; // the target prediction is aiming at
int hitchance{}; // use expected_hitchance field inside spell_data if you only want to check > hitchance
math::vector3 predicted_position{}; // predicted position of the target **use cast_position** if you want to cast a spell
math::vector3 predicted_dodge_position{}; // predicted dodge position (usually on the side of the target)
math::vector3 cast_position{}; // position to use when casting the spell (second cast if vector type)
math::vector3 first_cast_position{}; // for vector types: viktor E, ruble R..
float intersection_time{}; // time until the skillshot will hit the player
math::vector3 collision_pos{}; // the point where the spell collided
std::vector< collision_data > collided_units{}; // the forbidden_collisions that the spell collided with
pred_data() {};
pred_data( game_object* target )
{
this->target = target;
}
};Predicting
There are multiple functions you can use depending on your need:
Find a target and predict it
pred_sdk::pred_data sdk::prediction->predict( pred_sdk::spell_data spell_data )
Predicts a specific target
pred_sdk::pred_data sdk::prediction->predict( game_object* obj, pred_sdk::spell_data spell_data )
Finds a target and predicts it (for targetted spells only, used to account for wall collisions)
pred_sdk::pred_data sdk::prediction->targetted( pred_sdk::spell_data spell_data )
Getting the collision position
If you want to check if the spell collided during prediction you can do so using this example:
cpp
pred_sdk::spell_data q_data{};
q_data.spell_type = pred_sdk::spell_type::linear;
q_data.targetting_type = pred_sdk::targetting_type::center;
q_data.expected_hitchance = 45; // pred_sdk::hitchance::automatic is possible
q_data.spell_slot = 0;
q_data.range = 1150.f;
q_data.radius = 60.f;
q_data.delay = 0.25f;
q_data.projectile_speed = 2000.f;
q_data.forbidden_collisions =
{
pred_sdk::collision_type::unit,
pred_sdk::collision_type::hero,
pred_sdk::collision_type::yasuo_wall,
pred_sdk::collision_type::braum_wall,
};
const auto pred = sdk::prediction->predict( q_data );
if( !pred.is_valid && pred.collision_pos != math::vector3{} )
{
g_sdk->log_console( "Spell collided at %s", pred.collision_pos.to_string().c_str() );
}pred_sdk::spell_data q_data{};
q_data.spell_type = pred_sdk::spell_type::linear;
q_data.targetting_type = pred_sdk::targetting_type::center;
q_data.expected_hitchance = 45; // pred_sdk::hitchance::automatic is possible
q_data.spell_slot = 0;
q_data.range = 1150.f;
q_data.radius = 60.f;
q_data.delay = 0.25f;
q_data.projectile_speed = 2000.f;
q_data.forbidden_collisions =
{
pred_sdk::collision_type::unit,
pred_sdk::collision_type::hero,
pred_sdk::collision_type::yasuo_wall,
pred_sdk::collision_type::braum_wall,
};
const auto pred = sdk::prediction->predict( q_data );
if( !pred.is_valid && pred.collision_pos != math::vector3{} )
{
g_sdk->log_console( "Spell collided at %s", pred.collision_pos.to_string().c_str() );
}Example using Ezreal Q
cpp
pred_sdk::spell_data q_data{};
q_data.spell_type = pred_sdk::spell_type::linear;
q_data.targetting_type = pred_sdk::targetting_type::center;
q_data.expected_hitchance = 45; // pred_sdk::hitchance::automatic is possible
q_data.spell_slot = 0;
q_data.range = 1150.f;
q_data.radius = 60.f;
q_data.delay = 0.25f;
q_data.projectile_speed = 2000.f;
q_data.forbidden_collisions =
{
pred_sdk::collision_type::unit,
pred_sdk::collision_type::hero,
pred_sdk::collision_type::yasuo_wall,
pred_sdk::collision_type::braum_wall,
};
const auto pred = sdk::prediction->predict( q_data );
if ( pred.is_valid )
{
g_sdk->log_console( "Casting spell at %s | hitchance %d", pred.target->get_char_name().c_str(), pred.hitchance );
util::cast_spell( q_data.spell_slot, pred.cast_position );
}pred_sdk::spell_data q_data{};
q_data.spell_type = pred_sdk::spell_type::linear;
q_data.targetting_type = pred_sdk::targetting_type::center;
q_data.expected_hitchance = 45; // pred_sdk::hitchance::automatic is possible
q_data.spell_slot = 0;
q_data.range = 1150.f;
q_data.radius = 60.f;
q_data.delay = 0.25f;
q_data.projectile_speed = 2000.f;
q_data.forbidden_collisions =
{
pred_sdk::collision_type::unit,
pred_sdk::collision_type::hero,
pred_sdk::collision_type::yasuo_wall,
pred_sdk::collision_type::braum_wall,
};
const auto pred = sdk::prediction->predict( q_data );
if ( pred.is_valid )
{
g_sdk->log_console( "Casting spell at %s | hitchance %d", pred.target->get_char_name().c_str(), pred.hitchance );
util::cast_spell( q_data.spell_slot, pred.cast_position );
}Predicting on Path
WARNING
Only use this function if you cannot achieve what you want with the functions above
math::vector3 sdk::prediction->predict_on_path( game_object* obj, float time, bool use_server_pos = true )
INFO
The time argument takes seconds
The use_server_pos argument lets you choose between client predicted position or server position
Collision
To check whether a spell collides with any forbidden_collisions you may use the function
cpp
struct collision_data
{
game_object* object{};
math::vector3 collided_position{};
};
struct collision_ret
{
bool collided{};
std::vector< collision_data > collided_units{};
};struct collision_data
{
game_object* object{};
math::vector3 collided_position{};
};
struct collision_ret
{
bool collided{};
std::vector< collision_data > collided_units{};
};collision_ret sdk::prediction->collides( const math::vector3& end_point, pred_sdk::spell_data spell_data, const game_object* target )
INFO
This is used internally inside the predicting functions
Prediction Utilities
cpp
float sdk::prediction->util()->get_spell_range( pred_sdk::spell_data& data, game_object* target, game_object* source )
bool sdk::prediction->util()->is_in_range( pred_sdk::spell_data& data, math::vector3 cast_position, game_object* target )
float sdk::prediction->util()->get_spell_hit_time( pred_sdk::spell_data& data, math::vector3 pos, game_object* target = nullptr )
float sdk::prediction->util()->get_spell_escape_time( pred_sdk::spell_data& data, game_object* target )float sdk::prediction->util()->get_spell_range( pred_sdk::spell_data& data, game_object* target, game_object* source )
bool sdk::prediction->util()->is_in_range( pred_sdk::spell_data& data, math::vector3 cast_position, game_object* target )
float sdk::prediction->util()->get_spell_hit_time( pred_sdk::spell_data& data, math::vector3 pos, game_object* target = nullptr )
float sdk::prediction->util()->get_spell_escape_time( pred_sdk::spell_data& data, game_object* target )Example
cpp
const auto cursor_pos = g_sdk->hud_manager->get_cursor_position();
g_sdk->log_console( "Time until spells hit cursor position %.2f", sdk::prediction->util()->get_spell_hit_time( q_data, cursor_pos ) );const auto cursor_pos = g_sdk->hud_manager->get_cursor_position();
g_sdk->log_console( "Time until spells hit cursor position %.2f", sdk::prediction->util()->get_spell_hit_time( q_data, cursor_pos ) );