You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
691 lines
22 KiB
691 lines
22 KiB
//========= 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 "sourcevr/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
|
|
|