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