mirror of
https://github.com/celisej567/cool-source-archive.git
synced 2026-09-09 20:09:18 +03:00
215 lines
5.6 KiB
C++
215 lines
5.6 KiB
C++
#include "cbase.h"
|
|
#include "basenetworkedragdoll_cl.h"
|
|
|
|
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_BaseNetworkedRagdoll, DT_BaseNetworkedRagdoll, CBaseNetworkedRagdoll )
|
|
RecvPropVector( RECVINFO(m_vecRagdollOrigin) ),
|
|
RecvPropEHandle( RECVINFO( m_hPlayer ) ),
|
|
RecvPropInt( RECVINFO( m_nModelIndex ) ),
|
|
RecvPropInt( RECVINFO(m_nForceBone) ),
|
|
RecvPropVector( RECVINFO(m_vecForce) ),
|
|
RecvPropVector( RECVINFO( m_vecRagdollVelocity ) )
|
|
END_RECV_TABLE()
|
|
|
|
LINK_ENTITY_TO_CLASS( networked_ragdoll, C_BaseNetworkedRagdoll );
|
|
|
|
C_BaseNetworkedRagdoll::~C_BaseNetworkedRagdoll()
|
|
{
|
|
PhysCleanupFrictionSounds( this );
|
|
|
|
if ( m_hPlayer )
|
|
m_hPlayer->CreateModelInstance();
|
|
}
|
|
|
|
void C_BaseNetworkedRagdoll::Interp_Copy( C_BaseAnimatingOverlay* pSourceEntity )
|
|
{
|
|
if ( !pSourceEntity )
|
|
return;
|
|
|
|
VarMapping_t* pSrc = pSourceEntity->GetVarMapping();
|
|
VarMapping_t* pDest = GetVarMapping();
|
|
|
|
// Find all the VarMapEntry_t's that represent the same variable.
|
|
for ( int i = 0; i < pDest->m_Entries.Count(); i++ )
|
|
{
|
|
VarMapEntry_t* pDestEntry = &pDest->m_Entries[i];
|
|
const char* pszName = pDestEntry->watcher->GetDebugName();
|
|
for ( int j=0; j < pSrc->m_Entries.Count(); j++ )
|
|
{
|
|
VarMapEntry_t* pSrcEntry = &pSrc->m_Entries[j];
|
|
if ( !Q_strcmp( pSrcEntry->watcher->GetDebugName(), pszName ) )
|
|
{
|
|
pDestEntry->watcher->Copy( pSrcEntry->watcher );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void C_BaseNetworkedRagdoll::ImpactTrace( trace_t* pTrace, int iDamageType, char* pCustomImpactName )
|
|
{
|
|
IPhysicsObject* pPhysicsObject = VPhysicsGetObject();
|
|
|
|
if( !pPhysicsObject )
|
|
return;
|
|
|
|
Vector dir = pTrace->endpos - pTrace->startpos;
|
|
|
|
if ( iDamageType == DMG_BLAST )
|
|
{
|
|
dir *= 4000; // adjust impact strenght
|
|
|
|
// apply force at object mass center
|
|
pPhysicsObject->ApplyForceCenter( dir );
|
|
}
|
|
else
|
|
{
|
|
Vector hitpos;
|
|
|
|
VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
|
|
VectorNormalize( dir );
|
|
|
|
dir *= 4000; // adjust impact strenght
|
|
|
|
// apply force where we hit it
|
|
pPhysicsObject->ApplyForceOffset( dir, hitpos );
|
|
}
|
|
|
|
m_pRagdoll->ResetRagdollSleepAfterTime();
|
|
}
|
|
|
|
|
|
void C_BaseNetworkedRagdoll::CreateRagdoll( void )
|
|
{
|
|
// First, initialize all our data. If we have the player's entity on our client,
|
|
// then we can make ourselves start out exactly where the player is.
|
|
C_BasePlayer* pPlayer = dynamic_cast<C_BasePlayer*>( m_hPlayer.Get() );
|
|
|
|
if ( pPlayer && !pPlayer->IsDormant() )
|
|
{
|
|
// move my current model instance to the ragdoll's so decals are preserved.
|
|
pPlayer->SnatchModelInstance( this );
|
|
|
|
VarMapping_t* varMap = GetVarMapping();
|
|
|
|
// Copy all the interpolated vars from the player entity.
|
|
// The entity uses the interpolated history to get bone velocity.
|
|
bool bRemotePlayer = (pPlayer != C_BasePlayer::GetLocalPlayer());
|
|
if ( bRemotePlayer )
|
|
{
|
|
Interp_Copy( pPlayer );
|
|
|
|
SetAbsAngles( pPlayer->GetRenderAngles() );
|
|
GetRotationInterpolator().Reset();
|
|
|
|
m_flAnimTime = pPlayer->m_flAnimTime;
|
|
SetSequence( pPlayer->GetSequence() );
|
|
m_flPlaybackRate = pPlayer->GetPlaybackRate();
|
|
}
|
|
else
|
|
{
|
|
// This is the local player, so set them in a default
|
|
// pose and slam their velocity, angles and origin
|
|
SetAbsOrigin( m_vecRagdollOrigin );
|
|
|
|
SetAbsAngles( pPlayer->GetRenderAngles() );
|
|
|
|
SetAbsVelocity( m_vecRagdollVelocity );
|
|
|
|
int iSeq = pPlayer->GetSequence();
|
|
if ( iSeq == -1 )
|
|
{
|
|
Assert( false ); // missing walk_lower?
|
|
iSeq = 0;
|
|
}
|
|
|
|
SetSequence( iSeq ); // walk_lower, basic pose
|
|
SetCycle( 0.0 );
|
|
|
|
Interp_Reset( varMap );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// overwrite network origin so later interpolation will
|
|
// use this position
|
|
SetNetworkOrigin( m_vecRagdollOrigin );
|
|
|
|
SetAbsOrigin( m_vecRagdollOrigin );
|
|
SetAbsVelocity( m_vecRagdollVelocity );
|
|
|
|
Interp_Reset( GetVarMapping() );
|
|
|
|
}
|
|
|
|
SetModelIndex( m_nModelIndex );
|
|
|
|
// Make us a ragdoll..
|
|
m_nRenderFX = kRenderFxRagdoll;
|
|
|
|
matrix3x4_t boneDelta0[MAXSTUDIOBONES];
|
|
matrix3x4_t boneDelta1[MAXSTUDIOBONES];
|
|
matrix3x4_t currentBones[MAXSTUDIOBONES];
|
|
const float boneDt = 0.05f;
|
|
|
|
if ( pPlayer && !pPlayer->IsDormant() )
|
|
pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
|
|
else
|
|
GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
|
|
|
|
InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt );
|
|
}
|
|
|
|
|
|
void C_BaseNetworkedRagdoll::OnDataChanged( DataUpdateType_t type )
|
|
{
|
|
BaseClass::OnDataChanged( type );
|
|
|
|
if ( type == DATA_UPDATE_CREATED )
|
|
CreateRagdoll();
|
|
}
|
|
|
|
IRagdoll* C_BaseNetworkedRagdoll::GetIRagdoll() const
|
|
{
|
|
return m_pRagdoll;
|
|
}
|
|
|
|
void C_BaseNetworkedRagdoll::UpdateOnRemove( void )
|
|
{
|
|
VPhysicsSetObject( NULL );
|
|
|
|
BaseClass::UpdateOnRemove();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: clear out any face/eye values stored in the material system
|
|
//-----------------------------------------------------------------------------
|
|
void C_BaseNetworkedRagdoll::SetupWeights( const matrix3x4_t* pBoneToWorld, int nFlexWeightCount, float* pFlexWeights, float* pFlexDelayedWeights )
|
|
{
|
|
BaseClass::SetupWeights( pBoneToWorld, nFlexWeightCount, pFlexWeights, pFlexDelayedWeights );
|
|
|
|
static float destweight[128];
|
|
static bool bIsInited = false;
|
|
|
|
CStudioHdr* hdr = GetModelPtr();
|
|
if ( !hdr )
|
|
return;
|
|
|
|
int nFlexDescCount = hdr->numflexdesc();
|
|
if ( nFlexDescCount )
|
|
{
|
|
Assert( !pFlexDelayedWeights );
|
|
memset( pFlexWeights, 0, nFlexWeightCount* sizeof(float) );
|
|
}
|
|
|
|
if ( m_iEyeAttachment > 0 )
|
|
{
|
|
matrix3x4_t attToWorld;
|
|
if (GetAttachment( m_iEyeAttachment, attToWorld ))
|
|
{
|
|
Vector local, tmp;
|
|
local.Init( 1000.0f, 0.0f, 0.0f );
|
|
VectorTransform( local, attToWorld, tmp );
|
|
modelrender->SetViewTarget( GetModelPtr(), GetBody(), tmp );
|
|
}
|
|
}
|
|
} |