mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-21 04:56:01 +08:00
Added most recent version of unmodified HL2 SDK for Episode 1 engine
This commit is contained in:
404
cl_dll/sdk/c_sdk_player.cpp
Normal file
404
cl_dll/sdk/c_sdk_player.cpp
Normal file
@ -0,0 +1,404 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_sdk_player.h"
|
||||
#include "weapon_sdkbase.h"
|
||||
#include "c_basetempentity.h"
|
||||
|
||||
#if defined( CSDKPlayer )
|
||||
#undef CSDKPlayer
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------- //
|
||||
// Player animation event. Sent to the client when a player fires, jumps, reloads, etc..
|
||||
// -------------------------------------------------------------------------------- //
|
||||
|
||||
class C_TEPlayerAnimEvent : public C_BaseTempEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_TEPlayerAnimEvent, C_BaseTempEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
// Create the effect.
|
||||
C_SDKPlayer *pPlayer = dynamic_cast< C_SDKPlayer* >( m_hPlayer.Get() );
|
||||
if ( pPlayer && !pPlayer->IsDormant() )
|
||||
{
|
||||
pPlayer->DoAnimationEvent( (PlayerAnimEvent_t)m_iEvent.Get() );
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
CNetworkHandle( CBasePlayer, m_hPlayer );
|
||||
CNetworkVar( int, m_iEvent );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_EVENT( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent, CTEPlayerAnimEvent );
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent )
|
||||
RecvPropEHandle( RECVINFO( m_hPlayer ) ),
|
||||
RecvPropInt( RECVINFO( m_iEvent ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( C_SDKPlayer, DT_SDKLocalPlayerExclusive )
|
||||
RecvPropInt( RECVINFO( m_iShotsFired ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_SDKPlayer, DT_SDKPlayer, CSDKPlayer )
|
||||
RecvPropDataTable( "sdklocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_SDKLocalPlayerExclusive) ),
|
||||
RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ),
|
||||
RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ),
|
||||
RecvPropInt( RECVINFO( m_iThrowGrenadeCounter ) ),
|
||||
RecvPropEHandle( RECVINFO( m_hRagdoll ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_SDKPlayer )
|
||||
DEFINE_PRED_FIELD( m_flCycle, FIELD_FLOAT, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ),
|
||||
DEFINE_PRED_FIELD( m_iShotsFired, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
class C_SDKRagdoll : public C_BaseAnimatingOverlay
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_SDKRagdoll, C_BaseAnimatingOverlay );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_SDKRagdoll();
|
||||
~C_SDKRagdoll();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
|
||||
int GetPlayerEntIndex() const;
|
||||
IRagdoll* GetIRagdoll() const;
|
||||
|
||||
void ImpactTrace( trace_t *pTrace, int iDamageType, char *pCustomImpactName );
|
||||
|
||||
private:
|
||||
|
||||
C_SDKRagdoll( const C_SDKRagdoll & ) {}
|
||||
|
||||
void Interp_Copy( C_BaseAnimatingOverlay *pSourceEntity );
|
||||
|
||||
void CreateRagdoll();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
EHANDLE m_hPlayer;
|
||||
CNetworkVector( m_vecRagdollVelocity );
|
||||
CNetworkVector( m_vecRagdollOrigin );
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_SDKRagdoll, DT_SDKRagdoll, CSDKRagdoll )
|
||||
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()
|
||||
|
||||
|
||||
C_SDKRagdoll::C_SDKRagdoll()
|
||||
{
|
||||
}
|
||||
|
||||
C_SDKRagdoll::~C_SDKRagdoll()
|
||||
{
|
||||
PhysCleanupFrictionSounds( this );
|
||||
}
|
||||
|
||||
void C_SDKRagdoll::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];
|
||||
for ( int j=0; j < pSrc->m_Entries.Count(); j++ )
|
||||
{
|
||||
VarMapEntry_t *pSrcEntry = &pSrc->m_Entries[j];
|
||||
if ( !Q_strcmp( pSrcEntry->watcher->GetDebugName(),
|
||||
pDestEntry->watcher->GetDebugName() ) )
|
||||
{
|
||||
pDestEntry->watcher->Copy( pSrcEntry->watcher );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_SDKRagdoll::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_SDKRagdoll::CreateRagdoll()
|
||||
{
|
||||
// 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_SDKPlayer *pPlayer = dynamic_cast< C_SDKPlayer* >( 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 = LookupSequence( "walk_lower" );
|
||||
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 );
|
||||
|
||||
// Turn it into a ragdoll.
|
||||
// Make us a ragdoll..
|
||||
m_nRenderFX = kRenderFxRagdoll;
|
||||
|
||||
BecomeRagdollOnClient( false );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void C_SDKRagdoll::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( type == DATA_UPDATE_CREATED )
|
||||
{
|
||||
CreateRagdoll();
|
||||
|
||||
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
|
||||
|
||||
if( pPhysicsObject )
|
||||
{
|
||||
AngularImpulse aVelocity(0,0,0);
|
||||
|
||||
Vector vecExaggeratedVelocity = 3 * m_vecRagdollVelocity;
|
||||
|
||||
pPhysicsObject->AddVelocity( &vecExaggeratedVelocity, &aVelocity );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IRagdoll* C_SDKRagdoll::GetIRagdoll() const
|
||||
{
|
||||
return m_pRagdoll;
|
||||
}
|
||||
|
||||
C_BaseAnimating * C_SDKPlayer::BecomeRagdollOnClient( bool bCopyEntity )
|
||||
{
|
||||
// Let the C_CSRagdoll entity do this.
|
||||
// m_builtRagdoll = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
IRagdoll* C_SDKPlayer::GetRepresentativeRagdoll() const
|
||||
{
|
||||
if ( m_hRagdoll.Get() )
|
||||
{
|
||||
C_SDKRagdoll *pRagdoll = (C_SDKRagdoll*)m_hRagdoll.Get();
|
||||
|
||||
return pRagdoll->GetIRagdoll();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
C_SDKPlayer::C_SDKPlayer() :
|
||||
m_iv_angEyeAngles( "C_SDKPlayer::m_iv_angEyeAngles" )
|
||||
{
|
||||
m_PlayerAnimState = CreatePlayerAnimState( this, this, LEGANIM_9WAY, true );
|
||||
|
||||
m_angEyeAngles.Init();
|
||||
AddVar( &m_angEyeAngles, &m_iv_angEyeAngles, LATCH_SIMULATION_VAR );
|
||||
}
|
||||
|
||||
|
||||
C_SDKPlayer::~C_SDKPlayer()
|
||||
{
|
||||
m_PlayerAnimState->Release();
|
||||
}
|
||||
|
||||
|
||||
C_SDKPlayer* C_SDKPlayer::GetLocalSDKPlayer()
|
||||
{
|
||||
return ToSDKPlayer( C_BasePlayer::GetLocalPlayer() );
|
||||
}
|
||||
|
||||
|
||||
const QAngle& C_SDKPlayer::GetRenderAngles()
|
||||
{
|
||||
if ( IsRagdoll() )
|
||||
{
|
||||
return vec3_angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_PlayerAnimState->GetRenderAngles();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_SDKPlayer::UpdateClientSideAnimation()
|
||||
{
|
||||
// Update the animation data. It does the local check here so this works when using
|
||||
// a third-person camera (and we don't have valid player angles).
|
||||
if ( this == C_SDKPlayer::GetLocalSDKPlayer() )
|
||||
m_PlayerAnimState->Update( EyeAngles()[YAW], m_angEyeAngles[PITCH] );
|
||||
else
|
||||
m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
|
||||
|
||||
BaseClass::UpdateClientSideAnimation();
|
||||
}
|
||||
|
||||
|
||||
void C_SDKPlayer::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
// C_BaseEntity assumes we're networking the entity's angles, so pretend that it
|
||||
// networked the same value we already have.
|
||||
SetNetworkAngles( GetLocalAngles() );
|
||||
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
}
|
||||
|
||||
void C_SDKPlayer::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( type == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
|
||||
void C_SDKPlayer::DoAnimationEvent( PlayerAnimEvent_t event )
|
||||
{
|
||||
if ( event == PLAYERANIMEVENT_THROW_GRENADE )
|
||||
{
|
||||
// Let the server handle this event. It will update m_iThrowGrenadeCounter and the client will
|
||||
// pick up the event in CCSPlayerAnimState.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PlayerAnimState->DoAnimationEvent( event );
|
||||
}
|
||||
}
|
||||
|
||||
bool C_SDKPlayer::ShouldDraw( void )
|
||||
{
|
||||
// If we're dead, our ragdoll will be drawn for us instead.
|
||||
if ( !IsAlive() )
|
||||
return false;
|
||||
|
||||
if( GetTeamNumber() == TEAM_SPECTATOR )
|
||||
return false;
|
||||
|
||||
if( IsLocalPlayer() && IsRagdoll() )
|
||||
return true;
|
||||
|
||||
return BaseClass::ShouldDraw();
|
||||
}
|
||||
|
||||
CWeaponSDKBase* C_SDKPlayer::GetActiveSDKWeapon() const
|
||||
{
|
||||
return dynamic_cast< CWeaponSDKBase* >( GetActiveWeapon() );
|
||||
}
|
Reference in New Issue
Block a user