-
Автор темы
- #1
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
C++:
__forceinline Vector_t CalculateSpread(C_CSWeaponBase* weapon, int seed, float inaccuracy, float spread, bool revolver2 = false) {
const char* item_def_index;
float recoil_index, r1, r2, r3, r4, s1, c1, s2, c2;
if (!weapon)
return { };
// if we have no bullets, we have no spread.
auto wep_info = weapon->datawep();
if (!wep_info)
return { };
if (F::RAGE::rage->m_computed_seeds.empty())
return {};
// get some data for later.
item_def_index = wep_info->m_szName();
recoil_index = weapon->m_flRecoilIndex();
// generate needed floats.
r1 = std::get<0>(F::RAGE::rage->m_computed_seeds[seed]);
r2 = std::get<1>(F::RAGE::rage->m_computed_seeds[seed]);
r3 = std::get<0>(F::RAGE::rage->m_computed_seeds[seed]);
r4 = std::get<1>(F::RAGE::rage->m_computed_seeds[seed]);
// revolver secondary spread.
if (item_def_index == CS_XOR("weapon_revoler") && revolver2) {
r1 = 1.f - (r1 * r1);
r3 = 1.f - (r3 * r3);
}
// negev spread.
else if (item_def_index == CS_XOR("weapon_negev") && recoil_index < 3.f) {
for (int i{ 3 }; i > recoil_index; --i) {
r1 *= r1;
r3 *= r3;
}
r1 = 1.f - r1;
r3 = 1.f - r3;
}
// get needed sine / cosine values.
c1 = std::cos(r2);
c2 = std::cos(r4);
s1 = std::sin(r2);
s2 = std::sin(r4);
// calculate spread vector.
return {
(c1 * (r1 * inaccuracy)) + (c2 * (r3 * spread)),
(s1 * (r1 * inaccuracy)) + (s2 * (r3 * spread)),
0.f
};
}
bool F::RAGE::impl::CanHit(Vector_t start, Vector_t end, C_CSPlayerPawn* pLocal, C_CSPlayerPawn* record, int box)
{
if (!pLocal)
return false;
if (!record)
return false;
return false;
}
bool F::RAGE::impl::Hitchance(C_CSPlayerPawn* pLocal, C_CSPlayerPawn* ent, C_CSWeaponBase* weapon, QAngle_t vAimpoint, int iChance)
{
if (!pLocal)
return false;
if (!weapon)
return false;
auto data = weapon->datawep();
if (!data)
return false;
float HITCHANCE_MAX = 100.f;
constexpr int SEED_MAX = 255;
Vector_t start{ pLocal->GetEyePosition() }, end, fwd, right, up, dir, wep_spread;
float inaccuracy, spread;
float hitchance = rage_data.rage_hitchance;
if (hitchance <= 0)
return true;
size_t total_hits{ }, needed_hits{ (size_t)std::ceil((hitchance * SEED_MAX) / HITCHANCE_MAX) };
// get needed directional vectors.
MATH::anglevectors(vAimpoint, &fwd, &right, &up);
// store off inaccuracy / spread ( these functions are quite intensive and we only need them once ).
inaccuracy = this->GetInaccuracy(pLocal, weapon);
spread = this->GetSpread(weapon);
// iterate all possible seeds.
for (int i{ }; i <= SEED_MAX; ++i) {
// get spread.
wep_spread = CalculateSpread(weapon, i, inaccuracy, spread);
// get spread direction.
dir = (fwd + (right * wep_spread.x) + (up * wep_spread.y)).normalized();
// get end of trace.
end = start - (dir * data->m_flRange());
trace_filter_t filter = {};
I::Trace->Init(filter, pLocal, MASK_SHOT, 3, 7);
game_trace_t trace = {};
ray_t ray = {};
I::Trace->TraceShape(ray, &start, &end, filter, trace);
I::Trace->ClipTraceToPlayers(start, end, &filter, &trace, 0.F, 60.F, (1.F / (start - end).Length()) * (trace.m_end_pos - start).Length());
if (trace.HitEntity && trace.HitEntity->GetRefEHandle().GetEntryIndex() == ent->GetRefEHandle().GetEntryIndex())
++total_hits;
// we made it.
if (total_hits >= needed_hits)
return true;
// we cant make it anymore.
if ((SEED_MAX - i + total_hits) < needed_hits)
return false;
}
return false;
}