Ru/Full Holster Sequence (HL2MP)

этот урок покажет вам как дать время для проигрывания анимации опускания оружия, перед тем как достать следующие, в Half-Life 2 Deathmatch SDK. Новая игровая система вводит код прогнозирования смены оружия на клиенте (Которая необходима только в мультиплеере). Код так же предотвращает самостоятельную активацию, когда игрок получает оружие и припасы перед появлением на карте.
==c_basecombatcharacter.h==
Add the following to the client combat character class:
Добавте в класс ( class C_BaseCombatCharacter : public C_BaseFlex к примеру после virtual bool		Weapon_CanSwitchTo(C_BaseCombatWeapon *pWeapon); ) вот это:
friend class C_ShowWeapon; // This allows CShowWeapon to access whatever it needs to update for the character
==basecombatcharacter.h==
Добавте в класс ( class CBaseCombatCharacter : public CBaseFlex к примеру после CBaseCombatWeapon	*Weapon_GetWpnForAmmo( int iAmmoIndex ); ) 
friend class CShowWeapon; // This allows CShowWeapon to access whatever it needs to update for the character
==player.h==
Добавте в класс (class CBasePlayer : public CBaseCombatCharacter к примеру после IBotController *GetBotController() { return &m_PlayerInfo; } )
	bool IsSpawning() { return m_bSpawning; } 
public:
	bool m_bSpawning;
==hl2mp_player.cpp==
Добавьте это значение до GiveNamedItem в CHL2MP_Player::GiveDefaultItems:
m_bSpawning = true;
Добавте это значение после всех вызовов GiveNamedItem в CHL2MP_Player::GiveDefaultItems:
m_bSpawning = false;
==basecombatcharacter_shared.cpp==
Удалите или закоментируйте в CBaseCombatCharacter::Weapon_Switch:
 	m_hActiveWeapon = pWeapon;
И добавте в CBaseCombatCharacter::Weapon_CanSwitchTo после:
	if (pVehicle && !pPlayer->UsingStandardWeaponsInVehicle())
		return false;
Вот это:
#ifndef CLIENT_DLL
	if(pPlayer->IsSpawning())
		return false;
#endif
}
==basecombatweapon_shared.cpp==
Найдите: bool CBaseCombatWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, int iActivity, char *szAnimExt ) и перед этой функцией добавьте этот класс, чтобы дать время для запуска deploy:
#ifdef CLIENT_DLL
#define CShowWeapon C_ShowWeapon
#endif
class CShowWeapon : public CAutoGameSystemPerFrame
{
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( );
			}
		}
		// 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;
----
Так же изменяем DefaultDeploy т.к. он использует новую систему:
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;
}
Перевод: --Slam12f 00:58, 22 July 2013 (PDT)