//----------------------------------------------------------------------------- // Move it to the top of the LRU //----------------------------------------------------------------------------- void CRagdollLRURetirement::MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant ) { if ( bImportant ) { m_LRUImportantRagdolls.AddToTail( pRagdoll ); if ( m_LRUImportantRagdolls.Count() > g_ragdoll_important_maxcount.GetInt() ) { int iIndex = m_LRUImportantRagdolls.Head(); CBaseAnimating *pRagdoll = m_LRUImportantRagdolls[iIndex].Get(); if ( pRagdoll ) { #ifdef CLIENT_DLL pRagdoll->SUB_Remove(); #else pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRUImportantRagdolls.Remove(iIndex); } } return; } for ( int i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = m_LRU.Next(i) ) { if ( m_LRU[i].Get() == pRagdoll ) { m_LRU.Remove(i); break; } } m_LRU.AddToTail( pRagdoll ); }
void CRagdollLRURetirement::Update( float frametime ) // Non-episodic version { VPROF( "CRagdollLRURetirement::Update" ); // Compress out dead items int i, next; int iMaxRagdollCount = m_iMaxRagdolls; if ( iMaxRagdollCount == -1 ) { iMaxRagdollCount = g_ragdoll_maxcount.GetInt(); } // fade them all for the low violence version if ( g_RagdollLVManager.IsLowViolence() ) { iMaxRagdollCount = 0; } m_iRagdollCount = 0; m_iSimulatedRagdollCount = 0; // remove ragdolls with a forced retire time for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); //Just ignore it until we're done burning/dissolving. if ( pRagdoll && pRagdoll->GetEffectEntity() ) continue; // ignore if it's not time to force retire this ragdoll if ( m_LRU[i].GetForcedRetireTime() == 0.0f || gpGlobals->curtime < m_LRU[i].GetForcedRetireTime() ) continue; //Msg(" Removing ragdoll %s due to forced retire time of %f (now = %f)\n", pRagdoll->GetModelName(), m_LRU[i].GetForcedRetireTime(), gpGlobals->curtime ); #ifdef CLIENT_DLL pRagdoll->SUB_Remove(); #else pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); if ( pRagdoll ) { m_iRagdollCount++; IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if (pObject && !pObject->IsAsleep()) { m_iSimulatedRagdollCount++; } if ( m_LRU.Count() > iMaxRagdollCount ) { //Found one, we're done. if ( ShouldRemoveThisRagdoll( pRagdoll ) == true ) { #ifdef CLIENT_DLL pRagdoll->SUB_Remove(); #else pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); return; } } } else { m_LRU.Remove(i); } } ////////////////////////////// /// ORIGINAL ALGORITHM /// ////////////////////////////// // not episodic -- this is the original mechanism for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { if ( m_LRU.Count() <= iMaxRagdollCount ) break; next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); //Just ignore it until we're done burning/dissolving. if ( pRagdoll && pRagdoll->GetEffectEntity() ) continue; #ifdef CLIENT_DLL pRagdoll->SUB_Remove(); #else pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } }
void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION { VPROF( "CRagdollLRURetirement::Update" ); // Compress out dead items int i, next; int iMaxRagdollCount = m_iMaxRagdolls; if ( iMaxRagdollCount == -1 ) { iMaxRagdollCount = g_ragdoll_maxcount.GetInt(); } // fade them all for the low violence version if ( g_RagdollLVManager.IsLowViolence() ) { iMaxRagdollCount = 0; } m_iRagdollCount = 0; m_iSimulatedRagdollCount = 0; // First, find ragdolls that are good candidates for deletion because they are not // visible at all, or are in a culled visibility box for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); if ( pRagdoll ) { m_iRagdollCount++; IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if (pObject && !pObject->IsAsleep()) { m_iSimulatedRagdollCount++; } if ( m_LRU.Count() > iMaxRagdollCount ) { //Found one, we're done. if ( ShouldRemoveThisRagdoll( pRagdoll ) == true ) { #ifdef CLIENT_DLL pRagdoll->SUB_Remove(); #else pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); return; } } } else { m_LRU.Remove(i); } } ////////////////////////////// /// EPISODIC ALGORITHM /// ////////////////////////////// // If we get here, it means we couldn't find a suitable ragdoll to remove, // so just remove the furthest one. int furthestOne = m_LRU.Head(); float furthestDistSq = 0; #ifdef CLIENT_DLL ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 ); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); #else CBasePlayer *pPlayer = g_pGameRules->IsMultiplayer() ? NULL : UTIL_GetLocalPlayer(); #endif if (pPlayer && m_LRU.Count() > iMaxRagdollCount) // find the furthest one algorithm { Vector PlayerOrigin = pPlayer->GetAbsOrigin(); // const CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { CBaseAnimating *pRagdoll = m_LRU[i].Get(); next = m_LRU.Next(i); IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) ) continue; if ( pRagdoll ) { // float distToPlayer = (pPlayer->GetAbsOrigin() - pRagdoll->GetAbsOrigin()).LengthSqr(); float distToPlayer = (PlayerOrigin - pRagdoll->GetAbsOrigin()).LengthSqr(); if (distToPlayer > furthestDistSq) { furthestOne = i; furthestDistSq = distToPlayer; } } else // delete bad rags first. { furthestOne = i; break; } } CBaseAnimating *pRemoveRagdoll = m_LRU[ furthestOne ].Get(); #ifdef CLIENT_DLL pRemoveRagdoll->SUB_Remove(); #else pRemoveRagdoll->SUB_StartFadeOut( 0 ); #endif } else // fall back on old-style pick the oldest one algorithm { for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { if ( m_LRU.Count() <= iMaxRagdollCount ) break; next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); //Just ignore it until we're done burning/dissolving. IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) ) continue; #ifdef CLIENT_DLL pRagdoll->SUB_Remove(); #else pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } } }