diff --git a/sp/src/game/server/ai_speech_new.cpp b/sp/src/game/server/ai_speech_new.cpp index 1edffdb7..76735a9d 100644 --- a/sp/src/game/server/ai_speech_new.cpp +++ b/sp/src/game/server/ai_speech_new.cpp @@ -461,7 +461,7 @@ CAI_Expresser::~CAI_Expresser() #ifdef DEBUG g_nExpressers--; if ( g_nExpressers == 0 && pSemaphore->GetOwner() ) - DevMsg( 2, "Speech semaphore being held by non-talker entity\n" ); + CGMsg( 2, CON_GROUP_SPEECH_AI, "Speech semaphore being held by non-talker entity\n" ); #endif } @@ -826,7 +826,7 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t &concept, AI_Response *re { entityName = ToBasePlayer( GetOuter() )->GetPlayerName(); } - DevMsg( 2, "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)concept ); + CGMsg( 2, CON_GROUP_SPEECH_AI, "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)concept ); // Tracker 15911: Can break the game if we stop an imported map placed lcs here, so only // cancel actor out of instanced scripted scenes. ywb @@ -835,7 +835,7 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t &concept, AI_Response *re if ( IsRunningScriptedScene( GetOuter() ) ) { - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)concept ); + CGMsg( 1, CON_GROUP_SPEECH_AI, "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)concept ); return false; } } @@ -858,7 +858,7 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t &concept, AI_Response *re float speakTime = GetResponseDuration( result ); GetOuter()->EmitSound( response ); - DevMsg( 2, "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); + CGMsg( 2, CON_GROUP_SPEECH_AI, "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); NoteSpeaking( speakTime, delay ); spoke = true; #ifdef MAPBASE @@ -1079,7 +1079,7 @@ bool CAI_Expresser::FireEntIOFromResponse( char *response, CBaseEntity *pInitiat CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, pszEntname, pInitiator ); if ( !pTarget ) { - Msg( "Response rule targeted %s with entityio, but that doesn't exist.\n", pszEntname ); + CGMsg( 0, CON_GROUP_SPEECH_AI, "Response rule targeted %s with entityio, but that doesn't exist.\n", pszEntname ); // but this is actually a legit use case, so return true (below). } else @@ -1528,7 +1528,7 @@ void CAI_Expresser::DumpHistories() { ConceptHistory_t *h = &m_ConceptHistories[ i ]; - DevMsg( "%i: %s at %f\n", c++, m_ConceptHistories.GetElementName( i ), h->timeSpoken ); + CGMsg( 1, CON_GROUP_SPEECH_AI, "%i: %s at %f\n", c++, m_ConceptHistories.GetElementName( i ), h->timeSpoken ); } } @@ -1571,7 +1571,7 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ) } else { - DevMsg( CFmtStr( &pszFormat ) ); + CGMsg( 1, CON_GROUP_SPEECH_AI, CFmtStr( &pszFormat ) ); } UTIL_LogPrintf( (char *) ( (const char *) CFmtStr( &pszFormat ) ) ); } diff --git a/sp/src/game/shared/mapbase/mapbase_shared.cpp b/sp/src/game/shared/mapbase/mapbase_shared.cpp index 5aff896f..e93add3c 100644 --- a/sp/src/game/shared/mapbase/mapbase_shared.cpp +++ b/sp/src/game/shared/mapbase/mapbase_shared.cpp @@ -9,6 +9,7 @@ #include "cbase.h" #include "tier0/icommandline.h" +#include "tier1/mapbase_con_groups.h" #include "igamesystem.h" #include "filesystem.h" #include @@ -151,6 +152,8 @@ public: virtual bool Init() { + InitConsoleGroups( g_pFullFileSystem ); + // Checks gameinfo.txt for additional command line options KeyValues *gameinfo = new KeyValues("GameInfo"); if (GetGameInfoKeyValues(gameinfo)) @@ -626,3 +629,38 @@ BEGIN_DATADESC( CMapbaseManifestEntity ) END_DATADESC() #endif + +//----------------------------------------------------------------------------- + +void CV_IncludeNameChanged( IConVar *pConVar, const char *pOldString, float flOldValue ); + +#ifdef CLIENT_DLL +ConVar con_group_include_name_client( "con_group_include_name_client", "0", FCVAR_NONE, "Includes groups when printing on the client.", CV_IncludeNameChanged ); + +void CV_IncludeNameChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) +{ + SetConsoleGroupIncludeNames( con_group_include_name_client.GetBool() ); +} +#else +ConVar con_group_include_name( "con_group_include_name", "0", FCVAR_NONE, "Includes groups when printing.", CV_IncludeNameChanged ); + +void CV_IncludeNameChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) +{ + SetConsoleGroupIncludeNames( con_group_include_name.GetBool() ); +} +#endif + +CON_COMMAND_SHARED( con_group_reload, "Reloads all console groups." ) +{ + InitConsoleGroups( g_pFullFileSystem ); +} + +CON_COMMAND_SHARED( con_group_list, "Prints a list of all console groups." ) +{ + PrintAllConsoleGroups(); +} + +CON_COMMAND_SHARED( con_group_toggle, "Toggles a console group." ) +{ + ToggleConsoleGroups( args.Arg( 1 ) ); +} diff --git a/sp/src/public/tier1/mapbase_con_groups.h b/sp/src/public/tier1/mapbase_con_groups.h index cdd955c9..7346092e 100644 --- a/sp/src/public/tier1/mapbase_con_groups.h +++ b/sp/src/public/tier1/mapbase_con_groups.h @@ -16,25 +16,48 @@ //static const Color CON_COLOR_DEV_VERBOSE( 192, 128, 192, 255 ); -// General -#define CON_GROUP_MAPBASE_MISC 0 // "Mapbase Misc." -#define CON_GROUP_PHYSICS 1 // "Physics" +enum ConGroupID_t +{ + // General + CON_GROUP_MAPBASE_MISC, // "Mapbase misc." + CON_GROUP_PHYSICS, // "Physics" + CON_GROUP_IO_SYSTEM, // "Entity I/O" + CON_GROUP_RESPONSE_SYSTEM, // "Response System" -// Server -#define CON_GROUP_IO_SYSTEM 2 // "Entity I/O" -#define CON_GROUP_NPC_AI 3 // "NPC AI" -#define CON_GROUP_NPC_SCRIPTS 4 // "NPC Scripts" -#define CON_GROUP_CHOREO 5 // "Choreo" + // Game + CON_GROUP_NPC_AI, // "NPC AI" + CON_GROUP_NPC_SCRIPTS, // "NPC scripts" + CON_GROUP_SPEECH_AI, // "Speech AI" + CON_GROUP_CHOREO, // "Choreo" -// VScript -#define CON_GROUP_VSCRIPT 6 // "VScript" -#define CON_GROUP_VSCRIPT_PRINT 7 // "VScript Print" + // VScript + CON_GROUP_VSCRIPT, // "VScript" + CON_GROUP_VSCRIPT_PRINT, // "VScript print" -#define CON_GROUP_MAX 8 // must always be at the end + //-------------------------- + + // + // Mod groups can be inserted here + // + + //-------------------------- + + CON_GROUP_MAX, // Keep this at the end +}; // Mapbase console group message. -void CGMsg( int level, int nGroup, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 ); +void CGMsg( int level, ConGroupID_t nGroup, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 ); #define CGWarning CGMsg +//----------------------------------------------------------------------------- + +class IBaseFileSystem; + +void InitConsoleGroups( IBaseFileSystem *filesystem ); + +void PrintAllConsoleGroups(); +void ToggleConsoleGroups( const char *pszQuery ); +void SetConsoleGroupIncludeNames( bool bToggle ); + #endif diff --git a/sp/src/tier1/mapbase_con_groups.cpp b/sp/src/tier1/mapbase_con_groups.cpp index 08ca8fc7..65bcd21d 100644 --- a/sp/src/tier1/mapbase_con_groups.cpp +++ b/sp/src/tier1/mapbase_con_groups.cpp @@ -11,102 +11,116 @@ #include #include #include "basetypes.h" -#include "tier1/tier1.h" -#include "tier1/utldict.h" +#include "tier1.h" +#include "utldict.h" #include "Color.h" -#include "tier1/mapbase_con_groups.h" - -void CV_ColorChanged( IConVar *pConVar, const char *pOldString, float flOldValue ); +#include "mapbase_con_groups.h" +#include "KeyValues.h" +#include "filesystem.h" +#include "mapbase_matchers_base.h" struct ConGroup_t { - ConGroup_t( const char *_pszName, ConVar *pCvar ) + ConGroup_t( const char *_pszName, const char *_pszDescription ) { pszName = _pszName; - cvar = pCvar; + pszDescription = _pszDescription; + _clr.SetColor( 224, 224, 224, 255 ); // Default to a shade of gray } const Color &GetColor() { - if (_clr.a() == 0) - { - // Read the cvar - int clr[3]; - sscanf( cvar->GetString(), "%i %i %i", &clr[0], &clr[1], &clr[2] ); - _clr.SetColor( clr[0], clr[1], clr[2], 255 ); - } return _clr; } const char *pszName; + const char *pszDescription; Color _clr; - ConVar *cvar; - //bool bDisabled; + bool bDisabled; }; -//----------------------------------------------------------------------------- -// To define a console group, -//----------------------------------------------------------------------------- - -#define DEFINE_CON_GROUP_CVAR(name, def, desc) static ConVar con_group_##name##_color( "con_group_" #name "_color", def, FCVAR_ARCHIVE | FCVAR_REPLICATED, desc, CV_ColorChanged ) - -DEFINE_CON_GROUP_CVAR( mapbase_misc, "192 128 224", "Messages from misc. Mapbase functions, like map-specific files." ); -DEFINE_CON_GROUP_CVAR( physics, "159 209 159", "Messages from physics-related events." ); - -DEFINE_CON_GROUP_CVAR( inputoutput, "220 170 220", "Messages from I/O events. (these display in developer 2)" ); -DEFINE_CON_GROUP_CVAR( npc_ai, "240 160 200", "Messages from NPC AI, etc. which display at various verbse levels." ); -DEFINE_CON_GROUP_CVAR( npc_scripts, "255 115 215", "Messages from scripted_sequence, etc. (these display in developer 2)" ); -DEFINE_CON_GROUP_CVAR( choreo, "240 224 180", "Messages from choreographed scenes and response expressers. (these display in developer 1, 2, etc.)" ); - -DEFINE_CON_GROUP_CVAR( vscript, "192 224 240", "Internal messages from VScript not produced by the user's scripts." ); -DEFINE_CON_GROUP_CVAR( vscript_print, "80 186 255", "Messages from VScript's 'print' function." ); +// TODO: Something more reliable? +static bool g_bIncludeConGroupNames = false; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -#define DEFINE_CON_GROUP(id, name, codename) { name, &con_group_##codename##_color } +//#define DEFINE_CON_GROUP(id, name, codename) { name, &con_group_##codename##_color } +#define DEFINE_CON_GROUP(id, name, description) { name, description } ConGroup_t g_ConGroups[CON_GROUP_MAX] = { // General - DEFINE_CON_GROUP( CON_GROUP_MAPBASE_MISC, "Mapbase misc.", mapbase_misc ), - DEFINE_CON_GROUP( CON_GROUP_PHYSICS, "Physics", physics ), + DEFINE_CON_GROUP( CON_GROUP_MAPBASE_MISC, "Mapbase misc.", "Messages from misc. Mapbase functions, like map-specific files." ), + DEFINE_CON_GROUP( CON_GROUP_PHYSICS, "Physics", "Messages from physics-related events." ), + DEFINE_CON_GROUP( CON_GROUP_IO_SYSTEM, "Entity IO", "Messages from I/O events. (these display in developer 2)" ), + DEFINE_CON_GROUP( CON_GROUP_RESPONSE_SYSTEM, "Response System", "Messages from the Response System, a library primarily used for NPC speech." ), - // Server - DEFINE_CON_GROUP( CON_GROUP_IO_SYSTEM, "Entity IO", inputoutput ), - DEFINE_CON_GROUP( CON_GROUP_NPC_AI, "NPC AI", npc_ai ), - DEFINE_CON_GROUP( CON_GROUP_NPC_SCRIPTS, "NPC scripts", npc_scripts ), - DEFINE_CON_GROUP( CON_GROUP_CHOREO, "Choreo", choreo ), + // Game + DEFINE_CON_GROUP( CON_GROUP_NPC_AI, "NPC AI", "Messages from NPC AI, etc. which display at various verbose levels." ), + DEFINE_CON_GROUP( CON_GROUP_NPC_SCRIPTS, "NPC scripts", "Messages from scripted_sequence, etc. (these display in developer 2)" ), + DEFINE_CON_GROUP( CON_GROUP_SPEECH_AI, "Speech AI", "Messages from response expressers. (these display in developer 1, 2, etc.)" ), + DEFINE_CON_GROUP( CON_GROUP_CHOREO, "Choreo", "Messages from choreographed scenes. (these display in developer 1, 2, etc.)" ), // VScript - DEFINE_CON_GROUP( CON_GROUP_VSCRIPT, "VScript", vscript ), - DEFINE_CON_GROUP( CON_GROUP_VSCRIPT_PRINT, "VScript print", vscript_print ), + DEFINE_CON_GROUP( CON_GROUP_VSCRIPT, "VScript", "Internal messages from VScript not produced by actual scripts." ), + DEFINE_CON_GROUP( CON_GROUP_VSCRIPT_PRINT, "VScript print", "Messages from VScript's 'print' function." ), }; -void CV_ColorChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) +int FindConGroup( const char *pszName ) { for (int i = 0; i < CON_GROUP_MAX; i++) { - // Reset the alpha to indicate it needs to be refreshed - g_ConGroups[i]._clr[3] = 0; + if (Q_stricmp( pszName, g_ConGroups[i].pszName ) == 0) + return i; } + + return -1; } //----------------------------------------------------------------------------- +// Loads console groups //----------------------------------------------------------------------------- +void LoadConsoleGroupsFromFile( IBaseFileSystem *filesystem, const char *pszFileName, const char *pathID ) +{ + KeyValues *pGroupRoot = new KeyValues( "ConsoleGroups" ); -ConVar con_group_include_name( "con_group_include_name", "0", FCVAR_NONE, "Includes groups when printing." ); + pGroupRoot->LoadFromFile( filesystem, pszFileName, pathID ); -CON_COMMAND( con_group_list, "Prints a list of all console groups." ) + KeyValues *pGroup = NULL; + for ( pGroup = pGroupRoot->GetFirstTrueSubKey(); pGroup; pGroup = pGroup->GetNextTrueSubKey() ) + { + int index = FindConGroup( pGroup->GetName() ); + if (index != -1) + { + g_ConGroups[index]._clr = pGroup->GetColor( "MessageColor" ); + //g_ConGroups[index].bDisabled = pGroup->GetBool( "Disabled", false ); + } + else + { + Warning( "Invalid console group %s (new groups should be defined in the code)\n", pGroup->GetName() ); + } + } + + pGroupRoot->deleteThis(); +} + +void InitConsoleGroups( IBaseFileSystem *filesystem ) +{ + LoadConsoleGroupsFromFile( filesystem, "scripts/mapbase_con_groups.txt", "MOD" ); + LoadConsoleGroupsFromFile( filesystem, "scripts/mod_con_groups.txt", "MOD" ); +} + +void PrintAllConsoleGroups() { Msg( "============================================================\n" ); for (int i = 0; i < CON_GROUP_MAX; i++) { Msg( " # " ); ConColorMsg( g_ConGroups[i].GetColor(), "%s", g_ConGroups[i].pszName ); - Msg( " - %s ", g_ConGroups[i].cvar->GetHelpText() ); + Msg( " - %s ", g_ConGroups[i].pszDescription ); //if (g_ConGroups[i].bDisabled) // Msg("(DISABLED)"); @@ -116,26 +130,33 @@ CON_COMMAND( con_group_list, "Prints a list of all console groups." ) Msg( "============================================================\n" ); } -// TODO: Figure out how this can be done without server/client disparity issues -/* -CON_COMMAND( con_group_toggle, "Toggles a console group." ) +void ToggleConsoleGroups( const char *pszQuery ) { - const char *pszGroup = args.Arg( 1 ); + bool bMatched = false; + for (int i = 0; i < ARRAYSIZE( g_ConGroups ); i++) { - if (V_stricmp(pszGroup, g_ConGroups[i].pszName) == 0) + if (Matcher_NamesMatch( pszQuery, g_ConGroups[i].pszName )) { Msg( "%s is now %s\n", g_ConGroups[i].pszName, g_ConGroups[i].bDisabled ? "enabled" : "disabled" ); g_ConGroups[i].bDisabled = !g_ConGroups[i].bDisabled; - return; + bMatched = true; } } - Msg( "No group named \"%s\"\n", pszGroup ); + if (!bMatched) + Msg( "No groups matching \"%s\"\n", pszQuery ); } -*/ -void CGMsg( int level, int nGroup, const tchar* pMsg, ... ) +void SetConsoleGroupIncludeNames( bool bToggle ) +{ + g_bIncludeConGroupNames = bToggle; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void CGMsg( int level, ConGroupID_t nGroup, const tchar* pMsg, ... ) { // Return early if we're not at this level if (!IsSpewActive("developer", level)) @@ -152,11 +173,11 @@ void CGMsg( int level, int nGroup, const tchar* pMsg, ... ) ConGroup_t *pGroup = &g_ConGroups[nGroup]; - /*if (pGroup->bDisabled) + if (pGroup->bDisabled) { - // Do nothing + // Do nothing } - else*/ if (con_group_include_name.GetBool()) + else if (g_bIncludeConGroupNames) { ConColorMsg(level, pGroup->GetColor(), "[%s] %s", pGroup->pszName, string); }