void c_movement::auto_strafe()
{
if (!g_interfaces->m_engine->is_connected() || !g_interfaces->m_engine->is_in_game())
return;
if (!g_ctx->m_local_pawn || !g_ctx->m_local_controller->m_pawn_is_alive())
return;
if (g_ctx->m_local_pawn->m_flags() & FL_ONGROUND)
return;
if (g_ctx->m_local_pawn->m_move_type() == 1794 || g_ctx->m_local_pawn->m_move_type() == 2313)
return;
if (!g_cfg->misc.m_auto_strafe)
return;
if (g_ctx->m_user_cmd->m_button_state.m_button_state & (1 << 16))
return;
auto movement_services = g_ctx->m_local_pawn->m_movement_services();
if (!movement_services)
return;
vec3_t vel = g_ctx->m_local_pawn->m_vec_abs_velocity();
vec3_t move = movement_services->m_last_movement_impulses();
float yaw = normalize(g_interfaces->m_csgo_input->get_view_angles().y);
static uint64_t last_pressed = 0;
static uint64_t last_buttons = 0;
const auto current_buttons = g_ctx->m_user_cmd->m_button_state.m_button_state;
auto check_button = [&](const uint64_t button) {
if (current_buttons & button && (!(last_buttons & button) ||
(button & IN_MOVELEFT && !(last_pressed & IN_MOVERIGHT)) ||
(button & IN_MOVERIGHT && !(last_pressed & IN_MOVELEFT)) ||
(button & IN_FORWARD && !(last_pressed & IN_BACK)) ||
(button & IN_BACK && !(last_pressed & IN_FORWARD)))) {
if (button & IN_MOVELEFT)
last_pressed &= ~IN_MOVERIGHT;
else if (button & IN_MOVERIGHT)
last_pressed &= ~IN_MOVELEFT;
else if (button & IN_FORWARD)
last_pressed &= ~IN_BACK;
else if (button & IN_BACK)
last_pressed &= ~IN_FORWARD;
last_pressed |= button;
}
else if (!(current_buttons & button))
last_pressed &= ~button;
};
check_button(IN_MOVELEFT);
check_button(IN_MOVERIGHT);
check_button(IN_FORWARD);
check_button(IN_BACK);
last_buttons = current_buttons;
float offset = 0.f;
if (last_pressed & IN_MOVELEFT)
offset += 90.f;
if (last_pressed & IN_MOVERIGHT)
offset -= 90.f;
if (last_pressed & IN_FORWARD)
offset *= 0.5f;
else if (last_pressed & IN_BACK)
offset = -offset * 0.5f + 180.f;
yaw += offset;
float velocity_angle = RAD2DEG * std::atan2f(vel.y, vel.x);
if (velocity_angle < 0.0f)
velocity_angle += 360.0f;
velocity_angle -= floorf(velocity_angle / 360.0f + 0.5f) * 360.0f;
float speed = vel.length_2d();
float ideal = speed > 0.f ? std::clamp(RAD2DEG * std::atan2(40.f / speed, 1.f), 0.0f, 90.0f) : 90.0f;
float correct = (100.f - 100) * 0.01f * ideal;
auto rotate_movement = [](float target_yaw) {
float rot = DEG2RAD * (g_interfaces->m_csgo_input->get_view_angles().y - target_yaw);
float new_forward = std::cos(rot) * g_ctx->m_user_cmd->pb.mutable_base()->forwardmove() -
std::sin(rot) * g_ctx->m_user_cmd->pb.mutable_base()->leftmove();
float new_side = std::sin(rot) * g_ctx->m_user_cmd->pb.mutable_base()->forwardmove() +
std::cos(rot) * g_ctx->m_user_cmd->pb.mutable_base()->leftmove();
g_ctx->m_user_cmd->m_button_state.m_button_state &= ~(IN_BACK | IN_FORWARD | IN_MOVELEFT | IN_MOVERIGHT);
g_ctx->m_user_cmd->m_button_state.m_button_state2 &= ~(IN_BACK | IN_FORWARD | IN_MOVELEFT | IN_MOVERIGHT);
g_ctx->m_user_cmd->pb.mutable_base()->set_forwardmove(std::clamp(new_forward, -1.f, 1.f));
g_ctx->m_user_cmd->pb.mutable_base()->set_leftmove(std::clamp(new_side * -1.f, -1.f, 1.f));
if (g_ctx->m_user_cmd->pb.mutable_base()->forwardmove() > 0.0f)
g_ctx->m_user_cmd->m_button_state.m_button_state |= IN_FORWARD;
else if (g_ctx->m_user_cmd->pb.mutable_base()->forwardmove() < 0.0f)
g_ctx->m_user_cmd->m_button_state.m_button_state |= IN_BACK;
if (g_ctx->m_user_cmd->pb.mutable_base()->leftmove() > 0.0f)
g_ctx->m_user_cmd->m_button_state.m_button_state |= IN_MOVELEFT;
else if (g_ctx->m_user_cmd->pb.mutable_base()->leftmove() < 0.0f)
g_ctx->m_user_cmd->m_button_state.m_button_state |= IN_MOVERIGHT;
};
float velocity_delta = normalize(yaw - velocity_angle);
if (fabsf(velocity_delta) > 90.f)
velocity_delta = std::copysignf(90.f, velocity_delta);
g_ctx->m_user_cmd->pb.mutable_base()->set_forwardmove(0.f);
g_ctx->m_user_cmd->pb.mutable_base()->set_leftmove(0.f);
if (speed <= 80.f) {
yaw += ideal * 3.0f;
g_ctx->m_user_cmd->pb.mutable_base()->set_leftmove(1.0f);
}
else if (velocity_delta > correct) {
yaw = velocity_angle + correct * 4.0f;
g_ctx->m_user_cmd->pb.mutable_base()->set_leftmove(-1.0f);
}
else if (velocity_delta < -correct) {
yaw = velocity_angle - correct * 4.0f;
g_ctx->m_user_cmd->pb.mutable_base()->set_leftmove(1.0f);
}
else {
yaw += ideal * 4.0f;
g_ctx->m_user_cmd->pb.mutable_base()->set_leftmove(1.0f);
}
rotate_movement(normalize(yaw));
}