Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
11 KiB

5 years ago
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Support weapon and weapons contained within it
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "basetfplayer_shared.h"
#include "weapon_twohandedcontainer.h"
#include "baseviewmodel_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CWeaponTwoHandedContainer::CWeaponTwoHandedContainer()
{
m_hRightWeapon = NULL;
m_hLeftWeapon = NULL;
SetPredictionEligible( true );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CWeaponTwoHandedContainer::~CWeaponTwoHandedContainer()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponTwoHandedContainer::Spawn( void )
{
BaseClass::Spawn();
}
#ifdef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponTwoHandedContainer::GetViewmodelBoneControllers( CBaseViewModel *pViewModel, float controllers[MAXSTUDIOBONECTRLS])
{
C_BasePlayer *player = ToBasePlayer( GetOwner() );
Assert( player );
if ( !player )
return;
// Find the weapon that matches the viewmodel
if ( m_hLeftWeapon != NULL && player->GetViewModel(0) == pViewModel )
{
m_hLeftWeapon->GetViewmodelBoneControllers( pViewModel, controllers);
}
else if ( m_hRightWeapon != NULL && player->GetViewModel(1) == pViewModel )
{
m_hRightWeapon->GetViewmodelBoneControllers( pViewModel, controllers);
}
}
#else // CLIENT_DLL
void CWeaponTwoHandedContainer::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
{
// Skip this work if we're already marked for transmission.
if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
return;
// Send our left and right weapons.
if ( m_hLeftWeapon )
m_hLeftWeapon->SetTransmit( pInfo, bAlways );
if ( m_hRightWeapon )
m_hRightWeapon->SetTransmit( pInfo, bAlways );
BaseClass::SetTransmit( pInfo, bAlways );
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CWeaponTwoHandedContainer::GetViewModel( int viewmodelindex /*=0*/ )
{
if ( m_hLeftWeapon != NULL && m_hRightWeapon != NULL )
{
if ( viewmodelindex == 0 )
{
return m_hLeftWeapon->GetViewModel();
}
else
{
return m_hRightWeapon->GetViewModel();
}
}
return BaseClass::GetViewModel( viewmodelindex );
}
//-----------------------------------------------------------------------------
// Purpose: Get the string to print death notices with
//-----------------------------------------------------------------------------
char *CWeaponTwoHandedContainer::GetDeathNoticeName( void )
{
// If we have a weapon in our left slot, return it. Otherwise, return this weapon.
if ( m_hLeftWeapon )
return m_hLeftWeapon->GetDeathNoticeName();
return BaseClass::GetDeathNoticeName();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponTwoHandedContainer::ItemPostFrame( void )
{
// HACK HACK: Do nonshield first in case it disallows ItemPostFrame on shield
if ( m_hLeftWeapon != NULL )
{
// REMOVE WHEN ALL WEAPONS ARE PREDICTED!
#if defined( CLIENT_DLL )
if ( m_hLeftWeapon->IsPredicted() )
#endif
m_hLeftWeapon->ItemPostFrame();
}
if ( m_hRightWeapon != NULL && m_hRightWeapon->IsPredicted() )
{
// REMOVE WHEN ALL WEAPONS ARE PREDICTED!
#if defined( CLIENT_DLL )
if ( m_hRightWeapon->IsPredicted() )
#endif
m_hRightWeapon->ItemPostFrame();
}
}
//-----------------------------------------------------------------------------
// Purpose: Called each frame by the player PostThink, if the player's not ready to attack yet
//-----------------------------------------------------------------------------
void CWeaponTwoHandedContainer::ItemBusyFrame( void )
{
// HACK HACK: Do nonshield first in case it disallows ItemPostFrame on shield
if ( m_hLeftWeapon != NULL )
{
m_hLeftWeapon->ItemBusyFrame();
}
if ( m_hRightWeapon != NULL )
{
m_hRightWeapon->ItemBusyFrame();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponTwoHandedContainer::SetWeapons( CBaseTFCombatWeapon *left, CBaseTFCombatWeapon *right )
{
CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() );
if ( !pOwner )
return;
// Do we have a different left weapon?
if ( m_hLeftWeapon.Get() && m_hLeftWeapon != left )
{
// Holster our old one
m_hLeftWeapon->Holster();
m_hLeftWeapon = NULL;
}
// Do we have a different right weapon?
if ( m_hRightWeapon.Get() && m_hRightWeapon != right )
{
// Holster our old one
m_hRightWeapon->Holster();
m_hRightWeapon = NULL;
}
// Make new weapons if we need to
if ( !m_hLeftWeapon )
{
m_hLeftWeapon = left;
if ( m_hLeftWeapon )
{
m_hLeftWeapon->SetOwner( pOwner );
m_hLeftWeapon->Deploy();
m_hLeftWeapon->SetViewModelIndex( 0 );
//m_hLeftWeapon->SendWeaponAnim( ACT_IDLE );
}
}
if ( !m_hRightWeapon )
{
m_hRightWeapon = right;
if ( m_hRightWeapon )
{
m_hRightWeapon->SetOwner( pOwner );
m_hRightWeapon->Deploy();
m_hRightWeapon->SetViewModelIndex( 1 );
//m_hRightWeapon->SendWeaponAnim( ACT_IDLE );
UnhideSecondViewmodel();
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Unhide the second viewmodel, in case we're switching from a single weapon
//-----------------------------------------------------------------------------
void CWeaponTwoHandedContainer::UnhideSecondViewmodel( void )
{
CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() );
if ( pOwner )
{
CBaseViewModel *pVM = pOwner->GetViewModel(1);
if ( pVM )
{
pVM->RemoveEffects( EF_NODRAW );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Abort any reload we have in progress
//-----------------------------------------------------------------------------
void CWeaponTwoHandedContainer::AbortReload( void )
{
BaseClass::AbortReload();
if ( m_hLeftWeapon )
{
m_hLeftWeapon->AbortReload();
}
if ( m_hRightWeapon )
{
m_hRightWeapon->AbortReload();
}
}
//-----------------------------------------------------------------------------
// Purpose: Return true if the left weapon has any ammo
//-----------------------------------------------------------------------------
bool CWeaponTwoHandedContainer::HasAnyAmmo( void )
{
if ( m_hLeftWeapon )
return m_hLeftWeapon->HasAnyAmmo();
return BaseClass::HasAnyAmmo();
}
//-----------------------------------------------------------------------------
// Purpose: Deploy and start thinking
//-----------------------------------------------------------------------------
bool CWeaponTwoHandedContainer::Deploy( void )
{
if ( !BaseClass::Deploy() )
return false;
if ( m_hLeftWeapon )
{
m_hLeftWeapon->Deploy();
}
if ( m_hRightWeapon )
{
m_hRightWeapon->Deploy();
UnhideSecondViewmodel();
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseCombatWeapon *CWeaponTwoHandedContainer::GetLastWeapon( void )
{
if ( m_hLeftWeapon )
return m_hLeftWeapon->GetLastWeapon();
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float CWeaponTwoHandedContainer::GetDefaultAnimSpeed( void )
{
if ( m_hLeftWeapon )
return m_hLeftWeapon->GetDefaultAnimSpeed();
return 1.0;
}
//-----------------------------------------------------------------------------
// Purpose: Stop thinking and holster
//-----------------------------------------------------------------------------
bool CWeaponTwoHandedContainer::Holster( CBaseCombatWeapon *pSwitchingTo )
{
CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() );
// If I'm holstering a weapon for another weapon that supports two-handed, just switch them out
CBaseTFCombatWeapon *pWeapon = (CBaseTFCombatWeapon *)pSwitchingTo;
if ( pWeapon && pWeapon->SupportsTwoHanded() )
{
// For now, holster the left weapon and switch it.
// In the future, we might want weapons to say which side they'd like to be on
SetWeapons( pWeapon, m_hRightWeapon );
// We might need to force the new weapon to be in the right animation
if ( 0 ) //if ( m_hRightWeapon.Get() && m_hRightWeapon->IsReflectingAnimations() )
{
pWeapon->SendWeaponAnim( m_hRightWeapon->GetLastReflectedActivity() );
}
UnhideSecondViewmodel();
return false;
}
if ( m_hLeftWeapon )
{
m_hLeftWeapon->Holster(pSwitchingTo);
}
if ( m_hRightWeapon )
{
m_hRightWeapon->Holster(pSwitchingTo);
}
// We're changing to a single weapon, so hide the second viewmodel
if ( pOwner )
{
CBaseViewModel *pVM = pOwner->GetViewModel(1);
if ( pVM )
{
pVM->AddEffects( EF_NODRAW );
}
}
return BaseClass::Holster(pSwitchingTo);
}
//-----------------------------------------------------------------------------
// Purpose: Get the correct weight of our active weapon
//-----------------------------------------------------------------------------
int CWeaponTwoHandedContainer::GetWeight( void )
{
if ( !m_hLeftWeapon )
return BaseClass::GetWeight();
return m_hLeftWeapon->GetWpnData().iWeight;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : CBaseTFCombatWeapon
//-----------------------------------------------------------------------------
CBaseTFCombatWeapon *CWeaponTwoHandedContainer::GetLeftWeapon( void )
{
return m_hLeftWeapon;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : CBaseTFCombatWeapon
//-----------------------------------------------------------------------------
CBaseTFCombatWeapon *CWeaponTwoHandedContainer::GetRightWeapon( void )
{
return m_hRightWeapon;
}
LINK_ENTITY_TO_CLASS( weapon_twohandedcontainer, CWeaponTwoHandedContainer );
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponTwoHandedContainer , DT_WeaponTwoHandedContainer )
BEGIN_NETWORK_TABLE( CWeaponTwoHandedContainer , DT_WeaponTwoHandedContainer )
#if !defined( CLIENT_DLL )
SendPropEHandle( SENDINFO(m_hRightWeapon) ),
SendPropEHandle( SENDINFO(m_hLeftWeapon) ),
#else
RecvPropEHandle( RECVINFO(m_hRightWeapon ) ),
RecvPropEHandle( RECVINFO(m_hLeftWeapon ) ),
#endif
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CWeaponTwoHandedContainer )
DEFINE_PRED_FIELD( m_hRightWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_hLeftWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
#if defined( CLIENT_DLL )
// DEFINE_FIELD( m_hOldRightWeapon, FIELD_EHANDLE ),
// DEFINE_FIELD( m_hOldLeftWeapon, FIELD_EHANDLE ),
#endif
END_PREDICTION_DATA()
PRECACHE_WEAPON_REGISTER(weapon_twohandedcontainer);