Начинающий
- Статус
- Оффлайн
- Регистрация
- 15 Окт 2019
- Сообщения
- 47
- Реакции
- 8
C++:
// call in void Aimbot::think()
// cache random values cuz valve random system cause performance issues
if (!m_bInitialisedRandomSpread) {
for (auto i = 0; i <= 255; i++) {
g_csgo.RandomSeed(i + 1);
m_uRandomSpread[i].flRand1 = g_csgo.RandomFloat(0.0f, 1.0f);
m_uRandomSpread[i].flRandPi1 = g_csgo.RandomFloat(0.0f, DirectX::XM_2PI);
m_uRandomSpread[i].flRand2 = g_csgo.RandomFloat(0.0f, 1.0f);
m_uRandomSpread[i].flRandPi2 = g_csgo.RandomFloat(0.0f, DirectX::XM_2PI);
}
m_bInitialisedRandomSpread = true;
}
if (!m_bInitialisedRandomSpread) {
return;
}
// Returns a vector of hitbox indices to scan for the given player and record.
std::vector<int> GetDynamicHitboxes(Player* player, LagRecord* record) {
std::vector<int> hitboxes;
// Example: Always scan head and body.
hitboxes.push_back(HITBOX_HEAD);
hitboxes.push_back(HITBOX_BODY);
// Example: If player is low HP, prefer body.
if (player->m_iHealth() <= 20)
hitboxes.push_back(HITBOX_PELVIS);
// Example: If airborne, prefer body.
if (record && !(record->m_pred_flags & FL_ONGROUND))
hitboxes.push_back(HITBOX_CHEST);
// Example: If using Zeus, only scan body.
if (g_cl.m_weapon_id == ZEUS) {
hitboxes.clear();
hitboxes.push_back(HITBOX_BODY);
return hitboxes;
}
// Add more conditions as needed...
return hitboxes;
}
bool Aimbot::CheckHitchance(Player* player, const ang_t& angle) {
// Get hitchance value from menu.
float flChance = g_menu.main.aimbot.hitchance_amount.get();
if (flChance <= 0.0f)
return true;
std::vector<int> hitboxes = GetDynamicHitboxes(player, m_record);
for (int hitboxIdx : hitboxes) {
// Get model and hitbox data.
const model_t* model = player->GetModel();
if (!model)
continue;
studiohdr_t* hdr = g_csgo.m_model_info->GetStudioModel(model);
if (!hdr)
continue;
mstudiohitboxset_t* set = hdr->GetHitboxSet(player->m_nHitboxSet());
if (!set)
continue;
mstudiobbox_t* bbox = set->GetHitbox(hitboxIdx);
if (!bbox)
continue;
matrix3x4_t* matrix = m_record->m_matrix;
if (!matrix)
continue;
// calculate hitbox world positions.
vec3_t vecMin, vecMax;
math::VectorTransform(bbox->m_mins, matrix[bbox->m_bone], vecMin);
math::VectorTransform(bbox->m_maxs, matrix[bbox->m_bone], vecMax);
// setup forward, right, up vectors.
vec3_t forward, right, up;
math::AngleVectors(angle, &forward, &right, &up);
// eye position.
vec3_t start = g_cl.m_shoot_pos;
// weapon range.
float range = g_cl.m_weapon_info->m_range;
// capsule or box.
bool isCapsule = bbox->m_radius > 0.f;
// simulation.
constexpr int maxTraces = 128;
int hits = 0;
for (int i = 0; i < maxTraces; ++i) {
// use cached random spread.
float flRand1 = m_uRandomSpread[i].flRand1;
float flRandPi1 = m_uRandomSpread[i].flRandPi1;
float flRand2 = m_uRandomSpread[i].flRand2;
float flRandPi2 = m_uRandomSpread[i].flRandPi2;
float recoilIdx = g_cl.m_weapon->m_flRecoilIndex();
int weaponId = g_cl.m_weapon_id;
// weapon-specific spread adjustments.
if (weaponId == REVOLVER) {
flRand1 = 1.0f - flRand1 * flRand1;
flRand2 = 1.0f - flRand2 * flRand2;
}
else if (weaponId == NEGEV && recoilIdx < 3.f) {
for (int x = 3; x > recoilIdx; --x) {
flRand1 *= flRand1;
flRand2 *= flRand2;
}
flRand1 = 1.f - flRand1;
flRand2 = 1.f - flRand2;
}
float inaccuracy = g_cl.m_weapon->GetInaccuracy();
float spread = g_cl.m_weapon->GetSpread();
float flRandInaccuracy = flRand1 * inaccuracy;
float flRandSpread = flRand2 * spread;
float flRandPi1Cos, flRandPi1Sin;
float flRandPi2Cos, flRandPi2Sin;
// use DirectX::XMScalarSinCos for both sine and cosine at once.
DirectX::XMScalarSinCos(&flRandPi1Sin, &flRandPi1Cos, flRandPi1);
DirectX::XMScalarSinCos(&flRandPi2Sin, &flRandPi2Cos, flRandPi2);
float spread_x = flRandPi1Cos * flRandInaccuracy + flRandPi2Cos * flRandSpread;
float spread_y = flRandPi1Sin * flRandInaccuracy + flRandPi2Sin * flRandSpread;
// build direction.
vec3_t direction = (forward + right * spread_x + up * spread_y).normalized();
vec3_t end = start + direction * range;
// geometric intersection.
bool bHit = false;
if (isCapsule) {
// capsule intersection.
bHit = math::IntersectSegmentToSegment(start, end, vecMin, vecMax, bbox->m_radius);
}
else {
// build direction.
vec3_t direction = (end - start).normalized();
// box intersection.
bHit = math::IntersectionBoundingBox(start, bbox, direction, matrix[bbox->m_bone]);
}
if (bHit)
++hits;
// early out if we can't reach hitchance anymore.
if (static_cast<float>(hits + maxTraces - i) / static_cast<float>(maxTraces) < (flChance / 100.f))
break;
}
float hc = hits ? static_cast<float>(hits) / static_cast<float>(maxTraces) : 0.f;
if (hc >= (flChance / 100.f))
return true; // if any hitbox passes, return true.
}
return false; // none of the hitboxes passed hitchance.
}
Последнее редактирование: