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.

293 lines
12 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: The CResponseSystem class. Don't include this header; include the response_types
  4. // into which it is transcluded.
  5. //
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #ifndef RESPONSE_SYSTEM_H
  9. #define RESPONSE_SYSTEM_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "utldict.h"
  14. namespace ResponseRules
  15. {
  16. typedef ResponseParams AI_ResponseParams ;
  17. #define AI_CriteriaSet ResponseRules::CriteriaSet
  18. class CriteriaSet;
  19. //-----------------------------------------------------------------------------
  20. // Purpose: The database of all available responses.
  21. // The Rules are partitioned based on a variety of factors (presently,
  22. // speaker and concept) for faster lookup, basically a seperate-chained hash.
  23. //-----------------------------------------------------------------------------
  24. class CResponseSystem : public IResponseSystem
  25. {
  26. public:
  27. CResponseSystem();
  28. ~CResponseSystem();
  29. typedef void (CResponseSystem::*pfnResponseDispatch)( void );
  30. typedef void (CResponseSystem::*pfnParseRuleDispatch)( Rule & );
  31. typedef void (CResponseSystem::*pfnParseResponseDispatch)( ParserResponse &, ResponseGroup&, AI_ResponseParams * );
  32. typedef void (CResponseSystem::*pfnParseResponseGroupDispatch) ( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  33. typedef CUtlMap< unsigned,pfnResponseDispatch > DispatchMap_t;
  34. typedef CUtlMap< unsigned,pfnParseRuleDispatch > ParseRuleDispatchMap_t;
  35. typedef CUtlMap< unsigned,pfnParseResponseDispatch > ParseResponseDispatchMap_t;
  36. typedef CUtlMap< unsigned,pfnParseResponseGroupDispatch > ParseResponseGroupDispatchMap_t;
  37. #pragma region IResponseSystem
  38. // IResponseSystem
  39. virtual bool FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter = NULL );
  40. virtual void GetAllResponses( CUtlVector<CRR_Response> *pResponses );
  41. #pragma endregion Implement interface from IResponseSystem
  42. virtual void Release() = 0;
  43. virtual void DumpRules();
  44. bool IsCustomManagable() { return m_bCustomManagable; }
  45. void Clear();
  46. void DumpDictionary( const char *pszName );
  47. protected:
  48. void BuildDispatchTables();
  49. bool Dispatch( char const *pToken, unsigned int uiHash, DispatchMap_t &rMap );
  50. bool DispatchParseRule( char const *pToken, unsigned int uiHash, ParseRuleDispatchMap_t &rMap, Rule &newRule );
  51. bool DispatchParseResponse( char const *pToken, unsigned int uiHash, ParseResponseDispatchMap_t &rMap, ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  52. bool DispatchParseResponseGroup( char const *pToken, unsigned int uiHash, ParseResponseGroupDispatchMap_t &rMap, char const *responseGroupName, ResponseGroup& newGroup, AI_ResponseParams &groupResponseParams );
  53. virtual const char *GetScriptFile( void ) = 0;
  54. void LoadRuleSet( const char *setname );
  55. void ResetResponseGroups();
  56. float LookForCriteria( const CriteriaSet &criteriaSet, int iCriteria );
  57. float RecursiveLookForCriteria( const CriteriaSet &criteriaSet, Criteria *pParent );
  58. public:
  59. void CopyRuleFrom( Rule *pSrcRule, ResponseRulePartition::tIndex iRule, CResponseSystem *pCustomSystem );
  60. void CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem );
  61. void CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem );
  62. void CopyEnumerationsFrom( CResponseSystem *pCustomSystem );
  63. //private:
  64. struct Enumeration
  65. {
  66. float value;
  67. };
  68. struct ResponseSearchResult
  69. {
  70. ResponseSearchResult()
  71. {
  72. group = NULL;
  73. action = NULL;
  74. }
  75. ResponseGroup *group;
  76. ParserResponse *action;
  77. };
  78. inline bool ParseToken( void )
  79. {
  80. if ( m_bUnget )
  81. {
  82. m_bUnget = false;
  83. return true;
  84. }
  85. if ( m_ScriptStack.Count() <= 0 )
  86. {
  87. Assert( 0 );
  88. return false;
  89. }
  90. m_ScriptStack[ 0 ].currenttoken = IEngineEmulator::Get()->ParseFile( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) );
  91. m_ScriptStack[ 0 ].tokencount++;
  92. return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false;
  93. }
  94. inline void Unget()
  95. {
  96. m_bUnget = true;
  97. }
  98. inline bool TokenWaiting( void )
  99. {
  100. if ( m_ScriptStack.Count() <= 0 )
  101. {
  102. Assert( 0 );
  103. return false;
  104. }
  105. const char *p = m_ScriptStack[ 0 ].currenttoken;
  106. if ( !p )
  107. {
  108. Error( "AI_ResponseSystem: Unxpected TokenWaiting() with NULL buffer in %s", (char * ) m_ScriptStack[ 0 ].name );
  109. return false;
  110. }
  111. while ( *p && *p!='\n')
  112. {
  113. // Special handler for // comment blocks
  114. if ( *p == '/' && *(p+1) == '/' )
  115. return false;
  116. if ( !V_isspace( *p ) || V_isalnum( *p ) )
  117. return true;
  118. p++;
  119. }
  120. return false;
  121. }
  122. void ParseOneResponse( const char *responseGroupName, ResponseGroup& group, ResponseParams *defaultParams = NULL );
  123. void ParseInclude( void );
  124. void ParseResponse( void );
  125. void ParseCriterion( void );
  126. void ParseRule( void );
  127. void ParseEnumeration( void );
  128. private:
  129. void ParseRule_MatchOnce( Rule &newRule );
  130. void ParseRule_ApplyContextToWorld( Rule &newRule );
  131. void ParseRule_ApplyContext( Rule &newRule );
  132. void ParseRule_Response( Rule &newRule );
  133. //void ParseRule_ForceWeight( Rule &newRule );
  134. void ParseRule_Criteria( Rule &newRule );
  135. char const *m_pParseRuleName;
  136. bool m_bParseRuleValid;
  137. void ParseResponse_Weight( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  138. void ParseResponse_PreDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  139. void ParseResponse_NoDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  140. void ParseResponse_DefaultDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  141. void ParseResponse_Delay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  142. void ParseResponse_SpeakOnce( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  143. void ParseResponse_NoScene( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  144. void ParseResponse_StopOnNonIdle( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  145. void ParseResponse_Odds( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  146. void ParseResponse_RespeakDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  147. void ParseResponse_WeaponDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  148. void ParseResponse_Soundlevel( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  149. void ParseResponse_DisplayFirst( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  150. void ParseResponse_DisplayLast( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  151. void ParseResponse_Fire( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  152. void ParseResponse_Then( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
  153. void ParseResponseGroup_Start( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  154. void ParseResponseGroup_PreDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  155. void ParseResponseGroup_NoDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  156. void ParseResponseGroup_DefaultDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  157. void ParseResponseGroup_Delay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  158. void ParseResponseGroup_SpeakOnce( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  159. void ParseResponseGroup_NoScene( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  160. void ParseResponseGroup_StopOnNonIdle( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  161. void ParseResponseGroup_Odds( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  162. void ParseResponseGroup_RespeakDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  163. void ParseResponseGroup_WeaponDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  164. void ParseResponseGroup_Soundlevel( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
  165. public:
  166. int ParseOneCriterion( const char *criterionName );
  167. bool Compare( const char *setValue, Criteria *c, bool verbose = false );
  168. bool CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose = false );
  169. void ComputeMatcher( Criteria *c, Matcher& matcher );
  170. void ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken );
  171. float LookupEnumeration( const char *name, bool& found );
  172. ResponseRulePartition::tIndex FindBestMatchingRule( const CriteriaSet& set, bool verbose, float &scoreOfBestMatchingRule );
  173. float ScoreCriteriaAgainstRule( const CriteriaSet& set, ResponseRulePartition::tRuleDict &dict, int irule, bool verbose = false );
  174. float RecursiveScoreSubcriteriaAgainstRule( const CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ );
  175. float ScoreCriteriaAgainstRuleCriteria( const CriteriaSet& set, int icriterion, bool& exclude, bool verbose = false );
  176. void FakeDepletes( ResponseGroup *g, IResponseFilter *pFilter );
  177. void RevertFakedDepletes( ResponseGroup *g );
  178. bool GetBestResponse( ResponseSearchResult& result, Rule *rule, bool verbose = false, IResponseFilter *pFilter = NULL );
  179. bool ResolveResponse( ResponseSearchResult& result, int depth, const char *name, bool verbose = false, IResponseFilter *pFilter = NULL );
  180. int SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter );
  181. void DescribeResponseGroup( ResponseGroup *group, int selected, int depth );
  182. void DebugPrint( int depth, PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 3, 4 );
  183. void LoadFromBuffer( const char *scriptfile, const char *buffer );
  184. void GetCurrentScript( char *buf, size_t buflen );
  185. int GetCurrentToken() const;
  186. void SetCurrentScript( const char *script );
  187. inline bool IsRootCommand( unsigned int hash ) const
  188. {
  189. int slot = m_RootCommandHashes.Find( hash );
  190. return slot != m_RootCommandHashes.InvalidIndex();
  191. }
  192. inline bool IsRootCommand() const
  193. {
  194. return IsRootCommand( RR_HASH( token ) );
  195. }
  196. void PushScript( const char *scriptfile, unsigned char *buffer );
  197. void PopScript(void);
  198. void ResponseWarning( PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 2, 3 );
  199. CUtlDict< ResponseGroup, short > m_Responses;
  200. CUtlDict< Criteria, short > m_Criteria;
  201. // CUtlDict< Rule, short > m_Rules;
  202. ResponseRulePartition m_RulePartitions;
  203. CUtlDict< Enumeration, short > m_Enumerations;
  204. CUtlVector<int> m_FakedDepletes;
  205. char token[ 1204 ];
  206. bool m_bUnget;
  207. bool m_bCustomManagable;
  208. struct ScriptEntry
  209. {
  210. unsigned char *buffer;
  211. FileNameHandle_t name;
  212. const char *currenttoken;
  213. int tokencount;
  214. };
  215. CUtlVector< ScriptEntry > m_ScriptStack;
  216. CStringPool m_IncludedFiles;
  217. DispatchMap_t m_FileDispatch;
  218. ParseRuleDispatchMap_t m_RuleDispatch;
  219. ParseResponseDispatchMap_t m_ResponseDispatch;
  220. ParseResponseGroupDispatchMap_t m_ResponseGroupDispatch;
  221. CUtlRBTree< unsigned int > m_RootCommandHashes;
  222. // for debugging purposes only: concepts to be emitted from rr_debugresponses 2
  223. typedef CUtlLinkedList< CRR_Concept, unsigned short, false, unsigned int > ExcludeList_t;
  224. static ExcludeList_t m_DebugExcludeList;
  225. friend class CDefaultResponseSystemSaveRestoreBlockHandler;
  226. friend class CResponseSystemSaveRestoreOps;
  227. };
  228. // Some globals inherited from AI_Speech.h:
  229. const float AIS_DEF_MIN_DELAY = 2.8; // Minimum amount of time an NPCs will wait after someone has spoken before considering speaking again
  230. const float AIS_DEF_MAX_DELAY = 3.2; // Maximum amount of time an NPCs will wait after someone has spoken before considering speaking again
  231. }
  232. #endif // RESPONSE_SYSTEM_H