diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/shared/baseviewmodel_shared.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/shared/baseviewmodel_shared.cpp')
| -rw-r--r-- | mp/src/game/shared/baseviewmodel_shared.cpp | 691 |
1 files changed, 691 insertions, 0 deletions
diff --git a/mp/src/game/shared/baseviewmodel_shared.cpp b/mp/src/game/shared/baseviewmodel_shared.cpp new file mode 100644 index 00000000..7078beb0 --- /dev/null +++ b/mp/src/game/shared/baseviewmodel_shared.cpp @@ -0,0 +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<CBaseAnimating*>((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<<VIEWMODEL_ANIMATION_PARITY_BITS) - 1 );
+
+#if defined( CLIENT_DLL )
+ m_nOldAnimationParity = m_nAnimationParity;
+
+ // Force frame interpolation to start at exactly frame zero
+ m_flAnimTime = gpGlobals->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
|