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.

263 lines
6.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Base class for many flying NPCs
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "ai_basenpc_flyer.h"
  9. #include "ai_route.h"
  10. #include "ai_navigator.h"
  11. #include "ai_motor.h"
  12. // memdbgon must be the last include file in a .cpp file!!!
  13. #include "tier0/memdbgon.h"
  14. BEGIN_DATADESC( CAI_BaseFlyingBot )
  15. DEFINE_FIELD( m_vCurrentVelocity, FIELD_VECTOR),
  16. DEFINE_FIELD( m_vCurrentAngularVelocity, FIELD_VECTOR ),
  17. DEFINE_FIELD( m_vCurrentBanking, FIELD_VECTOR),
  18. DEFINE_FIELD( m_vNoiseMod, FIELD_VECTOR),
  19. DEFINE_FIELD( m_fHeadYaw, FIELD_FLOAT),
  20. DEFINE_FIELD( m_vLastPatrolDir, FIELD_VECTOR),
  21. END_DATADESC()
  22. //------------------------------------------------------------------------------
  23. // Purpose : Override to return correct velocity
  24. // Input :
  25. // Output :
  26. //------------------------------------------------------------------------------
  27. void CAI_BaseFlyingBot::GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity)
  28. {
  29. if (vVelocity != NULL)
  30. {
  31. VectorCopy(m_vCurrentVelocity,*vVelocity);
  32. }
  33. if (vAngVelocity != NULL)
  34. {
  35. QAngle tmp = GetLocalAngularVelocity();
  36. QAngleToAngularImpulse( tmp, *vAngVelocity );
  37. }
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Purpose: Turn head yaw into facing direction
  41. // Input :
  42. // Output :
  43. //-----------------------------------------------------------------------------
  44. QAngle CAI_BaseFlyingBot::BodyAngles()
  45. {
  46. return QAngle(0,m_fHeadYaw,0);
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose:
  50. // Input :
  51. // Output :
  52. //-----------------------------------------------------------------------------
  53. void CAI_BaseFlyingBot::TurnHeadToTarget(float flInterval, const Vector &MoveTarget )
  54. {
  55. float flDestYaw = VecToYaw( MoveTarget - GetLocalOrigin() );
  56. float newYaw = AI_ClampYaw( GetHeadTurnRate() * 10.0f, m_fHeadYaw, flDestYaw, gpGlobals->curtime - GetLastThink() );
  57. if ( newYaw != m_fHeadYaw )
  58. {
  59. m_fHeadYaw = newYaw;
  60. }
  61. // Set us to face that way
  62. SetBoneController( 0, m_fHeadYaw );
  63. }
  64. //------------------------------------------------------------------------------
  65. // Purpose :
  66. // Input :
  67. // Output :
  68. //------------------------------------------------------------------------------
  69. float CAI_BaseFlyingBot::MinGroundDist(void)
  70. {
  71. return 0;
  72. }
  73. //------------------------------------------------------------------------------
  74. // Purpose :
  75. // Input :
  76. // Output :
  77. //------------------------------------------------------------------------------
  78. Vector CAI_BaseFlyingBot::VelocityToAvoidObstacles(float flInterval)
  79. {
  80. // --------------------------------
  81. // Avoid banging into stuff
  82. // --------------------------------
  83. trace_t tr;
  84. Vector vTravelDir = m_vCurrentVelocity*flInterval;
  85. Vector endPos = GetAbsOrigin() + vTravelDir;
  86. AI_TraceEntity( this, GetAbsOrigin(), endPos, MASK_NPCSOLID|CONTENTS_WATER, &tr );
  87. if (tr.fraction != 1.0)
  88. {
  89. // Bounce off in normal
  90. Vector vBounce = tr.plane.normal * 0.5 * m_vCurrentVelocity.Length();
  91. return (vBounce);
  92. }
  93. // --------------------------------
  94. // Try to remain above the ground.
  95. // --------------------------------
  96. float flMinGroundDist = MinGroundDist();
  97. AI_TraceLine(GetAbsOrigin(), GetAbsOrigin() + Vector(0, 0, -flMinGroundDist),
  98. MASK_NPCSOLID_BRUSHONLY|CONTENTS_WATER, this, COLLISION_GROUP_NONE, &tr);
  99. if (tr.fraction < 1)
  100. {
  101. // Clamp veloctiy
  102. if (tr.fraction < 0.1)
  103. {
  104. tr.fraction = 0.1;
  105. }
  106. return Vector(0, 0, 50/tr.fraction);
  107. }
  108. return vec3_origin;
  109. }
  110. //------------------------------------------------------------------------------
  111. // Purpose :
  112. // Input :
  113. // Output :
  114. //------------------------------------------------------------------------------
  115. void CAI_BaseFlyingBot::StartTask( const Task_t *pTask )
  116. {
  117. switch (pTask->iTask)
  118. {
  119. // Skip as done via bone controller
  120. case TASK_FACE_ENEMY:
  121. {
  122. TaskComplete();
  123. break;
  124. }
  125. // Activity is just idle (have no run)
  126. case TASK_RUN_PATH:
  127. {
  128. GetNavigator()->SetMovementActivity(ACT_IDLE);
  129. TaskComplete();
  130. break;
  131. }
  132. // Don't check for run/walk activity
  133. case TASK_SCRIPT_RUN_TO_TARGET:
  134. case TASK_SCRIPT_WALK_TO_TARGET:
  135. {
  136. if (GetTarget() == NULL)
  137. {
  138. TaskFail(FAIL_NO_TARGET);
  139. }
  140. else
  141. {
  142. if (!GetNavigator()->SetGoal( GOALTYPE_TARGETENT ) )
  143. {
  144. TaskFail(FAIL_NO_ROUTE);
  145. GetNavigator()->ClearGoal();
  146. }
  147. }
  148. TaskComplete();
  149. break;
  150. }
  151. // Override to get more to get a directional path
  152. case TASK_GET_PATH_TO_RANDOM_NODE:
  153. {
  154. if ( GetNavigator()->SetRandomGoal( pTask->flTaskData, m_vLastPatrolDir ) )
  155. TaskComplete();
  156. else
  157. TaskFail(FAIL_NO_REACHABLE_NODE);
  158. break;
  159. }
  160. default:
  161. {
  162. BaseClass::StartTask(pTask);
  163. }
  164. }
  165. }
  166. //------------------------------------------------------------------------------
  167. void CAI_BaseFlyingBot::MoveToTarget(float flInterval, const Vector &MoveTarget)
  168. {
  169. Assert(0); // This must be overridden in the leaf classes
  170. }
  171. //------------------------------------------------------------------------------
  172. AI_NavPathProgress_t CAI_BaseFlyingBot::ProgressFlyPath(
  173. float flInterval,
  174. const CBaseEntity *pNewTarget,
  175. unsigned collisionMask,
  176. bool bNewTrySimplify,
  177. float strictPointTolerance)
  178. {
  179. AI_ProgressFlyPathParams_t params( collisionMask, strictPointTolerance );
  180. params.SetCurrent( pNewTarget, bNewTrySimplify );
  181. AI_NavPathProgress_t progress = GetNavigator()->ProgressFlyPath( params );
  182. switch ( progress )
  183. {
  184. case AINPP_NO_CHANGE:
  185. case AINPP_ADVANCED:
  186. {
  187. MoveToTarget(flInterval, GetNavigator()->GetCurWaypointPos());
  188. break;
  189. }
  190. case AINPP_COMPLETE:
  191. {
  192. TaskMovementComplete();
  193. break;
  194. }
  195. case AINPP_BLOCKED: // function is not supposed to test blocking, just simple path progression
  196. default:
  197. {
  198. AssertMsg( 0, ( "Unexpected result" ) );
  199. break;
  200. }
  201. }
  202. return progress;
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose:
  206. // Input : *pTarget -
  207. // &chasePosition -
  208. //-----------------------------------------------------------------------------
  209. void CAI_BaseFlyingBot::TranslateNavGoal( CBaseEntity *pTarget, Vector &chasePosition )
  210. {
  211. Assert( pTarget != NULL );
  212. if ( pTarget == NULL )
  213. {
  214. chasePosition = vec3_origin;
  215. return;
  216. }
  217. // Chase their eyes
  218. chasePosition = pTarget->GetAbsOrigin() + pTarget->GetViewOffset();
  219. }
  220. //------------------------------------------------------------------------------
  221. // Purpose :
  222. // Input :
  223. // Output :
  224. //------------------------------------------------------------------------------
  225. CAI_BaseFlyingBot::CAI_BaseFlyingBot()
  226. {
  227. #ifdef _DEBUG
  228. m_vCurrentVelocity.Init();
  229. m_vCurrentBanking.Init();
  230. m_vLastPatrolDir.Init();
  231. #endif
  232. }