void CGib::DieThink ( void ) { if ( GetSprite() ) { CSprite *pSprite = dynamic_cast<CSprite*>( GetSprite() ); if ( pSprite ) { pSprite->FadeAndDie( 0.0 ); } } if ( GetFlame() ) { CEntityFlame *pFlame = dynamic_cast< CEntityFlame*>( GetFlame() ); if ( pFlame ) { pFlame->SetLifetime( 1.0f ); } } if ( g_pGameRules->IsMultiplayer() ) { UTIL_Remove( this ); } else { SetThink ( &CGib::SUB_FadeOut ); SetNextThink( gpGlobals->curtime ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : inputdata - //----------------------------------------------------------------------------- void CEntityFlame::InputIgnite( inputdata_t &inputdata ) { if (m_target != NULL_STRING) { CBaseEntity *pTarget = NULL; while ((pTarget = gEntList.FindEntityGeneric(pTarget, STRING(m_target), this, inputdata.pActivator)) != NULL) { // Combat characters know how to catch themselves on fire. CBaseCombatCharacter *pBCC = pTarget->MyCombatCharacterPointer(); if (pBCC) { // DVS TODO: consider promoting Ignite to CBaseEntity and doing everything here pBCC->Ignite(m_flLifetime); } // Everything else, we handle here. else { CEntityFlame *pFlame = CEntityFlame::Create(pTarget); if (pFlame) { pFlame->SetLifetime(m_flLifetime); } } } } }
//----------------------------------------------------------------------------- // Purpose: Creates a flame and attaches it to a target entity. // Input : pTarget - //----------------------------------------------------------------------------- CEntityFlame *CEntityFlame::Create( CBaseEntity *pTarget, float flLifetime, float flSize /*= 0.0f*/, bool bUseHitboxes /*= true*/ ) { CEntityFlame *pFlame = (CEntityFlame *)CreateEntityByName( "entityflame" ); if ( pFlame == NULL ) return NULL; if ( flSize <= 0.0f ) { float xSize = pTarget->CollisionProp()->OBBMaxs().x - pTarget->CollisionProp()->OBBMins().x; float ySize = pTarget->CollisionProp()->OBBMaxs().y - pTarget->CollisionProp()->OBBMins().y; flSize = ( xSize + ySize ) * 0.5f; if ( flSize < 16.0f ) { flSize = 16.0f; } } if ( flLifetime <= 0.0f ) { flLifetime = 2.0f; } pFlame->m_flSize = flSize; pFlame->Spawn(); UTIL_SetOrigin( pFlame, pTarget->GetAbsOrigin() ); pFlame->AttachToEntity( pTarget ); pFlame->SetLifetime( flLifetime ); pFlame->Activate(); return pFlame; }
//========================================================= // WaitTillLand - in order to emit their meaty scent from // the proper location, gibs should wait until they stop // bouncing to emit their scent. That's what this function // does. //========================================================= void CGib::WaitTillLand ( void ) { if (!IsInWorld()) { UTIL_Remove( this ); return; } if ( GetAbsVelocity() == vec3_origin ) { SetRenderAlpha( 255 ); m_nRenderMode = kRenderTransTexture; if ( GetMoveType() != MOVETYPE_VPHYSICS ) { AddSolidFlags( FSOLID_NOT_SOLID ); } SetLocalAngularVelocity( vec3_angle ); SetNextThink( gpGlobals->curtime + m_lifeTime ); SetThink ( &CGib::SUB_FadeOut ); if ( GetSprite() ) { CSprite *pSprite = dynamic_cast<CSprite*>( GetSprite() ); if ( pSprite ) { //Adrian - Why am I doing this? Check InitPointGib for the answer! if ( m_lifeTime == 0 ) m_lifeTime = random->RandomFloat( 1, 3 ); pSprite->FadeAndDie( m_lifeTime ); } } if ( GetFlame() ) { CEntityFlame *pFlame = dynamic_cast< CEntityFlame*>( GetFlame() ); if ( pFlame ) { pFlame->SetLifetime( 1.0f ); } } // If you bleed, you stink! if ( m_bloodColor != DONT_BLEED ) { // ok, start stinkin! // FIXME: It's too easy to fill up the sound queue with all these meat sounds // CSoundEnt::InsertSound ( SOUND_MEAT, GetAbsOrigin(), 384, 25 ); } } else { // wait and check again in another half second. SetNextThink( gpGlobals->curtime + 0.5f ); } }
//------------------------------------------------------------------------------ // Pow! //------------------------------------------------------------------------------ void CPropAPC2::ExplodeAndThrowChunk( const Vector &vecExplosionPos ) { ExplosionCreate( vecExplosionPos, vec3_angle, this, 1000, 500.0f, SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE | SF_ENVEXPLOSION_NOFIREBALLSMOKE, 0 ); UTIL_ScreenShake( vecExplosionPos, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); // Drop a flaming, smoking chunk. CGib *pChunk = CREATE_ENTITY( CGib, "gib" ); pChunk->Spawn( "models/gibs/hgibs.mdl" ); pChunk->SetBloodColor( DONT_BLEED ); QAngle vecSpawnAngles; vecSpawnAngles.Random( -90, 90 ); pChunk->SetAbsOrigin( vecExplosionPos ); pChunk->SetAbsAngles( vecSpawnAngles ); int nGib = random->RandomInt( 0, APC_MAX_CHUNKS - 1 ); pChunk->Spawn( s_pChunkModelName[nGib] ); pChunk->SetOwnerEntity( this ); pChunk->m_lifeTime = random->RandomFloat( 6.0f, 8.0f ); pChunk->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); IPhysicsObject *pPhysicsObject = pChunk->VPhysicsInitNormal( SOLID_VPHYSICS, pChunk->GetSolidFlags(), false ); // Set the velocity if ( pPhysicsObject ) { pPhysicsObject->EnableMotion( true ); Vector vecVelocity; QAngle angles; angles.x = random->RandomFloat( -40, 0 ); angles.y = random->RandomFloat( 0, 360 ); angles.z = 0.0f; AngleVectors( angles, &vecVelocity ); vecVelocity *= random->RandomFloat( 300, 900 ); vecVelocity += GetAbsVelocity(); AngularImpulse angImpulse; angImpulse = RandomAngularImpulse( -180, 180 ); pChunk->SetAbsVelocity( vecVelocity ); pPhysicsObject->SetVelocity(&vecVelocity, &angImpulse ); } CEntityFlame *pFlame = CEntityFlame::Create( pChunk, false ); if ( pFlame != NULL ) { pFlame->SetLifetime( pChunk->m_lifeTime ); } pChunk->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); }
//----------------------------------------------------------------------------- // Purpose: Creates a flame and attaches it to a target entity. // Input : pTarget - //----------------------------------------------------------------------------- CEntityFlame *CEntityFlame::Create( CBaseEntity *pTarget, bool useHitboxes ) { CEntityFlame *pFlame = (CEntityFlame *) CreateEntityByName( "entityflame" ); if ( pFlame == NULL ) return NULL; float xSize = pTarget->CollisionProp()->OBBMaxs().x - pTarget->CollisionProp()->OBBMins().x; float ySize = pTarget->CollisionProp()->OBBMaxs().y - pTarget->CollisionProp()->OBBMins().y; float size = ( xSize + ySize ) * 0.5f; if ( size < 16.0f ) { size = 16.0f; } UTIL_SetOrigin( pFlame, pTarget->GetAbsOrigin() ); pFlame->m_flSize = size; pFlame->SetThink( &CEntityFlame::FlameThink ); pFlame->SetNextThink( gpGlobals->curtime + 0.1f ); pFlame->AttachToEntity( pTarget ); pFlame->SetLifetime( 2.0f ); //Send to the client even though we don't have a model pFlame->AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); pFlame->SetUseHitboxes( useHitboxes ); return pFlame; }
void CASW_Simple_Alien::ASW_Ignite( float flFlameLifetime, float flSize, CBaseEntity *pAttacker, CBaseEntity *pDamagingWeapon ) { if (AllowedToIgnite()) { if( IsOnFire() ) return; CEntityFlame *pFlame = CEntityFlame::Create( this, flFlameLifetime, flSize ); if (pFlame) { if (pAttacker) pFlame->SetOwnerEntity(pAttacker); pFlame->SetLifetime( flFlameLifetime ); AddFlag( FL_ONFIRE ); SetEffectEntity( pFlame ); } m_OnIgnite.FireOutput( this, this ); } }
//----------------------------------------------------------------------------- // Purpose: Creates a flame and attaches it to a target entity. // Input : pTarget - //----------------------------------------------------------------------------- CEntityFlame *CEntityFlame::Create( CBaseEntity *pTarget ) { CEntityFlame *pFlame = (CEntityFlame *) CreateEntityByName( "entityflame" ); if ( pFlame == NULL ) return NULL; /*IPhysicsObject *pPhysicsObject = pTarget->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject-> }*/ float size = ( pTarget->WorldAlignMaxs().y - pTarget->WorldAlignMins().y ); if ( size < 8 ) size = 8; UTIL_SetOrigin( pFlame, pTarget->GetAbsOrigin() ); pFlame->m_flSize = size; pFlame->SetThink( &CEntityFlame::FlameThink ); pFlame->SetNextThink( gpGlobals->curtime + 0.1f ); pFlame->AttachToEntity( pTarget ); pFlame->SetLifetime( 2.0f ); //Send to the client even though we don't have a model pFlame->AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); return pFlame; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPropAPC::Event_Killed( const CTakeDamageInfo &info ) { m_OnDeath.FireOutput( info.GetAttacker(), this ); Vector vecAbsMins, vecAbsMaxs; CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs ); Vector vecNormalizedMins, vecNormalizedMaxs; CollisionProp()->WorldToNormalizedSpace( vecAbsMins, &vecNormalizedMins ); CollisionProp()->WorldToNormalizedSpace( vecAbsMaxs, &vecNormalizedMaxs ); Vector vecAbsPoint; CPASFilter filter( GetAbsOrigin() ); for (int i = 0; i < 5; i++) { CollisionProp()->RandomPointInBounds( vecNormalizedMins, vecNormalizedMaxs, &vecAbsPoint ); te->Explosion( filter, random->RandomFloat( 0.0, 1.0 ), &vecAbsPoint, g_sModelIndexFireball, random->RandomInt( 4, 10 ), random->RandomInt( 8, 15 ), ( i < 2 ) ? TE_EXPLFLAG_NODLIGHTS : TE_EXPLFLAG_NOPARTICLES | TE_EXPLFLAG_NOFIREBALLSMOKE | TE_EXPLFLAG_NODLIGHTS, 100, 0 ); } // TODO: make the gibs spawn in sync with the delayed explosions int nGibs = random->RandomInt( 1, 4 ); for ( int i = 0; i < nGibs; i++) { // Throw a flaming, smoking chunk. CGib *pChunk = CREATE_ENTITY( CGib, "gib" ); pChunk->Spawn( "models/gibs/hgibs.mdl" ); pChunk->SetBloodColor( DONT_BLEED ); QAngle vecSpawnAngles; vecSpawnAngles.Random( -90, 90 ); pChunk->SetAbsOrigin( vecAbsPoint ); pChunk->SetAbsAngles( vecSpawnAngles ); int nGib = random->RandomInt( 0, APC_MAX_CHUNKS - 1 ); pChunk->Spawn( s_pChunkModelName[nGib] ); pChunk->SetOwnerEntity( this ); pChunk->m_lifeTime = random->RandomFloat( 6.0f, 8.0f ); pChunk->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); IPhysicsObject *pPhysicsObject = pChunk->VPhysicsInitNormal( SOLID_VPHYSICS, pChunk->GetSolidFlags(), false ); // Set the velocity if ( pPhysicsObject ) { pPhysicsObject->EnableMotion( true ); Vector vecVelocity; QAngle angles; angles.x = random->RandomFloat( -20, 20 ); angles.y = random->RandomFloat( 0, 360 ); angles.z = 0.0f; AngleVectors( angles, &vecVelocity ); vecVelocity *= random->RandomFloat( 300, 900 ); vecVelocity += GetAbsVelocity(); AngularImpulse angImpulse; angImpulse = RandomAngularImpulse( -180, 180 ); pChunk->SetAbsVelocity( vecVelocity ); pPhysicsObject->SetVelocity(&vecVelocity, &angImpulse ); } CEntityFlame *pFlame = CEntityFlame::Create( pChunk, false ); if ( pFlame != NULL ) { pFlame->SetLifetime( pChunk->m_lifeTime ); } } UTIL_ScreenShake( vecAbsPoint, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); if( hl2_episodic.GetBool() ) { // EP1 perf hit Ignite( 6, false ); } else { Ignite( 60, false ); } m_lifeState = LIFE_DYING; // Spawn a lesser amount if the player is close m_iRocketSalvoLeft = DEATH_VOLLEY_ROCKET_COUNT; m_flRocketTime = gpGlobals->curtime; }