summaryrefslogtreecommitdiff
path: root/game/server/tf/bot/behavior/tf_bot_use_teleporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/tf/bot/behavior/tf_bot_use_teleporter.cpp')
-rw-r--r--game/server/tf/bot/behavior/tf_bot_use_teleporter.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/game/server/tf/bot/behavior/tf_bot_use_teleporter.cpp b/game/server/tf/bot/behavior/tf_bot_use_teleporter.cpp
new file mode 100644
index 0000000..fc249fb
--- /dev/null
+++ b/game/server/tf/bot/behavior/tf_bot_use_teleporter.cpp
@@ -0,0 +1,123 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// tf_bot_use_teleporter.cpp
+// Ride a friendly teleporter
+// Michael Booth, May 2010
+
+#include "cbase.h"
+#include "nav_mesh.h"
+#include "tf_player.h"
+#include "bot/tf_bot.h"
+#include "bot/behavior/tf_bot_use_teleporter.h"
+
+extern ConVar tf_bot_path_lookahead_range;
+
+//---------------------------------------------------------------------------------------------
+CTFBotUseTeleporter::CTFBotUseTeleporter( CObjectTeleporter *teleporter, UseHowType how )
+{
+ m_teleporter = teleporter;
+ m_how = how;
+ m_isInTransit = false;
+}
+
+
+//---------------------------------------------------------------------------------------------
+ActionResult< CTFBot > CTFBotUseTeleporter::OnStart( CTFBot *me, Action< CTFBot > *priorAction )
+{
+ m_path.SetMinLookAheadDistance( me->GetDesiredPathLookAheadRange() );
+
+ return Continue();
+}
+
+
+//---------------------------------------------------------------------------------------------
+// We could compute the time it would take to walk from the tele entrance to exit
+// and compare that to the time needed to wait for the tele to be ready to send us,
+// but players tend to use the tele only if it is ready NOW (or very soon).
+bool CTFBotUseTeleporter::IsTeleporterAvailable( void ) const
+{
+ if ( m_teleporter != NULL )
+ {
+ if ( !m_teleporter->IsReady() )
+ return false;
+
+ if ( m_teleporter->GetState() == TELEPORTER_STATE_READY )
+ return true;
+
+/* causes massive bot pileups
+ if ( m_teleporter->GetState() == TELEPORTER_STATE_SENDING ||
+ m_teleporter->GetState() == TELEPORTER_STATE_RECHARGING )
+ {
+ if ( m_teleporter->GetUpgradeLevel() == 3 )
+ {
+ // we'll wait for level 3 teleporters - they're really fast
+ return true;
+ }
+ }
+*/
+ }
+
+ return false;
+}
+
+
+//---------------------------------------------------------------------------------------------
+ActionResult< CTFBot > CTFBotUseTeleporter::Update( CTFBot *me, float interval )
+{
+ if ( m_teleporter == NULL )
+ {
+ return Done( "Teleporter is gone" );
+ }
+
+ CObjectTeleporter *teleporterExit = m_teleporter->GetMatchingTeleporter();
+ if ( !teleporterExit )
+ {
+ return Done( "Missing teleporter exit" );
+ }
+
+ if ( m_teleporter->IsSendingPlayer( me ) )
+ {
+ // note that we have been teleported, because it takes a few frames
+ // to actually relocate us, even after our teleporter leaves the "sending" state
+ m_isInTransit = true;
+ }
+
+ if ( m_isInTransit )
+ {
+ if ( me->IsRangeLessThan( teleporterExit, 25.0f ) )
+ {
+ return Done( "Successful teleport" );
+ }
+ }
+ else if ( !IsTeleporterAvailable() && m_how == USE_IF_READY )
+ {
+ return Done( "Teleporter is not available" );
+ }
+
+ const CKnownEntity *threat = me->GetVisionInterface()->GetPrimaryKnownThreat();
+ if ( threat && threat->IsVisibleRecently() )
+ {
+ // prepare to fight
+ me->EquipBestWeaponForThreat( threat );
+ }
+
+ if ( m_repathTimer.IsElapsed() )
+ {
+ m_repathTimer.Start( RandomFloat( 1.0f, 2.0f ) );
+
+ CTFBotPathCost cost( me, FASTEST_ROUTE );
+ if ( m_path.Compute( me, m_teleporter->GetAbsOrigin(), cost ) == false )
+ {
+ // no path to teleporter
+ return Done( "Can't reach teleporter!" );
+ }
+ }
+
+ // move toward the teleporter until we're standing on it
+ if ( me->GetLocomotionInterface()->GetGround() != m_teleporter )
+ {
+ m_path.Update( me );
+ }
+
+ return Continue();
+}
+