add visible check, trace, bones, player box

This commit is contained in:
_or_75
2025-10-20 14:39:17 +03:00
parent 53a8270149
commit 19521e1d4c
14 changed files with 432 additions and 0 deletions
@@ -241,9 +241,12 @@
<ClCompile Include="Andromeda-CS2-Base\DllLauncher.cpp" />
<ClCompile Include="Andromeda-CS2-Base\DllMain.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CEntityCache\CEntityCache.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_Bones.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_Bypass.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_ItemDefinition.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_Players.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_Trace.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_VisibleCheck.cpp" />
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_Weapons.cpp" />
</ItemGroup>
<ItemGroup>
@@ -451,9 +454,12 @@
<ClInclude Include="Andromeda-CS2-Base\DllLauncher.hpp" />
<ClInclude Include="Andromeda-CS2-Base\DllMain.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CEntityCache\CEntityCache.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_Bones.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_Bypass.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_ItemDefinition.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_Players.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_Trace.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_VisibleCheck.hpp" />
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_Weapons.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
@@ -450,6 +450,15 @@
<ClCompile Include="Andromeda-CS2-Base\AndromedaClient\Features\CVisual\CVisual.cpp">
<Filter>Andromeda-CS2-Base\AndromedaClient\Features</Filter>
</ClCompile>
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_Bones.cpp">
<Filter>Andromeda-CS2-Base\GameClient</Filter>
</ClCompile>
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_Trace.cpp">
<Filter>Andromeda-CS2-Base\GameClient</Filter>
</ClCompile>
<ClCompile Include="Andromeda-CS2-Base\GameClient\CL_VisibleCheck.cpp">
<Filter>Andromeda-CS2-Base\GameClient</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Andromeda-CS2-Base\DllLauncher.hpp">
@@ -1076,5 +1085,14 @@
<ClInclude Include="Andromeda-CS2-Base\Common\Base64.h">
<Filter>Andromeda-CS2-Base\Common</Filter>
</ClInclude>
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_Bones.hpp">
<Filter>Andromeda-CS2-Base\GameClient</Filter>
</ClInclude>
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_Trace.hpp">
<Filter>Andromeda-CS2-Base\GameClient</Filter>
</ClInclude>
<ClInclude Include="Andromeda-CS2-Base\GameClient\CL_VisibleCheck.hpp">
<Filter>Andromeda-CS2-Base\GameClient</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -64,6 +64,8 @@ auto CAndromedaClient::OnClientOutput() -> void
auto CAndromedaClient::OnCreateMove( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
{
GetVisual()->OnCreateMove();
DEV_LOG( "%s\n" , pUserCmd->cmd.DebugString().c_str() );
}
@@ -8,6 +8,8 @@
#include <AndromedaClient/Settings/Settings.hpp>
#include <GameClient/CEntityCache/CEntityCache.hpp>
#include <GameClient/CL_Players.hpp>
#include <GameClient/CL_VisibleCheck.hpp>
static CVisual g_CVisual{};
@@ -48,7 +50,63 @@ auto CVisual::OnRender() -> void
auto CVisual::OnRenderPlayerEsp( CCSPlayerController* pCCSPlayerController , const Rect_t& bBox , const bool bVisible ) -> void
{
if ( !pCCSPlayerController->m_bPawnIsAlive() )
return;
auto* pC_CSPlayerPawn = pCCSPlayerController->m_hPawn().Get<C_CSPlayerPawn>();
if ( !pC_CSPlayerPawn || !pC_CSPlayerPawn->IsPlayerPawn() )
return;
auto IsEnemy = false;
if ( auto* pLocalPlayerController = GetCL_Players()->GetLocalPlayerController(); pLocalPlayerController )
IsEnemy = pCCSPlayerController->m_iTeamNum() != pLocalPlayerController->m_iTeamNum();
const ImVec2 min = { bBox.x, bBox.y };
const ImVec2 max = { bBox.w, bBox.h };
std::vector<std::string> PlayerItemIconList;
auto Draw = false;
if ( Settings::Visual::Team && !IsEnemy )
Draw = true;
if ( Settings::Visual::Enemy && IsEnemy )
Draw = true;
if ( Draw )
{
if ( Settings::Visual::PlayerBox )
{
auto PlayerColor = ImColor( 255 , 255 , 255 );
if ( pCCSPlayerController->m_iTeamNum() == TEAM_TT )
{
PlayerColor = ImColor( Settings::Colors::Visual::PlayerBoxTT[0] , Settings::Colors::Visual::PlayerBoxTT[1] , Settings::Colors::Visual::PlayerBoxTT[2] , Settings::Colors::Visual::PlayerBoxTT[3] );
if ( bVisible )
PlayerColor = ImColor( Settings::Colors::Visual::PlayerBoxTT_Visible[0] , Settings::Colors::Visual::PlayerBoxTT_Visible[1] , Settings::Colors::Visual::PlayerBoxTT_Visible[2] , Settings::Colors::Visual::PlayerBoxTT_Visible[3] );
}
else if ( pCCSPlayerController->m_iTeamNum() == TEAM_CT )
{
PlayerColor = ImColor( Settings::Colors::Visual::PlayerBoxCT[0] , Settings::Colors::Visual::PlayerBoxCT[1] , Settings::Colors::Visual::PlayerBoxCT[2] , Settings::Colors::Visual::PlayerBoxCT[3] );
if ( bVisible )
PlayerColor = ImColor( Settings::Colors::Visual::PlayerBoxCT_Visible[0] , Settings::Colors::Visual::PlayerBoxCT_Visible[1] , Settings::Colors::Visual::PlayerBoxCT_Visible[2] , Settings::Colors::Visual::PlayerBoxCT_Visible[3] );
}
if ( Settings::Visual::PlayerBoxType == EVisualBoxType_t::BOX )
GetRenderStackSystem()->DrawBox( min , max , PlayerColor );
else if ( Settings::Visual::PlayerBoxType == EVisualBoxType_t::OUTLINE_BOX )
GetRenderStackSystem()->DrawOutlineBox( min , max , PlayerColor );
else if ( Settings::Visual::PlayerBoxType == EVisualBoxType_t::COAL_BOX )
GetRenderStackSystem()->DrawCoalBox( min , max , PlayerColor );
else if ( Settings::Visual::PlayerBoxType == EVisualBoxType_t::OUTLINE_COAL_BOX )
GetRenderStackSystem()->DrawOutlineCoalBox( min , max , PlayerColor );
}
}
}
auto CVisual::OnClientOutput() -> void
@@ -56,6 +114,40 @@ auto CVisual::OnClientOutput() -> void
OnRender();
}
auto CVisual::OnCreateMove() -> void
{
if ( !Settings::Visual::Active )
return;
const auto CachedVec = GetEntityCache()->GetCachedEntity();
for ( auto& CachedEntity : *CachedVec )
{
auto pEntity = CachedEntity.m_Handle.Get();
if ( !pEntity )
continue;
auto hEntity = pEntity->pEntityIdentity()->Handle();
if ( hEntity != CachedEntity.m_Handle )
continue;
switch ( CachedEntity.m_Type )
{
case CachedEntity_t::PLAYER_CONTROLLER:
{
auto* pCCSPlayerController = reinterpret_cast<CCSPlayerController*>( pEntity );
CachedEntity.m_bVisible = GetCL_VisibleCheck()->IsPlayerControllerVisible( pCCSPlayerController );
}
break;
default:
break;
}
}
}
auto CVisual::CalculateBoundingBoxes() -> void
{
if ( !SDK::Interfaces::EngineToClient()->IsInGame() )
@@ -11,6 +11,7 @@ class IVisual
public:
virtual void OnRender() = 0;
virtual void OnClientOutput() = 0;
virtual void OnCreateMove() = 0;
};
class CVisual final : public IVisual
@@ -18,8 +19,18 @@ class CVisual final : public IVisual
public:
virtual void OnRender() override;
virtual void OnClientOutput() override;
virtual void OnCreateMove() override;
private:
enum EVisualBoxType_t : int32_t
{
BOX ,
OUTLINE_BOX ,
COAL_BOX ,
OUTLINE_COAL_BOX ,
CIRCLE_3D ,
};
auto OnRenderPlayerEsp( CCSPlayerController* pCCSPlayerController , const Rect_t& bBox , const bool bVisible ) -> void;
public:
@@ -7,11 +7,25 @@ namespace Settings
namespace Visual
{
inline auto Active = true;
inline auto Team = true;
inline auto Enemy = true;
inline auto PlayerBox = true;
inline auto PlayerBoxType = 3;
}
namespace Misc
{
inline auto MenuAlpha = 200;
inline auto MenuStyle = 0;
}
namespace Colors
{
namespace Visual
{
inline float PlayerBoxTT[4] = { 255.f / 255.f , 75.f / 255.f , 75.f / 255.f , 1.f };
inline float PlayerBoxTT_Visible[4] = { 0 , 1.f , 0.f , 1.f };
inline float PlayerBoxCT[4] = { 65.f / 255.f , 200 / 255.f , 255.f / 255.f , 1.f };
inline float PlayerBoxCT_Visible[4] = { 0 , 1.f , 0.f , 1.f };
}
}
}
@@ -0,0 +1,44 @@
#include "CL_Bones.hpp"
#include <CS2/SDK/Types/CEntityData.hpp>
static CL_Bones g_CL_Bones{};
std::vector<std::string> g_AllTraceVisibleCheckBones =
{
"head_0",
"pelvis",
"arm_lower_r",
"arm_lower_l",
"ankle_r",
"ankle_l",
};
auto CL_Bones::GetBonePositionByName( C_CSPlayerPawn* pC_CSPlayerPawn , const char* szBoneName ) -> Vector3
{
Vector3 BonePosition;
if ( auto* pSkeletonInstance = pC_CSPlayerPawn->m_pGameSceneNode()->GetSkeletonInstance(); pSkeletonInstance )
{
pSkeletonInstance->CalcWorldSpaceBones( FLAG_ALL_BONE_FLAGS );
const auto& Model = pSkeletonInstance->m_modelState().m_hModel();
if ( !Model.is_valid() )
return BonePosition;
const auto BoneIndex = pC_CSPlayerPawn->GetBoneIdByName( szBoneName );
if ( BoneIndex != -1 && pSkeletonInstance->GetBonePosition( BoneIndex , BonePosition ) )
return BonePosition;
else
DEV_LOG( "[error] GetBoneIdByName: %s\n" , szBoneName );
}
return BonePosition;
}
auto GetCL_Bones() -> CL_Bones*
{
return &g_CL_Bones;
}
@@ -0,0 +1,18 @@
#pragma once
#include <Common/Common.hpp>
#include <vector>
#include <CS2/SDK/Math/Vector3.hpp>
class C_CSPlayerPawn;
extern std::vector<std::string> g_AllTraceVisibleCheckBones;
class CL_Bones final
{
public:
auto GetBonePositionByName( C_CSPlayerPawn* pC_CSPlayerPawn , const char* szBoneName ) -> Vector3;
};
auto GetCL_Bones() -> CL_Bones*;
@@ -26,6 +26,26 @@ auto CL_Players::GetLocalPlayerPawn() -> C_CSPlayerPawn*
return nullptr;
}
auto CL_Players::GetLocalOrigin() -> Vector3
{
auto pLocalPlayerPawn = GetLocalPlayerPawn();
if ( pLocalPlayerPawn )
return pLocalPlayerPawn->GetOrigin();
return Vector3();
}
auto CL_Players::GetLocalEyeOrigin() -> Vector3
{
auto pLocalPlayerPawn = GetLocalPlayerPawn();
if ( pLocalPlayerPawn )
return GetLocalOrigin() + pLocalPlayerPawn->m_vecViewOffset();
return Vector3();
}
auto CL_Players::IsLocalPlayerAlive() -> bool
{
auto pLocalPlayerController = GetLocalPlayerController();
@@ -13,6 +13,10 @@ public:
auto GetLocalPlayerController() -> CCSPlayerController*;
auto GetLocalPlayerPawn() -> C_CSPlayerPawn*;
public:
auto GetLocalOrigin()->Vector3;
auto GetLocalEyeOrigin()->Vector3;
public:
auto IsLocalPlayerAlive() -> bool;
};
@@ -0,0 +1,90 @@
#include "CL_Trace.hpp"
#include <Fnv1a/Hash_Fnv1a_Constexpr.hpp>
#include <CS2/SDK/SDK.hpp>
#include <CS2/SDK/FunctionListSDK.hpp>
#include <CS2/SDK/Types/CEntityData.hpp>
#include <CS2/SDK/Update/GameTrace.hpp>
#include <CS2/SDK/Update/CCSGOInput.hpp>
#include <CS2/SDK/Math/Math.hpp>
#include <GameClient/CL_Players.hpp>
#include <GameClient/CL_Weapons.hpp>
#include <GameClient/CL_Bones.hpp>
static CL_Trace g_CL_Trace{};
auto CL_Trace::TraceToBoneEntity( CCSGOInput* pInput , const QAngle* AngleCorrection , QAngle* ViewAngleCorrection ) -> std::pair<uint64_t , C_BaseEntity*>
{
auto pLocalPlayerPawn = GetCL_Players()->GetLocalPlayerPawn();
if ( !pLocalPlayerPawn )
return { 0 , nullptr };
Vector3 vForward;
Ray_t Ray;
CGameTrace GameTrace;
CTraceFilter Filter( 0x1C1003 , pLocalPlayerPawn , 3 , 15 );
const auto vStart = GetCL_Players()->GetLocalEyeOrigin();
QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 );
if ( AngleCorrection )
ViewAngles += ( *AngleCorrection * 2.f );
if ( ViewAngleCorrection )
*ViewAngleCorrection = ViewAngles;
Math::AngleVectors( ViewAngles , vForward );
vForward *= 8192.f;
const auto vEnd = vStart + vForward;
if ( IGamePhysicsQuery_TraceShape( SDK::Pointers::CVPhys2World() , Ray , vStart , vEnd , &Filter , &GameTrace ) )
{
if ( GameTrace.pHitBox && GameTrace.pHitBox->szBoneName &&
hash_64_fnv1a_const( GameTrace.pHitBox->szBoneName ) != hash_64_fnv1a_const( "invalid_bone" ) )
{
//DEV_LOG( "Trace: %s\n" , GameTrace.pHitBox->szBoneName );
return { hash_64_fnv1a_const( GameTrace.pHitBox->szBoneName ) , GameTrace.pHitEntity };
}
}
return { 0 , nullptr };
}
auto CL_Trace::TraceToEntityEndPos( const Vector3* vEnd ) -> C_BaseEntity*
{
auto pLocalPlayerPawn = GetCL_Players()->GetLocalPlayerPawn();
if ( !pLocalPlayerPawn )
return nullptr;
Ray_t Ray;
CGameTrace GameTrace;
CTraceFilter Filter( 0x1C1003 , pLocalPlayerPawn , 3 , 15 );
const auto vStart = GetCL_Players()->GetLocalEyeOrigin();
if ( IGamePhysicsQuery_TraceShape( SDK::Pointers::CVPhys2World() , Ray , vStart , *vEnd , &Filter , &GameTrace ) )
{
if ( GameTrace.pHitBox && GameTrace.pHitEntity && GameTrace.pHitBox->szBoneName &&
hash_64_fnv1a_const( GameTrace.pHitBox->szBoneName ) != hash_64_fnv1a_const( "invalid_bone" ) )
{
return GameTrace.pHitEntity;
}
}
return nullptr;
}
auto GetCL_Trace() -> CL_Trace*
{
return &g_CL_Trace;
}
@@ -0,0 +1,21 @@
#pragma once
#include <Common/Common.hpp>
#include <CS2/SDK/Update/GameTrace.hpp>
#include "CL_Bones.hpp"
class QAngle;
class Vector3;
class CCSGOInput;
class C_BaseEntity;
class CL_Trace final
{
public:
auto TraceToBoneEntity( CCSGOInput* pInput , const QAngle* AngleCorrection , QAngle* ViewAngleCorrection ) -> std::pair<uint64_t , C_BaseEntity*>;
auto TraceToEntityEndPos( const Vector3* vEnd ) -> C_BaseEntity*;
};
auto GetCL_Trace() -> CL_Trace*;
@@ -0,0 +1,74 @@
#include "CL_VisibleCheck.hpp"
#include <CS2/SDK/Types/CEntityData.hpp>
#include <GameClient/CL_Bones.hpp>
#include <GameClient/CL_Trace.hpp>
static CL_VisibleCheck g_CL_VisibleCheck{};
auto CL_VisibleCheck::IsPlayerControllerVisible( CCSPlayerController* pCCSPlayerController ) -> bool
{
auto Visible = false;
if ( pCCSPlayerController )
Visible = IsPlayerPawnVisible( pCCSPlayerController->m_hPawn().Get<C_CSPlayerPawn>() );
return Visible;
}
auto CL_VisibleCheck::IsPlayerPawnVisible( C_CSPlayerPawn* pC_CSPlayerPawn ) -> bool
{
auto Visible = false;
if ( pC_CSPlayerPawn && pC_CSPlayerPawn->IsPlayerPawn() )
{
bool IsBoneVisible = false;
for ( const auto& BoneName : g_AllTraceVisibleCheckBones )
{
const Vector3 BonePos = GetCL_Bones()->GetBonePositionByName( pC_CSPlayerPawn , BoneName.c_str() );
if ( !BonePos.IsZero() )
{
const auto* pTracedEntity = GetCL_Trace()->TraceToEntityEndPos( &BonePos );
if ( pTracedEntity == pC_CSPlayerPawn )
IsBoneVisible = true;
else
continue;
}
else
{
IsBoneVisible = false;
}
}
Visible = IsBoneVisible;
}
return Visible;
}
auto CL_VisibleCheck::IsBoneVisible( C_CSPlayerPawn* pC_CSPlayerPawn , const Vector3& BonePos ) -> bool
{
auto Visible = false;
if ( pC_CSPlayerPawn && pC_CSPlayerPawn->IsPlayerPawn() )
{
if ( !BonePos.IsZero() )
{
const auto* pTracedEntity = GetCL_Trace()->TraceToEntityEndPos( &BonePos );
if ( pTracedEntity == pC_CSPlayerPawn )
Visible = true;
}
}
return Visible;
}
auto GetCL_VisibleCheck() -> CL_VisibleCheck*
{
return &g_CL_VisibleCheck;
}
@@ -0,0 +1,18 @@
#pragma once
#include <Common/Common.hpp>
#include <CS2/SDK/Math/Vector3.hpp>
class CCSPlayerController;
class C_CSPlayerPawn;
class CL_VisibleCheck final
{
public:
auto IsPlayerControllerVisible( CCSPlayerController* pCCSPlayerController ) -> bool;
auto IsPlayerPawnVisible( C_CSPlayerPawn* pC_CSPlayerPawn ) -> bool;
auto IsBoneVisible( C_CSPlayerPawn* pC_CSPlayerPawn , const Vector3& BonePos ) -> bool;
};
auto GetCL_VisibleCheck() -> CL_VisibleCheck*;