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.

344 lines
8.1 KiB

  1. // ai_addon.h
  2. #ifndef AI_ADDON_H
  3. #define AI_ADDON_H
  4. #ifdef _WIN32
  5. #pragma once
  6. #endif
  7. #include "tier1/utlvector.h"
  8. #include "baseanimating.h"
  9. #include "ai_agent.h"
  10. #include "ai_behavior.h"
  11. #include "player_pickup.h"
  12. #include "IEffects.h"
  13. class CAI_BaseNPC;
  14. #define INVALID_ADDON_ATTACHMENT_ID -1
  15. int GetIDForAttachmentName( char *pszAttachmentName );
  16. int GetNumAddOnAttachmentPoints();
  17. bool IsAddOnAttachmentAvailable( CAI_BaseNPC *pHost, char *pszAttachmentName );
  18. int CountAddOns( CAI_BaseNPC *pHost );
  19. //=========================================================
  20. //=========================================================
  21. class CAI_AddOn : public CBaseAnimating, public CAI_Agent, public CDefaultPlayerPickupVPhysics
  22. {
  23. public:
  24. DECLARE_CLASS( CAI_AddOn, CBaseAnimating );
  25. //---------------------------------
  26. // CTor/DTor
  27. //---------------------------------
  28. CAI_AddOn() { m_iAttachmentID = INVALID_ADDON_ATTACHMENT_ID; }
  29. //---------------------------------
  30. // Precache/Spawn/etc
  31. //---------------------------------
  32. virtual void Precache();
  33. virtual void Spawn();
  34. virtual void UpdateOnRemove();
  35. const char *GetDebugName() { return CBaseEntity::GetDebugName(); }
  36. int entindex() { return CBaseEntity::entindex(); }
  37. virtual int DrawDebugTextOverlays(void);
  38. //---------------------------------
  39. //---------------------------------
  40. bool SUB_AllowedToFade( void )
  41. {
  42. return true;
  43. }
  44. int Save( ISave &save )
  45. {
  46. int result = CBaseAnimating::Save( save );
  47. if ( result )
  48. {
  49. result = CAI_Agent::Save( save );
  50. }
  51. return result;
  52. }
  53. //-------------------------------------
  54. int Restore( IRestore &restore )
  55. {
  56. int result = CBaseAnimating::Restore( restore );
  57. if ( result )
  58. {
  59. result = CAI_Agent::Restore( restore );
  60. }
  61. return result;
  62. }
  63. //---------------------------------
  64. // Agent stuff
  65. //---------------------------------
  66. virtual void GatherConditions();
  67. virtual int SelectSchedule();
  68. virtual void StartTask( const Task_t *pTask );
  69. virtual void RunTask( const Task_t *pTask );
  70. //---------------------------------
  71. // Install/Remove AddOns
  72. //---------------------------------
  73. virtual bool Install( CAI_BaseNPC *pHost, bool bRemoveOnFail = true );
  74. void SetPhysReplacement( CBaseEntity *pEntity );
  75. bool Attach( CAI_BaseNPC *pHost );
  76. void Dettach( void );
  77. virtual void Remove() { Unbind(); Dettach(); }
  78. virtual void Bind() {}
  79. virtual void Unbind() {}
  80. //---------------------------------
  81. // Hosts/Outer accessors
  82. //---------------------------------
  83. CAI_BaseNPC *GetNPCHost();
  84. CBaseEntity *GetHostEnemy();
  85. //---------------------------------
  86. // Thinking
  87. //---------------------------------
  88. void DispatchAddOnThink();
  89. virtual float GetThinkInterval() { return 0.1f; }
  90. //---------------------------------
  91. // Appearance & Position
  92. //---------------------------------
  93. virtual void PickAttachment( CAI_BaseNPC *pHost, char *pchAttachment ) = 0;
  94. virtual char *GetAddOnModelName() = 0;
  95. virtual Vector GetAttachOffset( QAngle &attachmentAngles ) { return vec3_origin; }
  96. virtual QAngle GetAttachOrientation( QAngle &attachmentAngles ) { return attachmentAngles; }
  97. virtual QAngle GetLocalOrientation( void );
  98. int GetAttachmentID() { return m_iAttachmentID; }
  99. virtual void EjectFromHost();
  100. //---------------------------------
  101. // Entity I/O
  102. //---------------------------------
  103. void InputInstall( inputdata_t &data );
  104. void InputRemove( inputdata_t &data );
  105. //---------------------------------
  106. // Schedule/Task/Conditions
  107. //---------------------------------
  108. enum
  109. {
  110. TASK_ADDON_WAIT = NEXT_TASK,
  111. TASK_ADDON_WAIT_RANDOM,
  112. NEXT_TASK,
  113. };
  114. enum
  115. {
  116. COND_ADDON_LOST_HOST = NEXT_CONDITION,
  117. NEXT_CONDITION,
  118. };
  119. enum
  120. {
  121. SCHED_ADDON_NO_OWNER = NEXT_SCHEDULE,
  122. NEXT_SCHEDULE,
  123. };
  124. DECLARE_DATADESC();
  125. protected:
  126. CHandle<CAI_BaseNPC> m_hNPCHost;
  127. CHandle<CBaseEntity> m_hPhysReplacement;
  128. int m_iPhysReplacementSolidFlags;
  129. int m_iPhysReplacementMoveType;
  130. QAngle m_angPhysReplacementLocalOrientation;
  131. Vector m_vecPhysReplacementDetatchForce;
  132. bool m_bWasAttached;
  133. private:
  134. //---------------------------------
  135. // Fields used by AI
  136. //---------------------------------
  137. float m_flWaitFinished; // Same as for AI_BaseNPC
  138. int m_iAttachmentID; // Which attachment point am I connected to on my host's model?
  139. float m_flNextAttachTime;
  140. public:
  141. //---------------------------------
  142. // Hammer keyfields
  143. //---------------------------------
  144. DEFINE_AGENT();
  145. };
  146. //=========================================================
  147. //=========================================================
  148. class CAI_AddOnBehaviorBase : public CAI_SimpleBehavior
  149. {
  150. public:
  151. virtual bool ShouldNPCSave()
  152. {
  153. return false;
  154. }
  155. virtual CAI_AddOn **GetAddOnsBase() { return NULL; }
  156. const CAI_AddOn **GetAddOnsBase() const { return (const CAI_AddOn **)const_cast<CAI_AddOnBehaviorBase *>(this)->GetAddOnsBase(); }
  157. virtual int NumAddOns() const { return 0; }
  158. };
  159. template <class ADDON>
  160. class CAI_AddOnBehavior : public CAI_AddOnBehaviorBase
  161. {
  162. public:
  163. virtual int BindAddOn( ADDON *pAddOn )
  164. {
  165. Assert( m_AddOns.Find( pAddOn ) == m_AddOns.InvalidIndex() );
  166. Assert( static_cast<CAI_AddOn *>(pAddOn) ); // Satic cast is used to trap improper inheritance
  167. m_AddOns.AddToTail( pAddOn );
  168. return m_AddOns.Count();
  169. }
  170. virtual int UnbindAddOn( ADDON *pAddOn )
  171. {
  172. Assert( m_AddOns.Find( pAddOn ) != m_AddOns.InvalidIndex() );
  173. m_AddOns.FindAndRemove( pAddOn );
  174. return m_AddOns.Count();
  175. }
  176. virtual CAI_AddOn **GetAddOnsBase()
  177. {
  178. return (CAI_AddOn **)m_AddOns.Base();
  179. }
  180. virtual ADDON **GetAddOns()
  181. {
  182. return m_AddOns.Base();
  183. }
  184. virtual int NumAddOns() const
  185. {
  186. return m_AddOns.Count();
  187. }
  188. protected:
  189. CUtlVector<ADDON *> m_AddOns;
  190. };
  191. //=========================================================
  192. //=========================================================
  193. template <class ADDON, class BEHAVIOR>
  194. class CAI_AddOnBehaviorConnector : public ADDON
  195. {
  196. DECLARE_CLASS( CAI_AddOnBehaviorConnector, ADDON );
  197. virtual int ObjectCaps( void )
  198. {
  199. return BaseClass::ObjectCaps() | FCAP_IMPULSE_USE;
  200. }
  201. virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
  202. {
  203. CBasePlayer *pPlayer = ToBasePlayer( pActivator );
  204. if ( pPlayer == NULL )
  205. return;
  206. if ( this->m_bWasAttached )
  207. {
  208. this->Remove();
  209. g_pEffects->Sparks( this->GetAbsOrigin(), 2, 2 );
  210. }
  211. pPlayer->PickupObject( this );
  212. }
  213. virtual void Bind()
  214. {
  215. if ( this->m_hNPCHost )
  216. {
  217. BEHAVIOR *pBehavior;
  218. if ( !this->m_hNPCHost->GetBehavior( &pBehavior ) )
  219. {
  220. pBehavior = new BEHAVIOR;
  221. this->m_hNPCHost->AddBehavior( pBehavior );
  222. }
  223. pBehavior->BindAddOn( this );
  224. }
  225. }
  226. virtual void Unbind()
  227. {
  228. if ( this->m_hNPCHost )
  229. {
  230. BEHAVIOR *pBehavior;
  231. if ( this->m_hNPCHost->GetBehavior( &pBehavior ) )
  232. {
  233. if ( pBehavior->UnbindAddOn( this ) == 0 )
  234. {
  235. this->m_hNPCHost->RemoveAndDestroyBehavior( pBehavior );
  236. }
  237. }
  238. }
  239. }
  240. //-------------------------------------
  241. int Save( ISave &save )
  242. {
  243. int result = BaseClass::Save( save );
  244. if ( result )
  245. {
  246. bool bSaved = false;
  247. BEHAVIOR *pBehavior;
  248. if ( this->m_hNPCHost && this->m_hNPCHost->GetBehavior( &pBehavior ) )
  249. {
  250. bSaved = true;
  251. CAI_BehaviorBase::SaveBehaviors( save, pBehavior, (CAI_BehaviorBase **)&pBehavior, 1, false );
  252. }
  253. if ( !bSaved )
  254. {
  255. CAI_BehaviorBase::SaveBehaviors( save, NULL, NULL, 0 );
  256. }
  257. }
  258. return result;
  259. }
  260. //-------------------------------------
  261. int Restore( IRestore &restore )
  262. {
  263. int result = BaseClass::Restore( restore );
  264. if ( result )
  265. {
  266. Bind();
  267. BEHAVIOR *pBehavior;
  268. if ( this->m_hNPCHost && this->m_hNPCHost->GetBehavior( &pBehavior ) )
  269. {
  270. CAI_BehaviorBase::RestoreBehaviors( restore, (CAI_BehaviorBase **)&pBehavior, 1, false );
  271. }
  272. else
  273. {
  274. CAI_BehaviorBase::RestoreBehaviors( restore, NULL, 0,false );
  275. }
  276. }
  277. return result;
  278. }
  279. };
  280. #define LINK_ENTITY_TO_ADDON_AND_BEHAVIOR( mapClassName, DLLClassName, BehaviorName ) \
  281. typedef CAI_AddOnBehaviorConnector<DLLClassName, BehaviorName> DLLClassName##_##BehaviorName##_Binder; \
  282. LINK_ENTITY_TO_CLASS( mapClassName, DLLClassName##_##BehaviorName##_Binder )
  283. #endif // AI_ADDON_H