Add deterministic seed trigger (real random_seed spread simulation)
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
#include "CMisc.hpp"
|
#include "CMisc.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
|
||||||
@@ -30,6 +32,298 @@
|
|||||||
|
|
||||||
#include <ImGui/imgui.h>
|
#include <ImGui/imgui.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// Deterministic Valve RNG (matches the game's math::random_seed generator).
|
||||||
|
class CValveRng
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
auto Seed( int s ) -> void
|
||||||
|
{
|
||||||
|
m_State = -std::abs( s );
|
||||||
|
m_Index = 0;
|
||||||
|
m_bSeeded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Generate() -> int
|
||||||
|
{
|
||||||
|
if ( !m_bSeeded )
|
||||||
|
{
|
||||||
|
auto v = -m_State;
|
||||||
|
|
||||||
|
if ( v < 1 )
|
||||||
|
v = 1;
|
||||||
|
|
||||||
|
for ( int j = 39; j >= 0; --j )
|
||||||
|
{
|
||||||
|
v = LCG( v );
|
||||||
|
|
||||||
|
if ( j < 32 )
|
||||||
|
m_Table[ j ] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_State = v;
|
||||||
|
m_Index = m_Table[ 0 ];
|
||||||
|
m_bSeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_State = LCG( m_State );
|
||||||
|
|
||||||
|
const auto Index = m_Index / 0x4000000;
|
||||||
|
m_Index = m_Table[ Index ];
|
||||||
|
m_Table[ Index ] = m_State;
|
||||||
|
|
||||||
|
return m_Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto RandomFloat( float Min = 0.f , float Max = 1.f ) -> float
|
||||||
|
{
|
||||||
|
const auto Raw = Generate();
|
||||||
|
const auto Norm = std::fminf( 0.99999988f , static_cast<float>( Raw ) * 4.6566129e-10f );
|
||||||
|
|
||||||
|
return Min + Norm * ( Max - Min );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static auto LCG( int State ) -> int
|
||||||
|
{
|
||||||
|
const auto k = State / 127773;
|
||||||
|
auto Result = 16807 * ( State - k * 127773 ) - 2836 * k;
|
||||||
|
|
||||||
|
if ( Result < 0 )
|
||||||
|
Result += 2147483647;
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int m_State = 0;
|
||||||
|
int m_Index = 0;
|
||||||
|
int m_Table[ 32 ]{};
|
||||||
|
bool m_bSeeded = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Minimal SHA-1 (for computing the spread seed from angles + tick).
|
||||||
|
class CSha1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
auto Reset() -> void
|
||||||
|
{
|
||||||
|
m_State[ 0 ] = 0x67452301;
|
||||||
|
m_State[ 1 ] = 0xEFCDAB89;
|
||||||
|
m_State[ 2 ] = 0x98BADCFE;
|
||||||
|
m_State[ 3 ] = 0x10325476;
|
||||||
|
m_State[ 4 ] = 0xC3D2E1F0;
|
||||||
|
m_Count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Update( const void* pData , std::size_t Len ) -> void
|
||||||
|
{
|
||||||
|
const auto* pBytes = static_cast<const uint8_t*>( pData );
|
||||||
|
auto Index = static_cast<std::size_t>( m_Count & 63 );
|
||||||
|
m_Count += Len;
|
||||||
|
|
||||||
|
std::size_t i = 0;
|
||||||
|
|
||||||
|
if ( Index )
|
||||||
|
{
|
||||||
|
auto PartLen = 64 - Index;
|
||||||
|
|
||||||
|
if ( Len >= PartLen )
|
||||||
|
{
|
||||||
|
std::memcpy( m_Buffer + Index , pBytes , PartLen );
|
||||||
|
Transform( m_Buffer );
|
||||||
|
i = PartLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::memcpy( m_Buffer + Index , pBytes , Len );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ; i + 64 <= Len; i += 64 )
|
||||||
|
Transform( pBytes + i );
|
||||||
|
|
||||||
|
if ( i < Len )
|
||||||
|
std::memcpy( m_Buffer , pBytes + i , Len - i );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Final() -> void
|
||||||
|
{
|
||||||
|
uint8_t Padding[ 64 ]{};
|
||||||
|
Padding[ 0 ] = 0x80;
|
||||||
|
|
||||||
|
const auto Index = static_cast<std::size_t>( m_Count & 63 );
|
||||||
|
const auto PadLen = ( Index < 56 ) ? ( 56 - Index ) : ( 120 - Index );
|
||||||
|
const auto BitCount = m_Count * 8;
|
||||||
|
|
||||||
|
Update( Padding , PadLen );
|
||||||
|
|
||||||
|
uint8_t Bits[ 8 ]{};
|
||||||
|
|
||||||
|
for ( int i = 0; i < 8; ++i )
|
||||||
|
Bits[ 7 - i ] = static_cast<uint8_t>( BitCount >> ( i * 8 ) );
|
||||||
|
|
||||||
|
Update( Bits , 8 );
|
||||||
|
|
||||||
|
for ( int i = 0; i < 5; ++i )
|
||||||
|
{
|
||||||
|
m_Digest[ i * 4 + 0 ] = static_cast<uint8_t>( m_State[ i ] >> 24 );
|
||||||
|
m_Digest[ i * 4 + 1 ] = static_cast<uint8_t>( m_State[ i ] >> 16 );
|
||||||
|
m_Digest[ i * 4 + 2 ] = static_cast<uint8_t>( m_State[ i ] >> 8 );
|
||||||
|
m_Digest[ i * 4 + 3 ] = static_cast<uint8_t>( m_State[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto GetFirstUInt32() const -> uint32_t
|
||||||
|
{
|
||||||
|
uint32_t Result;
|
||||||
|
std::memcpy( &Result , m_Digest , sizeof Result );
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static auto RotL( uint32_t v , int n ) -> uint32_t
|
||||||
|
{
|
||||||
|
return ( v << n ) | ( v >> ( 32 - n ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Transform( const uint8_t* pBlock ) -> void
|
||||||
|
{
|
||||||
|
uint32_t w[ 80 ]{};
|
||||||
|
|
||||||
|
for ( int i = 0; i < 16; ++i )
|
||||||
|
w[ i ] = static_cast<uint32_t>( pBlock[ i * 4 ] ) << 24 | static_cast<uint32_t>( pBlock[ i * 4 + 1 ] ) << 16 | static_cast<uint32_t>( pBlock[ i * 4 + 2 ] ) << 8 | static_cast<uint32_t>( pBlock[ i * 4 + 3 ] );
|
||||||
|
|
||||||
|
for ( int i = 16; i < 80; ++i )
|
||||||
|
w[ i ] = RotL( w[ i - 3 ] ^ w[ i - 8 ] ^ w[ i - 14 ] ^ w[ i - 16 ] , 1 );
|
||||||
|
|
||||||
|
auto a = m_State[ 0 ];
|
||||||
|
auto b = m_State[ 1 ];
|
||||||
|
auto c = m_State[ 2 ];
|
||||||
|
auto d = m_State[ 3 ];
|
||||||
|
auto e = m_State[ 4 ];
|
||||||
|
|
||||||
|
for ( int i = 0; i < 80; ++i )
|
||||||
|
{
|
||||||
|
uint32_t f , k;
|
||||||
|
|
||||||
|
if ( i < 20 )
|
||||||
|
{
|
||||||
|
f = ( b & c ) | ( ( ~b ) & d );
|
||||||
|
k = 0x5A827999;
|
||||||
|
}
|
||||||
|
else if ( i < 40 )
|
||||||
|
{
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
k = 0x6ED9EBA1;
|
||||||
|
}
|
||||||
|
else if ( i < 60 )
|
||||||
|
{
|
||||||
|
f = ( b & c ) | ( b & d ) | ( c & d );
|
||||||
|
k = 0x8F1BBCDC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
k = 0xCA62C1D6;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto Temp = RotL( a , 5 ) + f + e + k + w[ i ];
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = RotL( b , 30 );
|
||||||
|
b = a;
|
||||||
|
a = Temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_State[ 0 ] += a;
|
||||||
|
m_State[ 1 ] += b;
|
||||||
|
m_State[ 2 ] += c;
|
||||||
|
m_State[ 3 ] += d;
|
||||||
|
m_State[ 4 ] += e;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t m_State[ 5 ]{};
|
||||||
|
std::uint64_t m_Count = 0;
|
||||||
|
uint8_t m_Buffer[ 64 ]{};
|
||||||
|
uint8_t m_Digest[ 20 ]{};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto NormalizeAngle( float Angle ) -> float
|
||||||
|
{
|
||||||
|
return Angle - std::floorf( Angle * 0.0027777778f + 0.5f ) * 360.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto QuantizeAngle( float Angle ) -> float
|
||||||
|
{
|
||||||
|
return std::floorf( NormalizeAngle( Angle ) * 2.0f ) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto GetSpreadSeed( const QAngle& ViewAngles , int Tick ) -> uint32_t
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float Pitch;
|
||||||
|
float Yaw;
|
||||||
|
int PlayerRenderTick;
|
||||||
|
} Buffer{};
|
||||||
|
|
||||||
|
Buffer.Pitch = QuantizeAngle( ViewAngles.m_x );
|
||||||
|
Buffer.Yaw = QuantizeAngle( ViewAngles.m_y );
|
||||||
|
Buffer.PlayerRenderTick = Tick;
|
||||||
|
|
||||||
|
CSha1 Hash;
|
||||||
|
Hash.Reset();
|
||||||
|
Hash.Update( &Buffer , 12 );
|
||||||
|
Hash.Final();
|
||||||
|
|
||||||
|
return Hash.GetFirstUInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SeedSpread2_t
|
||||||
|
{
|
||||||
|
float x = 0.f;
|
||||||
|
float y = 0.f;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto CalculateSeedSpread( int Seed , float Inaccuracy , float Spread , int ItemDefIdx ) -> SeedSpread2_t
|
||||||
|
{
|
||||||
|
constexpr auto k_RevolverId = 64;
|
||||||
|
constexpr auto k_NegevId = 28;
|
||||||
|
constexpr auto k_TwoPi = 6.2831853f;
|
||||||
|
|
||||||
|
CValveRng Rng;
|
||||||
|
Rng.Seed( Seed );
|
||||||
|
|
||||||
|
auto InacR = Rng.RandomFloat( 0.f , 1.f );
|
||||||
|
const auto InacA = Rng.RandomFloat( 0.f , k_TwoPi );
|
||||||
|
|
||||||
|
if ( ItemDefIdx == k_RevolverId )
|
||||||
|
InacR = 1.f - ( InacR * InacR );
|
||||||
|
else if ( ItemDefIdx == k_NegevId )
|
||||||
|
InacR = 1.f - ( InacR * InacR );
|
||||||
|
|
||||||
|
InacR *= Inaccuracy;
|
||||||
|
|
||||||
|
auto SprR = Rng.RandomFloat( 0.f , 1.f );
|
||||||
|
const auto SprA = Rng.RandomFloat( 0.f , k_TwoPi );
|
||||||
|
|
||||||
|
if ( ItemDefIdx == k_RevolverId )
|
||||||
|
SprR = 1.f - ( SprR * SprR );
|
||||||
|
else if ( ItemDefIdx == k_NegevId )
|
||||||
|
SprR = 1.f - ( SprR * SprR );
|
||||||
|
|
||||||
|
SprR *= Spread;
|
||||||
|
|
||||||
|
return
|
||||||
|
{
|
||||||
|
std::cosf( SprA ) * SprR + std::cosf( InacA ) * InacR,
|
||||||
|
std::sinf( SprA ) * SprR + std::sinf( InacA ) * InacR
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static CMisc g_CMisc{};
|
static CMisc g_CMisc{};
|
||||||
|
|
||||||
auto CMisc::OnRender() -> void
|
auto CMisc::OnRender() -> void
|
||||||
@@ -278,7 +572,19 @@ auto CMisc::RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto Result = GetCL_Trace()->TraceToHitGroup( pInput );
|
TriggerTraceResult_t Result;
|
||||||
|
|
||||||
|
if ( Settings::Triggerbot::SeedTrigger )
|
||||||
|
{
|
||||||
|
Vector3 vDirection;
|
||||||
|
|
||||||
|
if ( CalculateSeedDirection( pInput , pUserCmd , &vDirection ) )
|
||||||
|
Result = GetCL_Trace()->TraceDirectionToHitGroup( &vDirection );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = GetCL_Trace()->TraceToHitGroup( pInput );
|
||||||
|
}
|
||||||
|
|
||||||
auto* pTargetPawn = reinterpret_cast<C_CSPlayerPawn*>( Result.pHitEntity );
|
auto* pTargetPawn = reinterpret_cast<C_CSPlayerPawn*>( Result.pHitEntity );
|
||||||
|
|
||||||
@@ -300,7 +606,7 @@ auto CMisc::RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
|||||||
default: bTargetValid = true; break;
|
default: bTargetValid = true; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bTargetValid && Settings::Triggerbot::Hitchance > 0 )
|
if ( bTargetValid && !Settings::Triggerbot::SeedTrigger && Settings::Triggerbot::Hitchance > 0 )
|
||||||
{
|
{
|
||||||
const QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 );
|
const QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 );
|
||||||
|
|
||||||
@@ -410,6 +716,50 @@ auto CMisc::CalculateHitchance( CCSGOInput* pInput , C_CSPlayerPawn* pTarget , c
|
|||||||
return static_cast<float>( Hits ) / static_cast<float>( Samples );
|
return static_cast<float>( Hits ) / static_cast<float>( Samples );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto CMisc::CalculateSeedDirection( CCSGOInput* pInput , CUserCmd* pUserCmd , Vector3* vOutDirection ) -> bool
|
||||||
|
{
|
||||||
|
if ( !pInput || !vOutDirection )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto* pWeapon = GetCL_Weapons()->GetLocalActiveWeapon();
|
||||||
|
|
||||||
|
if ( !pWeapon )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 );
|
||||||
|
|
||||||
|
int iSeed = 0;
|
||||||
|
|
||||||
|
if ( pUserCmd && pUserCmd->cmd.base().has_random_seed() )
|
||||||
|
{
|
||||||
|
iSeed = pUserCmd->cmd.base().random_seed();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int iTick = 0;
|
||||||
|
|
||||||
|
if ( pUserCmd && pUserCmd->cmd.base().has_client_tick() )
|
||||||
|
iTick = pUserCmd->cmd.base().client_tick();
|
||||||
|
|
||||||
|
iSeed = static_cast<int>( GetSpreadSeed( ViewAngles , iTick ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const float flInaccuracy = C_CSWeaponBaseGun_GetInaccuracy( pWeapon , nullptr , nullptr );
|
||||||
|
const float flSpread = C_CSWeaponBaseGun_GetSpread( pWeapon );
|
||||||
|
|
||||||
|
const auto ItemDefIdx = GetCL_Weapons()->GetLocalWeaponDefinitionIndex();
|
||||||
|
|
||||||
|
const auto sv = CalculateSeedSpread( iSeed + 1 , flInaccuracy , flSpread , ItemDefIdx );
|
||||||
|
|
||||||
|
Vector3 vForward , vRight , vUp;
|
||||||
|
|
||||||
|
Math::AngleVectors( ViewAngles , vForward , vRight , vUp );
|
||||||
|
|
||||||
|
*vOutDirection = ( vForward + vRight * -sv.x + vUp * sv.y ).Normalized();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto CMisc::OnFrameStageNotify( int FrameStage ) -> void
|
auto CMisc::OnFrameStageNotify( int FrameStage ) -> void
|
||||||
{
|
{
|
||||||
if ( FrameStage != 6 )
|
if ( FrameStage != 6 )
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
auto RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void;
|
auto RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void;
|
||||||
auto CalculateHitchance( CCSGOInput* pInput , C_CSPlayerPawn* pTarget , const QAngle& ViewAngles , const int Samples ) -> float;
|
auto CalculateHitchance( CCSGOInput* pInput , C_CSPlayerPawn* pTarget , const QAngle& ViewAngles , const int Samples ) -> float;
|
||||||
|
auto CalculateSeedDirection( CCSGOInput* pInput , CUserCmd* pUserCmd , Vector3* vOutDirection ) -> bool;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::chrono::steady_clock::time_point m_HitTime{};
|
std::chrono::steady_clock::time_point m_HitTime{};
|
||||||
|
|||||||
@@ -393,10 +393,15 @@ auto CAndromedaMenu::RenderMiscPanel() -> void
|
|||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
|
Checkbox( "Seed-Modus (deterministisch)" , Settings::Triggerbot::SeedTrigger );
|
||||||
|
|
||||||
|
if ( !Settings::Triggerbot::SeedTrigger )
|
||||||
|
{
|
||||||
SliderInt( "Hitchance (%)" , Settings::Triggerbot::Hitchance , 0 , 100 , Settings::Triggerbot::Hitchance > 0 ? "%d%%" : "%d (aus)" );
|
SliderInt( "Hitchance (%)" , Settings::Triggerbot::Hitchance , 0 , 100 , Settings::Triggerbot::Hitchance > 0 ? "%d%%" : "%d (aus)" );
|
||||||
|
|
||||||
if ( Settings::Triggerbot::Hitchance > 0 )
|
if ( Settings::Triggerbot::Hitchance > 0 )
|
||||||
SliderInt( "Hitchance Samples" , Settings::Triggerbot::HitchanceSamples , 16 , 128 );
|
SliderInt( "Hitchance Samples" , Settings::Triggerbot::HitchanceSamples , 16 , 128 );
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ namespace Settings
|
|||||||
inline auto DrawIndicator = true;
|
inline auto DrawIndicator = true;
|
||||||
inline auto Hitchance = 0; // percent, 0 = off
|
inline auto Hitchance = 0; // percent, 0 = off
|
||||||
inline auto HitchanceSamples = 64;
|
inline auto HitchanceSamples = 64;
|
||||||
|
inline auto SeedTrigger = false; // deterministic: only fire if the real bullet (current random_seed) would hit
|
||||||
}
|
}
|
||||||
namespace Colors
|
namespace Colors
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,6 +120,35 @@ auto CL_Trace::TraceToHitGroup( CCSGOInput* pInput ) -> TriggerTraceResult_t
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto CL_Trace::TraceDirectionToHitGroup( const Vector3* vDirection ) -> TriggerTraceResult_t
|
||||||
|
{
|
||||||
|
TriggerTraceResult_t Result;
|
||||||
|
|
||||||
|
auto pLocalPlayerPawn = GetCL_Players()->GetLocalPlayerPawn();
|
||||||
|
|
||||||
|
if ( !pLocalPlayerPawn || !vDirection )
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
Ray_t Ray;
|
||||||
|
CGameTrace GameTrace;
|
||||||
|
CTraceFilter Filter( 0x1C1003 , pLocalPlayerPawn , 3 , 15 );
|
||||||
|
|
||||||
|
const auto vStart = GetCL_Players()->GetLocalEyeOrigin();
|
||||||
|
|
||||||
|
const auto vEnd = vStart + ( *vDirection * 8192.f );
|
||||||
|
|
||||||
|
if ( IGamePhysicsQuery_TraceShape( SDK::Pointers::CVPhys2World() , Ray , vStart , vEnd , &Filter , &GameTrace ) )
|
||||||
|
{
|
||||||
|
if ( GameTrace.pHitEntity && GameTrace.pHitBox )
|
||||||
|
{
|
||||||
|
Result.pHitEntity = GameTrace.pHitEntity;
|
||||||
|
Result.nHitGroup = GameTrace.pHitBox->nGroupId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
auto GetCL_Trace() -> CL_Trace*
|
auto GetCL_Trace() -> CL_Trace*
|
||||||
{
|
{
|
||||||
return &g_CL_Trace;
|
return &g_CL_Trace;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public:
|
|||||||
auto TraceToBoneEntity( CCSGOInput* pInput , const QAngle* AngleCorrection , QAngle* ViewAngleCorrection ) -> std::pair<uint64_t , C_BaseEntity*>;
|
auto TraceToBoneEntity( CCSGOInput* pInput , const QAngle* AngleCorrection , QAngle* ViewAngleCorrection ) -> std::pair<uint64_t , C_BaseEntity*>;
|
||||||
auto TraceToEntityEndPos( const Vector3* vEnd ) -> C_BaseEntity*;
|
auto TraceToEntityEndPos( const Vector3* vEnd ) -> C_BaseEntity*;
|
||||||
auto TraceToHitGroup( CCSGOInput* pInput ) -> TriggerTraceResult_t;
|
auto TraceToHitGroup( CCSGOInput* pInput ) -> TriggerTraceResult_t;
|
||||||
|
auto TraceDirectionToHitGroup( const Vector3* vDirection ) -> TriggerTraceResult_t;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto GetCL_Trace() -> CL_Trace*;
|
auto GetCL_Trace() -> CL_Trace*;
|
||||||
|
|||||||
Reference in New Issue
Block a user