aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/sdk/sdk_player.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/server/sdk/sdk_player.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/sdk/sdk_player.cpp')
-rw-r--r--mp/src/game/server/sdk/sdk_player.cpp366
1 files changed, 366 insertions, 0 deletions
diff --git a/mp/src/game/server/sdk/sdk_player.cpp b/mp/src/game/server/sdk/sdk_player.cpp
new file mode 100644
index 00000000..e9b33181
--- /dev/null
+++ b/mp/src/game/server/sdk/sdk_player.cpp
@@ -0,0 +1,366 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Player for HL1.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "sdk_player.h"
+#include "sdk_gamerules.h"
+#include "weapon_sdkbase.h"
+#include "predicted_viewmodel.h"
+#include "iservervehicle.h"
+#include "viewport_panel_names.h"
+
+extern int gEvilImpulse101;
+
+ConVar sv_motd_unload_on_dismissal( "sv_motd_unload_on_dismissal", "0", 0, "If enabled, the MOTD contents will be unloaded when the player closes the MOTD." );
+
+#define SDK_PLAYER_MODEL "models/player/terror.mdl"
+
+
+// -------------------------------------------------------------------------------- //
+// Player animation event. Sent to the client when a player fires, jumps, reloads, etc..
+// -------------------------------------------------------------------------------- //
+
+class CTEPlayerAnimEvent : public CBaseTempEntity
+{
+public:
+ DECLARE_CLASS( CTEPlayerAnimEvent, CBaseTempEntity );
+ DECLARE_SERVERCLASS();
+
+ CTEPlayerAnimEvent( const char *name ) : CBaseTempEntity( name )
+ {
+ }
+
+ CNetworkHandle( CBasePlayer, m_hPlayer );
+ CNetworkVar( int, m_iEvent );
+ CNetworkVar( int, m_nData );
+};
+
+#define THROWGRENADE_COUNTER_BITS 3
+
+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() );
+
+ g_TEPlayerAnimEvent.m_hPlayer = pPlayer;
+ g_TEPlayerAnimEvent.m_iEvent = event;
+ g_TEPlayerAnimEvent.m_nData = nData;
+ g_TEPlayerAnimEvent.Create( filter, 0 );
+}
+
+// -------------------------------------------------------------------------------- //
+// Tables.
+// -------------------------------------------------------------------------------- //
+BEGIN_DATADESC( CSDKPlayer )
+DEFINE_THINKFUNC( SDKPushawayThink ),
+END_DATADESC()
+
+LINK_ENTITY_TO_CLASS( player, CSDKPlayer );
+PRECACHE_REGISTER(player);
+
+BEGIN_SEND_TABLE_NOBASE( CSDKPlayer, DT_SDKLocalPlayerExclusive )
+ SendPropInt( SENDINFO( m_iShotsFired ), 8, SPROP_UNSIGNED ),
+END_SEND_TABLE()
+
+IMPLEMENT_SERVERCLASS_ST( CSDKPlayer, DT_SDKPlayer )
+ SendPropExclude( "DT_BaseAnimating", "m_flPoseParameter" ),
+ SendPropExclude( "DT_BaseAnimating", "m_flPlaybackRate" ),
+ SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
+ SendPropExclude( "DT_BaseEntity", "m_angRotation" ),
+ SendPropExclude( "DT_BaseAnimatingOverlay", "overlay_vars" ),
+
+ // playeranimstate and clientside animation takes care of these on the client
+ SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ),
+ SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ),
+
+ // Data that only gets sent to the local player.
+ SendPropDataTable( "sdklocaldata", 0, &REFERENCE_SEND_TABLE(DT_SDKLocalPlayerExclusive), SendProxy_SendLocalDataTable ),
+
+ SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 11 ),
+ SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 11 ),
+ SendPropEHandle( SENDINFO( m_hRagdoll ) ),
+
+ SendPropInt( SENDINFO( m_iThrowGrenadeCounter ), THROWGRENADE_COUNTER_BITS, SPROP_UNSIGNED ),
+END_SEND_TABLE()
+
+class CSDKRagdoll : public CBaseAnimatingOverlay
+{
+public:
+ DECLARE_CLASS( CSDKRagdoll, CBaseAnimatingOverlay );
+ DECLARE_SERVERCLASS();
+
+ // Transmit ragdolls to everyone.
+ virtual int UpdateTransmitState()
+ {
+ return SetTransmitState( FL_EDICT_ALWAYS );
+ }
+
+public:
+ // In case the client has the player entity, we transmit the player index.
+ // In case the client doesn't have it, we transmit the player's model index, origin, and angles
+ // so they can create a ragdoll in the right place.
+ CNetworkHandle( CBaseEntity, m_hPlayer ); // networked entity handle
+ CNetworkVector( m_vecRagdollVelocity );
+ CNetworkVector( m_vecRagdollOrigin );
+};
+
+LINK_ENTITY_TO_CLASS( sdk_ragdoll, CSDKRagdoll );
+
+IMPLEMENT_SERVERCLASS_ST_NOBASE( CSDKRagdoll, DT_SDKRagdoll )
+ SendPropVector( SENDINFO(m_vecRagdollOrigin), -1, SPROP_COORD ),
+ SendPropEHandle( SENDINFO( m_hPlayer ) ),
+ SendPropModelIndex( SENDINFO( m_nModelIndex ) ),
+ SendPropInt ( SENDINFO(m_nForceBone), 8, 0 ),
+ SendPropVector ( SENDINFO(m_vecForce), -1, SPROP_NOSCALE ),
+ SendPropVector( SENDINFO( m_vecRagdollVelocity ) )
+END_SEND_TABLE()
+
+
+// -------------------------------------------------------------------------------- //
+
+void cc_CreatePredictionError_f()
+{
+ CBaseEntity *pEnt = CBaseEntity::Instance( 1 );
+ pEnt->SetAbsOrigin( pEnt->GetAbsOrigin() + Vector( 63, 0, 0 ) );
+}
+
+ConCommand cc_CreatePredictionError( "CreatePredictionError", cc_CreatePredictionError_f, "Create a prediction error", FCVAR_CHEAT );
+
+
+CSDKPlayer::CSDKPlayer()
+{
+ m_PlayerAnimState = CreatePlayerAnimState( this, this, LEGANIM_9WAY, true );
+
+ UseClientSideAnimation();
+ m_angEyeAngles.Init();
+
+ SetViewOffset( SDK_PLAYER_VIEW_OFFSET );
+
+ m_iThrowGrenadeCounter = 0;
+}
+
+
+CSDKPlayer::~CSDKPlayer()
+{
+ m_PlayerAnimState->Release();
+}
+
+
+CSDKPlayer *CSDKPlayer::CreatePlayer( const char *className, edict_t *ed )
+{
+ CSDKPlayer::s_PlayerEdict = ed;
+ return (CSDKPlayer*)CreateEntityByName( className );
+}
+
+void CSDKPlayer::LeaveVehicle( const Vector &vecExitPoint, const QAngle &vecExitAngles )
+{
+ BaseClass::LeaveVehicle( vecExitPoint, vecExitAngles );
+
+ //teleport physics shadow too
+ // Vector newPos = GetAbsOrigin();
+ // QAngle newAng = GetAbsAngles();
+
+ // Teleport( &newPos, &newAng, &vec3_origin );
+}
+
+void CSDKPlayer::PreThink(void)
+{
+ // Riding a vehicle?
+ if ( IsInAVehicle() )
+ {
+ // make sure we update the client, check for timed damage and update suit even if we are in a vehicle
+ UpdateClientData();
+ CheckTimeBasedDamage();
+
+ // Allow the suit to recharge when in the vehicle.
+ CheckSuitUpdate();
+
+ WaterMove();
+ return;
+ }
+
+ BaseClass::PreThink();
+}
+
+
+void CSDKPlayer::PostThink()
+{
+ BaseClass::PostThink();
+
+ QAngle angles = GetLocalAngles();
+ angles[PITCH] = 0;
+ SetLocalAngles( angles );
+
+ // Store the eye angles pitch so the client can compute its animation state correctly.
+ m_angEyeAngles = EyeAngles();
+
+ m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
+}
+
+
+void CSDKPlayer::Precache()
+{
+ PrecacheModel( SDK_PLAYER_MODEL );
+
+ BaseClass::Precache();
+}
+
+void CSDKPlayer::Spawn()
+{
+ SetModel( SDK_PLAYER_MODEL );
+ SetMoveType( MOVETYPE_WALK );
+ RemoveSolidFlags( FSOLID_NOT_SOLID );
+
+ m_hRagdoll = NULL;
+
+ BaseClass::Spawn();
+}
+
+void CSDKPlayer::InitialSpawn( void )
+{
+ BaseClass::InitialSpawn();
+
+ const ConVar *hostname = cvar->FindVar( "hostname" );
+ const char *title = (hostname) ? hostname->GetString() : "MESSAGE OF THE DAY";
+
+ // open info panel on client showing MOTD:
+ KeyValues *data = new KeyValues("data");
+ data->SetString( "title", title ); // info panel title
+ data->SetString( "type", "1" ); // show userdata from stringtable entry
+ data->SetString( "msg", "motd" ); // use this stringtable entry
+ data->SetInt( "cmd", TEXTWINDOW_CMD_IMPULSE101 );// exec this command if panel closed
+ data->SetBool( "unload", sv_motd_unload_on_dismissal.GetBool() );
+
+ ShowViewPortPanel( PANEL_INFO, true, data );
+
+ data->deleteThis();
+}
+
+void CSDKPlayer::Event_Killed( const CTakeDamageInfo &info )
+{
+ // Note: since we're dead, it won't draw us on the client, but we don't set EF_NODRAW
+ // because we still want to transmit to the clients in our PVS.
+
+ BaseClass::Event_Killed( info );
+
+ CreateRagdollEntity();
+}
+
+void CSDKPlayer::CreateRagdollEntity()
+{
+ // If we already have a ragdoll, don't make another one.
+ CSDKRagdoll *pRagdoll = dynamic_cast< CSDKRagdoll* >( m_hRagdoll.Get() );
+
+ if ( !pRagdoll )
+ {
+ // create a new one
+ pRagdoll = dynamic_cast< CSDKRagdoll* >( CreateEntityByName( "sdk_ragdoll" ) );
+ }
+
+ if ( pRagdoll )
+ {
+ pRagdoll->m_hPlayer = this;
+ pRagdoll->m_vecRagdollOrigin = GetAbsOrigin();
+ pRagdoll->m_vecRagdollVelocity = GetAbsVelocity();
+ pRagdoll->m_nModelIndex = m_nModelIndex;
+ pRagdoll->m_nForceBone = m_nForceBone;
+ pRagdoll->m_vecForce = Vector(0,0,0);
+ }
+
+ // ragdolls will be removed on round restart automatically
+ m_hRagdoll = pRagdoll;
+}
+
+void CSDKPlayer::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
+{
+ if ( event == PLAYERANIMEVENT_THROW_GRENADE )
+ {
+ // Grenade throwing has to synchronize exactly with the player's grenade weapon going away,
+ // and events get delayed a bit, so we let CCSPlayerAnimState pickup the change to this
+ // variable.
+ m_iThrowGrenadeCounter = (m_iThrowGrenadeCounter+1) % (1<<THROWGRENADE_COUNTER_BITS);
+ }
+ else
+ {
+ m_PlayerAnimState->DoAnimationEvent( event, nData );
+ TE_PlayerAnimEvent( this, event, nData ); // Send to any clients who can see this guy.
+ }
+}
+
+CWeaponSDKBase* CSDKPlayer::GetActiveSDKWeapon() const
+{
+ return dynamic_cast< CWeaponSDKBase* >( GetActiveWeapon() );
+}
+
+void CSDKPlayer::CreateViewModel( int index /*=0*/ )
+{
+ 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 CSDKPlayer::CheatImpulseCommands( int iImpulse )
+{
+ if ( iImpulse != 101 )
+ {
+ BaseClass::CheatImpulseCommands( iImpulse );
+ return ;
+ }
+ gEvilImpulse101 = true;
+
+ EquipSuit();
+
+ GiveNamedItem( "weapon_mp5" );
+ GiveNamedItem( "weapon_grenade" );
+ GiveNamedItem( "weapon_shotgun" );
+
+ // Give the player everything!
+ GiveAmmo( 90, AMMO_BULLETS );
+ GiveAmmo( 3, AMMO_GRENADE );
+
+ if ( GetHealth() < 100 )
+ {
+ TakeHealth( 25, DMG_GENERIC );
+ }
+
+ gEvilImpulse101 = false;
+}
+
+
+void CSDKPlayer::FlashlightTurnOn( void )
+{
+ AddEffects( EF_DIMLIGHT );
+}
+
+void CSDKPlayer::FlashlightTurnOff( void )
+{
+ RemoveEffects( EF_DIMLIGHT );
+}
+
+int CSDKPlayer::FlashlightIsOn( void )
+{
+ return IsEffectActive( EF_DIMLIGHT );
+}