void CASW_DamageAllocationMgr::Remove( const EHANDLE &handle ) { IndexType_t i = Find( handle ); if ( IsValid(i) ) { // strike all projectiles for this target ProjectilePool_t::IndexLocalType_t j = i->m_nProjectiles; while ( m_ProjectileLists.IsValidIndex(j) ) { ProjectilePool_t::IndexLocalType_t old = j; j = m_ProjectileLists.Next(j); m_ProjectileLists.Remove( old ); } int vectoridx = i - m_Targets.Base(); Assert( &m_Targets[vectoridx] == i ); m_Targets.FastRemove( vectoridx ); } else { AssertMsg1( false, "Tried to remove %s from a damage allocation manager whence it was absent.\n", handle->GetDebugName() ); } }
//----------------------------------------------------------------------------- // Purpose: Stop all effects that were created using the given definition // name. //----------------------------------------------------------------------------- void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly /* =false */, int nSplitScreenPlayerSlot /*= -1*/ ) { CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName ); AssertMsg1(pDef, "Could not find particle definition %s", pszEffectName ); if (!pDef) return; // If we return from dormancy and are then told to stop emitting, // we should have died while dormant. Remove ourselves immediately. bool bRemoveInstantly = (m_iDormancyChangedAtFrame == gpGlobals->framecount); // force remove particles instantly if caller specified bRemoveInstantly |= bForceRemoveInstantly; int nCount = m_ParticleEffects.Count(); for ( int i = 0; i < nCount; ++i ) { // for each effect... CNewParticleEffect *pParticleEffect = m_ParticleEffects[i].pParticleEffect.GetObject(); if (pParticleEffect->m_pDef() == pDef) { if ( nSplitScreenPlayerSlot != -1 ) { if ( !pParticleEffect->ShouldDrawForSplitScreenUser( nSplitScreenPlayerSlot ) ) continue; } pParticleEffect->StopEmission( false, bRemoveInstantly ); } } }
void CParticleProperty::StopParticlesWithNameAndAttachment( const char *pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly /* =false */ ) { CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName ); AssertMsg1(pDef, "Could not find particle definition %s", pszEffectName ); if (!pDef) return; // If we return from dormancy and are then told to stop emitting, // we should have died while dormant. Remove ourselves immediately. bool bRemoveInstantly = (m_iDormancyChangedAtFrame == gpGlobals->framecount); // force remove particles instantly if caller specified bRemoveInstantly |= bForceRemoveInstantly; int nCount = m_ParticleEffects.Count(); for ( int i = 0; i < nCount; ++i ) { // for each effect... ParticleEffectList_t *pParticleEffectList = &m_ParticleEffects[i]; CNewParticleEffect *pParticleEffect = pParticleEffectList->pParticleEffect.GetObject(); if (pParticleEffect->m_pDef() == pDef) { int nControlPointCount = pParticleEffectList->pControlPoints.Count(); for ( int j = 0; j < nControlPointCount; ++j ) { if ( pParticleEffectList->pControlPoints[j].iAttachmentPoint == iAttachmentPoint ) { pParticleEffect->StopEmission( false, bRemoveInstantly ); break; } } } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CAI_Expresser *CFlexExpresser::CreateExpresser( void ) { AssertMsg1( !m_pExpresser, "LEAK: Double-created expresser for FlexExpresser %s", GetDebugName() ); m_pExpresser = new CAI_ExpresserWithFollowup(this); if ( !m_pExpresser ) return NULL; m_pExpresser->Connect(this); return m_pExpresser; }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void C_NPC_AntlionGuard::UpdateBleedingPerformance() { // get my particles CParticleProperty * pProp = ParticleProp(); // squelch the prior effect if it exists if (m_pBleedingFX) { pProp->StopEmission(m_pBleedingFX); m_pBleedingFX = NULL; } // kick off a new effect switch (m_iBleedingLevel) { case 1: // light bleeding { m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_light", PATTACH_ABSORIGIN_FOLLOW ); AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_light" ); if ( m_pBleedingFX ) { pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW ); } } break; case 2: // severe bleeding { m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_heavy", PATTACH_ABSORIGIN_FOLLOW ); AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_heavy" ); if ( m_pBleedingFX ) { pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW ); } } break; } m_iPerformingBleedingLevel = m_iBleedingLevel; }
// because nothing inherits from CFlexExpresser, we can just check classname. CFlexExpresser * CFlexExpresser::AsFlexExpresser( CBaseEntity *pEntity ) { if ( pEntity ) { if ( pEntity->ClassMatches( MAKE_STRING("prop_talker") ) ) { return static_cast< CFlexExpresser * >(pEntity); } } AssertMsg1( pEntity == NULL || dynamic_cast<CFlexExpresser *>(pEntity) == NULL, "%s subclasses prop_talker; update CFlexExpresser::AsFlexExpresser\n", pEntity->GetClassname() ); return NULL; }
CThreadSemaphore::CThreadSemaphore( long initialValue, long maxValue ) { if ( maxValue ) { AssertMsg( maxValue > 0, "Invalid max value for semaphore" ); AssertMsg( initialValue >= 0 && initialValue <= maxValue, "Invalid initial value for semaphore" ); m_hSyncObject = CreateSemaphore( NULL, initialValue, maxValue, NULL ); AssertMsg1(m_hSyncObject, "Failed to create semaphore (error 0x%x)", GetLastError()); } else { m_hSyncObject = NULL; } }
// Server to client message received void C_NPC_Advisor::ReceiveMessage( int classID, bf_read &msg ) { if ( classID != GetClientClass()->m_ClassID ) { // message is for subclass BaseClass::ReceiveMessage( classID, msg ); return; } int messageType = msg.ReadByte(); switch( messageType ) { case ADVISOR_MSG_START_BEAM: { int eindex = msg.ReadLong(); StartBeamFX(IndexToEntity(eindex)); } break; case ADVISOR_MSG_STOP_BEAM: { int eindex = msg.ReadLong(); StopBeamFX(IndexToEntity(eindex)); } break; case ADVISOR_MSG_STOP_ALL_BEAMS: { ParticleProp()->StopEmission(); } break; case ADVISOR_MSG_START_ELIGHT: { StartElight(); } break; case ADVISOR_MSG_STOP_ELIGHT: { StopElight(); } break; default: AssertMsg1( false, "Received unknown message %d", messageType); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_ParticleSystem::ClientThink( void ) { if ( m_bActive ) { const char *pszName = GetParticleSystemNameFromIndex( m_iEffectIndex ); if ( pszName && pszName[0] ) { CNewParticleEffect *pEffect = ParticleProp()->Create( pszName, PATTACH_ABSORIGIN_FOLLOW ); AssertMsg1( pEffect, "Particle system couldn't make %s", pszName ); if (pEffect) { for ( int i = 0 ; i < kMAXCONTROLPOINTS ; ++i ) { CBaseEntity *pOnEntity = m_hControlPointEnts[i].Get(); if ( pOnEntity ) { ParticleProp()->AddControlPoint( pEffect, i + 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW ); } AssertMsg2( m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS , "Particle system specified bogus control point parent (%d) for point %d.", m_iControlPointParents[i], i ); if (m_iControlPointParents[i] != 0) { pEffect->SetControlPointParent(i+1, m_iControlPointParents[i]); } } // NOTE: What we really want here is to compare our lifetime and that of our children and see if this delta is // already past the end of it, denoting that we're finished. In that case, just destroy us and be done. -- jdw // TODO: This can go when the SkipToTime code below goes ParticleProp()->OnParticleSystemUpdated( pEffect, 0.0f ); // Skip the effect ahead if we're restarting it float flTimeDelta = gpGlobals->curtime - m_flStartTime; if ( flTimeDelta > 0.01f ) { VPROF_BUDGET( "C_ParticleSystem::ClientThink SkipToTime", "Particle Simulation" ); pEffect->SkipToTime( flTimeDelta ); } } } } }
CThreadEvent::CThreadEvent( bool bManualReset ) { #ifdef _WIN32 m_hSyncObject = CreateEvent( NULL, bManualReset, FALSE, NULL ); AssertMsg1(m_hSyncObject, "Failed to create event (error 0x%x)", GetLastError() ); #elif _LINUX pthread_mutexattr_t Attr; pthread_mutexattr_init( &Attr ); pthread_mutex_init( &m_Mutex, &Attr ); pthread_mutexattr_destroy( &Attr ); pthread_cond_init( &m_Condition, NULL ); m_bInitalized = true; m_cSet = 0; m_bManualReset = bManualReset; #else #error "Implement me" #endif }
//----------------------------------------------------------------------------- // Grows the memory //----------------------------------------------------------------------------- int UtlMemory_CalcNewAllocationCount( int nAllocationCount, int nGrowSize, int nNewSize, int nBytesItem ) { if ( nGrowSize ) { nAllocationCount = ((1 + ((nNewSize - 1) / nGrowSize)) * nGrowSize); } else { if ( !nAllocationCount ) { if ( nBytesItem > 0 ) { // Compute an allocation which is at least as big as a cache line... nAllocationCount = (31 + nBytesItem) / nBytesItem; } else { // Should be impossible, but if hit try to grow an amount that may be large // enough for most cases and thus avoid both divide by zero above as well as // likely memory corruption afterwards. AssertMsg1( false, "nBytesItem is %d in UtlMemory_CalcNewAllocationCount", nBytesItem ); nAllocationCount = 256; } } // Cap growth to avoid high-end doubling insanity (1 GB -> 2 GB -> overflow) int nMaxGrowStep = Max( 1, 256*1024*1024 / ( nBytesItem > 0 ? nBytesItem : 1 ) ); while (nAllocationCount < nNewSize) { #ifndef _XBOX // Grow by doubling, but at most 256 MB at a time. nAllocationCount += Min( nAllocationCount, nMaxGrowStep ); #else int nNewAllocationCount = ( nAllocationCount * 9) / 8; // 12.5 % if ( nNewAllocationCount > nAllocationCount ) nAllocationCount = nNewAllocationCount; else nAllocationCount *= 2; #endif } } return nAllocationCount; }
// Pick a sequence for the given activity. If the current sequence is appropriate for the // current activity, and its stored weight is negative (whatever that means), always select // it. Otherwise perform a weighted selection -- imagine a large roulette wheel, with each // sequence having a number of spaces corresponding to its weight. int CStudioHdr::CActivityToSequenceMapping::SelectWeightedSequence( CStudioHdr *pstudiohdr, int activity, int curSequence ) { if (!ValidateAgainst(pstudiohdr)) { AssertMsg1(false, "CStudioHdr %s has changed its vmodel pointer without reinitializing its activity mapping! Now performing emergency reinitialization.", pstudiohdr->pszName()); ExecuteOnce(DebuggerBreakIfDebugging()); Reinitialize(pstudiohdr); } // a null m_pSequenceTuples just means that this studio header has no activities. if (!m_pSequenceTuples) return ACTIVITY_NOT_AVAILABLE; // is the current sequence appropriate? if (curSequence >= 0) { mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( curSequence ); if (seqdesc.activity == activity && seqdesc.actweight < 0) return curSequence; } // get the data for the given activity HashValueType dummy( activity, 0, 0, 0 ); UtlHashHandle_t handle = m_ActToSeqHash.Find(dummy); if (!m_ActToSeqHash.IsValidHandle(handle)) { return ACTIVITY_NOT_AVAILABLE; } const HashValueType * __restrict actData = &m_ActToSeqHash[handle]; int weighttotal = actData->totalWeight; // generate a random number from 0 to the total weight int randomValue; if ( IsInPrediction() ) { randomValue = SharedRandomInt( "SelectWeightedSequence", 0, weighttotal - 1 ); } else { randomValue = RandomInt( 0, weighttotal - 1 ); } // chug through the entries in the list (they are sequential therefore cache-coherent) // until we run out of random juice SequenceTuple * __restrict sequenceInfo = m_pSequenceTuples + actData->startingIdx; const SequenceTuple *const stopHere = sequenceInfo + actData->count; // this is a backup // in case the weights are somehow miscalculated -- we don't read or write through // it (because it aliases the restricted pointer above); it's only here for // the comparison. while (randomValue >= sequenceInfo->weight && sequenceInfo < stopHere) { randomValue -= sequenceInfo->weight; ++sequenceInfo; } return sequenceInfo->seqnum; }
CThreadFullMutex::CThreadFullMutex( bool bEstablishInitialOwnership, const char *pszName ) { m_hSyncObject = CreateMutex( NULL, bEstablishInitialOwnership, pszName ); AssertMsg1( m_hSyncObject, "Failed to create mutex (error 0x%x)", GetLastError() ); }
bool CThread::Start( unsigned nBytesStack ) { AUTO_LOCK( m_Lock ); if ( IsAlive() ) { AssertMsg( 0, "Tried to create a thread that has already been created!" ); return false; } bool bInitSuccess = false; #ifdef _WIN32 HANDLE hThread; CThreadEvent createComplete; ThreadInit_t init = { this, &createComplete, &bInitSuccess }; m_hThread = hThread = (HANDLE)CreateThread( NULL, nBytesStack, (LPTHREAD_START_ROUTINE)GetThreadProc(), new ThreadInit_t(init), 0, &m_threadId ); if ( !hThread ) { AssertMsg1( 0, "Failed to create thread (error 0x%x)", GetLastError() ); return false; } #elif _LINUX ThreadInit_t init = { this, &bInitSuccess }; pthread_attr_t attr; pthread_attr_init( &attr ); pthread_attr_setstacksize( &attr, max( nBytesStack, 1024*1024 ) ); if ( pthread_create( &m_threadId, &attr, GetThreadProc(), new ThreadInit_t( init ) ) != 0 ) { AssertMsg1( 0, "Failed to create thread (error 0x%x)", GetLastError() ); return false; } bInitSuccess = true; #endif #ifdef _WIN32 if ( !WaitForCreateComplete( &createComplete ) ) { Msg( "Thread failed to initialize\n" ); CloseHandle( m_hThread ); m_hThread = NULL; return false; } #endif if ( !bInitSuccess ) { Msg( "Thread failed to initialize\n" ); #ifdef _WIN32 CloseHandle( m_hThread ); m_hThread = NULL; #elif _LINUX m_threadId = 0; #endif return false; } #ifdef _WIN32 if ( !m_hThread ) { Msg( "Thread exited immediately\n" ); } #endif #ifdef _WIN32 return !!m_hThread; #elif _LINUX return !!m_threadId; #endif }
int CStudioHdr::CActivityToSequenceMapping::SelectWeightedSequenceFromModifiers( CStudioHdr *pstudiohdr, int activity, CUtlSymbol *pActivityModifiers, int iModifierCount ) { if ( !pstudiohdr->SequencesAvailable() ) { return ACTIVITY_NOT_AVAILABLE; } VerifySequenceIndex( pstudiohdr ); if ( pstudiohdr->GetNumSeq() == 1 ) { return ( ::GetSequenceActivity( pstudiohdr, 0, NULL ) == activity ) ? 0 : ACTIVITY_NOT_AVAILABLE; } if (!ValidateAgainst(pstudiohdr)) { AssertMsg1(false, "CStudioHdr %s has changed its vmodel pointer without reinitializing its activity mapping! Now performing emergency reinitialization.", pstudiohdr->pszName()); ExecuteOnce(DebuggerBreakIfDebugging()); Reinitialize(pstudiohdr); } // a null m_pSequenceTuples just means that this studio header has no activities. if (!m_pSequenceTuples) return ACTIVITY_NOT_AVAILABLE; // get the data for the given activity HashValueType dummy( activity, 0, 0, 0 ); UtlHashHandle_t handle = m_ActToSeqHash.Find(dummy); if (!m_ActToSeqHash.IsValidHandle(handle)) { return ACTIVITY_NOT_AVAILABLE; } const HashValueType * __restrict actData = &m_ActToSeqHash[handle]; // go through each sequence and give it a score int top_score = -1; CUtlVector<int> topScoring( actData->count, actData->count ); for ( int i = 0; i < actData->count; i++ ) { SequenceTuple * __restrict sequenceInfo = m_pSequenceTuples + actData->startingIdx + i; int score = 0; // count matching activity modifiers for ( int m = 0; m < iModifierCount; m++ ) { int num_modifiers = sequenceInfo->iNumActivityModifiers; for ( int k = 0; k < num_modifiers; k++ ) { if ( sequenceInfo->pActivityModifiers[ k ] == pActivityModifiers[ m ] ) { score++; break; } } } if ( score > top_score ) { topScoring.RemoveAll(); topScoring.AddToTail( sequenceInfo->seqnum ); top_score = score; } } // randomly pick between the highest scoring sequences ( NOTE: this method of selecting a sequence ignores activity weights ) if ( IsInPrediction() ) { return topScoring[ SharedRandomInt( "SelectWeightedSequence", 0, topScoring.Count() - 1 ) ]; } return topScoring[ RandomInt( 0, topScoring.Count() - 1 ) ]; }