aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/hl2/c_basehlplayer.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/client/hl2/c_basehlplayer.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/client/hl2/c_basehlplayer.cpp')
-rw-r--r--mp/src/game/client/hl2/c_basehlplayer.cpp1298
1 files changed, 649 insertions, 649 deletions
diff --git a/mp/src/game/client/hl2/c_basehlplayer.cpp b/mp/src/game/client/hl2/c_basehlplayer.cpp
index 230a720a..fbc40eb2 100644
--- a/mp/src/game/client/hl2/c_basehlplayer.cpp
+++ b/mp/src/game/client/hl2/c_basehlplayer.cpp
@@ -1,649 +1,649 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "c_basehlplayer.h"
-#include "playerandobjectenumerator.h"
-#include "engine/ivdebugoverlay.h"
-#include "c_ai_basenpc.h"
-#include "in_buttons.h"
-#include "collisionutils.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-// How fast to avoid collisions with center of other object, in units per second
-#define AVOID_SPEED 2000.0f
-extern ConVar cl_forwardspeed;
-extern ConVar cl_backspeed;
-extern ConVar cl_sidespeed;
-
-extern ConVar zoom_sensitivity_ratio;
-extern ConVar default_fov;
-extern ConVar sensitivity;
-
-ConVar cl_npc_speedmod_intime( "cl_npc_speedmod_intime", "0.25", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
-ConVar cl_npc_speedmod_outtime( "cl_npc_speedmod_outtime", "1.5", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
-
-IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player)
- RecvPropDataTable( RECVINFO_DT(m_HL2Local),0, &REFERENCE_RECV_TABLE(DT_HL2Local) ),
- RecvPropBool( RECVINFO( m_fIsSprinting ) ),
-END_RECV_TABLE()
-
-BEGIN_PREDICTION_DATA( C_BaseHLPlayer )
- DEFINE_PRED_TYPEDESCRIPTION( m_HL2Local, C_HL2PlayerLocalData ),
- DEFINE_PRED_FIELD( m_fIsSprinting, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
-END_PREDICTION_DATA()
-
-//-----------------------------------------------------------------------------
-// Purpose: Drops player's primary weapon
-//-----------------------------------------------------------------------------
-void CC_DropPrimary( void )
-{
- C_BasePlayer *pPlayer = (C_BasePlayer *) C_BasePlayer::GetLocalPlayer();
-
- if ( pPlayer == NULL )
- return;
-
- pPlayer->Weapon_DropPrimary();
-}
-
-static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops the primary weapon of the player.");
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-C_BaseHLPlayer::C_BaseHLPlayer()
-{
- AddVar( &m_Local.m_vecPunchAngle, &m_Local.m_iv_vecPunchAngle, LATCH_SIMULATION_VAR );
- AddVar( &m_Local.m_vecPunchAngleVel, &m_Local.m_iv_vecPunchAngleVel, LATCH_SIMULATION_VAR );
-
- m_flZoomStart = 0.0f;
- m_flZoomEnd = 0.0f;
- m_flZoomRate = 0.0f;
- m_flZoomStartTime = 0.0f;
- m_flSpeedMod = cl_forwardspeed.GetFloat();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::OnDataChanged( DataUpdateType_t updateType )
-{
- // Make sure we're thinking
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-
- BaseClass::OnDataChanged( updateType );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::Weapon_DropPrimary( void )
-{
- engine->ServerCmd( "DropPrimary" );
-}
-
-float C_BaseHLPlayer::GetFOV()
-{
- //Find our FOV with offset zoom value
- float flFOVOffset = BaseClass::GetFOV() + GetZoom();
-
- // Clamp FOV in MP
- int min_fov = ( gpGlobals->maxClients == 1 ) ? 5 : default_fov.GetInt();
-
- // Don't let it go too low
- flFOVOffset = MAX( min_fov, flFOVOffset );
-
- return flFOVOffset;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float C_BaseHLPlayer::GetZoom( void )
-{
- float fFOV = m_flZoomEnd;
-
- //See if we need to lerp the values
- if ( ( m_flZoomStart != m_flZoomEnd ) && ( m_flZoomRate > 0.0f ) )
- {
- float deltaTime = (float)( gpGlobals->curtime - m_flZoomStartTime ) / m_flZoomRate;
-
- if ( deltaTime >= 1.0f )
- {
- //If we're past the zoom time, just take the new value and stop lerping
- fFOV = m_flZoomStart = m_flZoomEnd;
- }
- else
- {
- fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_flZoomStart, m_flZoomEnd );
- }
- }
-
- return fFOV;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : FOVOffset -
-// time -
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::Zoom( float FOVOffset, float time )
-{
- m_flZoomStart = GetZoom();
- m_flZoomEnd = FOVOffset;
- m_flZoomRate = time;
- m_flZoomStartTime = gpGlobals->curtime;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Hack to zero out player's pitch, use value from poseparameter instead
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int C_BaseHLPlayer::DrawModel( int flags )
-{
- // Not pitch for player
- QAngle saveAngles = GetLocalAngles();
-
- QAngle useAngles = saveAngles;
- useAngles[ PITCH ] = 0.0f;
-
- SetLocalAngles( useAngles );
-
- int iret = BaseClass::DrawModel( flags );
-
- SetLocalAngles( saveAngles );
-
- return iret;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Helper to remove from ladder
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::ExitLadder()
-{
- if ( MOVETYPE_LADDER != GetMoveType() )
- return;
-
- SetMoveType( MOVETYPE_WALK );
- SetMoveCollide( MOVECOLLIDE_DEFAULT );
- // Remove from ladder
- m_HL2Local.m_hLadder = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Determines if a player can be safely moved towards a point
-// Input: pos - position to test move to, fVertDist - how far to trace downwards to see if the player would fall,
-// radius - how close the player can be to the object, objPos - position of the object to avoid,
-// objDir - direction the object is travelling
-//-----------------------------------------------------------------------------
-bool C_BaseHLPlayer::TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir )
-{
- trace_t trUp;
- trace_t trOver;
- trace_t trDown;
- float flHit1, flHit2;
-
- UTIL_TraceHull( GetAbsOrigin(), pos, GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
- if ( trOver.fraction < 1.0f )
- {
- // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
- if ( objDir.IsZero() ||
- ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) &&
- ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) )
- )
- {
- // our first trace failed, so see if we can go farther if we step up.
-
- // trace up to see if we have enough room.
- UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, m_Local.m_flStepSize ),
- GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trUp );
-
- // do a trace from the stepped up height
- UTIL_TraceHull( trUp.endpos, pos + Vector( 0, 0, trUp.endpos.z - trUp.startpos.z ),
- GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
-
- if ( trOver.fraction < 1.0f )
- {
- // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
- if ( objDir.IsZero() ||
- ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) && ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) ) )
- {
- return false;
- }
- }
- }
- }
-
- // trace down to see if this position is on the ground
- UTIL_TraceLine( trOver.endpos, trOver.endpos - Vector( 0, 0, fVertDist ),
- MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &trDown );
-
- if ( trDown.fraction == 1.0f )
- return false;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Client-side obstacle avoidance
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd )
-{
- // Don't avoid if noclipping or in movetype none
- switch ( GetMoveType() )
- {
- case MOVETYPE_NOCLIP:
- case MOVETYPE_NONE:
- case MOVETYPE_OBSERVER:
- return;
- default:
- break;
- }
-
- // Try to steer away from any objects/players we might interpenetrate
- Vector size = WorldAlignSize();
-
- float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y );
- float curspeed = GetLocalVelocity().Length2D();
-
- //int slot = 1;
- //engine->Con_NPrintf( slot++, "speed %f\n", curspeed );
- //engine->Con_NPrintf( slot++, "radius %f\n", radius );
-
- // If running, use a larger radius
- float factor = 1.0f;
-
- if ( curspeed > 150.0f )
- {
- curspeed = MIN( 2048.0f, curspeed );
- factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f );
-
- //engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor );
-
- radius = radius * factor;
- }
-
- Vector currentdir;
- Vector rightdir;
-
- QAngle vAngles = pCmd->viewangles;
- vAngles.x = 0;
-
- AngleVectors( vAngles, &currentdir, &rightdir, NULL );
-
- bool istryingtomove = false;
- bool ismovingforward = false;
- if ( fabs( pCmd->forwardmove ) > 0.0f ||
- fabs( pCmd->sidemove ) > 0.0f )
- {
- istryingtomove = true;
- if ( pCmd->forwardmove > 1.0f )
- {
- ismovingforward = true;
- }
- }
-
- if ( istryingtomove == true )
- radius *= 1.3f;
-
- CPlayerAndObjectEnumerator avoid( radius );
- partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid );
-
- // Okay, decide how to avoid if there's anything close by
- int c = avoid.GetObjectCount();
- if ( c <= 0 )
- return;
-
- //engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false" );
-
- float adjustforwardmove = 0.0f;
- float adjustsidemove = 0.0f;
-
- for ( int i = 0; i < c; i++ )
- {
- C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i ));
-
- if( !obj )
- continue;
-
- Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin();
-
- float flDist = vecToObject.Length2D();
-
- // Figure out a 2D radius for the object
- Vector vecWorldMins, vecWorldMaxs;
- obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
- Vector objSize = vecWorldMaxs - vecWorldMins;
-
- float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y );
-
- //Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them.
- if ( !obj->IsMoving() && flDist > objectradius )
- continue;
-
- if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) )
- {
- obj->RemoveEffects( EF_NODRAW );
- }
-
- Vector vecNPCVelocity;
- obj->EstimateAbsVelocity( vecNPCVelocity );
- float flNPCSpeed = VectorNormalize( vecNPCVelocity );
-
- Vector vPlayerVel = GetAbsVelocity();
- VectorNormalize( vPlayerVel );
-
- float flHit1, flHit2;
- Vector vRayDir = vecToObject;
- VectorNormalize( vRayDir );
-
- float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel );
- float flDirProduct = DotProduct( vRayDir, vPlayerVel );
-
- if ( !IntersectInfiniteRayWithSphere(
- GetAbsOrigin(),
- vRayDir,
- obj->GetAbsOrigin(),
- radius,
- &flHit1,
- &flHit2 ) )
- continue;
-
- Vector dirToObject = -vecToObject;
- VectorNormalize( dirToObject );
-
- float fwd = 0;
- float rt = 0;
-
- float sidescale = 2.0f;
- float forwardscale = 1.0f;
- bool foundResult = false;
-
- Vector vMoveDir = vecNPCVelocity;
- if ( flNPCSpeed > 0.001f )
- {
- // This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity.
- // Start with whatever side they're on relative to the NPC's velocity.
- Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) );
- int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1;
- for ( int nTries = 0; nTries < 2; nTries++ )
- {
- Vector vecTryMove = vecNPCTrajectoryRight * iDirection;
- VectorNormalize( vecTryMove );
-
- Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2;
-
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( vecTryMove );
- rt = rightdir.Dot( vecTryMove );
-
- //Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- break;
- }
- else
- {
- // Try the other direction.
- iDirection *= -1;
- }
- }
- }
- else
- {
- // the object isn't moving, so try moving opposite the way it's facing
- Vector vecNPCForward;
- obj->GetVectors( &vecNPCForward, NULL, NULL );
-
- Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2;
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( -vecNPCForward );
- rt = rightdir.Dot( -vecNPCForward );
-
- if ( flDist < objectradius )
- {
- obj->AddEffects( EF_NODRAW );
- }
-
- //Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- }
- }
-
- if ( !foundResult )
- {
- // test if we can move in the direction the object is moving
- Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2;
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( vMoveDir );
- rt = rightdir.Dot( vMoveDir );
-
- if ( flDist < objectradius )
- {
- obj->AddEffects( EF_NODRAW );
- }
-
- //Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- }
- else
- {
- // try moving directly away from the object
- Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2;
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( -dirToObject );
- rt = rightdir.Dot( -dirToObject );
- foundResult = true;
-
- //Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt );
- }
- }
- }
-
- if ( !foundResult )
- {
- // test if we can move through the object
- Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2;
- fwd = currentdir.Dot( -vMoveDir );
- rt = rightdir.Dot( -vMoveDir );
-
- if ( flDist < objectradius )
- {
- obj->AddEffects( EF_NODRAW );
- }
-
- //Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- }
-
- // If running, then do a lot more sideways veer since we're not going to do anything to
- // forward velocity
- if ( istryingtomove )
- {
- sidescale = 6.0f;
- }
-
- if ( flVelProduct > 0.0f && flDirProduct > 0.0f )
- {
- sidescale = 0.1f;
- }
-
- float force = 1.0f;
- float forward = forwardscale * fwd * force * AVOID_SPEED;
- float side = sidescale * rt * force * AVOID_SPEED;
-
- adjustforwardmove += forward;
- adjustsidemove += side;
- }
-
- pCmd->forwardmove += adjustforwardmove;
- pCmd->sidemove += adjustsidemove;
-
- // Clamp the move to within legal limits, preserving direction. This is a little
- // complicated because we have different limits for forward, back, and side
-
- //Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
-
- float flForwardScale = 1.0f;
- if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
- {
- flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
- }
- else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
- {
- flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
- }
-
- float flSideScale = 1.0f;
- if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
- {
- flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
- }
-
- float flScale = MIN( flForwardScale, flSideScale );
- pCmd->forwardmove *= flScale;
- pCmd->sidemove *= flScale;
-
- //Msg( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
-}
-
-
-void C_BaseHLPlayer::PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd )
-{
- if ( m_hClosestNPC == NULL )
- {
- if ( m_flSpeedMod != cl_forwardspeed.GetFloat() )
- {
- float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
- m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_outtime.GetFloat(), 0, m_flExitSpeedMod, cl_forwardspeed.GetFloat() );
- }
- }
- else
- {
- C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC *>( m_hClosestNPC.Get() );
-
- if ( pNPC )
- {
- float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();
- bool bShouldModSpeed = false;
-
- // Within range?
- if ( flDist < pNPC->GetSpeedModifyRadius() )
- {
- // Now, only slowdown if we're facing & running parallel to the target's movement
- // Facing check first (in 2D)
- Vector vecTargetOrigin = pNPC->GetAbsOrigin();
- Vector los = ( vecTargetOrigin - EyePosition() );
- los.z = 0;
- VectorNormalize( los );
- Vector facingDir;
- AngleVectors( GetAbsAngles(), &facingDir );
- float flDot = DotProduct( los, facingDir );
- if ( flDot > 0.8 )
- {
- /*
- // Velocity check (abort if the target isn't moving)
- Vector vecTargetVelocity;
- pNPC->EstimateAbsVelocity( vecTargetVelocity );
- float flSpeed = VectorNormalize(vecTargetVelocity);
- Vector vecMyVelocity = GetAbsVelocity();
- VectorNormalize(vecMyVelocity);
- if ( flSpeed > 1.0 )
- {
- // Velocity roughly parallel?
- if ( DotProduct(vecTargetVelocity,vecMyVelocity) > 0.4 )
- {
- bShouldModSpeed = true;
- }
- }
- else
- {
- // NPC's not moving, slow down if we're moving at him
- //Msg("Dot: %.2f\n", DotProduct( los, vecMyVelocity ) );
- if ( DotProduct( los, vecMyVelocity ) > 0.8 )
- {
- bShouldModSpeed = true;
- }
- }
- */
-
- bShouldModSpeed = true;
- }
- }
-
- if ( !bShouldModSpeed )
- {
- m_hClosestNPC = NULL;
- m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_outtime.GetFloat();
- m_flExitSpeedMod = m_flSpeedMod;
- return;
- }
- else
- {
- if ( m_flSpeedMod != pNPC->GetSpeedModifySpeed() )
- {
- float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
- m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_intime.GetFloat(), 0, cl_forwardspeed.GetFloat(), pNPC->GetSpeedModifySpeed() );
- }
- }
- }
- }
-
- if ( pCmd->forwardmove > 0.0f )
- {
- pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
- }
- else
- {
- pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
- }
- pCmd->sidemove = clamp( pCmd->sidemove, -m_flSpeedMod, m_flSpeedMod );
-
- //Msg( "fwd %f right %f\n", pCmd->forwardmove, pCmd->sidemove );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Input handling
-//-----------------------------------------------------------------------------
-bool C_BaseHLPlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd )
-{
- bool bResult = BaseClass::CreateMove( flInputSampleTime, pCmd );
-
- if ( !IsInAVehicle() )
- {
- PerformClientSideObstacleAvoidance( TICK_INTERVAL, pCmd );
- PerformClientSideNPCSpeedModifiers( TICK_INTERVAL, pCmd );
- }
-
- return bResult;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Input handling
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
-{
- BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
- BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "c_basehlplayer.h"
+#include "playerandobjectenumerator.h"
+#include "engine/ivdebugoverlay.h"
+#include "c_ai_basenpc.h"
+#include "in_buttons.h"
+#include "collisionutils.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+// How fast to avoid collisions with center of other object, in units per second
+#define AVOID_SPEED 2000.0f
+extern ConVar cl_forwardspeed;
+extern ConVar cl_backspeed;
+extern ConVar cl_sidespeed;
+
+extern ConVar zoom_sensitivity_ratio;
+extern ConVar default_fov;
+extern ConVar sensitivity;
+
+ConVar cl_npc_speedmod_intime( "cl_npc_speedmod_intime", "0.25", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+ConVar cl_npc_speedmod_outtime( "cl_npc_speedmod_outtime", "1.5", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+
+IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player)
+ RecvPropDataTable( RECVINFO_DT(m_HL2Local),0, &REFERENCE_RECV_TABLE(DT_HL2Local) ),
+ RecvPropBool( RECVINFO( m_fIsSprinting ) ),
+END_RECV_TABLE()
+
+BEGIN_PREDICTION_DATA( C_BaseHLPlayer )
+ DEFINE_PRED_TYPEDESCRIPTION( m_HL2Local, C_HL2PlayerLocalData ),
+ DEFINE_PRED_FIELD( m_fIsSprinting, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
+END_PREDICTION_DATA()
+
+//-----------------------------------------------------------------------------
+// Purpose: Drops player's primary weapon
+//-----------------------------------------------------------------------------
+void CC_DropPrimary( void )
+{
+ C_BasePlayer *pPlayer = (C_BasePlayer *) C_BasePlayer::GetLocalPlayer();
+
+ if ( pPlayer == NULL )
+ return;
+
+ pPlayer->Weapon_DropPrimary();
+}
+
+static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops the primary weapon of the player.");
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+C_BaseHLPlayer::C_BaseHLPlayer()
+{
+ AddVar( &m_Local.m_vecPunchAngle, &m_Local.m_iv_vecPunchAngle, LATCH_SIMULATION_VAR );
+ AddVar( &m_Local.m_vecPunchAngleVel, &m_Local.m_iv_vecPunchAngleVel, LATCH_SIMULATION_VAR );
+
+ m_flZoomStart = 0.0f;
+ m_flZoomEnd = 0.0f;
+ m_flZoomRate = 0.0f;
+ m_flZoomStartTime = 0.0f;
+ m_flSpeedMod = cl_forwardspeed.GetFloat();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::OnDataChanged( DataUpdateType_t updateType )
+{
+ // Make sure we're thinking
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+
+ BaseClass::OnDataChanged( updateType );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::Weapon_DropPrimary( void )
+{
+ engine->ServerCmd( "DropPrimary" );
+}
+
+float C_BaseHLPlayer::GetFOV()
+{
+ //Find our FOV with offset zoom value
+ float flFOVOffset = BaseClass::GetFOV() + GetZoom();
+
+ // Clamp FOV in MP
+ int min_fov = ( gpGlobals->maxClients == 1 ) ? 5 : default_fov.GetInt();
+
+ // Don't let it go too low
+ flFOVOffset = MAX( min_fov, flFOVOffset );
+
+ return flFOVOffset;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float C_BaseHLPlayer::GetZoom( void )
+{
+ float fFOV = m_flZoomEnd;
+
+ //See if we need to lerp the values
+ if ( ( m_flZoomStart != m_flZoomEnd ) && ( m_flZoomRate > 0.0f ) )
+ {
+ float deltaTime = (float)( gpGlobals->curtime - m_flZoomStartTime ) / m_flZoomRate;
+
+ if ( deltaTime >= 1.0f )
+ {
+ //If we're past the zoom time, just take the new value and stop lerping
+ fFOV = m_flZoomStart = m_flZoomEnd;
+ }
+ else
+ {
+ fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_flZoomStart, m_flZoomEnd );
+ }
+ }
+
+ return fFOV;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : FOVOffset -
+// time -
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::Zoom( float FOVOffset, float time )
+{
+ m_flZoomStart = GetZoom();
+ m_flZoomEnd = FOVOffset;
+ m_flZoomRate = time;
+ m_flZoomStartTime = gpGlobals->curtime;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Hack to zero out player's pitch, use value from poseparameter instead
+// Input : flags -
+// Output : int
+//-----------------------------------------------------------------------------
+int C_BaseHLPlayer::DrawModel( int flags )
+{
+ // Not pitch for player
+ QAngle saveAngles = GetLocalAngles();
+
+ QAngle useAngles = saveAngles;
+ useAngles[ PITCH ] = 0.0f;
+
+ SetLocalAngles( useAngles );
+
+ int iret = BaseClass::DrawModel( flags );
+
+ SetLocalAngles( saveAngles );
+
+ return iret;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper to remove from ladder
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::ExitLadder()
+{
+ if ( MOVETYPE_LADDER != GetMoveType() )
+ return;
+
+ SetMoveType( MOVETYPE_WALK );
+ SetMoveCollide( MOVECOLLIDE_DEFAULT );
+ // Remove from ladder
+ m_HL2Local.m_hLadder = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Determines if a player can be safely moved towards a point
+// Input: pos - position to test move to, fVertDist - how far to trace downwards to see if the player would fall,
+// radius - how close the player can be to the object, objPos - position of the object to avoid,
+// objDir - direction the object is travelling
+//-----------------------------------------------------------------------------
+bool C_BaseHLPlayer::TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir )
+{
+ trace_t trUp;
+ trace_t trOver;
+ trace_t trDown;
+ float flHit1, flHit2;
+
+ UTIL_TraceHull( GetAbsOrigin(), pos, GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
+ if ( trOver.fraction < 1.0f )
+ {
+ // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
+ if ( objDir.IsZero() ||
+ ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) &&
+ ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) )
+ )
+ {
+ // our first trace failed, so see if we can go farther if we step up.
+
+ // trace up to see if we have enough room.
+ UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, m_Local.m_flStepSize ),
+ GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trUp );
+
+ // do a trace from the stepped up height
+ UTIL_TraceHull( trUp.endpos, pos + Vector( 0, 0, trUp.endpos.z - trUp.startpos.z ),
+ GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
+
+ if ( trOver.fraction < 1.0f )
+ {
+ // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
+ if ( objDir.IsZero() ||
+ ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) && ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) ) )
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ // trace down to see if this position is on the ground
+ UTIL_TraceLine( trOver.endpos, trOver.endpos - Vector( 0, 0, fVertDist ),
+ MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &trDown );
+
+ if ( trDown.fraction == 1.0f )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Client-side obstacle avoidance
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd )
+{
+ // Don't avoid if noclipping or in movetype none
+ switch ( GetMoveType() )
+ {
+ case MOVETYPE_NOCLIP:
+ case MOVETYPE_NONE:
+ case MOVETYPE_OBSERVER:
+ return;
+ default:
+ break;
+ }
+
+ // Try to steer away from any objects/players we might interpenetrate
+ Vector size = WorldAlignSize();
+
+ float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y );
+ float curspeed = GetLocalVelocity().Length2D();
+
+ //int slot = 1;
+ //engine->Con_NPrintf( slot++, "speed %f\n", curspeed );
+ //engine->Con_NPrintf( slot++, "radius %f\n", radius );
+
+ // If running, use a larger radius
+ float factor = 1.0f;
+
+ if ( curspeed > 150.0f )
+ {
+ curspeed = MIN( 2048.0f, curspeed );
+ factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f );
+
+ //engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor );
+
+ radius = radius * factor;
+ }
+
+ Vector currentdir;
+ Vector rightdir;
+
+ QAngle vAngles = pCmd->viewangles;
+ vAngles.x = 0;
+
+ AngleVectors( vAngles, &currentdir, &rightdir, NULL );
+
+ bool istryingtomove = false;
+ bool ismovingforward = false;
+ if ( fabs( pCmd->forwardmove ) > 0.0f ||
+ fabs( pCmd->sidemove ) > 0.0f )
+ {
+ istryingtomove = true;
+ if ( pCmd->forwardmove > 1.0f )
+ {
+ ismovingforward = true;
+ }
+ }
+
+ if ( istryingtomove == true )
+ radius *= 1.3f;
+
+ CPlayerAndObjectEnumerator avoid( radius );
+ partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid );
+
+ // Okay, decide how to avoid if there's anything close by
+ int c = avoid.GetObjectCount();
+ if ( c <= 0 )
+ return;
+
+ //engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false" );
+
+ float adjustforwardmove = 0.0f;
+ float adjustsidemove = 0.0f;
+
+ for ( int i = 0; i < c; i++ )
+ {
+ C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i ));
+
+ if( !obj )
+ continue;
+
+ Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin();
+
+ float flDist = vecToObject.Length2D();
+
+ // Figure out a 2D radius for the object
+ Vector vecWorldMins, vecWorldMaxs;
+ obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
+ Vector objSize = vecWorldMaxs - vecWorldMins;
+
+ float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y );
+
+ //Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them.
+ if ( !obj->IsMoving() && flDist > objectradius )
+ continue;
+
+ if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) )
+ {
+ obj->RemoveEffects( EF_NODRAW );
+ }
+
+ Vector vecNPCVelocity;
+ obj->EstimateAbsVelocity( vecNPCVelocity );
+ float flNPCSpeed = VectorNormalize( vecNPCVelocity );
+
+ Vector vPlayerVel = GetAbsVelocity();
+ VectorNormalize( vPlayerVel );
+
+ float flHit1, flHit2;
+ Vector vRayDir = vecToObject;
+ VectorNormalize( vRayDir );
+
+ float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel );
+ float flDirProduct = DotProduct( vRayDir, vPlayerVel );
+
+ if ( !IntersectInfiniteRayWithSphere(
+ GetAbsOrigin(),
+ vRayDir,
+ obj->GetAbsOrigin(),
+ radius,
+ &flHit1,
+ &flHit2 ) )
+ continue;
+
+ Vector dirToObject = -vecToObject;
+ VectorNormalize( dirToObject );
+
+ float fwd = 0;
+ float rt = 0;
+
+ float sidescale = 2.0f;
+ float forwardscale = 1.0f;
+ bool foundResult = false;
+
+ Vector vMoveDir = vecNPCVelocity;
+ if ( flNPCSpeed > 0.001f )
+ {
+ // This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity.
+ // Start with whatever side they're on relative to the NPC's velocity.
+ Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) );
+ int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1;
+ for ( int nTries = 0; nTries < 2; nTries++ )
+ {
+ Vector vecTryMove = vecNPCTrajectoryRight * iDirection;
+ VectorNormalize( vecTryMove );
+
+ Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2;
+
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( vecTryMove );
+ rt = rightdir.Dot( vecTryMove );
+
+ //Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ break;
+ }
+ else
+ {
+ // Try the other direction.
+ iDirection *= -1;
+ }
+ }
+ }
+ else
+ {
+ // the object isn't moving, so try moving opposite the way it's facing
+ Vector vecNPCForward;
+ obj->GetVectors( &vecNPCForward, NULL, NULL );
+
+ Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2;
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( -vecNPCForward );
+ rt = rightdir.Dot( -vecNPCForward );
+
+ if ( flDist < objectradius )
+ {
+ obj->AddEffects( EF_NODRAW );
+ }
+
+ //Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ }
+ }
+
+ if ( !foundResult )
+ {
+ // test if we can move in the direction the object is moving
+ Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2;
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( vMoveDir );
+ rt = rightdir.Dot( vMoveDir );
+
+ if ( flDist < objectradius )
+ {
+ obj->AddEffects( EF_NODRAW );
+ }
+
+ //Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ }
+ else
+ {
+ // try moving directly away from the object
+ Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2;
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( -dirToObject );
+ rt = rightdir.Dot( -dirToObject );
+ foundResult = true;
+
+ //Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt );
+ }
+ }
+ }
+
+ if ( !foundResult )
+ {
+ // test if we can move through the object
+ Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2;
+ fwd = currentdir.Dot( -vMoveDir );
+ rt = rightdir.Dot( -vMoveDir );
+
+ if ( flDist < objectradius )
+ {
+ obj->AddEffects( EF_NODRAW );
+ }
+
+ //Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ }
+
+ // If running, then do a lot more sideways veer since we're not going to do anything to
+ // forward velocity
+ if ( istryingtomove )
+ {
+ sidescale = 6.0f;
+ }
+
+ if ( flVelProduct > 0.0f && flDirProduct > 0.0f )
+ {
+ sidescale = 0.1f;
+ }
+
+ float force = 1.0f;
+ float forward = forwardscale * fwd * force * AVOID_SPEED;
+ float side = sidescale * rt * force * AVOID_SPEED;
+
+ adjustforwardmove += forward;
+ adjustsidemove += side;
+ }
+
+ pCmd->forwardmove += adjustforwardmove;
+ pCmd->sidemove += adjustsidemove;
+
+ // Clamp the move to within legal limits, preserving direction. This is a little
+ // complicated because we have different limits for forward, back, and side
+
+ //Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
+
+ float flForwardScale = 1.0f;
+ if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
+ {
+ flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
+ }
+ else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
+ {
+ flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
+ }
+
+ float flSideScale = 1.0f;
+ if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
+ {
+ flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
+ }
+
+ float flScale = MIN( flForwardScale, flSideScale );
+ pCmd->forwardmove *= flScale;
+ pCmd->sidemove *= flScale;
+
+ //Msg( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
+}
+
+
+void C_BaseHLPlayer::PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd )
+{
+ if ( m_hClosestNPC == NULL )
+ {
+ if ( m_flSpeedMod != cl_forwardspeed.GetFloat() )
+ {
+ float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
+ m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_outtime.GetFloat(), 0, m_flExitSpeedMod, cl_forwardspeed.GetFloat() );
+ }
+ }
+ else
+ {
+ C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC *>( m_hClosestNPC.Get() );
+
+ if ( pNPC )
+ {
+ float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();
+ bool bShouldModSpeed = false;
+
+ // Within range?
+ if ( flDist < pNPC->GetSpeedModifyRadius() )
+ {
+ // Now, only slowdown if we're facing & running parallel to the target's movement
+ // Facing check first (in 2D)
+ Vector vecTargetOrigin = pNPC->GetAbsOrigin();
+ Vector los = ( vecTargetOrigin - EyePosition() );
+ los.z = 0;
+ VectorNormalize( los );
+ Vector facingDir;
+ AngleVectors( GetAbsAngles(), &facingDir );
+ float flDot = DotProduct( los, facingDir );
+ if ( flDot > 0.8 )
+ {
+ /*
+ // Velocity check (abort if the target isn't moving)
+ Vector vecTargetVelocity;
+ pNPC->EstimateAbsVelocity( vecTargetVelocity );
+ float flSpeed = VectorNormalize(vecTargetVelocity);
+ Vector vecMyVelocity = GetAbsVelocity();
+ VectorNormalize(vecMyVelocity);
+ if ( flSpeed > 1.0 )
+ {
+ // Velocity roughly parallel?
+ if ( DotProduct(vecTargetVelocity,vecMyVelocity) > 0.4 )
+ {
+ bShouldModSpeed = true;
+ }
+ }
+ else
+ {
+ // NPC's not moving, slow down if we're moving at him
+ //Msg("Dot: %.2f\n", DotProduct( los, vecMyVelocity ) );
+ if ( DotProduct( los, vecMyVelocity ) > 0.8 )
+ {
+ bShouldModSpeed = true;
+ }
+ }
+ */
+
+ bShouldModSpeed = true;
+ }
+ }
+
+ if ( !bShouldModSpeed )
+ {
+ m_hClosestNPC = NULL;
+ m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_outtime.GetFloat();
+ m_flExitSpeedMod = m_flSpeedMod;
+ return;
+ }
+ else
+ {
+ if ( m_flSpeedMod != pNPC->GetSpeedModifySpeed() )
+ {
+ float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
+ m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_intime.GetFloat(), 0, cl_forwardspeed.GetFloat(), pNPC->GetSpeedModifySpeed() );
+ }
+ }
+ }
+ }
+
+ if ( pCmd->forwardmove > 0.0f )
+ {
+ pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
+ }
+ else
+ {
+ pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
+ }
+ pCmd->sidemove = clamp( pCmd->sidemove, -m_flSpeedMod, m_flSpeedMod );
+
+ //Msg( "fwd %f right %f\n", pCmd->forwardmove, pCmd->sidemove );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Input handling
+//-----------------------------------------------------------------------------
+bool C_BaseHLPlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd )
+{
+ bool bResult = BaseClass::CreateMove( flInputSampleTime, pCmd );
+
+ if ( !IsInAVehicle() )
+ {
+ PerformClientSideObstacleAvoidance( TICK_INTERVAL, pCmd );
+ PerformClientSideNPCSpeedModifiers( TICK_INTERVAL, pCmd );
+ }
+
+ return bResult;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Input handling
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
+{
+ BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
+ BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" );
+}
+