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.

245 lines
6.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "ai_default.h"
  8. #include "ai_task.h"
  9. #include "ai_schedule.h"
  10. #include "ai_node.h"
  11. #include "ai_hull.h"
  12. #include "ai_hint.h"
  13. #include "ai_squad.h"
  14. #include "ai_senses.h"
  15. #include "ai_navigator.h"
  16. #include "ai_motor.h"
  17. #include "ai_behavior.h"
  18. #include "ai_baseactor.h"
  19. #include "ai_behavior_lead.h"
  20. #include "ai_behavior_follow.h"
  21. #include "ai_behavior_standoff.h"
  22. #include "ai_behavior_assault.h"
  23. #include "npc_playercompanion.h"
  24. #include "soundent.h"
  25. #include "game.h"
  26. #include "npcevent.h"
  27. #include "entitylist.h"
  28. #include "activitylist.h"
  29. #include "vstdlib/random.h"
  30. #include "engine/IEngineSound.h"
  31. #include "sceneentity.h"
  32. // memdbgon must be the last include file in a .cpp file!!!
  33. #include "tier0/memdbgon.h"
  34. #define FISHERMAN_MODEL "models/lostcoast/fisherman/fisherman.mdl"
  35. //=========================================================
  36. // Fisherman activities
  37. //=========================================================
  38. Activity ACT_FISHERMAN_HAT_UP;
  39. Activity ACT_FISHERMAN_HAT_DOWN;
  40. //=========================================================
  41. // animation events
  42. //=========================================================
  43. int AE_FISHERMAN_HAT_UP;
  44. int AE_FISHERMAN_HAT_DOWN;
  45. int AE_FISHERMAN_HAT_ON;
  46. int AE_FISHERMAN_HAT_OFF;
  47. //---------------------------------------------------------
  48. //
  49. //---------------------------------------------------------
  50. class CNPC_Fisherman : public CNPC_PlayerCompanion
  51. {
  52. public:
  53. DECLARE_CLASS( CNPC_Fisherman, CNPC_PlayerCompanion );
  54. //DECLARE_SERVERCLASS();
  55. DECLARE_DATADESC();
  56. virtual void Precache()
  57. {
  58. // Prevents a warning
  59. SelectModel( );
  60. BaseClass::Precache();
  61. PrecacheScriptSound( "NPC_Fisherman.FootstepLeft" );
  62. PrecacheScriptSound( "NPC_Fisherman.FootstepRight" );
  63. PrecacheScriptSound( "NPC_Fisherman.Die" );
  64. PrecacheInstancedScene( "scenes/Expressions/FishermanIdle.vcd" );
  65. PrecacheInstancedScene( "scenes/Expressions/FishermanAlert.vcd" );
  66. PrecacheInstancedScene( "scenes/Expressions/FishermanCombat.vcd" );
  67. }
  68. virtual void Activate()
  69. {
  70. BaseClass::Activate();
  71. if (m_iHatState == -1)
  72. {
  73. m_iHatState = ACT_FISHERMAN_HAT_DOWN;
  74. }
  75. // allocate layer, start with the hat down
  76. m_iHatLayer = AddGesture( (Activity)m_iHatState, false );
  77. }
  78. void Spawn( void );
  79. void SelectModel();
  80. Class_T Classify( void );
  81. void HandleAnimEvent( animevent_t *pEvent );
  82. bool ShouldLookForBetterWeapon() { return false; }
  83. virtual bool IgnorePlayerPushing( void ) { return true; }
  84. void DeathSound( const CTakeDamageInfo &info );
  85. int m_iHatLayer; // overlay layer for hat, don't save/restore.
  86. int m_iHatState; // hat state, persistant.
  87. DEFINE_CUSTOM_AI;
  88. };
  89. LINK_ENTITY_TO_CLASS( npc_fisherman, CNPC_Fisherman );
  90. //---------------------------------------------------------
  91. //
  92. //---------------------------------------------------------
  93. /*
  94. IMPLEMENT_SERVERCLASS_ST(CNPC_Fisherman, DT_NPC_Fisherman)
  95. END_SEND_TABLE()
  96. */
  97. //---------------------------------------------------------
  98. // Save/Restore
  99. //---------------------------------------------------------
  100. BEGIN_DATADESC( CNPC_Fisherman )
  101. // DEFINE_FIELD( m_iHatLayer, FIELD_INT ),
  102. DEFINE_FIELD( m_iHatState, FIELD_INTEGER ),
  103. END_DATADESC()
  104. //-----------------------------------------------------------------------------
  105. // Purpose:
  106. //-----------------------------------------------------------------------------
  107. void CNPC_Fisherman::SelectModel()
  108. {
  109. SetModelName( AllocPooledString( FISHERMAN_MODEL ) );
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Purpose:
  113. //-----------------------------------------------------------------------------
  114. void CNPC_Fisherman::Spawn( void )
  115. {
  116. m_iHatLayer = -1;
  117. m_iHatState = -1;
  118. Precache();
  119. m_iHealth = 80;
  120. // m_iszIdleExpression = MAKE_STRING("scenes/Expressions/FishermanIdle.vcd");
  121. // m_iszAlertExpression = MAKE_STRING("scenes/Expressions/FishermanAlert.vcd");
  122. // m_iszCombatExpression = MAKE_STRING("scenes/Expressions/FishermanCombat.vcd");
  123. BaseClass::Spawn();
  124. AddEFlags( EFL_NO_DISSOLVE | EFL_NO_MEGAPHYSCANNON_RAGDOLL | EFL_NO_PHYSCANNON_INTERACTION );
  125. NPCInit();
  126. }
  127. //-----------------------------------------------------------------------------
  128. // Purpose:
  129. // Output :
  130. //-----------------------------------------------------------------------------
  131. Class_T CNPC_Fisherman::Classify( void )
  132. {
  133. return CLASS_PLAYER_ALLY_VITAL;
  134. }
  135. //---------------------------------------------------------
  136. //---------------------------------------------------------
  137. void CNPC_Fisherman::HandleAnimEvent( animevent_t *pEvent )
  138. {
  139. if ( pEvent->event == NPC_EVENT_LEFTFOOT )
  140. {
  141. EmitSound( "NPC_Fisherman.FootstepLeft", pEvent->eventtime );
  142. }
  143. else if ( pEvent->event == NPC_EVENT_RIGHTFOOT )
  144. {
  145. EmitSound( "NPC_Fisherman.FootstepRight", pEvent->eventtime );
  146. }
  147. else if ( pEvent->event == AE_FISHERMAN_HAT_UP )
  148. {
  149. if (m_iHatLayer != -1)
  150. {
  151. RemoveLayer( m_iHatLayer, 0.2, 0.2 );
  152. m_iHatLayer = -1;
  153. }
  154. m_iHatState = ACT_FISHERMAN_HAT_UP;
  155. m_iHatLayer = AddGesture( (Activity)m_iHatState, false );
  156. }
  157. else if ( pEvent->event == AE_FISHERMAN_HAT_DOWN )
  158. {
  159. if (m_iHatLayer != -1)
  160. {
  161. RemoveLayer( m_iHatLayer, 0.2, 0.2 );
  162. m_iHatLayer = -1;
  163. }
  164. m_iHatState = ACT_FISHERMAN_HAT_DOWN;
  165. m_iHatLayer = AddGesture( (Activity)m_iHatState, false );
  166. }
  167. else if ( pEvent->event == AE_FISHERMAN_HAT_ON )
  168. {
  169. m_iHatLayer = AddGesture( (Activity)m_iHatState, false );
  170. }
  171. else if ( pEvent->event == AE_FISHERMAN_HAT_OFF )
  172. {
  173. if (m_iHatLayer != -1)
  174. {
  175. RemoveLayer( m_iHatLayer, 0.2, 0.2 );
  176. m_iHatLayer = -1;
  177. }
  178. }
  179. else
  180. {
  181. BaseClass::HandleAnimEvent( pEvent );
  182. }
  183. }
  184. //------------------------------------------------------------------------------
  185. //------------------------------------------------------------------------------
  186. void CNPC_Fisherman::DeathSound( const CTakeDamageInfo &info )
  187. {
  188. // Sentences don't play on dead NPCs
  189. SentenceStop();
  190. }
  191. //-----------------------------------------------------------------------------
  192. //
  193. // Schedules
  194. //
  195. //-----------------------------------------------------------------------------
  196. AI_BEGIN_CUSTOM_NPC( npc_fisherman, CNPC_Fisherman )
  197. DECLARE_ACTIVITY( ACT_FISHERMAN_HAT_UP )
  198. DECLARE_ACTIVITY( ACT_FISHERMAN_HAT_DOWN )
  199. DECLARE_ANIMEVENT( AE_FISHERMAN_HAT_UP )
  200. DECLARE_ANIMEVENT( AE_FISHERMAN_HAT_DOWN )
  201. DECLARE_ANIMEVENT( AE_FISHERMAN_HAT_ON )
  202. DECLARE_ANIMEVENT( AE_FISHERMAN_HAT_OFF )
  203. AI_END_CUSTOM_NPC()