Восстановление Holster анимации

From Valve Developer Community
Jump to: navigation, search
English (en)русский (ru)
... Icon-Important.png

этот урок покажет вам как дать время для проигрывания анимации опускания оружия, перед тем как достать следующие, в Half-Life 2 Deathmatch SDK. Новая игровая система вводит код прогнозирования смены оружия на клиенте (Которая необходима только в мультиплеере). Код так же предотвращает самостоятельную активацию, когда игрок получает оружие и припасы перед появлением на карте.

Note.pngNote:Не все оружия имеют holster анимацию, поэтому её нужно добавить непосредственно в модель.
Note.pngNote:Для использования в синглплеере, пропустите шаг hl2mp_player.cpp

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)