diff options
Diffstat (limited to 'mp/src/game/shared/baseviewmodel_shared.cpp')
| -rw-r--r-- | mp/src/game/shared/baseviewmodel_shared.cpp | 1382 |
1 files changed, 691 insertions, 691 deletions
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<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
+//========= 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 |