Team Fortress 2 Source Code as on 22/4/2020
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.

199 lines
5.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // simple_bot.cpp
  3. // A simple bot
  4. // Michael Booth, February 2009
  5. #include "cbase.h"
  6. #include "simple_bot.h"
  7. #include "nav_mesh.h"
  8. //-----------------------------------------------------------------------------------------------------
  9. // Command to add a Simple Bot where your crosshairs are aiming
  10. //-----------------------------------------------------------------------------------------------------
  11. CON_COMMAND_F( simple_bot_add, "Add a simple bot.", FCVAR_CHEAT )
  12. {
  13. CBasePlayer *player = UTIL_GetCommandClient();
  14. if ( !player )
  15. {
  16. return;
  17. }
  18. Vector forward;
  19. player->EyeVectors( &forward );
  20. trace_t result;
  21. UTIL_TraceLine( player->EyePosition(), player->EyePosition() + 999999.9f * forward, MASK_BLOCKLOS_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE, player, COLLISION_GROUP_NONE, &result );
  22. if ( !result.DidHit() )
  23. {
  24. return;
  25. }
  26. CSimpleBot *bot = static_cast< CSimpleBot * >( CreateEntityByName( "simple_bot" ) );
  27. if ( bot )
  28. {
  29. Vector forward = player->GetAbsOrigin() - result.endpos;
  30. forward.z = 0.0f;
  31. forward.NormalizeInPlace();
  32. QAngle angles;
  33. VectorAngles( forward, angles );
  34. bot->SetAbsAngles( angles );
  35. bot->SetAbsOrigin( result.endpos + Vector( 0, 0, 10.0f ) );
  36. DispatchSpawn( bot );
  37. }
  38. }
  39. //-----------------------------------------------------------------------------------------------------
  40. // The Simple Bot
  41. //-----------------------------------------------------------------------------------------------------
  42. LINK_ENTITY_TO_CLASS( simple_bot, CSimpleBot );
  43. #ifndef TF_DLL
  44. PRECACHE_REGISTER( simple_bot );
  45. #endif
  46. //-----------------------------------------------------------------------------------------------------
  47. CSimpleBot::CSimpleBot()
  48. {
  49. ALLOCATE_INTENTION_INTERFACE( CSimpleBot );
  50. m_locomotor = new NextBotGroundLocomotion( this );
  51. }
  52. //-----------------------------------------------------------------------------------------------------
  53. CSimpleBot::~CSimpleBot()
  54. {
  55. DEALLOCATE_INTENTION_INTERFACE;
  56. if ( m_locomotor )
  57. delete m_locomotor;
  58. }
  59. //-----------------------------------------------------------------------------------------------------
  60. void CSimpleBot::Precache()
  61. {
  62. BaseClass::Precache();
  63. #ifndef DOTA_DLL
  64. PrecacheModel( "models/humans/group01/female_01.mdl" );
  65. #endif
  66. }
  67. //-----------------------------------------------------------------------------------------------------
  68. void CSimpleBot::Spawn( void )
  69. {
  70. BaseClass::Spawn();
  71. #ifndef DOTA_DLL
  72. SetModel( "models/humans/group01/female_01.mdl" );
  73. #endif
  74. }
  75. //---------------------------------------------------------------------------------------------
  76. // The Simple Bot behaviors
  77. //---------------------------------------------------------------------------------------------
  78. /**
  79. * For use with TheNavMesh->ForAllAreas()
  80. * Find the Nth area in the sequence
  81. */
  82. class SelectNthAreaFunctor
  83. {
  84. public:
  85. SelectNthAreaFunctor( int count )
  86. {
  87. m_count = count;
  88. m_area = NULL;
  89. }
  90. bool operator() ( CNavArea *area )
  91. {
  92. m_area = area;
  93. return ( m_count-- > 0 );
  94. }
  95. int m_count;
  96. CNavArea *m_area;
  97. };
  98. //---------------------------------------------------------------------------------------------
  99. /**
  100. * This action causes the bot to pick a random nav area in the mesh and move to it, then
  101. * pick another, etc.
  102. * Actions usually each have their own .cpp/.h file and are organized into folders since there
  103. * are often many of them. For this example, we're keeping everything to a single .cpp/.h file.
  104. */
  105. class CSimpleBotRoam : public Action< CSimpleBot >
  106. {
  107. public:
  108. //----------------------------------------------------------------------------------
  109. // OnStart is called once when the Action first becomes active
  110. virtual ActionResult< CSimpleBot > OnStart( CSimpleBot *me, Action< CSimpleBot > *priorAction )
  111. {
  112. // smooth out the bot's path following by moving toward a point farther down the path
  113. m_path.SetMinLookAheadDistance( 300.0f );
  114. return Continue();
  115. }
  116. //----------------------------------------------------------------------------------
  117. // Update is called repeatedly (usually once per server frame) while the Action is active
  118. virtual ActionResult< CSimpleBot > Update( CSimpleBot *me, float interval )
  119. {
  120. if ( m_path.IsValid() && !m_timer.IsElapsed() )
  121. {
  122. // PathFollower::Update() moves the bot along the path using the bot's ILocomotion and IBody interfaces
  123. m_path.Update( me );
  124. }
  125. else
  126. {
  127. SelectNthAreaFunctor pick( RandomInt( 0, TheNavMesh->GetNavAreaCount() - 1 ) );
  128. TheNavMesh->ForAllAreas( pick );
  129. if ( pick.m_area )
  130. {
  131. CSimpleBotPathCost cost( me );
  132. m_path.Compute( me, pick.m_area->GetCenter(), cost );
  133. }
  134. // follow this path for a random duration (or until we reach the end)
  135. m_timer.Start( RandomFloat( 5.0f, 10.0f ) );
  136. }
  137. return Continue();
  138. }
  139. //----------------------------------------------------------------------------------
  140. // this is an event handler - many more are available (see declaration of Action< Actor > in NextBotBehavior.h)
  141. virtual EventDesiredResult< CSimpleBot > OnStuck( CSimpleBot *me )
  142. {
  143. // we are stuck trying to follow the current path - invalidate it so a new one is chosen
  144. m_path.Invalidate();
  145. return TryContinue();
  146. }
  147. virtual const char *GetName( void ) const { return "Roam"; } // return name of this action
  148. private:
  149. PathFollower m_path;
  150. CountdownTimer m_timer;
  151. };
  152. //---------------------------------------------------------------------------------------------
  153. /**
  154. * Instantiate the bot's Intention interface and start the initial Action (CSimpleBotRoam in this case)
  155. */
  156. IMPLEMENT_INTENTION_INTERFACE( CSimpleBot, CSimpleBotRoam )