Defer inventory apply/remove to game thread (OnFrameStageNotify) to fix freeze on skin select

This commit is contained in:
2026-08-05 16:00:25 +02:00
parent a5c5c906da
commit b0603cd8a9
4 changed files with 75 additions and 5 deletions
@@ -38,7 +38,12 @@ static CInventoryChanger g_CInventoryChanger{};
auto CInventoryChanger::OnFrameStageNotify( int FrameStage ) -> void
{
if ( FrameStage != 6 || !SDK::Interfaces::EngineToClient()->IsInGame() )
if ( FrameStage != 6 )
return;
GetInventoryItemsManager()->FlushPendingRequests();
if ( !SDK::Interfaces::EngineToClient()->IsInGame() )
return;
auto pLocalInventory = CCSPlayerInventory::Get();
@@ -310,6 +310,59 @@ auto CInventoryItemsManager::SetMusicKit( int musicId , bool equip ) -> bool
return false;
}
auto CInventoryItemsManager::RequestWeaponSkin( uint16_t defIdx , int paintKit ) -> void
{
m_iPendingWeaponDefIdx = defIdx;
m_iPendingWeaponSkinId = paintKit;
}
auto CInventoryItemsManager::RequestMusicKit( int musicId ) -> void
{
m_iPendingMusicId = musicId;
}
auto CInventoryItemsManager::RequestRemoveWeaponSkin( uint16_t defIdx ) -> void
{
m_iPendingRemoveWeaponDefIdx = defIdx;
}
auto CInventoryItemsManager::RequestRemoveMusicKit() -> void
{
m_bPendingRemoveMusic = true;
}
auto CInventoryItemsManager::FlushPendingRequests() -> void
{
if ( m_iPendingRemoveWeaponDefIdx >= 0 )
{
RemoveWeaponSkin( static_cast<uint16_t>( m_iPendingRemoveWeaponDefIdx ) );
m_iPendingRemoveWeaponDefIdx = -1;
}
if ( m_bPendingRemoveMusic )
{
RemoveMusicKit();
m_bPendingRemoveMusic = false;
}
if ( m_iPendingWeaponDefIdx >= 0 && m_iPendingWeaponSkinId >= 0 )
{
SetWeaponSkin( static_cast<uint16_t>( m_iPendingWeaponDefIdx ) , m_iPendingWeaponSkinId , true );
m_iPendingWeaponDefIdx = -1;
m_iPendingWeaponSkinId = -1;
}
if ( m_iPendingMusicId >= 0 )
{
SetMusicKit( m_iPendingMusicId , true );
m_iPendingMusicId = -1;
}
}
auto CInventoryItemsManager::RemoveWeaponSkin( uint16_t defIdx ) -> bool
{
auto bRemoved = false;
@@ -76,6 +76,12 @@ private:
std::unordered_map<uint16_t , int> m_WeaponSkinSelections;
int m_iMusicSelection = -1;
int m_iPendingWeaponDefIdx = -1;
int m_iPendingWeaponSkinId = -1;
int m_iPendingMusicId = -1;
int m_iPendingRemoveWeaponDefIdx = -1;
bool m_bPendingRemoveMusic = false;
public:
// Scan all available items (does NOT add to inventory)
auto ScanAllItems() -> void;
@@ -94,6 +100,12 @@ public:
auto SetMusicKit( int musicId , bool equip = true ) -> bool;
auto RemoveMusicKit() -> bool;
auto RequestWeaponSkin( uint16_t defIdx , int paintKit ) -> void;
auto RequestMusicKit( int musicId ) -> void;
auto RequestRemoveWeaponSkin( uint16_t defIdx ) -> void;
auto RequestRemoveMusicKit() -> void;
auto FlushPendingRequests() -> void;
auto ApplyConfigSelections() -> void;
auto ClearAllSelections() -> void;
@@ -458,7 +458,7 @@ auto CAndromedaMenu::RenderSkinPanel() -> void
{
m_iSelectedSkinIdx = static_cast<int>( j );
pManager->SetWeaponSkin( Item.m_DefIdx , Skin.m_ID , true );
pManager->RequestWeaponSkin( Item.m_DefIdx , Skin.m_ID );
}
ImGui::PopStyleColor();
@@ -467,7 +467,7 @@ auto CAndromedaMenu::RenderSkinPanel() -> void
ImGui::NewLine();
if ( ImGui::Button( "Remove" , ImVec2( 120.f * m_fUIScale , 28.f * m_fUIScale ) ) )
pManager->RemoveWeaponSkin( Item.m_DefIdx );
pManager->RequestRemoveWeaponSkin( Item.m_DefIdx );
}
}
else
@@ -507,7 +507,7 @@ auto CAndromedaMenu::RenderMusicPanel() -> void
{
m_iSelectedMusicIdx = Skin.m_ID;
pManager->SetMusicKit( Skin.m_ID , true );
pManager->RequestMusicKit( Skin.m_ID );
}
}
}
@@ -515,7 +515,7 @@ auto CAndromedaMenu::RenderMusicPanel() -> void
ImGui::NewLine();
if ( ImGui::Button( "Reset" , ImVec2( 100.f * m_fUIScale , 28.f * m_fUIScale ) ) )
pManager->RemoveMusicKit();
pManager->RequestRemoveMusicKit();
}
ImGui::EndChild();