From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/shared/baseviewmodel_shared.cpp | 1382 +++++++++++++-------------- 1 file changed, 691 insertions(+), 691 deletions(-) (limited to 'mp/src/game/shared/baseviewmodel_shared.cpp') diff --git a/mp/src/game/shared/baseviewmodel_shared.cpp b/mp/src/game/shared/baseviewmodel_shared.cpp index 7078beb0..99c4bfce 100644 --- a/mp/src/game/shared/baseviewmodel_shared.cpp +++ b/mp/src/game/shared/baseviewmodel_shared.cpp @@ -1,691 +1,691 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// -#include "cbase.h" -#include "baseviewmodel_shared.h" -#include "datacache/imdlcache.h" - -#if defined( CLIENT_DLL ) -#include "iprediction.h" -#include "prediction.h" -#include "client_virtualreality.h" -#include "headtrack/isourcevirtualreality.h" -#else -#include "vguiscreen.h" -#endif - -#if defined( CLIENT_DLL ) && defined( SIXENSE ) -#include "sixense/in_sixense.h" -#include "sixense/sixense_convars_extern.h" -#endif - -#ifdef SIXENSE -extern ConVar in_forceuser; -#include "iclientmode.h" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#define VIEWMODEL_ANIMATION_PARITY_BITS 3 -#define SCREEN_OVERLAY_MATERIAL "vgui/screens/vgui_overlay" - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CBaseViewModel::CBaseViewModel() -{ -#if defined( CLIENT_DLL ) - // NOTE: We do this here because the color is never transmitted for the view model. - m_nOldAnimationParity = 0; - m_EntClientFlags |= ENTCLIENTFLAG_ALWAYS_INTERPOLATE; -#endif - SetRenderColor( 255, 255, 255, 255 ); - - // View model of this weapon - m_sVMName = NULL_STRING; - // Prefix of the animations that should be used by the player carrying this weapon - m_sAnimationPrefix = NULL_STRING; - - m_nViewModelIndex = 0; - - m_nAnimationParity = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CBaseViewModel::~CBaseViewModel() -{ -} - -void CBaseViewModel::UpdateOnRemove( void ) -{ - BaseClass::UpdateOnRemove(); - - DestroyControlPanels(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseViewModel::Precache( void ) -{ -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseViewModel::Spawn( void ) -{ - Precache( ); - SetSize( Vector( -8, -4, -2), Vector(8, 4, 2) ); - SetSolid( SOLID_NONE ); -} - - -#if defined ( CSTRIKE_DLL ) && !defined ( CLIENT_DLL ) -#define VGUI_CONTROL_PANELS -#endif - -#if defined ( TF_DLL ) -#define VGUI_CONTROL_PANELS -#endif - -#ifdef INVASION_DLL -#define VGUI_CONTROL_PANELS -#endif - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseViewModel::SetControlPanelsActive( bool bState ) -{ -#if defined( VGUI_CONTROL_PANELS ) - // Activate control panel screens - for ( int i = m_hScreens.Count(); --i >= 0; ) - { - if (m_hScreens[i].Get()) - { - m_hScreens[i]->SetActive( bState ); - } - } -#endif -} - -//----------------------------------------------------------------------------- -// This is called by the base object when it's time to spawn the control panels -//----------------------------------------------------------------------------- -void CBaseViewModel::SpawnControlPanels() -{ -#if defined( VGUI_CONTROL_PANELS ) - char buf[64]; - - // Destroy existing panels - DestroyControlPanels(); - - CBaseCombatWeapon *weapon = m_hWeapon.Get(); - - if ( weapon == NULL ) - { - return; - } - - MDLCACHE_CRITICAL_SECTION(); - - // FIXME: Deal with dynamically resizing control panels? - - // If we're attached to an entity, spawn control panels on it instead of use - CBaseAnimating *pEntityToSpawnOn = this; - char *pOrgLL = "controlpanel%d_ll"; - char *pOrgUR = "controlpanel%d_ur"; - char *pAttachmentNameLL = pOrgLL; - char *pAttachmentNameUR = pOrgUR; - /* - if ( IsBuiltOnAttachment() ) - { - pEntityToSpawnOn = dynamic_cast((CBaseEntity*)m_hBuiltOnEntity.Get()); - if ( pEntityToSpawnOn ) - { - char sBuildPointLL[64]; - char sBuildPointUR[64]; - Q_snprintf( sBuildPointLL, sizeof( sBuildPointLL ), "bp%d_controlpanel%%d_ll", m_iBuiltOnPoint ); - Q_snprintf( sBuildPointUR, sizeof( sBuildPointUR ), "bp%d_controlpanel%%d_ur", m_iBuiltOnPoint ); - pAttachmentNameLL = sBuildPointLL; - pAttachmentNameUR = sBuildPointUR; - } - else - { - pEntityToSpawnOn = this; - } - } - */ - - Assert( pEntityToSpawnOn ); - - // Lookup the attachment point... - int nPanel; - for ( nPanel = 0; true; ++nPanel ) - { - Q_snprintf( buf, sizeof( buf ), pAttachmentNameLL, nPanel ); - int nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); - if (nLLAttachmentIndex <= 0) - { - // Try and use my panels then - pEntityToSpawnOn = this; - Q_snprintf( buf, sizeof( buf ), pOrgLL, nPanel ); - nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); - if (nLLAttachmentIndex <= 0) - return; - } - - Q_snprintf( buf, sizeof( buf ), pAttachmentNameUR, nPanel ); - int nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); - if (nURAttachmentIndex <= 0) - { - // Try and use my panels then - Q_snprintf( buf, sizeof( buf ), pOrgUR, nPanel ); - nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); - if (nURAttachmentIndex <= 0) - return; - } - - const char *pScreenName; - weapon->GetControlPanelInfo( nPanel, pScreenName ); - if (!pScreenName) - continue; - - const char *pScreenClassname; - weapon->GetControlPanelClassName( nPanel, pScreenClassname ); - if ( !pScreenClassname ) - continue; - - // Compute the screen size from the attachment points... - matrix3x4_t panelToWorld; - pEntityToSpawnOn->GetAttachment( nLLAttachmentIndex, panelToWorld ); - - matrix3x4_t worldToPanel; - MatrixInvert( panelToWorld, worldToPanel ); - - // Now get the lower right position + transform into panel space - Vector lr, lrlocal; - pEntityToSpawnOn->GetAttachment( nURAttachmentIndex, panelToWorld ); - MatrixGetColumn( panelToWorld, 3, lr ); - VectorTransform( lr, worldToPanel, lrlocal ); - - float flWidth = lrlocal.x; - float flHeight = lrlocal.y; - - CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, pEntityToSpawnOn, this, nLLAttachmentIndex ); - pScreen->ChangeTeam( GetTeamNumber() ); - pScreen->SetActualSize( flWidth, flHeight ); - pScreen->SetActive( false ); - pScreen->MakeVisibleOnlyToTeammates( false ); - -#ifdef INVASION_DLL - pScreen->SetOverlayMaterial( SCREEN_OVERLAY_MATERIAL ); -#endif - pScreen->SetAttachedToViewModel( true ); - int nScreen = m_hScreens.AddToTail( ); - m_hScreens[nScreen].Set( pScreen ); - } -#endif -} - -void CBaseViewModel::DestroyControlPanels() -{ -#if defined( VGUI_CONTROL_PANELS ) - // Kill the control panels - int i; - for ( i = m_hScreens.Count(); --i >= 0; ) - { - DestroyVGuiScreen( m_hScreens[i].Get() ); - } - m_hScreens.RemoveAll(); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pEntity - -//----------------------------------------------------------------------------- -void CBaseViewModel::SetOwner( CBaseEntity *pEntity ) -{ - m_hOwner = pEntity; -#if !defined( CLIENT_DLL ) - // Make sure we're linked into hierarchy - //SetParent( pEntity ); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : nIndex - -//----------------------------------------------------------------------------- -void CBaseViewModel::SetIndex( int nIndex ) -{ - m_nViewModelIndex = nIndex; - Assert( m_nViewModelIndex < (1 << VIEWMODEL_INDEX_BITS) ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CBaseViewModel::ViewModelIndex( ) const -{ - return m_nViewModelIndex; -} - -//----------------------------------------------------------------------------- -// Purpose: Pass our visibility on to our child screens -//----------------------------------------------------------------------------- -void CBaseViewModel::AddEffects( int nEffects ) -{ - if ( nEffects & EF_NODRAW ) - { - SetControlPanelsActive( false ); - } - - BaseClass::AddEffects( nEffects ); -} - -//----------------------------------------------------------------------------- -// Purpose: Pass our visibility on to our child screens -//----------------------------------------------------------------------------- -void CBaseViewModel::RemoveEffects( int nEffects ) -{ - if ( nEffects & EF_NODRAW ) - { - SetControlPanelsActive( true ); - } - - BaseClass::RemoveEffects( nEffects ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *modelname - -//----------------------------------------------------------------------------- -void CBaseViewModel::SetWeaponModel( const char *modelname, CBaseCombatWeapon *weapon ) -{ - m_hWeapon = weapon; - -#if defined( CLIENT_DLL ) - SetModel( modelname ); -#else - string_t str; - if ( modelname != NULL ) - { - str = MAKE_STRING( modelname ); - } - else - { - str = NULL_STRING; - } - - if ( str != m_sVMName ) - { - // Msg( "SetWeaponModel %s at %f\n", modelname, gpGlobals->curtime ); - m_sVMName = str; - SetModel( STRING( m_sVMName ) ); - - // Create any vgui control panels associated with the weapon - SpawnControlPanels(); - - bool showControlPanels = weapon && weapon->ShouldShowControlPanels(); - SetControlPanelsActive( showControlPanels ); - } -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : CBaseCombatWeapon -//----------------------------------------------------------------------------- -CBaseCombatWeapon *CBaseViewModel::GetOwningWeapon( void ) -{ - return m_hWeapon.Get(); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : sequence - -//----------------------------------------------------------------------------- -void CBaseViewModel::SendViewModelMatchingSequence( int sequence ) -{ - // since all we do is send a sequence number down to the client, - // set this here so other weapons code knows which sequence is playing. - SetSequence( sequence ); - - m_nAnimationParity = ( m_nAnimationParity + 1 ) & ( (1<curtime; -#else - CBaseCombatWeapon *weapon = m_hWeapon.Get(); - bool showControlPanels = weapon && weapon->ShouldShowControlPanels(); - SetControlPanelsActive( showControlPanels ); -#endif - - // Restart animation at frame 0 - SetCycle( 0 ); - ResetSequenceInfo(); -} - -#if defined( CLIENT_DLL ) -#include "ivieweffects.h" -#endif - -void CBaseViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePosition, const QAngle& eyeAngles ) -{ - // UNDONE: Calc this on the server? Disabled for now as it seems unnecessary to have this info on the server -#if defined( CLIENT_DLL ) - QAngle vmangoriginal = eyeAngles; - QAngle vmangles = eyeAngles; - Vector vmorigin = eyePosition; - - CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); - //Allow weapon lagging - if ( pWeapon != NULL ) - { -#if defined( CLIENT_DLL ) - if ( !prediction->InPrediction() ) -#endif - { - // add weapon-specific bob - pWeapon->AddViewmodelBob( this, vmorigin, vmangles ); -#if defined ( CSTRIKE_DLL ) - CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); -#endif - } - } - // Add model-specific bob even if no weapon associated (for head bob for off hand models) - AddViewModelBob( owner, vmorigin, vmangles ); -#if !defined ( CSTRIKE_DLL ) - // This was causing weapon jitter when rotating in updated CS:S; original Source had this in above InPrediction block 07/14/10 - // Add lag - CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); -#endif - -#if defined( CLIENT_DLL ) - if ( !prediction->InPrediction() ) - { - // Let the viewmodel shake at about 10% of the amplitude of the player's view - vieweffects->ApplyShake( vmorigin, vmangles, 0.1 ); - } -#endif - - if( UseVR() ) - { - g_ClientVirtualReality.OverrideViewModelTransform( vmorigin, vmangles, pWeapon && pWeapon->ShouldUseLargeViewModelVROverride() ); - } - - SetLocalOrigin( vmorigin ); - SetLocalAngles( vmangles ); - -#ifdef SIXENSE - if( g_pSixenseInput->IsEnabled() && (owner->GetObserverMode()==OBS_MODE_NONE) && !UseVR() ) - { - const float max_gun_pitch = 20.0f; - - float viewmodel_fov_ratio = g_pClientMode->GetViewModelFOV()/owner->GetFOV(); - QAngle gun_angles = g_pSixenseInput->GetViewAngleOffset() * -viewmodel_fov_ratio; - - // Clamp pitch a bit to minimize seeing back of viewmodel - if( gun_angles[PITCH] < -max_gun_pitch ) - { - gun_angles[PITCH] = -max_gun_pitch; - } - -#ifdef WIN32 // ShouldFlipViewModel comes up unresolved on osx? Mabye because it's defined inline? fixme - if( ShouldFlipViewModel() ) - { - gun_angles[YAW] *= -1.0f; - } -#endif - - vmangles = EyeAngles() + gun_angles; - - SetLocalAngles( vmangles ); - } -#endif -#endif - -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -float g_fMaxViewModelLag = 1.5f; - -void CBaseViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& original_angles ) -{ - Vector vOriginalOrigin = origin; - QAngle vOriginalAngles = angles; - - // Calculate our drift - Vector forward; - AngleVectors( angles, &forward, NULL, NULL ); - - if ( gpGlobals->frametime != 0.0f ) - { - Vector vDifference; - VectorSubtract( forward, m_vecLastFacing, vDifference ); - - float flSpeed = 5.0f; - - // If we start to lag too far behind, we'll increase the "catch up" speed. Solves the problem with fast cl_yawspeed, m_yaw or joysticks - // rotating quickly. The old code would slam lastfacing with origin causing the viewmodel to pop to a new position - float flDiff = vDifference.Length(); - if ( (flDiff > g_fMaxViewModelLag) && (g_fMaxViewModelLag > 0.0f) ) - { - float flScale = flDiff / g_fMaxViewModelLag; - flSpeed *= flScale; - } - - // FIXME: Needs to be predictable? - VectorMA( m_vecLastFacing, flSpeed * gpGlobals->frametime, vDifference, m_vecLastFacing ); - // Make sure it doesn't grow out of control!!! - VectorNormalize( m_vecLastFacing ); - VectorMA( origin, 5.0f, vDifference * -1.0f, origin ); - - Assert( m_vecLastFacing.IsValid() ); - } - - Vector right, up; - AngleVectors( original_angles, &forward, &right, &up ); - - float pitch = original_angles[ PITCH ]; - if ( pitch > 180.0f ) - pitch -= 360.0f; - else if ( pitch < -180.0f ) - pitch += 360.0f; - - if ( g_fMaxViewModelLag == 0.0f ) - { - origin = vOriginalOrigin; - angles = vOriginalAngles; - } - - //FIXME: These are the old settings that caused too many exposed polys on some models - VectorMA( origin, -pitch * 0.035f, forward, origin ); - VectorMA( origin, -pitch * 0.03f, right, origin ); - VectorMA( origin, -pitch * 0.02f, up, origin); -} - -//----------------------------------------------------------------------------- -// Stub to keep networking consistent for DEM files -//----------------------------------------------------------------------------- -#if defined( CLIENT_DLL ) - extern void RecvProxy_EffectFlags( const CRecvProxyData *pData, void *pStruct, void *pOut ); - void RecvProxy_SequenceNum( const CRecvProxyData *pData, void *pStruct, void *pOut ); -#endif - -//----------------------------------------------------------------------------- -// Purpose: Resets anim cycle when the server changes the weapon on us -//----------------------------------------------------------------------------- -#if defined( CLIENT_DLL ) -static void RecvProxy_Weapon( const CRecvProxyData *pData, void *pStruct, void *pOut ) -{ - CBaseViewModel *pViewModel = ((CBaseViewModel*)pStruct); - CBaseCombatWeapon *pOldWeapon = pViewModel->GetOwningWeapon(); - - // Chain through to the default recieve proxy ... - RecvProxy_IntToEHandle( pData, pStruct, pOut ); - - // ... and reset our cycle index if the server is switching weapons on us - CBaseCombatWeapon *pNewWeapon = pViewModel->GetOwningWeapon(); - if ( pNewWeapon != pOldWeapon ) - { - // Restart animation at frame 0 - pViewModel->SetCycle( 0 ); - pViewModel->m_flAnimTime = gpGlobals->curtime; - } -} -#endif - - -LINK_ENTITY_TO_CLASS( viewmodel, CBaseViewModel ); - -IMPLEMENT_NETWORKCLASS_ALIASED( BaseViewModel, DT_BaseViewModel ) - -BEGIN_NETWORK_TABLE_NOBASE(CBaseViewModel, DT_BaseViewModel) -#if !defined( CLIENT_DLL ) - SendPropModelIndex(SENDINFO(m_nModelIndex)), - SendPropInt (SENDINFO(m_nBody), 8), - SendPropInt (SENDINFO(m_nSkin), 10), - SendPropInt (SENDINFO(m_nSequence), 8, SPROP_UNSIGNED), - SendPropInt (SENDINFO(m_nViewModelIndex), VIEWMODEL_INDEX_BITS, SPROP_UNSIGNED), - SendPropFloat (SENDINFO(m_flPlaybackRate), 8, SPROP_ROUNDUP, -4.0, 12.0f), - SendPropInt (SENDINFO(m_fEffects), 10, SPROP_UNSIGNED), - SendPropInt (SENDINFO(m_nAnimationParity), 3, SPROP_UNSIGNED ), - SendPropEHandle (SENDINFO(m_hWeapon)), - SendPropEHandle (SENDINFO(m_hOwner)), - - SendPropInt( SENDINFO( m_nNewSequenceParity ), EF_PARITY_BITS, SPROP_UNSIGNED ), - SendPropInt( SENDINFO( m_nResetEventsParity ), EF_PARITY_BITS, SPROP_UNSIGNED ), - SendPropInt( SENDINFO( m_nMuzzleFlashParity ), EF_MUZZLEFLASH_BITS, SPROP_UNSIGNED ), - -#if !defined( INVASION_DLL ) && !defined( INVASION_CLIENT_DLL ) - SendPropArray (SendPropFloat(SENDINFO_ARRAY(m_flPoseParameter), 8, 0, 0.0f, 1.0f), m_flPoseParameter), -#endif -#else - RecvPropInt (RECVINFO(m_nModelIndex)), - RecvPropInt (RECVINFO(m_nSkin)), - RecvPropInt (RECVINFO(m_nBody)), - RecvPropInt (RECVINFO(m_nSequence), 0, RecvProxy_SequenceNum ), - RecvPropInt (RECVINFO(m_nViewModelIndex)), - RecvPropFloat (RECVINFO(m_flPlaybackRate)), - RecvPropInt (RECVINFO(m_fEffects), 0, RecvProxy_EffectFlags ), - RecvPropInt (RECVINFO(m_nAnimationParity)), - RecvPropEHandle (RECVINFO(m_hWeapon), RecvProxy_Weapon ), - RecvPropEHandle (RECVINFO(m_hOwner)), - - RecvPropInt( RECVINFO( m_nNewSequenceParity )), - RecvPropInt( RECVINFO( m_nResetEventsParity )), - RecvPropInt( RECVINFO( m_nMuzzleFlashParity )), - -#if !defined( INVASION_DLL ) && !defined( INVASION_CLIENT_DLL ) - RecvPropArray(RecvPropFloat(RECVINFO(m_flPoseParameter[0]) ), m_flPoseParameter ), -#endif -#endif -END_NETWORK_TABLE() - -#ifdef CLIENT_DLL - -BEGIN_PREDICTION_DATA( CBaseViewModel ) - - // Networked - DEFINE_PRED_FIELD( m_nModelIndex, FIELD_SHORT, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ), - DEFINE_PRED_FIELD( m_nSkin, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD( m_nBody, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD( m_nSequence, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD( m_nViewModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD_TOL( m_flPlaybackRate, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, 0.125f ), - DEFINE_PRED_FIELD( m_fEffects, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_OVERRIDE ), - DEFINE_PRED_FIELD( m_nAnimationParity, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD( m_hWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD( m_flAnimTime, FIELD_FLOAT, 0 ), - - DEFINE_FIELD( m_hOwner, FIELD_EHANDLE ), - DEFINE_FIELD( m_flTimeWeaponIdle, FIELD_FLOAT ), - DEFINE_FIELD( m_Activity, FIELD_INTEGER ), - DEFINE_PRED_FIELD( m_flCycle, FIELD_FLOAT, FTYPEDESC_PRIVATE | FTYPEDESC_OVERRIDE | FTYPEDESC_NOERRORCHECK ), - -END_PREDICTION_DATA() - -void RecvProxy_SequenceNum( const CRecvProxyData *pData, void *pStruct, void *pOut ) -{ - CBaseViewModel *model = (CBaseViewModel *)pStruct; - if (pData->m_Value.m_Int != model->GetSequence()) - { - MDLCACHE_CRITICAL_SECTION(); - - model->SetSequence(pData->m_Value.m_Int); - model->m_flAnimTime = gpGlobals->curtime; - model->SetCycle(0); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CBaseViewModel::LookupAttachment( const char *pAttachmentName ) -{ - if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) - return m_hWeapon.Get()->LookupAttachment( pAttachmentName ); - - return BaseClass::LookupAttachment( pAttachmentName ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CBaseViewModel::GetAttachment( int number, matrix3x4_t &matrix ) -{ - if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) - return m_hWeapon.Get()->GetAttachment( number, matrix ); - - return BaseClass::GetAttachment( number, matrix ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CBaseViewModel::GetAttachment( int number, Vector &origin ) -{ - if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) - return m_hWeapon.Get()->GetAttachment( number, origin ); - - return BaseClass::GetAttachment( number, origin ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CBaseViewModel::GetAttachment( int number, Vector &origin, QAngle &angles ) -{ - if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) - return m_hWeapon.Get()->GetAttachment( number, origin, angles ); - - return BaseClass::GetAttachment( number, origin, angles ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CBaseViewModel::GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel ) -{ - if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) - return m_hWeapon.Get()->GetAttachmentVelocity( number, originVel, angleVel ); - - return BaseClass::GetAttachmentVelocity( number, originVel, angleVel ); -} - -#endif +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "baseviewmodel_shared.h" +#include "datacache/imdlcache.h" + +#if defined( CLIENT_DLL ) +#include "iprediction.h" +#include "prediction.h" +#include "client_virtualreality.h" +#include "headtrack/isourcevirtualreality.h" +#else +#include "vguiscreen.h" +#endif + +#if defined( CLIENT_DLL ) && defined( SIXENSE ) +#include "sixense/in_sixense.h" +#include "sixense/sixense_convars_extern.h" +#endif + +#ifdef SIXENSE +extern ConVar in_forceuser; +#include "iclientmode.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define VIEWMODEL_ANIMATION_PARITY_BITS 3 +#define SCREEN_OVERLAY_MATERIAL "vgui/screens/vgui_overlay" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CBaseViewModel::CBaseViewModel() +{ +#if defined( CLIENT_DLL ) + // NOTE: We do this here because the color is never transmitted for the view model. + m_nOldAnimationParity = 0; + m_EntClientFlags |= ENTCLIENTFLAG_ALWAYS_INTERPOLATE; +#endif + SetRenderColor( 255, 255, 255, 255 ); + + // View model of this weapon + m_sVMName = NULL_STRING; + // Prefix of the animations that should be used by the player carrying this weapon + m_sAnimationPrefix = NULL_STRING; + + m_nViewModelIndex = 0; + + m_nAnimationParity = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CBaseViewModel::~CBaseViewModel() +{ +} + +void CBaseViewModel::UpdateOnRemove( void ) +{ + BaseClass::UpdateOnRemove(); + + DestroyControlPanels(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseViewModel::Precache( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseViewModel::Spawn( void ) +{ + Precache( ); + SetSize( Vector( -8, -4, -2), Vector(8, 4, 2) ); + SetSolid( SOLID_NONE ); +} + + +#if defined ( CSTRIKE_DLL ) && !defined ( CLIENT_DLL ) +#define VGUI_CONTROL_PANELS +#endif + +#if defined ( TF_DLL ) +#define VGUI_CONTROL_PANELS +#endif + +#ifdef INVASION_DLL +#define VGUI_CONTROL_PANELS +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseViewModel::SetControlPanelsActive( bool bState ) +{ +#if defined( VGUI_CONTROL_PANELS ) + // Activate control panel screens + for ( int i = m_hScreens.Count(); --i >= 0; ) + { + if (m_hScreens[i].Get()) + { + m_hScreens[i]->SetActive( bState ); + } + } +#endif +} + +//----------------------------------------------------------------------------- +// This is called by the base object when it's time to spawn the control panels +//----------------------------------------------------------------------------- +void CBaseViewModel::SpawnControlPanels() +{ +#if defined( VGUI_CONTROL_PANELS ) + char buf[64]; + + // Destroy existing panels + DestroyControlPanels(); + + CBaseCombatWeapon *weapon = m_hWeapon.Get(); + + if ( weapon == NULL ) + { + return; + } + + MDLCACHE_CRITICAL_SECTION(); + + // FIXME: Deal with dynamically resizing control panels? + + // If we're attached to an entity, spawn control panels on it instead of use + CBaseAnimating *pEntityToSpawnOn = this; + char *pOrgLL = "controlpanel%d_ll"; + char *pOrgUR = "controlpanel%d_ur"; + char *pAttachmentNameLL = pOrgLL; + char *pAttachmentNameUR = pOrgUR; + /* + if ( IsBuiltOnAttachment() ) + { + pEntityToSpawnOn = dynamic_cast((CBaseEntity*)m_hBuiltOnEntity.Get()); + if ( pEntityToSpawnOn ) + { + char sBuildPointLL[64]; + char sBuildPointUR[64]; + Q_snprintf( sBuildPointLL, sizeof( sBuildPointLL ), "bp%d_controlpanel%%d_ll", m_iBuiltOnPoint ); + Q_snprintf( sBuildPointUR, sizeof( sBuildPointUR ), "bp%d_controlpanel%%d_ur", m_iBuiltOnPoint ); + pAttachmentNameLL = sBuildPointLL; + pAttachmentNameUR = sBuildPointUR; + } + else + { + pEntityToSpawnOn = this; + } + } + */ + + Assert( pEntityToSpawnOn ); + + // Lookup the attachment point... + int nPanel; + for ( nPanel = 0; true; ++nPanel ) + { + Q_snprintf( buf, sizeof( buf ), pAttachmentNameLL, nPanel ); + int nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); + if (nLLAttachmentIndex <= 0) + { + // Try and use my panels then + pEntityToSpawnOn = this; + Q_snprintf( buf, sizeof( buf ), pOrgLL, nPanel ); + nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); + if (nLLAttachmentIndex <= 0) + return; + } + + Q_snprintf( buf, sizeof( buf ), pAttachmentNameUR, nPanel ); + int nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); + if (nURAttachmentIndex <= 0) + { + // Try and use my panels then + Q_snprintf( buf, sizeof( buf ), pOrgUR, nPanel ); + nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf); + if (nURAttachmentIndex <= 0) + return; + } + + const char *pScreenName; + weapon->GetControlPanelInfo( nPanel, pScreenName ); + if (!pScreenName) + continue; + + const char *pScreenClassname; + weapon->GetControlPanelClassName( nPanel, pScreenClassname ); + if ( !pScreenClassname ) + continue; + + // Compute the screen size from the attachment points... + matrix3x4_t panelToWorld; + pEntityToSpawnOn->GetAttachment( nLLAttachmentIndex, panelToWorld ); + + matrix3x4_t worldToPanel; + MatrixInvert( panelToWorld, worldToPanel ); + + // Now get the lower right position + transform into panel space + Vector lr, lrlocal; + pEntityToSpawnOn->GetAttachment( nURAttachmentIndex, panelToWorld ); + MatrixGetColumn( panelToWorld, 3, lr ); + VectorTransform( lr, worldToPanel, lrlocal ); + + float flWidth = lrlocal.x; + float flHeight = lrlocal.y; + + CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, pEntityToSpawnOn, this, nLLAttachmentIndex ); + pScreen->ChangeTeam( GetTeamNumber() ); + pScreen->SetActualSize( flWidth, flHeight ); + pScreen->SetActive( false ); + pScreen->MakeVisibleOnlyToTeammates( false ); + +#ifdef INVASION_DLL + pScreen->SetOverlayMaterial( SCREEN_OVERLAY_MATERIAL ); +#endif + pScreen->SetAttachedToViewModel( true ); + int nScreen = m_hScreens.AddToTail( ); + m_hScreens[nScreen].Set( pScreen ); + } +#endif +} + +void CBaseViewModel::DestroyControlPanels() +{ +#if defined( VGUI_CONTROL_PANELS ) + // Kill the control panels + int i; + for ( i = m_hScreens.Count(); --i >= 0; ) + { + DestroyVGuiScreen( m_hScreens[i].Get() ); + } + m_hScreens.RemoveAll(); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pEntity - +//----------------------------------------------------------------------------- +void CBaseViewModel::SetOwner( CBaseEntity *pEntity ) +{ + m_hOwner = pEntity; +#if !defined( CLIENT_DLL ) + // Make sure we're linked into hierarchy + //SetParent( pEntity ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : nIndex - +//----------------------------------------------------------------------------- +void CBaseViewModel::SetIndex( int nIndex ) +{ + m_nViewModelIndex = nIndex; + Assert( m_nViewModelIndex < (1 << VIEWMODEL_INDEX_BITS) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CBaseViewModel::ViewModelIndex( ) const +{ + return m_nViewModelIndex; +} + +//----------------------------------------------------------------------------- +// Purpose: Pass our visibility on to our child screens +//----------------------------------------------------------------------------- +void CBaseViewModel::AddEffects( int nEffects ) +{ + if ( nEffects & EF_NODRAW ) + { + SetControlPanelsActive( false ); + } + + BaseClass::AddEffects( nEffects ); +} + +//----------------------------------------------------------------------------- +// Purpose: Pass our visibility on to our child screens +//----------------------------------------------------------------------------- +void CBaseViewModel::RemoveEffects( int nEffects ) +{ + if ( nEffects & EF_NODRAW ) + { + SetControlPanelsActive( true ); + } + + BaseClass::RemoveEffects( nEffects ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *modelname - +//----------------------------------------------------------------------------- +void CBaseViewModel::SetWeaponModel( const char *modelname, CBaseCombatWeapon *weapon ) +{ + m_hWeapon = weapon; + +#if defined( CLIENT_DLL ) + SetModel( modelname ); +#else + string_t str; + if ( modelname != NULL ) + { + str = MAKE_STRING( modelname ); + } + else + { + str = NULL_STRING; + } + + if ( str != m_sVMName ) + { + // Msg( "SetWeaponModel %s at %f\n", modelname, gpGlobals->curtime ); + m_sVMName = str; + SetModel( STRING( m_sVMName ) ); + + // Create any vgui control panels associated with the weapon + SpawnControlPanels(); + + bool showControlPanels = weapon && weapon->ShouldShowControlPanels(); + SetControlPanelsActive( showControlPanels ); + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : CBaseCombatWeapon +//----------------------------------------------------------------------------- +CBaseCombatWeapon *CBaseViewModel::GetOwningWeapon( void ) +{ + return m_hWeapon.Get(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : sequence - +//----------------------------------------------------------------------------- +void CBaseViewModel::SendViewModelMatchingSequence( int sequence ) +{ + // since all we do is send a sequence number down to the client, + // set this here so other weapons code knows which sequence is playing. + SetSequence( sequence ); + + m_nAnimationParity = ( m_nAnimationParity + 1 ) & ( (1<curtime; +#else + CBaseCombatWeapon *weapon = m_hWeapon.Get(); + bool showControlPanels = weapon && weapon->ShouldShowControlPanels(); + SetControlPanelsActive( showControlPanels ); +#endif + + // Restart animation at frame 0 + SetCycle( 0 ); + ResetSequenceInfo(); +} + +#if defined( CLIENT_DLL ) +#include "ivieweffects.h" +#endif + +void CBaseViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePosition, const QAngle& eyeAngles ) +{ + // UNDONE: Calc this on the server? Disabled for now as it seems unnecessary to have this info on the server +#if defined( CLIENT_DLL ) + QAngle vmangoriginal = eyeAngles; + QAngle vmangles = eyeAngles; + Vector vmorigin = eyePosition; + + CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); + //Allow weapon lagging + if ( pWeapon != NULL ) + { +#if defined( CLIENT_DLL ) + if ( !prediction->InPrediction() ) +#endif + { + // add weapon-specific bob + pWeapon->AddViewmodelBob( this, vmorigin, vmangles ); +#if defined ( CSTRIKE_DLL ) + CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); +#endif + } + } + // Add model-specific bob even if no weapon associated (for head bob for off hand models) + AddViewModelBob( owner, vmorigin, vmangles ); +#if !defined ( CSTRIKE_DLL ) + // This was causing weapon jitter when rotating in updated CS:S; original Source had this in above InPrediction block 07/14/10 + // Add lag + CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); +#endif + +#if defined( CLIENT_DLL ) + if ( !prediction->InPrediction() ) + { + // Let the viewmodel shake at about 10% of the amplitude of the player's view + vieweffects->ApplyShake( vmorigin, vmangles, 0.1 ); + } +#endif + + if( UseVR() ) + { + g_ClientVirtualReality.OverrideViewModelTransform( vmorigin, vmangles, pWeapon && pWeapon->ShouldUseLargeViewModelVROverride() ); + } + + SetLocalOrigin( vmorigin ); + SetLocalAngles( vmangles ); + +#ifdef SIXENSE + if( g_pSixenseInput->IsEnabled() && (owner->GetObserverMode()==OBS_MODE_NONE) && !UseVR() ) + { + const float max_gun_pitch = 20.0f; + + float viewmodel_fov_ratio = g_pClientMode->GetViewModelFOV()/owner->GetFOV(); + QAngle gun_angles = g_pSixenseInput->GetViewAngleOffset() * -viewmodel_fov_ratio; + + // Clamp pitch a bit to minimize seeing back of viewmodel + if( gun_angles[PITCH] < -max_gun_pitch ) + { + gun_angles[PITCH] = -max_gun_pitch; + } + +#ifdef WIN32 // ShouldFlipViewModel comes up unresolved on osx? Mabye because it's defined inline? fixme + if( ShouldFlipViewModel() ) + { + gun_angles[YAW] *= -1.0f; + } +#endif + + vmangles = EyeAngles() + gun_angles; + + SetLocalAngles( vmangles ); + } +#endif +#endif + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +float g_fMaxViewModelLag = 1.5f; + +void CBaseViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& original_angles ) +{ + Vector vOriginalOrigin = origin; + QAngle vOriginalAngles = angles; + + // Calculate our drift + Vector forward; + AngleVectors( angles, &forward, NULL, NULL ); + + if ( gpGlobals->frametime != 0.0f ) + { + Vector vDifference; + VectorSubtract( forward, m_vecLastFacing, vDifference ); + + float flSpeed = 5.0f; + + // If we start to lag too far behind, we'll increase the "catch up" speed. Solves the problem with fast cl_yawspeed, m_yaw or joysticks + // rotating quickly. The old code would slam lastfacing with origin causing the viewmodel to pop to a new position + float flDiff = vDifference.Length(); + if ( (flDiff > g_fMaxViewModelLag) && (g_fMaxViewModelLag > 0.0f) ) + { + float flScale = flDiff / g_fMaxViewModelLag; + flSpeed *= flScale; + } + + // FIXME: Needs to be predictable? + VectorMA( m_vecLastFacing, flSpeed * gpGlobals->frametime, vDifference, m_vecLastFacing ); + // Make sure it doesn't grow out of control!!! + VectorNormalize( m_vecLastFacing ); + VectorMA( origin, 5.0f, vDifference * -1.0f, origin ); + + Assert( m_vecLastFacing.IsValid() ); + } + + Vector right, up; + AngleVectors( original_angles, &forward, &right, &up ); + + float pitch = original_angles[ PITCH ]; + if ( pitch > 180.0f ) + pitch -= 360.0f; + else if ( pitch < -180.0f ) + pitch += 360.0f; + + if ( g_fMaxViewModelLag == 0.0f ) + { + origin = vOriginalOrigin; + angles = vOriginalAngles; + } + + //FIXME: These are the old settings that caused too many exposed polys on some models + VectorMA( origin, -pitch * 0.035f, forward, origin ); + VectorMA( origin, -pitch * 0.03f, right, origin ); + VectorMA( origin, -pitch * 0.02f, up, origin); +} + +//----------------------------------------------------------------------------- +// Stub to keep networking consistent for DEM files +//----------------------------------------------------------------------------- +#if defined( CLIENT_DLL ) + extern void RecvProxy_EffectFlags( const CRecvProxyData *pData, void *pStruct, void *pOut ); + void RecvProxy_SequenceNum( const CRecvProxyData *pData, void *pStruct, void *pOut ); +#endif + +//----------------------------------------------------------------------------- +// Purpose: Resets anim cycle when the server changes the weapon on us +//----------------------------------------------------------------------------- +#if defined( CLIENT_DLL ) +static void RecvProxy_Weapon( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + CBaseViewModel *pViewModel = ((CBaseViewModel*)pStruct); + CBaseCombatWeapon *pOldWeapon = pViewModel->GetOwningWeapon(); + + // Chain through to the default recieve proxy ... + RecvProxy_IntToEHandle( pData, pStruct, pOut ); + + // ... and reset our cycle index if the server is switching weapons on us + CBaseCombatWeapon *pNewWeapon = pViewModel->GetOwningWeapon(); + if ( pNewWeapon != pOldWeapon ) + { + // Restart animation at frame 0 + pViewModel->SetCycle( 0 ); + pViewModel->m_flAnimTime = gpGlobals->curtime; + } +} +#endif + + +LINK_ENTITY_TO_CLASS( viewmodel, CBaseViewModel ); + +IMPLEMENT_NETWORKCLASS_ALIASED( BaseViewModel, DT_BaseViewModel ) + +BEGIN_NETWORK_TABLE_NOBASE(CBaseViewModel, DT_BaseViewModel) +#if !defined( CLIENT_DLL ) + SendPropModelIndex(SENDINFO(m_nModelIndex)), + SendPropInt (SENDINFO(m_nBody), 8), + SendPropInt (SENDINFO(m_nSkin), 10), + SendPropInt (SENDINFO(m_nSequence), 8, SPROP_UNSIGNED), + SendPropInt (SENDINFO(m_nViewModelIndex), VIEWMODEL_INDEX_BITS, SPROP_UNSIGNED), + SendPropFloat (SENDINFO(m_flPlaybackRate), 8, SPROP_ROUNDUP, -4.0, 12.0f), + SendPropInt (SENDINFO(m_fEffects), 10, SPROP_UNSIGNED), + SendPropInt (SENDINFO(m_nAnimationParity), 3, SPROP_UNSIGNED ), + SendPropEHandle (SENDINFO(m_hWeapon)), + SendPropEHandle (SENDINFO(m_hOwner)), + + SendPropInt( SENDINFO( m_nNewSequenceParity ), EF_PARITY_BITS, SPROP_UNSIGNED ), + SendPropInt( SENDINFO( m_nResetEventsParity ), EF_PARITY_BITS, SPROP_UNSIGNED ), + SendPropInt( SENDINFO( m_nMuzzleFlashParity ), EF_MUZZLEFLASH_BITS, SPROP_UNSIGNED ), + +#if !defined( INVASION_DLL ) && !defined( INVASION_CLIENT_DLL ) + SendPropArray (SendPropFloat(SENDINFO_ARRAY(m_flPoseParameter), 8, 0, 0.0f, 1.0f), m_flPoseParameter), +#endif +#else + RecvPropInt (RECVINFO(m_nModelIndex)), + RecvPropInt (RECVINFO(m_nSkin)), + RecvPropInt (RECVINFO(m_nBody)), + RecvPropInt (RECVINFO(m_nSequence), 0, RecvProxy_SequenceNum ), + RecvPropInt (RECVINFO(m_nViewModelIndex)), + RecvPropFloat (RECVINFO(m_flPlaybackRate)), + RecvPropInt (RECVINFO(m_fEffects), 0, RecvProxy_EffectFlags ), + RecvPropInt (RECVINFO(m_nAnimationParity)), + RecvPropEHandle (RECVINFO(m_hWeapon), RecvProxy_Weapon ), + RecvPropEHandle (RECVINFO(m_hOwner)), + + RecvPropInt( RECVINFO( m_nNewSequenceParity )), + RecvPropInt( RECVINFO( m_nResetEventsParity )), + RecvPropInt( RECVINFO( m_nMuzzleFlashParity )), + +#if !defined( INVASION_DLL ) && !defined( INVASION_CLIENT_DLL ) + RecvPropArray(RecvPropFloat(RECVINFO(m_flPoseParameter[0]) ), m_flPoseParameter ), +#endif +#endif +END_NETWORK_TABLE() + +#ifdef CLIENT_DLL + +BEGIN_PREDICTION_DATA( CBaseViewModel ) + + // Networked + DEFINE_PRED_FIELD( m_nModelIndex, FIELD_SHORT, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ), + DEFINE_PRED_FIELD( m_nSkin, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_nBody, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_nSequence, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_nViewModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD_TOL( m_flPlaybackRate, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, 0.125f ), + DEFINE_PRED_FIELD( m_fEffects, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_OVERRIDE ), + DEFINE_PRED_FIELD( m_nAnimationParity, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_hWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_flAnimTime, FIELD_FLOAT, 0 ), + + DEFINE_FIELD( m_hOwner, FIELD_EHANDLE ), + DEFINE_FIELD( m_flTimeWeaponIdle, FIELD_FLOAT ), + DEFINE_FIELD( m_Activity, FIELD_INTEGER ), + DEFINE_PRED_FIELD( m_flCycle, FIELD_FLOAT, FTYPEDESC_PRIVATE | FTYPEDESC_OVERRIDE | FTYPEDESC_NOERRORCHECK ), + +END_PREDICTION_DATA() + +void RecvProxy_SequenceNum( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + CBaseViewModel *model = (CBaseViewModel *)pStruct; + if (pData->m_Value.m_Int != model->GetSequence()) + { + MDLCACHE_CRITICAL_SECTION(); + + model->SetSequence(pData->m_Value.m_Int); + model->m_flAnimTime = gpGlobals->curtime; + model->SetCycle(0); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CBaseViewModel::LookupAttachment( const char *pAttachmentName ) +{ + if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) + return m_hWeapon.Get()->LookupAttachment( pAttachmentName ); + + return BaseClass::LookupAttachment( pAttachmentName ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseViewModel::GetAttachment( int number, matrix3x4_t &matrix ) +{ + if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) + return m_hWeapon.Get()->GetAttachment( number, matrix ); + + return BaseClass::GetAttachment( number, matrix ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseViewModel::GetAttachment( int number, Vector &origin ) +{ + if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) + return m_hWeapon.Get()->GetAttachment( number, origin ); + + return BaseClass::GetAttachment( number, origin ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseViewModel::GetAttachment( int number, Vector &origin, QAngle &angles ) +{ + if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) + return m_hWeapon.Get()->GetAttachment( number, origin, angles ); + + return BaseClass::GetAttachment( number, origin, angles ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseViewModel::GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel ) +{ + if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) + return m_hWeapon.Get()->GetAttachmentVelocity( number, originVel, angleVel ); + + return BaseClass::GetAttachmentVelocity( number, originVel, angleVel ); +} + +#endif -- cgit v1.2.3