Пример #1
0
static void ApplyErrorToAngle(QAngle* angles, float margin)
{
	QAngle error;
	error.Random(-1.0f, 1.0f);
	error *= margin;
	angles->operator+=(error);
}
//------------------------------------------------------------------------------
// 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 );
}
Пример #3
0
//-----------------------------------------------------------------------------
// 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;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : fTimeDelta - 
//-----------------------------------------------------------------------------
void C_ExtinguisherJet::Update( float fTimeDelta )
{
	if ( m_bEmit == false )
		return;

	C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();

	if ( m_bUseMuzzlePoint )
	{
		C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;

		if ( vm )
		{
			int iAttachment = vm->LookupAttachment( "muzzle" );
			Vector origin;
			QAngle angles;
			vm->GetAttachment( iAttachment, origin, angles );

			Assert( !GetMoveParent() );
			SetLocalOrigin( origin );
			SetLocalAngles( angles );
		}
	}

	trace_t	tr;
	Vector	shotDir, vRight, vUp;

	AngleVectors( GetAbsAngles(), &shotDir, &vRight, &vUp );
	
	//FIXME: Muzzle point is incorrect on the model!
	if ( m_bUseMuzzlePoint )
	{
		shotDir.Negate();
	}

	Vector	endPoint = GetAbsOrigin() + ( shotDir * 150.0f );
	
	UTIL_TraceLine( GetAbsOrigin(), endPoint, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &tr );

	bool	hitWall = ( tr.fraction < 1.0f );

	//Add normal jet
	if ( m_pEmitter.IsValid() )
	{
		SimpleParticle	*pParticle;

		m_pEmitter->SetSortOrigin( GetAbsOrigin() );
	
		float tempDelta = fTimeDelta;
		
		//FIXME: All particles need to be within this loop
		while( m_ParticleSpawn.NextEvent( tempDelta ) )
		{
			pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );

			if ( pParticle )
			{
				pParticle->m_flDieTime	= 0.2f;
				pParticle->m_flLifetime	= 0.0f;
				
				pParticle->m_flRoll		= random->RandomInt( 0, 360 );
				pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
				
				pParticle->m_uchStartSize	= 1;
				pParticle->m_uchEndSize		= random->RandomInt( 32, 48 );
				pParticle->m_uchStartAlpha	= random->RandomInt( 128, 164 );
				pParticle->m_uchEndAlpha	= 0;
				
				int	cScale = random->RandomInt( 192, 255 );
				pParticle->m_uchColor[0]	= cScale;
				pParticle->m_uchColor[1]	= cScale;
				pParticle->m_uchColor[2]	= cScale;

				Vector	dir;
				QAngle  ofsAngles;

				ofsAngles.Random( -8.0f, 8.0f );
				ofsAngles += GetAbsAngles();

				AngleVectors( ofsAngles, &dir );

				if ( m_bUseMuzzlePoint )
				{
					dir.Negate();
				}

				pParticle->m_vecVelocity	= dir * random->RandomInt( 400, 800 );
			}

			//Add muzzle effect
			pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );

			if ( pParticle )
			{
				pParticle->m_flDieTime	= 0.1f;
				pParticle->m_flLifetime	= 0.0f;
				
				pParticle->m_flRoll		= random->RandomInt( 0, 360 );
				pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
				
				pParticle->m_uchStartSize	= 1;
				pParticle->m_uchEndSize		= random->RandomInt( 8, 16 );
				pParticle->m_uchStartAlpha	= random->RandomInt( 128, 255 );
				pParticle->m_uchEndAlpha	= 0;
				
				int	cScale = random->RandomInt( 192, 255 );
				pParticle->m_uchColor[0]	= cScale;
				pParticle->m_uchColor[1]	= cScale;
				pParticle->m_uchColor[2]	= cScale;

				Vector	dir;
				QAngle  ofsAngles;

				ofsAngles.Random( -64.0f, 64.0f );
				ofsAngles += GetAbsAngles();

				AngleVectors( ofsAngles, &dir );

				if ( m_bUseMuzzlePoint )
				{
					dir.Negate();
				}

				pParticle->m_vecVelocity	= dir * random->RandomInt( 32, 64 );
			}

			//Add a wall effect if needed
			if ( hitWall )
			{
				AddExtinguisherDecal( tr );

				Vector	offDir;

				offDir.Random( -16.0f, 16.0f );

				pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, ( tr.endpos + ( tr.plane.normal * 8.0f ) ) + offDir );

				if ( pParticle )
				{
					pParticle->m_flDieTime	= 0.4f;
					pParticle->m_flLifetime	= 0.0f;
					
					pParticle->m_flRoll		= random->RandomInt( 0, 360 );
					pParticle->m_flRollDelta= random->RandomFloat( -2.0f, 2.0f );
					
					pParticle->m_uchStartSize	= random->RandomInt( 8, 16 );
					pParticle->m_uchEndSize		= random->RandomInt( 24, 32 );
					pParticle->m_uchStartAlpha	= random->RandomInt( 64, 128 );
					pParticle->m_uchEndAlpha	= 0;
					
					int	cScale = random->RandomInt( 192, 255 );
					pParticle->m_uchColor[0]	= cScale;
					pParticle->m_uchColor[1]	= cScale;
					pParticle->m_uchColor[2]	= cScale;

					Vector	rDir;

					rDir = tr.plane.normal;
					rDir[0] += random->RandomFloat( -0.9f, 0.9f );
					rDir[1] += random->RandomFloat( -0.9f, 0.9f );
					rDir[2] += random->RandomFloat( -0.9f, 0.9f );

					pParticle->m_vecVelocity = rDir * random->RandomInt( 32, 64 );
				}			
			}

			//Add small ember-like particles
			if ( random->RandomInt( 0, 1 ) == 0 )
			{
				m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() );

				pParticle = (SimpleParticle *) m_pEmberEmitter->AddParticle( sizeof(SimpleParticle), m_pEmberEmitter->GetPMaterial( "particle/particle_smokegrenade" ), GetAbsOrigin() );
				
				assert(pParticle);

				if ( pParticle )
				{
					pParticle->m_flLifetime		= 0.0f;
					pParticle->m_flDieTime		= 1.0f;

					pParticle->m_flRoll			= 0;
					pParticle->m_flRollDelta	= 0;

					pParticle->m_uchColor[0]	= 255;
					pParticle->m_uchColor[1]	= 255;
					pParticle->m_uchColor[2]	= 255;
					pParticle->m_uchStartAlpha	= 255;
					pParticle->m_uchEndAlpha	= 0;
					pParticle->m_uchStartSize	= 1;
					pParticle->m_uchEndSize		= 0;
					
					Vector	dir;
					QAngle  ofsAngles;

					ofsAngles.Random( -8.0f, 8.0f );
					ofsAngles += GetAbsAngles();

					AngleVectors( ofsAngles, &dir );

					if ( m_bUseMuzzlePoint )
					{
						dir.Negate();
					}

					pParticle->m_vecVelocity	= dir * random->RandomInt( 400, 800 );
				}
			}
		}
	}

	// Inner beam

	CBeamSegDraw	beamDraw;
	CBeamSeg		seg;
	const int		numPoints = 4;
	Vector			beamPoints[numPoints];

	beamPoints[0] = GetAbsOrigin();

	// Create our beam points
	int i;
	for ( i = 0; i < numPoints; i++ )
	{
		beamPoints[i] = GetAbsOrigin() + ( shotDir * (32*i*i) );

		beamPoints[i] += vRight * sin( gpGlobals->curtime * 4.0f ) * (2.0f*i);
		beamPoints[i] += vUp * sin( gpGlobals->curtime * 8.0f ) * (1.0f*i);
		beamPoints[i] += shotDir * sin( gpGlobals->curtime * (16.0f*i) ) * (1.0f*i);
	}

	IMaterial *pMat = materials->FindMaterial( "particle/particle_smokegrenade", NULL );

	beamDraw.Start( numPoints, pMat );

	//Setup and draw those points	
	for( i = 0; i < numPoints; i++ )
	{
		float	t = (float) i / (numPoints - 1);
		float	color = 1.0f * (1.0f - t);

		seg.m_vColor		= Vector( color, color, color );
		seg.m_vPos			= beamPoints[i];
		seg.m_flTexCoord	= (float)i/(float)(numPoints-1) - ((gpGlobals->curtime - (int)gpGlobals->curtime) * 4.0f );
		seg.m_flWidth		= 4.0f + ( (64.0f*t) * (fabs( sin( gpGlobals->curtime * 16.0f ) )) );
		seg.m_flAlpha		= color;

		beamDraw.NextSeg( &seg );
	}
	
	beamDraw.End();
}