Burst Fire (Machine Gun)

From Valve Developer Community
Revision as of 18:48, 13 July 2009 by £cho (talk | contribs) (Created page with ''''NOTE:''' The following code has only been tested using the HL2MP OB version of Source SDK's source code, though with a few modifications, it should work with most any version …')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

NOTE: The following code has only been tested using the HL2MP OB version of Source SDK's source code, though with a few modifications, it should work with most any version available. The code also calls for the sound "BURST", which must be defined in your weapon's .txt file in your /scripts folder. If it is not, no sound will play when you burst fire the weapon, so make sure it is added before you continue.

The code below will add a burst mode functionality to any machine gun based weapon for the its secondary fire.

If the weapon you are modifying does not have a SecondaryAttack() function yet, declare it in the weapon's class before continuing by adding the following under one of your "public:" entries in your weapon's class:

void SecondaryAttack( void );

Here's what's going on below that's worth noting before you go on copying and pasting:

  • Force a 0.5 second delay in between firing.
  • Ensure the weapon is only firing three bullets at most.
void CWeaponMP5K::SecondaryAttack( void )
{
	// Check our secondary attack delay before anything
	if ( m_flNextSecondaryAttack > gpGlobals->curtime )
		return;

	// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
	if ( !pPlayer )
		return;
	
	// Abort here to handle burst and auto fire modes
	if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) )
		return;

	m_nShotsFired++;

	pPlayer->DoMuzzleFlash();

	// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, 
	// especially if the weapon we're firing has a really fast rate of fire.
	int iBulletsToFire = 0;
	float fireRate = GetFireRate();

	while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
		// MUST call sound before removing a round from the clip of a CHLMachineGun
		WeaponSound(BURST, m_flNextPrimaryAttack);
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
		iBulletsToFire++;
	}

	// Make sure we don't fire more than the amount in the clip, if this weapon uses clips
	if ( UsesClipsForAmmo1() )
	{
		if ( iBulletsToFire > 3 )
			iBulletsToFire = 3;

		if ( iBulletsToFire > m_iClip1 )
			iBulletsToFire = m_iClip1;

		m_iClip1 -= iBulletsToFire;
	}

	CHL2MP_Player *pHL2MPPlayer = ToHL2MPPlayer( pPlayer );

	// Fire the bullets
	FireBulletsInfo_t info;
	info.m_iShots = iBulletsToFire;
	info.m_vecSrc = pHL2MPPlayer->Weapon_ShootPosition( );
	info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
	info.m_vecSpread = pHL2MPPlayer->GetAttackSpread( this );
	info.m_flDistance = MAX_TRACE_LENGTH;
	info.m_iAmmoType = m_iPrimaryAmmoType;
	info.m_iTracerFreq = 1;
	FireBullets( info );

	//Factor in the view kick
	AddViewKick();
	
	if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
	{
		// HEV suit - indicate out of ammo condition
		pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); 
	}

	SendWeaponAnim( GetPrimaryAttackActivity() );
	pPlayer->SetAnimation( PLAYER_ATTACK1 );

	m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
}