diff options
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.cpp | 123 |
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(); +} + |