Counter Strike : Global Offensive Source Code
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.

195 lines
5.5 KiB

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