Rework ragebot: per-hitbox toggles, target modes, smooth aim, autoscope/autocrouch, mindamage, autofire delay, recoil scale and overlay

This commit is contained in:
2026-08-05 18:21:37 +02:00
parent 12ae5bef43
commit e51e39f7ed
4 changed files with 426 additions and 116 deletions
@@ -449,6 +449,52 @@ auto CMisc::OnClientOutput() -> void
}
}
if ( Settings::Ragebot::Active && Settings::Ragebot::DrawFov )
{
const auto DisplaySize = ImGui::GetIO().DisplaySize;
const ImVec2 Center( DisplaySize.x * 0.5f , DisplaySize.y * 0.5f );
constexpr float k_Pi = 3.14159265358979f;
const float flRadius = std::tanf( Settings::Ragebot::FOV * ( k_Pi / 180.f ) ) * ( DisplaySize.y * 0.6f );
constexpr int k_Segments = 48;
for ( int i = 0; i < k_Segments; i++ )
{
const float flAngle0 = ( static_cast<float>( i ) / k_Segments ) * 2.f * k_Pi;
const float flAngle1 = ( static_cast<float>( i + 1 ) / k_Segments ) * 2.f * k_Pi;
const ImVec2 A( Center.x + std::cosf( flAngle0 ) * flRadius , Center.y + std::sinf( flAngle0 ) * flRadius );
const ImVec2 B( Center.x + std::cosf( flAngle1 ) * flRadius , Center.y + std::sinf( flAngle1 ) * flRadius );
GetRenderStackSystem()->DrawLine( A , B , ImColor( 255 , 255 , 255 , 140 ) , 1.f );
}
}
if ( Settings::Ragebot::Active && Settings::Ragebot::DrawTarget )
{
if ( m_bRagebotTargetValid )
{
ImVec2 Screen;
if ( Math::WorldToScreen( m_vRagebotTargetPoint , Screen ) )
{
const auto DisplaySize = ImGui::GetIO().DisplaySize;
const ImVec2 Center( DisplaySize.x * 0.5f , DisplaySize.y * 0.5f );
const float flHp = std::clamp( m_flRagebotTargetHealth , 0.f , 100.f );
const ImColor TargetColor( static_cast<int>( 255 * ( 1.f - flHp / 100.f ) ) , static_cast<int>( 255 * ( flHp / 100.f ) ) , 0 );
GetRenderStackSystem()->DrawLine( Center , Screen , TargetColor , 1.5f );
GetRenderStackSystem()->DrawCircleFilled( Screen , 5.f , TargetColor );
}
}
}
if ( Settings::Misc::Hitmarker )
{
if ( m_HitTime.time_since_epoch().count() > 0 )
@@ -1350,6 +1396,7 @@ auto CMisc::CalculateRagebotFov( const QAngle& ViewAngles , const QAngle& AimAng
auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
{
m_bRagebotFiring = false;
m_bRagebotTargetValid = false;
auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn();
@@ -1409,6 +1456,8 @@ auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
if ( !pWeapon )
return;
auto* pWeaponVData = GetCL_Weapons()->GetLocalWeaponVData();
const float flInaccuracy = C_CSWeaponBaseGun_GetInaccuracy( pWeapon , nullptr , nullptr );
const float flSpread = C_CSWeaponBaseGun_GetSpread( pWeapon );
const int iItemDefIdx = GetCL_Weapons()->GetLocalWeaponDefinitionIndex();
@@ -1417,9 +1466,100 @@ auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
const QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 );
C_CSPlayerPawn* pBestPawn = nullptr;
QAngle BestAngles;
float flBestFov = 9999.f;
struct RageHitbox
{
const char* szBoneName;
bool bEnabled;
bool bHead;
};
const RageHitbox Hitboxes[] =
{
{ "head_0" , Settings::Ragebot::Hitbox_Head , true },
{ "neck_0" , Settings::Ragebot::Hitbox_Neck , true },
{ "spine_3" , Settings::Ragebot::Hitbox_Chest , false },
{ "spine_1" , Settings::Ragebot::Hitbox_Stomach , false },
{ "pelvis" , Settings::Ragebot::Hitbox_Pelvis , false },
{ "arm_lower_r" , Settings::Ragebot::Hitbox_Arms , false },
{ "ankle_l" , Settings::Ragebot::Hitbox_Legs , false },
{ "ankle_l" , Settings::Ragebot::Hitbox_Feet , false },
};
auto ComputeAimAngles = [ & ]( const Vector3& vAimPoint ) -> QAngle
{
Vector3 vDelta = vAimPoint - vEyeOrigin;
QAngle AimAngles;
Math::VectorAngles( vDelta.Normalized() , AimAngles );
if ( Settings::Ragebot::Recoil )
{
const auto& PunchCache = pLocalPawn->m_aimPunchCache();
if ( PunchCache.Count() > 0 )
{
AimAngles.m_x -= PunchCache[ 0 ].m_x * Settings::Ragebot::RecoilScale;
AimAngles.m_y -= PunchCache[ 0 ].m_y * Settings::Ragebot::RecoilScale;
}
}
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 );
return AimAngles;
};
auto EstimateDamage = [ & ]( C_CSPlayerPawn* pTarget , const Vector3& vAimPoint , bool bHead ) -> float
{
if ( !pWeaponVData )
return 0.f;
const float flDistance = ( vAimPoint - vEyeOrigin ).Length();
float flDamage = static_cast<float>( pWeaponVData->m_nDamage() );
flDamage *= std::pow( pWeaponVData->m_flRangeModifier() , flDistance / 500.f );
if ( bHead )
flDamage *= pWeaponVData->m_flHeadshotMultiplier();
if ( pTarget->m_ArmorValue() > 0 )
flDamage *= pWeaponVData->m_flArmorRatio();
return flDamage;
};
struct RageCandidate
{
C_CSPlayerPawn* pPawn = nullptr;
Vector3 vAimPoint{};
QAngle AimAngles{};
float flFov = 9999.f;
float flDistance = 0.f;
float flHealth = 0.f;
};
RageCandidate Best;
const auto& CachedVec = GetEntityCache()->GetCachedEntity();
@@ -1448,93 +1588,152 @@ auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
if ( Settings::Ragebot::IgnoreTeammates && pPawn->m_iTeamNum() == pLocalPawn->m_iTeamNum() )
continue;
const char* szBoneName = "head_0";
constexpr int k_HitboxCount = 8;
switch ( Settings::Ragebot::Hitbox )
bool abValid[ k_HitboxCount ] = { false };
Vector3 avAimPoint[ k_HitboxCount ]{};
QAngle aAimAngles[ k_HitboxCount ]{};
float aflFov[ k_HitboxCount ] = { 9999.f };
float aflDistance[ k_HitboxCount ] = { 0.f };
int iValidCount = 0;
for ( int i = 0; i < k_HitboxCount; i++ )
{
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;
if ( !Hitboxes[ i ].bEnabled )
continue;
const Vector3 vAimPoint = GetCL_Bones()->GetBonePositionByName( pPawn , Hitboxes[ i ].szBoneName );
if ( vAimPoint.IsZero() )
continue;
if ( Settings::Ragebot::VisibleOnly && !GetCL_VisibleCheck()->IsBoneVisible( pPawn , vAimPoint ) )
continue;
const QAngle AimAngles = ComputeAimAngles( vAimPoint );
const float flFov = CalculateRagebotFov( ViewAngles , AimAngles );
const float flDistance = ( vAimPoint - vEyeOrigin ).Length();
avAimPoint[ i ] = vAimPoint;
aAimAngles[ i ] = AimAngles;
aflFov[ i ] = flFov;
aflDistance[ i ] = flDistance;
abValid[ i ] = true;
iValidCount++;
}
const Vector3 vAimPoint = GetCL_Bones()->GetBonePositionByName( pPawn , szBoneName );
if ( vAimPoint.IsZero() )
if ( iValidCount == 0 )
continue;
Vector3 vDelta = vAimPoint - vEyeOrigin;
int iBestHitbox = -1;
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 )
if ( Settings::Ragebot::HitboxMode == 1 )
{
const auto& PunchCache = pLocalPawn->m_aimPunchCache();
const int iPreferred = Settings::Ragebot::PreferredHitbox;
if ( PunchCache.Count() > 0 )
if ( iPreferred >= 0 && iPreferred < k_HitboxCount && abValid[ iPreferred ] )
iBestHitbox = iPreferred;
}
if ( iBestHitbox == -1 )
{
if ( Settings::Ragebot::HitboxMode == 2 )
{
constexpr float k_PunchScale = 2.f;
float flBestHitchance = -1.f;
AimAngles.m_x -= PunchCache[ 0 ].m_x * k_PunchScale;
AimAngles.m_y -= PunchCache[ 0 ].m_y * k_PunchScale;
for ( int i = 0; i < k_HitboxCount; i++ )
{
if ( !abValid[ i ] )
continue;
const float flHitchance = CalculateHitchance( pInput , pPawn , aAimAngles[ i ] , Settings::Ragebot::HitchanceSamples );
if ( flHitchance > flBestHitchance )
{
flBestHitchance = flHitchance;
iBestHitbox = i;
}
}
}
else
{
float flBestFov = 9999.f;
for ( int i = 0; i < k_HitboxCount; i++ )
{
if ( !abValid[ i ] )
continue;
if ( aflFov[ i ] < flBestFov )
{
flBestFov = aflFov[ i ];
iBestHitbox = i;
}
}
}
}
if ( Settings::Ragebot::NoSpread )
if ( iBestHitbox == -1 )
continue;
if ( aflFov[ iBestHitbox ] > static_cast<float>( Settings::Ragebot::FOV ) )
continue;
if ( Settings::Ragebot::MaxDistance > 0 && aflDistance[ iBestHitbox ] > static_cast<float>( Settings::Ragebot::MaxDistance ) )
continue;
if ( Settings::Ragebot::MinDamage > 0 )
{
constexpr float k_RadToDeg = 180.f / 3.14159265358979f;
const float flDamage = EstimateDamage( pPawn , avAimPoint[ iBestHitbox ] , Hitboxes[ iBestHitbox ].bHead );
for ( auto i = 0; i < 3; i++ )
if ( flDamage < static_cast<float>( Settings::Ragebot::MinDamage ) )
continue;
}
bool bBetter = false;
if ( !Best.pPawn )
bBetter = true;
else
{
switch ( Settings::Ragebot::TargetMode )
{
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;
case 1: bBetter = aflDistance[ iBestHitbox ] < Best.flDistance; break;
case 2: bBetter = static_cast<float>( pPawn->m_iHealth() ) < Best.flHealth; break;
default: bBetter = aflFov[ iBestHitbox ] < Best.flFov; break;
}
}
Math::NormalizeAngles( AimAngles );
Math::ClampAngles( AimAngles );
const float flFov = CalculateRagebotFov( ViewAngles , AimAngles );
if ( flFov > static_cast<float>( Settings::Ragebot::FOV ) )
continue;
if ( flFov < flBestFov )
if ( bBetter )
{
flBestFov = flFov;
pBestPawn = pPawn;
BestAngles = AimAngles;
Best.pPawn = pPawn;
Best.vAimPoint = avAimPoint[ iBestHitbox ];
Best.AimAngles = aAimAngles[ iBestHitbox ];
Best.flFov = aflFov[ iBestHitbox ];
Best.flDistance = aflDistance[ iBestHitbox ];
Best.flHealth = static_cast<float>( pPawn->m_iHealth() );
}
}
if ( !pBestPawn )
if ( !Best.pPawn )
return;
if ( Settings::Ragebot::Hitchance > 0 )
{
const float flHitchance = CalculateHitchance( pInput , pBestPawn , BestAngles , Settings::Ragebot::HitchanceSamples );
const float flHitchance = CalculateHitchance( pInput , Best.pPawn , Best.AimAngles , Settings::Ragebot::HitchanceSamples );
if ( ( flHitchance * 100.f ) < static_cast<float>( Settings::Ragebot::Hitchance ) )
return;
}
auto& uButtons = pUserCmd->button_states.buttonstate1;
if ( Settings::Ragebot::AutoScope && WeaponType == CSWeaponType_t::WEAPONTYPE_SNIPER_RIFLE && !pLocalPawn->m_bIsScoped() )
uButtons |= IN_ATTACK2;
if ( Settings::Ragebot::AutoCrouch )
uButtons |= IN_DUCK;
if ( Settings::Ragebot::AutoStop )
{
const Vector3 Velocity = pLocalPawn->m_vecVelocity();
@@ -1555,8 +1754,6 @@ auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
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 )
@@ -1565,18 +1762,36 @@ auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
uButtons |= IN_FORWARD;
else
uButtons |= IN_MOVERIGHT;
pUserCmd->cmd.mutable_base()->mutable_buttons_pb()->set_buttonstate1( uButtons );
}
}
GetCL_Bypass()->SetViewAngles( &BestAngles , pInput , pUserCmd );
pUserCmd->cmd.mutable_base()->mutable_buttons_pb()->set_buttonstate1( uButtons );
if ( Settings::Ragebot::AutoFire )
QAngle FinalAngles = Best.AimAngles;
if ( Settings::Ragebot::Smooth > 1 )
Math::SmoothAngles( ViewAngles , Best.AimAngles , FinalAngles , static_cast<float>( Settings::Ragebot::Smooth ) );
GetCL_Bypass()->SetViewAngles( &FinalAngles , pInput , pUserCmd );
const auto Now = std::chrono::steady_clock::now();
const bool bFireReady = ( Now - m_RageLastShotTime ) >= std::chrono::milliseconds( Settings::Ragebot::AutoFireDelay );
if ( Settings::Ragebot::AutoFire && bFireReady )
{
GetCL_Bypass()->SetAttack( pUserCmd , true );
m_RageLastShotTime = Now;
m_bRagebotFiring = true;
}
if ( Settings::Ragebot::DrawTarget )
{
m_bRagebotTargetValid = true;
m_vRagebotTargetPoint = Best.vAimPoint;
m_flRagebotTargetHealth = Best.flHealth;
}
}
static thread_local std::mt19937 g_TriggerRng( std::random_device{}() );
@@ -83,6 +83,11 @@ private:
std::atomic_bool m_bRagebotFiring = false;
bool m_bRagebotKeyDown = false;
bool m_bRagebotToggledOn = false;
std::chrono::steady_clock::time_point m_RageLastShotTime{};
bool m_bRagebotTargetValid = false;
Vector3 m_vRagebotTargetPoint{};
float m_flRagebotTargetHealth = 0.f;
};
auto GetMisc() -> CMisc*;
@@ -457,64 +457,120 @@ auto CAndromedaMenu::RenderRagebotPanel() -> void
Checkbox( "Enabled" , Settings::Ragebot::Active );
if ( Settings::Ragebot::Active )
if ( !Settings::Ragebot::Active )
return;
const char* RageModeItems[] =
{
const char* RageModeItems[] =
"Hold Key" , "Always" , "Toggle"
};
Combo( "Modus" , 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 )
{
"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;
}
iKeyIdx = i;
break;
}
}
if ( Combo( "Key" , iKeyIdx , RageKeyItems , IM_ARRAYSIZE( RageKeyItems ) ) )
Settings::Ragebot::Key = RageKeys[ iKeyIdx ];
if ( Combo( "Key" , iKeyIdx , RageKeyItems , IM_ARRAYSIZE( RageKeyItems ) ) )
Settings::Ragebot::Key = RageKeys[ iKeyIdx ];
const char* HitboxItems[] =
ImGui::SeparatorText( "Zielauswahl" );
const char* TargetModeItems[] =
{
"Fadenkreuz (FOV)" , "Entfernung" , "Niedrigste HP"
};
Combo( "Zielmodus" , Settings::Ragebot::TargetMode , TargetModeItems , IM_ARRAYSIZE( TargetModeItems ) );
SliderInt( "FOV (Grad)" , Settings::Ragebot::FOV , 1 , 180 );
SliderInt( "Max. Entfernung" , Settings::Ragebot::MaxDistance , 0 , 8192 , Settings::Ragebot::MaxDistance > 0 ? "%d u" : "%d (aus)" );
ImGui::SeparatorText( "Hitbox" );
const char* HitboxModeItems[] =
{
"Nächste zum Fadenkreuz" , "Bevorzugt" , "Beste Hitchance"
};
Combo( "Hitbox-Modus" , Settings::Ragebot::HitboxMode , HitboxModeItems , IM_ARRAYSIZE( HitboxModeItems ) );
if ( Settings::Ragebot::HitboxMode == 1 )
{
const char* PreferredHitboxItems[] =
{
"Head" , "Nearest" , "Chest" , "Stomach" , "Legs"
"Kopf" , "Hals" , "Brust" , "Bauch" , "Becken" , "Arme" , "Beine" , "Füße"
};
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 );
Combo( "Bevorzugte Hitbox" , Settings::Ragebot::PreferredHitbox , PreferredHitboxItems , IM_ARRAYSIZE( PreferredHitboxItems ) );
}
Checkbox( "Kopf" , Settings::Ragebot::Hitbox_Head );
Checkbox( "Hals" , Settings::Ragebot::Hitbox_Neck );
Checkbox( "Brust" , Settings::Ragebot::Hitbox_Chest );
Checkbox( "Bauch" , Settings::Ragebot::Hitbox_Stomach );
Checkbox( "Becken" , Settings::Ragebot::Hitbox_Pelvis );
Checkbox( "Arme" , Settings::Ragebot::Hitbox_Arms );
Checkbox( "Beine" , Settings::Ragebot::Hitbox_Legs );
Checkbox( "Füße" , Settings::Ragebot::Hitbox_Feet );
ImGui::SeparatorText( "Präzision" );
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 );
SliderInt( "Min. Schaden" , Settings::Ragebot::MinDamage , 0 , 200 , Settings::Ragebot::MinDamage > 0 ? "%d" : "%d (aus)" );
ImGui::SeparatorText( "Aim" );
SliderInt( "Smooth" , Settings::Ragebot::Smooth , 1 , 100 );
Checkbox( "NoSpread" , Settings::Ragebot::NoSpread );
Checkbox( "Recoil Control" , Settings::Ragebot::Recoil );
if ( Settings::Ragebot::Recoil )
SliderFloat( "Recoil Skalierung" , Settings::Ragebot::RecoilScale , 0.f , 5.f );
ImGui::SeparatorText( "Feuer" );
Checkbox( "Auto Fire" , Settings::Ragebot::AutoFire );
if ( Settings::Ragebot::AutoFire )
SliderInt( "Schussverzögerung (ms)" , Settings::Ragebot::AutoFireDelay , 0 , 500 );
Checkbox( "Auto Stop" , Settings::Ragebot::AutoStop );
Checkbox( "Auto Scope (Sniper)" , Settings::Ragebot::AutoScope );
Checkbox( "Auto Duck" , Settings::Ragebot::AutoCrouch );
ImGui::SeparatorText( "Sicherheit" );
Checkbox( "Teammates ignorieren" , Settings::Ragebot::IgnoreTeammates );
Checkbox( "Nur sichtbar" , Settings::Ragebot::VisibleOnly );
ImGui::SeparatorText( "Overlay" );
Checkbox( "FOV-Kreis" , Settings::Ragebot::DrawFov );
Checkbox( "Ziel markieren" , Settings::Ragebot::DrawTarget );
}
auto CAndromedaMenu::RenderConfigPanel() -> void
@@ -90,19 +90,53 @@ namespace Settings
}
namespace Ragebot
{
// --- Aktivierung ---
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
// --- Zielauswahl ---
inline auto TargetMode = 0; // 0 = Crosshair (FOV), 1 = Entfernung, 2 = Niedrigste HP
inline auto FOV = 10; // degrees
inline auto MaxDistance = 0; // 0 = aus, sonst Max-Reichweite in Units
// --- Hitbox ---
inline auto HitboxMode = 0; // 0 = Nächste zum Fadenkreuz, 1 = Bevorzugt, 2 = Beste Hitchance
inline auto PreferredHitbox = 0; // 0 = Head, 1 = Neck, 2 = Chest, 3 = Stomach, 4 = Pelvis, 5 = Arms, 6 = Legs, 7 = Feet
inline auto Hitbox_Head = true;
inline auto Hitbox_Neck = false;
inline auto Hitbox_Chest = true;
inline auto Hitbox_Stomach = true;
inline auto Hitbox_Pelvis = true;
inline auto Hitbox_Arms = false;
inline auto Hitbox_Legs = false;
inline auto Hitbox_Feet = false;
// --- Präzision ---
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 MinDamage = 0; // 0 = aus, sonst mind. Schaden
// --- Aim ---
inline auto Smooth = 1; // 1 = sofort, höher = langsamer/glatter
inline auto Recoil = true;
inline auto RecoilScale = 2.f; // 0 = aus, 1 = exakt, 2 = überschwingen
inline auto NoSpread = true;
// --- Feuer ---
inline auto AutoFire = true;
inline auto AutoFireDelay = 0; // ms zwischen Schüssen, 0 = sofort
inline auto AutoStop = true;
inline auto AutoScope = false; // Sniper automatisch zoomen
inline auto AutoCrouch = false; // Ducken beim Schießen
// --- Sicherheit ---
inline auto IgnoreTeammates = true;
inline auto VisibleOnly = true;
// --- Overlay ---
inline auto DrawFov = false; // FOV-Kreis ums Fadenkreuz
inline auto DrawTarget = true; // Ziel markieren
}
namespace Colors
{