//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_ParticleSystem::PostDataUpdate( DataUpdateType_t updateType ) { BaseClass::PostDataUpdate( updateType ); // Always restart if just created and updated // FIXME: Does this play fairly with PVS? if ( updateType == DATA_UPDATE_CREATED ) { if ( m_bActive ) { // Delayed here so that we don't get invalid abs queries on level init with active particle systems SetNextClientThink( gpGlobals->curtime ); } } else { if ( m_bOldActive != m_bActive ) { if ( m_bActive ) { // Delayed here so that we don't get invalid abs queries on level init with active particle systems SetNextClientThink( gpGlobals->curtime ); } else { ParticleProp()->StopEmission(); } } } }
/// only use of the clientthink on the advisor is to update the elight void C_NPC_Advisor::ClientThink( void ) { // if the elight has gone away, bail out if (m_ElightKey == 0) { SetNextClientThink( CLIENT_THINK_NEVER ); return; } // get the elight dlight_t * el = effects->GetElightByKey(m_ElightKey); if (!el) { // the elight has been invalidated. bail out. m_ElightKey = 0; SetNextClientThink( CLIENT_THINK_NEVER ); return; } else { el->origin = WorldSpaceCenter(); #if ADVISOR_ELIGHT_CVARS el->color.exponent = advisor_elight_e.GetFloat(); el->radius = advisor_elight_rfeet.GetFloat() * 12.0f; #endif } }
//----------------------------------------------------------------------------- // Think for all entities that need it //----------------------------------------------------------------------------- void CClientThinkList::PerformThinkFunctions() { VPROF_("Client Thinks", 1, VPROF_BUDGETGROUP_CLIENT_SIM, false, BUDGETFLAG_CLIENT); int nMaxList = m_ThinkEntries.Count(); if ( nMaxList == 0 ) return; ++m_nIterEnum; // Build a list of entities to think this frame, in order of hierarchy. // Do this because the list may be modified during the thinking and also to // prevent bad situations where an entity can think more than once in a frame. ThinkEntry_t **ppThinkEntryList = (ThinkEntry_t**)stackalloc( nMaxList * sizeof(ThinkEntry_t*) ); int nThinkCount = 0; for ( unsigned short iCur=m_ThinkEntries.Head(); iCur != m_ThinkEntries.InvalidIndex(); iCur = m_ThinkEntries.Next( iCur ) ) { AddEntityToFrameThinkList( &m_ThinkEntries[iCur], false, nThinkCount, ppThinkEntryList ); Assert( nThinkCount <= nMaxList ); } // While we're in the loop, no changes to the think list are allowed m_bInThinkLoop = true; // Perform thinks on all entities that need it int i; for ( i = 0; i < nThinkCount; ++i ) { PerformThinkFunction( ppThinkEntryList[i], gpGlobals->curtime ); } m_bInThinkLoop = false; // Apply changes to the think list int nCount = m_aChangeList.Count(); for ( i = 0; i < nCount; ++i ) { ClientThinkHandle_t hThink = m_aChangeList[i].m_hThink; if ( hThink != INVALID_THINK_HANDLE ) { // This can happen if the same think handle was removed twice if ( !m_ThinkEntries.IsInList( (unsigned long)hThink ) ) continue; // NOTE: This is necessary for the case where the client entity handle // is slammed to NULL during a think interval; the hThink will get stuck // in the list and can never leave. SetNextClientThink( hThink, m_aChangeList[i].m_flNextTime ); } else { SetNextClientThink( m_aChangeList[i].m_hEnt, m_aChangeList[i].m_flNextTime ); } } m_aChangeList.RemoveAll(); // Clear out the client-side entity deletion list. CleanUpDeleteList(); }
//----------------------------------------------------------------------------- // On data update //----------------------------------------------------------------------------- void C_EnvHeadcrabCanister::OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); if ( updateType == DATA_UPDATE_CREATED ) { SetNextClientThink( CLIENT_THINK_ALWAYS ); } // Stop client-side simulation on landing if ( m_bLanded ) { SetNextClientThink( CLIENT_THINK_NEVER ); } }
void C_RagdollShadow::OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); // Has to happen *after* the client handle is set SetNextClientThink( CLIENT_THINK_ALWAYS ); bool bnewentity = (updateType == DATA_UPDATE_CREATED); if ( bnewentity && ( m_nPlayer != 0 ) ) { SetNextClientThink( CLIENT_THINK_ALWAYS ); Assert( !m_pPhysicsObject ); C_BaseEntity *pl = static_cast< C_BaseEntity * >( cl_entitylist->GetEnt( m_nPlayer ) ); if ( pl ) { m_hPlayer = pl; } m_pPhysicsObject = VPhysicsInitShadow( true, false ); } if ( m_pPhysicsObject ) { // Create the spring if we don't have one yet if ( !m_pSpring ) { C_BaseTFPlayer *pl = static_cast< C_BaseTFPlayer * >( (C_BaseEntity *)m_hPlayer ); if ( pl && pl->VPhysicsGetObject() ) { springparams_t spring; spring.constant = 15000; spring.damping = 1.0; spring.naturalLength = 0.0f; spring.relativeDamping = 100.0f; VectorCopy( vec3_origin, spring.startPosition ); VectorCopy( vec3_origin, spring.endPosition ); spring.useLocalPositions = true; m_pSpring = physenv->CreateSpring( m_pPhysicsObject, pl->VPhysicsGetObject(), &spring ); physenv->DisableCollisions( m_pPhysicsObject, pl->VPhysicsGetObject() ); } } m_pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 ); } }
void C_EntityFlame::ClientThink( void ) { for (int i = 0; i < NUM_HITBOX_FIRES; i++) { if ( m_pFireSmoke[i] != NULL ) { if ( m_pFireSmoke[i]->m_bFadingOut == false ) { m_pFireSmoke[i]->m_flScaleStart = m_pFireSmoke[i]->m_flScaleEnd; m_pFireSmoke[i]->m_flScaleEnd = 0.00001; m_pFireSmoke[i]->m_flScaleTimeStart = Helper_GetTime(); m_pFireSmoke[i]->m_flScaleTimeEnd = Helper_GetTime() + 2.0; m_pFireSmoke[i]->m_flScaleRegister = -1; m_pFireSmoke[i]->m_bFadingOut = true; } else { if ( m_pFireSmoke[i]->m_flScaleTimeEnd <= Helper_GetTime() ) { if ( m_hEntAttached ) { CPASAttenuationFilter filter( m_hEntAttached ); m_hEntAttached->EmitSound( filter, m_hEntAttached->GetSoundSourceIndex(), "General.StopBurning" ); } CleanUpRagdollOnRemove(); Release(); return; } } } } SetNextClientThink( gpGlobals->curtime + 0.1f ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_GrenadeAntiPersonnel::OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); // Only think when sapping SetNextClientThink( CLIENT_THINK_ALWAYS ); }
void C_SkeletonPlayer::OnDataChanged( DataUpdateType_t type ) { if ( type == DATA_UPDATE_CREATED ) SetNextClientThink( CLIENT_THINK_ALWAYS ); BaseClass::OnDataChanged( type ); }
void CViewAngleAnimation::Spawn( void ) { m_iFlags = 0; QAngle angles; engine->GetViewAngles( angles ); /* if ( m_iFlags & VIEWANIM_RELATIVE ) { AddKeyFrame( new CViewAngleKeyFrame( vec3_angle, 0.0, 0 ) ); // seed this so we can add keyframes and have them calc the delta properly m_vecBaseAngles = angles; } else { AddKeyFrame( new CViewAngleKeyFrame( angles, 0.0, 0 ) ); } */ m_bFinished = true; // don't run right away ClientEntityList().AddNonNetworkableEntity( this ); SetNextClientThink( CLIENT_THINK_ALWAYS ); }
void C_ASW_DynamicLight::ClientThink(void) { Vector forward; AngleVectors( GetAbsAngles(), &forward ); if ( (m_Flags & DLIGHT_NO_MODEL_ILLUMINATION) == 0 ) { if (!m_pDynamicLight || m_pDynamicLight->key != ASW_LIGHT_INDEX_FIRES + index) { m_pDynamicLight = effects->CL_AllocDlight( ASW_LIGHT_INDEX_FIRES + index ); } m_pDynamicLight->color.b = GetRenderColorB(); m_pDynamicLight->color.g = GetRenderColorG(); m_pDynamicLight->color.r = GetRenderColorR(); m_pDynamicLight->origin = GetAbsOrigin(); m_pDynamicLight->radius = m_Radius; m_pDynamicLight->color.exponent = m_Exponent; m_pDynamicLight->die = gpGlobals->curtime + 30.0f; } else { // In this case, the m_Flags could have changed; which is how we turn the light off if (m_pDynamicLight) { m_pDynamicLight->die = gpGlobals->curtime; m_pDynamicLight = 0; } } SetNextClientThink(gpGlobals->curtime + 0.001); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_CitadelEnergyCore::NotifyShouldTransmit( ShouldTransmitState_t state ) { BaseClass::NotifyShouldTransmit( state ); // Turn off if ( state == SHOULDTRANSMIT_END ) { SetNextClientThink( CLIENT_THINK_NEVER ); } // Turn on if ( state == SHOULDTRANSMIT_START ) { SetNextClientThink( CLIENT_THINK_ALWAYS ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CASW_Shotgun_Pellet_Predicted::OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); if ( updateType == DATA_UPDATE_CREATED && gpGlobals->maxClients <= 1) { // create a trail beam (it'll fade out and kill itself after a short period) C_ASW_Trail_Beam *pBeam = new C_ASW_Trail_Beam(); if (pBeam) { if (pBeam->InitializeAsClientEntity( NULL, false )) { C_ASW_Marine *pMarine = dynamic_cast<C_ASW_Marine*>(GetOwnerEntity()); if (pMarine) pBeam->InitBeam(pMarine->Weapon_ShootPosition(), this); else pBeam->InitBeam(GetAbsOrigin(), this); } else { UTIL_Remove( pBeam ); } } } SetNextClientThink( CLIENT_THINK_ALWAYS ); }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void C_SpotlightEnd::OnDataChanged(DataUpdateType_t updateType) { if ( updateType == DATA_UPDATE_CREATED ) { SetNextClientThink(CLIENT_THINK_ALWAYS); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pszModelName - // vecOrigin - // vecForceDir - // vecAngularImp - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool C_Gib::InitializeGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float flLifetime ) { if ( InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false ) { Release(); return false; } SetAbsOrigin( vecOrigin ); SetCollisionGroup( COLLISION_GROUP_DEBRIS ); solid_t tmpSolid; PhysModelParseSolid( tmpSolid, this, GetModelIndex() ); m_pPhysicsObject = VPhysicsInitNormal( SOLID_VPHYSICS, 0, false, &tmpSolid ); if ( m_pPhysicsObject ) { float flForce = m_pPhysicsObject->GetMass(); vecForceDir *= flForce; m_pPhysicsObject->ApplyForceOffset( vecForceDir, GetAbsOrigin() ); m_pPhysicsObject->SetCallbackFlags( m_pPhysicsObject->GetCallbackFlags() | CALLBACK_GLOBAL_TOUCH | CALLBACK_GLOBAL_TOUCH_STATIC ); } else { // failed to create a physics object Release(); return false; } SetNextClientThink( gpGlobals->curtime + flLifetime ); return true; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_EnvPortalPathTrack::NotifyShouldTransmit( ShouldTransmitState_t state ) { BaseClass::NotifyShouldTransmit( state ); // Turn off if ( state == SHOULDTRANSMIT_END ) { SetNextClientThink( CLIENT_THINK_NEVER ); } // Turn on if ( state == SHOULDTRANSMIT_START ) { SetNextClientThink( CLIENT_THINK_ALWAYS ); } }
//----------------------------------------------------------------------------- // Purpose: Start the buzzer's engine sound. //----------------------------------------------------------------------------- void C_ASW_Buzzer::OnDataChanged( DataUpdateType_t type ) { BaseClass::OnDataChanged( type ); if (( m_nEnginePitch1 <= 0 ) ) { SoundShutdown(); } else { SoundInit(); } UpdateFireEmitters(); if ( type == DATA_UPDATE_CREATED ) { // We want to think every frame. SetNextClientThink( CLIENT_THINK_ALWAYS ); if ( !m_pTrailEffect ) { m_pTrailEffect = this->ParticleProp()->Create( "buzzer_trail", PATTACH_ABSORIGIN_FOLLOW ); } } }
void C_Func_Dust::OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); if( updateType == DATA_UPDATE_CREATED ) { m_hMaterial = m_Effect.GetPMaterial( "particle/sparkles" ); m_Effect.SetSortOrigin( WorldSpaceCenter( ) ); // Let us think each frame. SetNextClientThink( CLIENT_THINK_ALWAYS ); // If we're setup to be frozen, just make a bunch of particles initially. if( m_DustFlags & DUSTFLAGS_FROZEN ) { for( int i=0; i < m_SpawnRate; i++ ) { AttemptSpawnNewParticle(); } } } m_Spawner.Init( m_SpawnRate ); // N particles per second }
void C_WeaponPortalgun::OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); if ( updateType == DATA_UPDATE_CREATED ) { // Start thinking (Baseclass stops it) SetNextClientThink( CLIENT_THINK_ALWAYS ); { C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, true ); StartEffects(); } DoEffect( m_EffectState ); } // Update effect state when out of parity with the server else if ( m_nOldEffectState != m_EffectState || m_bOldCanFirePortal1 != m_bCanFirePortal1 || m_bOldCanFirePortal2 != m_bCanFirePortal2 ) { DoEffect( m_EffectState ); m_nOldEffectState = m_EffectState; m_bOldCanFirePortal1 = m_bCanFirePortal1; m_bOldCanFirePortal2 = m_bCanFirePortal2; } }
void C_ASW_DynamicLight::OnDataChanged(DataUpdateType_t updateType) { if ( updateType == DATA_UPDATE_CREATED ) { SetNextClientThink(gpGlobals->curtime + 0.05); } }
void C_NPC_Advisor::StartElight() { AssertMsg(m_ElightKey == 0 , "Advisor trying to create new elight on top of old one!"); if ( m_ElightKey != 0 ) { Warning("Advisor tried to start his elight when it was already one.\n"); } else { m_ElightKey = LIGHT_INDEX_TE_DYNAMIC + this->entindex(); dlight_t * el = effects->CL_AllocElight( m_ElightKey ); if ( el ) { // create an elight on top of me el->origin = this->WorldSpaceCenter(); el->color.r = 235; el->color.g = 255; el->color.b = 255; el->color.exponent = 3; el->radius = 52*12; el->decay = 0.0f; el->die = gpGlobals->curtime + 2000.0f; // 1000 just means " a long time " SetNextClientThink( CLIENT_THINK_ALWAYS ); } else { // null out the light value m_ElightKey = 0; } } }
void CSprite::ClientThink( void ) { bool bDisableThink = true; // Module render colors over time if ( m_flSpriteScale != m_flDestScale ) { m_flStartScale = m_flDestScale; m_flDestScale = m_flSpriteScale; m_flScaleTimeStart = gpGlobals->curtime; bDisableThink = false; } if ( m_nBrightness != m_nDestBrightness ) { m_nStartBrightness = m_nDestBrightness; m_nDestBrightness = m_nBrightness; m_flBrightnessTimeStart = gpGlobals->curtime; bDisableThink = false; } if ( bDisableThink ) { SetNextClientThink(CLIENT_THINK_NEVER); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool C_FuncPhysicsRespawnZone::Initialize( void ) { if ( InitializeAsClientEntity( STRING(GetModelName()), RENDER_GROUP_OPAQUE_ENTITY ) == false ) return false; SetSolid( SOLID_BSP ); AddSolidFlags( FSOLID_NOT_SOLID ); AddSolidFlags( FSOLID_TRIGGER ); SetMoveType( MOVETYPE_NONE ); const model_t *mod = GetModel(); if ( mod ) { Vector mins, maxs; modelinfo->GetModelBounds( mod, mins, maxs ); SetCollisionBounds( mins, maxs ); } Spawn(); AddEffects( EF_NODRAW ); UpdatePartitionListEntry(); CollisionProp()->UpdatePartition(); UpdateVisibility(); SetNextClientThink( gpGlobals->curtime + (cl_phys_props_respawnrate.GetFloat() * RandomFloat(1.0,1.1)) ); return true; }
//----------------------------------------------------------------------------- // Purpose: Starts the effect // Input : *pParticleMgr - // *pArgs - //----------------------------------------------------------------------------- void C_SmokeStack::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs) { pParticleMgr->AddEffect( &m_ParticleEffect, this ); // Figure out the material name. char str[512] = "unset_material"; const model_t *pModel = modelinfo->GetModel( m_iMaterialModel ); if ( pModel ) { Q_strncpy( str, modelinfo->GetModelName( pModel ), sizeof( str ) ); // Get rid of the extension because the material system doesn't want it. char *pExt = Q_stristr( str, ".vmt" ); if ( pExt ) pExt[0] = 0; } m_MaterialHandle[0] = m_ParticleEffect.FindOrAddMaterial( str ); int iCount = 1; char szNames[512]; int iLength = Q_strlen( str ); str[iLength-1] = '\0'; Q_snprintf( szNames, sizeof( szNames ), "%s%d.vmt", str, iCount ); while ( filesystem->FileExists( VarArgs( "materials/%s", szNames ) ) && iCount < SMOKESTACK_MAX_MATERIALS ) { char *pExt = Q_stristr( szNames, ".vmt" ); if ( pExt ) pExt[0] = 0; m_MaterialHandle[iCount] = m_ParticleEffect.FindOrAddMaterial( szNames ); iCount++; } m_iMaxFrames = iCount-1; m_ParticleSpawn.Init( mat_reduceparticles.GetBool() ? m_Rate / 4 : m_Rate ); // Obey mat_reduceparticles in episodic m_InvLifetime = m_Speed / m_JetLength; m_pParticleMgr = pParticleMgr; // Figure out how we need to draw. IMaterial *pMaterial = pParticleMgr->PMaterialToIMaterial( m_MaterialHandle[0] ); if( pMaterial ) { m_Renderer.Init( pParticleMgr, pMaterial ); } QueueLightParametersInRenderer(); // For the first N seconds, always simulate so it can build up the smokestack. // Afterwards, we set it to freeze when it's not being rendered. m_ParticleEffect.SetAlwaysSimulate( true ); SetNextClientThink( gpGlobals->curtime + 5 ); }
void C_GlobalLight::Spawn() { BaseClass::Spawn(); m_bOldEnableShadows = m_bEnableShadows; SetNextClientThink( CLIENT_THINK_ALWAYS ); }
void C_PlayerResource::OnDataChanged(DataUpdateType_t updateType) { BaseClass::OnDataChanged( updateType ); if ( updateType == DATA_UPDATE_CREATED ) { SetNextClientThink( gpGlobals->curtime + PLAYER_RESOURCE_THINK_INTERVAL ); } }
void C_SlideshowDisplay::Spawn( void ) { BaseClass::Spawn(); m_NextSlideTime = 0; SetNextClientThink( CLIENT_THINK_ALWAYS ); }
void C_ASW_Sentry_Top::ClientThink() { BaseClass::ClientThink(); Scan(); SetNextClientThink( gpGlobals->curtime + 0.05f ); }
void C_SpatialEntity::InitSpatialEntity() { SetNextClientThink( CLIENT_THINK_ALWAYS ); AddToPersonalSpatialEntityMgr(); m_flWeight = 0.0f; m_flInfluence = 0.0f; }
void OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); if ( updateType == DATA_UPDATE_CREATED ) { SetNextClientThink( CLIENT_THINK_ALWAYS ); } }
void C_TFHintManager::OnDataChanged( DataUpdateType_t updateType ) { BaseClass::OnDataChanged( updateType ); // Think right away if ( updateType == DATA_UPDATE_CREATED ) SetNextClientThink( 0.0f ); }