diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj
index 62d939c..d849fa4 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj
@@ -241,9 +241,12 @@
+
+
+
@@ -451,9 +454,12 @@
+
+
+
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters
index c496531..05d47a4 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters
@@ -450,6 +450,15 @@
Andromeda-CS2-Base\AndromedaClient\Features
+
+ Andromeda-CS2-Base\GameClient
+
+
+ Andromeda-CS2-Base\GameClient
+
+
+ Andromeda-CS2-Base\GameClient
+
@@ -1076,5 +1085,14 @@
Andromeda-CS2-Base\Common
+
+ Andromeda-CS2-Base\GameClient
+
+
+ Andromeda-CS2-Base\GameClient
+
+
+ Andromeda-CS2-Base\GameClient
+
\ No newline at end of file
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/CAndromedaClient.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/CAndromedaClient.cpp
index 77fbb11..d220b68 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/CAndromedaClient.cpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/CAndromedaClient.cpp
@@ -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() );
}
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.cpp
index 197bf6a..fc4c220 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.cpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.cpp
@@ -8,6 +8,8 @@
#include
#include
+#include
+#include
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();
+
+ 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 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( pEntity );
+
+ CachedEntity.m_bVisible = GetCL_VisibleCheck()->IsPlayerControllerVisible( pCCSPlayerController );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
auto CVisual::CalculateBoundingBoxes() -> void
{
if ( !SDK::Interfaces::EngineToClient()->IsInGame() )
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.hpp
index bcd401e..2389fce 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.hpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.hpp
@@ -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:
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp
index a880cb5..5009db5 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp
@@ -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 };
+ }
+ }
}
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Bones.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Bones.cpp
new file mode 100644
index 0000000..fb9be4f
--- /dev/null
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Bones.cpp
@@ -0,0 +1,44 @@
+#include "CL_Bones.hpp"
+
+#include
+
+static CL_Bones g_CL_Bones{};
+
+std::vector 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;
+}
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Bones.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Bones.hpp
new file mode 100644
index 0000000..6abcdee
--- /dev/null
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Bones.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include
+#include
+
+#include
+
+class C_CSPlayerPawn;
+
+extern std::vector g_AllTraceVisibleCheckBones;
+
+class CL_Bones final
+{
+public:
+ auto GetBonePositionByName( C_CSPlayerPawn* pC_CSPlayerPawn , const char* szBoneName ) -> Vector3;
+};
+
+auto GetCL_Bones() -> CL_Bones*;
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.cpp
index 381229e..fff9371 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.cpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.cpp
@@ -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();
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.hpp
index 1eda7f6..5cc8393 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.hpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Players.hpp
@@ -13,6 +13,10 @@ public:
auto GetLocalPlayerController() -> CCSPlayerController*;
auto GetLocalPlayerPawn() -> C_CSPlayerPawn*;
+public:
+ auto GetLocalOrigin()->Vector3;
+ auto GetLocalEyeOrigin()->Vector3;
+
public:
auto IsLocalPlayerAlive() -> bool;
};
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.cpp
new file mode 100644
index 0000000..749c0cb
--- /dev/null
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.cpp
@@ -0,0 +1,90 @@
+#include "CL_Trace.hpp"
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+static CL_Trace g_CL_Trace{};
+
+auto CL_Trace::TraceToBoneEntity( CCSGOInput* pInput , const QAngle* AngleCorrection , QAngle* ViewAngleCorrection ) -> std::pair
+{
+ 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;
+}
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.hpp
new file mode 100644
index 0000000..b6bb3d0
--- /dev/null
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include
+#include
+
+#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;
+ auto TraceToEntityEndPos( const Vector3* vEnd ) -> C_BaseEntity*;
+};
+
+auto GetCL_Trace() -> CL_Trace*;
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_VisibleCheck.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_VisibleCheck.cpp
new file mode 100644
index 0000000..1e54539
--- /dev/null
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_VisibleCheck.cpp
@@ -0,0 +1,74 @@
+#include "CL_VisibleCheck.hpp"
+
+#include
+
+#include
+#include
+
+static CL_VisibleCheck g_CL_VisibleCheck{};
+
+auto CL_VisibleCheck::IsPlayerControllerVisible( CCSPlayerController* pCCSPlayerController ) -> bool
+{
+ auto Visible = false;
+
+ if ( pCCSPlayerController )
+ Visible = IsPlayerPawnVisible( pCCSPlayerController->m_hPawn().Get() );
+
+ 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;
+}
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_VisibleCheck.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_VisibleCheck.hpp
new file mode 100644
index 0000000..1b456dd
--- /dev/null
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_VisibleCheck.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include
+
+#include
+
+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*;