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.

215 lines
6.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // tf_tactical_mission.cpp
  3. // Team Fortress specific missions
  4. // Michael Booth, June 2009
  5. #include "cbase.h"
  6. #include "nav_pathfind.h"
  7. #include "nav_mesh/tf_nav_mesh.h"
  8. #include "tf_player.h"
  9. #include "tf_tactical_mission.h"
  10. extern ConVar tf_bot_max_point_defend_range;
  11. /*
  12. //-----------------------------------------------------------------------------------------------------
  13. //-----------------------------------------------------------------------------------------------------
  14. class CCollectPointDefenseAreas : public ISearchSurroundingAreasFunctor
  15. {
  16. public:
  17. CCollectPointDefenseAreas( CTFNavArea *pointArea, bool isKingOfTheHill, CUtlVector< CNavArea * > *areaVector )
  18. {
  19. m_pointArea = pointArea;
  20. m_isKingOfTheHill = isKingOfTheHill;
  21. // don't select areas that are beyond the point
  22. m_incursionFlowLimit = pointArea->GetIncursionDistance( TF_TEAM_RED ) + 250.0f;
  23. m_areaVector = areaVector;
  24. m_areaVector->RemoveAll();
  25. }
  26. virtual bool operator() ( CNavArea *baseArea, CNavArea *priorArea, float travelDistanceSoFar )
  27. {
  28. CTFNavArea *area = (CTFNavArea *)baseArea;
  29. if ( !m_isKingOfTheHill )
  30. {
  31. // don't select areas that are beyond the point
  32. if ( area->GetIncursionDistance( TF_TEAM_RED ) > m_incursionFlowLimit )
  33. return true;
  34. }
  35. if ( area->IsPotentiallyVisible( m_pointArea ) )
  36. {
  37. // a bit of a hack here to avoid bots choosing to defend in bottom of ravine at stage 3 of dustbowl
  38. const float tooLow = 220.0f;
  39. if ( m_pointArea->GetCenter().z - area->GetCenter().z < tooLow )
  40. {
  41. // valid defense position
  42. area->SetAttributeTF( TF_NAV_DEFEND_POINT );
  43. m_areaVector->AddToTail( area );
  44. }
  45. }
  46. return true;
  47. }
  48. virtual bool ShouldSearch( CNavArea *adjArea, CNavArea *currentArea, float travelDistanceSoFar )
  49. {
  50. if ( adjArea->IsBlocked( m_isKingOfTheHill ? TEAM_ANY : TF_TEAM_RED ) )
  51. {
  52. return false;
  53. }
  54. if ( travelDistanceSoFar > tf_bot_max_point_defend_range.GetFloat() )
  55. {
  56. // too far away
  57. return false;
  58. }
  59. const float maxHeightChange = 65.0f;
  60. float deltaZ = currentArea->ComputeAdjacentConnectionHeightChange( adjArea );
  61. return ( fabs( deltaZ ) < maxHeightChange );
  62. }
  63. CTFNavArea *m_pointArea;
  64. CUtlVector< CNavArea * > *m_areaVector;
  65. float m_incursionFlowLimit;
  66. bool m_isKingOfTheHill;
  67. };
  68. / **
  69. * Create a zone of areas that are good defensive places for the given point
  70. * /
  71. CTFDefendPointZone::CTFDefendPointZone( CTeamControlPoint *point )
  72. {
  73. CTFNavArea *pointArea = static_cast< CTFNavArea * >( TheNavMesh->GetNearestNavArea( point->GetAbsOrigin() ) );
  74. if ( pointArea )
  75. {
  76. bool isKingOfTheHill = false;
  77. CTeamControlPointMaster *master = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
  78. if ( master )
  79. {
  80. isKingOfTheHill = ( master->GetNumPoints() == 1 );
  81. }
  82. // search outwards from the point along walkable areas (not drop downs) to make sure we can get back to the point quickly
  83. CCollectPointDefenseAreas collector( pointArea, isKingOfTheHill, &m_areaVector );
  84. SearchSurroundingAreas( pointArea, collector );
  85. }
  86. }
  87. */
  88. //-----------------------------------------------------------------------------------------------------
  89. //-----------------------------------------------------------------------------------------------------
  90. /**
  91. * Create a zone of areas that are good sniper spots to defend the given point
  92. */
  93. CTFDefendPointSniperZone::CTFDefendPointSniperZone( CTeamControlPoint *point )
  94. {
  95. }
  96. //-----------------------------------------------------------------------------------------------------
  97. //-----------------------------------------------------------------------------------------------------
  98. CTFDefendPointMission::CTFDefendPointMission( CTeamControlPoint *point )
  99. {
  100. // m_defenseZone = new CTFDefendPointZone( point );
  101. m_sniperZone = new CTFDefendPointSniperZone( point );
  102. m_name.sprintf( "DefendPoint%d", point->GetPointIndex() );
  103. }
  104. //-----------------------------------------------------------------------------------------------------
  105. CTFDefendPointMission::~CTFDefendPointMission( void )
  106. {
  107. // delete m_defenseZone;
  108. delete m_sniperZone;
  109. }
  110. //-----------------------------------------------------------------------------------------------------
  111. // where give player should be during this mission
  112. const CTacticalMissionZone *CTFDefendPointMission::GetDeployZone( CBasePlayer *baseWho ) const
  113. {
  114. // CTFPlayer *who = ToTFPlayer( baseWho );
  115. // if ( who->IsPlayerClass( TF_CLASS_SNIPER ) )
  116. // return m_sniperZone;
  117. return m_defenseZone;
  118. }
  119. //-----------------------------------------------------------------------------------------------------
  120. // control points, setup gates, sections of cart path, etc.
  121. const CTacticalMissionZone *CTFDefendPointMission::GetObjectiveZone( void ) const
  122. {
  123. return NULL;
  124. }
  125. //-----------------------------------------------------------------------------------------------------
  126. // where we expect enemies to be during this mission
  127. const CTacticalMissionZone *CTFDefendPointMission::GetEnemyZone( void ) const
  128. {
  129. return NULL;
  130. }
  131. //-----------------------------------------------------------------------------------------------------
  132. //-----------------------------------------------------------------------------------------------------
  133. /**
  134. * Invoked when server loads a new map, after everything has been created/spawned
  135. */
  136. void CTFTacticalMissionManager::OnServerActivate( void )
  137. {
  138. }
  139. //-----------------------------------------------------------------------------------------------------
  140. /**
  141. * Invoked when a game round restarts
  142. */
  143. void CTFTacticalMissionManager::OnRoundRestart( void )
  144. {
  145. // for now, delete and rebuild all the missions
  146. // @todo only delete/rebuild generated missions
  147. FOR_EACH_VEC( m_missionVector, it )
  148. {
  149. delete m_missionVector[ it ];
  150. }
  151. m_missionVector.RemoveAll();
  152. // generate a defensive mission for each control point
  153. CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
  154. if ( pMaster )
  155. {
  156. for( int i=0; i<pMaster->GetNumPoints(); ++i )
  157. {
  158. CTeamControlPoint *point = pMaster->GetControlPoint( i );
  159. if ( point && pMaster->IsInRound( point ) )
  160. {
  161. CTFNavArea *pointArea = (CTFNavArea *)TheNavMesh->GetNearestNavArea( point->WorldSpaceCenter() );
  162. if ( pointArea && pointArea->IsReachableByTeam( TF_TEAM_BLUE ) )
  163. {
  164. CTacticalMission *defendPointMission = new CTFDefendPointMission( point );
  165. TheTacticalMissions().Register( defendPointMission );
  166. }
  167. }
  168. }
  169. }
  170. }