summaryrefslogtreecommitdiff
path: root/game/server/tf/passtime_ballcontroller_playerseek.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/tf/passtime_ballcontroller_playerseek.cpp')
-rw-r--r--game/server/tf/passtime_ballcontroller_playerseek.cpp110
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( &currentvel, 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;
+}