Burst Fire (Machine Gun)
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;
}