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.
110 lines
3.4 KiB
110 lines
3.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "tf_passtime_ball.h" |
|
#include "tf_passtime_logic.h" |
|
#include "passtime_convars.h" |
|
#include "passtime_ballcontroller_playerseek.h" |
|
#include "tf_player.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
namespace { |
|
const int kPriority = 1; // same as homing, so they stack |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
CPasstimeBallControllerPlayerSeek::CPasstimeBallControllerPlayerSeek() |
|
: CPasstimeBallController( kPriority ) // low priority |
|
, m_fEnableTime( 0 ) |
|
{} |
|
|
|
//----------------------------------------------------------------------------- |
|
bool CPasstimeBallControllerPlayerSeek::Apply( CPasstimeBall *ball ) |
|
{ |
|
if ( gpGlobals->curtime < m_fEnableTime ) |
|
return false; |
|
return Seek( ball, FindTarget( ball->GetThrower(), ball->GetAbsOrigin() ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
CTFPlayer *CPasstimeBallControllerPlayerSeek::FindTarget( CTFPlayer *pIgnorePlayer, const Vector& ballOrigin ) const |
|
{ |
|
CTFPlayer *pTarget = 0; |
|
float closestPlayerDist = tf_passtime_ball_seek_range.GetFloat(); |
|
closestPlayerDist *= closestPlayerDist; // avoid some sqrts |
|
|
|
// Treat this trace exactly like radius damage |
|
CTraceFilterIgnorePlayers traceFilter( 0, COLLISION_GROUP_PLAYER_MOVEMENT ); |
|
|
|
for ( int i = 1; i <= MAX_PLAYERS; i++ ) |
|
{ |
|
CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( i ) ); |
|
if ( !pPlayer ) |
|
continue; // wat |
|
|
|
if ( pPlayer == pIgnorePlayer ) |
|
continue; |
|
|
|
const Vector& eyepos = pPlayer->WorldSpaceCenter(); |
|
const float dist = (eyepos - ballOrigin).LengthSqr(); |
|
if ( dist >= closestPlayerDist ) |
|
continue; // to far away |
|
|
|
if ( pPlayer->m_Shared.InCond( TF_COND_DISGUISED ) ) |
|
continue; // don't seek any disguised people |
|
|
|
if ( !g_pPasstimeLogic->BCanPlayerPickUpBall( pPlayer ) ) |
|
continue; // can't pick it up |
|
|
|
trace_t trace; |
|
UTIL_TraceLine( ballOrigin, eyepos, MASK_PLAYERSOLID, &traceFilter, &trace ); |
|
if ( trace.fraction != 1 ) |
|
continue; // occluded |
|
|
|
// chicken dinner |
|
pTarget = pPlayer; |
|
closestPlayerDist = dist; |
|
} |
|
return pTarget; |
|
} |
|
|
|
extern float GetCurrentGravity( void ); // tf_gamerules.h |
|
|
|
//----------------------------------------------------------------------------- |
|
bool CPasstimeBallControllerPlayerSeek::Seek( CPasstimeBall *ball, CTFPlayer *pTarget ) const |
|
{ |
|
if ( !pTarget ) |
|
return false; |
|
|
|
// taken from ballcontroller_homing |
|
IPhysicsObject *pPhys = ball->VPhysicsGetObject(); |
|
Vector ballpos; |
|
pPhys->GetPosition( &ballpos, 0 ); |
|
|
|
Vector targetvel = pTarget->EyePosition() - ballpos; |
|
targetvel.NormalizeInPlace(); |
|
targetvel *= pTarget->TeamFortress_CalculateMaxSpeed() * |
|
tf_passtime_ball_seek_speed_factor.GetFloat(); |
|
|
|
Vector currentvel; |
|
pPhys->GetVelocity( ¤tvel, 0 ); |
|
Vector steer = targetvel - currentvel; |
|
pPhys->AddVelocity( &steer, 0 ); |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void CPasstimeBallControllerPlayerSeek::OnBallSpawned( CPasstimeBall *ball ) |
|
{ |
|
// NOTE: this hack is the only thing that prevents players from picking up |
|
// balls immediately after they were thrown (including by nearby unrelated |
|
// players) |
|
m_fEnableTime = gpGlobals->curtime + 0.25f; |
|
}
|
|
|