Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

424 lines
12 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Auto Repair
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "in_buttons.h"
#include "tf_gamemovement_commando.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFGameMovementCommando::CTFGameMovementCommando()
{
m_pCommandoData = NULL;
m_vStandMins = COMMANDOCLASS_HULL_STAND_MIN;
m_vStandMaxs = COMMANDOCLASS_HULL_STAND_MAX;
m_vStandViewOffset = COMMANDOCLASS_VIEWOFFSET_STAND;
m_vDuckMins = COMMANDOCLASS_HULL_DUCK_MIN;
m_vDuckMaxs = COMMANDOCLASS_HULL_DUCK_MAX;
m_vDuckViewOffset = COMMANDOCLASS_VIEWOFFSET_DUCK;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::ProcessClassMovement( CBaseTFPlayer *pPlayer, CTFMoveData *pTFMoveData )
{
// Get the class specific data from the TFMoveData structure
Assert( PlayerClassCommandoData_t::PLAYERCLASS_ID == pTFMoveData->m_nClassID );
// Is this how I want to handle this???
// m_pCommandoData = &pTFMoveData->CommandoData();
// to test pass it through!!
BaseClass::ProcessMovement( (CBasePlayer *)pPlayer, static_cast<CMoveData*>( pTFMoveData ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const Vector &CTFGameMovementCommando::GetPlayerMins( bool bDucked ) const
{
return bDucked ? m_vDuckMins : m_vStandMins;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const Vector &CTFGameMovementCommando::GetPlayerMaxs( bool bDucked ) const
{
return bDucked ? m_vDuckMaxs : m_vStandMaxs;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const Vector &CTFGameMovementCommando::GetPlayerViewOffset( bool bDucked ) const
{
return bDucked ? m_vDuckViewOffset : m_vStandViewOffset;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CTFGameMovementCommando::CheckDoubleTapForward( void )
{
// Check for other movement keys!!!
if ( ( TFMove()->m_nButtons & IN_MOVELEFT ) || ( TFMove()->m_nButtons & IN_MOVERIGHT ) ||
( TFMove()->m_nButtons & IN_BACK ) || ( TFMove()->m_nButtons & IN_JUMP ) )
{
TFMove()->CommandoData().m_flDoubleTapForwardTime = COMMANDO_TIME_INVALID;
return false;
}
if ( ( TFMove()->m_nButtons & IN_FORWARD ) && !( TFMove()->m_nOldButtons & IN_FORWARD ) )
{
// Start timer.
if ( TFMove()->CommandoData().m_flDoubleTapForwardTime == COMMANDO_TIME_INVALID )
{
TFMove()->CommandoData().m_flDoubleTapForwardTime = COMMANDO_DOUBLETAP_TIME;
}
// Check for a double tap.
else
{
if ( TFMove()->CommandoData().m_flDoubleTapForwardTime > 0.0f )
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::CheckBullRush( void )
{
// Don't check for bullrush if we are dead!
if ( IsDead() )
return;
// Don't go into bullrush if noclipping
if ( player->GetMoveType() == MOVETYPE_NOCLIP )
return;
// Cannot bullrush inside of a vehicle (manned <gun>).
#if !defined (CLIENT_DLL)
IServerVehicle *pVehicle = player->GetVehicle();
if ( pVehicle )
return;
#else
IClientVehicle *pVehicle = player->GetVehicle();
if ( pVehicle )
return;
#endif
if ( CheckDoubleTapForward() && !TFMove()->CommandoData().m_bBullRush &&
TFMove()->CommandoData().m_bCanBullRush && !( player->GetFlags() & FL_DUCKING ) )
{
// Set in a bull rush.
TFMove()->CommandoData().m_bBullRush = true;
// Set timers.
TFMove()->CommandoData().m_flBullRushTime = COMMANDO_BULLRUSH_TIME;
// Lock view/move angles
Vector vBullrushDir;
AngleVectors( TFMove()->m_vecViewAngles, &vBullrushDir, NULL, NULL );
TFMove()->CommandoData().m_vecBullRushDir = vBullrushDir;
TFMove()->CommandoData().m_vecBullRushViewDir = TFMove()->m_vecViewAngles;
TFMove()->CommandoData().m_vecBullRushViewGoalDir.Init();
TFMove()->CommandoData().m_vecBullRushViewGoalDir.SetY( TFMove()->m_vecViewAngles.y );
// Set movement type.
player->SetMoveType( (MoveType_t)COMMANDO_MOVETYPE_BULLRUSH );
player->SetMoveCollide( MOVECOLLIDE_DEFAULT );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CTFGameMovementCommando::PrePlayerMove( void )
{
// Assume we don't touch anything (Reset the touch list).
MoveHelper()->ResetTouchList();
// Check to see if we are stuck.
if ( CheckStuck() )
return false;
CheckBullRush();
// Update (reduce) movement timers.
UpdateTimers();
// Check to see if the player is dead and setup death data, otherwise setup
// the players view angles.
if ( !CheckDeath() )
{
SetupViewAngles();
}
// Handle ducking.
HandleDuck();
// Handle ladder.
HandleLadder();
// Categorize the player's position.
CategorizePosition();
// Calculate the player's movement speed (has to happen after categorize position)
SetupSpeed();
// Update our stepping sound (based on the player's location).
player->UpdateStepSound( m_pSurfaceData, mv->m_vecAbsOrigin, mv->m_vecVelocity );
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::HandlePlayerMove( void )
{
// Handle the specific bull rush movement type.
if ( player->GetMoveType() == COMMANDO_MOVETYPE_BULLRUSH )
{
BullRushMove();
return;
}
// Let the default TF2 player movement code handle the move.
BaseClass::HandlePlayerMove();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::HandleDuck( void )
{
if ( player->GetMoveType() == COMMANDO_MOVETYPE_BULLRUSH )
return;
BaseClass::HandleDuck();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::UpdateTimers( void )
{
BaseClass::UpdateTimers();
CTFMoveData *pMoveData = TFMove();
if ( !pMoveData )
return;
float frame_msec = 1000.0f * gpGlobals->frametime;
// Decrement the bull rush time.
if ( pMoveData->CommandoData().m_flBullRushTime != COMMANDO_TIME_INVALID )
{
if ( pMoveData->CommandoData().m_flBullRushTime > 0.0f )
{
pMoveData->CommandoData().m_flBullRushTime -= frame_msec;
}
else
{
TFMove()->CommandoData().m_bBullRush = false;
TFMove()->CommandoData().m_flBullRushTime = COMMANDO_TIME_INVALID;
player->SetMoveType( MOVETYPE_WALK );
player->SetMoveCollide( MOVECOLLIDE_DEFAULT );
}
}
if ( pMoveData->CommandoData().m_flDoubleTapForwardTime != COMMANDO_TIME_INVALID )
{
if ( pMoveData->CommandoData().m_flDoubleTapForwardTime > 0.0f )
{
pMoveData->CommandoData().m_flDoubleTapForwardTime -= frame_msec;
}
else
{
pMoveData->CommandoData().m_flDoubleTapForwardTime = COMMANDO_TIME_INVALID;
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::SetupViewAngles( void )
{
BaseClass::SetupViewAngles();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::SetupSpeed( void )
{
BaseClass::SetupSpeed();
if ( player->GetMoveType() == COMMANDO_MOVETYPE_BULLRUSH )
{
mv->m_flMaxSpeed = sv_maxspeed.GetFloat();
// Slow down by the speed factor
if (m_pSurfaceData)
{
mv->m_flMaxSpeed *= m_pSurfaceData->game.maxSpeedFactor;
}
mv->m_flForwardMove = TFMove()->m_flClientMaxSpeed * 4.0f;
mv->m_flUpMove = 0.0f;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CTFGameMovementCommando::CalcWishVelocityAndPosition( Vector &vWishPos, Vector &vWishDir, float &flWishSpeed )
{
//
// Determine the movement angles.
//
Vector vForward, vRight, vUp;
if ( player->GetMoveType() == COMMANDO_MOVETYPE_BULLRUSH )
{
vForward = TFMove()->CommandoData().m_vecBullRushDir;
// Cross the bullrush direction with the z-axis to get the right vector.
CrossProduct( vForward, Vector( 0.0f, 0.0f, 1.0f ), vRight );
vUp.Init();
}
else
{
AngleVectors( mv->m_vecViewAngles, &vForward, &vRight, &vUp );
//
// Zero out the z component of the movement vectors and renormalize.
//
vForward.z = 0.0f;
VectorNormalize( vForward );
vRight.z = 0.0f;
VectorNormalize( vRight );
}
//
// Determine the xy parts of the velocity.
//
Vector vWishVel( 0.0f, 0.0f, 0.0f );
for ( int axis = 0; axis < 2; axis++ )
{
vWishVel[axis] = ( vForward[axis] * mv->m_flForwardMove ) +
( vRight[axis] * mv->m_flSideMove );
}
vWishVel.z = 0.0f;
//
// Componentize the velocity into direction and speed.
//
VectorCopy( vWishVel, vWishDir );
flWishSpeed = VectorNormalize( vWishDir );
if ( flWishSpeed > mv->m_flMaxSpeed )
{
VectorScale( vWishVel, ( mv->m_flMaxSpeed / flWishSpeed ), vWishVel );
flWishSpeed = mv->m_flMaxSpeed;
}
//
// Accelerate (in the plane).
//
mv->m_vecVelocity.z = 0.0f;
Accelerate( vWishDir, flWishSpeed, sv_accelerate.GetFloat() );
mv->m_vecVelocity.z = 0.0f;
// Add in any base velocity (from conveyers, etc.) to the current velocity.
VectorAdd( mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity );
//
// Stop the player (zero out velocity) if the player's speed is below a
// given threshold.
//
float flSpeed = VectorLength( mv->m_vecVelocity );
if ( flSpeed < 1.0f /*SPEED_STOP_THRESHOLD*/ )
{
mv->m_vecVelocity.Init();
return false;
}
//
// Calculate the wish position.
//
vWishPos.x = mv->m_vecAbsOrigin.x + ( mv->m_vecVelocity.x * gpGlobals->frametime );
vWishPos.y = mv->m_vecAbsOrigin.y + ( mv->m_vecVelocity.y * gpGlobals->frametime );
vWishPos.z = mv->m_vecAbsOrigin.z;
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGameMovementCommando::BullRushMove( void )
{
CTFMoveData *pMoveData = TFMove();
if ( !pMoveData )
return;
// Ignoring water for now!!!!
StartGravity();
// Fricion is handled before we add in any base velocity. That way, if we are on a conveyor,
// we don't slow when standing still, relative to the conveyor.
if (player->GetGroundEntity() != NULL)
{
mv->m_vecVelocity[2] = 0.0;
Friction();
}
// Make sure velocity is valid.
CheckVelocity();
if (player->GetGroundEntity() != NULL)
{
WalkMove2();
}
else
{
AirMove(); // Take into account movement when in air.
}
// Set final flags.
CategorizePosition();
// Now pull the base velocity back out. Base velocity is set if you are on a moving object, like
// a conveyor (or maybe another monster?)
VectorSubtract (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity );
// Make sure velocity is valid.
CheckVelocity();
// Add any remaining gravitational component.
FinishGravity();
// If we are on ground, no downward velocity.
if ( player->GetGroundEntity() != NULL )
{
mv->m_vecVelocity[2] = 0;
}
CheckFalling();
}