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.
231 lines
5.9 KiB
231 lines
5.9 KiB
![]()
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: CBaseTFPlayer functions dealing with death and reinforcement
|
||
|
//
|
||
|
// $Workfile: $
|
||
|
// $Date: $
|
||
|
// $NoKeywords: $
|
||
|
//=============================================================================//
|
||
|
#include "cbase.h"
|
||
|
#include "player.h"
|
||
|
#include "tf_player.h"
|
||
|
#include "gamerules.h"
|
||
|
#include "basecombatweapon.h"
|
||
|
#include "EntityList.h"
|
||
|
#include "tf_shareddefs.h"
|
||
|
#include "tf_team.h"
|
||
|
#include "baseviewmodel.h"
|
||
|
#include "tf_class_infiltrator.h"
|
||
|
#include "in_buttons.h"
|
||
|
#include "globals.h"
|
||
|
|
||
|
int g_iNumberOfCorpses;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: The player was just killed
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFPlayer::Event_Killed( const CTakeDamageInfo &info )
|
||
|
{
|
||
|
// TODO don't use temp entities to transmit messages
|
||
|
CPASFilter filter( GetLocalOrigin() );
|
||
|
te->KillPlayerAttachments( filter, 0.0, entindex() );
|
||
|
|
||
|
// Remove the player from any vehicle they're in
|
||
|
if ( IsInAVehicle() )
|
||
|
{
|
||
|
LeaveVehicle();
|
||
|
}
|
||
|
|
||
|
// Holster weapon immediately, to allow it to cleanup
|
||
|
if (GetActiveWeapon())
|
||
|
{
|
||
|
GetActiveWeapon()->Holster( );
|
||
|
}
|
||
|
|
||
|
// Stop attaching sappers
|
||
|
if ( IsAttachingSapper() )
|
||
|
{
|
||
|
StopAttaching();
|
||
|
}
|
||
|
|
||
|
// stop them touching anything
|
||
|
AddFlag( FL_DONTTOUCH );
|
||
|
|
||
|
g_pGameRules->PlayerKilled( this, info );
|
||
|
|
||
|
ClearUseEntity();
|
||
|
|
||
|
// If I'm ragdolling due to a knockdown, don't play any animations
|
||
|
if ( m_hRagdollShadow == NULL )
|
||
|
{
|
||
|
if ( PlayerClass() != TFCLASS_INFILTRATOR )
|
||
|
{
|
||
|
// Calculate death force
|
||
|
Vector forceVector = CalcDamageForceVector( info );
|
||
|
|
||
|
BecomeRagdollOnClient( forceVector );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetAnimation( PLAYER_DIE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DeathSound( info );
|
||
|
|
||
|
SetViewOffset( VEC_DEAD_VIEWHEIGHT_SCALED( this ) );
|
||
|
m_lifeState = LIFE_DYING;
|
||
|
pl.deadflag = true;
|
||
|
|
||
|
// Enter dying state
|
||
|
AddSolidFlags( FSOLID_NOT_SOLID );
|
||
|
SetMoveType( MOVETYPE_NONE );
|
||
|
QAngle angles = GetLocalAngles();
|
||
|
angles.x = angles.z = 0;
|
||
|
SetLocalAngles( angles );
|
||
|
m_takedamage = DAMAGE_NO;
|
||
|
|
||
|
// clear out the suit message cache so we don't keep chattering
|
||
|
SetSuitUpdate(NULL, false, 0);
|
||
|
|
||
|
// reset FOV
|
||
|
SetFOV( this, 0 );
|
||
|
|
||
|
// Setup for respawn
|
||
|
m_flTimeOfDeath = gpGlobals->curtime;
|
||
|
|
||
|
SetThink(TFPlayerDeathThink);
|
||
|
SetNextThink( gpGlobals->curtime + 0.1f );
|
||
|
|
||
|
SetPowerup(POWERUP_EMP,false);
|
||
|
|
||
|
// Tell the playerclass that the player died
|
||
|
if ( GetPlayerClass() )
|
||
|
{
|
||
|
GetPlayerClass()->PlayerDied( info.GetAttacker() );
|
||
|
}
|
||
|
|
||
|
// Tell the attacker's playerclass that he killed someone
|
||
|
if ( info.GetAttacker() && info.GetAttacker()->IsPlayer() )
|
||
|
{
|
||
|
CBaseTFPlayer *pPlayerAttacker = (CBaseTFPlayer*)info.GetAttacker();
|
||
|
pPlayerAttacker->KilledPlayer( this );
|
||
|
}
|
||
|
|
||
|
DropAllResourceChunks();
|
||
|
|
||
|
// Tell all teams to update their orders
|
||
|
COrderEvent_PlayerKilled order( this );
|
||
|
GlobalOrderEvent( &order );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Think function for dead/dying players.
|
||
|
// Play their death animation, then set up for reinforcement.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFPlayer::TFPlayerDeathThink(void)
|
||
|
{
|
||
|
float flForward;
|
||
|
|
||
|
SetNextThink( gpGlobals->curtime + 0.1f );
|
||
|
|
||
|
if ( GetFlags() & FL_ONGROUND )
|
||
|
{
|
||
|
flForward = GetAbsVelocity().Length() - 20;
|
||
|
if (flForward <= 0)
|
||
|
{
|
||
|
SetAbsVelocity( vec3_origin );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Vector vecNewVelocity = GetAbsVelocity();
|
||
|
VectorNormalize( vecNewVelocity );
|
||
|
vecNewVelocity *= flForward;
|
||
|
SetAbsVelocity( vecNewVelocity );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
StudioFrameAdvance();
|
||
|
|
||
|
if (GetModelIndex() && (!IsSequenceFinished()) && (m_lifeState == LIFE_DYING))
|
||
|
{
|
||
|
m_iRespawnFrames++;
|
||
|
if ( m_iRespawnFrames < 60 ) // animations should be no longer than this
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Start looping dying state
|
||
|
SetAnimation( PLAYER_DIE );
|
||
|
|
||
|
// ROBIN: Everyone respawns immediately now. Maps will define respawns in the future.
|
||
|
|
||
|
if ( (gpGlobals->curtime - m_flTimeOfDeath) < 3 )
|
||
|
return;
|
||
|
|
||
|
m_lifeState = LIFE_RESPAWNABLE;
|
||
|
|
||
|
// Respawn on button press, but not if they're checking the scores
|
||
|
// Also respawn if they're not looking at scores, and they've been dead for over 5 seconds
|
||
|
bool bButtonDown = (m_nButtons & ~IN_SCORE) > 0;
|
||
|
if ( (bButtonDown || (gpGlobals->curtime - m_flTimeOfDeath) > 5 ) )
|
||
|
{
|
||
|
PlayerRespawn();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
// Aliens become respawnable immediately, because they're waiting for a reinforcement wave.
|
||
|
// Humans have to wait a short time.
|
||
|
if ( (GetTeamNumber() == TEAM_HUMANS) && (gpGlobals->curtime - m_flTimeOfDeath) < 3 )
|
||
|
return;
|
||
|
if ( (GetTeamNumber() == TEAM_ALIENS) && (gpGlobals->curtime - m_flTimeOfDeath) < 1 )
|
||
|
return;
|
||
|
|
||
|
// Humans can respawn, Aliens can't (reinforcement wave for their kind)
|
||
|
// Aliens stop thinking now and wait for the reinforcement wave
|
||
|
if ( GetTeamNumber() == TEAM_ALIENS )
|
||
|
{
|
||
|
m_lifeState = LIFE_RESPAWNABLE;
|
||
|
SetThink( NULL );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_lifeState = LIFE_RESPAWNABLE;
|
||
|
|
||
|
// Respawn on button press
|
||
|
if ( m_nButtons & ~IN_SCORE )
|
||
|
{
|
||
|
PlayerRespawn();
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Return true if this player is ready to reinforce
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBaseTFPlayer::IsReadyToReinforce( void )
|
||
|
{
|
||
|
// Only Aliens reinforce in waves, humans respawn normally
|
||
|
if ( (GetTeamNumber() == TEAM_ALIENS) && (m_lifeState == LIFE_RESPAWNABLE) )
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Bring the player back to life in a reinforcement wave
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFPlayer::Reinforce( void )
|
||
|
{
|
||
|
// Tell all teams to update their orders
|
||
|
COrderEvent_PlayerRespawned order( this );
|
||
|
GlobalOrderEvent( &order );
|
||
|
|
||
|
StopAnimation();
|
||
|
IncrementInterpolationFrame();
|
||
|
m_flPlaybackRate = 0.0;
|
||
|
|
||
|
PlayerRespawn();
|
||
|
}
|
||
|
|