diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 49343f0c9e..6017b4b1fe 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3465,6 +3465,7 @@ void CClientGame::Event_OnIngame() g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level g_pGame->GetWaterManager()->SetWaterDrawnLast(true); m_pCamera->SetCameraClip(true, true); + g_pMultiplayer->ResetClothingCacheTime(); // Deallocate all custom models m_pManager->GetModelManager()->RemoveAll(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 3de38bbf76..4e68ffe03d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -86,6 +86,7 @@ void CLuaEngineDefs::LoadFunctions() {"engineRestoreCOL", EngineRestoreCOL}, {"engineReplaceModel", EngineReplaceModel}, {"engineAddClothingModel", ArgumentParser}, + {"engineSetClothingCacheTime", ArgumentParser}, {"engineRestoreModel", EngineRestoreModel}, {"engineReplaceAnimation", EngineReplaceAnimation}, {"engineRestoreAnimation", EngineRestoreAnimation}, @@ -852,6 +853,11 @@ bool CLuaEngineDefs::EngineAddClothingModel(CClientDFF* pDFF, std::string strMod return true; } +bool CLuaEngineDefs::EngineSetClothingCacheTime(std::uint32_t timeInMs) +{ + return g_pMultiplayer->SetClothingCacheTime(timeInMs); +} + int CLuaEngineDefs::EngineRestoreModel(lua_State* luaVM) { // Grab the model ID diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 48fa2706a4..0395f57a97 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -60,6 +60,7 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineRestoreObjectGroupPhysicalProperties) static bool EngineAddClothingModel(CClientDFF* pDff, std::string strModelName); + static bool EngineSetClothingCacheTime(std::uint32_t timeInMs); static bool EngineAddClothingTXD(CClientTXD* pTxd, std::string strModelName); static uint EngineGetModelFlags(uint uiModelID); static bool EngineSetModelFlags(uint uiModelID, uint uiFlags, std::optional bIdeFlags); diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 75206d8211..4074aeffac 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -345,6 +345,8 @@ class CMultiplayerSA : public CMultiplayer virtual void GetRwResourceStats(SRwResourceStats& outStats); virtual void GetClothesCacheStats(SClothesCacheStats& outStats); + virtual void ResetClothingCacheTime(); + virtual bool SetClothingCacheTime(std::uint32_t timeInMs); virtual void SetIsMinimizedAndNotConnected(bool bIsMinimizedAndNotConnected); virtual void SetMirrorsEnabled(bool bEnabled); diff --git a/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp b/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp index 3b5dd798ad..a6d342c1a1 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp @@ -16,6 +16,8 @@ #define CLOTHES_REF_TEST 1 // Debug clothes geometry refs +static constexpr std::uint32_t DEFAULT_CACHE_TIME = 1000; + //////////////////////////////////////////////// // // class CPedClothesDesc @@ -113,7 +115,7 @@ class CClumpStore std::vector savedClumpList; uint m_uiMaxSize; - uint m_uiMinCacheTime; + std::uint32_t m_minCacheTime; SClothesCacheStats m_Stats; int m_iCacheRevision; @@ -126,7 +128,7 @@ class CClumpStore { memset(&m_Stats, 0, sizeof(m_Stats)); m_uiMaxSize = 4; - m_uiMinCacheTime = 1000; + m_minCacheTime = DEFAULT_CACHE_TIME; m_iCacheRevision = 1; } @@ -138,30 +140,34 @@ class CClumpStore uint GetNumCached() { uint uiNumCached = 0; - for (std::vector::iterator iter = savedClumpList.begin(); iter != savedClumpList.end(); ++iter) + + if (m_minCacheTime > 0) { - SSavedClumpInfo& info = *iter; - RpGeometry* pGeometry = ((RpAtomic*)((info.pClump->atomics.root.next) - 0x8))->geometry; -#ifdef CLOTHES_REF_TEST - if (pGeometry->refs < 21) + for (std::vector::iterator iter = savedClumpList.begin(); iter != savedClumpList.end(); ++iter) { - AddReportLog(7521, SString("Clothes geometry refs below expected value: %d", pGeometry->refs)); - pGeometry->refs = 21; - } - if (pGeometry->refs == 21) + SSavedClumpInfo& info = *iter; + RpGeometry* pGeometry = ((RpAtomic*)((info.pClump->atomics.root.next) - 0x8))->geometry; +#ifdef CLOTHES_REF_TEST + if (pGeometry->refs < 21) + { + AddReportLog(7521, SString("Clothes geometry refs below expected value: %d", pGeometry->refs)); + pGeometry->refs = 21; + } + if (pGeometry->refs == 21) #else - if (pGeometry->refs == 1) + if (pGeometry->refs == 1) #endif - { - uiNumCached++; - if (!info.bUnused) { - info.timeUnused = CTickCount::Now(); - info.bUnused = true; + uiNumCached++; + if (!info.bUnused) + { + info.timeUnused = CTickCount::Now(); + info.bUnused = true; + } } + else + info.bUnused = false; } - else - info.bUnused = false; } m_Stats.uiNumTotal = savedClumpList.size(); @@ -236,7 +242,7 @@ class CClumpStore if (info.bUnused) { uint uiAge = (timeNow - info.timeUnused).ToInt(); - if (uiAge > m_uiMinCacheTime) + if (uiAge > m_minCacheTime) { if (uiAge > uiBestAge || uiBestAge == -1) { @@ -402,6 +408,34 @@ void CMultiplayerSA::GetClothesCacheStats(SClothesCacheStats& outStats) outStats = ms_clumpStore.m_Stats; } +////////////////////////////////////////////////////////////////////////////////////////// +// +// CMultiplayerSA::SetClothingCacheTime +// +// +////////////////////////////////////////////////////////////////////////////////////////// +bool CMultiplayerSA::SetClothingCacheTime(std::uint32_t timeInMs) +{ + if (timeInMs == ms_clumpStore.m_minCacheTime) + return false; + + ms_clumpStore.savedClumpList.clear(); + ms_clumpStore.m_minCacheTime = timeInMs; + + return true; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CMultiplayerSA::ResetClothingCacheTime +// +// +////////////////////////////////////////////////////////////////////////////////////////// +void CMultiplayerSA::ResetClothingCacheTime() +{ + SetClothingCacheTime(DEFAULT_CACHE_TIME); +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::InitHooks_ClothesCache diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index e5e591ad5d..83eb39da8f 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -455,6 +455,8 @@ class CMultiplayer virtual void GetRwResourceStats(SRwResourceStats& outStats) = 0; virtual void GetClothesCacheStats(SClothesCacheStats& outStats) = 0; + virtual void ResetClothingCacheTime() = 0; + virtual bool SetClothingCacheTime(std::uint32_t timeInMs) = 0; virtual void SetIsMinimizedAndNotConnected(bool bIsMinimizedAndNotConnected) = 0; virtual void SetMirrorsEnabled(bool bEnabled) = 0;