class CGlock : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int iItemSlot( void ) { return 2; }
int GetItemInfo(ItemInfo *p);
void PrimaryAttack( void );
void SecondaryAttack( void );
void GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim );
BOOL Deploy( void );
void Reload( void );
void WeaponIdle( void );
BOOL TriggerReleased; // added
// This declares the TriggerReleased boolean.
...
BOOL CGlock::Deploy( )
{
TriggerReleased = FALSE; // added
return DefaultDeploy( "models/v_9mmhandgun.mdl", "models/p_9mmhandgun.mdl", GLOCK_DRAW, "onehanded", UseDecrement() ? 1 : 0, pev->body );
}
Since you need to press the fire key to confirm a weapon deploy, we consider that this key is down when the weapon is deployed (this is just to set a value anyway). Next, go to `PrimaryAttack`:
void CGlock::PrimaryAttack( void )
{
if ( !TriggerReleased ) return; // added
GlockFire( 0.01, 0.3, TRUE );
TriggerReleased = FALSE; // added
}
Pretty simple, if the trigger has not been released, you can't shoot, and if you shoot, we can assume that the trigger is down. You can do that on the Secondary attack, too.void CGlock::WeaponIdle( void )
{
TriggerReleased = TRUE; // added
ResetEmptySound( );
m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
if ( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() ) return;
...
As soon as you stop pressing the attack button, WeaponIdle()
will be called and TriggerReleased
set to true. Make sure you do this before the test on m_flTimeWeaponIdle
though or you would need to wait for an actual idle animation before shooting again.ItemPostFrame()
function in weapons.cpp which handles the main weapon code (it may slightly differ from the original but nothing important)
void CBasePlayerWeapon::ItemPostFrame( void )
{
if ((m_fInReload) && (m_pPlayer->m_flNextAttack <= 0.0))
{
#if 0 // FIXME, need ammo on client to make this work right
// complete the reload.
int j = min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]);
// Add them to the clip
m_iClip += j;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j;
#else
m_iClip += 10;
#endif
m_fInReload = FALSE;
}
if ((m_pPlayer->pev->button & IN_ATTACK2) && (m_flNextSecondaryAttack <= 0.0))
{
if ( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] )
{
m_fFireOnEmpty = TRUE;
}
SecondaryAttack();
m_pPlayer->pev->button &= ~IN_ATTACK2;
}
else if ((m_pPlayer->pev->button & IN_ATTACK) && (m_flNextPrimaryAttack <= 0.0))
{
if ( (m_iClip == 0 && pszAmmo1()) || (iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) )
{
m_fFireOnEmpty = TRUE;
}
PrimaryAttack();
}
else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload )
{
// reload when reload is pressed, or if no buttons are down and weapon is empty.
Reload();
}
else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) )
{
// no fire buttons down
m_fFireOnEmpty = FALSE;
// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
if ( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < 0.0 )
{
Reload();
return;
}
WeaponIdle( );
return;
}
// catch all
if ( ShouldWeaponIdle() )
{
WeaponIdle();
}
}
You can see that the code is made in such a way that WeaponIdle()
will only be activated if none of the attack buttons are pressed (by default it used to be only the primary attack button, I think), which is exactly what we needed to achieve the desired effect. If the WeaponIdle code has to be executed anyway, there is a test for ShouldWeaponIdle()
. This returns false for all weapons but the RPG, which needs to update the laserspot. If for some reason you absolutely needed to execute the WeaponIdle code, then we would need to modify ItemPostFrame and store the buttons state from the previous frame. Now that's your problem.
You must log in to post a comment. You can login or register a new account.