bool IdealFreestand(SDK::CBaseEntity* entity, float &yaw, int damage_tolerance) /// perfect resolving if is not urine
{
if (!(entity->GetFlags() & FL_ONGROUND))
return false;
auto local_player = INTERFACES::ClientEntityList->GetClientEntity(INTERFACES::Engine->GetLocalPlayer());
if (!local_player || local_player->GetLifeState() != 0)
return false;
std::vector<SDK::CBaseEntity*> enemies;
const float height = 64;
float leftdamage = 0.f, rightdamage = 0.f, backdamage = 0.f;
std::vector<Vector> last_eye_positions;
last_eye_positions.insert(last_eye_positions.begin(), local_player->GetVecOrigin() + local_player->GetViewOffset());
if (last_eye_positions.size() > 128)
last_eye_positions.pop_back();
auto nci = INTERFACES::Engine->GetNetChannelInfo();
if (!nci)
return false;
const int latency_ticks = TIME_TO_TICKS(nci->GetLatency(FLOW_OUTGOING));
const auto latency_based_eye_pos = last_eye_positions.size() <= latency_ticks ? last_eye_positions.back() : last_eye_positions[latency_ticks];
Vector direction_1, direction_2, direction_3;
MATH::AngleVectors(Vector(0.f, MATH::CalcAngle(local_player->GetVecOrigin(), entity->GetVecOrigin()).y - 90.f, 0.f), &direction_1);
MATH::AngleVectors(Vector(0.f, MATH::CalcAngle(local_player->GetVecOrigin(), entity->GetVecOrigin()).y + 90.f, 0.f), &direction_2);
MATH::AngleVectors(Vector(0.f, MATH::CalcAngle(local_player->GetVecOrigin(), entity->GetVecOrigin()).y + 180.f, 0.f), &direction_3);
const auto left_eye_pos = entity->GetVecOrigin() + Vector(0, 0, height) + (direction_1 * 16.f);
const auto right_eye_pos = entity->GetVecOrigin() + Vector(0, 0, height) + (direction_2 * 16.f);
const auto back_eye_pos = entity->GetVecOrigin() + Vector(0, 0, height) + (direction_3 * 16.f);
leftdamage = autowall->CalculateDamage(latency_based_eye_pos,
left_eye_pos, local_player, entity).damage;
rightdamage = autowall->CalculateDamage(latency_based_eye_pos,
right_eye_pos, local_player, entity).damage;
backdamage = autowall->CalculateDamage(latency_based_eye_pos,
back_eye_pos, local_player, entity).damage;
int right_damage = rightdamage;
int left_damage = leftdamage;
int back_damage = backdamage;
float at_target_yaw = MATH::CalcAngle(entity->GetVecOrigin(), local_player->GetVecOrigin()).y;
const float right_yaw = at_target_yaw - 90.f;
const float left_yaw = at_target_yaw + 90.f;
auto head_position = entity->GetVecOrigin() + Vector(0, 0, 74.f);
float calculated_yaw;
/// Find the lowest fov enemy
SDK::CBaseEntity* closest_enemy = nullptr;
float lowest_fov = 360.f;
for (int i = 0; i <= 64; i++)
{
auto ent = INTERFACES::ClientEntityList->GetClientEntity(i);
if (!ent || ent->GetIsDormant() || ent->GetTeam() == entity->GetTeam() || ent->GetHealth() <= 0 || !ent->IsAlive())
continue;
const float current_fov = fabs(MATH::NormalizeYaw(MATH::CalcAngle(entity->GetVecOrigin(), ent->GetVecOrigin()).y - at_target_yaw));
if (current_fov < lowest_fov)
{
lowest_fov = current_fov;
closest_enemy = ent;
}
enemies.push_back(ent);
}
if (closest_enemy == nullptr)
return false;
auto RotateAndExtendPosition = [](Vector position, float yaw, float distance) -> Vector
{
Vector direction;
MATH::AngleVectors(Vector(0, yaw, 0), &direction);
return position + (direction * distance);
};
auto right_head_position = RotateAndExtendPosition(head_position, right_yaw, 17.f);
auto left_head_position = RotateAndExtendPosition(head_position, left_yaw, 17.f);
auto CalcDamage = [entity, enemies](Vector point) -> int
{
int damage = 0;
for (auto& enemy : enemies)
{
damage += UTILS::Max<int>(autowall->CalculateDamage(enemy->GetVecOrigin() + Vector(0, 0, 64.f), point, enemy, entity).damage,
autowall->CalculateDamage(enemy->GetVecOrigin() + Vector(0, 0, 49.f), point, enemy, entity).damage);
}
return damage;
};
auto RotateLBYAndYaw = [right_yaw, left_yaw, entity](int right_damage, int left_damage, float& yaw, bool prefect_angle = false) -> bool
{
bool prefer_right = right_damage < left_damage;
yaw = prefer_right ? right_yaw : left_yaw;
/// If not moving
if (prefect_angle)
yaw = UTILS::GetLBYRotatedYaw(entity->GetLowerBodyYaw(), yaw);
return true;
};
if (left_damage >= damage_tolerance && right_damage >= damage_tolerance && back_damage >= damage_tolerance)
return false;
if (left_damage >= damage_tolerance && right_damage >= damage_tolerance && back_damage < damage_tolerance)
calculated_yaw = at_target_yaw + 180.f;
else if (right_damage == left_damage)
{
if (MATH::NormalizePitch(MATH::CalcAngle(entity->GetVecOrigin(), local_player->GetVecOrigin()).x) > 15.f && back_damage < damage_tolerance)
calculated_yaw = at_target_yaw + 180.f;
else
{
right_head_position = RotateAndExtendPosition(head_position, right_yaw, 50.f);
left_head_position = RotateAndExtendPosition(head_position, left_yaw, 50.f);
right_damage = CalcDamage(right_head_position), left_damage = CalcDamage(left_head_position);
if (right_damage == left_damage)
{
/// just return the side closest to a wall
right_head_position = UTILS::TraceToEnd(head_position, RotateAndExtendPosition(head_position, right_yaw, 17.f));
left_head_position = UTILS::TraceToEnd(head_position, RotateAndExtendPosition(head_position, left_yaw, 17.f));
float distance_1, distance_2;
SDK::trace_t trace;
SDK::Ray_t ray;
SDK::CTraceWorldOnly filter;
auto end_pos = local_player->GetVecOrigin() + Vector(0, 0, 64.f);
/// right position
ray.Init(right_head_position, end_pos);
INTERFACES::Trace->TraceRay(ray, MASK_ALL, &filter, &trace);
distance_1 = (right_head_position - trace.end).Length();
/// left position
ray.Init(left_head_position, end_pos);
INTERFACES::Trace->TraceRay(ray, MASK_ALL, &filter, &trace);
distance_2 = (left_head_position - trace.end).Length();
if (fabs(distance_1 - distance_2) > 15.f)
RotateLBYAndYaw(distance_1, distance_2, calculated_yaw);
else
calculated_yaw = at_target_yaw + 180;
}
else
RotateLBYAndYaw(right_damage, left_damage, calculated_yaw);
}
}
else
{
if (MATH::NormalizePitch(MATH::CalcAngle(entity->GetVecOrigin(), local_player->GetVecOrigin()).x) > 15.f && back_damage < damage_tolerance)
calculated_yaw = at_target_yaw + 180.f;
else
{
bool prefer_right = (right_damage < left_damage);
calculated_yaw = prefer_right ? right_yaw : left_yaw;
}
}
yaw = calculated_yaw;
return true;
}
void CResolver::resolve(SDK::CBaseEntity* entity)
{
auto local_player = INTERFACES::ClientEntityList->GetClientEntity(INTERFACES::Engine->GetLocalPlayer());
shots_missed[entity->GetIndex()] = shots_fired[entity->GetIndex()] - shots_hit[entity->GetIndex()];
int i = entity->GetIndex();
static float oldlby[65], predict[65], lastmovelby[65], laststandlby[65];
// pitch fix
entity->GetEyeAnglesPointer()->x = MATH::NormalizePitch(entity->GetEyeAnglesPointer()->x);
if (entity->GetVelocity().Length2D() > 15 && !IsFakeWalking(entity) && entity->GetFlags() & FL_ONGROUND)
{
entity->GetEyeAnglesPointer()->y = entity->GetLowerBodyYaw();
lastmovelby[i] = entity->GetLowerBodyYaw();
predict[i] = entity->GetSimTime() + 0.22;
SETTINGS::settings.resolvermode = "Moving LBY";
}
else
{
laststandlby[i] = entity->GetLowerBodyYaw();
for (int j = 0; j < 15; j++)
{
const int activity = entity->GetSequenceActivity(entity->GetAnimOverlay(j).m_nSequence);
if (activity == 979 && entity->GetAnimOverlay(3).m_flWeight == 0)
{
entity->GetEyeAnglesPointer()->y = entity->GetLowerBodyYaw();
predict[i] = entity->GetSimTime() + INTERFACES::Globals->interval_per_tick + 1.1;
SETTINGS::settings.resolvermode = "LBY Backtrack";
}
else if (activity == 973)
{
entity->GetEyeAnglesPointer()->y = entity->GetLowerBodyYaw();
predict[i] = entity->GetSimTime() + INTERFACES::Globals->interval_per_tick + 1.1;
SETTINGS::settings.resolvermode = "LBY Change";
}
else if (entity->GetSimTime() >= predict[i])
{
entity->GetEyeAnglesPointer()->y = entity->GetLowerBodyYaw();
predict[i] = entity->GetSimTime() + INTERFACES::Globals->interval_per_tick + 1.1;
SETTINGS::settings.resolvermode = "LBY Prediction";
}
else if (activity == 980 && entity->GetAnimOverlay(3).m_flWeight == 0)
{
entity->GetEyeAnglesPointer()->y = entity->GetLowerBodyYaw();
SETTINGS::settings.resolvermode = "LBY 980";
}
else if (activity == 980 && entity->GetAnimOverlay(3).m_flWeight == 1)
{
entity->GetEyeAnglesPointer()->y = laststandlby[i];
SETTINGS::settings.resolvermode = "LastStand LBY";
}
else if (IdealFreestand(entity, entity->GetEyeAnglesPointer()->y, 10))
{
SETTINGS::settings.resolvermode = "Anti Freestand";
}
else
{
entity->GetEyeAnglesPointer()->y = lastmovelby[i];
SETTINGS::settings.resolvermode = "LastMove LBY";
}
}
}
}