From 00f38439929b298356e0fccc706678f31382184f Mon Sep 17 00:00:00 2001 From: _or_75 Date: Fri, 8 May 2026 13:05:49 +0300 Subject: [PATCH] added changer --- Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj | 6 + .../Andromeda-CS2-Base.vcxproj.filters | 21 + .../AndromedaClient/CAndromedaClient.cpp | 5 +- .../CInventoryChanger/CInventoryChanger.cpp | 485 +++++++++++++ .../CInventoryChanger/CInventoryChanger.hpp | 151 ++++ .../CInventoryItemsManager.cpp | 607 ++++++++++++++++ .../CInventoryItemsManager.hpp | 123 ++++ .../Andromeda-CS2-Base/CS2/CHook_Loader.cpp | 4 +- .../CS2/Hook/Hook_EquipItemInLoadout.cpp | 10 + .../CS2/Hook/Hook_EquipItemInLoadout.hpp | 8 + .../CS2/Hook/Hook_SOCacheSubscribed.cpp | 3 +- .../CS2/SDK/CFunctionList.cpp | 1 + .../CS2/SDK/CFunctionList.hpp | 1 + .../CS2/SDK/Econ/CEconItemSchema.hpp | 5 + .../CS2/SDK/FunctionListSDK.hpp | 1 + .../CS2/SDK/Types/CEntityData.cpp | 8 +- .../CS2/SDK/Types/CEntityData.hpp | 18 +- .../CS2/SDK/Update/Offsets.hpp | 2 +- .../CS2/SDK/Update/VMT_Index.hpp | 4 +- SchemaDump.hpp | 675 +++++++++--------- 20 files changed, 1785 insertions(+), 353 deletions(-) create mode 100644 Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.cpp create mode 100644 Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.hpp create mode 100644 Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.cpp create mode 100644 Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.hpp create mode 100644 Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.cpp create mode 100644 Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.hpp diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj index 3b5c8d9..dc9ea70 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj @@ -138,6 +138,8 @@ + + @@ -163,6 +165,7 @@ + @@ -254,6 +257,8 @@ + + @@ -343,6 +348,7 @@ + diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters index 6fc4384..300209f 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base.vcxproj.filters @@ -121,6 +121,9 @@ {eafcd62e-e607-498c-8634-0be5feeec9ae} + + {fe55cde6-ca84-4245-b799-edaad8c9c80d} + @@ -465,6 +468,15 @@ Andromeda-CS2-Base\CS2\Hook + + Andromeda-CS2-Base\AndromedaClient\Features\CInventoryChanger + + + Andromeda-CS2-Base\AndromedaClient\Features\CInventoryChanger + + + Andromeda-CS2-Base\CS2\Hook + @@ -1109,5 +1121,14 @@ Andromeda-CS2-Base\CS2\Hook + + Andromeda-CS2-Base\AndromedaClient\Features\CInventoryChanger + + + Andromeda-CS2-Base\AndromedaClient\Features\CInventoryChanger + + + Andromeda-CS2-Base\CS2\Hook + \ 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 b9db1f0..3e3a6ac 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/CAndromedaClient.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/CAndromedaClient.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -22,12 +23,12 @@ auto CAndromedaClient::OnInit() -> void auto CAndromedaClient::OnFrameStageNotify( int FrameStage ) -> void { - + GetInventoryChanger()->OnFrameStageNotify( FrameStage ); } auto CAndromedaClient::OnFireEventClientSide( IGameEvent* pGameEvent ) -> void { - + GetInventoryChanger()->OnFireEventClientSide( pGameEvent ); } auto CAndromedaClient::OnAddEntity( CEntityInstance* pInst , CHandle handle ) -> void diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.cpp new file mode 100644 index 0000000..778cded --- /dev/null +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.cpp @@ -0,0 +1,485 @@ +#include "CInventoryChanger.hpp" + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +static CInventoryChanger g_CInventoryChanger{}; + +auto CInventoryChanger::OnFrameStageNotify( int FrameStage ) -> void +{ + if ( FrameStage != 6 || !SDK::Interfaces::EngineToClient()->IsInGame() ) + return; + + auto pLocalInventory = CCSPlayerInventory::Get(); + + if ( !pLocalInventory ) + return; + + const auto steamID = pLocalInventory->GetOwner().ID(); + const auto pLocalPlayerController = GetCL_Players()->GetLocalPlayerController(); + + if ( !pLocalPlayerController ) + return; + + auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn(); + + if ( !pLocalPawn ) + return; + + auto* pWeaponServices = pLocalPawn->m_pWeaponServices(); + + if ( !pWeaponServices ) + return; + + auto* pC_CS2HudModelWeapon = pLocalPawn->GetViewModel(); + + if ( !pC_CS2HudModelWeapon ) + return; + + for ( auto WeaponIndex = 0; WeaponIndex < pWeaponServices->m_hMyWeapons().Count(); ++WeaponIndex ) + { + const auto& Weapon = pWeaponServices->m_hMyWeapons()[WeaponIndex]; + + if ( !Weapon.IsValid() ) + continue; + + auto* pEntity = Weapon.Get(); + + if ( !pEntity || !pEntity->IsBasePlayerWeapon() ) + continue; + + auto pWeapon = reinterpret_cast( pEntity ); + + if ( pWeapon->GetOriginalOwnerXuid() != steamID ) + continue; + + auto pAttributeContainer = pWeapon->m_AttributeManager(); + + if ( !pAttributeContainer ) + continue; + + auto pWeaponItemView = pAttributeContainer->m_Item(); + + if ( !pWeaponItemView ) + continue; + + auto pWeaponDefinition = pWeaponItemView->GetStaticData(); + + if ( !pWeaponDefinition ) + continue; + + auto pWeaponSceneNode = pWeapon->m_pGameSceneNode(); + + if ( !pWeaponSceneNode ) + continue; + + int id = pAttributeContainer->m_Item()->m_iItemDefinitionIndex(); + + if ( id == 43 || id == 44 || id == 45 || id == 46 || id == 47 || id == 48 || id == 49 ) + continue; + + C_EconItemView* pWeaponInLoadoutItemView = nullptr; + + if ( pWeaponDefinition->IsWeapon() ) + { + for ( int i = 0; i < LOADOUT_SLOT_COUNT; ++i ) + { + auto pItemView = pLocalInventory->GetItemInLoadout( pWeapon->m_iOriginalTeamNumber() , i ); + + if ( !pItemView ) + continue; + + if ( pItemView->m_iItemDefinitionIndex() == pWeaponDefinition->m_nDefIndex() ) + { + pWeaponInLoadoutItemView = pItemView; + break; + } + } + } + else + { + pWeaponInLoadoutItemView = pLocalInventory->GetItemInLoadout( pWeapon->m_iOriginalTeamNumber() , pWeaponDefinition->LoadoutSlot() ); + } + + if ( !pWeaponInLoadoutItemView ) + continue; + + auto pWeaponInLoadoutDefinition = pWeaponInLoadoutItemView->GetStaticData(); + + if ( !pWeaponInLoadoutDefinition ) + continue; + + const auto isKnife = pWeaponInLoadoutDefinition->IsKnife( false ); + + if ( !isKnife && pWeaponInLoadoutDefinition->m_nDefIndex() != pWeaponDefinition->m_nDefIndex() ) + continue; + + pWeaponItemView->m_bDisallowSOC() = false; + pWeaponItemView->m_bRestoreCustomMaterialAfterPrecache() = true; + pWeaponItemView->m_iItemID() = pWeaponInLoadoutItemView->m_iItemID(); + pWeaponItemView->m_iItemIDHigh() = pWeaponInLoadoutItemView->m_iItemIDHigh(); + pWeaponItemView->m_iItemIDLow() = pWeaponInLoadoutItemView->m_iItemIDLow(); + pWeaponItemView->m_iItemDefinitionIndex() = pWeaponInLoadoutItemView->m_iItemDefinitionIndex(); + pWeaponItemView->m_iAccountID() = uint32_t( steamID ); + + pWeapon->m_nFallbackPaintKit() = pWeaponInLoadoutItemView->GetCustomPaintKitIndex(); + + C_EconItemView_set_attribute_value_by_name( pWeaponItemView , "set item texture prefab" , pWeaponInLoadoutItemView->GetCustomPaintKitIndex() ); + + const auto& AddedItems = GetInventoryItemsManager()->GetAddedItems(); + const auto& Skin = AddedItems.find( pWeaponInLoadoutItemView->m_iItemID() ); + + auto* pKnifeModel = pLocalPawn->GetKnifeModel(); + auto* pCompositeMaterial = reinterpret_cast( (PBYTE)pWeapon + g_CompositeMaterialOffset ); + + if ( pCompositeMaterial && m_ApplySkin.find( pCompositeMaterial ) == m_ApplySkin.end() ) + { + uint64_t meshGroupMask = 1; + + if ( Skin != AddedItems.end() ) + meshGroupMask = 1 + static_cast( Skin->second.m_bLegacyModel ); + + DEV_LOG( "meshGroupMask: %i\n" , meshGroupMask ); + + if ( isKnife ) + { + pWeapon->SetModel( pWeaponInLoadoutDefinition->m_pszModelName() ); + + if ( pKnifeModel ) + { + pKnifeModel->SetModel( pWeaponInLoadoutDefinition->m_pszModelName() ); + pKnifeModel->m_pGameSceneNode()->SetMeshGroupMask( meshGroupMask ); + pKnifeModel->m_pGameSceneNode()->PostDataUpdate(); + } + } + + pWeapon->m_pGameSceneNode()->SetMeshGroupMask( meshGroupMask ); + pC_CS2HudModelWeapon->m_pGameSceneNode()->SetMeshGroupMask( meshGroupMask ); + + std::uint32_t Hash = CUtlStringToken( std::to_string( pWeaponInLoadoutDefinition->m_nDefIndex() ).c_str() ).GetHashCode(); + + pWeapon->m_nSubclassID().SetHashCode( Hash ); + pWeapon->UpdateSubclass(); + + pWeapon->UpdateCompositeMaterial( pCompositeMaterial ); + pWeapon->UpdateSkin(); + pWeapon->m_pGameSceneNode()->PostDataUpdate(); + + auto* pCCSGO_HudWeaponSelection = CCSGOHudElement::Find( "HudWeaponSelection" ); + + if ( pCCSGO_HudWeaponSelection ) + { + pWeaponItemView->pCEconItemDescription() = 0; + + CCSGO_HudWeaponSelection_ClearHudWeaponIcon( + reinterpret_cast( + (uintptr_t)pCCSGO_HudWeaponSelection - 0x98 ) , 0 , 0 ); + } + + m_ApplySkin[pCompositeMaterial] = true; + } + } + + SetGlove( pLocalInventory , pLocalPawn , pC_CS2HudModelWeapon ); + SetAgent( pLocalInventory , pLocalPawn ); + SetMusic( pLocalInventory ); +} + +auto CInventoryChanger::OnEquipItemInLoadout( int iTeam , int iSlot , uint64_t iItemID ) -> void +{ + auto* pInventoryManager = CCSInventoryManager::Get(); + + if ( !pInventoryManager ) + return; + + auto* pPlayerInventory = CCSPlayerInventory::Get(); + + if ( !pPlayerInventory ) + return; + + const auto& AddedItems = GetInventoryItemsManager()->GetAddedItems(); + + if ( AddedItems.find( iItemID ) == AddedItems.end() ) + return; + + DEV_LOG( "OnEquipItemInLoadout: %i , %i , %lld\n" , iTeam , iSlot , iItemID ); + + EquipConfigItem( iTeam , iSlot , iItemID , true ); + + auto* pEconItemView = pPlayerInventory->GetItemViewForItem( iItemID ); + + if ( !pEconItemView ) + return; + + auto* pItemInLoadOut = pPlayerInventory->GetItemInLoadout( iTeam , iSlot ); + + if ( !pItemInLoadOut ) + return; + + auto* pItemInLoadoutStaticData = pItemInLoadOut->GetStaticData(); + + if ( !pItemInLoadoutStaticData ) + return; + + if ( pItemInLoadoutStaticData->IsGlove( false ) || + pItemInLoadoutStaticData->IsKnife( false ) || + pItemInLoadoutStaticData->IsAgent( false ) || + pItemInLoadoutStaticData->m_nDefIndex() == pEconItemView->m_iItemDefinitionIndex() ) + { + DEV_LOG( "Skin Cleared #1\n" ); + + // force glove + if ( pItemInLoadoutStaticData->IsGlove( false ) ) + m_bApplyGloves = true; + + // force skins and knife reaplly + if ( pItemInLoadoutStaticData->m_nDefIndex() == pEconItemView->m_iItemDefinitionIndex() || + pItemInLoadoutStaticData->IsKnife( false ) ) + { + m_ApplySkin.clear(); + + DEV_LOG( "Skin Cleared #2\n" ); + } + + return; + } + + const uint64_t defaultItemID = ( std::uint64_t( 0xF ) << 60 ) | pEconItemView->m_iItemDefinitionIndex(); + + pInventoryManager->EquipItemInLoadout( iTeam , iSlot , defaultItemID ); + + auto* pItemInLoadoutSOCData = pItemInLoadOut->GetSOCData(); + + if ( !pItemInLoadoutSOCData ) + return; + + pPlayerInventory->SOUpdated( pPlayerInventory->GetOwner() , (CSharedObject*)pItemInLoadoutSOCData , GCSDK::eSOCacheEvent_Incremental ); +} + +auto CInventoryChanger::OnFireEventClientSide( IGameEvent* pGameEvent ) -> void +{ + if ( _strcmpi( pGameEvent->GetName() , XorStr( "item_pickup" ) ) == 0 ) + { + if ( const auto* pItemPickupController = pGameEvent->GetPlayerController( XorStr( "userid" ) ); pItemPickupController ) + { + if ( pItemPickupController == GetCL_Players()->GetLocalPlayerController() ) + { + if ( _strcmpi( pGameEvent->GetString( "item" ) , XorStr( "defuser" ) ) == 0 ) + m_bApplyGloves = true; + } + } + } + + if ( _strcmpi( pGameEvent->GetName() , XorStr( "player_death" ) ) == 0 ) + { + if ( auto* pPlayerInventory = CCSPlayerInventory::Get(); pPlayerInventory ) + { + if ( auto* pLocalPlayerPawn = GetCL_Players()->GetLocalPlayerPawn(); pLocalPlayerPawn ) + { + if ( auto* pItemInLoadOut = pPlayerInventory->GetItemInLoadout( pLocalPlayerPawn->m_iTeamNum() , LOADOUT_SLOT_MELEE ); pItemInLoadOut ) + { + if ( auto* pItemInLoadoutStaticData = pItemInLoadOut->GetStaticData(); pItemInLoadoutStaticData ) + { + if ( const auto* pAttackerController = pGameEvent->GetPlayerController( XorStr( "attacker" ) ); pAttackerController ) + { + if ( GetCL_Weapons()->GetLocalWeaponType() == CSWeaponType_t::WEAPONTYPE_KNIFE ) + { + if ( auto* pLocalPlayerController = GetCL_Players()->GetLocalPlayerController(); pLocalPlayerController ) + { + if ( pAttackerController == pLocalPlayerController ) + { + const auto WeaponKillName = pGameEvent->GetString( "weapon" ); + + if ( !strcmp( WeaponKillName , "knife" ) ) + { + const auto szKnifeName = GetKnifeIconNameFromDefinitionIndex( pItemInLoadoutStaticData->m_nDefIndex() ); + + pGameEvent->SetString( "weapon" , szKnifeName ); + } + } + } + } + } + } + } + } + } + } +} + +auto CInventoryChanger::SetGlove( CCSPlayerInventory* pInventory , C_CSPlayerPawn* pLocalPawn , C_CS2HudModelWeapon* pViewModel ) -> void +{ + auto& pGloveItemView = pLocalPawn->m_EconGloves(); + auto* pItemViewLoadout = pInventory->GetItemInLoadout( pLocalPawn->m_iTeamNum() , LOADOUT_SLOT_CLOTHING_HANDS ); + + if ( !pItemViewLoadout ) + return; + + static std::uint8_t uUpdateFrames = 0U; + + if ( pLocalPawn->m_flLastSpawnTimeIndex().m_Value != m_flLastSpawnTime || m_bApplyGloves ) + { + uUpdateFrames = 3; + + { + pGloveItemView.m_bDisallowSOC() = false; + pGloveItemView.m_bRestoreCustomMaterialAfterPrecache() = true; + pGloveItemView.m_iItemDefinitionIndex() = pItemViewLoadout->m_iItemDefinitionIndex(); + pGloveItemView.m_iItemID() = pItemViewLoadout->m_iItemID(); + pGloveItemView.m_iItemIDHigh() = pItemViewLoadout->m_iItemIDHigh(); + pGloveItemView.m_iItemIDLow() = pItemViewLoadout->m_iItemIDLow(); + pGloveItemView.m_iAccountID() = pItemViewLoadout->m_iAccountID(); + } + + m_flLastSpawnTime = pLocalPawn->m_flLastSpawnTimeIndex().m_Value; + m_bApplyGloves = false; + } + + if ( uUpdateFrames > 0 ) + { + pGloveItemView.m_bInitialized() = true; + + pLocalPawn->SetBodyGroup(); + C_BaseEntity_UpdateBodyGroupChoice( pLocalPawn ); + pLocalPawn->m_bNeedToReApplyGloves() = true; + + uUpdateFrames--; + } +} + +auto CInventoryChanger::SetAgent( CCSPlayerInventory* pInventory , C_CSPlayerPawn* pLocalPawn ) -> void +{ + auto* pItemViewLoadout = pInventory->GetItemInLoadout( pLocalPawn->m_iTeamNum() , LOADOUT_SLOT_CLOTHING_CUSTOMPLAYER ); + + if ( !pItemViewLoadout ) + return; + + auto* pEconDefinition = pItemViewLoadout->GetStaticData(); + + if ( !pEconDefinition ) + return; + + if ( !pLocalPawn->m_pGameSceneNode() || !pLocalPawn->m_pGameSceneNode()->GetSkeletonInstance() ) + return; + + static uint64_t HashAgent = 0; + + const auto pModelName = pEconDefinition->m_pszModelName(); + + if ( pModelName ) + { + if ( hash_64_fnv1a_const( pModelName ) == HashAgent ) + return; + + HashAgent = hash_64_fnv1a_const( pModelName ); + + if ( strlen( pModelName ) > 0 ) + pLocalPawn->SetModel( pModelName ); + } +} + +auto CInventoryChanger::SetMusic( CCSPlayerInventory* pInventory ) -> void +{ + if ( auto* pLocalPlayerController = GetCL_Players()->GetLocalPlayerController(); pLocalPlayerController ) + { + if ( auto* pInventoryServices = pLocalPlayerController->m_pInventoryServices(); pInventoryServices ) + { + auto* pItemViewLoadout = pInventory->GetItemInLoadout( 0 , LOADOUT_SLOT_MUSICKIT ); + + if ( !pItemViewLoadout ) + return; + + auto* pEconDefinition = pItemViewLoadout->GetStaticData(); + + if ( !pEconDefinition ) + return; + + auto* pSOCData = pItemViewLoadout->GetSOCData(); + + if ( !pSOCData ) + return; + + static CSOEconItem g_CSOEconItem; + + pSOCData->SerializeToProtoBufItem( &g_CSOEconItem ); + + for ( auto AttributeIndex = 0; AttributeIndex < g_CSOEconItem.attribute_size(); AttributeIndex++ ) + { + const auto& Attribute = g_CSOEconItem.attribute( AttributeIndex ); + + if ( Attribute.has_def_index() && Attribute.has_value_bytes() && Attribute.def_index() == ATTRIBUTE_MUSIC_ID ) + { + pInventoryServices->m_unMusicID() = *(uint32_t*)( Attribute.value_bytes().data() ); + } + } + } + } +} + +auto CInventoryChanger::EquipConfigItem( int iTeam , int iSlot , uint64_t iItemID , bool Equipped ) -> void +{ + DEV_LOG( "EquipConfigItem: %i , %i , %lld , %i\n" , iTeam , iSlot , iItemID , Equipped ); + + for ( auto& EquipItem : m_vecEquipItems ) + { + if ( EquipItem.m_iTeam == iTeam && EquipItem.m_iSlot == iSlot ) + { + EquipItem.m_bEquipped = false; + } + } + + auto ItemHasAdded = false; + + for ( auto& EquipItem : m_vecEquipItems ) + { + if ( EquipItem.m_iItemID == iItemID ) + { + EquipItem.m_bEquipped = Equipped; + ItemHasAdded = true; + + break; + } + } + + if ( !ItemHasAdded ) + m_vecEquipItems.emplace_back( iTeam , iSlot , iItemID , Equipped ); + + if ( Equipped ) + EquipItemInLoadout_o( CCSInventoryManager::Get() , iTeam , iSlot , iItemID ); +} + +auto GetInventoryChanger() -> CInventoryChanger* +{ + return &g_CInventoryChanger; +} diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.hpp new file mode 100644 index 0000000..3bb8f3b --- /dev/null +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryChanger.hpp @@ -0,0 +1,151 @@ +#pragma once + +#include + +#include + +class C_CSWeaponBase; +class CCSPlayerInventory; +class C_CS2HudModelWeapon; +class C_CSPlayerPawn; +class IGameEvent; +class CCompositeMaterialOwner; + +enum LoadOutSlot_t +{ + LOADOUT_SLOT_C4 = 1 , + LOADOUT_SLOT_CLOTHING_APPEARANCE = 46 , + LOADOUT_SLOT_CLOTHING_CUSTOMPLAYER = 38 , + LOADOUT_SLOT_CLOTHING_EYEWEAR = 42 , + LOADOUT_SLOT_CLOTHING_FACEMASK = 40 , + LOADOUT_SLOT_CLOTHING_HANDS = 41 , + LOADOUT_SLOT_CLOTHING_HAT = 43 , + LOADOUT_SLOT_CLOTHING_LOWERBODY = 44 , + LOADOUT_SLOT_CLOTHING_TORSO = 45 , + LOADOUT_SLOT_COUNT = 57 , + LOADOUT_SLOT_EQUIPMENT0 = 32 , + LOADOUT_SLOT_EQUIPMENT1 = 33 , + LOADOUT_SLOT_EQUIPMENT2 = 34 , + LOADOUT_SLOT_EQUIPMENT3 = 35 , + LOADOUT_SLOT_EQUIPMENT4 = 36 , + LOADOUT_SLOT_EQUIPMENT5 = 37 , + LOADOUT_SLOT_FIRST_ALL_CHARACTER = 54 , + LOADOUT_SLOT_FIRST_AUTO_BUY_WEAPON = 0 , + LOADOUT_SLOT_FIRST_COSMETIC = 41 , + LOADOUT_SLOT_FIRST_PRIMARY_WEAPON = 8 , + LOADOUT_SLOT_FIRST_WHEEL_EQUIPMENT = 32 , + LOADOUT_SLOT_FIRST_WHEEL_GRENADE = 26 , + LOADOUT_SLOT_FIRST_WHEEL_WEAPON = 2 , + LOADOUT_SLOT_FLAIR0 = 55 , + LOADOUT_SLOT_GRENADE0 = 26 , + LOADOUT_SLOT_GRENADE1 = 27 , + LOADOUT_SLOT_GRENADE2 = 28 , + LOADOUT_SLOT_GRENADE3 = 29 , + LOADOUT_SLOT_GRENADE4 = 30 , + LOADOUT_SLOT_GRENADE5 = 31 , + LOADOUT_SLOT_HEAVY0 = 20 , + LOADOUT_SLOT_HEAVY1 = 21 , + LOADOUT_SLOT_HEAVY2 = 22 , + LOADOUT_SLOT_HEAVY3 = 23 , + LOADOUT_SLOT_HEAVY4 = 24 , + LOADOUT_SLOT_HEAVY5 = 25 , + LOADOUT_SLOT_INVALID = 4294967295 , + LOADOUT_SLOT_LAST_ALL_CHARACTER = 56 , + LOADOUT_SLOT_LAST_AUTO_BUY_WEAPON = 1 , + LOADOUT_SLOT_LAST_COSMETIC = 41 , + LOADOUT_SLOT_LAST_PRIMARY_WEAPON = 25 , + LOADOUT_SLOT_LAST_WHEEL_EQUIPMENT = 37 , + LOADOUT_SLOT_LAST_WHEEL_GRENADE = 31 , + LOADOUT_SLOT_LAST_WHEEL_WEAPON = 25 , + LOADOUT_SLOT_MELEE = 0 , + LOADOUT_SLOT_MISC0 = 47 , + LOADOUT_SLOT_MISC1 = 48 , + LOADOUT_SLOT_MISC2 = 49 , + LOADOUT_SLOT_MISC3 = 50 , + LOADOUT_SLOT_MISC4 = 51 , + LOADOUT_SLOT_MISC5 = 52 , + LOADOUT_SLOT_MISC6 = 53 , + LOADOUT_SLOT_MUSICKIT = 54 , + LOADOUT_SLOT_PET = 39 , + LOADOUT_SLOT_PROMOTED = 4294967295 , + LOADOUT_SLOT_RIFLE0 = 14 , + LOADOUT_SLOT_RIFLE1 = 15 , + LOADOUT_SLOT_RIFLE2 = 16 , + LOADOUT_SLOT_RIFLE3 = 17 , + LOADOUT_SLOT_RIFLE4 = 18 , + LOADOUT_SLOT_RIFLE5 = 19 , + LOADOUT_SLOT_SECONDARY0 = 2 , + LOADOUT_SLOT_SECONDARY1 = 3 , + LOADOUT_SLOT_SECONDARY2 = 4 , + LOADOUT_SLOT_SECONDARY3 = 5 , + LOADOUT_SLOT_SECONDARY4 = 6 , + LOADOUT_SLOT_SECONDARY5 = 7 , + LOADOUT_SLOT_SMG0 = 8 , + LOADOUT_SLOT_SMG1 = 9 , + LOADOUT_SLOT_SMG2 = 10 , + LOADOUT_SLOT_SMG3 = 11 , + LOADOUT_SLOT_SMG4 = 12 , + LOADOUT_SLOT_SMG5 = 13 , + LOADOUT_SLOT_SPRAY0 = 56 +}; + +class IInventoryChanger +{ +public: + virtual void OnFrameStageNotify( int FrameStage ) = 0; + virtual void OnEquipItemInLoadout( int iTeam , int iSlot , uint64_t iItemID ) = 0; + virtual void OnFireEventClientSide( IGameEvent* pGameEvent ) = 0; +}; + +class CInventoryChanger final : public IInventoryChanger +{ +public: + virtual void OnFrameStageNotify( int FrameStage ) override; + virtual void OnEquipItemInLoadout( int iTeam , int iSlot , uint64_t iItemID ) override; + virtual void OnFireEventClientSide( IGameEvent* pGameEvent ) override; + +public: + auto SetGlove( CCSPlayerInventory* pInventory , C_CSPlayerPawn* pLocalPawn , C_CS2HudModelWeapon* pViewModel ) -> void; + auto SetAgent( CCSPlayerInventory* pInventory , C_CSPlayerPawn* pLocalPawn ) -> void; + auto SetMusic( CCSPlayerInventory* pInventory ) -> void; + +public: + struct EquipItem_t + { + EquipItem_t() = default; + EquipItem_t(int team, int slot, uint64_t itemID, bool equipped) + : m_iTeam(team), m_iSlot(slot), m_iItemID(itemID), m_bEquipped(equipped) {} + + int m_iTeam = -1; + int m_iSlot = -1; + uint64_t m_iItemID = 0; + bool m_bEquipped = false; + }; + + using VecEquipItems_t = std::vector; + +public: + auto EquipConfigItem( int iTeam , int iSlot , uint64_t iItemID , bool Equipped = false ) -> void; + +public: + inline auto GetEquipConfigItems() -> VecEquipItems_t& + { + return m_vecEquipItems; + } + +public: + bool m_bApplyGloves = false; + + // Made public for CInventoryItemsManager access + std::unordered_map m_ApplySkin; + + // Refresh all skins (for periodic revalidation) + auto RefreshAllSkins() -> void { m_ApplySkin.clear(); } + +private: + VecEquipItems_t m_vecEquipItems; + float m_flLastSpawnTime = -1.f; + int m_nUpdateSkinFrame = 0; +}; + +auto GetInventoryChanger() -> CInventoryChanger*; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.cpp new file mode 100644 index 0000000..28bb687 --- /dev/null +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.cpp @@ -0,0 +1,607 @@ +#include "CInventoryItemsManager.hpp" + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +static CInventoryItemsManager g_CInventoryItemsManager{}; + +// Scan all available items WITHOUT adding them to inventory +auto CInventoryItemsManager::ScanAllItems() -> void +{ + auto* pItemSchema = SDK::Interfaces::Source2Client()->GetEconItemSystem()->GetEconItemSchema(); + auto* pPlayerInventory = CCSPlayerInventory::Get(); + + if ( !pItemSchema || !pPlayerInventory ) + return; + + static const std::string SkinIconPath = "panorama/images/econ/default_generated/"; + + const CUtlMap& vecItems = pItemSchema->GetSortedItemDefinitionMap(); + const CUtlMap& vecPaintKits = pItemSchema->GetPaintKits(); + const CUtlMap& vecMusicKit = pItemSchema->GetMusicKitDefinitions(); + + for ( const auto& it : vecItems ) + { + auto* pItem = it.m_value; + + if ( !pItem ) + continue; + + const bool isWeapon = pItem->IsWeapon(); + const bool isKnife = pItem->IsKnife( true ); + const bool isGlove = pItem->IsGlove( true ); + const bool isAgent = pItem->IsAgent( true ); + + if ( !isWeapon && !isKnife && !isGlove && !isAgent ) + continue; + + // Some items don't have names. + const char* itemBaseName = pItem->m_pszItemBaseName(); + + if ( !itemBaseName || itemBaseName[0] == '\0' ) + continue; + + const uint16_t defIdx = pItem->m_nDefIndex(); + + DumpedItem_t dumpedItem; + + dumpedItem.m_DefIdx = defIdx; + dumpedItem.m_Rarity = pItem->m_nItemRarity(); + + // Get human-readable name for UI + const char* localizedName = SDK::Interfaces::Localize()->FindSafe( itemBaseName ); + + if ( localizedName && localizedName[0] != '\0' && localizedName[0] != '#' ) + dumpedItem.m_DisplayName = localizedName; + else if ( itemBaseName && itemBaseName[0] != '\0' ) + dumpedItem.m_DisplayName = itemBaseName; + else + dumpedItem.m_DisplayName = "Unknown Item"; + + if ( isWeapon ) + dumpedItem.m_ItemType = DUMPED_ITEM_TYPE_WEAPON; + else if ( isKnife ) + dumpedItem.m_ItemType = DUMPED_ITEM_TYPE_KNIFE; + else if ( isGlove ) + dumpedItem.m_ItemType = DUMPED_ITEM_TYPE_GLOVE; + else if ( isAgent ) + dumpedItem.m_ItemType = DUMPED_ITEM_TYPE_AGENT; + + if ( strstr( SDK::Interfaces::Localize()->FindSafe( itemBaseName ) , XorStr( "#CSGO_CustomPlayer" ) ) ) + continue; + + if ( isKnife || isGlove || isAgent ) + dumpedItem.m_UnusualItem = true; + + if ( isAgent && strstr( itemBaseName , XorStr( "map_based" ) ) ) + continue; + + if ( isAgent ) + { + std::string IconPath = "panorama/images/econ/characters/"; + std::string SkinName = itemBaseName + 19; + + IconPath += "customplayer_"; + IconPath += SkinName; + IconPath += "_png.vtex_c"; + + if ( SDK::Interfaces::BaseFileSystem()->FileExists( IconPath.c_str() ) ) + { + dumpedItem.m_IconPath = IconPath; + dumpedItem.m_PaintKitName = SkinName; + } + } + + for ( const auto& paintIt : vecPaintKits ) + { + CPaintKit* pPaintKit = paintIt.m_value; + + if ( !pPaintKit || pPaintKit->nID == 0 || pPaintKit->nID == 9001 ) + continue; + + if ( strstr( pPaintKit->sName , XorStr( "doppler_phase2" ) ) || + strstr( pPaintKit->sName , XorStr( "doppler_phase3" ) ) || + strstr( pPaintKit->sName , XorStr( "doppler_phase4" ) ) ) + continue; + + bool hasValidIcon = false; + std::string IconPath; + + // Weapons + if ( !hasValidIcon ) + { + if ( std::string WeaponName = GetWeaponDescFromDefinitionIndex( dumpedItem.m_DefIdx ); WeaponName.size() ) + { + IconPath = SkinIconPath + WeaponName + "_" + std::string( pPaintKit->sName ) + "_light_png.vtex_c"; + + if ( SDK::Interfaces::BaseFileSystem()->FileExists( IconPath.c_str() ) ) + hasValidIcon = true; + } + } + + // Gloves + if ( !hasValidIcon ) + { + if ( std::string GloveName = GetGloveDescFromDefinitionIndex( dumpedItem.m_DefIdx ); GloveName.size() ) + { + IconPath = SkinIconPath + GloveName + "_" + std::string( pPaintKit->sName ) + "_light_png.vtex_c"; + + if ( SDK::Interfaces::BaseFileSystem()->FileExists( IconPath.c_str() ) ) + hasValidIcon = true; + } + } + + // Knifes + if ( !hasValidIcon ) + { + if ( std::string KnifeName = GetKnifeDescFromDefinitionIndex( dumpedItem.m_DefIdx ); KnifeName.size() ) + { + IconPath = SkinIconPath + KnifeName + "_" + std::string( pPaintKit->sName ) + "_light_png.vtex_c"; + + if ( SDK::Interfaces::BaseFileSystem()->FileExists( IconPath.c_str() ) ) + hasValidIcon = true; + } + } + + if ( hasValidIcon ) + { + DumpedSkin_t dumpedSkin; + + dumpedSkin.m_ID = pPaintKit->nID; + dumpedSkin.m_Rarity = pPaintKit->nRarity; + dumpedSkin.m_bLegacyModel = pPaintKit->m_use_legacy_model(); + dumpedSkin.m_PaintKitName = pPaintKit->sName; + + // Get skin name for UI + if ( pPaintKit->sDescriptionTag && pPaintKit->sDescriptionTag[0] != '\0' ) + { + const char* skinName = SDK::Interfaces::Localize()->FindSafe( pPaintKit->sDescriptionTag ); + + if ( skinName && skinName[0] != '\0' && skinName[0] != '#' ) + dumpedSkin.m_DisplayName = skinName; + else if ( pPaintKit->sName && pPaintKit->sName[0] != '\0' ) + dumpedSkin.m_DisplayName = pPaintKit->sName; + else + dumpedSkin.m_DisplayName = "Unknown Skin"; + } + else if ( pPaintKit->sName && pPaintKit->sName[0] != '\0' ) + { + dumpedSkin.m_DisplayName = pPaintKit->sName; + } + else + { + dumpedSkin.m_DisplayName = "Default"; + } + + dumpedSkin.m_IconPath = IconPath; + dumpedItem.m_DumpedSkins.emplace_back( dumpedSkin ); + } + } + + m_vecDumpedItems.emplace_back( dumpedItem ); + } + + // Music kits + for ( const auto& it : vecMusicKit ) + { + CMusicKit* pItem = it.m_value; + + if ( !pItem || pItem->nID == 1 || pItem->nID == 2 ) + continue; + + DumpedItem_t dumpedItem; + DumpedSkin_t dumpedSkin; + + dumpedItem.m_DefIdx = EInventoryPrefab_t::INVENTORY_PREFAB_MUSIC_KIT; + dumpedItem.m_ItemType = DUMPED_ITEM_TYPE_MUSIC; + dumpedItem.m_Rarity = 1; + dumpedItem.m_PaintKitName = pItem->sName; + + // Get music kit name + if ( pItem->sNameLocToken && pItem->sNameLocToken[0] != '\0' ) + { + const char* musicName = SDK::Interfaces::Localize()->FindSafe( pItem->sNameLocToken ); + + if ( musicName && musicName[0] != '\0' && musicName[0] != '#' ) + dumpedItem.m_DisplayName = musicName; + else if ( pItem->sName && pItem->sName[0] != '\0' ) + dumpedItem.m_DisplayName = pItem->sName; + else + dumpedItem.m_DisplayName = "Music Kit"; + } + else if ( pItem->sName && pItem->sName[0] != '\0' ) + { + dumpedItem.m_DisplayName = pItem->sName; + } + else + { + dumpedItem.m_DisplayName = "Music Kit"; + } + + std::string SkinPath = "panorama/images/"; + std::string IconPath = SkinPath + pItem->sInventoryImage; + + IconPath += "_png.vtex_c"; + + if ( SDK::Interfaces::BaseFileSystem()->FileExists( IconPath.c_str() ) ) + dumpedSkin.m_IconPath = IconPath; + + dumpedSkin.m_ID = pItem->nID; + dumpedSkin.m_Rarity = 1; + dumpedSkin.m_DisplayName = dumpedItem.m_DisplayName; + dumpedSkin.m_PaintKitName = dumpedItem.m_PaintKitName; + dumpedItem.m_DumpedSkins.emplace_back( dumpedSkin ); + + m_vecDumpedItems.emplace_back( dumpedItem ); + } +} + +// Legacy function - now scans items and loads selected skins from config +auto CInventoryItemsManager::OnAddAllItems() -> void +{ + ScanAllItems(); + + for ( auto& Item : m_vecDumpedItems ) + { + if ( Item.m_ItemType == EDumpedItemType_t::DUMPED_ITEM_TYPE_WEAPON || + Item.m_ItemType == EDumpedItemType_t::DUMPED_ITEM_TYPE_KNIFE || + Item.m_ItemType == EDumpedItemType_t::DUMPED_ITEM_TYPE_GLOVE ) + { + if ( Item.m_DumpedSkins.size() ) + { + for ( auto& Skin : Item.m_DumpedSkins ) + { + AddSelectedSkinToInventory( Item.m_DefIdx , Skin.m_ID , 0.0f , false , 0 , -1 ); + } + } + } + else if ( Item.m_ItemType == EDumpedItemType_t::DUMPED_ITEM_TYPE_AGENT ) + { + AddSelectedSkinToInventory( Item.m_DefIdx , 0 , 0.0f , false , 0 , -1 ); + } + else if ( Item.m_ItemType == EDumpedItemType_t::DUMPED_ITEM_TYPE_MUSIC ) + { + if ( Item.m_DumpedSkins.size() ) + { + for ( auto& Skin : Item.m_DumpedSkins ) + { + AddMusicToInventory( Item.m_DefIdx , Skin.m_ID ); + } + } + } + } +} + +// Add a specific skin to inventory +auto CInventoryItemsManager::AddSelectedSkinToInventory( uint16_t defIdx , int paintKit , float wear , bool equip , int seed , int statTrak ) -> bool +{ + auto* pCCSPlayerInventory = CCSPlayerInventory::Get(); + + if ( !pCCSPlayerInventory ) + return false; + + // Find the item in our scanned list + DumpedItem_t* pFoundItem = nullptr; + DumpedSkin_t* pFoundSkin = nullptr; + + for ( auto& item : m_vecDumpedItems ) + { + if ( item.m_DefIdx == defIdx ) + { + pFoundItem = &item; + + for ( auto& skin : item.m_DumpedSkins ) + { + if ( skin.m_ID == paintKit ) + { + pFoundSkin = &skin; + break; + } + } + + break; + } + } + + if ( !pFoundItem ) + return false; + + CEconItem* pItem = CEconItem::Create(); + + if ( !pItem ) + return false; + + auto highestIDs = pCCSPlayerInventory->GetHighestIDs(); + + pItem->m_ulID = highestIDs.first + 1; + pItem->m_unInventory = highestIDs.second + 1; + pItem->m_unAccountID = uint32_t( pCCSPlayerInventory->GetOwner().m_id ); + pItem->m_unDefIndex = defIdx; + + if ( pFoundItem->m_UnusualItem ) + pItem->m_nQuality = IQ_UNUSUAL; + + int skinRarity = pFoundSkin ? pFoundSkin->m_Rarity : 0; + pItem->m_nRarity = std::clamp( pFoundItem->m_Rarity + skinRarity - 1 , 0 , ( skinRarity == 7 ) ? 7 : 6 ); + + if ( paintKit ) + { + pItem->SetPaintKit( static_cast( paintKit ) ); + } + + // Set wear if specified + if ( wear > 0.0f ) + { + pItem->SetPaintWear( wear ); + } + + // Set seed if specified + if ( seed > 0 ) + { + pItem->SetPaintSeed( static_cast( seed ) ); + } + + // Set StatTrak if specified + if ( statTrak >= 0 ) + { + pItem->SetStatTrak( statTrak ); + } + + if ( pCCSPlayerInventory->AddEconItem( pItem ) ) + { + AddedItem_t Item; + + if( pFoundItem ) + { + Item.m_DefIdx = defIdx; + Item.m_PaintKit = paintKit; + Item.m_Rarity = pItem->m_nRarity; + Item.m_Wear = wear; + Item.m_UnusualItem = pFoundItem->m_UnusualItem; + Item.m_ItemType = pFoundItem->m_ItemType; + + if ( pFoundItem->m_ItemType == EDumpedItemType_t::DUMPED_ITEM_TYPE_AGENT ) + { + Item.m_bLegacyModel = false; + Item.m_PaintKitName = pFoundItem->m_PaintKitName; + Item.m_DisplayName = pFoundItem->m_DisplayName; + } + else + { + if ( pFoundSkin ) + { + Item.m_bLegacyModel = pFoundSkin->m_bLegacyModel; + Item.m_PaintKitName = pFoundSkin->m_PaintKitName; + Item.m_DisplayName = pFoundSkin->m_DisplayName; + } + } + + Item.m_pEconItem = pItem; + + m_AddedItems[pItem->m_ulID] = Item; + } + + // Auto-equip to loadout for both teams + auto* pInventoryManager = CCSInventoryManager::Get(); + + if ( pInventoryManager && pFoundItem ) + { + // Get item definition to find loadout slot + auto* pItemSchema = SDK::Interfaces::Source2Client()->GetEconItemSystem()->GetEconItemSchema(); + + if ( pItemSchema ) + { + // Find item definition from map + CEconItemDefinition* pItemDef = nullptr; + const auto& itemMap = pItemSchema->GetSortedItemDefinitionMap(); + + for ( const auto& it : itemMap ) + { + if ( it.m_value && it.m_value->m_nDefIndex() == defIdx ) + { + pItemDef = it.m_value; + break; + } + } + + if ( pItemDef ) + { + int loadoutSlot = pItemDef->LoadoutSlot(); + + if ( loadoutSlot >= 0 && equip ) + { + // Equip to T side (team 2) and CT side (team 3) + GetInventoryChanger()->OnEquipItemInLoadout( TEAM_TT , loadoutSlot , pItem->m_ulID ); + GetInventoryChanger()->OnEquipItemInLoadout( TEAM_CT , loadoutSlot , pItem->m_ulID ); + } + } + } + } + + DEV_LOG( "[Inventory] Added skin: DefIdx=%d, PaintKit=%d\n" , defIdx , paintKit ); + + return true; + } + + return false; +} + +auto CInventoryItemsManager::AddMusicToInventory( uint16_t defIdx , int MusicId , bool equip ) -> bool +{ + if ( auto* pCCSPlayerInventory = CCSPlayerInventory::Get(); pCCSPlayerInventory ) + { + // Find the item in our scanned list + DumpedItem_t* pFoundItem = nullptr; + DumpedSkin_t* pFoundSkin = nullptr; + + for ( auto& item : m_vecDumpedItems ) + { + if ( item.m_DefIdx == defIdx ) + { + pFoundItem = &item; + + for ( auto& skin : item.m_DumpedSkins ) + { + if ( skin.m_ID == MusicId ) + { + pFoundSkin = &skin; + break; + } + } + } + } + + if ( !pFoundItem || !pFoundSkin ) + return false; + + CEconItem* pItem = CEconItem::Create(); + + if ( pItem ) + { + auto highestIDs = pCCSPlayerInventory->GetHighestIDs(); + + pItem->m_ulID = highestIDs.first + 1; + pItem->m_unInventory = highestIDs.second + 1; + pItem->m_unAccountID = uint32_t( pCCSPlayerInventory->GetOwner().m_id ); + pItem->m_unDefIndex = EInventoryPrefab_t::INVENTORY_PREFAB_MUSIC_KIT; + + pItem->SetMusicId( MusicId ); + + if ( pCCSPlayerInventory->AddEconItem( pItem ) ) + { + AddedItem_t Item; + { + Item.m_DefIdx = EInventoryPrefab_t::INVENTORY_PREFAB_MUSIC_KIT; + Item.m_PaintKit = MusicId; + Item.m_Rarity = 1; + Item.m_UnusualItem = false; + Item.m_PaintKitName = pFoundSkin->m_PaintKitName; + Item.m_DisplayName = pFoundSkin->m_DisplayName; + Item.m_ItemType = DUMPED_ITEM_TYPE_MUSIC; + Item.m_pEconItem = pItem; + } + + m_AddedItems[pItem->m_ulID] = Item; + + if ( equip ) + { + // Equip to T side (team 2) and CT side (team 3) + GetInventoryChanger()->OnEquipItemInLoadout( 0 , LOADOUT_SLOT_MUSICKIT , pItem->m_ulID ); + } + + return true; + } + } + } + + return false; +} + +auto CInventoryItemsManager::RemoveItemFromInventoryByID( uint64_t ID ) -> bool +{ + if ( IsItemIDAdded( ID ) ) + { + if ( auto* pInventory = CCSPlayerInventory::Get(); pInventory ) + { + auto Item = m_AddedItems.find( ID ); + { + pInventory->RemoveEconItem( Item->second.m_pEconItem ); + } + + m_AddedItems.erase( ID ); + + return true; + } + } + + return false; +} + +auto CInventoryItemsManager::GetSkinName( int paintKitId ) -> std::string +{ + for ( const auto& item : m_vecDumpedItems ) + { + for ( const auto& skin : item.m_DumpedSkins ) + { + if ( skin.m_ID == paintKitId ) + return skin.m_DisplayName; + } + } + + return "Unknown"; +} + +auto CInventoryItemsManager::GetWeaponName( uint16_t defIdx ) -> std::string +{ + for ( const auto& item : m_vecDumpedItems ) + { + if ( item.m_DefIdx == defIdx ) + return item.m_DisplayName; + } + + return "Unknown"; +} + +auto CInventoryItemsManager::GetRarityName( int rarity ) -> std::string +{ + switch ( rarity ) + { + case 0: return "Common"; + case 1: return "Consumer Grade"; + case 2: return "Industrial Grade"; + case 3: return "Mil-Spec"; + case 4: return "Restricted"; + case 5: return "Classified"; + case 6: return "Covert"; + case 7: return "Contraband"; + case 99: return "Unsual"; + default: return "Common"; + } +} + +auto CInventoryItemsManager::GetRarityColor( int rarity ) -> ImU32 +{ + switch ( rarity ) + { + case 0: return ImColor( 77 , 116 , 85 ); + case 1: return ImColor( 176 , 195 , 217 ); + case 2: return ImColor( 94 , 152 , 217 ); + case 3: return ImColor( 75 , 105 , 255 ); + case 4: return ImColor( 136 , 71 , 255 ); + case 5: return ImColor( 211 , 44 , 230 ); + case 6: return ImColor( 235 , 75 , 75 ); + case 7: return ImColor( 207 , 106 , 50 ); + case 99: return ImColor( 255 , 215 , 0 ); + default: return ImColor( 222 , 214 , 204 ); + } +} + +auto GetInventoryItemsManager() -> CInventoryItemsManager* +{ + return &g_CInventoryItemsManager; +} diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.hpp new file mode 100644 index 0000000..49fe5bb --- /dev/null +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CInventoryChanger/CInventoryItemsManager.hpp @@ -0,0 +1,123 @@ +#pragma once + +#include +#include +#include +#include + +#include + +class CCSPlayerInventory; +class CEconItem; +struct ID3D11ShaderResourceView; + +class CInventoryItemsManager final +{ +public: + enum EInventoryPrefab_t : uint32_t + { + INVENTORY_PREFAB_MUSIC_KIT = 1314 , + INVENTORY_PREFAB_STICKER_KIT = 1209 , + }; + + enum EDumpedItemType_t + { + DUMPED_ITEM_TYPE_NONE , + DUMPED_ITEM_TYPE_WEAPON , + DUMPED_ITEM_TYPE_KNIFE , + DUMPED_ITEM_TYPE_GLOVE , + DUMPED_ITEM_TYPE_AGENT , + DUMPED_ITEM_TYPE_MUSIC, + }; + + // Made public for UI access + struct DumpedSkin_t + { + int m_ID = 0; + int m_Rarity = 0; + std::string m_PaintKitName = ""; + std::string m_DisplayName = ""; // Skin name for UI + std::string m_IconPath = ""; // Path to icon for UI + bool m_bLegacyModel = false; + }; + + struct DumpedItem_t + { + uint16_t m_DefIdx = 0; + int m_Rarity = 0; + bool m_UnusualItem = false; + std::vector m_DumpedSkins = {}; + EDumpedItemType_t m_ItemType = DUMPED_ITEM_TYPE_NONE; + std::string m_PaintKitName = ""; + std::string m_DisplayName = ""; // Item name for UI + std::string m_IconPath = ""; // Path to icon for UI + }; + + struct AddedItem_t + { + uint16_t m_DefIdx = 0; + int m_PaintKit = 0; + int m_Rarity = 0; + float m_Wear = 0.0f; + bool m_UnusualItem = false; + bool m_bLegacyModel = false; + std::string m_PaintKitName = ""; + std::string m_DisplayName = ""; // Skin/Item name for UI + EDumpedItemType_t m_ItemType = DUMPED_ITEM_TYPE_NONE; + CEconItem* m_pEconItem = nullptr; + }; + +private: + std::vector m_vecDumpedItems; + std::unordered_map m_AddedItems; + +public: + // Scan all available items (does NOT add to inventory) + auto ScanAllItems() -> void; + + // Legacy function - now calls ScanAllItems + applies selected skins from config + auto OnAddAllItems() -> void; + + // Add a specific selected skin to inventory + auto AddSelectedSkinToInventory( uint16_t defIdx , int paintKit , float wear = 0.0f , bool equip = false , int seed = 0 , int statTrak = -1 ) -> bool; + +public: + auto AddMusicToInventory( uint16_t defIdx , int MusicId , bool equip = false ) -> bool; + +public: + auto RemoveItemFromInventoryByID( uint64_t ID ) -> bool; + +public: + inline auto IsItemIDAdded( uint64_t ID ) -> bool + { + if ( m_AddedItems.find( ID ) == m_AddedItems.end() ) + return false; + + return true; + } + +public: + inline auto GetDumpedItems() -> std::vector& + { + return m_vecDumpedItems; + } + + inline auto GetAddedItems()->std::unordered_map& + { + return m_AddedItems; + } + + // Helper to get skin name from paint kit ID + auto GetSkinName( int paintKitId ) -> std::string; + + // Helper to get weapon name from def index + auto GetWeaponName( uint16_t defIdx ) -> std::string; + + // Helper to get rarity name + auto GetRarityName( int rarity ) -> std::string; + + // Helper to get rarity color + auto GetRarityColor( int rarity ) -> ImU32; +}; + +auto GetInventoryItemsManager() -> CInventoryItemsManager*; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/CHook_Loader.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/CHook_Loader.cpp index 9faee9a..76ea6b3 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/CHook_Loader.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/CHook_Loader.cpp @@ -22,6 +22,7 @@ #include #include #include +#include static CHook_Loader g_CHook_Loader{}; @@ -74,7 +75,8 @@ auto CHook_Loader::InstallSecondHook() -> bool // he is no longer needed //{ { XorStr( "Hook::UpdateInPVS" ) , XorStr( "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B D9 8B F2 48 8B 89 ? ? ? ? 48 8B 01 FF 50 ? 33 FF 48 85 C0 74 ? 48 8B 80 ? ? ? ? EB ? 48 8B C7 39 B8 ? ? ? ? 0F 8F ? ? ? ? 0F B6 48 ? 80 F9" ) , CLIENT_DLL } , &Hook_UpdateInPVS , reinterpret_cast( &UpdateInPVS_o ) }, { { XorStr( "Hook::AntiTamper" ) , XorStr( "40 53 41 57 48 83 EC ? 48 89 74 24 ? 48 8B F1" ) , CLIENT_DLL } , &Hook_AntiTamper , reinterpret_cast( &AntiTamper_o ) }, - { {XorStr("Hook::IsLoadoutAllowed") , XorStr("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B E9 48 8B 0D ? ? ? ? ? ? ? FF 50") , CLIENT_DLL } ,&Hook_IsLoadoutAllowed , reinterpret_cast(&IsLoadoutAllowed_o) , true , true } + { {XorStr("Hook::IsLoadoutAllowed") , XorStr("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B E9 48 8B 0D ? ? ? ? ? ? ? FF 50") , CLIENT_DLL } ,&Hook_IsLoadoutAllowed , reinterpret_cast(&IsLoadoutAllowed_o) , true , true } , + { { XorStr( "Hook::EquipItemInLoadout" ) , XorStr( "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 89 54 24 ? 57 41 54 41 55 41 56 41 57 48 83 EC ? 0F B7 FA" ) , CLIENT_DLL } ,& Hook_EquipItemInLoadout , reinterpret_cast( &EquipItemInLoadout_o ) }, }; return InstallHooks(); diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.cpp new file mode 100644 index 0000000..9f607bc --- /dev/null +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.cpp @@ -0,0 +1,10 @@ +#include "Hook_EquipItemInLoadout.hpp" + +#include + +auto Hook_EquipItemInLoadout( CCSInventoryManager* pManager , int iTeam , int iSlot , uint64_t iItemID ) -> void +{ + GetInventoryChanger()->OnEquipItemInLoadout( iTeam , iSlot , iItemID ); + + EquipItemInLoadout_o( pManager , iTeam , iSlot , iItemID ); +} diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.hpp new file mode 100644 index 0000000..33a1220 --- /dev/null +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_EquipItemInLoadout.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +using EquipItemInLoadout_t = void( __fastcall* )( CCSInventoryManager* , int , int , uint64_t ); +inline EquipItemInLoadout_t EquipItemInLoadout_o = nullptr; + +auto Hook_EquipItemInLoadout( CCSInventoryManager* pManager , int iTeam , int iSlot , uint64_t iItemID ) -> void; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_SOCacheSubscribed.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_SOCacheSubscribed.cpp index d271570..b61268b 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_SOCacheSubscribed.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/Hook/Hook_SOCacheSubscribed.cpp @@ -1,6 +1,7 @@ #include "Hook_SOCacheSubscribed.hpp" #include +#include auto Hook_SOCacheSubscribed( CCSPlayerInventory* pCSPlayerInventory , GCSDK::SOID_t owner , int64_t unk ) -> void* { @@ -8,7 +9,7 @@ auto Hook_SOCacheSubscribed( CCSPlayerInventory* pCSPlayerInventory , GCSDK::SOI if ( pCSPlayerInventory->GetOwner().m_type == owner.m_type && pCSPlayerInventory->GetOwner().m_id == owner.m_id ) { - + GetInventoryItemsManager()->OnAddAllItems(); } return pResult; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.cpp index 2cfffee..6e8fe29 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.cpp @@ -70,6 +70,7 @@ auto CFunctionList::OnInit() -> bool &CCSGO_HudWeaponSelection_ClearHudWeaponIcon, &C_BaseEntity_GetHitBoxSet, &C_BaseEntity_UpdateBodyGroupChoice, + &C_EconItemView_set_attribute_value_by_name, }; auto Searched = true; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.hpp index 7438485..1c1c47c 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/CFunctionList.hpp @@ -142,6 +142,7 @@ public: CBasePattern CCSGO_HudWeaponSelection_ClearHudWeaponIcon = { VmpStr( "CCSGO_HudWeaponSelection::ClearHudWeaponIcon" ) , VmpStr( "E8 ? ? ? ? 8B F8 C6 84 24" ) , CLIENT_DLL , 0 , SEARCH_TYPE_CALL }; CBasePattern C_BaseEntity_GetHitBoxSet = { VmpStr( "C_BaseEntity::GetHitBoxSet" ) , VmpStr( "48 89 5C 24 ? 48 89 74 24 ? 57 48 81 EC ? ? ? ? 8B DA 48 8B F9 E8 ? ? ? ? 48 8B F0" ) , CLIENT_DLL , 0 , SEARCH_TYPE_NONE }; CBasePattern C_BaseEntity_UpdateBodyGroupChoice = { VmpStr( "C_BaseEntity::UpdateBodyGroupChoice" ) , VmpStr( "E8 ? ? ? ? 4C 8B AC 24 ? ? ? ? 48 8B BC 24" ) , CLIENT_DLL , 0 , SEARCH_TYPE_CALL }; + CBasePattern C_EconItemView_set_attribute_value_by_name = { VmpStr( "C_EconItemView::set_attribute_value_by_name" ) , VmpStr( "E8 ? ? ? ? 66 41 0F 6E D4" ) , CLIENT_DLL , 0 , SEARCH_TYPE_CALL }; }; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Econ/CEconItemSchema.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Econ/CEconItemSchema.hpp index add7960..9997fa5 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Econ/CEconItemSchema.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Econ/CEconItemSchema.hpp @@ -21,6 +21,11 @@ public: char pad3[0x8]; // no idea char pad4[0x4]; // no idea int nRarity; + + uint8_t m_use_legacy_model() + { + return *reinterpret_cast( (std::uintptr_t)this + 0xAE ); + } }; class CMusicKit diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/FunctionListSDK.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/FunctionListSDK.hpp index 92933be..f61398d 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/FunctionListSDK.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/FunctionListSDK.hpp @@ -119,6 +119,7 @@ DECLARATE_CS2_FUNCTION_SDK_FASTCALL( void , CTraceFilter_Constructor , ( CTraceF DECLARATE_CS2_FUNCTION_SDK_FASTCALL( void , CCSGO_HudWeaponSelection_ClearHudWeaponIcon , ( CCSGO_HudWeaponSelection* pCCSGO_HudWeaponSelection , int unk1 , int64_t unk2 ) , ( CCSGO_HudWeaponSelection* , int , int64_t ) , ( pCCSGO_HudWeaponSelection , unk1 , unk2 ) ); DECLARATE_CS2_FUNCTION_SDK_FASTCALL( CHitBoxSet* , C_BaseEntity_GetHitBoxSet , ( C_BaseEntity* pC_BaseEntity , uint32_t Index = 0 ) , ( C_BaseEntity* , uint32_t ) , ( pC_BaseEntity , Index ) ); DECLARATE_CS2_FUNCTION_SDK_FASTCALL( void , C_BaseEntity_UpdateBodyGroupChoice , ( C_BaseEntity* pC_BaseEntity ) , ( C_BaseEntity* ) , ( pC_BaseEntity ) ); +DECLARATE_CS2_FUNCTION_SDK_FASTCALL( void , C_EconItemView_set_attribute_value_by_name , ( C_EconItemView* pC_EconItemView , const char* szAttributeName , float flValue ) , ( C_EconItemView* , const char* , float ) , ( pC_EconItemView , szAttributeName , flValue ) ); // Helpers: diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.cpp index 2321218..9e7e033 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.cpp @@ -183,8 +183,7 @@ auto C_BaseEntity::ComputeHitboxSurroundingBox( Vector3& mins , Vector3& maxs ) auto C_BaseEntity::SetBodyGroup() -> void { - C_BaseEntity_SetBodyGroup( this , m_iTeamNum() == TEAM_TT ? 0 : 1 , 1 ); - C_BaseEntity_UpdateBodyGroupChoice( this ); + return C_BaseEntity_SetBodyGroup( this , m_iTeamNum() == TEAM_TT ? 0 : 1 , 1 ); } auto C_BaseEntity::GetBoneIdByName( const char* szName ) -> int @@ -287,6 +286,11 @@ auto C_EconItemView::GetBasePlayerWeaponVData() -> CCSWeaponBaseVData* return C_EconItemView_GetBasePlayerWeaponVData( this ); } +auto C_EconItemView::GetCustomPaintKitIndex() -> int +{ + return C_EconItemView_GetCustomPaintKitIndex( this ); +} + auto C_BaseModelEntity::SetModel( const char* szModel ) -> void { return C_BaseModelEntity_SetModel( this , szModel ); diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.hpp index 34ceab0..2e35235 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Types/CEntityData.hpp @@ -113,13 +113,6 @@ public: return pBinding; } -public: - auto PostDataUpdate() -> void - { - VirtualFn( void )( CEntityInstance* , int UpdateType ); - return vget< Fn >( this , SDK::VMT_Index::CEntityInstance::PostDataUpdate )( this , 1 ); - } - public: SCHEMA_OFFSET( "CEntityInstance" , "m_pEntity" , pEntityIdentity , CEntityIdentity* ); }; @@ -148,6 +141,13 @@ public: auto SetMeshGroupMask( uint64_t meshGroupMask ) -> void; auto GetBonePosition( int32 BoneIndex , Vector3& BonePos ) -> bool; +public: + auto PostDataUpdate() -> void + { + VirtualFn( void )( CGameSceneNode* , int64_t UpdateType , int64_t unk1 ); + return vget< Fn >( this , SDK::VMT_Index::CGameSceneNode::PostDataUpdate )( this , 0 , 0 ); + } + public: auto GetSkeletonInstance() -> CSkeletonInstance* { @@ -190,6 +190,7 @@ public: auto GetSOCData() -> CEconItem*; auto GetStaticData() -> CEconItemDefinition*; auto GetBasePlayerWeaponVData() -> CCSWeaponBaseVData*; + auto GetCustomPaintKitIndex() -> int; public: SCHEMA_OFFSET( "C_EconItemView" , "m_bRestoreCustomMaterialAfterPrecache" , m_bRestoreCustomMaterialAfterPrecache , bool ); @@ -506,6 +507,9 @@ public: PSCHEMA_OFFSET( "C_EconEntity" , "m_AttributeManager" , m_AttributeManager , C_AttributeContainer ); SCHEMA_OFFSET( "C_EconEntity" , "m_OriginalOwnerXuidLow" , m_OriginalOwnerXuidLow , uint32 ); SCHEMA_OFFSET( "C_EconEntity" , "m_OriginalOwnerXuidHigh" , m_OriginalOwnerXuidHigh , uint32 ); + SCHEMA_OFFSET( "C_EconEntity" , "m_nFallbackPaintKit" , m_nFallbackPaintKit , int32 ); + SCHEMA_OFFSET( "C_EconEntity" , "m_nFallbackSeed" , m_nFallbackSeed , int32 ); + SCHEMA_OFFSET( "C_EconEntity" , "m_flFallbackWear" , m_flFallbackWear , float32 ); inline auto GetOriginalOwnerXuid() -> uint64_t { diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/Offsets.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/Offsets.hpp index 174d211..e7ee4a9 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/Offsets.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/Offsets.hpp @@ -11,7 +11,7 @@ static constexpr auto g_CompositeMaterialOffset = 0x608; // 48 8D 58 ? 49 89 4B static constexpr auto g_CEconItemSchema_GetSortedItemDefinitionMap = 0x128; -static constexpr auto g_CEconItemSchema_GetPaintKits = 0x2E8; +static constexpr auto g_CEconItemSchema_GetPaintKits = 0x2F0; // E8 ? ? ? ? 48 85 C0 74 ? 48 8B 40 ? 4C 8B C7 /* diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/VMT_Index.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/VMT_Index.hpp index 0329ee3..0b24866 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/VMT_Index.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/CS2/SDK/Update/VMT_Index.hpp @@ -11,8 +11,8 @@ namespace SDK::VMT_Index { GetScreenSize = 60 , }; - enum CEntityInstance : uint32_t + enum CGameSceneNode : uint32_t { - PostDataUpdate = 10 , + PostDataUpdate = 22 , }; } diff --git a/SchemaDump.hpp b/SchemaDump.hpp index 3d4efcc..703cb17 100644 --- a/SchemaDump.hpp +++ b/SchemaDump.hpp @@ -17523,98 +17523,98 @@ class CPlayer_FlashlightServices : public CPlayerPawnComponent // server }; class CCSPlayerController : public CBasePlayerController // server { - CCSPlayerController_InGameMoneyServices* m_pInGameMoneyServices; // 0x07D8 - CCSPlayerController_InventoryServices* m_pInventoryServices; // 0x07E0 - CCSPlayerController_ActionTrackingServices* m_pActionTrackingServices; // 0x07E8 - CCSPlayerController_DamageServices* m_pDamageServices; // 0x07F0 - uint32 m_iPing; // 0x07F8 - bool m_bHasCommunicationAbuseMute; // 0x07FC - uint32 m_uiCommunicationMuteFlags; // 0x0800 - CUtlSymbolLarge m_szCrosshairCodes; // 0x0808 - uint8 m_iPendingTeamNum; // 0x0810 - GameTime_t m_flForceTeamTime; // 0x0814 - int32 m_iCompTeammateColor; // 0x0818 - bool m_bEverPlayedOnTeam; // 0x081C - bool m_bAttemptedToGetColor; // 0x081D - int32 m_iTeammatePreferredColor; // 0x0820 - bool m_bTeamChanged; // 0x0824 - bool m_bInSwitchTeam; // 0x0825 - bool m_bHasSeenJoinGame; // 0x0826 - bool m_bJustBecameSpectator; // 0x0827 - bool m_bSwitchTeamsOnNextRoundReset; // 0x0828 - bool m_bRemoveAllItemsOnNextRoundReset; // 0x0829 - GameTime_t m_flLastJoinTeamTime; // 0x082C - CUtlSymbolLarge m_szClan; // 0x0830 - int32 m_iCoachingTeam; // 0x0838 - uint64 m_nPlayerDominated; // 0x0840 - uint64 m_nPlayerDominatingMe; // 0x0848 - int32 m_iCompetitiveRanking; // 0x0850 - int32 m_iCompetitiveWins; // 0x0854 - int8 m_iCompetitiveRankType; // 0x0858 - int32 m_iCompetitiveRankingPredicted_Win; // 0x085C - int32 m_iCompetitiveRankingPredicted_Loss; // 0x0860 - int32 m_iCompetitiveRankingPredicted_Tie; // 0x0864 - int32 m_nEndMatchNextMapVote; // 0x0868 - uint16 m_unActiveQuestId; // 0x086C - uint32 m_rtActiveMissionPeriod; // 0x0870 - QuestProgress::Reason m_nQuestProgressReason; // 0x0874 - uint32 m_unPlayerTvControlFlags; // 0x0878 - int32 m_iDraftIndex; // 0x08A8 - uint32 m_msQueuedModeDisconnectionTimestamp; // 0x08AC - uint32 m_uiAbandonRecordedReason; // 0x08B0 - uint32 m_eNetworkDisconnectionReason; // 0x08B4 - bool m_bCannotBeKicked; // 0x08B8 - bool m_bEverFullyConnected; // 0x08B9 - bool m_bAbandonAllowsSurrender; // 0x08BA - bool m_bAbandonOffersInstantSurrender; // 0x08BB - bool m_bDisconnection1MinWarningPrinted; // 0x08BC - bool m_bScoreReported; // 0x08BD - int32 m_nDisconnectionTick; // 0x08C0 - bool m_bControllingBot; // 0x08D0 - bool m_bHasControlledBotThisRound; // 0x08D1 - bool m_bHasBeenControlledByPlayerThisRound; // 0x08D2 - int32 m_nBotsControlledThisRound; // 0x08D4 - bool m_bCanControlObservedBot; // 0x08D8 - CHandle< CCSPlayerPawn > m_hPlayerPawn; // 0x08DC - CHandle< CCSObserverPawn > m_hObserverPawn; // 0x08E0 - int32 m_DesiredObserverMode; // 0x08E4 - CEntityHandle m_hDesiredObserverTarget; // 0x08E8 - bool m_bPawnIsAlive; // 0x08EC - uint32 m_iPawnHealth; // 0x08F0 - int32 m_iPawnArmor; // 0x08F4 - bool m_bPawnHasDefuser; // 0x08F8 - bool m_bPawnHasHelmet; // 0x08F9 - uint16 m_nPawnCharacterDefIndex; // 0x08FA - int32 m_iPawnLifetimeStart; // 0x08FC - int32 m_iPawnLifetimeEnd; // 0x0900 - int32 m_iPawnBotDifficulty; // 0x0904 - CHandle< CCSPlayerController > m_hOriginalControllerOfCurrentPawn; // 0x0908 - int32 m_iScore; // 0x090C - int32 m_iRoundScore; // 0x0910 - int32 m_iRoundsWon; // 0x0914 - uint8[8] m_recentKillQueue; // 0x0918 - uint8 m_nFirstKill; // 0x0920 - uint8 m_nKillCount; // 0x0921 - bool m_bMvpNoMusic; // 0x0922 - int32 m_eMvpReason; // 0x0924 - int32 m_iMusicKitID; // 0x0928 - int32 m_iMusicKitMVPs; // 0x092C - int32 m_iMVPs; // 0x0930 - int32 m_nUpdateCounter; // 0x0934 - float32 m_flSmoothedPing; // 0x0938 - IntervalTimer m_lastHeldVoteTimer; // 0x0940 - bool m_bShowHints; // 0x0958 - int32 m_iNextTimeCheck; // 0x095C - bool m_bJustDidTeamKill; // 0x0960 - bool m_bPunishForTeamKill; // 0x0961 - bool m_bGaveTeamDamageWarning; // 0x0962 - bool m_bGaveTeamDamageWarningThisRound; // 0x0963 - float64 m_dblLastReceivedPacketPlatFloatTime; // 0x0968 - GameTime_t m_LastTeamDamageWarningTime; // 0x0970 - GameTime_t m_LastTimePlayerWasDisconnectedForPawnsRemove; // 0x0974 - uint32 m_nSuspiciousHitCount; // 0x0978 - uint32 m_nNonSuspiciousHitStreak; // 0x097C - bool m_bFireBulletsSeedSynchronized; // 0x0A21 + CCSPlayerController_InGameMoneyServices* m_pInGameMoneyServices; // 0x07E0 + CCSPlayerController_InventoryServices* m_pInventoryServices; // 0x07E8 + CCSPlayerController_ActionTrackingServices* m_pActionTrackingServices; // 0x07F0 + CCSPlayerController_DamageServices* m_pDamageServices; // 0x07F8 + uint32 m_iPing; // 0x0800 + bool m_bHasCommunicationAbuseMute; // 0x0804 + uint32 m_uiCommunicationMuteFlags; // 0x0808 + CUtlSymbolLarge m_szCrosshairCodes; // 0x0810 + uint8 m_iPendingTeamNum; // 0x0818 + GameTime_t m_flForceTeamTime; // 0x081C + int32 m_iCompTeammateColor; // 0x0820 + bool m_bEverPlayedOnTeam; // 0x0824 + bool m_bAttemptedToGetColor; // 0x0825 + int32 m_iTeammatePreferredColor; // 0x0828 + bool m_bTeamChanged; // 0x082C + bool m_bInSwitchTeam; // 0x082D + bool m_bHasSeenJoinGame; // 0x082E + bool m_bJustBecameSpectator; // 0x082F + bool m_bSwitchTeamsOnNextRoundReset; // 0x0830 + bool m_bRemoveAllItemsOnNextRoundReset; // 0x0831 + GameTime_t m_flLastJoinTeamTime; // 0x0834 + CUtlSymbolLarge m_szClan; // 0x0838 + int32 m_iCoachingTeam; // 0x0840 + uint64 m_nPlayerDominated; // 0x0848 + uint64 m_nPlayerDominatingMe; // 0x0850 + int32 m_iCompetitiveRanking; // 0x0858 + int32 m_iCompetitiveWins; // 0x085C + int8 m_iCompetitiveRankType; // 0x0860 + int32 m_iCompetitiveRankingPredicted_Win; // 0x0864 + int32 m_iCompetitiveRankingPredicted_Loss; // 0x0868 + int32 m_iCompetitiveRankingPredicted_Tie; // 0x086C + int32 m_nEndMatchNextMapVote; // 0x0870 + uint16 m_unActiveQuestId; // 0x0874 + uint32 m_rtActiveMissionPeriod; // 0x0878 + QuestProgress::Reason m_nQuestProgressReason; // 0x087C + uint32 m_unPlayerTvControlFlags; // 0x0880 + int32 m_iDraftIndex; // 0x08B0 + uint32 m_msQueuedModeDisconnectionTimestamp; // 0x08B4 + uint32 m_uiAbandonRecordedReason; // 0x08B8 + uint32 m_eNetworkDisconnectionReason; // 0x08BC + bool m_bCannotBeKicked; // 0x08C0 + bool m_bEverFullyConnected; // 0x08C1 + bool m_bAbandonAllowsSurrender; // 0x08C2 + bool m_bAbandonOffersInstantSurrender; // 0x08C3 + bool m_bDisconnection1MinWarningPrinted; // 0x08C4 + bool m_bScoreReported; // 0x08C5 + int32 m_nDisconnectionTick; // 0x08C8 + bool m_bControllingBot; // 0x08D8 + bool m_bHasControlledBotThisRound; // 0x08D9 + bool m_bHasBeenControlledByPlayerThisRound; // 0x08DA + int32 m_nBotsControlledThisRound; // 0x08DC + bool m_bCanControlObservedBot; // 0x08E0 + CHandle< CCSPlayerPawn > m_hPlayerPawn; // 0x08E4 + CHandle< CCSObserverPawn > m_hObserverPawn; // 0x08E8 + int32 m_DesiredObserverMode; // 0x08EC + CEntityHandle m_hDesiredObserverTarget; // 0x08F0 + bool m_bPawnIsAlive; // 0x08F4 + uint32 m_iPawnHealth; // 0x08F8 + int32 m_iPawnArmor; // 0x08FC + bool m_bPawnHasDefuser; // 0x0900 + bool m_bPawnHasHelmet; // 0x0901 + uint16 m_nPawnCharacterDefIndex; // 0x0902 + int32 m_iPawnLifetimeStart; // 0x0904 + int32 m_iPawnLifetimeEnd; // 0x0908 + int32 m_iPawnBotDifficulty; // 0x090C + CHandle< CCSPlayerController > m_hOriginalControllerOfCurrentPawn; // 0x0910 + int32 m_iScore; // 0x0914 + int32 m_iRoundScore; // 0x0918 + int32 m_iRoundsWon; // 0x091C + uint8[8] m_recentKillQueue; // 0x0920 + uint8 m_nFirstKill; // 0x0928 + uint8 m_nKillCount; // 0x0929 + bool m_bMvpNoMusic; // 0x092A + int32 m_eMvpReason; // 0x092C + int32 m_iMusicKitID; // 0x0930 + int32 m_iMusicKitMVPs; // 0x0934 + int32 m_iMVPs; // 0x0938 + int32 m_nUpdateCounter; // 0x093C + float32 m_flSmoothedPing; // 0x0940 + IntervalTimer m_lastHeldVoteTimer; // 0x0948 + bool m_bShowHints; // 0x0960 + int32 m_iNextTimeCheck; // 0x0964 + bool m_bJustDidTeamKill; // 0x0968 + bool m_bPunishForTeamKill; // 0x0969 + bool m_bGaveTeamDamageWarning; // 0x096A + bool m_bGaveTeamDamageWarningThisRound; // 0x096B + float64 m_dblLastReceivedPacketPlatFloatTime; // 0x0970 + GameTime_t m_LastTeamDamageWarningTime; // 0x0978 + GameTime_t m_LastTimePlayerWasDisconnectedForPawnsRemove; // 0x097C + uint32 m_nSuspiciousHitCount; // 0x0980 + uint32 m_nNonSuspiciousHitStreak; // 0x0984 + bool m_bFireBulletsSeedSynchronized; // 0x0A29 }; class CPhysLength : public CPhysConstraint // server { @@ -17730,58 +17730,58 @@ class CEnvShake : public CPointEntity // server }; class CCSPlayer_MovementServices : public CPlayer_MovementServices_Humanoid // server { - CCSPlayerAnimationState m_AnimationState; // 0x02E0 - Vector m_vecLadderNormal; // 0x03C0 - int32 m_nLadderSurfacePropIndex; // 0x03CC - bool m_bDucked; // 0x03D0 - float32 m_flDuckAmount; // 0x03D4 - float32 m_flDuckSpeed; // 0x03D8 - bool m_bDuckOverride; // 0x03DC - bool m_bDesiresDuck; // 0x03DD - bool m_bDucking; // 0x03DE - float32 m_flDuckRootOffset; // 0x03E0 - float32 m_flDuckViewOffset; // 0x03E4 - float32 m_flLastDuckTime; // 0x03E8 - float32 m_flBombPlantViewOffset; // 0x03EC - Vector2D m_vecLastPositionAtFullCrouchSpeed; // 0x03F8 - bool m_duckUntilOnGround; // 0x0400 - bool m_bHasWalkMovedSinceLastJump; // 0x0401 - bool m_bInStuckTest; // 0x0402 - int32 m_nTraceCount; // 0x0610 - int32 m_StuckLast; // 0x0614 - bool m_bSpeedCropped; // 0x0618 - int32 m_nOldWaterLevel; // 0x061C - float32 m_flWaterEntryTime; // 0x0620 - Vector m_vecForward; // 0x0624 - Vector m_vecLeft; // 0x0630 - Vector m_vecUp; // 0x063C - int32 m_nGameCodeHasMovedPlayerAfterCommand; // 0x0648 - bool m_bMadeFootstepNoise; // 0x064C - int32 m_iFootsteps; // 0x0650 - GameTime_t m_fStashGrenadeParameterWhen; // 0x0654 - uint64 m_nButtonDownMaskPrev; // 0x0658 - bool m_bUseFrictionStashedSpeed; // 0x0660 - float32 m_flUseFrictionStashedSpeedUntilFrac; // 0x0664 - float32 m_flFrictionStashedSpeed; // 0x0668 - float32 m_flStamina; // 0x066C - float32 m_flHeightAtJumpStart; // 0x0670 - float32 m_flMaxJumpHeightThisJump; // 0x0674 - float32 m_flMaxJumpHeightLastJump; // 0x0678 - float32 m_flStaminaAtJumpStart; // 0x067C - float32 m_flVelMulAtJumpStart; // 0x0680 - float32 m_flAccumulatedJumpError; // 0x0684 - CCSPlayerLegacyJump m_LegacyJump; // 0x0688 - CCSPlayerModernJump m_ModernJump; // 0x06A0 - GameTick_t m_nLastJumpTick; // 0x06D8 - float32 m_flLastJumpFrac; // 0x06DC - float32 m_flLastJumpVelocityZ; // 0x06E0 - bool m_bJumpApexPending; // 0x06E4 - float32 m_flTicksSinceLastSurfingDetected; // 0x06E8 - bool m_bWasSurfing; // 0x06EC - Vector2D m_vecWalkWishVel; // 0x077C - GameTime_t m_gtLastTimeOnStaticWorldGround; // 0x0FA8 - GameTime_t m_gtLastTimeInAir; // 0x0FAC - bool m_bHasEverProcessedCommand; // 0x0FB0 + CCSPlayerAnimationState m_AnimationState; // 0x0310 + bool m_bUsingGroundTopologyOffset; // 0x03F0 + float32 m_flUsingGroundTopologyOffsetTransitionSmoothing; // 0x03F4 + Vector m_vecLadderNormal; // 0x03F8 + int32 m_nLadderSurfacePropIndex; // 0x0404 + bool m_bDucked; // 0x0408 + float32 m_flDuckAmount; // 0x040C + float32 m_flDuckSpeed; // 0x0410 + bool m_bDuckOverride; // 0x0414 + bool m_bDesiresDuck; // 0x0415 + bool m_bDucking; // 0x0416 + float32 m_flDuckRootOffset; // 0x0418 + float32 m_flDuckViewOffset; // 0x041C + float32 m_flLastDuckTime; // 0x0420 + float32 m_flBombPlantViewOffset; // 0x0424 + Vector2D m_vecLastPositionAtFullCrouchSpeed; // 0x0430 + bool m_duckUntilOnGround; // 0x0438 + bool m_bHasWalkMovedSinceLastJump; // 0x0439 + bool m_bInStuckTest; // 0x043A + int32 m_nTraceCount; // 0x0648 + int32 m_StuckLast; // 0x064C + bool m_bSpeedCropped; // 0x0650 + int32 m_nOldWaterLevel; // 0x0654 + float32 m_flWaterEntryTime; // 0x0658 + Vector m_vecForward; // 0x065C + Vector m_vecLeft; // 0x0668 + Vector m_vecUp; // 0x0674 + int32 m_nGameCodeHasMovedPlayerAfterCommand; // 0x0680 + bool m_bMadeFootstepNoise; // 0x0684 + int32 m_iFootsteps; // 0x0688 + GameTime_t m_fStashGrenadeParameterWhen; // 0x068C + uint64 m_nButtonDownMaskPrev; // 0x0690 + bool m_bUseFrictionStashedSpeed; // 0x0698 + float32 m_flUseFrictionStashedSpeedUntilFrac; // 0x069C + float32 m_flFrictionStashedSpeed; // 0x06A0 + float32 m_flStamina; // 0x06A4 + float32 m_flHeightAtJumpStart; // 0x06A8 + float32 m_flMaxJumpHeightThisJump; // 0x06AC + float32 m_flMaxJumpHeightLastJump; // 0x06B0 + float32 m_flStaminaAtJumpStart; // 0x06B4 + float32 m_flVelMulAtJumpStart; // 0x06B8 + float32 m_flAccumulatedJumpError; // 0x06BC + CCSPlayerLegacyJump m_LegacyJump; // 0x06C0 + CCSPlayerModernJump m_ModernJump; // 0x06D8 + GameTick_t m_nLastJumpTick; // 0x0710 + float32 m_flLastJumpFrac; // 0x0714 + float32 m_flLastJumpVelocityZ; // 0x0718 + bool m_bJumpApexPending; // 0x071C + float32 m_flTicksSinceLastSurfingDetected; // 0x0720 + bool m_bWasSurfing; // 0x0724 + Vector2D m_vecWalkWishVel; // 0x07B4 + bool m_bHasEverProcessedCommand; // 0x0FE0 }; class SellbackPurchaseEntry_t // server { @@ -21617,21 +21617,22 @@ class CBasePlayerController : public CBaseEntity // server CUtlVector< CHandle< CBasePlayerController > > m_hSplitScreenPlayers; // 0x04F0 bool m_bIsHLTV; // 0x0508 PlayerConnectedState m_iConnected; // 0x050C - char[128] m_iszPlayerName; // 0x0510 - CUtlString m_szNetworkIDString; // 0x0590 - float32 m_fLerpTime; // 0x0598 - bool m_bLagCompensation; // 0x059C - bool m_bPredict; // 0x059D - bool m_bIsLowViolence; // 0x05A4 - bool m_bGamePaused; // 0x05A5 - ChatIgnoreType_t m_iIgnoreGlobalChat; // 0x06E0 - float32 m_flLastPlayerTalkTime; // 0x06E4 - float32 m_flLastEntitySteadyState; // 0x06E8 - int32 m_nAvailableEntitySteadyState; // 0x06EC - bool m_bHasAnySteadyStateEnts; // 0x06F0 - uint64 m_steamID; // 0x0700 - bool m_bNoClipEnabled; // 0x0708 - uint32 m_iDesiredFOV; // 0x070C + PlayerConnectedState m_iMostConnected; // 0x0510 + char[128] m_iszPlayerName; // 0x0514 + CUtlString m_szNetworkIDString; // 0x0598 + float32 m_fLerpTime; // 0x05A0 + bool m_bLagCompensation; // 0x05A4 + bool m_bPredict; // 0x05A5 + bool m_bIsLowViolence; // 0x05AC + bool m_bGamePaused; // 0x05AD + ChatIgnoreType_t m_iIgnoreGlobalChat; // 0x06E8 + float32 m_flLastPlayerTalkTime; // 0x06EC + float32 m_flLastEntitySteadyState; // 0x06F0 + int32 m_nAvailableEntitySteadyState; // 0x06F4 + bool m_bHasAnySteadyStateEnts; // 0x06F8 + uint64 m_steamID; // 0x0708 + bool m_bNoClipEnabled; // 0x0710 + uint32 m_iDesiredFOV; // 0x0714 }; class C_CSGO_TeamIntroCharacterPosition : public C_CSGO_TeamPreviewCharacterPosition // client { @@ -22352,10 +22353,10 @@ class CCSPlayerLegacyJump // client class C_WeaponNOVA : public C_CSWeaponBaseShotgun // client { }; -class C_DEagle : public C_CSWeaponBaseGun // client +class C_CS2HudModelAddon : public C_LateUpdatedAnimating // client { }; -class C_CS2HudModelAddon : public C_LateUpdatedAnimating // client +class C_DEagle : public C_CSWeaponBaseGun // client { }; class C_TriggerMultiple : public C_BaseTrigger // client @@ -22972,57 +22973,56 @@ class C_CSPlayerPawn : public C_CSPlayerPawnBase // client float32 m_flViewmodelOffsetZ; // 0x1B78 float32 m_flViewmodelFOV; // 0x1B7C uint32[5] m_vecPlayerPatchEconIndices; // 0x1B80 - Color m_GunGameImmunityColor; // 0x1BC0 - CUtlVector< C_BulletHitModel* > m_vecBulletHitModels; // 0x1C10 - bool m_bIsWalking; // 0x1C28 - EntitySpottedState_t m_entitySpottedState; // 0x1C30 - bool m_bIsScoped; // 0x1C48 - bool m_bResumeZoom; // 0x1C49 - bool m_bIsDefusing; // 0x1C4A - bool m_bIsGrabbingHostage; // 0x1C4B - CSPlayerBlockingUseAction_t m_iBlockingUseActionInProgress; // 0x1C4C - GameTime_t m_flEmitSoundTime; // 0x1C50 - bool m_bInNoDefuseArea; // 0x1C54 - int32 m_nWhichBombZone; // 0x1C58 - int32 m_iShotsFired; // 0x1C5C - float32 m_flFlinchStack; // 0x1C60 - float32 m_flVelocityModifier; // 0x1C64 - bool m_bWaitForNoAttack; // 0x1C68 - float32 m_ignoreLadderJumpTime; // 0x1C6C - bool m_bKilledByHeadshot; // 0x1C71 - int32 m_ArmorValue; // 0x1C74 - uint16 m_unCurrentEquipmentValue; // 0x1C78 - uint16 m_unRoundStartEquipmentValue; // 0x1C7A - uint16 m_unFreezetimeEndEquipmentValue; // 0x1C7C - CEntityIndex m_nLastKillerIndex; // 0x1C80 - bool m_bOldIsScoped; // 0x1C84 - bool m_bHasDeathInfo; // 0x1C85 - float32 m_flDeathInfoTime; // 0x1C88 - Vector m_vecDeathInfoOrigin; // 0x1C8C - GameTime_t m_grenadeParameterStashTime; // 0x1CC8 - bool m_bGrenadeParametersStashed; // 0x1CCC - QAngle m_angStashedShootAngles; // 0x1CD0 - Vector m_vecStashedGrenadeThrowPosition; // 0x1CDC - Vector m_vecStashedVelocity; // 0x1CE8 - QAngle[2] m_angShootAngleHistory; // 0x1CF4 - Vector[2] m_vecThrowPositionHistory; // 0x1D0C - Vector[2] m_vecVelocityHistory; // 0x1D24 - bool m_bShouldAutobuyDMWeapons; // 0x3270 - GameTime_t m_fImmuneToGunGameDamageTime; // 0x3274 - bool m_bGunGameImmunity; // 0x3278 - GameTime_t m_fImmuneToGunGameDamageTimeLast; // 0x327C - float32 m_fMolotovDamageTime; // 0x3280 - bool m_bThirdpersonActiveWeaponCanSafelyOcclude; // 0x3288 - ParticleIndex_t m_nPlayerInfernoBodyFx; // 0x328C - QAngle m_angEyeAngles; // 0x3300 - GameTime_t[4] m_arrOldEyeAnglesTimes; // 0x3390 - QAngle[4] m_arrOldEyeAngles; // 0x33A0 - QAngle m_angEyeAnglesVelocity; // 0x33D0 - CEntityIndex m_iIDEntIndex; // 0x33DC - CountdownTimer m_delayTargetIDTimer; // 0x33E0 - CEntityIndex m_iTargetItemEntIdx; // 0x33F8 - CEntityIndex m_iOldIDEntIndex; // 0x33FC - CountdownTimer m_holdTargetIDTimer; // 0x3400 + Color m_GunGameImmunityColor; // 0x1BC8 + CUtlVector< C_BulletHitModel* > m_vecBulletHitModels; // 0x1C18 + bool m_bIsWalking; // 0x1C30 + EntitySpottedState_t m_entitySpottedState; // 0x1C38 + bool m_bIsScoped; // 0x1C50 + bool m_bResumeZoom; // 0x1C51 + bool m_bIsDefusing; // 0x1C52 + bool m_bIsGrabbingHostage; // 0x1C53 + CSPlayerBlockingUseAction_t m_iBlockingUseActionInProgress; // 0x1C54 + GameTime_t m_flEmitSoundTime; // 0x1C58 + bool m_bInNoDefuseArea; // 0x1C5C + int32 m_nWhichBombZone; // 0x1C60 + int32 m_iShotsFired; // 0x1C64 + float32 m_flFlinchStack; // 0x1C68 + float32 m_flVelocityModifier; // 0x1C6C + bool m_bWaitForNoAttack; // 0x1C70 + float32 m_ignoreLadderJumpTime; // 0x1C74 + bool m_bKilledByHeadshot; // 0x1C79 + int32 m_ArmorValue; // 0x1C7C + uint16 m_unCurrentEquipmentValue; // 0x1C80 + uint16 m_unRoundStartEquipmentValue; // 0x1C82 + uint16 m_unFreezetimeEndEquipmentValue; // 0x1C84 + CEntityIndex m_nLastKillerIndex; // 0x1C88 + bool m_bOldIsScoped; // 0x1C8C + bool m_bHasDeathInfo; // 0x1C8D + float32 m_flDeathInfoTime; // 0x1C90 + Vector m_vecDeathInfoOrigin; // 0x1C94 + GameTime_t m_grenadeParameterStashTime; // 0x1CD0 + bool m_bGrenadeParametersStashed; // 0x1CD4 + QAngle m_angStashedShootAngles; // 0x1CD8 + Vector m_vecStashedGrenadeThrowPosition; // 0x1CE4 + Vector m_vecStashedVelocity; // 0x1CF0 + QAngle[2] m_angShootAngleHistory; // 0x1CFC + Vector[2] m_vecThrowPositionHistory; // 0x1D14 + Vector[2] m_vecVelocityHistory; // 0x1D2C + bool m_bShouldAutobuyDMWeapons; // 0x3280 + GameTime_t m_fImmuneToGunGameDamageTime; // 0x3284 + bool m_bGunGameImmunity; // 0x3288 + GameTime_t m_fImmuneToGunGameDamageTimeLast; // 0x328C + float32 m_fMolotovDamageTime; // 0x3290 + ParticleIndex_t m_nPlayerInfernoBodyFx; // 0x32FC + QAngle m_angEyeAngles; // 0x3370 + GameTime_t[4] m_arrOldEyeAnglesTimes; // 0x3400 + QAngle[4] m_arrOldEyeAngles; // 0x3410 + QAngle m_angEyeAnglesVelocity; // 0x3440 + CEntityIndex m_iIDEntIndex; // 0x344C + CountdownTimer m_delayTargetIDTimer; // 0x3450 + CEntityIndex m_iTargetItemEntIdx; // 0x3468 + CEntityIndex m_iOldIDEntIndex; // 0x346C + CountdownTimer m_holdTargetIDTimer; // 0x3470 }; class C_CSGO_TeamIntroTerroristPosition : public C_CSGO_TeamIntroCharacterPosition // client { @@ -23972,74 +23972,74 @@ class CPlayer_FlashlightServices : public CPlayerPawnComponent // client }; class CCSPlayerController : public CBasePlayerController // client { - CCSPlayerController_InGameMoneyServices* m_pInGameMoneyServices; // 0x0800 - CCSPlayerController_InventoryServices* m_pInventoryServices; // 0x0808 - CCSPlayerController_ActionTrackingServices* m_pActionTrackingServices; // 0x0810 - CCSPlayerController_DamageServices* m_pDamageServices; // 0x0818 - uint32 m_iPing; // 0x0820 - bool m_bHasCommunicationAbuseMute; // 0x0824 - uint32 m_uiCommunicationMuteFlags; // 0x0828 - CUtlSymbolLarge m_szCrosshairCodes; // 0x0830 - uint8 m_iPendingTeamNum; // 0x0838 - GameTime_t m_flForceTeamTime; // 0x083C - int32 m_iCompTeammateColor; // 0x0840 - bool m_bEverPlayedOnTeam; // 0x0844 - GameTime_t m_flPreviousForceJoinTeamTime; // 0x0848 - CUtlSymbolLarge m_szClan; // 0x0850 - CUtlString m_sSanitizedPlayerName; // 0x0858 - int32 m_iCoachingTeam; // 0x0860 - uint64 m_nPlayerDominated; // 0x0868 - uint64 m_nPlayerDominatingMe; // 0x0870 - int32 m_iCompetitiveRanking; // 0x0878 - int32 m_iCompetitiveWins; // 0x087C - int8 m_iCompetitiveRankType; // 0x0880 - int32 m_iCompetitiveRankingPredicted_Win; // 0x0884 - int32 m_iCompetitiveRankingPredicted_Loss; // 0x0888 - int32 m_iCompetitiveRankingPredicted_Tie; // 0x088C - int32 m_nEndMatchNextMapVote; // 0x0890 - uint16 m_unActiveQuestId; // 0x0894 - uint32 m_rtActiveMissionPeriod; // 0x0898 - QuestProgress::Reason m_nQuestProgressReason; // 0x089C - uint32 m_unPlayerTvControlFlags; // 0x08A0 - int32 m_iDraftIndex; // 0x08D0 - uint32 m_msQueuedModeDisconnectionTimestamp; // 0x08D4 - uint32 m_uiAbandonRecordedReason; // 0x08D8 - uint32 m_eNetworkDisconnectionReason; // 0x08DC - bool m_bCannotBeKicked; // 0x08E0 - bool m_bEverFullyConnected; // 0x08E1 - bool m_bAbandonAllowsSurrender; // 0x08E2 - bool m_bAbandonOffersInstantSurrender; // 0x08E3 - bool m_bDisconnection1MinWarningPrinted; // 0x08E4 - bool m_bScoreReported; // 0x08E5 - int32 m_nDisconnectionTick; // 0x08E8 - bool m_bControllingBot; // 0x08F8 - bool m_bHasControlledBotThisRound; // 0x08F9 - bool m_bHasBeenControlledByPlayerThisRound; // 0x08FA - int32 m_nBotsControlledThisRound; // 0x08FC - bool m_bCanControlObservedBot; // 0x0900 - CHandle< C_CSPlayerPawn > m_hPlayerPawn; // 0x0904 - CHandle< C_CSObserverPawn > m_hObserverPawn; // 0x0908 - bool m_bPawnIsAlive; // 0x090C - uint32 m_iPawnHealth; // 0x0910 - int32 m_iPawnArmor; // 0x0914 - bool m_bPawnHasDefuser; // 0x0918 - bool m_bPawnHasHelmet; // 0x0919 - uint16 m_nPawnCharacterDefIndex; // 0x091A - int32 m_iPawnLifetimeStart; // 0x091C - int32 m_iPawnLifetimeEnd; // 0x0920 - int32 m_iPawnBotDifficulty; // 0x0924 - CHandle< CCSPlayerController > m_hOriginalControllerOfCurrentPawn; // 0x0928 - int32 m_iScore; // 0x092C - uint8[8] m_recentKillQueue; // 0x0930 - uint8 m_nFirstKill; // 0x0938 - uint8 m_nKillCount; // 0x0939 - bool m_bMvpNoMusic; // 0x093A - int32 m_eMvpReason; // 0x093C - int32 m_iMusicKitID; // 0x0940 - int32 m_iMusicKitMVPs; // 0x0944 - int32 m_iMVPs; // 0x0948 - bool m_bIsPlayerNameDirty; // 0x094C - bool m_bFireBulletsSeedSynchronized; // 0x094D + CCSPlayerController_InGameMoneyServices* m_pInGameMoneyServices; // 0x0808 + CCSPlayerController_InventoryServices* m_pInventoryServices; // 0x0810 + CCSPlayerController_ActionTrackingServices* m_pActionTrackingServices; // 0x0818 + CCSPlayerController_DamageServices* m_pDamageServices; // 0x0820 + uint32 m_iPing; // 0x0828 + bool m_bHasCommunicationAbuseMute; // 0x082C + uint32 m_uiCommunicationMuteFlags; // 0x0830 + CUtlSymbolLarge m_szCrosshairCodes; // 0x0838 + uint8 m_iPendingTeamNum; // 0x0840 + GameTime_t m_flForceTeamTime; // 0x0844 + int32 m_iCompTeammateColor; // 0x0848 + bool m_bEverPlayedOnTeam; // 0x084C + GameTime_t m_flPreviousForceJoinTeamTime; // 0x0850 + CUtlSymbolLarge m_szClan; // 0x0858 + CUtlString m_sSanitizedPlayerName; // 0x0860 + int32 m_iCoachingTeam; // 0x0868 + uint64 m_nPlayerDominated; // 0x0870 + uint64 m_nPlayerDominatingMe; // 0x0878 + int32 m_iCompetitiveRanking; // 0x0880 + int32 m_iCompetitiveWins; // 0x0884 + int8 m_iCompetitiveRankType; // 0x0888 + int32 m_iCompetitiveRankingPredicted_Win; // 0x088C + int32 m_iCompetitiveRankingPredicted_Loss; // 0x0890 + int32 m_iCompetitiveRankingPredicted_Tie; // 0x0894 + int32 m_nEndMatchNextMapVote; // 0x0898 + uint16 m_unActiveQuestId; // 0x089C + uint32 m_rtActiveMissionPeriod; // 0x08A0 + QuestProgress::Reason m_nQuestProgressReason; // 0x08A4 + uint32 m_unPlayerTvControlFlags; // 0x08A8 + int32 m_iDraftIndex; // 0x08D8 + uint32 m_msQueuedModeDisconnectionTimestamp; // 0x08DC + uint32 m_uiAbandonRecordedReason; // 0x08E0 + uint32 m_eNetworkDisconnectionReason; // 0x08E4 + bool m_bCannotBeKicked; // 0x08E8 + bool m_bEverFullyConnected; // 0x08E9 + bool m_bAbandonAllowsSurrender; // 0x08EA + bool m_bAbandonOffersInstantSurrender; // 0x08EB + bool m_bDisconnection1MinWarningPrinted; // 0x08EC + bool m_bScoreReported; // 0x08ED + int32 m_nDisconnectionTick; // 0x08F0 + bool m_bControllingBot; // 0x0900 + bool m_bHasControlledBotThisRound; // 0x0901 + bool m_bHasBeenControlledByPlayerThisRound; // 0x0902 + int32 m_nBotsControlledThisRound; // 0x0904 + bool m_bCanControlObservedBot; // 0x0908 + CHandle< C_CSPlayerPawn > m_hPlayerPawn; // 0x090C + CHandle< C_CSObserverPawn > m_hObserverPawn; // 0x0910 + bool m_bPawnIsAlive; // 0x0914 + uint32 m_iPawnHealth; // 0x0918 + int32 m_iPawnArmor; // 0x091C + bool m_bPawnHasDefuser; // 0x0920 + bool m_bPawnHasHelmet; // 0x0921 + uint16 m_nPawnCharacterDefIndex; // 0x0922 + int32 m_iPawnLifetimeStart; // 0x0924 + int32 m_iPawnLifetimeEnd; // 0x0928 + int32 m_iPawnBotDifficulty; // 0x092C + CHandle< CCSPlayerController > m_hOriginalControllerOfCurrentPawn; // 0x0930 + int32 m_iScore; // 0x0934 + uint8[8] m_recentKillQueue; // 0x0938 + uint8 m_nFirstKill; // 0x0940 + uint8 m_nKillCount; // 0x0941 + bool m_bMvpNoMusic; // 0x0942 + int32 m_eMvpReason; // 0x0944 + int32 m_iMusicKitID; // 0x0948 + int32 m_iMusicKitMVPs; // 0x094C + int32 m_iMVPs; // 0x0950 + bool m_bIsPlayerNameDirty; // 0x0954 + bool m_bFireBulletsSeedSynchronized; // 0x0955 }; class C_CSGO_TeamIntroCounterTerroristPosition : public C_CSGO_TeamIntroCharacterPosition // client { @@ -24065,56 +24065,56 @@ class C_SoundEventAABBEntity : public C_SoundEventEntity // client }; class CCSPlayer_MovementServices : public CPlayer_MovementServices_Humanoid // client { - CCSPlayerAnimationState m_AnimationState; // 0x02E0 - Vector m_vecLadderNormal; // 0x03C0 - int32 m_nLadderSurfacePropIndex; // 0x03CC - bool m_bDucked; // 0x03D0 - float32 m_flDuckAmount; // 0x03D4 - float32 m_flDuckSpeed; // 0x03D8 - bool m_bDuckOverride; // 0x03DC - bool m_bDesiresDuck; // 0x03DD - bool m_bDucking; // 0x03DE - float32 m_flDuckRootOffset; // 0x03E0 - float32 m_flDuckViewOffset; // 0x03E4 - float32 m_flLastDuckTime; // 0x03E8 - float32 m_flBombPlantViewOffset; // 0x03EC - Vector2D m_vecLastPositionAtFullCrouchSpeed; // 0x03F8 - bool m_duckUntilOnGround; // 0x0400 - bool m_bHasWalkMovedSinceLastJump; // 0x0401 - bool m_bInStuckTest; // 0x0402 - int32 m_nTraceCount; // 0x0610 - int32 m_StuckLast; // 0x0614 - bool m_bSpeedCropped; // 0x0618 - int32 m_nOldWaterLevel; // 0x061C - float32 m_flWaterEntryTime; // 0x0620 - Vector m_vecForward; // 0x0624 - Vector m_vecLeft; // 0x0630 - Vector m_vecUp; // 0x063C - int32 m_nGameCodeHasMovedPlayerAfterCommand; // 0x0648 - GameTime_t m_fStashGrenadeParameterWhen; // 0x064C - uint64 m_nButtonDownMaskPrev; // 0x0650 - bool m_bUseFrictionStashedSpeed; // 0x0658 - float32 m_flUseFrictionStashedSpeedUntilFrac; // 0x065C - float32 m_flFrictionStashedSpeed; // 0x0660 - float32 m_flStamina; // 0x0664 - float32 m_flHeightAtJumpStart; // 0x0668 - float32 m_flMaxJumpHeightThisJump; // 0x066C - float32 m_flMaxJumpHeightLastJump; // 0x0670 - float32 m_flStaminaAtJumpStart; // 0x0674 - float32 m_flVelMulAtJumpStart; // 0x0678 - float32 m_flAccumulatedJumpError; // 0x067C - CCSPlayerLegacyJump m_LegacyJump; // 0x0680 - CCSPlayerModernJump m_ModernJump; // 0x0698 - GameTick_t m_nLastJumpTick; // 0x06D0 - float32 m_flLastJumpFrac; // 0x06D4 - float32 m_flLastJumpVelocityZ; // 0x06D8 - bool m_bJumpApexPending; // 0x06DC - float32 m_flTicksSinceLastSurfingDetected; // 0x06E0 - bool m_bWasSurfing; // 0x06E4 - Vector2D m_vecWalkWishVel; // 0x0774 - GameTime_t m_gtLastTimeOnStaticWorldGround; // 0x0FA0 - GameTime_t m_gtLastTimeInAir; // 0x0FA4 - bool m_bHasEverProcessedCommand; // 0x0FA8 + CCSPlayerAnimationState m_AnimationState; // 0x0310 + bool m_bUsingGroundTopologyOffset; // 0x03F0 + float32 m_flUsingGroundTopologyOffsetTransitionSmoothing; // 0x03F4 + Vector m_vecLadderNormal; // 0x03F8 + int32 m_nLadderSurfacePropIndex; // 0x0404 + bool m_bDucked; // 0x0408 + float32 m_flDuckAmount; // 0x040C + float32 m_flDuckSpeed; // 0x0410 + bool m_bDuckOverride; // 0x0414 + bool m_bDesiresDuck; // 0x0415 + bool m_bDucking; // 0x0416 + float32 m_flDuckRootOffset; // 0x0418 + float32 m_flDuckViewOffset; // 0x041C + float32 m_flLastDuckTime; // 0x0420 + float32 m_flBombPlantViewOffset; // 0x0424 + Vector2D m_vecLastPositionAtFullCrouchSpeed; // 0x0430 + bool m_duckUntilOnGround; // 0x0438 + bool m_bHasWalkMovedSinceLastJump; // 0x0439 + bool m_bInStuckTest; // 0x043A + int32 m_nTraceCount; // 0x0648 + int32 m_StuckLast; // 0x064C + bool m_bSpeedCropped; // 0x0650 + int32 m_nOldWaterLevel; // 0x0654 + float32 m_flWaterEntryTime; // 0x0658 + Vector m_vecForward; // 0x065C + Vector m_vecLeft; // 0x0668 + Vector m_vecUp; // 0x0674 + int32 m_nGameCodeHasMovedPlayerAfterCommand; // 0x0680 + GameTime_t m_fStashGrenadeParameterWhen; // 0x0684 + uint64 m_nButtonDownMaskPrev; // 0x0688 + bool m_bUseFrictionStashedSpeed; // 0x0690 + float32 m_flUseFrictionStashedSpeedUntilFrac; // 0x0694 + float32 m_flFrictionStashedSpeed; // 0x0698 + float32 m_flStamina; // 0x069C + float32 m_flHeightAtJumpStart; // 0x06A0 + float32 m_flMaxJumpHeightThisJump; // 0x06A4 + float32 m_flMaxJumpHeightLastJump; // 0x06A8 + float32 m_flStaminaAtJumpStart; // 0x06AC + float32 m_flVelMulAtJumpStart; // 0x06B0 + float32 m_flAccumulatedJumpError; // 0x06B4 + CCSPlayerLegacyJump m_LegacyJump; // 0x06B8 + CCSPlayerModernJump m_ModernJump; // 0x06D0 + GameTick_t m_nLastJumpTick; // 0x0708 + float32 m_flLastJumpFrac; // 0x070C + float32 m_flLastJumpVelocityZ; // 0x0710 + bool m_bJumpApexPending; // 0x0714 + float32 m_flTicksSinceLastSurfingDetected; // 0x0718 + bool m_bWasSurfing; // 0x071C + Vector2D m_vecWalkWishVel; // 0x07AC + bool m_bHasEverProcessedCommand; // 0x0FD8 }; class SellbackPurchaseEntry_t // client { @@ -25362,8 +25362,8 @@ class C_ModelPointEntity : public C_BaseModelEntity // client }; class C_CSGO_PreviewPlayer : public C_CSPlayerPawn // client { - CGlobalSymbol m_animgraphCharacterModeString; // 0x3420 - float32 m_flInitialModelScale; // 0x3428 + CGlobalSymbol m_animgraphCharacterModeString; // 0x3490 + float32 m_flInitialModelScale; // 0x3498 }; class C_RectLight : public C_BarnLight // client { @@ -26092,11 +26092,12 @@ class CBasePlayerController : public C_BaseEntity // client CUtlVector< CHandle< CBasePlayerController > > m_hSplitScreenPlayers; // 0x06D0 bool m_bIsHLTV; // 0x06E8 PlayerConnectedState m_iConnected; // 0x06EC - char[128] m_iszPlayerName; // 0x06F0 - uint64 m_steamID; // 0x0778 - bool m_bIsLocalPlayerController; // 0x0780 - bool m_bNoClipEnabled; // 0x0781 - uint32 m_iDesiredFOV; // 0x0784 + PlayerConnectedState m_iMostConnected; // 0x06F0 + char[128] m_iszPlayerName; // 0x06F4 + uint64 m_steamID; // 0x0780 + bool m_bIsLocalPlayerController; // 0x0788 + bool m_bNoClipEnabled; // 0x0789 + uint32 m_iDesiredFOV; // 0x078C }; class C_CSGO_EndOfMatchLineupEndpoint : public C_BaseEntity // client {