Full Holster Sequence (HL2MP)
Jump to navigation
Jump to search
Overview
This tutorial provides insight on giving an active weapon time to play its holster animation before showing a newly chosen weapon.
c_basecombatcharacter.h & basecombatcharacter.h
Add the following to the combat character class:
friend class CShowWeapon;
Add the following system to this file to act as the timer for triggering the weapon deploy.
#ifdef CLIENT_DLL
#define CShowWeapon C_ShowWeapon
#endif
class CShowWeapon : public CAutoGameSystem
{
public:
bool Init()
{
ClearShowWeapon();
return true;
}
void FrameUpdatePreEntityThink()
{
if(m_pWeapon&&m_flTime<gpGlobals->curtime)
{
ShowWeapon();
}
}
void Update(float frametime)
{
FrameUpdatePreEntityThink(); // This adds compatibility to this gamesystem on the client
}
void SetShowWeapon(CBaseCombatWeapon *pWeapon, int iActivity, float delta)
{
m_pWeapon = pWeapon;
m_iActivity = iActivity;
if(delta==0)
{
ShowWeapon();
}
else
{
m_flTime = gpGlobals->curtime + delta;
}
}
void ClearShowWeapon()
{
m_pWeapon = NULL;
}
private:
void ShowWeapon()
{
Assert(m_pWeapon);
m_pWeapon->SetWeaponVisible(true);
if(m_pWeapon->GetOwner())
{
CBaseCombatWeapon *pLastWeapon = m_pWeapon->GetOwner()->GetActiveWeapon();
m_pWeapon->GetOwner()->m_hActiveWeapon = m_pWeapon;
CBasePlayer *pOwner = ToBasePlayer( m_pWeapon->GetOwner() );
if ( pOwner )
{
m_pWeapon->SetViewModel();
m_pWeapon->SendWeaponAnim( m_iActivity );
pOwner->SetNextAttack( gpGlobals->curtime + m_pWeapon->SequenceDuration() );
if ( pLastWeapon && pOwner->Weapon_ShouldSetLast( pLastWeapon, m_pWeapon ) )
{
pOwner->Weapon_SetLast( pLastWeapon->GetLastWeapon() );
}
CBaseViewModel *pViewModel = pOwner->GetViewModel();
Assert( pViewModel );
if ( pViewModel )
pViewModel->RemoveEffects( EF_NODRAW );
pOwner->ResetAutoaim( );
m_pWeapon->SetupSkin(pViewModel,pOwner);
}
}
// Can't shoot again until we've finished deploying
m_pWeapon->m_flNextSecondaryAttack = m_pWeapon->m_flNextPrimaryAttack = gpGlobals->curtime + m_pWeapon->SequenceDuration();
ClearShowWeapon();
}
CBaseCombatWeapon *m_pWeapon;
int m_iActivity;
float m_flTime;
};
static CShowWeapon g_ShowWeapon;
Modify DefaultDeploy so it utilizes the new system:
bool CBaseCombatWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, int iActivity, char *szAnimExt )
{
// Msg( "deploy %s at %f\n", GetClassname(), gpGlobals->curtime );
// Weapons that don't autoswitch away when they run out of ammo
// can still be deployed when they have no ammo.
if ( !HasAnyAmmo() && AllowsAutoSwitchFrom() )
return false;
float flSequenceDuration = 0.0f;
if(GetOwner())
{
if ( !GetOwner()->IsAlive() )
return false;
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner )
{
pOwner->SetAnimationExtension( szAnimExt );
}
CBaseCombatWeapon *pActive = GetOwner()->GetActiveWeapon();
if ( pActive && pActive->GetActivity() == ACT_VM_HOLSTER )
{
flSequenceDuration = pActive->SequenceDuration();
}
}
g_ShowWeapon.SetShowWeapon( this, iActivity, flSequenceDuration );
#ifndef CLIENT_DLL
// Cancel any pending hide events
g_EventQueue.CancelEventOn( this, "HideWeapon" );
#endif
return true;
}