User talk:Otisranson

From Valve Developer Community
Jump to: navigation, search

Make shotgun more manual

I recently modified the shotgun to be more like a manual pump shotgun rather than shoot, auto pump with animations. It's a one-liner so it wasn't difficult, but a really cool outcome (at least I thought so). Anyway here goes:

Obviously, I recommend Subversion if you haven't already created a repository, go ahead and do that. That's out of the scope of the tutorial but see wiki.

Open weapon_shotgun.cpp

Now, first thing I did was take out auto reload if the user runs out of bullets and forgets to reload, too bad.

Should be about line 543.

else
{
	// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
	if ( m_iClip1 <= 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime )
	{
		if (StartReload())
		{
			// if we've successfully started to reload, we're done
			return;
		}
	}
}

Comment it out using comment block (/* ... */) instead of the single line (//).

/*
else
{
	// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
	if ( m_iClip1 <= 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime )
	{
		if (StartReload())
		{
			// if we've successfully started to reload, we're done
			return;
		}
	}
}*/

Now our shotgun will not automatically reload if all bullets are expended. If all the bullets are expended, do nothing is basically what we are doing here. You could have also looked at ITEM_FLAG_NOAUTORELOAD, but hey, why do that when you have comments? Matter of implementation. This obviously requires less work and less chance of messing something else up. However, you leave code in your source which adds a small amount of bloating of the code (minuscule in size).

Let's get to the nitty gritty. Making a real pump action shotty. Scroll to line 446. Change this:

if ((m_bNeedPump) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
{
	Pump();
	return;
}

To this:

if ((m_bNeedPump) && (m_flNextPrimaryAttack <= gpGlobals->curtime) && (pOwner->m_nButtons & IN_ATTACK || pOwner->m_nButtons & IN_ATTACK2))
{
	Pump();
	return;
}

Analyze this for a minute, that way we are learning something instead of copy paste coding. Realize that the compiler follows PEMDAS (Parenthesis, Exponents, Multiplication, Division, Addition, Subtraction), order of looking at 'if' statements, so a statement inside a parenthesis is going to be analyzed first.

First 'if' statement says this: If you need to pump the shotty, and the next attack time is less than or equal to the current time, pump the gun. Our change says this: If the user is pressing the attack or attack2 button and you need to pump and attack time is less than or equal to current time, let's pump.

Pretty important you understand that logic. Basically, this logic is what is making our gun more of a manual action.

Now, I also wanted to be able to pump after you reload ONLY if you expend all your ammunition. This is because if you expend all your ammo now, you want to reload immediately, but you will have an expended round in the chamber, so pump it out. Scroll up to line 146 (inside bool CWeaponShotgun::StartReload( void ))and after:

	if (j <= 0)
		return false;

Insert this:

if( m_iClip1 == 0 )
{
	m_bNeedPump = true ;
}

Compile, load up, enjoy.