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.

426 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: The downtrodden citizens of City 17. Timid when unarmed, they will
  4. // rise up against their Combine oppressors when given a weapon.
  5. //
  6. //=============================================================================//
  7. #ifndef NPC_CITIZEN_H
  8. #define NPC_CITIZEN_H
  9. #include "npc_playercompanion.h"
  10. #include "ai_behavior_functank.h"
  11. struct SquadCandidate_t;
  12. //-----------------------------------------------------------------------------
  13. //
  14. // CLASS: CNPC_Citizen
  15. //
  16. //-----------------------------------------------------------------------------
  17. //-------------------------------------
  18. // Spawnflags
  19. //-------------------------------------
  20. #define SF_CITIZEN_FOLLOW ( 1 << 16 ) //65536 follow the player as soon as I spawn.
  21. #define SF_CITIZEN_MEDIC ( 1 << 17 ) //131072
  22. #define SF_CITIZEN_RANDOM_HEAD ( 1 << 18 ) //262144
  23. #define SF_CITIZEN_AMMORESUPPLIER ( 1 << 19 ) //524288
  24. #define SF_CITIZEN_NOT_COMMANDABLE ( 1 << 20 ) //1048576
  25. #define SF_CITIZEN_IGNORE_SEMAPHORE ( 1 << 21 ) //2097152 Work outside the speech semaphore system
  26. #define SF_CITIZEN_RANDOM_HEAD_MALE ( 1 << 22 ) //4194304
  27. #define SF_CITIZEN_RANDOM_HEAD_FEMALE ( 1 << 23 )//8388608
  28. #define SF_CITIZEN_USE_RENDER_BOUNDS ( 1 << 24 )//16777216
  29. //-------------------------------------
  30. // Animation events
  31. //-------------------------------------
  32. enum CitizenType_t
  33. {
  34. CT_DEFAULT,
  35. CT_DOWNTRODDEN,
  36. CT_REFUGEE,
  37. CT_REBEL,
  38. CT_UNIQUE
  39. };
  40. //-----------------------------------------------------------------------------
  41. // Citizen expression types
  42. //-----------------------------------------------------------------------------
  43. enum CitizenExpressionTypes_t
  44. {
  45. CIT_EXP_UNASSIGNED, // Defaults to this, selects other in spawn.
  46. CIT_EXP_SCARED,
  47. CIT_EXP_NORMAL,
  48. CIT_EXP_ANGRY,
  49. CIT_EXP_LAST_TYPE,
  50. };
  51. //-------------------------------------
  52. class CNPC_Citizen : public CNPC_PlayerCompanion
  53. {
  54. DECLARE_CLASS( CNPC_Citizen, CNPC_PlayerCompanion );
  55. public:
  56. CNPC_Citizen()
  57. : m_iHead( -1 )
  58. {
  59. }
  60. //---------------------------------
  61. bool CreateBehaviors();
  62. void Precache();
  63. void PrecacheAllOfType( CitizenType_t );
  64. void Spawn();
  65. void PostNPCInit();
  66. virtual void SelectModel();
  67. void SelectExpressionType();
  68. void Activate();
  69. virtual void OnGivenWeapon( CBaseCombatWeapon *pNewWeapon );
  70. void FixupMattWeapon();
  71. #ifdef HL2_EPISODIC
  72. virtual float GetJumpGravity() const { return 1.8f; }
  73. #endif//HL2_EPISODIC
  74. void OnRestore();
  75. //---------------------------------
  76. string_t GetModelName() const;
  77. Class_T Classify();
  78. bool ShouldAlwaysThink();
  79. //---------------------------------
  80. // Behavior
  81. //---------------------------------
  82. bool ShouldBehaviorSelectSchedule( CAI_BehaviorBase *pBehavior );
  83. void GatherConditions();
  84. void PredictPlayerPush();
  85. void PrescheduleThink();
  86. void BuildScheduleTestBits();
  87. bool FInViewCone( CBaseEntity *pEntity );
  88. int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
  89. int SelectSchedule();
  90. int SelectSchedulePriorityAction();
  91. int SelectScheduleHeal();
  92. int SelectScheduleRetrieveItem();
  93. int SelectScheduleNonCombat();
  94. int SelectScheduleManhackCombat();
  95. int SelectScheduleCombat();
  96. bool ShouldDeferToFollowBehavior();
  97. int TranslateSchedule( int scheduleType );
  98. bool ShouldAcceptGoal( CAI_BehaviorBase *pBehavior, CAI_GoalEntity *pGoal );
  99. void OnClearGoal( CAI_BehaviorBase *pBehavior, CAI_GoalEntity *pGoal );
  100. void StartTask( const Task_t *pTask );
  101. void RunTask( const Task_t *pTask );
  102. Activity NPC_TranslateActivity( Activity eNewActivity );
  103. void HandleAnimEvent( animevent_t *pEvent );
  104. void TaskFail( AI_TaskFailureCode_t code );
  105. void PickupItem( CBaseEntity *pItem );
  106. void SimpleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  107. bool IgnorePlayerPushing( void );
  108. int DrawDebugTextOverlays( void );
  109. virtual const char *SelectRandomExpressionForState( NPC_STATE state );
  110. //---------------------------------
  111. // Combat
  112. //---------------------------------
  113. bool OnBeginMoveAndShoot();
  114. void OnEndMoveAndShoot();
  115. virtual bool UseAttackSquadSlots() { return false; }
  116. void LocateEnemySound();
  117. bool IsManhackMeleeCombatant();
  118. Vector GetActualShootPosition( const Vector &shootOrigin );
  119. void OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon );
  120. bool ShouldLookForBetterWeapon();
  121. //---------------------------------
  122. // Damage handling
  123. //---------------------------------
  124. int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  125. //---------------------------------
  126. // Commander mode
  127. //---------------------------------
  128. bool IsCommandable();
  129. bool IsPlayerAlly( CBasePlayer *pPlayer = NULL );
  130. bool CanJoinPlayerSquad();
  131. bool WasInPlayerSquad();
  132. bool HaveCommandGoal() const;
  133. bool IsCommandMoving();
  134. bool ShouldAutoSummon();
  135. bool IsValidCommandTarget( CBaseEntity *pTarget );
  136. bool NearCommandGoal();
  137. bool VeryFarFromCommandGoal();
  138. bool TargetOrder( CBaseEntity *pTarget, CAI_BaseNPC **Allies, int numAllies );
  139. void MoveOrder( const Vector &vecDest, CAI_BaseNPC **Allies, int numAllies );
  140. void OnMoveOrder();
  141. void CommanderUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  142. bool ShouldSpeakRadio( CBaseEntity *pListener );
  143. void OnMoveToCommandGoalFailed();
  144. void AddToPlayerSquad();
  145. void RemoveFromPlayerSquad();
  146. void TogglePlayerSquadState();
  147. void UpdatePlayerSquad();
  148. static int __cdecl PlayerSquadCandidateSortFunc( const SquadCandidate_t *, const SquadCandidate_t * );
  149. void FixupPlayerSquad();
  150. void ClearFollowTarget();
  151. void UpdateFollowCommandPoint();
  152. bool IsFollowingCommandPoint();
  153. CAI_BaseNPC * GetSquadCommandRepresentative();
  154. void SetSquad( CAI_Squad *pSquad );
  155. void AddInsignia();
  156. void RemoveInsignia();
  157. bool SpeakCommandResponse( AIConcept_t concept, const char *modifiers = NULL );
  158. //---------------------------------
  159. // Scanner interaction
  160. //---------------------------------
  161. float GetNextScannerInspectTime() { return m_fNextInspectTime; }
  162. void SetNextScannerInspectTime( float flTime ) { m_fNextInspectTime = flTime; }
  163. bool HandleInteraction(int interactionType, void *data, CBaseCombatCharacter* sourceEnt);
  164. //---------------------------------
  165. // Hints
  166. //---------------------------------
  167. bool FValidateHintType ( CAI_Hint *pHint );
  168. //---------------------------------
  169. // Special abilities
  170. //---------------------------------
  171. bool IsMedic() { return HasSpawnFlags(SF_CITIZEN_MEDIC); }
  172. bool IsAmmoResupplier() { return HasSpawnFlags(SF_CITIZEN_AMMORESUPPLIER); }
  173. bool CanHeal();
  174. bool ShouldHealTarget( CBaseEntity *pTarget, bool bActiveUse = false );
  175. #if HL2_EPISODIC
  176. bool ShouldHealTossTarget( CBaseEntity *pTarget, bool bActiveUse = false );
  177. #endif
  178. void Heal();
  179. bool ShouldLookForHealthItem();
  180. #if HL2_EPISODIC
  181. void TossHealthKit( CBaseCombatCharacter *pThrowAt, const Vector &offset ); // create a healthkit and throw it at someone
  182. void InputForceHealthKitToss( inputdata_t &inputdata );
  183. #endif
  184. //---------------------------------
  185. // Inputs
  186. //---------------------------------
  187. void InputRemoveFromPlayerSquad( inputdata_t &inputdata ) { RemoveFromPlayerSquad(); }
  188. void InputStartPatrolling( inputdata_t &inputdata );
  189. void InputStopPatrolling( inputdata_t &inputdata );
  190. void InputSetCommandable( inputdata_t &inputdata );
  191. void InputSetMedicOn( inputdata_t &inputdata );
  192. void InputSetMedicOff( inputdata_t &inputdata );
  193. void InputSetAmmoResupplierOn( inputdata_t &inputdata );
  194. void InputSetAmmoResupplierOff( inputdata_t &inputdata );
  195. void InputSpeakIdleResponse( inputdata_t &inputdata );
  196. //---------------------------------
  197. // Sounds & speech
  198. //---------------------------------
  199. void FearSound( void );
  200. void DeathSound( const CTakeDamageInfo &info );
  201. bool UseSemaphore( void );
  202. virtual void OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior );
  203. private:
  204. //-----------------------------------------------------
  205. // Conditions, Schedules, Tasks
  206. //-----------------------------------------------------
  207. enum
  208. {
  209. COND_CIT_PLAYERHEALREQUEST = BaseClass::NEXT_CONDITION,
  210. COND_CIT_COMMANDHEAL,
  211. COND_CIT_HURTBYFIRE,
  212. COND_CIT_START_INSPECTION,
  213. SCHED_CITIZEN_PLAY_INSPECT_ACTIVITY = BaseClass::NEXT_SCHEDULE,
  214. SCHED_CITIZEN_HEAL,
  215. SCHED_CITIZEN_RANGE_ATTACK1_RPG,
  216. SCHED_CITIZEN_PATROL,
  217. SCHED_CITIZEN_MOURN_PLAYER,
  218. SCHED_CITIZEN_SIT_ON_TRAIN,
  219. SCHED_CITIZEN_STRIDER_RANGE_ATTACK1_RPG,
  220. #ifdef HL2_EPISODIC
  221. SCHED_CITIZEN_HEAL_TOSS,
  222. #endif
  223. TASK_CIT_HEAL = BaseClass::NEXT_TASK,
  224. TASK_CIT_RPG_AUGER,
  225. TASK_CIT_PLAY_INSPECT_SEQUENCE,
  226. TASK_CIT_SIT_ON_TRAIN,
  227. TASK_CIT_LEAVE_TRAIN,
  228. TASK_CIT_SPEAK_MOURNING,
  229. #ifdef HL2_EPISODIC
  230. TASK_CIT_HEAL_TOSS,
  231. #endif
  232. };
  233. //-----------------------------------------------------
  234. int m_nInspectActivity;
  235. float m_flNextFearSoundTime;
  236. float m_flStopManhackFlinch;
  237. float m_fNextInspectTime; // Next time I'm allowed to get inspected by a scanner
  238. float m_flPlayerHealTime;
  239. float m_flNextHealthSearchTime; // Next time I'm allowed to look for a healthkit
  240. float m_flAllyHealTime;
  241. float m_flPlayerGiveAmmoTime;
  242. string_t m_iszAmmoSupply;
  243. int m_iAmmoAmount;
  244. bool m_bRPGAvoidPlayer;
  245. bool m_bShouldPatrol;
  246. string_t m_iszOriginalSquad;
  247. float m_flTimeJoinedPlayerSquad;
  248. bool m_bWasInPlayerSquad;
  249. float m_flTimeLastCloseToPlayer;
  250. string_t m_iszDenyCommandConcept;
  251. CSimpleSimTimer m_AutoSummonTimer;
  252. Vector m_vAutoSummonAnchor;
  253. CitizenType_t m_Type;
  254. CitizenExpressionTypes_t m_ExpressionType;
  255. int m_iHead;
  256. static CSimpleSimTimer gm_PlayerSquadEvaluateTimer;
  257. float m_flTimePlayerStare; // The game time at which the player started staring at me.
  258. float m_flTimeNextHealStare; // Next time I'm allowed to heal a player who is staring at me.
  259. //-----------------------------------------------------
  260. // Outputs
  261. //-----------------------------------------------------
  262. COutputEvent m_OnJoinedPlayerSquad;
  263. COutputEvent m_OnLeftPlayerSquad;
  264. COutputEvent m_OnFollowOrder;
  265. COutputEvent m_OnStationOrder;
  266. COutputEvent m_OnPlayerUse;
  267. COutputEvent m_OnNavFailBlocked;
  268. //-----------------------------------------------------
  269. CAI_FuncTankBehavior m_FuncTankBehavior;
  270. CHandle<CAI_FollowGoal> m_hSavedFollowGoalEnt;
  271. bool m_bNotifyNavFailBlocked;
  272. bool m_bNeverLeavePlayerSquad; // Don't leave the player squad unless killed, or removed via Entity I/O.
  273. //-----------------------------------------------------
  274. DECLARE_DATADESC();
  275. #ifdef _XBOX
  276. protected:
  277. #endif
  278. DEFINE_CUSTOM_AI;
  279. };
  280. //---------------------------------------------------------
  281. //---------------------------------------------------------
  282. inline bool CNPC_Citizen::NearCommandGoal()
  283. {
  284. const float flDistSqr = COMMAND_GOAL_TOLERANCE * COMMAND_GOAL_TOLERANCE;
  285. return ( ( GetAbsOrigin() - GetCommandGoal() ).LengthSqr() <= flDistSqr );
  286. }
  287. //---------------------------------------------------------
  288. //---------------------------------------------------------
  289. inline bool CNPC_Citizen::VeryFarFromCommandGoal()
  290. {
  291. const float flDistSqr = (12*50) * (12*50);
  292. return ( ( GetAbsOrigin() - GetCommandGoal() ).LengthSqr() > flDistSqr );
  293. }
  294. //==============================================================================
  295. // CITIZEN PLAYER-RESPONSE SYSTEM
  296. //
  297. // NOTE: This system is obsolete, and left here for legacy support.
  298. // It has been superseded by the ai_eventresponse system.
  299. //
  300. //==============================================================================
  301. #define CITIZEN_RESPONSE_DISTANCE 768 // Maximum distance for responding citizens
  302. #define CITIZEN_RESPONSE_REFIRE_TIME 15.0 // Time after giving a response before giving any more
  303. #define CITIZEN_RESPONSE_GIVEUP_TIME 4.0 // Time after a response trigger was fired before discarding it without responding
  304. enum citizenresponses_t
  305. {
  306. CR_PLAYER_SHOT_GUNSHIP, // Player has shot the gunship with a bullet weapon
  307. CR_PLAYER_KILLED_GUNSHIP, // Player has destroyed the gunship
  308. CR_VITALNPC_DIED, // Mapmaker specified that an NPC that was vital has died
  309. // Add new responses here
  310. MAX_CITIZEN_RESPONSES,
  311. };
  312. //-------------------------------------
  313. class CCitizenResponseSystem : public CBaseEntity
  314. {
  315. DECLARE_CLASS( CCitizenResponseSystem, CBaseEntity );
  316. public:
  317. DECLARE_DATADESC();
  318. void Spawn();
  319. void OnRestore();
  320. void AddResponseTrigger( citizenresponses_t iTrigger );
  321. void ResponseThink();
  322. //---------------------------------
  323. // Inputs
  324. //---------------------------------
  325. void InputResponseVitalNPC( inputdata_t &inputdata );
  326. private:
  327. float m_flResponseAddedTime[ MAX_CITIZEN_RESPONSES ]; // Time at which the response was added. 0 if we have no response.
  328. float m_flNextResponseTime;
  329. };
  330. //-------------------------------------
  331. class CSquadInsignia : public CBaseAnimating
  332. {
  333. DECLARE_CLASS( CSquadInsignia, CBaseAnimating );
  334. void Spawn();
  335. };
  336. //-------------------------------------
  337. CCitizenResponseSystem *GetCitizenResponse();
  338. //-----------------------------------------------------------------------------
  339. #endif //NPC_CITIZEN_H