initial
This commit is contained in:
293
common/responserules/response_system.h
Normal file
293
common/responserules/response_system.h
Normal file
@@ -0,0 +1,293 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: The CResponseSystem class. Don't include this header; include the response_types
|
||||
// into which it is transcluded.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef RESPONSE_SYSTEM_H
|
||||
#define RESPONSE_SYSTEM_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utldict.h"
|
||||
|
||||
namespace ResponseRules
|
||||
{
|
||||
typedef ResponseParams AI_ResponseParams ;
|
||||
#define AI_CriteriaSet ResponseRules::CriteriaSet
|
||||
class CriteriaSet;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The database of all available responses.
|
||||
// The Rules are partitioned based on a variety of factors (presently,
|
||||
// speaker and concept) for faster lookup, basically a seperate-chained hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CResponseSystem : public IResponseSystem
|
||||
{
|
||||
public:
|
||||
CResponseSystem();
|
||||
~CResponseSystem();
|
||||
|
||||
typedef void (CResponseSystem::*pfnResponseDispatch)( void );
|
||||
typedef void (CResponseSystem::*pfnParseRuleDispatch)( Rule & );
|
||||
typedef void (CResponseSystem::*pfnParseResponseDispatch)( ParserResponse &, ResponseGroup&, AI_ResponseParams * );
|
||||
typedef void (CResponseSystem::*pfnParseResponseGroupDispatch) ( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
|
||||
typedef CUtlMap< unsigned,pfnResponseDispatch > DispatchMap_t;
|
||||
typedef CUtlMap< unsigned,pfnParseRuleDispatch > ParseRuleDispatchMap_t;
|
||||
typedef CUtlMap< unsigned,pfnParseResponseDispatch > ParseResponseDispatchMap_t;
|
||||
typedef CUtlMap< unsigned,pfnParseResponseGroupDispatch > ParseResponseGroupDispatchMap_t;
|
||||
|
||||
#pragma region IResponseSystem
|
||||
// IResponseSystem
|
||||
virtual bool FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter = NULL );
|
||||
virtual void GetAllResponses( CUtlVector<CRR_Response> *pResponses );
|
||||
#pragma endregion Implement interface from IResponseSystem
|
||||
|
||||
virtual void Release() = 0;
|
||||
|
||||
virtual void DumpRules();
|
||||
|
||||
bool IsCustomManagable() { return m_bCustomManagable; }
|
||||
|
||||
void Clear();
|
||||
|
||||
void DumpDictionary( const char *pszName );
|
||||
|
||||
protected:
|
||||
|
||||
void BuildDispatchTables();
|
||||
bool Dispatch( char const *pToken, unsigned int uiHash, DispatchMap_t &rMap );
|
||||
bool DispatchParseRule( char const *pToken, unsigned int uiHash, ParseRuleDispatchMap_t &rMap, Rule &newRule );
|
||||
bool DispatchParseResponse( char const *pToken, unsigned int uiHash, ParseResponseDispatchMap_t &rMap, ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
bool DispatchParseResponseGroup( char const *pToken, unsigned int uiHash, ParseResponseGroupDispatchMap_t &rMap, char const *responseGroupName, ResponseGroup& newGroup, AI_ResponseParams &groupResponseParams );
|
||||
|
||||
virtual const char *GetScriptFile( void ) = 0;
|
||||
void LoadRuleSet( const char *setname );
|
||||
|
||||
void ResetResponseGroups();
|
||||
|
||||
float LookForCriteria( const CriteriaSet &criteriaSet, int iCriteria );
|
||||
float RecursiveLookForCriteria( const CriteriaSet &criteriaSet, Criteria *pParent );
|
||||
|
||||
public:
|
||||
|
||||
void CopyRuleFrom( Rule *pSrcRule, ResponseRulePartition::tIndex iRule, CResponseSystem *pCustomSystem );
|
||||
void CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem );
|
||||
void CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem );
|
||||
void CopyEnumerationsFrom( CResponseSystem *pCustomSystem );
|
||||
|
||||
//private:
|
||||
|
||||
struct Enumeration
|
||||
{
|
||||
float value;
|
||||
};
|
||||
|
||||
struct ResponseSearchResult
|
||||
{
|
||||
ResponseSearchResult()
|
||||
{
|
||||
group = NULL;
|
||||
action = NULL;
|
||||
}
|
||||
|
||||
ResponseGroup *group;
|
||||
ParserResponse *action;
|
||||
};
|
||||
|
||||
inline bool ParseToken( void )
|
||||
{
|
||||
if ( m_bUnget )
|
||||
{
|
||||
m_bUnget = false;
|
||||
return true;
|
||||
}
|
||||
if ( m_ScriptStack.Count() <= 0 )
|
||||
{
|
||||
Assert( 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ScriptStack[ 0 ].currenttoken = IEngineEmulator::Get()->ParseFile( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) );
|
||||
m_ScriptStack[ 0 ].tokencount++;
|
||||
return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false;
|
||||
}
|
||||
|
||||
inline void Unget()
|
||||
{
|
||||
m_bUnget = true;
|
||||
}
|
||||
|
||||
inline bool TokenWaiting( void )
|
||||
{
|
||||
if ( m_ScriptStack.Count() <= 0 )
|
||||
{
|
||||
Assert( 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *p = m_ScriptStack[ 0 ].currenttoken;
|
||||
|
||||
if ( !p )
|
||||
{
|
||||
Error( "AI_ResponseSystem: Unxpected TokenWaiting() with NULL buffer in %s", (char * ) m_ScriptStack[ 0 ].name );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while ( *p && *p!='\n')
|
||||
{
|
||||
// Special handler for // comment blocks
|
||||
if ( *p == '/' && *(p+1) == '/' )
|
||||
return false;
|
||||
|
||||
if ( !V_isspace( *p ) || V_isalnum( *p ) )
|
||||
return true;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParseOneResponse( const char *responseGroupName, ResponseGroup& group, ResponseParams *defaultParams = NULL );
|
||||
|
||||
void ParseInclude( void );
|
||||
void ParseResponse( void );
|
||||
void ParseCriterion( void );
|
||||
void ParseRule( void );
|
||||
void ParseEnumeration( void );
|
||||
|
||||
private:
|
||||
void ParseRule_MatchOnce( Rule &newRule );
|
||||
void ParseRule_ApplyContextToWorld( Rule &newRule );
|
||||
void ParseRule_ApplyContext( Rule &newRule );
|
||||
void ParseRule_Response( Rule &newRule );
|
||||
//void ParseRule_ForceWeight( Rule &newRule );
|
||||
void ParseRule_Criteria( Rule &newRule );
|
||||
char const *m_pParseRuleName;
|
||||
bool m_bParseRuleValid;
|
||||
|
||||
void ParseResponse_Weight( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_PreDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_NoDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_DefaultDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_Delay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_SpeakOnce( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_NoScene( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_StopOnNonIdle( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_Odds( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_RespeakDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_WeaponDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_Soundlevel( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_DisplayFirst( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_DisplayLast( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_Fire( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
void ParseResponse_Then( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp );
|
||||
|
||||
void ParseResponseGroup_Start( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_PreDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_NoDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_DefaultDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_Delay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_SpeakOnce( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_NoScene( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_StopOnNonIdle( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_Odds( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_RespeakDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_WeaponDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
void ParseResponseGroup_Soundlevel( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams );
|
||||
|
||||
public:
|
||||
int ParseOneCriterion( const char *criterionName );
|
||||
|
||||
bool Compare( const char *setValue, Criteria *c, bool verbose = false );
|
||||
bool CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose = false );
|
||||
void ComputeMatcher( Criteria *c, Matcher& matcher );
|
||||
void ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken );
|
||||
float LookupEnumeration( const char *name, bool& found );
|
||||
|
||||
ResponseRulePartition::tIndex FindBestMatchingRule( const CriteriaSet& set, bool verbose, float &scoreOfBestMatchingRule );
|
||||
|
||||
float ScoreCriteriaAgainstRule( const CriteriaSet& set, ResponseRulePartition::tRuleDict &dict, int irule, bool verbose = false );
|
||||
float RecursiveScoreSubcriteriaAgainstRule( const CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ );
|
||||
float ScoreCriteriaAgainstRuleCriteria( const CriteriaSet& set, int icriterion, bool& exclude, bool verbose = false );
|
||||
void FakeDepletes( ResponseGroup *g, IResponseFilter *pFilter );
|
||||
void RevertFakedDepletes( ResponseGroup *g );
|
||||
bool GetBestResponse( ResponseSearchResult& result, Rule *rule, bool verbose = false, IResponseFilter *pFilter = NULL );
|
||||
bool ResolveResponse( ResponseSearchResult& result, int depth, const char *name, bool verbose = false, IResponseFilter *pFilter = NULL );
|
||||
int SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter );
|
||||
void DescribeResponseGroup( ResponseGroup *group, int selected, int depth );
|
||||
void DebugPrint( int depth, PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 3, 4 );
|
||||
|
||||
void LoadFromBuffer( const char *scriptfile, const char *buffer );
|
||||
|
||||
void GetCurrentScript( char *buf, size_t buflen );
|
||||
int GetCurrentToken() const;
|
||||
void SetCurrentScript( const char *script );
|
||||
|
||||
inline bool IsRootCommand( unsigned int hash ) const
|
||||
{
|
||||
int slot = m_RootCommandHashes.Find( hash );
|
||||
return slot != m_RootCommandHashes.InvalidIndex();
|
||||
}
|
||||
|
||||
inline bool IsRootCommand() const
|
||||
{
|
||||
return IsRootCommand( RR_HASH( token ) );
|
||||
}
|
||||
|
||||
void PushScript( const char *scriptfile, unsigned char *buffer );
|
||||
void PopScript(void);
|
||||
|
||||
void ResponseWarning( PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 2, 3 );
|
||||
|
||||
CUtlDict< ResponseGroup, short > m_Responses;
|
||||
CUtlDict< Criteria, short > m_Criteria;
|
||||
// CUtlDict< Rule, short > m_Rules;
|
||||
ResponseRulePartition m_RulePartitions;
|
||||
CUtlDict< Enumeration, short > m_Enumerations;
|
||||
|
||||
CUtlVector<int> m_FakedDepletes;
|
||||
|
||||
char token[ 1204 ];
|
||||
|
||||
bool m_bUnget;
|
||||
|
||||
bool m_bCustomManagable;
|
||||
|
||||
struct ScriptEntry
|
||||
{
|
||||
unsigned char *buffer;
|
||||
FileNameHandle_t name;
|
||||
const char *currenttoken;
|
||||
int tokencount;
|
||||
};
|
||||
|
||||
CUtlVector< ScriptEntry > m_ScriptStack;
|
||||
CStringPool m_IncludedFiles;
|
||||
|
||||
DispatchMap_t m_FileDispatch;
|
||||
ParseRuleDispatchMap_t m_RuleDispatch;
|
||||
ParseResponseDispatchMap_t m_ResponseDispatch;
|
||||
ParseResponseGroupDispatchMap_t m_ResponseGroupDispatch;
|
||||
CUtlRBTree< unsigned int > m_RootCommandHashes;
|
||||
|
||||
// for debugging purposes only: concepts to be emitted from rr_debugresponses 2
|
||||
typedef CUtlLinkedList< CRR_Concept, unsigned short, false, unsigned int > ExcludeList_t;
|
||||
static ExcludeList_t m_DebugExcludeList;
|
||||
|
||||
friend class CDefaultResponseSystemSaveRestoreBlockHandler;
|
||||
friend class CResponseSystemSaveRestoreOps;
|
||||
};
|
||||
|
||||
// Some globals inherited from AI_Speech.h:
|
||||
const float AIS_DEF_MIN_DELAY = 2.8; // Minimum amount of time an NPCs will wait after someone has spoken before considering speaking again
|
||||
const float AIS_DEF_MAX_DELAY = 3.2; // Maximum amount of time an NPCs will wait after someone has spoken before considering speaking again
|
||||
}
|
||||
|
||||
#endif // RESPONSE_SYSTEM_H
|
||||
Reference in New Issue
Block a user