void Movement::Strafe() {
vec3_t velocity;
float delta, abs_delta, velocity_angle, velocity_delta, correct;
if (g_cl.m_local->m_MoveType() == MOVETYPE_NOCLIP || g_cl.m_local->m_MoveType() == MOVETYPE_LADDER)
return;
if ((g_cl.m_buttons & IN_SPEED) || !(g_cl.m_buttons & IN_JUMP) || (g_cl.m_flags & FL_ONGROUND))
return;
if (g_input.GetKeyState(g_menu.main.movement.fakewalk.get()) || !g_cl.m_pressing_move) {
FullStop();
return;
}
velocity = g_cl.m_local->m_vecVelocity();
m_speed = velocity.length_2d();
m_ideal = (m_speed > 0.f) ? math::rad_to_deg(std::asin(15.f / m_speed)) : 90.f;
m_ideal2 = (m_speed > 0.f) ? math::rad_to_deg(std::asin(30.f / m_speed)) : 90.f;
math::clamp(m_ideal, 0.f, 90.f);
math::clamp(m_ideal2, 0.f, 90.f);
m_mins = g_cl.m_local->m_vecMins();
m_maxs = g_cl.m_local->m_vecMaxs();
m_origin = g_cl.m_local->m_vecOrigin();
m_switch_value *= -1.f;
++m_strafe_index;
if (g_menu.main.movement.autostrafe.get() == 2 && g_cl.m_pressing_move) {
enum EDirections {
FORWARDS = 0,
BACKWARDS = 180,
LEFT = 90,
RIGHT = -90,
BACK_LEFT = 135,
BACK_RIGHT = -135,
FORWARD_LEFT = 45,
FORWARD_RIGHT = -45
};
float wish_dir{ };
bool holding_w = g_cl.m_buttons & IN_FORWARD;
bool holding_a = g_cl.m_buttons & IN_MOVELEFT;
bool holding_s = g_cl.m_buttons & IN_BACK;
bool holding_d = g_cl.m_buttons & IN_MOVERIGHT;
if (holding_w) {
if (holding_a) {
wish_dir += EDirections::FORWARD_LEFT;
}
else if (holding_d) {
wish_dir += EDirections::FORWARD_RIGHT;
}
else {
wish_dir += EDirections::FORWARDS;
}
}
else
if (holding_s) {
if (holding_a) {
wish_dir += EDirections::BACK_LEFT;
}
else if (holding_d) {
wish_dir += EDirections::BACK_RIGHT;
}
else {
wish_dir += EDirections::BACKWARDS;
}
g_cl.m_cmd->m_forward_move = 0.f;
}
else if (holding_a) {
wish_dir += EDirections::LEFT;
}
else if (holding_d) {
wish_dir += EDirections::RIGHT;
}
g_cl.m_strafe_angles.y += math::NormalizedAngle(wish_dir);
}
g_cl.m_cmd->m_forward_move = 0.f;
if (g_input.GetKeyState(g_menu.main.movement.astrafe.get())) {
float angle = std::max(m_ideal2, 4.f);
if (angle > m_ideal2 && !(m_strafe_index % 5))
angle = m_ideal2;
m_circle_yaw = math::NormalizedAngle(m_circle_yaw + angle);
g_cl.m_strafe_angles.y = m_circle_yaw;
g_cl.m_cmd->m_side_move = -450.f;
return;
}
else if (g_input.GetKeyState(g_menu.main.movement.cstrafe.get())) {
if (!g_menu.main.movement.airduck.get()) {
g_cl.m_cmd->m_buttons |= IN_DUCK;
}
DoPrespeed();
return;
}
else if (g_input.GetKeyState(g_menu.main.movement.zstrafe.get())) {
float freq = (g_menu.main.movement.z_freq.get() * 0.2f) * g_csgo.m_globals->m_realtime;
float factor = g_menu.main.movement.z_dist.get() * 0.5f;
g_cl.m_strafe_angles.y += (factor * std::sin(freq));
}
if (g_menu.main.movement.autostrafe.get() < 1)
return;
delta = math::NormalizedAngle(g_cl.m_strafe_angles.y - m_old_yaw);
abs_delta = std::abs(delta);
m_circle_yaw = m_old_yaw = g_cl.m_strafe_angles.y;
if (delta > 0.f)
g_cl.m_cmd->m_side_move = -450.f;
else if (delta < 0.f)
g_cl.m_cmd->m_side_move = 450.f;
if (abs_delta <= m_ideal || abs_delta >= 30.f) {
velocity_angle = math::rad_to_deg(std::atan2(velocity.y, velocity.x));
velocity_delta = math::NormalizedAngle(g_cl.m_strafe_angles.y - velocity_angle);
correct = m_ideal2 * 2.f;
if (velocity_delta <= correct || m_speed <= 15.f) {
if (-correct <= velocity_delta || m_speed <= 15.f) {
g_cl.m_strafe_angles.y += (m_ideal * m_switch_value);
g_cl.m_cmd->m_side_move = 450.f * m_switch_value;
}
else {
g_cl.m_strafe_angles.y = velocity_angle - correct;
g_cl.m_cmd->m_side_move = 450.f;
}
}
else {
g_cl.m_strafe_angles.y = velocity_angle + correct;
g_cl.m_cmd->m_side_move = -450.f;
}
}
}