diff options
Diffstat (limited to 'game/server/tf2/tf_player_death.cpp')
| -rw-r--r-- | game/server/tf2/tf_player_death.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/game/server/tf2/tf_player_death.cpp b/game/server/tf2/tf_player_death.cpp new file mode 100644 index 0000000..da90f9e --- /dev/null +++ b/game/server/tf2/tf_player_death.cpp @@ -0,0 +1,230 @@ +//========= 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(); +} + |