//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CNPC_GroundTurret::Shoot()
{
	FireBulletsInfo_t info;

	Vector vecSrc = EyePosition();
	Vector vecDir;

	GetVectors( &vecDir, NULL, NULL );

	for( int i = 0 ; i < 1 ; i++ )
	{
		info.m_vecSrc = vecSrc;
		
		if( i > 0 || !GetEnemy()->IsPlayer() )
		{
			// Subsequent shots or shots at non-players random
			GetVectors( &info.m_vecDirShooting, NULL, NULL );
			info.m_vecSpread = m_vecSpread;
		}
		else
		{
			// First shot is at the enemy.
			info.m_vecDirShooting = GetActualShootTrajectory( vecSrc );
			info.m_vecSpread = VECTOR_CONE_PRECALCULATED;
		}
		
		info.m_iTracerFreq = 1;
		info.m_iShots = 1;
		info.m_pAttacker = this;
		info.m_flDistance = MAX_COORD_RANGE;
		info.m_iAmmoType = m_iAmmoType;

		FireBullets( info );
	}

	// Do the AR2 muzzle flash
	CEffectData data;
	data.m_nEntIndex = entindex();
	data.m_nAttachmentIndex = LookupAttachment( "eyes" );
	data.m_flScale = 1.0f;
	data.m_fFlags = MUZZLEFLASH_COMBINE;
	DispatchEffect( "MuzzleFlash", data );

	EmitSound( "NPC_FloorTurret.ShotSounds", m_ShotSounds );

	if( IsX360() )
	{
		m_flTimeNextShoot = gpGlobals->curtime + 0.2;
	}
	else
	{
		m_flTimeNextShoot = gpGlobals->curtime + 0.09;
	}
}
Пример #2
0
//-----------------------------------------------------------------------------
// Purpose: Fire!
//-----------------------------------------------------------------------------
void CNPC_CeilingTurret::Shoot( const Vector &vecSrc, const Vector &vecDirToEnemy )
{
	if ( m_spawnflags & SF_CEILING_TURRET_OUT_OF_AMMO )
	{
		EmitSound( "NPC_FloorTurret.DryFire");
		EmitSound( "NPC_CeilingTurret.Activate" );

  		if ( RandomFloat( 0, 1 ) > 0.7 )
		{
			m_flShotTime = gpGlobals->curtime + random->RandomFloat( 0.5, 1.5 );
		}
		else
		{
			m_flShotTime = gpGlobals->curtime;
		}
		return;
	}

	FireBulletsInfo_t info;

	if ( GetEnemy() != NULL )
	{
		Vector vecDir = GetActualShootTrajectory( vecSrc );

		info.m_vecSrc = vecSrc;
		info.m_vecDirShooting = vecDir;
		info.m_iTracerFreq = 1;
		info.m_iShots = 1;
		info.m_pAttacker = this;
		info.m_vecSpread = VECTOR_CONE_PRECALCULATED;
		info.m_flDistance = MAX_COORD_RANGE;
		info.m_iAmmoType = m_iAmmoType;
	}
	else
	{
		// Just shoot where you're facing!
		Vector vecMuzzle, vecMuzzleDir;
		QAngle vecMuzzleAng;
		
		info.m_vecSrc = vecSrc;
		info.m_vecDirShooting = vecDirToEnemy;
		info.m_iTracerFreq = 1;
		info.m_iShots = 1;
		info.m_pAttacker = this;
		info.m_vecSpread = GetAttackSpread( NULL, NULL );
		info.m_flDistance = MAX_COORD_RANGE;
		info.m_iAmmoType = m_iAmmoType;
	}

	FireBullets( info );
	EmitSound( "NPC_CeilingTurret.ShotSounds" );
	DoMuzzleFlash();
}
void CNPC_Portal_GroundTurret::Shoot()
{
	FireBulletsInfo_t info;

	Vector vecSrc = EyePosition();
	Vector vecDir;

	GetVectors( &vecDir, NULL, NULL );

	for( int i = 0 ; i < 1 ; i++ )
	{
		info.m_vecSrc = vecSrc;

		if( i > 0 || !GetEnemy()->IsPlayer() )
		{
			// Subsequent shots or shots at non-players random
			GetVectors( &info.m_vecDirShooting, NULL, NULL );
			info.m_vecSpread = m_vecSpread;
		}
		else
		{
			// First shot is at the enemy.
			info.m_vecDirShooting = GetActualShootTrajectory( vecSrc );
			info.m_vecSpread = VECTOR_CONE_PRECALCULATED;
		}

		info.m_iTracerFreq = 1;
		info.m_iShots = 1;
		info.m_pAttacker = this;
		info.m_flDistance = MAX_COORD_RANGE;
		info.m_iAmmoType = m_iAmmoType;

		FireBullets( info );

		trace_t tr;
		CTraceFilterSkipTwoEntities traceFilter( this, info.m_pAdditionalIgnoreEnt, COLLISION_GROUP_NONE );
		Vector vecEnd = info.m_vecSrc + vecDir * info.m_flDistance;
		AI_TraceLine( info.m_vecSrc, vecEnd, MASK_SHOT, &traceFilter, &tr );

		if ( tr.m_pEnt && !tr.m_pEnt->IsPlayer() && ( vecDir * info.m_flDistance * tr.fraction ).Length() < 16.0f )
		{
			CTakeDamageInfo damageInfo;
			damageInfo.SetAttacker( this );
			damageInfo.SetDamageType( DMG_BULLET );
			damageInfo.SetDamage( 20.0f );

			TakeDamage( damageInfo );

			EmitSound( "NPC_FloorTurret.DryFire" );
		}
	}

	// Do the AR2 muzzle flash
	CEffectData data;
	data.m_nEntIndex = entindex();
	data.m_nAttachmentIndex = LookupAttachment( "eyes" );
	data.m_flScale = 1.0f;
	data.m_fFlags = MUZZLEFLASH_COMBINE;
	DispatchEffect( "MuzzleFlash", data );

	EmitSound( "NPC_FloorTurret.ShotSounds" );

	m_flTimeNextShoot = gpGlobals->curtime + 0.09;
}
//-----------------------------------------------------------------------------
// Purpose: Fire!
//-----------------------------------------------------------------------------
void CNPC_Portal_FloorTurret::Shoot( const Vector &vecSrc, const Vector &vecDirToEnemy, bool bStrict )
{
	FireBulletsInfo_t info;

	//if ( !bStrict && GetEnemy() == UTIL_PlayerByIndex( 1 ) )
	CBaseEntity *pEnemy = GetEnemy();
	if( !bStrict && (pEnemy && pEnemy->IsPlayer()) )
	{
		Vector vecDir = GetActualShootTrajectory( vecSrc );

		info.m_vecSrc = vecSrc;
		info.m_vecDirShooting = vecDir;
		info.m_iTracerFreq = 1;
		info.m_iShots = 1;
		info.m_pAttacker = this;
		info.m_vecSpread = GetAttackSpread( NULL, GetEnemy() );
		info.m_flDistance = MAX_COORD_RANGE;
		info.m_iAmmoType = m_iAmmoType;
	}
	else
	{
		// Just shoot where you're facing!
		Vector vecMuzzle, vecMuzzleDir;

		GetAttachment( m_iMuzzleAttachment, vecMuzzle, &vecMuzzleDir );

		info.m_vecSrc = vecSrc;
		info.m_vecDirShooting = vecMuzzleDir;
		info.m_iTracerFreq = 1;
		info.m_iShots = 1;
		info.m_pAttacker = this;
		info.m_vecSpread = GetAttackSpread( NULL, GetEnemy() );
		info.m_flDistance = MAX_COORD_RANGE;
		info.m_iAmmoType = m_iAmmoType;
	}

	info.m_flDamageForceScale = ( ( !m_bDamageForce ) ? ( 0.0f ) : ( TURRET_FLOOR_BULLET_FORCE_MULTIPLIER ) );

	int iBarrelIndex = ( m_bShootWithBottomBarrels ) ? ( 2 ) : ( 0 );
	QAngle angBarrelDir;

	// Shoot out of the left barrel if there's nothing solid between the turret's center and the muzzle
	trace_t tr;
	GetAttachment( m_iBarrelAttachments[ iBarrelIndex ], info.m_vecSrc, angBarrelDir );
	Vector vecCenter = GetAbsOrigin();
	UTIL_TraceLine( vecCenter, info.m_vecSrc, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
	if ( !tr.m_pEnt || !tr.m_pEnt->IsWorld() )
	{
		FireBullets( info );
	}

	// Shoot out of the right barrel if there's nothing solid between the turret's center and the muzzle
	GetAttachment( m_iBarrelAttachments[ iBarrelIndex + 1 ], info.m_vecSrc, angBarrelDir );
	vecCenter = GetAbsOrigin();
	UTIL_TraceLine( vecCenter, info.m_vecSrc, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
	if ( !tr.m_pEnt || !tr.m_pEnt->IsWorld() )
	{
		FireBullets( info );
	}

	// Flip shooting from the top or bottom
	m_bShootWithBottomBarrels = !m_bShootWithBottomBarrels;

	EmitSound( "NPC_FloorTurret.ShotSounds" );
	DoMuzzleFlash();

	// Make ropes shake if they exist
	for ( int iRope = 0; iRope < PORTAL_FLOOR_TURRET_NUM_ROPES; ++iRope )
	{
		if ( m_hRopes[ iRope ] )
		{
			m_hRopes[ iRope ]->ShakeRopes( vecSrc, 32.0f, 5.0f );
		}
	}

	// If a turret is partially tipped the recoil with each shot so that it can knock itself over
	Vector	up;
	GetVectors( NULL, NULL, &up );

	if ( up.z < 0.9f )
	{
		m_pMotionController->Suspend( 2.0f );

		IPhysicsObject *pTurretPhys = VPhysicsGetObject();
		Vector vVelocityImpulse = info.m_vecDirShooting * -35.0f;
		pTurretPhys->AddVelocity( &vVelocityImpulse, &vVelocityImpulse );
	}

	if ( m_iLastState == TURRET_ACTIVE && gpGlobals->curtime > m_fNextTalk )
	{
		EmitSound( GetTurretTalkName( m_iLastState ) );
		m_fNextTalk = gpGlobals->curtime + 2.5f;
	}
}