Files
marohook/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CVisual/CVisual.cpp
T
2025-11-03 18:38:47 +03:00

408 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "CVisual.hpp"
#include <CS2/SDK/SDK.hpp>
#include <CS2/SDK/Interface/IEngineToClient.hpp>
#include <AndromedaClient/Render/CRender.hpp>
#include <AndromedaClient/Render/CRenderStackSystem.hpp>
#include <AndromedaClient/Settings/Settings.hpp>
#include <GameClient/CEntityCache/CEntityCache.hpp>
#include <GameClient/CL_Players.hpp>
#include <GameClient/CL_VisibleCheck.hpp>
#include <GameClient/CL_Bones.hpp>
#include <CS2/SDK/Math/Math.hpp>
#include <CS2/SDK/Types/CEntityData.hpp>
#include <CS2/SDK/Types/Color.hpp>
static CVisual g_CVisual{};
auto CVisual::OnRender() -> void
{
if ( !Settings::Visual::Active )
return;
const auto& CachedVec = GetEntityCache()->GetCachedEntity();
std::scoped_lock Lock( GetEntityCache()->GetLock() );
for ( const 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 );
if ( CachedEntity.m_bDraw )
OnRenderPlayerEsp( pCCSPlayerController , CachedEntity.m_Bbox , CachedEntity.m_bVisible );
}
break;
}
}
}
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 ( Settings::Visual::OnlyVisible )
{
if ( bVisible )
Draw = true;
else
Draw = false;
}
if ( Draw )
{
if ( Settings::Visual::PlayerBox )
{
auto PlayerColor = ImColor( 255 , 255 , 255 );
if ( pCCSPlayerController->m_iTeamNum() == TEAM_TT )
{
PlayerColor = Settings::Colors::Visual::PlayerBoxTT;
if ( bVisible )
PlayerColor = Settings::Colors::Visual::PlayerBoxTT_Visible;
}
else if ( pCCSPlayerController->m_iTeamNum() == TEAM_CT )
{
PlayerColor = Settings::Colors::Visual::PlayerBoxCT;
if ( bVisible )
PlayerColor = Settings::Colors::Visual::PlayerBoxCT_Visible;
}
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 );
}
if ( Settings::Visual::BoneESP )
{
auto ShouldDrawBone = false;
if ( Settings::Visual::BoneESPTeam && !IsEnemy )
ShouldDrawBone = true;
if ( Settings::Visual::BoneESPEnemy && IsEnemy )
ShouldDrawBone = true;
if ( Settings::Visual::OnlyVisible && !bVisible )
ShouldDrawBone = false;
if ( ShouldDrawBone )
{
DrawBoneESP( pC_CSPlayerPawn , bVisible , pCCSPlayerController->m_iTeamNum() );
}
}
}
}
auto CVisual::ApplyGlow( C_CSPlayerPawn* pC_CSPlayerPawn , const bool bVisible , const int iTeamNum ) -> void
{
if ( !pC_CSPlayerPawn || !pC_CSPlayerPawn->IsPlayerPawn() )
return;
auto IsEnemy = false;
C_CSPlayerPawn* pLocalPawn = nullptr;
if ( auto* pLocalPlayerController = GetCL_Players()->GetLocalPlayerController(); pLocalPlayerController )
{
pLocalPawn = pLocalPlayerController->m_hPawn().Get<C_CSPlayerPawn>();
if ( pLocalPawn )
{
IsEnemy = iTeamNum != pLocalPawn->m_iTeamNum();
// Local player'dan glow'u kaldır
if ( pC_CSPlayerPawn == pLocalPawn )
{
auto& Glow = pC_CSPlayerPawn->m_Glow();
Glow.m_bGlowing() = false;
return;
}
}
}
auto DrawGlow = false;
if ( Settings::Visual::GlowTeam && !IsEnemy )
DrawGlow = true;
if ( Settings::Visual::GlowEnemy && IsEnemy )
DrawGlow = true;
if ( Settings::Visual::OnlyVisible && !bVisible )
DrawGlow = false;
if ( !DrawGlow )
{
// Glow'u kapat
auto& Glow = pC_CSPlayerPawn->m_Glow();
Glow.m_bGlowing() = false;
return;
}
auto GlowColor = Color( 255 , 255 , 255 , 255 );
if ( iTeamNum == TEAM_TT )
{
const auto& ColorVec = Settings::Colors::Visual::GlowTT;
if ( bVisible )
{
const auto& VisibleColorVec = Settings::Colors::Visual::GlowTT_Visible;
GlowColor = Color(
static_cast<BYTE>( VisibleColorVec.x * 255.f ) ,
static_cast<BYTE>( VisibleColorVec.y * 255.f ) ,
static_cast<BYTE>( VisibleColorVec.z * 255.f ) ,
static_cast<BYTE>( VisibleColorVec.w * 255.f )
);
}
else
{
GlowColor = Color(
static_cast<BYTE>( ColorVec.x * 255.f ) ,
static_cast<BYTE>( ColorVec.y * 255.f ) ,
static_cast<BYTE>( ColorVec.z * 255.f ) ,
static_cast<BYTE>( ColorVec.w * 255.f )
);
}
}
else if ( iTeamNum == TEAM_CT )
{
const auto& ColorVec = Settings::Colors::Visual::GlowCT;
if ( bVisible )
{
const auto& VisibleColorVec = Settings::Colors::Visual::GlowCT_Visible;
GlowColor = Color(
static_cast<BYTE>( VisibleColorVec.x * 255.f ) ,
static_cast<BYTE>( VisibleColorVec.y * 255.f ) ,
static_cast<BYTE>( VisibleColorVec.z * 255.f ) ,
static_cast<BYTE>( VisibleColorVec.w * 255.f )
);
}
else
{
GlowColor = Color(
static_cast<BYTE>( ColorVec.x * 255.f ) ,
static_cast<BYTE>( ColorVec.y * 255.f ) ,
static_cast<BYTE>( ColorVec.z * 255.f ) ,
static_cast<BYTE>( ColorVec.w * 255.f )
);
}
}
// Glow'u uygula
auto& Glow = pC_CSPlayerPawn->m_Glow();
Glow.m_bGlowing() = true;
Glow.m_glowColorOverride() = GlowColor;
}
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 );
if ( Settings::Visual::Glow && pCCSPlayerController->m_bPawnIsAlive() )
{
auto* pC_CSPlayerPawn = pCCSPlayerController->m_hPawn().Get<C_CSPlayerPawn>();
if ( pC_CSPlayerPawn && pC_CSPlayerPawn->IsPlayerPawn() )
{
ApplyGlow( pC_CSPlayerPawn , CachedEntity.m_bVisible , pCCSPlayerController->m_iTeamNum() );
}
}
}
break;
default:
break;
}
}
}
auto CVisual::CalculateBoundingBoxes() -> void
{
if ( !SDK::Interfaces::EngineToClient()->IsInGame() )
return;
const auto& CachedVec = GetEntityCache()->GetCachedEntity();
std::scoped_lock Lock( GetEntityCache()->GetLock() );
for ( auto& it : *CachedVec )
{
auto pEntity = it.m_Handle.Get();
if ( !pEntity )
continue;
auto hEntity = pEntity->pEntityIdentity()->Handle();
if ( hEntity != it.m_Handle )
continue;
switch ( it.m_Type )
{
case CachedEntity_t::PLAYER_CONTROLLER:
{
auto pPlayerController = reinterpret_cast<CCSPlayerController*>( pEntity );
auto pPlayerPawn = pPlayerController->m_hPawn().Get<C_CSPlayerPawn>();
if ( pPlayerPawn && pPlayerPawn->IsPlayerPawn() && pPlayerController->m_bPawnIsAlive() )
it.m_bDraw = pPlayerPawn->GetBoundingBox( it.m_Bbox );
}
break;
}
}
}
auto CVisual::DrawBoneESP( C_CSPlayerPawn* pC_CSPlayerPawn , const bool bVisible , const int iTeamNum ) -> void
{
if ( !pC_CSPlayerPawn || !pC_CSPlayerPawn->IsPlayerPawn() )
return;
auto BoneColor = ImColor( 255 , 255 , 255 );
if ( iTeamNum == TEAM_TT )
{
BoneColor = Settings::Colors::Visual::BoneESPTT;
if ( bVisible )
BoneColor = Settings::Colors::Visual::BoneESPTT_Visible;
}
else if ( iTeamNum == TEAM_CT )
{
BoneColor = Settings::Colors::Visual::BoneESPCT;
if ( bVisible )
BoneColor = Settings::Colors::Visual::BoneESPCT_Visible;
}
// Bone connections structure for CS2 skeleton
struct BoneConnection_t
{
const char* szFrom;
const char* szTo;
};
static const BoneConnection_t BoneConnections[] =
{
// Head to spine chain
{ "head_0" , "neck_0" },
{ "neck_0" , "spine_1" },
{ "spine_1" , "spine_2" },
{ "spine_2" , "spine_3" },
{ "spine_3" , "pelvis" },
// Left arm
{ "neck_0" , "clavicle_l" },
{ "clavicle_l" , "arm_upper_l" },
{ "arm_upper_l" , "arm_lower_l" },
{ "arm_lower_l" , "hand_l" },
// Right arm
{ "neck_0" , "clavicle_r" },
{ "clavicle_r" , "arm_upper_r" },
{ "arm_upper_r" , "arm_lower_r" },
{ "arm_lower_r" , "hand_r" },
// Left leg
{ "pelvis" , "leg_upper_l" },
{ "leg_upper_l" , "leg_lower_l" },
{ "leg_lower_l" , "ankle_l" },
// Right leg
{ "pelvis" , "leg_upper_r" },
{ "leg_upper_r" , "leg_lower_r" },
{ "leg_lower_r" , "ankle_r" },
};
for ( const auto& Connection : BoneConnections )
{
const Vector3 FromBone = GetCL_Bones()->GetBonePositionByName( pC_CSPlayerPawn , Connection.szFrom );
const Vector3 ToBone = GetCL_Bones()->GetBonePositionByName( pC_CSPlayerPawn , Connection.szTo );
if ( FromBone.IsZero() || ToBone.IsZero() )
continue;
ImVec2 FromScreen , ToScreen;
if ( Math::WorldToScreen( FromBone , FromScreen ) && Math::WorldToScreen( ToBone , ToScreen ) )
{
GetRenderStackSystem()->DrawLine( FromScreen , ToScreen , BoneColor , 1.5f );
}
}
}
auto GetVisual() -> CVisual*
{
return &g_CVisual;
}