Add ragebot with nospread, auto stop/fire, recoil control and separate Legitbot/Ragebot GUI tabs
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include <GameClient/CL_Weapons.hpp>
|
||||
#include <GameClient/CL_Trace.hpp>
|
||||
#include <GameClient/CL_Bypass.hpp>
|
||||
#include <GameClient/CL_VisibleCheck.hpp>
|
||||
#include <GameClient/CEntityCache/CEntityCache.hpp>
|
||||
#include <CS2/SDK/Types/CBaseTypes.hpp>
|
||||
#include <CS2/SDK/FunctionListSDK.hpp>
|
||||
@@ -479,6 +480,9 @@ auto CMisc::OnCreateMove( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
||||
if ( Settings::Triggerbot::Active )
|
||||
RunTriggerbot( pInput , pUserCmd );
|
||||
|
||||
if ( Settings::Ragebot::Active )
|
||||
RunRagebot( pInput , pUserCmd );
|
||||
|
||||
if ( Settings::Misc::Bunnyhop )
|
||||
{
|
||||
auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn();
|
||||
@@ -1335,6 +1339,246 @@ auto CMisc::RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
||||
}
|
||||
}
|
||||
|
||||
auto CMisc::CalculateRagebotFov( const QAngle& ViewAngles , const QAngle& AimAngles ) -> float
|
||||
{
|
||||
const float flPitch = std::fabsf( Math::AngleNormalize( AimAngles.m_x - ViewAngles.m_x ) );
|
||||
const float flYaw = std::fabsf( Math::AngleNormalize( AimAngles.m_y - ViewAngles.m_y ) );
|
||||
|
||||
return std::sqrtf( flPitch * flPitch + flYaw * flYaw );
|
||||
}
|
||||
|
||||
auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
||||
{
|
||||
m_bRagebotFiring = false;
|
||||
|
||||
auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn();
|
||||
|
||||
if ( !pLocalPawn || !pLocalPawn->IsAlive() )
|
||||
return;
|
||||
|
||||
const auto WeaponType = GetCL_Weapons()->GetLocalWeaponType();
|
||||
|
||||
const bool bIsGun = WeaponType == CSWeaponType_t::WEAPONTYPE_PISTOL ||
|
||||
WeaponType == CSWeaponType_t::WEAPONTYPE_SUBMACHINEGUN ||
|
||||
WeaponType == CSWeaponType_t::WEAPONTYPE_RIFLE ||
|
||||
WeaponType == CSWeaponType_t::WEAPONTYPE_SHOTGUN ||
|
||||
WeaponType == CSWeaponType_t::WEAPONTYPE_SNIPER_RIFLE ||
|
||||
WeaponType == CSWeaponType_t::WEAPONTYPE_MACHINEGUN ||
|
||||
WeaponType == CSWeaponType_t::WEAPONTYPE_TASER;
|
||||
|
||||
if ( !bIsGun )
|
||||
return;
|
||||
|
||||
bool bShouldRun = false;
|
||||
|
||||
switch ( Settings::Ragebot::Mode )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
bShouldRun = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
const bool bKeyDown = ( GetAsyncKeyState( Settings::Ragebot::Key ) & 0x8000 ) != 0;
|
||||
|
||||
if ( bKeyDown && !m_bRagebotKeyDown )
|
||||
m_bRagebotToggledOn = !m_bRagebotToggledOn;
|
||||
|
||||
m_bRagebotKeyDown = bKeyDown;
|
||||
|
||||
bShouldRun = m_bRagebotToggledOn;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
const bool bKeyDown = ( GetAsyncKeyState( Settings::Ragebot::Key ) & 0x8000 ) != 0;
|
||||
|
||||
bShouldRun = bKeyDown;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !bShouldRun )
|
||||
return;
|
||||
|
||||
auto* pWeapon = GetCL_Weapons()->GetLocalActiveWeapon();
|
||||
|
||||
if ( !pWeapon )
|
||||
return;
|
||||
|
||||
const float flInaccuracy = C_CSWeaponBaseGun_GetInaccuracy( pWeapon , nullptr , nullptr );
|
||||
const float flSpread = C_CSWeaponBaseGun_GetSpread( pWeapon );
|
||||
const int iItemDefIdx = GetCL_Weapons()->GetLocalWeaponDefinitionIndex();
|
||||
|
||||
const Vector3 vEyeOrigin = GetCL_Players()->GetLocalEyeOrigin();
|
||||
|
||||
const QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 );
|
||||
|
||||
C_CSPlayerPawn* pBestPawn = nullptr;
|
||||
QAngle BestAngles;
|
||||
float flBestFov = 9999.f;
|
||||
|
||||
const auto& CachedVec = GetEntityCache()->GetCachedEntity();
|
||||
|
||||
std::scoped_lock Lock( GetEntityCache()->GetLock() );
|
||||
|
||||
for ( const auto& CachedEntity : *CachedVec )
|
||||
{
|
||||
if ( CachedEntity.m_Type != CachedEntity_t::PLAYER_CONTROLLER )
|
||||
continue;
|
||||
|
||||
auto* pEntity = CachedEntity.m_Handle.Get();
|
||||
|
||||
if ( !pEntity )
|
||||
continue;
|
||||
|
||||
auto* pController = reinterpret_cast<CCSPlayerController*>( pEntity );
|
||||
|
||||
if ( pController == GetCL_Players()->GetLocalPlayerController() )
|
||||
continue;
|
||||
|
||||
auto* pPawn = pController->m_hPawn().Get<C_CSPlayerPawn>();
|
||||
|
||||
if ( !pPawn || !pPawn->IsPlayerPawn() || pPawn == pLocalPawn || !pPawn->IsAlive() )
|
||||
continue;
|
||||
|
||||
if ( Settings::Ragebot::IgnoreTeammates && pPawn->m_iTeamNum() == pLocalPawn->m_iTeamNum() )
|
||||
continue;
|
||||
|
||||
const char* szBoneName = "head_0";
|
||||
|
||||
switch ( Settings::Ragebot::Hitbox )
|
||||
{
|
||||
case 0: szBoneName = "head_0"; break;
|
||||
case 2: szBoneName = "spine_3"; break;
|
||||
case 3: szBoneName = "pelvis"; break;
|
||||
case 4: szBoneName = "ankle_l"; break;
|
||||
default: szBoneName = "pelvis"; break;
|
||||
}
|
||||
|
||||
const Vector3 vAimPoint = GetCL_Bones()->GetBonePositionByName( pPawn , szBoneName );
|
||||
|
||||
if ( vAimPoint.IsZero() )
|
||||
continue;
|
||||
|
||||
Vector3 vDelta = vAimPoint - vEyeOrigin;
|
||||
|
||||
if ( vDelta.Length() < 0.01f )
|
||||
continue;
|
||||
|
||||
if ( Settings::Ragebot::VisibleOnly && !GetCL_VisibleCheck()->IsBoneVisible( pPawn , vAimPoint ) )
|
||||
continue;
|
||||
|
||||
QAngle AimAngles;
|
||||
Math::VectorAngles( vDelta.Normalized() , AimAngles );
|
||||
|
||||
if ( Settings::Ragebot::Recoil )
|
||||
{
|
||||
const auto& PunchCache = pLocalPawn->m_aimPunchCache();
|
||||
|
||||
if ( PunchCache.Count() > 0 )
|
||||
{
|
||||
constexpr float k_PunchScale = 2.f;
|
||||
|
||||
AimAngles.m_x -= PunchCache[ 0 ].m_x * k_PunchScale;
|
||||
AimAngles.m_y -= PunchCache[ 0 ].m_y * k_PunchScale;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Settings::Ragebot::NoSpread )
|
||||
{
|
||||
constexpr float k_RadToDeg = 180.f / 3.14159265358979f;
|
||||
|
||||
for ( auto i = 0; i < 3; i++ )
|
||||
{
|
||||
int iTick = 0;
|
||||
|
||||
if ( pUserCmd && pUserCmd->cmd.base().has_client_tick() )
|
||||
iTick = pUserCmd->cmd.base().client_tick();
|
||||
|
||||
const auto iSeed = static_cast<int>( GetSpreadSeed( AimAngles , iTick ) );
|
||||
|
||||
const auto sv = CalculateSeedSpread( iSeed + 1 , flInaccuracy , flSpread , iItemDefIdx );
|
||||
|
||||
AimAngles.m_x -= sv.y * k_RadToDeg;
|
||||
AimAngles.m_y += sv.x * k_RadToDeg;
|
||||
}
|
||||
}
|
||||
|
||||
Math::NormalizeAngles( AimAngles );
|
||||
Math::ClampAngles( AimAngles );
|
||||
|
||||
const float flFov = CalculateRagebotFov( ViewAngles , AimAngles );
|
||||
|
||||
if ( flFov > static_cast<float>( Settings::Ragebot::FOV ) )
|
||||
continue;
|
||||
|
||||
if ( flFov < flBestFov )
|
||||
{
|
||||
flBestFov = flFov;
|
||||
pBestPawn = pPawn;
|
||||
BestAngles = AimAngles;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !pBestPawn )
|
||||
return;
|
||||
|
||||
if ( Settings::Ragebot::Hitchance > 0 )
|
||||
{
|
||||
const float flHitchance = CalculateHitchance( pInput , pBestPawn , BestAngles , Settings::Ragebot::HitchanceSamples );
|
||||
|
||||
if ( ( flHitchance * 100.f ) < static_cast<float>( Settings::Ragebot::Hitchance ) )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Settings::Ragebot::AutoStop )
|
||||
{
|
||||
const Vector3 Velocity = pLocalPawn->m_vecVelocity();
|
||||
|
||||
const float flSpeed = Velocity.Length2D();
|
||||
|
||||
if ( flSpeed > 5.f )
|
||||
{
|
||||
constexpr float k_Pi = 3.14159265358979f;
|
||||
|
||||
const float flVelYaw = std::atan2f( Velocity.m_y , Velocity.m_x ) * ( 180.f / k_Pi );
|
||||
|
||||
float flDelta = flVelYaw - ViewAngles.m_y;
|
||||
|
||||
while ( flDelta > 180.f )
|
||||
flDelta -= 360.f;
|
||||
|
||||
while ( flDelta < -180.f )
|
||||
flDelta += 360.f;
|
||||
|
||||
auto& uButtons = pUserCmd->button_states.buttonstate1;
|
||||
|
||||
if ( flDelta > -45.f && flDelta <= 45.f )
|
||||
uButtons |= IN_BACK;
|
||||
else if ( flDelta > 45.f && flDelta <= 135.f )
|
||||
uButtons |= IN_MOVELEFT;
|
||||
else if ( flDelta > 135.f || flDelta <= -135.f )
|
||||
uButtons |= IN_FORWARD;
|
||||
else
|
||||
uButtons |= IN_MOVERIGHT;
|
||||
|
||||
pUserCmd->cmd.mutable_base()->mutable_buttons_pb()->set_buttonstate1( uButtons );
|
||||
}
|
||||
}
|
||||
|
||||
GetCL_Bypass()->SetViewAngles( &BestAngles , pInput , pUserCmd );
|
||||
|
||||
if ( Settings::Ragebot::AutoFire )
|
||||
{
|
||||
GetCL_Bypass()->SetAttack( pUserCmd , true );
|
||||
m_bRagebotFiring = true;
|
||||
}
|
||||
}
|
||||
|
||||
static thread_local std::mt19937 g_TriggerRng( std::random_device{}() );
|
||||
|
||||
auto CMisc::CalculateHitchance( CCSGOInput* pInput , C_CSPlayerPawn* pTarget , const QAngle& ViewAngles , const int Samples ) -> float
|
||||
|
||||
@@ -35,8 +35,10 @@ public:
|
||||
|
||||
private:
|
||||
auto RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void;
|
||||
auto RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void;
|
||||
auto CalculateHitchance( CCSGOInput* pInput , C_CSPlayerPawn* pTarget , const QAngle& ViewAngles , const int Samples ) -> float;
|
||||
auto CalculateSeedDirection( CCSGOInput* pInput , CUserCmd* pUserCmd , Vector3* vOutDirection ) -> bool;
|
||||
auto CalculateRagebotFov( const QAngle& ViewAngles , const QAngle& AimAngles ) -> float;
|
||||
|
||||
auto RunMovement( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void;
|
||||
auto RunAutoStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void;
|
||||
@@ -77,6 +79,10 @@ private:
|
||||
bool m_bRightHeld = false;
|
||||
bool m_bForwardHeld = false;
|
||||
bool m_bBackHeld = false;
|
||||
|
||||
std::atomic_bool m_bRagebotFiring = false;
|
||||
bool m_bRagebotKeyDown = false;
|
||||
bool m_bRagebotToggledOn = false;
|
||||
};
|
||||
|
||||
auto GetMisc() -> CMisc*;
|
||||
|
||||
@@ -72,6 +72,18 @@ auto CAndromedaMenu::OnRenderMenu() -> void
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if ( ImGui::BeginTabItem( "Legitbot" ) )
|
||||
{
|
||||
RenderLegitbotPanel();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if ( ImGui::BeginTabItem( "Ragebot" ) )
|
||||
{
|
||||
RenderRagebotPanel();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if ( ImGui::BeginTabItem( "Misc" ) )
|
||||
{
|
||||
RenderMiscPanel();
|
||||
@@ -367,7 +379,10 @@ auto CAndromedaMenu::RenderMiscPanel() -> void
|
||||
|
||||
Checkbox( "Hitmarker" , Settings::Misc::Hitmarker );
|
||||
Checkbox( "Hit Sound" , Settings::Misc::HitSound );
|
||||
}
|
||||
|
||||
auto CAndromedaMenu::RenderLegitbotPanel() -> void
|
||||
{
|
||||
ImGui::SeparatorText( "Triggerbot" );
|
||||
|
||||
Checkbox( "Triggerbot" , Settings::Triggerbot::Active );
|
||||
@@ -436,6 +451,72 @@ auto CAndromedaMenu::RenderMiscPanel() -> void
|
||||
}
|
||||
}
|
||||
|
||||
auto CAndromedaMenu::RenderRagebotPanel() -> void
|
||||
{
|
||||
ImGui::SeparatorText( "Ragebot" );
|
||||
|
||||
Checkbox( "Enabled" , Settings::Ragebot::Active );
|
||||
|
||||
if ( Settings::Ragebot::Active )
|
||||
{
|
||||
const char* RageModeItems[] =
|
||||
{
|
||||
"Hold Key" , "Always" , "Toggle"
|
||||
};
|
||||
|
||||
Combo( "Mode" , Settings::Ragebot::Mode , RageModeItems , IM_ARRAYSIZE( RageModeItems ) );
|
||||
|
||||
static const char* RageKeyItems[] =
|
||||
{
|
||||
"Alt" , "Shift" , "Ctrl" , "Mouse 4" , "Mouse 5" , "Q" , "E" , "F" , "X" , "C" , "V" , "B" , "Space"
|
||||
};
|
||||
|
||||
static const int RageKeys[] =
|
||||
{
|
||||
VK_MENU , VK_SHIFT , VK_CONTROL , 0x04 , 0x05 , 0x51 , 0x45 , 0x46 , 0x58 , 0x43 , 0x56 , 0x42 , VK_SPACE
|
||||
};
|
||||
|
||||
int iKeyIdx = 0;
|
||||
|
||||
for ( int i = 0; i < IM_ARRAYSIZE( RageKeys ); i++ )
|
||||
{
|
||||
if ( RageKeys[ i ] == Settings::Ragebot::Key )
|
||||
{
|
||||
iKeyIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Combo( "Key" , iKeyIdx , RageKeyItems , IM_ARRAYSIZE( RageKeyItems ) ) )
|
||||
Settings::Ragebot::Key = RageKeys[ iKeyIdx ];
|
||||
|
||||
const char* HitboxItems[] =
|
||||
{
|
||||
"Head" , "Nearest" , "Chest" , "Stomach" , "Legs"
|
||||
};
|
||||
|
||||
Combo( "Hitbox" , Settings::Ragebot::Hitbox , HitboxItems , IM_ARRAYSIZE( HitboxItems ) );
|
||||
|
||||
SliderInt( "FOV" , Settings::Ragebot::FOV , 1 , 180 );
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
Checkbox( "NoSpread" , Settings::Ragebot::NoSpread );
|
||||
Checkbox( "Auto Fire" , Settings::Ragebot::AutoFire );
|
||||
Checkbox( "Auto Stop" , Settings::Ragebot::AutoStop );
|
||||
Checkbox( "Recoil Control" , Settings::Ragebot::Recoil );
|
||||
Checkbox( "Teammates ignorieren" , Settings::Ragebot::IgnoreTeammates );
|
||||
Checkbox( "Nur sichtbar" , Settings::Ragebot::VisibleOnly );
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
SliderInt( "Hitchance (%)" , Settings::Ragebot::Hitchance , 0 , 100 , Settings::Ragebot::Hitchance > 0 ? "%d%%" : "%d (aus)" );
|
||||
|
||||
if ( Settings::Ragebot::Hitchance > 0 )
|
||||
SliderInt( "Hitchance Samples" , Settings::Ragebot::HitchanceSamples , 16 , 128 );
|
||||
}
|
||||
}
|
||||
|
||||
auto CAndromedaMenu::RenderConfigPanel() -> void
|
||||
{
|
||||
ImGui::SeparatorText( "Menu" );
|
||||
|
||||
@@ -16,6 +16,8 @@ private:
|
||||
auto RenderMusicPanel() -> void;
|
||||
auto RenderConfigPanel() -> void;
|
||||
auto RenderMiscPanel() -> void;
|
||||
auto RenderLegitbotPanel() -> void;
|
||||
auto RenderRagebotPanel() -> void;
|
||||
|
||||
private:
|
||||
auto Checkbox( const char* szLabel , bool& bValue ) -> bool;
|
||||
|
||||
@@ -88,6 +88,22 @@ namespace Settings
|
||||
inline auto HitchanceSamples = 64;
|
||||
inline auto SeedTrigger = false; // deterministic: only fire if the real bullet (current random_seed) would hit
|
||||
}
|
||||
namespace Ragebot
|
||||
{
|
||||
inline auto Active = false;
|
||||
inline auto Mode = 0; // 0 = Hold Key, 1 = Always, 2 = Toggle
|
||||
inline auto Key = VK_MENU; // Alt
|
||||
inline auto Hitbox = 0; // 0 = Head, 1 = Nearest, 2 = Chest, 3 = Stomach, 4 = Legs
|
||||
inline auto FOV = 10; // degrees
|
||||
inline auto Hitchance = 70; // percent, 0 = off
|
||||
inline auto HitchanceSamples = 64;
|
||||
inline auto AutoFire = true;
|
||||
inline auto AutoStop = true;
|
||||
inline auto NoSpread = true;
|
||||
inline auto Recoil = true;
|
||||
inline auto IgnoreTeammates = true;
|
||||
inline auto VisibleOnly = true;
|
||||
}
|
||||
namespace Colors
|
||||
{
|
||||
namespace Visual
|
||||
|
||||
Reference in New Issue
Block a user