Files
cool-source-archive/game/server/sdk/basenetworkedplayer.cpp
Totterynine 4b952b0e4e init
2021-09-13 15:31:53 +05:00

178 lines
6.0 KiB
C++

#include "cbase.h"
#include "basenetworkedplayer.h"
#include "predicted_viewmodel.h"
#include "ilagcompensationmanager.h"
#include "basenetworkedragdoll.h"
//* **************** CTEPlayerAnimEvent* *********************
IMPLEMENT_SERVERCLASS_ST_NOBASE( CTEPlayerAnimEvent, DT_TEPlayerAnimEvent )
SendPropEHandle( SENDINFO( m_hPlayer ) ),
SendPropInt( SENDINFO( m_iEvent ), Q_log2( PLAYERANIMEVENT_COUNT ) + 1, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_nData ), 32 )
END_SEND_TABLE()
static CTEPlayerAnimEvent g_TEPlayerAnimEvent( "PlayerAnimEvent" );
void TE_PlayerAnimEvent( CBasePlayer* pPlayer, PlayerAnimEvent_t event, int nData )
{
CPVSFilter filter( (const Vector&)pPlayer->EyePosition() );
filter.RemoveRecipient( pPlayer );
g_TEPlayerAnimEvent.m_hPlayer = pPlayer;
g_TEPlayerAnimEvent.m_iEvent = event;
g_TEPlayerAnimEvent.m_nData = nData;
g_TEPlayerAnimEvent.Create( filter, 0 );
}
//* *************** CBaseNetworkedPlayer* ******************
extern void SendProxy_Origin( const SendProp* pProp, const void* pStruct, const void* pData, DVariant* pOut, int iElement, int objectID );
BEGIN_SEND_TABLE_NOBASE( CBaseNetworkedPlayer, DT_BaseNetworkedPlayerExclusive )
// send a hi-res origin to the local player for use in prediction
SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
SendPropFloat( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 8, SPROP_CHANGES_OFTEN, -90.0f, 90.0f ),
END_SEND_TABLE()
BEGIN_SEND_TABLE_NOBASE( CBaseNetworkedPlayer, DT_BaseNetworkedPlayerNonLocalExclusive )
// send a lo-res origin to other players
SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_COORD_MP_LOWPRECISION|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
SendPropFloat( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 8, SPROP_CHANGES_OFTEN, -90.0f, 90.0f ),
SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 10, SPROP_CHANGES_OFTEN ),
END_SEND_TABLE()
IMPLEMENT_SERVERCLASS_ST(CBaseNetworkedPlayer, DT_BaseNetworkedPlayer )
// These aren't needed either because we use client-side animation, or because they are being moved to the local/non-local table.
SendPropExclude( "DT_BaseAnimating", "m_flPoseParameter" ),
SendPropExclude( "DT_BaseAnimating", "m_flPlaybackRate" ),
SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
SendPropExclude( "DT_BaseAnimating", "m_nNewSequenceParity" ),
SendPropExclude( "DT_BaseAnimating", "m_nResetEventsParity" ),
SendPropExclude( "DT_BaseEntity", "m_angRotation" ),
SendPropExclude( "DT_BaseAnimatingOverlay", "overlay_vars" ),
SendPropExclude( "DT_BaseEntity", "m_vecOrigin" ),
SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ),
SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ),
// New props
SendPropBool( SENDINFO( m_bSpawnInterpCounter) ),
SendPropEHandle( SENDINFO( m_hRagdoll ) ),
// Data that only gets sent to the local player.
SendPropDataTable( "netplayer_localdata", 0, &REFERENCE_SEND_TABLE(DT_BaseNetworkedPlayerExclusive), SendProxy_SendLocalDataTable ),
// Data that gets sent to all other players
SendPropDataTable( "netplayer_nonlocaldata", 0, &REFERENCE_SEND_TABLE(DT_BaseNetworkedPlayerNonLocalExclusive), SendProxy_SendNonLocalDataTable ),
END_NETWORK_TABLE()
//* ****************** FUNCTIONS* *********************
CBaseNetworkedPlayer::CBaseNetworkedPlayer() {
UseClientSideAnimation();
SetPredictionEligible(true);
m_bSpawnInterpCounter = false;
m_angEyeAngles.Init();
ragdoll_ent_name = "networked_ragdoll";
}
CBaseNetworkedPlayer::~CBaseNetworkedPlayer() {
m_PlayerAnimState->Release();
RemoveRagdollEntity();
}
void CBaseNetworkedPlayer::Spawn()
{
BaseClass::Spawn();
// used to not interp players when they spawn
m_bSpawnInterpCounter = !m_bSpawnInterpCounter;
RemoveSolidFlags( FSOLID_NOT_SOLID );
}
void CBaseNetworkedPlayer::CreateViewModel( int index )
{
Assert( index >= 0 && index < MAX_VIEWMODELS );
if ( GetViewModel(index) )
return;
CPredictedViewModel* vm = (CPredictedViewModel*)CreateEntityByName( "predicted_viewmodel" );
if ( vm )
{
vm->SetAbsOrigin( GetAbsOrigin() );
vm->SetOwner( this );
vm->SetIndex( index );
DispatchSpawn( vm );
vm->FollowEntity( this, false );
m_hViewModel.Set( index, vm );
}
}
void CBaseNetworkedPlayer::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
{
m_PlayerAnimState->DoAnimationEvent( event, nData ); // execute on server
TE_PlayerAnimEvent( this, event, nData ); // transmit to clients
}
void CBaseNetworkedPlayer::PostThink()
{
BaseClass::PostThink();
// Keep the model upright; pose params will handle pitch aiming.
QAngle angles = GetLocalAngles();
angles[PITCH] = 0;
SetLocalAngles(angles);
m_angEyeAngles = EyeAngles();
m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
}
void CBaseNetworkedPlayer::FireBullets ( const FireBulletsInfo_t &info )
{
lagcompensation->StartLagCompensation( this, this->GetCurrentCommand() );
BaseClass::FireBullets(info);
lagcompensation->FinishLagCompensation( this );
}
void CBaseNetworkedPlayer::Event_Killed( const CTakeDamageInfo &info )
{
// show killer in death cam mode
if( info.GetAttacker() && info.GetAttacker()->IsPlayer() && info.GetAttacker() != (CBaseEntity*)this )
{
m_hObserverTarget.Set( info.GetAttacker() );
SetFOV( this, 0 ); // reset
}
else
m_hObserverTarget.Set( NULL );
CreateRagdollEntity();
BaseClass::Event_Killed( info );
AddEffects(EF_NODRAW);
}
void CBaseNetworkedPlayer::RemoveRagdollEntity()
{
if ( m_hRagdoll.Get() )
UTIL_RemoveImmediate( m_hRagdoll.Get() );
}
void CBaseNetworkedPlayer::CreateRagdollEntity()
{
RemoveRagdollEntity();
CBaseNetworkedRagdoll* pRagdoll = (CBaseNetworkedRagdoll*)CreateEntityByName(ragdoll_ent_name);
pRagdoll->m_hPlayer = this;
pRagdoll->m_vecRagdollOrigin = GetAbsOrigin();
pRagdoll->m_vecRagdollVelocity = GetAbsVelocity();
pRagdoll->m_nModelIndex = m_nModelIndex;
pRagdoll->m_nForceBone = m_nForceBone;
pRagdoll->SetAbsOrigin( GetAbsOrigin() );
// ragdolls will be removed on round restart automatically
m_hRagdoll = pRagdoll;
}