From ad0e4021bf9dc52173c00516175d56e173bb5962 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Mon, 9 Nov 2026 22:52:05 -0600 Subject: [PATCH 1/7] Remove mapbase_game_log (obsolete) --- src/game/client/client_mapbase.vpc | 1 - src/game/server/logicentities.cpp | 19 -- src/game/server/server_mapbase.vpc | 1 - src/game/shared/mapbase/mapbase_game_log.cpp | 243 ------------------- 4 files changed, 264 deletions(-) delete mode 100644 src/game/shared/mapbase/mapbase_game_log.cpp diff --git a/src/game/client/client_mapbase.vpc b/src/game/client/client_mapbase.vpc index 48c6201d1fc..d85cc748195 100644 --- a/src/game/client/client_mapbase.vpc +++ b/src/game/client/client_mapbase.vpc @@ -43,7 +43,6 @@ $Project $File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp" $File "$SRCDIR\game\shared\mapbase\mapbase_usermessages.cpp" $File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp" - $File "$SRCDIR\game\shared\mapbase\mapbase_game_log.cpp" $File "$SRCDIR\game\shared\mapbase\MapEdit.cpp" $File "$SRCDIR\game\shared\mapbase\MapEdit.h" $File "$SRCDIR\game\shared\mapbase\matchers.cpp" diff --git a/src/game/server/logicentities.cpp b/src/game/server/logicentities.cpp index 33b5ebfed4c..056e5e71997 100644 --- a/src/game/server/logicentities.cpp +++ b/src/game/server/logicentities.cpp @@ -3243,11 +3243,6 @@ int CLogicBranch::DrawDebugTextOverlays( void ) return text_offset; } -#ifdef MAPBASE -extern void MapbaseGameLog_Record( const char *szContext ); -extern ConVar mapbase_game_log_on_autosave; -#endif - //----------------------------------------------------------------------------- // Purpose: Autosaves when triggered //----------------------------------------------------------------------------- @@ -3284,13 +3279,6 @@ END_DATADESC() //----------------------------------------------------------------------------- void CLogicAutosave::InputSave( inputdata_t &inputdata ) { -#ifdef MAPBASE - if (mapbase_game_log_on_autosave.GetBool()) - { - MapbaseGameLog_Record( "autosave" ); - } -#endif - if ( m_bForceNewLevelUnit ) { engine->ClearSaveDir(); @@ -3304,13 +3292,6 @@ void CLogicAutosave::InputSave( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CLogicAutosave::InputSaveDangerous( inputdata_t &inputdata ) { -#ifdef MAPBASE - if (mapbase_game_log_on_autosave.GetBool()) - { - MapbaseGameLog_Record( "autosave_dangerous" ); - } -#endif - #ifdef MAPBASE_MP // From SecobMod CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); #else diff --git a/src/game/server/server_mapbase.vpc b/src/game/server/server_mapbase.vpc index 50308597bcf..666bea15eb6 100644 --- a/src/game/server/server_mapbase.vpc +++ b/src/game/server/server_mapbase.vpc @@ -41,7 +41,6 @@ $Project $File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp" $File "$SRCDIR\game\shared\mapbase\mapbase_usermessages.cpp" $File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp" - $File "$SRCDIR\game\shared\mapbase\mapbase_game_log.cpp" $File "$SRCDIR\game\shared\mapbase\MapEdit.cpp" $File "$SRCDIR\game\shared\mapbase\MapEdit.h" $File "$SRCDIR\game\shared\mapbase\matchers.cpp" diff --git a/src/game/shared/mapbase/mapbase_game_log.cpp b/src/game/shared/mapbase/mapbase_game_log.cpp deleted file mode 100644 index c51ab0c4e24..00000000000 --- a/src/game/shared/mapbase/mapbase_game_log.cpp +++ /dev/null @@ -1,243 +0,0 @@ -//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// -// -// Purpose: A special system designed to record game information for map testing. -// -// $NoKeywords: $ -//=============================================================================// - -#include "cbase.h" - -#include "tier0/icommandline.h" -#include "igamesystem.h" -#include "filesystem.h" -#include "utlbuffer.h" -#ifdef CLIENT_DLL -#else -#include "ammodef.h" -#include "ai_basenpc.h" -#include "ai_squad.h" -#include "fmtstr.h" -#include "GameEventListener.h" -#include "saverestore_utlvector.h" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#ifdef GAME_DLL -// ------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------ - -class CMapbaseGameLogger : public CLogicalEntity, public CGameEventListener -{ -public: - DECLARE_DATADESC(); - DECLARE_CLASS( CMapbaseGameLogger, CLogicalEntity ); - - CMapbaseGameLogger() - { - pGameLoggerEnt = this; - } - - void Activate() - { - BaseClass::Activate(); - - ListenForGameEvent("skill_changed"); - } - - void FireGameEvent( IGameEvent *event ) - { - if (FStrEq(event->GetName(), "skill_changed")) - { - m_ListSkillChanged.AddToTail(event->GetInt("skill_level")); - m_ListSkillChangedTime.AddToTail(gpGlobals->curtime); - } - } - - float m_flLastLogTime; - int m_iSaveID; - - CUtlVector m_ListSkillChanged; - CUtlVector m_ListSkillChangedTime; - - static CMapbaseGameLogger *GetGameLoggerEnt() - { - if (!pGameLoggerEnt) - pGameLoggerEnt = static_cast(CBaseEntity::Create("mapbase_game_logger", vec3_origin, vec3_angle)); - - return pGameLoggerEnt; - } - -private: - static CHandle pGameLoggerEnt; -}; - -LINK_ENTITY_TO_CLASS( mapbase_game_logger, CMapbaseGameLogger ); - -BEGIN_DATADESC( CMapbaseGameLogger ) - - DEFINE_FIELD( m_flLastLogTime, FIELD_TIME ), - DEFINE_FIELD( m_iSaveID, FIELD_INTEGER ), - - DEFINE_UTLVECTOR( m_ListSkillChanged, FIELD_INTEGER ), - DEFINE_UTLVECTOR( m_ListSkillChangedTime, FIELD_TIME ), - -END_DATADESC() - -CHandle CMapbaseGameLogger::pGameLoggerEnt; - -void MapbaseGameLog_CVarToggle( IConVar *var, const char *pOldString, float flOldValue ); -ConVar mapbase_game_log_on_autosave( "mapbase_game_log_on_autosave", "0", FCVAR_NONE, "Logs information to %mapname%_log_%number%.txt on each autosave", MapbaseGameLog_CVarToggle ); - -void MapbaseGameLog_Init() -{ - if (mapbase_game_log_on_autosave.GetBool()) - { - // Create the game logger ent - CMapbaseGameLogger::GetGameLoggerEnt(); - } -} - -void MapbaseGameLog_Record( const char *szContext ) -{ - CMapbaseGameLogger *pGameLoggerEnt = CMapbaseGameLogger::GetGameLoggerEnt(); - if (!pGameLoggerEnt) - { - Warning("Failed to get game logger ent\n"); - return; - } - - KeyValues *pKV = new KeyValues( "Log" ); - - KeyValues *pKVLogInfo = pKV->FindKey( "logging_info", true ); - if ( pKVLogInfo ) - { - pKVLogInfo->SetString("context", szContext); - pKVLogInfo->SetFloat("last_log", pGameLoggerEnt->m_flLastLogTime > 0.0f ? gpGlobals->curtime - pGameLoggerEnt->m_flLastLogTime : -1.0f); - } - - KeyValues *pKVGameInfo = pKV->FindKey( "game_info", true ); - if ( pKVGameInfo ) - { - pKVGameInfo->SetInt("skill", g_pGameRules->GetSkillLevel()); - - if (pGameLoggerEnt->m_ListSkillChanged.Count() > 0) - { - KeyValues *pKVSkill = pKVGameInfo->FindKey("skill_changes", true); - for (int i = 0; i < pGameLoggerEnt->m_ListSkillChanged.Count(); i++) - { - float flTime = pGameLoggerEnt->m_ListSkillChangedTime[i]; - switch (pGameLoggerEnt->m_ListSkillChanged[i]) - { - case SKILL_EASY: pKVSkill->SetString(CNumStr(flTime), "easy"); break; - case SKILL_MEDIUM: pKVSkill->SetString(CNumStr(flTime), "normal"); break; - case SKILL_HARD: pKVSkill->SetString(CNumStr(flTime), "hard"); break; - } - } - } - } - - KeyValues *pKVPlayer = pKV->FindKey( "player", true ); - if ( pKVPlayer ) - { - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - - if ( pPlayer ) - { - pKVPlayer->SetInt("health", pPlayer->GetHealth()); - pKVPlayer->SetInt("armor", pPlayer->ArmorValue()); - - pKVPlayer->SetString("position", CFmtStrN<128>("[%f %f %f]", pPlayer->GetAbsOrigin().x, pPlayer->GetAbsOrigin().y, pPlayer->GetAbsOrigin().z)); - pKVPlayer->SetString("angles", CFmtStrN<128>("[%f %f %f]", pPlayer->EyeAngles().x, pPlayer->EyeAngles().y, pPlayer->EyeAngles().z)); - - KeyValues *pKVWeapons = pKVPlayer->FindKey( "weapons", true ); - if ( pKVWeapons ) - { - // Cycle through all of the player's weapons - for ( int i = 0; i < pPlayer->WeaponCount(); i++ ) - { - CBaseCombatWeapon *pWeapon = pPlayer->GetWeapon(i); - if ( !pWeapon ) - continue; - - if ( pPlayer->GetActiveWeapon() == pWeapon ) - pKVWeapons->SetString(pWeapon->GetClassname(), CFmtStrN<32>("%i; %i (active)", pWeapon->m_iClip1.Get(), pWeapon->m_iClip2.Get())); - else - pKVWeapons->SetString(pWeapon->GetClassname(), CFmtStrN<32>("%i; %i", pWeapon->m_iClip1.Get(), pWeapon->m_iClip2.Get())); - } - } - - KeyValues *pKVAmmo = pKVPlayer->FindKey( "ammo", true ); - if ( pKVAmmo ) - { - // Cycle through all of the player's ammo - for ( int i = 0; i < GetAmmoDef()->m_nAmmoIndex; i++ ) - { - int iAmmo = pPlayer->GetAmmoCount( i ); - if ( iAmmo > 0 ) - pKVAmmo->SetInt( GetAmmoDef()->m_AmmoType[i].pName, iAmmo ); - } - } - } - } - - CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); - int nAIs = g_AI_Manager.NumAIs(); - for (int i = 0; i < nAIs; i++) - { - CAI_BaseNPC *pNPC = ppAIs[i]; - - if (!pNPC->IsAlive() || pNPC->GetSleepState() != AISS_AWAKE) - continue; - - KeyValues *pKVNPC = pKV->FindKey( CNumStr( pNPC->entindex() ), true ); - if (pKVNPC) - { - pKVNPC->SetString("classname", pNPC->GetClassname()); - pKVNPC->SetString("name", STRING(pNPC->GetEntityName())); - - pKVNPC->SetString("position", CFmtStrN<128>("[%f %f %f]", pNPC->GetAbsOrigin().x, pNPC->GetAbsOrigin().y, pNPC->GetAbsOrigin().z)); - - pKVNPC->SetInt("health", pNPC->GetHealth()); - - if (pNPC->GetActiveWeapon()) - pKVNPC->SetString("weapon", pNPC->GetActiveWeapon()->GetClassname()); - - if (pNPC->GetSquad()) - pKVNPC->SetString("squad", pNPC->GetSquad()->GetName()); - } - } - - CFmtStrN pathfmt("map_logs/%s_log_%i.txt", STRING(gpGlobals->mapname), pGameLoggerEnt->m_iSaveID); - - pGameLoggerEnt->m_flLastLogTime = gpGlobals->curtime; - pGameLoggerEnt->m_iSaveID++; - - // Create the folder first, since "map_logs" is not standard and is unlikely to exist - g_pFullFileSystem->CreateDirHierarchy( "map_logs", "MOD" ); - - if (pKV->SaveToFile( g_pFullFileSystem, pathfmt, "MOD" )) - { - Msg("Saved game log file to \"%s\"\n", pathfmt.Get()); - } - - pKV->deleteThis(); -} - -static void CC_Mapbase_GameLogRecord( const CCommand& args ) -{ - MapbaseGameLog_Record( "command" ); -} - -static ConCommand mapbase_game_log_record("mapbase_game_log_record", CC_Mapbase_GameLogRecord, "Records game data to %mapname%_log_%number%." ); - -void MapbaseGameLog_CVarToggle( IConVar *var, const char *pOldString, float flOldValue ) -{ - if (mapbase_game_log_on_autosave.GetBool()) - { - // Create the game logger ent - CMapbaseGameLogger::GetGameLoggerEnt(); - } -} -#endif From 898d8de7205603533f576c2cfb95c8bd65711234 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Mon, 9 Nov 2026 23:10:26 -0600 Subject: [PATCH 2/7] Pull Mapbase matcher cvars out of tier1 + clean up comments --- src/game/shared/mapbase/matchers.cpp | 45 +++++------------------- src/game/shared/mapbase/matchers.h | 12 +++---- src/public/tier1/mapbase_matchers_base.h | 10 +++--- src/tier1/mapbase_matchers_base.cpp | 33 ++++++----------- 4 files changed, 29 insertions(+), 71 deletions(-) diff --git a/src/game/shared/mapbase/matchers.cpp b/src/game/shared/mapbase/matchers.cpp index b8b915f4908..311c8945b9a 100644 --- a/src/game/shared/mapbase/matchers.cpp +++ b/src/game/shared/mapbase/matchers.cpp @@ -1,6 +1,6 @@ //========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= // -// Purpose: General matching functions for things like wildcards and !=. +// Purpose: General matching functions for wildcards and leading operators (e.g. '!=1'). // // $NoKeywords: $ //============================================================================= @@ -10,45 +10,18 @@ #include "matchers.h" #include "fmtstr.h" +bool Matcher_Match(const char *pszQuery, const char *szValue) +{ #ifdef CLIENT_DLL -// FIXME: There is no clientside equivalent to the RS code -static bool ResponseSystemCompare(const char *criterion, const char *value) { return Matcher_NamesMatch(criterion, value); } + // FIXME: There is no clientside equivalent to the RS code + return Matcher_NamesMatch( pszQuery, szValue ); #else -extern bool ResponseSystemCompare(const char *criterion, const char *value); + // This sends our comparison directly to the Response System, which is responsible for leading operator functions. + // Then, if applicable, it passes it along to Matcher_NamesMatch to handle the wildcards. + extern bool ResponseSystemCompare( const char *criterion, const char *value ); + return ResponseSystemCompare( pszQuery, szValue ); #endif - -//============================================================================= -// These are the "matchers" that compare with wildcards ("any*" for text starting with "any") -// and operators (<3 for numbers less than 3). -// -// Matcher_Match - Matching function using RS operators and NamesMatch wildcards/regex. -// Matcher_Regex - Uses regex functions from the std library. -// Matcher_NamesMatch - Based on Valve's original NamesMatch function, using wildcards and regex. -// -// AppearsToBeANumber - Response System-based function which checks if the string might be a number. -//============================================================================= - -bool Matcher_Match(const char *pszQuery, const char *szValue) -{ - // I wasn't kidding when I said all this did was hijack response system matching. - return ResponseSystemCompare(pszQuery, szValue); } bool Matcher_Match(const char *pszQuery, int iValue) { return Matcher_Match(pszQuery, CNumStr(iValue)); } bool Matcher_Match(const char *pszQuery, float flValue) { return Matcher_Match(pszQuery, CNumStr(flValue)); } - -// Matcher_Compare is a deprecated alias originally used when Matcher_Match didn't support wildcards. -/* -bool Matcher_Compare(const char *pszQuery, const char *szValue) -{ - return Matcher_Match(pszQuery, szValue); -#if 0 - // I have to do this so wildcards could test *before* the response system comparison. - // I know it removes the operators twice, but I won't worry about it. - bool match = Matcher_NamesMatch(Matcher_RemoveOperators(pszQuery), szValue); - if (match) - return Matcher_Match(pszQuery, szValue); - return false; -#endif -} -*/ diff --git a/src/game/shared/mapbase/matchers.h b/src/game/shared/mapbase/matchers.h index 7d86ad636a4..c1f3f261eb9 100644 --- a/src/game/shared/mapbase/matchers.h +++ b/src/game/shared/mapbase/matchers.h @@ -1,6 +1,6 @@ //========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= // -// Purpose: General matching functions for things like wildcards and !=. +// Purpose: General matching functions for wildcards and leading operators (e.g. '!=1'). // // $NoKeywords: $ //============================================================================= @@ -13,15 +13,11 @@ #include "tier1/mapbase_matchers_base.h" -// Compares with != and the like. Basically hijacks the response system matching. -// This also loops back around to Matcher_NamesMatch. -// pszQuery = The value that should have the operator(s) at the beginning. -// szValue = The value tested against the criterion. +// Complex string comparison. +// Scans pszQuery for leading operators (!=, <, etc.) and then evaluates szValue against them, +// if applicable. Then, uses Matcher_NamesMatch to compare using wildcards if necessary. bool Matcher_Match( const char *pszQuery, const char *szValue ); bool Matcher_Match( const char *pszQuery, int iValue ); bool Matcher_Match( const char *pszQuery, float flValue ); -// Deprecated; do not use -//static inline bool Matcher_Compare( const char *pszQuery, const char *szValue ) { return Matcher_Match( pszQuery, szValue ); } - #endif diff --git a/src/public/tier1/mapbase_matchers_base.h b/src/public/tier1/mapbase_matchers_base.h index beb1d869c91..b626e1145f9 100644 --- a/src/public/tier1/mapbase_matchers_base.h +++ b/src/public/tier1/mapbase_matchers_base.h @@ -1,6 +1,6 @@ //========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= // -// Purpose: General matching functions for things like wildcards and !=. +// Purpose: Utility functions for comparing strings with wildcards, regex, etc. // // $NoKeywords: $ //============================================================================= @@ -26,14 +26,14 @@ bool Matcher_Regex( const char *pszQuery, const char *szValue ); // Use Matcher_Match if you want <, !=, etc. as well. bool Matcher_NamesMatch( const char *pszQuery, const char *szValue ); -// Identical to baseentity.cpp's original NamesMatch(). +// Identical to baseentity.cpp's original NamesMatch(). Only trailing wildcards are supported. // pszQuery = The value that should have the wildcard. // szValue = The value tested against the query. bool Matcher_NamesMatch_Classic( const char *pszQuery, const char *szValue ); // Identical to Matcher_NamesMatch_Classic(), but either value could use a wildcard. -// pszQuery = The value that serves as the query. This value can use wildcards. -// szValue = The value tested against the query. This value can use wildcards as well. +// pszQuery = The value that serves as the query. This value can use a trailing wildcard. +// szValue = The value tested against the query. This value can use trailing wildcards as well. bool Matcher_NamesMatch_MutualWildcard( const char *pszQuery, const char *szValue ); // Returns true if the specified string contains a wildcard character. @@ -58,4 +58,6 @@ static bool AppearsToBeANumber( char const *token ) return true; } +void SetMatchersEnabled( bool bWildcards = true, bool bRegex = true ); + #endif diff --git a/src/tier1/mapbase_matchers_base.cpp b/src/tier1/mapbase_matchers_base.cpp index d4036f2ef42..3c6a3e7b65f 100644 --- a/src/tier1/mapbase_matchers_base.cpp +++ b/src/tier1/mapbase_matchers_base.cpp @@ -1,6 +1,6 @@ //========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= // -// Purpose: General matching functions for things like wildcards and !=. +// Purpose: Utility functions for comparing strings with wildcards, regex, etc. // // $NoKeywords: $ //============================================================================= @@ -15,9 +15,8 @@ #undef MINMAX_H //#include "minmax.h" -ConVar mapbase_wildcards_enabled("mapbase_wildcards_enabled", "1", FCVAR_NONE, "Toggles Mapbase's '?' wildcard and true '*' features. Useful for maps that have '?' in their targetnames."); -ConVar mapbase_wildcards_lazy_hack("mapbase_wildcards_lazy_hack", "1", FCVAR_NONE, "Toggles a hack which prevents Mapbase's lazy '?' wildcards from picking up \"???\", the default instance parameter."); -ConVar mapbase_regex_enabled("mapbase_regex_enabled", "1", FCVAR_NONE, "Toggles Mapbase's regex matching handover."); +static bool g_bWildcardsEnabled = true; +static bool g_bRegexEnabled = true; //============================================================================= // These are the "matchers" that compare with wildcards ("any*" for text starting with "any") @@ -48,7 +47,7 @@ bool Matcher_RunCharCompare(const char *pszQuery, const char *szValue) if ( *(pszQuery+1) == 0 ) return true; - if (mapbase_wildcards_enabled.GetBool()) + if (g_bWildcardsEnabled) { // There's text after this * which we need to test. // This recursion allows for multiple wildcards @@ -64,7 +63,7 @@ bool Matcher_RunCharCompare(const char *pszQuery, const char *szValue) } break; case '?': // Just skip if we're capable of lazy wildcards - if (mapbase_wildcards_enabled.GetBool()) + if (g_bWildcardsEnabled) break; default: return false; @@ -113,7 +112,7 @@ bool Matcher_NamesMatch(const char *pszQuery, const char *szValue) return true; // Check for regex - if ( *pszQuery == '@' && mapbase_regex_enabled.GetBool() ) + if ( *pszQuery == '@' && g_bRegexEnabled ) { // Make sure it has a forward slash // (prevents confusion with instance fixup escape) @@ -122,7 +121,7 @@ bool Matcher_NamesMatch(const char *pszQuery, const char *szValue) return Matcher_Regex( pszQuery+2, szValue ); } } - else if (pszQuery[0] == '?' && pszQuery[1] == '?' && pszQuery[2] == '?' && mapbase_wildcards_lazy_hack.GetBool()) + else if (pszQuery[0] == '?' && pszQuery[1] == '?' && pszQuery[2] == '?') { // HACKHACK: There's a nasty issue where instances with blank parameters use "???", but Mapbase's lazy wildcard code // recognizes this as essentially meaning "any name with 3 characters". This is a serious problem when the instance @@ -163,7 +162,6 @@ bool Matcher_NamesMatch_Classic(const char *pszQuery, const char *szValue) if ( *pszQuery == 0 && *szValue == 0 ) return true; - // @TODO (toml 03-18-03): Perhaps support real wildcards. Right now, only thing supported is trailing * if ( *pszQuery == '*' ) return true; @@ -202,7 +200,6 @@ bool Matcher_NamesMatch_MutualWildcard(const char *pszQuery, const char *szValue if ( *pszQuery == 0 && *szValue == 0 ) return true; - // @TODO (toml 03-18-03): Perhaps support real wildcards. Right now, only thing supported is trailing * if ( *pszQuery == '*' || *szValue == '*' ) return true; @@ -226,18 +223,8 @@ bool Matcher_ContainsWildcard(const char *pszQuery) return false; } -// Matcher_Compare is a deprecated alias originally used when Matcher_Match didn't support wildcards. -/* -bool Matcher_Compare(const char *pszQuery, const char *szValue) +void SetMatchersEnabled( bool bWildcards, bool bRegex ) { - return Matcher_Match(pszQuery, szValue); -#if 0 - // I have to do this so wildcards could test *before* the response system comparison. - // I know it removes the operators twice, but I won't worry about it. - bool match = Matcher_NamesMatch(Matcher_RemoveOperators(pszQuery), szValue); - if (match) - return Matcher_Match(pszQuery, szValue); - return false; -#endif + g_bWildcardsEnabled = bWildcards; + g_bRegexEnabled = bRegex; } -*/ From 9a997a66f2994d5489044389908ef3ccce0ac6d8 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Mon, 9 Nov 2026 23:31:57 -0600 Subject: [PATCH 3/7] Refactor Mapbase console group functionality --- src/common/mapbase_con_groups.cpp | 169 +++++++++++++++ src/common/mapbase_con_groups.h | 93 +++++++++ src/game/client/cbase.h | 2 +- src/game/client/client_mapbase.vpc | 4 + src/game/client/hl2mp/hud_deathnotice.cpp | 4 +- src/game/client/tf/hud_basedeathnotice.cpp | 8 +- src/game/client/tf/tf_gc_client.cpp | 2 +- src/game/server/ai_relationship.cpp | 12 +- src/game/server/cbase.h | 2 +- src/game/server/server_mapbase.vpc | 4 + src/game/shared/mapbase/game_con_groups.cpp | 24 +++ src/game/shared/mapbase/game_con_groups.h | 37 ++++ src/public/tier1/mapbase_con_groups.h | 60 +----- src/responserules/runtime/criteriaset.cpp | 2 - src/responserules/runtime/response_system.cpp | 1 - src/responserules/runtime/response_types.cpp | 2 - src/responserules/runtime/rr_response.cpp | 1 - src/responserules/runtime/rrbase.h | 3 + src/tier1/mapbase_con_groups.cpp | 193 ------------------ src/tier1/tier1.vpc | 1 - src/utils/vbsp/vbsp.vpc | 2 + src/vscript/vscript_squirrel.cpp | 2 +- 22 files changed, 354 insertions(+), 274 deletions(-) create mode 100644 src/common/mapbase_con_groups.cpp create mode 100644 src/common/mapbase_con_groups.h create mode 100644 src/game/shared/mapbase/game_con_groups.cpp create mode 100644 src/game/shared/mapbase/game_con_groups.h delete mode 100644 src/tier1/mapbase_con_groups.cpp diff --git a/src/common/mapbase_con_groups.cpp b/src/common/mapbase_con_groups.cpp new file mode 100644 index 00000000000..40076b4e1ce --- /dev/null +++ b/src/common/mapbase_con_groups.cpp @@ -0,0 +1,169 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: Mapbase classifies certain types of console messages into groups with specific colors. +// This is inspired by similar groups seen in CS:GO and Source 2 games. +// +// See game_con_groups.cpp for the default client/server implementation. +// +// $NoKeywords: $ +//============================================================================= + +#if defined(CLIENT_DLL) || defined(GAME_DLL) +#include "cbase.h" +#endif + +#include +#include +#include +#include "basetypes.h" +#include "mapbase_con_groups.h" +#include "KeyValues.h" +#include "filesystem.h" +#include "mapbase_matchers_base.h" + +bool ConGroup_t::g_bIncludeConGroupNames = false; + +static CUtlVector g_ConGroups; + +//----------------------------------------------------------------------------- + +ConGroup_t::ConGroup_t( CUtlVector &list, const char *_pszName ) +{ + pszName = _pszName; + clr.SetColor( 224, 224, 224, 255 ); // Default to a shade of gray + + list.AddToTail( this ); +} + +ConGroup_t::~ConGroup_t() +{ + // Assume we've already been added to the main list + g_ConGroups.FindAndRemove( this ); +} + +//----------------------------------------------------------------------------- + +// Base console groups +ConGroup_t ConGroup_MapbaseMisc ( g_ConGroups, "Mapbase misc." ); +ConGroup_t ConGroup_ResponseSys ( g_ConGroups, "Response System" ); +ConGroup_t ConGroup_VScript ( g_ConGroups, "VScript" ); +ConGroup_t ConGroup_VScriptPrint ( g_ConGroups, "VScript print" ); + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +int FindConGroup( const char *pszName ) +{ + for (int i = 0; i < g_ConGroups.Count(); i++) + { + 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 = NULL ) +{ + KeyValues *pGroupRoot = new KeyValues( "ConsoleGroups" ); + + pGroupRoot->LoadFromFile( filesystem, pszFileName, pathID ); + + KeyValues *pGroup = NULL; + for ( pGroup = pGroupRoot->GetFirstTrueSubKey(); pGroup; pGroup = pGroup->GetNextTrueSubKey() ) + { + int index = FindConGroup( pGroup->GetName() ); + if (index != -1) + { + Color msgClr = pGroup->GetColor( "MessageColor" ); + + // Make sure the color isn't 0,0,0,0 before assigning + if (msgClr.GetRawColor() != 0) + g_ConGroups[index]->clr = msgClr; + + 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, CUtlVector *list ) +{ + if ( list ) + { + g_ConGroups.AddVectorToTail( *list ); + list->Purge(); + } + + LoadConsoleGroupsFromFile( filesystem, "scripts/mapbase_con_groups.txt" ); + LoadConsoleGroupsFromFile( filesystem, "scripts/mod_con_groups.txt" ); +} + +void PrintAllConsoleGroups() +{ + Msg( "============================================================\n" ); + for (int i = 0; i < g_ConGroups.Count(); i++) + { + ConColorMsg( g_ConGroups[i]->clr, " # %s", g_ConGroups[i]->pszName ); + + if (g_ConGroups[i]->bDisabled) + Msg(" [DISABLED]"); + + //Msg( " - %s ", g_ConGroups[i]->pszDesc ); + + Msg("\n"); + } + Msg( "============================================================\n" ); +} + +void ToggleConsoleGroups( const char *pszQuery ) +{ + bool bMatched = false; + + for (int i = 0; i < g_ConGroups.Count(); i++) + { + 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; + bMatched = true; + } + } + + if (!bMatched) + Msg( "No groups matching \"%s\"\n", pszQuery ); +} + +void SetConsoleGroupIncludeNames( bool bToggle ) +{ + ConGroup_t::g_bIncludeConGroupNames = bToggle; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void _CGMsgFixup( int level, const ConGroup_t &group, const tchar* pMsg, ... ) +{ + // Return early if we're not at this level + if (!IsSpewActive("developer", level)) + return; + + char string[ 2048 ]; + va_list argptr; + va_start( argptr, pMsg ); + Q_vsnprintf( string, sizeof(string), pMsg, argptr ); + va_end( argptr ); + + // For now, this is the only reason we would be here + Assert( ConGroup_t::g_bIncludeConGroupNames ); + + ConColorMsg( level, group.clr, "[%s] %s", group.pszName, string ); +} diff --git a/src/common/mapbase_con_groups.h b/src/common/mapbase_con_groups.h new file mode 100644 index 00000000000..387c349222c --- /dev/null +++ b/src/common/mapbase_con_groups.h @@ -0,0 +1,93 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: See mapbase_con_groups.cpp for more information +// +// $NoKeywords: $ +//============================================================================= + +#ifndef MAPBASE_CON_GROUPS_H +#define MAPBASE_CON_GROUPS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "Color.h" +#include "utlvector.h" + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +struct ConGroup_t +{ + ConGroup_t( CUtlVector &list, const char *_pszName ); + ~ConGroup_t(); + + const char *pszName; + Color clr; + + bool bDisabled; + + //---------------------------------------- + + static bool g_bIncludeConGroupNames; +}; + +//----------------------------------------------------------------------------- + +extern ConGroup_t ConGroup_MapbaseMisc; +extern ConGroup_t ConGroup_ResponseSys; +extern ConGroup_t ConGroup_VScript; +extern ConGroup_t ConGroup_VScriptPrint; + +// Preprocessors for old naming convention + +#define CON_GROUP_MAPBASE_MISC ConGroup_MapbaseMisc +#define CON_GROUP_RESPONSE_SYSTEM ConGroup_ResponseSys +#define CON_GROUP_VSCRIPT ConGroup_VScript +#define CON_GROUP_VSCRIPT_PRINT ConGroup_VScriptPrint + +//----------------------------------------------------------------------------- + +// Fixes up the message instead of passing it directly to ConColorMsg. (do not call directly; call CGMsg instead) +void _CGMsgFixup( int level, const ConGroup_t &group, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 ); + +// Mapbase console group message. +// +// - "level" is developer level (like in DevMsg; use 0 for Msg) +// - "group" is the console group (use a string in the "CON_GROUP" function, or use one of the defaults) +// - "pMsg" and "..." are the message contents +// +// See below this macro for more information +#define CGMsg( level, group, pMsg, ... ) \ + do { \ + if ( !group.bDisabled ) \ + { \ + if ( ConGroup_t::g_bIncludeConGroupNames ) \ + _CGMsgFixup( level, group, pMsg, ##__VA_ARGS__ ); \ + else \ + ConColorMsg( level, group.clr, pMsg, ##__VA_ARGS__ ); \ + } \ + } while(0) + +// We use a macro so that we can pass the variadic arguments directly without using va_list or variadic functions. +// (since the former is slow and the latter bloats too much with this) +// The "do while" is so that we can directly plug the name into instances of Msg/DevMsg without having to change +// anything else, since it needs to have multiple lines but also end with a semicolon. +// +// The necessity of this mess is arguable, but it's filling in for direct calls to Msg/DevMsg, so I wanted to +// minimize the performance difference. +// (although calling Msg more than a few times per frame is usually a sign of a larger problem, anyway...) + +#define CGWarning CGMsg + +//----------------------------------------------------------------------------- + +class IBaseFileSystem; + +void InitConsoleGroups( IBaseFileSystem *filesystem, CUtlVector *list = NULL ); + +void PrintAllConsoleGroups(); +void ToggleConsoleGroups( const char *pszQuery ); +void SetConsoleGroupIncludeNames( bool bToggle ); + +#endif diff --git a/src/game/client/cbase.h b/src/game/client/cbase.h index 53322ca4be1..284140af8e3 100644 --- a/src/game/client/cbase.h +++ b/src/game/client/cbase.h @@ -38,7 +38,7 @@ struct studiohdr_t; #include #ifdef MAPBASE -#include "tier1/mapbase_con_groups.h" +#include "mapbase/game_con_groups.h" #endif diff --git a/src/game/client/client_mapbase.vpc b/src/game/client/client_mapbase.vpc index d85cc748195..4ac36dee9b0 100644 --- a/src/game/client/client_mapbase.vpc +++ b/src/game/client/client_mapbase.vpc @@ -49,6 +49,10 @@ $Project $File "$SRCDIR\game\shared\mapbase\matchers.h" $File "$SRCDIR\game\shared\mapbase\game_timer.cpp" $File "$SRCDIR\game\shared\mapbase\game_timer.h" + $File "$SRCDIR\game\shared\mapbase\game_con_groups.cpp" + $File "$SRCDIR\game\shared\mapbase\game_con_groups.h" + $File "$SRCDIR\common\mapbase_con_groups.cpp" + $File "$SRCDIR\common\mapbase_con_groups.h" $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT] diff --git a/src/game/client/hl2mp/hud_deathnotice.cpp b/src/game/client/hl2mp/hud_deathnotice.cpp index 432b1e5ff5c..08e87b86225 100644 --- a/src/game/client/hl2mp/hud_deathnotice.cpp +++ b/src/game/client/hl2mp/hud_deathnotice.cpp @@ -443,7 +443,7 @@ void CHudDeathNotice::FireGameEvent( IGameEvent * event ) } } - Msg( "%s", sDeathMsg ); + CGMsg( 0, ConGroup_DeathNotice, "%s", sDeathMsg ); } #ifdef MAPBASE_MP @@ -572,7 +572,7 @@ void CHudDeathNotice::OnNonPlayerKilled( IGameEvent * event ) } } - Msg( "%s", sDeathMsg ); + CGMsg( 0, ConGroup_DeathNotice, "%s", sDeathMsg ); } //----------------------------------------------------------------------------- diff --git a/src/game/client/tf/hud_basedeathnotice.cpp b/src/game/client/tf/hud_basedeathnotice.cpp index cb3bd83b1f8..ecc64e77647 100644 --- a/src/game/client/tf/hud_basedeathnotice.cpp +++ b/src/game/client/tf/hud_basedeathnotice.cpp @@ -584,11 +584,11 @@ void CHudBaseDeathNotice::FireGameEvent( IGameEvent *event ) { if ( m_DeathNotices[iMsg].bCrit ) { - Msg( "%s (crit)\n", sDeathMsg ); + CGMsg( 0, ConGroup_DeathNotice, "%s (crit)\n", sDeathMsg ); } else { - Msg( "%s\n", sDeathMsg ); + CGMsg( 0, ConGroup_DeathNotice, "%s\n", sDeathMsg ); } } } @@ -631,7 +631,7 @@ void CHudBaseDeathNotice::FireGameEvent( IGameEvent *event ) V_wcsncpy( m_DeathNotices[iMsg].wzInfoText, g_pVGuiLocalize->Find( len > 1 ? "#Msg_Captured_Multiple" : "#Msg_Captured" ), sizeof( m_DeathNotices[iMsg].wzInfoText ) ); // print a log message - Msg( "%s captured %s for team #%d\n", m_DeathNotices[iMsg].Killer.szName, m_DeathNotices[iMsg].Victim.szName, m_DeathNotices[iMsg].Killer.iTeam ); + CGMsg( 0, ConGroup_DeathNotice, "%s captured %s for team #%d\n", m_DeathNotices[iMsg].Killer.szName, m_DeathNotices[iMsg].Victim.szName, m_DeathNotices[iMsg].Killer.iTeam ); } else if ( FStrEq( "teamplay_capture_blocked", pszEventName ) ) { @@ -646,7 +646,7 @@ void CHudBaseDeathNotice::FireGameEvent( IGameEvent *event ) m_DeathNotices[iMsg].bLocalPlayerInvolved = true; // print a log message - Msg( "%s defended %s for team #%d\n", m_DeathNotices[iMsg].Killer.szName, m_DeathNotices[iMsg].Victim.szName, m_DeathNotices[iMsg].Killer.iTeam ); + CGMsg( 0, ConGroup_DeathNotice, "%s defended %s for team #%d\n", m_DeathNotices[iMsg].Killer.szName, m_DeathNotices[iMsg].Victim.szName, m_DeathNotices[iMsg].Killer.iTeam ); } else if ( FStrEq( "teamplay_flag_event", pszEventName ) ) { diff --git a/src/game/client/tf/tf_gc_client.cpp b/src/game/client/tf/tf_gc_client.cpp index 346654bac2a..69423697614 100644 --- a/src/game/client/tf/tf_gc_client.cpp +++ b/src/game/client/tf/tf_gc_client.cpp @@ -56,7 +56,7 @@ ConVar tf_mm_debug_level( "tf_mm_debug_level", "4" ); -#define GCMatchmakingDebugSpew( lvl, ...) do { if ( lvl <= GCMATCHMAKING_DEBUG_LEVEL || lvl <= tf_mm_debug_level.GetInt() ) { Msg( __VA_ARGS__); } } while(false) +#define GCMatchmakingDebugSpew( lvl, ...) do { if ( lvl <= GCMATCHMAKING_DEBUG_LEVEL || lvl <= tf_mm_debug_level.GetInt() ) { CGMsg( 0, ConGroup_GC, __VA_ARGS__); } } while(false) static ConVar mod_inventory_request_timeout( "mod_inventory_request_timeout", "300", FCVAR_NONE, "Seconds to wait for TF inventory before assuming failure" ); diff --git a/src/game/server/ai_relationship.cpp b/src/game/server/ai_relationship.cpp index 2f59b811099..b178bc80250 100644 --- a/src/game/server/ai_relationship.cpp +++ b/src/game/server/ai_relationship.cpp @@ -372,7 +372,7 @@ void CAI_Relationship::ChangeRelationships( int disposition, int iReverting, CBa if( iReverting != NOT_REVERTING && m_iPreviousDisposition == -1 ) { // Trying to revert without having ever set the relationships! - DevMsg( 2, "ai_relationship cannot revert changes before they are applied!\n"); + CGMsg( 2, ConGroup_NPC_AI, "ai_relationship cannot revert changes before they are applied!\n"); return; } @@ -405,7 +405,7 @@ void CAI_Relationship::ChangeRelationships( int disposition, int iReverting, CBa { if ( subjectList.Count() == MAX_HANDLED || targetList.Count() == MAX_HANDLED ) { - DevMsg( "Too many entities handled by ai_relationship %s\n", GetDebugName() ); + CGMsg( 1, ConGroup_NPC_AI, "Too many entities handled by ai_relationship %s\n", GetDebugName() ); break; } @@ -429,7 +429,7 @@ void CAI_Relationship::ChangeRelationships( int disposition, int iReverting, CBa { if ( subjectList.Count() == MAX_HANDLED || targetList.Count() == MAX_HANDLED ) { - DevMsg( "Too many entities handled by ai_relationship %s\n", GetDebugName() ); + CGMsg( 1, ConGroup_NPC_AI, "Too many entities handled by ai_relationship %s\n", GetDebugName() ); break; } @@ -451,12 +451,12 @@ void CAI_Relationship::ChangeRelationships( int disposition, int iReverting, CBa // If either list is still empty, we have a problem. if( subjectList.Count() == 0 ) { - DevMsg( 2, "ai_relationship '%s' finds no subject(s) called: %s\n", GetDebugName(), STRING( m_iszSubject ) ); + CGMsg( 2, ConGroup_NPC_AI, "ai_relationship '%s' finds no subject(s) called: %s\n", GetDebugName(), STRING( m_iszSubject ) ); return; } else if ( targetList.Count() == 0 ) { - DevMsg( 2, "ai_relationship '%s' finds no target(s) called: %s\n", GetDebugName(), STRING( m_target ) ); + CGMsg( 2, ConGroup_NPC_AI, "ai_relationship '%s' finds no target(s) called: %s\n", GetDebugName(), STRING( m_target ) ); return; } @@ -629,7 +629,7 @@ void CAI_ClassRelationship::ChangeRelationships( int disposition, int iReverting if( iReverting != NOT_REVERTING && m_iPreviousDisposition == -1 ) { // Trying to revert without having ever set the relationships! - DevMsg( 2, "ai_relationship cannot revert changes before they are applied!\n"); + CGMsg( 2, ConGroup_NPC_AI, "ai_relationship cannot revert changes before they are applied!\n"); return; } diff --git a/src/game/server/cbase.h b/src/game/server/cbase.h index 2b00af39ede..9d295c6087f 100644 --- a/src/game/server/cbase.h +++ b/src/game/server/cbase.h @@ -81,7 +81,7 @@ #include "basetoggle.h" #include "igameevents.h" #ifdef MAPBASE -#include "tier1/mapbase_con_groups.h" +#include "mapbase/game_con_groups.h" #endif // saverestore.h declarations diff --git a/src/game/server/server_mapbase.vpc b/src/game/server/server_mapbase.vpc index 666bea15eb6..887aeeefe09 100644 --- a/src/game/server/server_mapbase.vpc +++ b/src/game/server/server_mapbase.vpc @@ -47,6 +47,10 @@ $Project $File "$SRCDIR\game\shared\mapbase\matchers.h" $File "$SRCDIR\game\shared\mapbase\game_timer.cpp" $File "$SRCDIR\game\shared\mapbase\game_timer.h" + $File "$SRCDIR\game\shared\mapbase\game_con_groups.cpp" + $File "$SRCDIR\game\shared\mapbase\game_con_groups.h" + $File "$SRCDIR\common\mapbase_con_groups.cpp" + $File "$SRCDIR\common\mapbase_con_groups.h" $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT] diff --git a/src/game/shared/mapbase/game_con_groups.cpp b/src/game/shared/mapbase/game_con_groups.cpp new file mode 100644 index 00000000000..d51b6d01b39 --- /dev/null +++ b/src/game/shared/mapbase/game_con_groups.cpp @@ -0,0 +1,24 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: Server and client implementation of Mapbase's console groups. +// +//============================================================================= + +#include "cbase.h" +#include "mapbase_con_groups.h" + +CUtlVector g_GameConGroups; + +//----------------------------------------------------------------------------- + +// Game console groups +ConGroup_t ConGroup_Physics ( g_GameConGroups, "Physics" ); +ConGroup_t ConGroup_EntityIO ( g_GameConGroups, "Entity IO" ); +ConGroup_t ConGroup_NPC_AI ( g_GameConGroups, "NPC AI" ); +ConGroup_t ConGroup_NPC_Scripts ( g_GameConGroups, "NPC scripts" ); +ConGroup_t ConGroup_SpeechAI ( g_GameConGroups, "Speech AI" ); +ConGroup_t ConGroup_Choreo ( g_GameConGroups, "Choreo" ); +ConGroup_t ConGroup_DeathNotice ( g_GameConGroups, "Death Notice" ); +#if defined( TF_DLL ) || defined( TF_CLIENT_DLL ) +ConGroup_t ConGroup_GC ( g_GameConGroups, "Game Coordinator" ); +#endif diff --git a/src/game/shared/mapbase/game_con_groups.h b/src/game/shared/mapbase/game_con_groups.h new file mode 100644 index 00000000000..200ae54604f --- /dev/null +++ b/src/game/shared/mapbase/game_con_groups.h @@ -0,0 +1,37 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: Server and client implementation of Mapbase's console groups. +// +//============================================================================= + +#ifndef GAME_CON_GROUPS_H +#define GAME_CON_GROUPS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mapbase_con_groups.h" + +extern CUtlVector g_GameConGroups; + +extern ConGroup_t ConGroup_Physics; +extern ConGroup_t ConGroup_EntityIO; +extern ConGroup_t ConGroup_NPC_AI; +extern ConGroup_t ConGroup_NPC_Scripts; +extern ConGroup_t ConGroup_SpeechAI; +extern ConGroup_t ConGroup_Choreo; +extern ConGroup_t ConGroup_DeathNotice; +#if defined( TF_DLL ) || defined( TF_CLIENT_DLL ) +extern ConGroup_t ConGroup_GC; +#endif + +// Preprocessors for old naming convention + +#define CON_GROUP_PHYSICS ConGroup_Physics +#define CON_GROUP_IO_SYSTEM ConGroup_EntityIO +#define CON_GROUP_NPC_AI ConGroup_NPC_AI +#define CON_GROUP_NPC_SCRIPTS ConGroup_NPC_Scripts +#define CON_GROUP_SPEECH_AI ConGroup_SpeechAI +#define CON_GROUP_CHOREO ConGroup_Choreo + +#endif diff --git a/src/public/tier1/mapbase_con_groups.h b/src/public/tier1/mapbase_con_groups.h index 7346092e8de..573c0eaf5f6 100644 --- a/src/public/tier1/mapbase_con_groups.h +++ b/src/public/tier1/mapbase_con_groups.h @@ -1,63 +1,7 @@ //========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= // -// Purpose: See tier1/mapbase_con_groups.cpp for more information +// Purpose: // -// $NoKeywords: $ //============================================================================= -#ifndef CON_VERBOSE_COLORS_H -#define CON_VERBOSE_COLORS_H -#ifdef _WIN32 -#pragma once -#endif - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -//static const Color CON_COLOR_DEV_VERBOSE( 192, 128, 192, 255 ); - -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" - - // Game - CON_GROUP_NPC_AI, // "NPC AI" - CON_GROUP_NPC_SCRIPTS, // "NPC scripts" - CON_GROUP_SPEECH_AI, // "Speech AI" - CON_GROUP_CHOREO, // "Choreo" - - // VScript - CON_GROUP_VSCRIPT, // "VScript" - CON_GROUP_VSCRIPT_PRINT, // "VScript print" - - //-------------------------- - - // - // Mod groups can be inserted here - // - - //-------------------------- - - CON_GROUP_MAX, // Keep this at the end -}; - -// Mapbase console group message. -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 +#error "Console groups are no longer in tier1. Please include common/mapbase_con_groups.h instead." diff --git a/src/responserules/runtime/criteriaset.cpp b/src/responserules/runtime/criteriaset.cpp index a2682caf7ca..1421f9b6274 100644 --- a/src/responserules/runtime/criteriaset.cpp +++ b/src/responserules/runtime/criteriaset.cpp @@ -9,8 +9,6 @@ #include "utlmap.h" -#include "tier1/mapbase_con_groups.h" - // memdbgon must be the last include file in a .cpp file!!! #include diff --git a/src/responserules/runtime/response_system.cpp b/src/responserules/runtime/response_system.cpp index 8f41ad301e3..c8a9f29394b 100644 --- a/src/responserules/runtime/response_system.cpp +++ b/src/responserules/runtime/response_system.cpp @@ -12,7 +12,6 @@ #include "convar.h" #include "fmtstr.h" #include "generichash.h" -#include "tier1/mapbase_con_groups.h" #ifdef MAPBASE #include "tier1/mapbase_matchers_base.h" #endif diff --git a/src/responserules/runtime/response_types.cpp b/src/responserules/runtime/response_types.cpp index 1d8f6b311d1..e0a0b0b30f1 100644 --- a/src/responserules/runtime/response_types.cpp +++ b/src/responserules/runtime/response_types.cpp @@ -7,8 +7,6 @@ #include "rrbase.h" -#include "tier1/mapbase_con_groups.h" - // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" diff --git a/src/responserules/runtime/rr_response.cpp b/src/responserules/runtime/rr_response.cpp index eb21a55b5e9..9b0fd45c620 100644 --- a/src/responserules/runtime/rr_response.cpp +++ b/src/responserules/runtime/rr_response.cpp @@ -8,7 +8,6 @@ #include "rrbase.h" #include -#include "tier1/mapbase_con_groups.h" /* #include "AI_Criteria.h" diff --git a/src/responserules/runtime/rrbase.h b/src/responserules/runtime/rrbase.h index e7af74deef1..50bbce00c13 100644 --- a/src/responserules/runtime/rrbase.h +++ b/src/responserules/runtime/rrbase.h @@ -46,6 +46,9 @@ #include "const.h" #include "edict.h" +// Mapbase +#include "mapbase_con_groups.h" + // app #if defined(_X360) #define DISABLE_DEBUG_HISTORY 1 diff --git a/src/tier1/mapbase_con_groups.cpp b/src/tier1/mapbase_con_groups.cpp deleted file mode 100644 index 5f23b3f8b28..00000000000 --- a/src/tier1/mapbase_con_groups.cpp +++ /dev/null @@ -1,193 +0,0 @@ -//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= -// -// Purpose: Mapbase classifies certain types of console messages into groups with specific colors. -// -// This is inspired by similar groups seen in CS:GO and Source 2 games. -// -// $NoKeywords: $ -//============================================================================= - -#include -#include -#include -#include "basetypes.h" -#include "tier1.h" -#include "utldict.h" -#include "Color.h" -#include "mapbase_con_groups.h" -#include "KeyValues.h" -#include "filesystem.h" -#include "mapbase_matchers_base.h" - -struct ConGroup_t -{ - ConGroup_t( const char *_pszName, const char *_pszDescription ) - { - pszName = _pszName; - pszDescription = _pszDescription; - _clr.SetColor( 224, 224, 224, 255 ); // Default to a shade of gray - } - - const Color &GetColor() - { - return _clr; - } - - const char *pszName; - const char *pszDescription; - Color _clr; - - bool bDisabled; -}; - -// 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, description) { name, description } - -ConGroup_t g_ConGroups[CON_GROUP_MAX] = { - - // General - 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." ), - - // 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", "Internal messages from VScript not produced by actual scripts." ), - DEFINE_CON_GROUP( CON_GROUP_VSCRIPT_PRINT, "VScript print", "Messages from VScript's 'print' function." ), - -}; - -int FindConGroup( const char *pszName ) -{ - for (int i = 0; i < CON_GROUP_MAX; i++) - { - 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" ); - - pGroupRoot->LoadFromFile( filesystem, pszFileName, pathID ); - - KeyValues *pGroup = NULL; - for ( pGroup = pGroupRoot->GetFirstTrueSubKey(); pGroup; pGroup = pGroup->GetNextTrueSubKey() ) - { - int index = FindConGroup( pGroup->GetName() ); - if (index != -1) - { - Color msgClr = pGroup->GetColor( "MessageColor" ); - - // Make sure the color isn't 0,0,0,0 before assigning - if (msgClr.GetRawColor() != 0) - g_ConGroups[index]._clr = msgClr; - - 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++) - { - ConColorMsg( g_ConGroups[i].GetColor(), " # %s", g_ConGroups[i].pszName ); - - if (g_ConGroups[i].bDisabled) - Msg(" [DISABLED]"); - - Msg( " - %s ", g_ConGroups[i].pszDescription ); - - Msg("\n"); - } - Msg( "============================================================\n" ); -} - -void ToggleConsoleGroups( const char *pszQuery ) -{ - bool bMatched = false; - - for (int i = 0; i < ARRAYSIZE( g_ConGroups ); i++) - { - 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; - bMatched = true; - } - } - - if (!bMatched) - Msg( "No groups matching \"%s\"\n", pszQuery ); -} - -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)) - return; - - char string[ 2048 ]; - va_list argptr; - va_start( argptr, pMsg ); - Q_vsnprintf( string, sizeof(string), pMsg, argptr ); - va_end( argptr ); - - Assert( nGroup >= 0 ); - Assert( nGroup < CON_GROUP_MAX ); - - ConGroup_t *pGroup = &g_ConGroups[nGroup]; - - if (pGroup->bDisabled) - { - // Do nothing - } - else if (g_bIncludeConGroupNames) - { - ConColorMsg(level, pGroup->GetColor(), "[%s] %s", pGroup->pszName, string); - } - else - { - ConColorMsg(level, pGroup->GetColor(), "%s", string); - } -} diff --git a/src/tier1/tier1.vpc b/src/tier1/tier1.vpc index f9eebdd22ce..42df4abfa1e 100644 --- a/src/tier1/tier1.vpc +++ b/src/tier1/tier1.vpc @@ -82,7 +82,6 @@ $Project "tier1" $File "snappy.cpp" $File "snappy-sinksource.cpp" $File "snappy-stubs-internal.cpp" - $File "mapbase_con_groups.cpp" [$MAPBASE] $File "mapbase_matchers_base.cpp" [$MAPBASE] } diff --git a/src/utils/vbsp/vbsp.vpc b/src/utils/vbsp/vbsp.vpc index 3cbb69b4541..72d4f00b364 100644 --- a/src/utils/vbsp/vbsp.vpc +++ b/src/utils/vbsp/vbsp.vpc @@ -77,6 +77,8 @@ $Project "VBSP" $File "vscript_funcs_vmfs.h" [$MAPBASE_VSCRIPT] $File "vscript_funcs_vis.cpp" [$MAPBASE_VSCRIPT] $File "vscript_funcs_vis.h" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\common\mapbase_con_groups.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\common\mapbase_con_groups.h" [$MAPBASE_VSCRIPT] $Folder "Common Files" { diff --git a/src/vscript/vscript_squirrel.cpp b/src/vscript/vscript_squirrel.cpp index 4084a52b71e..96c54bc7971 100644 --- a/src/vscript/vscript_squirrel.cpp +++ b/src/vscript/vscript_squirrel.cpp @@ -36,8 +36,8 @@ #include "sqdbg.h" #include "tier1/utlbuffer.h" -#include "tier1/mapbase_con_groups.h" #include "tier1/convar.h" +#include "mapbase_con_groups.h" #include "vscript_squirrel.nut" From d53ce21d5ffaadcdfe489099fadd189860218585 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Mon, 9 Nov 2026 23:33:13 -0600 Subject: [PATCH 4/7] Refactor mapbase_shared.cpp and its dependent code --- src/game/client/client_mapbase.vpc | 1 + .../client/mapbase/mapbase_autocubemap.cpp | 6 +- src/game/server/ai_networkmanager.cpp | 5 +- src/game/server/gameinterface.cpp | 6 +- src/game/server/gameinterface.h | 17 - src/game/server/server_mapbase.vpc | 1 + src/game/shared/mapbase/mapbase_shared.cpp | 962 ++++++++---------- src/game/shared/mapbase/mapbase_shared.h | 168 +++ src/game/shared/weapon_parse.cpp | 12 +- 9 files changed, 593 insertions(+), 585 deletions(-) create mode 100644 src/game/shared/mapbase/mapbase_shared.h diff --git a/src/game/client/client_mapbase.vpc b/src/game/client/client_mapbase.vpc index 4ac36dee9b0..22285799dd5 100644 --- a/src/game/client/client_mapbase.vpc +++ b/src/game/client/client_mapbase.vpc @@ -41,6 +41,7 @@ $Project $Folder "Mapbase" { $File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_shared.h" $File "$SRCDIR\game\shared\mapbase\mapbase_usermessages.cpp" $File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp" $File "$SRCDIR\game\shared\mapbase\MapEdit.cpp" diff --git a/src/game/client/mapbase/mapbase_autocubemap.cpp b/src/game/client/mapbase/mapbase_autocubemap.cpp index 79f2497d96a..e5a247c9cd6 100644 --- a/src/game/client/mapbase/mapbase_autocubemap.cpp +++ b/src/game/client/mapbase/mapbase_autocubemap.cpp @@ -21,8 +21,6 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -extern const char *g_MapName; - ConVar autocubemap_hdr_do_both( "autocubemap_hdr_do_both", "1" ); ConVar autocubemap_hdr_value( "autocubemap_hdr_value", "2" ); @@ -132,7 +130,7 @@ class CAutoCubemapSystem : public CAutoGameSystem } // Just do this map - m_AutoCubemapMaps.AddToTail( strdup( g_MapName ) ); + m_AutoCubemapMaps.AddToTail( strdup( MapName() ) ); } if (autocubemap_hdr_do_both.GetBool()) @@ -145,7 +143,7 @@ class CAutoCubemapSystem : public CAutoGameSystem m_bAutoCubemapActive = true; m_AutoCubemapMapsIndex = 0; - if (FStrEq( m_AutoCubemapMaps[m_AutoCubemapMapsIndex], g_MapName )) + if (FStrEq( m_AutoCubemapMaps[m_AutoCubemapMapsIndex], MapName() )) { // Build cubemaps right here, right now m_bAutoCubemapBuildingCubemaps = true; diff --git a/src/game/server/ai_networkmanager.cpp b/src/game/server/ai_networkmanager.cpp index 1388a919063..124d76d0b8a 100644 --- a/src/game/server/ai_networkmanager.cpp +++ b/src/game/server/ai_networkmanager.cpp @@ -26,7 +26,7 @@ #include "ai_hint.h" #include "tier0/icommandline.h" #ifdef MAPBASE -#include "gameinterface.h" +#include "mapbase/mapbase_shared.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -76,9 +76,6 @@ ConVar g_ai_norebuildgraph( "ai_norebuildgraph", "0" ); ConVar g_ai_norebuildgraphmessage( "ai_norebuildgraphmessage", "0", FCVAR_ARCHIVE, "Stops the \"Node graph out of date\" message from appearing when rebuilding node graph" ); ConVar g_ai_norebuildgraph_if_in_chapters( "ai_norebuildgraph_if_in_chapters", "0", FCVAR_NONE, "Ignores rebuilding nodegraph if it's in chapters.txt. This allows for bypassing problems with Steam rebuilding nodegraphs in a mod's main maps without affecting custom maps." ); - -extern CUtlVector *Mapbase_GetChapterMaps(); -extern CUtlVector *Mapbase_GetChapterList(); #endif diff --git a/src/game/server/gameinterface.cpp b/src/game/server/gameinterface.cpp index 76c75b9fd30..7e8a7a24cd5 100644 --- a/src/game/server/gameinterface.cpp +++ b/src/game/server/gameinterface.cpp @@ -92,6 +92,7 @@ #include "player_voice_listener.h" #ifdef MAPBASE #include "world.h" +#include "mapbase/mapbase_shared.h" #endif #include "vscript/ivscript.h" @@ -1772,11 +1773,6 @@ static TITLECOMMENT gTitleComments[] = #endif }; -#ifdef MAPBASE -extern CUtlVector *Mapbase_GetChapterMaps(); -extern CUtlVector *Mapbase_GetChapterList(); -#endif - #ifdef _XBOX void CServerGameDLL::GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ) { diff --git a/src/game/server/gameinterface.h b/src/game/server/gameinterface.h index 5c94d38ab62..17a24069d17 100644 --- a/src/game/server/gameinterface.h +++ b/src/game/server/gameinterface.h @@ -232,22 +232,5 @@ class CServerGameTags : public IServerGameTags }; EXPOSE_SINGLE_INTERFACE( CServerGameTags, IServerGameTags, INTERFACEVERSION_SERVERGAMETAGS ); -#ifdef MAPBASE -// -// Dynamic mod-based mod title comments -// -typedef struct -{ - char pBSPName[64]; - char pTitleName[64]; -} MODTITLECOMMENT; - -typedef struct -{ - int iChapter; - char pChapterName[64]; -} MODCHAPTER; -#endif - #endif // GAMEINTERFACE_H diff --git a/src/game/server/server_mapbase.vpc b/src/game/server/server_mapbase.vpc index 887aeeefe09..312ace5756a 100644 --- a/src/game/server/server_mapbase.vpc +++ b/src/game/server/server_mapbase.vpc @@ -39,6 +39,7 @@ $Project $Folder "Mapbase" { $File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_shared.h" $File "$SRCDIR\game\shared\mapbase\mapbase_usermessages.cpp" $File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp" $File "$SRCDIR\game\shared\mapbase\MapEdit.cpp" diff --git a/src/game/shared/mapbase/mapbase_shared.cpp b/src/game/shared/mapbase/mapbase_shared.cpp index d79388f5c3d..c749728dbd3 100644 --- a/src/game/shared/mapbase/mapbase_shared.cpp +++ b/src/game/shared/mapbase/mapbase_shared.cpp @@ -8,10 +8,9 @@ #include "cbase.h" +#include "mapbase_shared.h" #include "tier0/icommandline.h" -#include "tier1/mapbase_con_groups.h" -#include "igamesystem.h" -#include "filesystem.h" +#include "tier1/mapbase_matchers_base.h" #include #include #include "saverestore_utlvector.h" @@ -38,28 +37,52 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -#define GENERIC_MANIFEST_FILE "scripts/mapbase_default_manifest.txt" +//----------------------------------------------------------------------------- +// Mod Data +//----------------------------------------------------------------------------- #ifdef CLIENT_DLL -#define AUTOLOADED_MANIFEST_FILE VarArgs("maps/%s_manifest.txt", g_MapName) +// This constant should change with each Mapbase update +ConVar mapbase_version_client( "mapbase_version_client", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's client.dll" ); #else -#define AUTOLOADED_MANIFEST_FILE UTIL_VarArgs("maps/%s_manifest.txt", g_MapName) +// This constant should change with each Mapbase update +ConVar mapbase_version( "mapbase_version", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's server.dll" ); +#endif + +// The game's name found in gameinfo.txt. Mostly used for Discord RPC. +char g_iszGameName[128]; + +#ifdef GAME_DLL +// Default player configuration +char g_szDefaultPlayerModel[MAX_PATH]; +bool g_bDefaultPlayerLegs; +bool g_bDefaultPlayerDrawExternally; + +char g_szDefaultHandsModel[MAX_PATH]; +int g_iDefaultHandsSkin; +int g_iDefaultHandsBody; + +#ifdef HL2_DLL +// See protagonist_system.h +char g_szDefaultProtagonist[MAX_PROTAGONIST_NAME]; +#endif #endif +//----------------------------------------------------------------------------- +// Map-Specific File Manifests +//----------------------------------------------------------------------------- + +#define GENERIC_MANIFEST_FILE "scripts/mapbase_default_manifest.txt" + const char *g_MapName; extern ISoundEmitterSystemBase *soundemitterbase; -ConVar mapbase_load_default_manifest("mapbase_load_default_manifest", "1", FCVAR_ARCHIVE, "Should we automatically load our default manifest file? (\"maps/%mapname%_manifest.txt\")"); - #ifdef GAME_DLL -// This constant should change with each Mapbase update -ConVar mapbase_version( "mapbase_version", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's server.dll" ); +ConVar mapbase_load_default_manifest( "mapbase_load_default_manifest", "1", FCVAR_NONE, "Should we automatically load our default manifest file? (\"maps/%mapname%_manifest.txt\")" ); ConVar mapbase_flush_talker("mapbase_flush_talker", "1", FCVAR_NONE, "Normally, when a map with custom talker files is unloaded, the response system resets to rid itself of the custom file(s). Turn this convar off to prevent that from happening."); -extern void MapbaseGameLog_Init(); - #ifdef HL2_DLL extern void ParseCustomActbusyFile(const char *file); #endif @@ -70,8 +93,7 @@ extern void ReloadResponseSystem(); // Reloads the response system when the map changes to avoid custom talker leaking static bool g_bMapContainsCustomTalker; #else -// This constant should change with each Mapbase update -ConVar mapbase_version_client( "mapbase_version_client", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's client.dll" ); +ConVar mapbase_load_default_manifest( "mapbase_load_default_manifest_client", "1", FCVAR_NONE, "Should we automatically load our default manifest file? (\"maps/%mapname%_manifest.txt\")" ); // This is from the vgui_controls library extern vgui::HScheme g_iCustomClientSchemeOverride; @@ -82,646 +104,503 @@ bool g_bUsingCustomHudLayout = false; extern void AddSurfacepropFile( const char *pFileName, IPhysicsSurfaceProps *pProps, IFileSystem *pFileSystem ); -// Indicates this is a core Mapbase mod and not a mod using its code. -static bool g_bMapbaseCore; +//----------------------------------------------------------------------------- -// The game's name found in gameinfo.txt. Mostly used for Discord RPC. -char g_iszGameName[128]; +CMapbaseSystem g_MapbaseSystem; -#ifdef GAME_DLL -// Default player configuration -char g_szDefaultPlayerModel[MAX_PATH]; -bool g_bDefaultPlayerLegs; -bool g_bDefaultPlayerDrawExternally; +BEGIN_DATADESC_NO_BASE( CMapbaseSystem ) -char g_szDefaultHandsModel[MAX_PATH]; -int g_iDefaultHandsSkin; -int g_iDefaultHandsBody; + //DEFINE_UTLVECTOR( m_StoredManifestFiles, FIELD_STRING ), -#ifdef HL2_DLL -// See protagonist_system.h -char g_szDefaultProtagonist[MAX_PROTAGONIST_NAME]; -#endif -#endif +END_DATADESC() -enum -{ - MANIFEST_SOUNDSCRIPTS, - //MANIFEST_PROPDATA, - //MANIFEST_SOUNDSCAPES, - MANIFEST_LOCALIZATION, - MANIFEST_SURFACEPROPS, -#ifdef CLIENT_DLL - MANIFEST_CLOSECAPTION, - MANIFEST_VGUI, - MANIFEST_CLIENTSCHEME, - MANIFEST_HUDANIMATIONS, - MANIFEST_HUDLAYOUT, -#else - MANIFEST_TALKER, - MANIFEST_CHOREOSENTENCES, - MANIFEST_ACTBUSY, -#endif #ifdef MAPBASE_VSCRIPT - MANIFEST_VSCRIPT, -#endif -#if defined(HL2_DLL) || defined(HL2_CLIENT_DLL) - MANIFEST_PROTAGONISTS, // See protagonist_system.h -#endif - - // Must always be kept below - MANIFEST_NUM_TYPES, -}; - -struct ManifestType_t -{ - ManifestType_t( const char *_string, const char *cvarname, const char *cvardesc ) : cvar( cvarname, "1", FCVAR_ARCHIVE, cvardesc ) - { - string = _string; - } - - //int type; - const char *string; - ConVar cvar; -}; - -#define DECLARE_MANIFEST_TYPE(name, cvar, desc) { #name, ConVar(#cvar, "1", FCVAR_ARCHIVE, #desc) } +BEGIN_SCRIPTDESC_ROOT( CMapbaseSystem, SCRIPT_SINGLETON "All-purpose Mapbase system primarily used for map-specific files." ) -// KEEP THS IN SYNC WITH THE ENUM! -static const ManifestType_t gm_szManifestFileStrings[MANIFEST_NUM_TYPES] = { - { "soundscripts", "mapbase_load_soundscripts", "Should we load map-specific soundscripts? e.g. \"maps/_level_sounds.txt\"" }, - //{ "propdata", "mapbase_load_propdata", "Should we load map-specific soundscripts? e.g. \"maps/_level_sounds.txt\"" }, - //{ "soundscapes", "mapbase_load_soundscapes", "Should we load map-specific soundscapes? e.g. \"maps/_soundscapes.txt\"" }, - { "localization", "mapbase_load_localization", "Should we load map-specific localized text files? e.g. \"maps/_english.txt\"" }, - { "surfaceprops", "mapbase_load_surfaceprops", "Should we load map-specific surfaceproperties files? e.g. \"maps/_surfaceproperties.txt\"" }, + DEFINE_SCRIPTFUNC_NAMED( ScriptAddManifestFile, "AddManifestFile", "Loads a manifest file." ) + DEFINE_SCRIPTFUNC( LoadCustomSoundscriptFile, "Loads a custom soundscript file." ) + DEFINE_SCRIPTFUNC( LoadCustomLocalizationFile, "Loads a custom localization file." ) + DEFINE_SCRIPTFUNC( LoadCustomSurfacePropsFile, "Loads a custom surface properties file." ) #ifdef CLIENT_DLL - { "closecaption", "mapbase_load_closecaption", "Should we load map-specific closed captioning? e.g. \"maps/_closecaption_english.txt\" and \"maps/_closecaption_english.dat\"" }, - { "vgui", "mapbase_load_vgui", "Should we load map-specific VGUI screens? e.g. \"maps/_screens.txt\"" }, - { "clientscheme", "mapbase_load_clientscheme", "Should we load map-specific ClientScheme.res overrides? e.g. \"maps/_clientscheme.res\"" }, - { "hudanimations", "mapbase_load_hudanimations", "Should we load map-specific HUD animation overrides? e.g. \"maps/_hudanimations.txt\"" }, - { "hudlayout", "mapbase_load_hudlayout", "Should we load map-specific HUD layout overrides? e.g. \"maps/_hudlayout.res\"" }, + DEFINE_SCRIPTFUNC( LoadCustomCloseCaptionFile, "Loads a custom closed captions file." ) + DEFINE_SCRIPTFUNC( LoadCustomVGUIFile, "Loads a custom VGUI definitions file." ) + DEFINE_SCRIPTFUNC( LoadCustomClientSchemeFile, "Loads a custom ClientScheme.res override file." ) + DEFINE_SCRIPTFUNC( LoadCustomHUDAnimationsFile, "Loads a custom HUD animations override file." ) + DEFINE_SCRIPTFUNC( LoadCustomHUDLayoutFile, "Loads a custom HUD layout override file." ) #else - { "talker", "mapbase_load_talker", "Should we load map-specific talker files? e.g. \"maps/_talker.txt\"" }, - { "choreosentences", "mapbase_load_choreosentences", "Should we load map-specific choreo sentences? e.g. \"maps/_choreosentences.txt\"" }, - { "actbusy", "mapbase_load_actbusy", "Should we load map-specific actbusy files? e.g. \"maps/_actbusy.txt\"" }, + DEFINE_SCRIPTFUNC( LoadCustomTalkerFile, "Loads a custom talker file." ) + DEFINE_SCRIPTFUNC( LoadCustomActbusyFile, "Loads a custom actbusy file." ) + DEFINE_SCRIPTFUNC( LoadCustomChoreoSentenceFile, "Loads a custom choreo sentence file." ) #endif -#ifdef MAPBASE_VSCRIPT - { "vscript", "mapbase_load_vscript", "Should we load map-specific VScript map spawn files? e.g. \"maps/_mapspawn.nut\"" }, + + DEFINE_SCRIPTFUNC( GetModName, "Gets the name of the mod. This is the name which shows up on Steam, RPC, etc." ) + + // Legacy + DEFINE_SCRIPTFUNC_NAMED( LoadCustomSoundscriptFile, "LoadSoundscriptFile", SCRIPT_HIDE ) +#ifndef CLIENT_DLL + DEFINE_SCRIPTFUNC_NAMED( LoadCustomTalkerFile, "LoadTalkerFile", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( LoadCustomActbusyFile, "LoadActbusyFile", SCRIPT_HIDE ) #endif -#if defined(HL2_DLL) || defined(HL2_CLIENT_DLL) - { "protagonists", "mapbase_load_protagonists", "Should we load map-specific protagonist files? e.g. \"maps/_protagonists.txt\"" }, + +END_SCRIPTDESC(); #endif -}; //----------------------------------------------------------------------------- -// Purpose: System used to load map-specific files, etc. -//----------------------------------------------------------------------------- -class CMapbaseSystem : public CAutoGameSystem -{ -public: - DECLARE_DATADESC(); - - CMapbaseSystem() : CAutoGameSystem( "CMapbaseSystem" ) - { - } - inline bool GetGameInfoKeyValues(KeyValues *pKeyValues) - { - return pKeyValues->LoadFromFile( filesystem, "gameinfo.txt", "MOD" ); - } +bool CMapbaseSystem::Init() +{ + InitConsoleGroups( g_pFullFileSystem, &g_GameConGroups ); - virtual bool Init() + // Checks gameinfo.txt for additional command line options + KeyValues *gameinfo = new KeyValues("GameInfo"); + if (GetGameInfoKeyValues(gameinfo)) { - InitConsoleGroups( g_pFullFileSystem ); - - // Checks gameinfo.txt for additional command line options - KeyValues *gameinfo = new KeyValues("GameInfo"); - if (GetGameInfoKeyValues(gameinfo)) + KeyValues *pCommandLineList = gameinfo->FindKey("CommandLine", false); + if (pCommandLineList) { - KeyValues *pCommandLineList = gameinfo->FindKey("CommandLine", false); - if (pCommandLineList) + for (KeyValues *pKey = pCommandLineList->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey()) { - for (KeyValues *pKey = pCommandLineList->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey()) - { - CommandLine()->AppendParm( pKey->GetName(), pKey->GetString() ); - } + CommandLine()->AppendParm( pKey->GetName(), pKey->GetString() ); } } - gameinfo->deleteThis(); + } + gameinfo->deleteThis(); #ifdef CLIENT_DLL - InitializeRTs(); + InitializeRTs(); - // Shared Mapbase scripts to avoid overwriting mod files - g_pVGuiLocalize->AddFile( "resource/mapbase_%language%.txt" ); + // Shared Mapbase scripts to avoid overwriting mod files + g_pVGuiLocalize->AddFile( "resource/mapbase_%language%.txt" ); #ifdef HL2_CLIENT_DLL - g_pVGuiLocalize->AddFile( "resource/mapbase_hl2_%language%.txt" ); + g_pVGuiLocalize->AddFile( "resource/mapbase_hl2_%language%.txt" ); #endif #ifdef TF_CLIENT_DLL - g_pVGuiLocalize->AddFile( "resource/mapbase_tf_%language%.txt" ); + g_pVGuiLocalize->AddFile( "resource/mapbase_tf_%language%.txt" ); #endif #endif + return true; +} - return true; - } +//----------------------------------------------------------------------------- - void RefreshCustomTalker() - { +void CMapbaseSystem::LevelInitPreEntity() +{ #ifdef GAME_DLL - if (g_bMapContainsCustomTalker && mapbase_flush_talker.GetBool()) - { - CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Mapbase: Reloading response system to flush custom talker\n" ); - ReloadResponseSystem(); - g_bMapContainsCustomTalker = false; - } + CGMsg( 0, ConGroup_MapbaseMisc, "Mapbase system loaded (v%s)\n", MAPBASE_VERSION ); #endif - } - virtual void LevelInitPreEntity() + // Checks gameinfo.txt for Mapbase-specific options + KeyValues *gameinfo = new KeyValues("GameInfo"); + if (GetGameInfoKeyValues(gameinfo)) { -#ifdef GAME_DLL - CGMsg( 0, CON_GROUP_MAPBASE_MISC, "Mapbase system loaded\n" ); -#endif + // Indicates this is a core Mapbase mod and not a mod using its code + //g_bMapbaseCore = gameinfo->GetBool("mapbase_core", false); - // Checks gameinfo.txt for Mapbase-specific options - KeyValues *gameinfo = new KeyValues("GameInfo"); - if (GetGameInfoKeyValues(gameinfo)) + if (!gameinfo->GetBool("hide_mod_name", false)) { - // Indicates this is a core Mapbase mod and not a mod using its code - g_bMapbaseCore = gameinfo->GetBool("mapbase_core", false); + // Store the game's name + const char *pszGameName = gameinfo->GetString("game_rpc", NULL); + if (pszGameName == NULL) + pszGameName = gameinfo->GetString("game"); - if (!gameinfo->GetBool("hide_mod_name", false)) - { - // Store the game's name - const char *pszGameName = gameinfo->GetString("game_rpc", NULL); - if (pszGameName == NULL) - pszGameName = gameinfo->GetString("game"); - - Q_strncpy(g_iszGameName, pszGameName, sizeof(g_iszGameName)); - } + Q_strncpy(g_iszGameName, pszGameName, sizeof(g_iszGameName)); + } #ifdef GAME_DLL - Q_strncpy( g_szDefaultPlayerModel, gameinfo->GetString( "player_default_model", "models/player.mdl" ), sizeof( g_szDefaultPlayerModel ) ); - g_bDefaultPlayerLegs = gameinfo->GetBool( "player_default_legs", false ); - g_bDefaultPlayerDrawExternally = gameinfo->GetBool( "player_default_draw_externally", false ); + Q_strncpy( g_szDefaultPlayerModel, gameinfo->GetString( "player_default_model", "models/player.mdl" ), sizeof( g_szDefaultPlayerModel ) ); + g_bDefaultPlayerLegs = gameinfo->GetBool( "player_default_legs", false ); + g_bDefaultPlayerDrawExternally = gameinfo->GetBool( "player_default_draw_externally", false ); - Q_strncpy( g_szDefaultHandsModel, gameinfo->GetString( "player_default_hands", "models/weapons/v_hands.mdl" ), sizeof( g_szDefaultHandsModel ) ); - g_iDefaultHandsSkin = gameinfo->GetInt( "player_default_hands_skin", 0 ); - g_iDefaultHandsBody = gameinfo->GetInt( "player_default_hands_body", 0 ); + Q_strncpy( g_szDefaultHandsModel, gameinfo->GetString( "player_default_hands", "models/weapons/v_hands.mdl" ), sizeof( g_szDefaultHandsModel ) ); + g_iDefaultHandsSkin = gameinfo->GetInt( "player_default_hands_skin", 0 ); + g_iDefaultHandsBody = gameinfo->GetInt( "player_default_hands_body", 0 ); #ifdef HL2_DLL - Q_strncpy( g_szDefaultProtagonist, gameinfo->GetString( "player_default_protagonist", "" ), sizeof( g_szDefaultProtagonist ) ); + Q_strncpy( g_szDefaultProtagonist, gameinfo->GetString( "player_default_protagonist", "" ), sizeof( g_szDefaultProtagonist ) ); #endif #endif - } - gameinfo->deleteThis(); - - RefreshMapName(); + } + gameinfo->deleteThis(); - // Shared Mapbase scripts to avoid overwriting mod files + // Shared Mapbase scripts to avoid overwriting mod files #ifdef CLIENT_DLL - PanelMetaClassMgr()->LoadMetaClassDefinitionFile( "scripts/vgui_screens_mapbase.txt" ); + PanelMetaClassMgr()->LoadMetaClassDefinitionFile( "scripts/vgui_screens_mapbase.txt" ); #endif - } - virtual void OnRestore() - { - RefreshMapName(); - } + if ( m_iManifestFileSymbols[0] == -1 ) + InitManifestFileSymbols(); +} - virtual void LevelInitPostEntity() - { - // Check for a generic "mapname_manifest.txt" file and load it. - if (filesystem->FileExists( AUTOLOADED_MANIFEST_FILE, "GAME" )) - { - AddManifestFile( AUTOLOADED_MANIFEST_FILE ); - } - else - { - // Load the generic script instead. - ParseGenericManifest(); - } +//----------------------------------------------------------------------------- -#ifdef GAME_DLL - MapbaseGameLog_Init(); -#endif - } +void CMapbaseSystem::LevelInitPostEntity() +{ + // Load the generic script. + ParseGenericManifest(); +} + +void CMapbaseSystem::LevelShutdownPreEntity() +{ + // How would we make sure they don't last between maps? + // TODO: Investigate ReloadLocalizationFiles() + //g_pVGuiLocalize->RemoveAll(); + //g_pVGuiLocalize->ReloadLocalizationFiles(); +} + +void CMapbaseSystem::LevelShutdownPostEntity() +{ + RefreshCustomTalker(); - virtual void LevelShutdownPreEntity() +#ifdef CLIENT_DLL + CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption ); + FOR_EACH_VEC( m_CloseCaptionFileNames, i ) { - // How would we make sure they don't last between maps? - // TODO: Investigate ReloadLocalizationFiles() - //g_pVGuiLocalize->RemoveAll(); - //g_pVGuiLocalize->ReloadLocalizationFiles(); + hudCloseCaption->RemoveCaptionDictionary( m_CloseCaptionFileNames[i] ); } + m_CloseCaptionFileNames.RemoveAll(); - virtual void LevelShutdownPostEntity() + if (g_iCustomClientSchemeOverride != 0 || g_bUsingCustomHudAnimations || g_bUsingCustomHudLayout) { - g_MapName = NULL; + CGMsg( 1, ConGroup_MapbaseMisc, "Mapbase: Reloading client mode and viewport scheme\n" ); - RefreshCustomTalker(); + // TODO: We currently have no way of actually cleaning up custom schemes upon level unload. + // That may or may not be sustainable if there's a ton of custom schemes loaded at once + g_iCustomClientSchemeOverride = 0; -#ifdef CLIENT_DLL - CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption ); - FOR_EACH_VEC( m_CloseCaptionFileNames, i ) - { - hudCloseCaption->RemoveCaptionDictionary( m_CloseCaptionFileNames[i] ); - } - m_CloseCaptionFileNames.RemoveAll(); + g_bUsingCustomHudAnimations = false; + g_bUsingCustomHudLayout = false; - if (g_iCustomClientSchemeOverride != 0 || g_bUsingCustomHudAnimations || g_bUsingCustomHudLayout) + // Reload scheme + ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal(); + if ( mode ) { - CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Mapbase: Reloading client mode and viewport scheme\n" ); - - // TODO: We currently have no way of actually cleaning up custom schemes upon level unload. - // That may or may not be sustainable if there's a ton of custom schemes loaded at once - g_iCustomClientSchemeOverride = 0; - - g_bUsingCustomHudAnimations = false; - g_bUsingCustomHudLayout = false; + mode->ReloadScheme( true ); - // Reload scheme - ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal(); - if ( mode ) + // We need to reload default values, so load a special "hudlayout_mapbase.res" file that only contains + // default Mapbase definitions identical to the defaults in the code + CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); + if (pViewport) { - mode->ReloadScheme( true ); - - // We need to reload default values, so load a special "hudlayout_mapbase.res" file that only contains - // default Mapbase definitions identical to the defaults in the code - CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); - if (pViewport) - { - KeyValuesAD pConditions( "conditions" ); - g_pClientMode->ComputeVguiResConditions( pConditions ); + KeyValuesAD pConditions( "conditions" ); + g_pClientMode->ComputeVguiResConditions( pConditions ); - // reload the .res file from disk - pViewport->LoadControlSettings( "scripts/hudlayout_mapbase.res", NULL, NULL, pConditions ); - } + // reload the .res file from disk + pViewport->LoadControlSettings( "scripts/hudlayout_mapbase.res", NULL, NULL, pConditions ); } } -#endif } - - bool RefreshMapName() - { -#ifdef GAME_DLL - const char *pszMapName = STRING(gpGlobals->mapname); -#else - //char mapname[128]; - //Q_StripExtension(MapName(), mapname, sizeof(mapname)); - const char *pszMapName = MapName(); #endif +} - if (g_MapName == NULL || !FStrEq(pszMapName, g_MapName)) - { - g_MapName = pszMapName; - return true; - } +//----------------------------------------------------------------------------- - return false; +void CMapbaseSystem::RefreshCustomTalker() +{ +#ifdef GAME_DLL + if (g_bMapContainsCustomTalker && mapbase_flush_talker.GetBool()) + { + CGMsg( 1, ConGroup_MapbaseMisc, "Mapbase: Reloading response system to flush custom talker\n" ); + ReloadResponseSystem(); + g_bMapContainsCustomTalker = false; } +#endif +} #ifdef CLIENT_DLL - //----------------------------------------------------------------------------- - // Initialize custom RT textures if necessary - //----------------------------------------------------------------------------- - void InitializeRTs() +//----------------------------------------------------------------------------- +// Initialize custom RT textures if necessary +//----------------------------------------------------------------------------- +void CMapbaseSystem::InitializeRTs() +{ + if (!m_bInitializedRTs) { - if (!m_bInitializedRTs) - { - int iNumCameras = CommandLine()->ParmValue( "-numcameratextures", 3 ); + int iNumCameras = CommandLine()->ParmValue( "-numcameratextures", 3 ); - materials->BeginRenderTargetAllocation(); + materials->BeginRenderTargetAllocation(); - for (int i = 0; i < iNumCameras; i++) - { - char szName[32]; - Q_snprintf( szName, sizeof(szName), "_rt_Camera%i", i ); - - int iRefIndex = m_CameraTextures.AddToTail(); - - //m_CameraTextures[iRefIndex].InitRenderTarget( - // 256, 256, RT_SIZE_DEFAULT, - // g_pMaterialSystem->GetBackBufferFormat(), - // MATERIAL_RT_DEPTH_SHARED, true, szName ); - - m_CameraTextures[iRefIndex].Init( g_pMaterialSystem->CreateNamedRenderTargetTextureEx2( - szName, - 256, 256, RT_SIZE_DEFAULT, - g_pMaterialSystem->GetBackBufferFormat(), - MATERIAL_RT_DEPTH_SHARED, - 0, - CREATERENDERTARGETFLAGS_HDR ) ); - } + for (int i = 0; i < iNumCameras; i++) + { + char szName[32]; + Q_snprintf( szName, sizeof(szName), "_rt_Camera%i", i ); + + int iRefIndex = m_CameraTextures.AddToTail(); + + //m_CameraTextures[iRefIndex].InitRenderTarget( + // 256, 256, RT_SIZE_DEFAULT, + // g_pMaterialSystem->GetBackBufferFormat(), + // MATERIAL_RT_DEPTH_SHARED, true, szName ); + + m_CameraTextures[iRefIndex].Init( g_pMaterialSystem->CreateNamedRenderTargetTextureEx2( + szName, + 256, 256, RT_SIZE_DEFAULT, + g_pMaterialSystem->GetBackBufferFormat(), + MATERIAL_RT_DEPTH_SHARED, + 0, + CREATERENDERTARGETFLAGS_HDR ) ); + } - materials->EndRenderTargetAllocation(); + materials->EndRenderTargetAllocation(); - m_bInitializedRTs = true; - } + m_bInitializedRTs = true; } +} - void Shutdown() +void CMapbaseSystem::Shutdown() +{ + if (m_bInitializedRTs) { - if (m_bInitializedRTs) + for (int i = 0; i < m_CameraTextures.Count(); i++) { - for (int i = 0; i < m_CameraTextures.Count(); i++) - { - m_CameraTextures[i].Shutdown(); - } - m_bInitializedRTs = false; + m_CameraTextures[i].Shutdown(); } + m_bInitializedRTs = false; } +} #endif - // Get a generic, hardcoded manifest with hardcoded names. - void ParseGenericManifest() - { - if (!mapbase_load_default_manifest.GetBool()) - return; +// Get a generic, hardcoded manifest with hardcoded names. +void CMapbaseSystem::ParseGenericManifest() +{ + if (!mapbase_load_default_manifest.GetBool()) + return; - KeyValues *pKV = new KeyValues("DefaultManifest"); - pKV->LoadFromFile(filesystem, GENERIC_MANIFEST_FILE); + KeyValues *pKV = new KeyValues("DefaultManifest"); + pKV->LoadFromFile(filesystem, GENERIC_MANIFEST_FILE); - AddManifestFile(pKV, g_MapName/*, true*/); + AddManifestFile(pKV, MapNameNoExt()/*, true*/); - pKV->deleteThis(); - } - - void AddManifestFile( const char *file ) - { - KeyValues *pKV = new KeyValues(file); - if ( !pKV->LoadFromFile( filesystem, file ) ) - { - Warning("Mapbase Manifest: \"%s\" is unreadable or missing (can't load KV, check for syntax errors)\n", file); - pKV->deleteThis(); - return; - } + pKV->deleteThis(); +} - CGMsg( 1, CON_GROUP_MAPBASE_MISC, "===== Mapbase Manifest: Loading manifest file %s =====\n", file ); +inline HKeySymbol AddKeySymbolForName( const char *pszName ) +{ + return KeyValuesSystem()->GetSymbolForString( pszName ); +} - AddManifestFile(pKV, g_MapName, false); +void CMapbaseSystem::InitManifestFileSymbols() +{ + // Keep in sync with the enum + const char *szManifestFileStrings[MANIFEST_NUM_TYPES] = { + "soundscripts", + //"propdata", + //"soundscapes", + "localization", + "surfaceprops", +#ifdef CLIENT_DLL + "closecaption", + "vgui", + "clientscheme", + "hudanimations", + "hudlayout", +#else + "talker", + "choreosentences", + "actbusy", +#endif +#ifdef MAPBASE_VSCRIPT + "vscript", +#endif +#if defined(HL2_DLL) || defined(HL2_CLIENT_DLL) + "protagonists", +#endif + }; - CGMsg( 1, CON_GROUP_MAPBASE_MISC, "==============================================================================\n" ); + for (int i = 0; i < MANIFEST_NUM_TYPES; i++) + { + m_iManifestFileSymbols[i] = KeyValuesSystem()->GetSymbolForString( szManifestFileStrings[i] ); + } +} +void CMapbaseSystem::AddManifestFile( const char *file ) +{ + KeyValues *pKV = new KeyValues(file); + if ( !pKV->LoadFromFile( filesystem, file ) ) + { + Warning("Mapbase Manifest: \"%s\" is unreadable or missing (can't load KV, check for syntax errors)\n", file); pKV->deleteThis(); + return; } - void LoadFromValue( const char *value, int type, bool bDontWarn ) + //CGMsg( 1, ConGroup_MapbaseMisc, "===== Mapbase Manifest: Loading manifest file %s =====\n", file ); + + AddManifestFile(pKV, MapNameNoExt(), false); + + //CGMsg( 1, ConGroup_MapbaseMisc, "==============================================================================\n" ); + + pKV->deleteThis(); +} + +void CMapbaseSystem::LoadFromValue( const char *value, int type, bool bDontWarn ) +{ + if (type != MANIFEST_VSCRIPT && !filesystem->FileExists(value, "MOD")) { - if (type != MANIFEST_VSCRIPT && !filesystem->FileExists(value, "MOD")) + if (!bDontWarn) { - if (!bDontWarn) - { - Warning("Mapbase Manifest: WARNING! \"%s\" does not exist!\n", value); - } - return; + Warning("Mapbase Manifest: WARNING! \"%s\" does not exist!\n", value); } + return; + } - switch (type) - { - case MANIFEST_SOUNDSCRIPTS: { soundemitterbase->AddSoundOverrides(value); } break; - //case MANIFEST_PROPDATA: { g_PropDataSystem.ParsePropDataFile(value); } break; - case MANIFEST_LOCALIZATION: { g_pVGuiLocalize->AddFile( value, "MOD", true ); } break; - case MANIFEST_SURFACEPROPS: { AddSurfacepropFile( value, physprops, filesystem ); } break; + switch (type) + { + case MANIFEST_SOUNDSCRIPTS: { soundemitterbase->AddSoundOverrides(value); } break; + //case MANIFEST_PROPDATA: { g_PropDataSystem.ParsePropDataFile(value); } break; + case MANIFEST_LOCALIZATION: { g_pVGuiLocalize->AddFile( value, "MOD", true ); } break; + case MANIFEST_SURFACEPROPS: { AddSurfacepropFile( value, physprops, filesystem ); } break; #ifdef CLIENT_DLL - case MANIFEST_CLOSECAPTION: { ManifestLoadCustomCloseCaption( value ); } break; - case MANIFEST_VGUI: { PanelMetaClassMgr()->LoadMetaClassDefinitionFile( value ); } break; - case MANIFEST_CLIENTSCHEME: { ManifestLoadCustomScheme( value ); } break; - case MANIFEST_HUDANIMATIONS: { ManifestLoadCustomHudAnimations( value ); } break; - case MANIFEST_HUDLAYOUT: { ManifestLoadCustomHudLayout( value ); } break; - //case MANIFEST_SOUNDSCAPES: { Soundscape_AddFile(value); } break; + case MANIFEST_CLOSECAPTION: { ManifestLoadCustomCloseCaption( value ); } break; + case MANIFEST_VGUI: { PanelMetaClassMgr()->LoadMetaClassDefinitionFile( value ); } break; + case MANIFEST_CLIENTSCHEME: { ManifestLoadCustomScheme( value ); } break; + case MANIFEST_HUDANIMATIONS: { ManifestLoadCustomHudAnimations( value ); } break; + case MANIFEST_HUDLAYOUT: { ManifestLoadCustomHudLayout( value ); } break; + //case MANIFEST_SOUNDSCAPES: { Soundscape_AddFile(value); } break; #else - case MANIFEST_TALKER: { - g_bMapContainsCustomTalker = true; - LoadResponseSystemFile(value); //PrecacheCustomResponseSystem( value ); - } break; - //case MANIFEST_SOUNDSCAPES: { g_SoundscapeSystem.AddSoundscapeFile(value); } break; - case MANIFEST_CHOREOSENTENCES: { LoadChoreoSentenceFile(value); } break; + case MANIFEST_TALKER: { + g_bMapContainsCustomTalker = true; + LoadResponseSystemFile(value); //PrecacheCustomResponseSystem( value ); + } break; + //case MANIFEST_SOUNDSCAPES: { g_SoundscapeSystem.AddSoundscapeFile(value); } break; + case MANIFEST_CHOREOSENTENCES: { LoadChoreoSentenceFile(value); } break; #ifdef HL2_DLL - case MANIFEST_ACTBUSY: { ParseCustomActbusyFile(value); } break; + case MANIFEST_ACTBUSY: { ParseCustomActbusyFile(value); } break; #endif #endif #ifdef MAPBASE_VSCRIPT - case MANIFEST_VSCRIPT: { VScriptRunScript(value, false); } break; + case MANIFEST_VSCRIPT: { VScriptRunScript(value, false); } break; #endif #if defined(HL2_DLL) || defined(HL2_CLIENT_DLL) - case MANIFEST_PROTAGONISTS: { g_ProtagonistSystem.LoadProtagonistFile( value ); } break; + case MANIFEST_PROTAGONISTS: { g_ProtagonistSystem.LoadProtagonistFile( value ); } break; #endif - } } +} + +// This doesn't call deleteThis()! +void CMapbaseSystem::AddManifestFile(KeyValues *pKV, const char *pszMapName, bool bDontWarn) +{ + char value[MAX_PATH]; + int iNoErrorsSymbol = KeyValuesSystem()->GetSymbolForString( "NoErrors" ); - // This doesn't call deleteThis()! - void AddManifestFile(KeyValues *pKV, const char *pszMapName, bool bDontWarn = false) + for (KeyValues *pKey = pKV->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey()) { - char value[MAX_PATH]; - const char *name; - for (KeyValues *pKey = pKV->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey()) + int iNameSymbol = pKey->GetNameSymbol(); + if (iNameSymbol == iNoErrorsSymbol) + { + bDontWarn = pKey->GetBool(); + continue; + } + + value[0] = '\0'; + + // Parse %mapname%, etc. + bool inparam = false; + CUtlStringList outStrings; + V_SplitString( pKey->GetString(), "%", outStrings ); + FOR_EACH_VEC( outStrings, i ) { - value[0] = '\0'; - name = pKey->GetName(); - - // Parse %mapname%, etc. - bool inparam = false; - CUtlStringList outStrings; - V_SplitString( pKey->GetString(), "%", outStrings ); - FOR_EACH_VEC( outStrings, i ) + if (inparam) { - if (inparam) + if (FStrEq( outStrings[i], "mapname" )) + { + Q_strncat( value, pszMapName, sizeof( value ) ); + } + else if (FStrEq( outStrings[i], "language" )) { - if (FStrEq( outStrings[i], "mapname" )) - { - Q_strncat( value, pszMapName, sizeof( value ) ); - } - else if (FStrEq( outStrings[i], "language" )) - { #ifdef CLIENT_DLL - char uilanguage[64]; - engine->GetUILanguage(uilanguage, sizeof(uilanguage)); - Q_strncat( value, uilanguage, sizeof( value ) ); + char uilanguage[64]; + engine->GetUILanguage(uilanguage, sizeof(uilanguage)); + Q_strncat( value, uilanguage, sizeof( value ) ); #else - // Give up, use English - Q_strncat( value, "english", sizeof( value ) ); + // Give up, use English + Q_strncat( value, "english", sizeof( value ) ); #endif - } - } - else - { - Q_strncat( value, outStrings[i], sizeof( value ) ); } - - inparam = !inparam; } - - outStrings.PurgeAndDeleteElements(); - - if (FStrEq(name, "NoErrors")) + else { - bDontWarn = pKey->GetBool(); + Q_strncat( value, outStrings[i], sizeof( value ) ); } - for (int i = 0; i < MANIFEST_NUM_TYPES; i++) + inparam = !inparam; + } + + outStrings.PurgeAndDeleteElements(); + + for (int i = 0; i < MANIFEST_NUM_TYPES; i++) + { + if (iNameSymbol == m_iManifestFileSymbols[i]) { - if (FStrEq(name, gm_szManifestFileStrings[i].string)) - { - if (gm_szManifestFileStrings[i].cvar.GetBool()) - { - LoadFromValue(value, i, bDontWarn); - } - break; - } + LoadFromValue(value, i, bDontWarn); + break; } } } - -private: +} #ifdef CLIENT_DLL - void ManifestLoadCustomCloseCaption( const char *pszFile ) - { - if (GET_HUDELEMENT( CHudCloseCaption )) - (GET_HUDELEMENT( CHudCloseCaption ))->AddCustomCaptionFile( pszFile, m_CloseCaptionFileNames ); - } +void CMapbaseSystem::ManifestLoadCustomCloseCaption( const char *pszFile ) +{ + if (GET_HUDELEMENT( CHudCloseCaption )) + (GET_HUDELEMENT( CHudCloseCaption ))->AddCustomCaptionFile( pszFile, m_CloseCaptionFileNames ); +} - // Custom scheme loading - void ManifestLoadCustomScheme( const char *pszFile ) - { - g_iCustomClientSchemeOverride = vgui::scheme()->LoadSchemeFromFile( pszFile, "CustomClientScheme" ); +// Custom scheme loading +void CMapbaseSystem::ManifestLoadCustomScheme( const char *pszFile ) +{ + g_iCustomClientSchemeOverride = vgui::scheme()->LoadSchemeFromFile( pszFile, "CustomClientScheme" ); - // Reload scheme - ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal(); - if ( mode ) - { - mode->ReloadScheme( true ); - } + // Reload scheme + ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal(); + if ( mode ) + { + mode->ReloadScheme( true ); } +} - void ManifestLoadCustomHudAnimations( const char *pszFile ) +void CMapbaseSystem::ManifestLoadCustomHudAnimations( const char *pszFile ) +{ + CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); + if (pViewport) { - CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); - if (pViewport) + g_bUsingCustomHudAnimations = true; + if (!pViewport->LoadCustomHudAnimations( pszFile )) { - g_bUsingCustomHudAnimations = true; - if (!pViewport->LoadCustomHudAnimations( pszFile )) - { - g_bUsingCustomHudAnimations = false; - CGWarning( 0, CON_GROUP_MAPBASE_MISC, "Custom HUD animations file \"%s\" failed to load\n", pszFile ); - pViewport->ReloadHudAnimations(); - } - else - { - CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Loaded custom HUD animations file \"%s\"\n", pszFile );; - } + g_bUsingCustomHudAnimations = false; + CGWarning( 0, ConGroup_MapbaseMisc, "Custom HUD animations file \"%s\" failed to load\n", pszFile ); + pViewport->ReloadHudAnimations(); } - } - - void ManifestLoadCustomHudLayout( const char *pszFile ) - { - CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); - if (pViewport) + else { - g_bUsingCustomHudLayout = true; - - KeyValuesAD pConditions( "conditions" ); - g_pClientMode->ComputeVguiResConditions( pConditions ); - - // reload the .res file from disk - pViewport->LoadControlSettings( pszFile, NULL, NULL, pConditions ); - - CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Loaded custom HUD layout file \"%s\"\n", pszFile );; + CGMsg( 1, ConGroup_MapbaseMisc, "Loaded custom HUD animations file \"%s\"\n", pszFile );; } } -#endif - -public: - - void LoadCustomSoundscriptFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_SOUNDSCRIPTS, false ); } - void LoadCustomLocalizationFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_LOCALIZATION, false ); } - void LoadCustomSurfacePropsFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_SURFACEPROPS, false ); } -#ifdef CLIENT_DLL - void LoadCustomCloseCaptionFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CLOSECAPTION, false ); } - void LoadCustomVGUIFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_VGUI, false ); } - void LoadCustomClientSchemeFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CLIENTSCHEME, false ); } - void LoadCustomHUDAnimationsFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_HUDANIMATIONS, false ); } - void LoadCustomHUDLayoutFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_HUDLAYOUT, false ); } -#else - void LoadCustomTalkerFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_TALKER, false ); } - void LoadCustomActbusyFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_ACTBUSY, false ); } - void LoadCustomChoreoSentenceFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CHOREOSENTENCES, false ); } -#endif - - const char *GetModName() { return g_iszGameName; } - bool IsCoreMapbase() { return g_bMapbaseCore; } - -#ifdef MAPBASE_VSCRIPT - void ScriptAddManifestFile( const char *szScript ) { AddManifestFile( szScript ); } +} - virtual void RegisterVScript() +void CMapbaseSystem::ManifestLoadCustomHudLayout( const char *pszFile ) +{ + CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); + if (pViewport) { - g_pScriptVM->RegisterInstance( this, "Mapbase" ); - } -#endif - -private: + g_bUsingCustomHudLayout = true; -#ifdef CLIENT_DLL - bool m_bInitializedRTs = false; - CUtlVector m_CameraTextures; - - CUtlVector m_CloseCaptionFileNames; -#endif -}; - -CMapbaseSystem g_MapbaseSystem; - -BEGIN_DATADESC_NO_BASE( CMapbaseSystem ) - - //DEFINE_UTLVECTOR( m_StoredManifestFiles, FIELD_STRING ), + KeyValuesAD pConditions( "conditions" ); + g_pClientMode->ComputeVguiResConditions( pConditions ); -END_DATADESC() - -#ifdef MAPBASE_VSCRIPT -BEGIN_SCRIPTDESC_ROOT( CMapbaseSystem, SCRIPT_SINGLETON "All-purpose Mapbase system primarily used for map-specific files." ) - - DEFINE_SCRIPTFUNC_NAMED( ScriptAddManifestFile, "AddManifestFile", "Loads a manifest file." ) - DEFINE_SCRIPTFUNC( LoadCustomSoundscriptFile, "Loads a custom soundscript file." ) - DEFINE_SCRIPTFUNC( LoadCustomLocalizationFile, "Loads a custom localization file." ) - DEFINE_SCRIPTFUNC( LoadCustomSurfacePropsFile, "Loads a custom surface properties file." ) -#ifdef CLIENT_DLL - DEFINE_SCRIPTFUNC( LoadCustomCloseCaptionFile, "Loads a custom closed captions file." ) - DEFINE_SCRIPTFUNC( LoadCustomVGUIFile, "Loads a custom VGUI definitions file." ) - DEFINE_SCRIPTFUNC( LoadCustomClientSchemeFile, "Loads a custom ClientScheme.res override file." ) - DEFINE_SCRIPTFUNC( LoadCustomHUDAnimationsFile, "Loads a custom HUD animations override file." ) - DEFINE_SCRIPTFUNC( LoadCustomHUDLayoutFile, "Loads a custom HUD layout override file." ) -#else - DEFINE_SCRIPTFUNC( LoadCustomTalkerFile, "Loads a custom talker file." ) - DEFINE_SCRIPTFUNC( LoadCustomActbusyFile, "Loads a custom actbusy file." ) - DEFINE_SCRIPTFUNC( LoadCustomChoreoSentenceFile, "Loads a custom choreo sentence file." ) -#endif - - DEFINE_SCRIPTFUNC( GetModName, "Gets the name of the mod. This is the name which shows up on Steam, RPC, etc." ) - DEFINE_SCRIPTFUNC( IsCoreMapbase, "Indicates whether this is one of the original Mapbase mods or just a separate mod using its code." ) - - // Legacy - DEFINE_SCRIPTFUNC_NAMED( LoadCustomSoundscriptFile, "LoadSoundscriptFile", SCRIPT_HIDE ) -#ifndef CLIENT_DLL - DEFINE_SCRIPTFUNC_NAMED( LoadCustomTalkerFile, "LoadTalkerFile", SCRIPT_HIDE ) - DEFINE_SCRIPTFUNC_NAMED( LoadCustomActbusyFile, "LoadActbusyFile", SCRIPT_HIDE ) -#endif + // reload the .res file from disk + pViewport->LoadControlSettings( pszFile, NULL, NULL, pConditions ); -END_SCRIPTDESC(); + CGMsg( 1, ConGroup_MapbaseMisc, "Loaded custom HUD layout file \"%s\"\n", pszFile );; + } +} #endif -static void CC_Mapbase_LoadManifestFile( const CCommand& args ) +const char *CMapbaseSystem::GetModName() const { - g_MapbaseSystem.AddManifestFile(args[1]); + return g_iszGameName; } -#ifdef CLIENT_DLL -static ConCommand mapbase_loadmanifestfile("mapbase_loadmanifestfile_client", CC_Mapbase_LoadManifestFile, "Loads a Mapbase manifest file on the client. If you don't want this to be saved and found when reloaded, type a '1' after the file path." ); -#else -static ConCommand mapbase_loadmanifestfile("mapbase_loadmanifestfile", CC_Mapbase_LoadManifestFile, "Loads a Mapbase manifest file. If you don't want this to be saved and found when reloaded, type a '1' after the file path." ); -#endif - +//----------------------------------------------------------------------------- +// Chapters +//----------------------------------------------------------------------------- #ifdef GAME_DLL static CUtlVector g_MapbaseChapterMaps; static CUtlVector g_MapbaseChapterList; @@ -787,56 +666,20 @@ ThreeState_t Flashlight_GetLegacyVersionKey() return TRS_NONE; } +#endif -#define SF_MANIFEST_START_ACTIVATED (1 << 0) - -class CMapbaseManifestEntity : public CPointEntity -{ -public: - DECLARE_DATADESC(); - - DECLARE_CLASS( CMapbaseManifestEntity, CPointEntity ); - - void Spawn( void ) - { - BaseClass::Spawn(); - if (HasSpawnFlags(SF_MANIFEST_START_ACTIVATED)) - { - LoadManifestFile(); - } - } - - void LoadManifestFile( void ) - { - const char *scriptfile = STRING(m_target); - if ( filesystem->FileExists( scriptfile, "MOD" ) ) - { - CGMsg(0, CON_GROUP_MAPBASE_MISC, "Mapbase: Adding manifest file \"%s\"\n", scriptfile); - g_MapbaseSystem.AddManifestFile(scriptfile); - } - else - { - Warning("Mapbase: Manifest file \"%s\" does not exist!", scriptfile); - } - } - - void InputActivate(inputdata_t &inputdata) - { - LoadManifestFile(); - } -}; - -LINK_ENTITY_TO_CLASS( mapbase_manifest, CMapbaseManifestEntity ); - -BEGIN_DATADESC( CMapbaseManifestEntity ) +//----------------------------------------------------------------------------- - // Needs to be set up in the Activate methods of derived classes - //DEFINE_CUSTOM_FIELD( m_pInstancedResponseSystem, responseSystemSaveRestoreOps ), +#ifndef CLIENT_DLL // TODO: Separate client cvars? +void CV_WildcardCvarChanged( IConVar *pConVar, const char *pOldString, float flOldValue ); - // Function Pointers - DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), +ConVar mapbase_wildcards_enabled( "mapbase_wildcards_enabled", "1", FCVAR_NONE, "Toggles Mapbase's '?' wildcard and true '*' features. Useful for maps that have '?' in their targetnames.", CV_WildcardCvarChanged ); +ConVar mapbase_regex_enabled( "mapbase_regex_enabled", "1", FCVAR_NONE, "Toggles Mapbase's regex matching handover.", CV_WildcardCvarChanged ); -END_DATADESC() +void CV_WildcardCvarChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) +{ + SetMatchersEnabled( mapbase_wildcards_enabled.GetBool(), mapbase_regex_enabled.GetBool() ); +} #endif //----------------------------------------------------------------------------- @@ -861,16 +704,31 @@ void CV_IncludeNameChanged( IConVar *pConVar, const char *pOldString, float flOl CON_COMMAND_SHARED( con_group_reload, "Reloads all console groups." ) { +#ifdef GAME_DLL + if ( !UTIL_IsCommandIssuedByServerAdmin() ) + return; +#endif + InitConsoleGroups( g_pFullFileSystem ); } CON_COMMAND_SHARED( con_group_list, "Prints a list of all console groups." ) { +#ifdef GAME_DLL + if ( !UTIL_IsCommandIssuedByServerAdmin() ) + return; +#endif + PrintAllConsoleGroups(); } CON_COMMAND_SHARED( con_group_toggle, "Toggles a console group." ) { +#ifdef GAME_DLL + if ( !UTIL_IsCommandIssuedByServerAdmin() ) + return; +#endif + ToggleConsoleGroups( args.Arg( 1 ) ); } diff --git a/src/game/shared/mapbase/mapbase_shared.h b/src/game/shared/mapbase/mapbase_shared.h new file mode 100644 index 00000000000..64b10a32145 --- /dev/null +++ b/src/game/shared/mapbase/mapbase_shared.h @@ -0,0 +1,168 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Carries the Mapbase CAutoGameSystem that loads manifest among other things. +// Also includes code that does not fit anywhere else. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "igamesystem.h" +#include "filesystem.h" +#include "vstdlib/IKeyValuesSystem.h" + +//----------------------------------------------------------------------------- +// Purpose: System used to load map-specific files, etc. +//----------------------------------------------------------------------------- +class CMapbaseSystem : public CAutoGameSystem +{ +public: + DECLARE_DATADESC(); + + CMapbaseSystem() : CAutoGameSystem( "CMapbaseSystem" ) + { + } + + inline bool GetGameInfoKeyValues(KeyValues *pKeyValues) + { + // TODO: If there's a custom GameUI override, draw from its KV instead + return pKeyValues->LoadFromFile( filesystem, "gameinfo.txt", "MOD" ); + } + + virtual bool Init(); + virtual void LevelInitPreEntity(); + virtual void LevelInitPostEntity(); + virtual void LevelShutdownPreEntity(); + virtual void LevelShutdownPostEntity(); + +#ifdef CLIENT_DLL + inline const char *MapNameNoExt() { return MapName(); } +#else + inline const char *MapNameNoExt() { return STRING( gpGlobals->mapname ); } +#endif + + void RefreshMapName(); + void RefreshCustomTalker(); + +#ifdef CLIENT_DLL + void InitializeRTs(); + void Shutdown(); +#endif + + void ParseGenericManifest(); + + void InitManifestFileSymbols(); + void AddManifestFile( const char *file ); + void LoadFromValue( const char *value, int type, bool bWarn ); + void LoadFromValue( const char *value, int type ); + void AddManifestFile( KeyValues *pKV, const char *pszMapName, bool bDontWarn = false ); + +private: + +#ifdef CLIENT_DLL + void ManifestLoadCustomCloseCaption( const char *pszFile ); + void ManifestLoadCustomScheme( const char *pszFile ); + void ManifestLoadCustomHudAnimations( const char *pszFile ); + void ManifestLoadCustomHudLayout( const char *pszFile ); +#endif + +public: + + void LoadCustomSoundscriptFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_SOUNDSCRIPTS, false ); } + void LoadCustomLocalizationFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_LOCALIZATION, false ); } + void LoadCustomSurfacePropsFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_SURFACEPROPS, false ); } +#ifdef CLIENT_DLL + void LoadCustomCloseCaptionFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CLOSECAPTION, false ); } + void LoadCustomVGUIFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_VGUI, false ); } + void LoadCustomClientSchemeFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CLIENTSCHEME, false ); } + void LoadCustomHUDAnimationsFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_HUDANIMATIONS, false ); } + void LoadCustomHUDLayoutFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_HUDLAYOUT, false ); } +#else + void LoadCustomTalkerFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_TALKER, false ); } + void LoadCustomActbusyFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_ACTBUSY, false ); } + void LoadCustomChoreoSentenceFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CHOREOSENTENCES, false ); } +#endif + + const char *GetModName() const; + +#ifdef MAPBASE_VSCRIPT + void ScriptAddManifestFile( const char *szScript ) { AddManifestFile( szScript ); } + + virtual void RegisterVScript() + { + g_pScriptVM->RegisterInstance( this, "Mapbase" ); + } +#endif + +public: + + enum + { + MANIFEST_SOUNDSCRIPTS, + //MANIFEST_PROPDATA, + //MANIFEST_SOUNDSCAPES, + MANIFEST_LOCALIZATION, + MANIFEST_SURFACEPROPS, +#ifdef CLIENT_DLL + MANIFEST_CLOSECAPTION, + MANIFEST_VGUI, + MANIFEST_CLIENTSCHEME, + MANIFEST_HUDANIMATIONS, + MANIFEST_HUDLAYOUT, +#else + MANIFEST_TALKER, + MANIFEST_CHOREOSENTENCES, + MANIFEST_ACTBUSY, +#endif +#ifdef MAPBASE_VSCRIPT + MANIFEST_VSCRIPT, +#endif +#if defined(HL2_DLL) || defined(HL2_CLIENT_DLL) + MANIFEST_PROTAGONISTS, // See protagonist_system.h +#endif + + // Must always be kept below + MANIFEST_NUM_TYPES, + }; + + struct ManifestType_t + { + ManifestType_t( const char *_string, const char *cvarname, const char *cvardesc ) + { + string = _string; + } + + //int type; + const char *string; + }; + +private: + + HKeySymbol m_iManifestFileSymbols[MANIFEST_NUM_TYPES] = { -1 }; + +#ifdef CLIENT_DLL + bool m_bInitializedRTs = false; + CUtlVector m_CameraTextures; + + CUtlVector m_CloseCaptionFileNames; +#endif +}; + +// +// Dynamic mod-based mod title comments +// +typedef struct +{ + char pBSPName[64]; + char pTitleName[64]; +} MODTITLECOMMENT; + +typedef struct +{ + int iChapter; + char pChapterName[64]; +} MODCHAPTER; + +extern CUtlVector *Mapbase_GetChapterMaps(); +extern CUtlVector *Mapbase_GetChapterList(); diff --git a/src/game/shared/weapon_parse.cpp b/src/game/shared/weapon_parse.cpp index 1861d048559..32711fced68 100644 --- a/src/game/shared/weapon_parse.cpp +++ b/src/game/shared/weapon_parse.cpp @@ -315,8 +315,6 @@ bool ReadWeaponDataFromFileForSlot( IFileSystem* pFilesystem, const char *szWeap } #ifdef MAPBASE -extern const char *g_MapName; - bool ReadCustomWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeaponName, WEAPON_FILE_INFO_HANDLE *phandle, const unsigned char *pICEKey ) { if ( !phandle ) @@ -334,8 +332,16 @@ bool ReadCustomWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *s //if ( pFileInfo->bParsedScript && pFileInfo->bCustom ) // return true; +#ifdef CLIENT_DLL + // It'd be nice if there was a better way + char szMap[MAX_MAP_NAME]; + Q_FileBase( engine->GetLevelName(), szMap, sizeof( szMap ) ); +#else + const char *szMap = STRING( gpGlobals->mapname ); +#endif + char sz[128]; - Q_snprintf( sz, sizeof( sz ), "maps/%s_%s", g_MapName, szWeaponName ); + Q_snprintf( sz, sizeof( sz ), "maps/%s_%s", szMap, szWeaponName ); KeyValues *pKV = ReadEncryptedKVFile( filesystem, sz, pICEKey, #if defined( DOD_DLL ) From 07b76b2882b1d64796f3785212167e34a26aad4c Mon Sep 17 00:00:00 2001 From: Blixibon Date: Mon, 9 Nov 2026 23:59:57 -0600 Subject: [PATCH 5/7] Remove CHudIcons and move instructor icon functionality to CHud --- src/game/client/hud.cpp | 252 ++----------------------- src/game/client/hud.h | 31 --- src/game/client/hud_locator_target.cpp | 4 +- 3 files changed, 20 insertions(+), 267 deletions(-) diff --git a/src/game/client/hud.cpp b/src/game/client/hud.cpp index ec3a99172cf..b8d8ec2ebcf 100644 --- a/src/game/client/hud.cpp +++ b/src/game/client/hud.cpp @@ -467,6 +467,15 @@ void CHud::Init( void ) LoadHudTextures( textureList, "scripts/hud_textures", NULL ); LoadHudTextures( textureList, "scripts/mod_textures", NULL ); + LoadHudTextures( textureList, "scripts/instructor_textures", NULL ); +#ifdef HL2_CLIENT_DLL + LoadHudTextures( textureList, "scripts/instructor_textures_hl2", NULL ); +#endif +#ifdef TF_CLIENT_DLL + LoadHudTextures( textureList, "scripts/instructor_textures_tf", NULL ); +#endif + LoadHudTextures( textureList, "scripts/instructor_modtextures", NULL ); + int c = textureList.Count(); for ( int index = 0; index < c; index++ ) { @@ -475,8 +484,6 @@ void CHud::Init( void ) } FreeHudTextureList( textureList ); - - HudIcons().Init(); } //----------------------------------------------------------------------------- @@ -820,6 +827,15 @@ void CHud::RefreshHudTextures() LoadHudTextures( textureList, "scripts/hud_textures", NULL ); LoadHudTextures( textureList, "scripts/mod_textures", NULL ); + LoadHudTextures( textureList, "scripts/instructor_textures", NULL ); +#ifdef HL2_CLIENT_DLL + LoadHudTextures( textureList, "scripts/instructor_textures_hl2", NULL ); +#endif +#ifdef TF_CLIENT_DLL + LoadHudTextures( textureList, "scripts/instructor_textures_tf", NULL ); +#endif + LoadHudTextures( textureList, "scripts/instructor_modtextures", NULL ); + // fix up all the texture icons first int c = textureList.Count(); for ( int index = 0; index < c; index++ ) @@ -1205,235 +1221,3 @@ CON_COMMAND_F( testhudanim, "Test a hud element animation.\n\tArguments: GetViewportAnimationController()->StartAnimationSequence( args[1] ); } -CHudIcons::CHudIcons() : - m_bHudTexturesLoaded( false ) -{ -} - -CHudIcons::~CHudIcons() -{ - int c = m_Icons.Count(); - for ( int i = c - 1; i >= 0; i-- ) - { - CHudTexture *tex = m_Icons[ i ]; - g_HudTextureMemoryPool.Free( tex ); - } - m_Icons.Purge(); -} - -void CHudIcons::Init() -{ - if ( m_bHudTexturesLoaded ) - return; - - m_bHudTexturesLoaded = true; - CUtlDict< CHudTexture *, int > textureList; - - // check to see if we have sprites for this res; if not, step down - LoadHudTextures( textureList, "scripts/hud_textures", NULL ); - LoadHudTextures( textureList, "scripts/mod_textures", NULL ); - - LoadHudTextures( textureList, "scripts/instructor_textures", NULL ); -#ifdef HL2_CLIENT_DLL - LoadHudTextures( textureList, "scripts/instructor_textures_hl2", NULL ); -#endif -#ifdef TF_CLIENT_DLL - LoadHudTextures( textureList, "scripts/instructor_textures_tf", NULL ); -#endif - LoadHudTextures( textureList, "scripts/instructor_modtextures", NULL ); - - int c = textureList.Count(); - for ( int index = 0; index < c; index++ ) - { - CHudTexture* tex = textureList[ index ]; - AddSearchableHudIconToList( *tex ); - } - - FreeHudTextureList( textureList ); -} - -void CHudIcons::Shutdown() -{ - m_bHudTexturesLoaded = false; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CHudTexture *CHudIcons::AddUnsearchableHudIconToList( CHudTexture& texture ) -{ - // These names are composed based on the texture file name - char composedName[ 512 ]; - - if ( texture.bRenderUsingFont ) - { - Q_snprintf( composedName, sizeof( composedName ), "%s_c%i", - texture.szTextureFile, texture.cCharacterInFont ); - } - else - { - Q_snprintf( composedName, sizeof( composedName ), "%s_%i_%i_%i_%i", - texture.szTextureFile, texture.rc.left, texture.rc.top, texture.rc.right, texture.rc.bottom ); - } - - CHudTexture *icon = GetIcon( composedName ); - if ( icon ) - { - return icon; - } - - CHudTexture *newTexture = ( CHudTexture * )g_HudTextureMemoryPool.Alloc(); - *newTexture = texture; - - SetupNewHudTexture( newTexture ); - - int idx = m_Icons.Insert( composedName, newTexture ); - return m_Icons[ idx ]; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CHudTexture *CHudIcons::AddSearchableHudIconToList( CHudTexture& texture ) -{ - CHudTexture *icon = GetIcon( texture.szShortName ); - if ( icon ) - { - return icon; - } - - CHudTexture *newTexture = ( CHudTexture * )g_HudTextureMemoryPool.Alloc(); - *newTexture = texture; - - SetupNewHudTexture( newTexture ); - - int idx = m_Icons.Insert( texture.szShortName, newTexture ); - return m_Icons[ idx ]; -} - -//----------------------------------------------------------------------------- -// Purpose: returns a pointer to an icon in the list -//----------------------------------------------------------------------------- -CHudTexture *CHudIcons::GetIcon( const char *szIcon ) -{ - int i = m_Icons.Find( szIcon ); - if ( i == m_Icons.InvalidIndex() ) - return NULL; - - return m_Icons[ i ]; -} - -//----------------------------------------------------------------------------- -// Purpose: Gets texture handles for the hud icon -//----------------------------------------------------------------------------- -void CHudIcons::SetupNewHudTexture( CHudTexture *t ) -{ - if ( t->bRenderUsingFont ) - { - vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); - t->hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( t->szTextureFile, true ); - t->rc.top = 0; - t->rc.left = 0; - t->rc.right = vgui::surface()->GetCharacterWidth( t->hFont, t->cCharacterInFont ); - t->rc.bottom = vgui::surface()->GetFontTall( t->hFont ); - } - else - { - // Set up texture id and texture coordinates - t->textureId = vgui::surface()->CreateNewTextureID(); - vgui::surface()->DrawSetTextureFile( t->textureId, t->szTextureFile, false, false ); - - int wide, tall; - vgui::surface()->DrawGetTextureSize( t->textureId, wide, tall ); - - t->texCoords[ 0 ] = (float)(t->rc.left + 0.5f) / (float)wide; - t->texCoords[ 1 ] = (float)(t->rc.top + 0.5f) / (float)tall; - t->texCoords[ 2 ] = (float)(t->rc.right - 0.5f) / (float)wide; - t->texCoords[ 3 ] = (float)(t->rc.bottom - 0.5f) / (float)tall; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudIcons::RefreshHudTextures() -{ - if ( !m_bHudTexturesLoaded ) - { - Assert( 0 ); - return; - } - - CUtlDict< CHudTexture *, int > textureList; - - // check to see if we have sprites for this res; if not, step down - LoadHudTextures( textureList, "scripts/hud_textures", NULL ); - LoadHudTextures( textureList, "scripts/mod_textures", NULL ); - - LoadHudTextures( textureList, "scripts/instructor_textures", NULL ); - - - // fix up all the texture icons first - int c = textureList.Count(); - for ( int index = 0; index < c; index++ ) - { - CHudTexture *tex = textureList[ index ]; - Assert( tex ); - - CHudTexture *icon = GetIcon( tex->szShortName ); - if ( !icon ) - continue; - - // Update file - Q_strncpy( icon->szTextureFile, tex->szTextureFile, sizeof( icon->szTextureFile ) ); - - if ( !icon->bRenderUsingFont ) - { - // Update subrect - icon->rc = tex->rc; - - // Keep existing texture id, but now update texture file and texture coordinates - vgui::surface()->DrawSetTextureFile( icon->textureId, icon->szTextureFile, false, false ); - - // Get new texture dimensions in case it changed - int wide, tall; - vgui::surface()->DrawGetTextureSize( icon->textureId, wide, tall ); - - // Assign coords - icon->texCoords[ 0 ] = (float)(icon->rc.left + 0.5f) / (float)wide; - icon->texCoords[ 1 ] = (float)(icon->rc.top + 0.5f) / (float)tall; - icon->texCoords[ 2 ] = (float)(icon->rc.right - 0.5f) / (float)wide; - icon->texCoords[ 3 ] = (float)(icon->rc.bottom - 0.5f) / (float)tall; - } - } - - FreeHudTextureList( textureList ); - - // fixup all the font icons - vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); - for (int i = m_Icons.First(); m_Icons.IsValidIndex(i); i = m_Icons.Next(i)) - { - CHudTexture *icon = m_Icons[i]; - if ( !icon ) - continue; - - // Update file - if ( icon->bRenderUsingFont ) - { - icon->hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( icon->szTextureFile, true ); - icon->rc.top = 0; - icon->rc.left = 0; - icon->rc.right = vgui::surface()->GetCharacterWidth( icon->hFont, icon->cCharacterInFont ); - icon->rc.bottom = vgui::surface()->GetFontTall( icon->hFont ); - } - } -} - - -static CHudIcons g_HudIcons; - -CHudIcons &HudIcons() -{ - return g_HudIcons; -} - diff --git a/src/game/client/hud.h b/src/game/client/hud.h index d836cbf1f47..3005f67a7d9 100644 --- a/src/game/client/hud.h +++ b/src/game/client/hud.h @@ -203,37 +203,6 @@ class CHud extern CHud gHUD; -//----------------------------------------------------------------------------- -// Purpose: CHudIcons -//----------------------------------------------------------------------------- -class CHudIcons -{ -public: - CHudIcons(); - ~CHudIcons(); - - void Init(); - void Shutdown(); - - CHudTexture *GetIcon( const char *szIcon ); - - // loads a new icon into the list, without duplicates - CHudTexture *AddUnsearchableHudIconToList( CHudTexture& texture ); - CHudTexture *AddSearchableHudIconToList( CHudTexture& texture ); - - void RefreshHudTextures(); - -private: - - void SetupNewHudTexture( CHudTexture *t ); - bool m_bHudTexturesLoaded; - // Global list of known icons - CUtlDict< CHudTexture *, int > m_Icons; - -}; - -CHudIcons &HudIcons(); - //----------------------------------------------------------------------------- // Global fonts used in the client DLL //----------------------------------------------------------------------------- diff --git a/src/game/client/hud_locator_target.cpp b/src/game/client/hud_locator_target.cpp index 38d800dea59..94a6c45e5f6 100644 --- a/src/game/client/hud_locator_target.cpp +++ b/src/game/client/hud_locator_target.cpp @@ -1321,7 +1321,7 @@ bool CLocatorPanel::ValidateTargetTextures( CLocatorTarget *pTarget ) } else { - pTarget->m_pIcon_onscreen = HudIcons().GetIcon( szIconTextureName ); + pTarget->m_pIcon_onscreen = gHUD.GetIcon( szIconTextureName ); if ( pTarget->m_pIcon_onscreen ) { pTarget->m_widthScale_onscreen = static_cast< float >( pTarget->m_pIcon_onscreen->Width() ) / pTarget->m_pIcon_onscreen->Height(); @@ -1362,7 +1362,7 @@ bool CLocatorPanel::ValidateTargetTextures( CLocatorTarget *pTarget ) } else { - pTarget->m_pIcon_offscreen = HudIcons().GetIcon( szIconTextureName ); + pTarget->m_pIcon_offscreen = gHUD.GetIcon( szIconTextureName ); } return true; From 9f6f8dd8db25216f72c3b5eacb039129bb9de533 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Fri, 13 Nov 2026 21:20:09 -0600 Subject: [PATCH 6/7] Refactor projected texture code + fix decals flickering + add support for multiple and variable shadow map resolutions --- src/game/client/C_Env_Projected_Texture.h | 54 --- src/game/client/c_env_global_light.cpp | 44 +- src/game/client/c_env_projectedtexture.cpp | 320 +------------- src/game/client/cdll_client_int.cpp | 9 + src/game/client/client_mapbase.vpc | 2 +- src/game/client/clientshadowmgr.cpp | 395 +++++++++++++----- src/game/client/iclientshadowmgr.h | 32 +- src/game/client/viewrender.cpp | 4 - src/game/server/env_projectedtexture.cpp | 325 +------------- src/game/server/env_projectedtexture.h | 3 +- src/game/shared/mapbase/mapbase_shared.cpp | 32 +- src/game/shared/mapbase/mapbase_shared.h | 19 + .../stdshaders/BaseVSShader.cpp | 65 ++- src/materialsystem/stdshaders/BaseVSShader.h | 2 + .../lightmappedgeneric_dx9_helper.cpp | 12 +- src/public/materialsystem/imaterialsystem.h | 32 +- src/public/renderparm.h | 15 +- 17 files changed, 494 insertions(+), 871 deletions(-) diff --git a/src/game/client/C_Env_Projected_Texture.h b/src/game/client/C_Env_Projected_Texture.h index cb6268148ca..d8325721aa9 100644 --- a/src/game/client/C_Env_Projected_Texture.h +++ b/src/game/client/C_Env_Projected_Texture.h @@ -14,8 +14,6 @@ #include "c_baseentity.h" #include "basetypes.h" -#ifdef ASW_PROJECTED_TEXTURES - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -111,56 +109,4 @@ bool C_EnvProjectedTexture::IsBBoxVisible( void ) return IsBBoxVisible( GetAbsOrigin() + m_vecExtentsMin, GetAbsOrigin() + m_vecExtentsMax ); } -#else - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -class C_EnvProjectedTexture : public C_BaseEntity -{ - DECLARE_CLASS( C_EnvProjectedTexture, C_BaseEntity ); -public: - DECLARE_CLIENTCLASS(); - - C_EnvProjectedTexture(); - ~C_EnvProjectedTexture(); - - virtual void OnDataChanged( DataUpdateType_t updateType ); - void ShutDownLightHandle( void ); - - virtual void Simulate(); - - void UpdateLight( bool bForceUpdate ); - - bool ShadowsEnabled(); - - float GetFOV(); - -private: - - ClientShadowHandle_t m_LightHandle; - - EHANDLE m_hTargetEntity; - - bool m_bState; - float m_flLightFOV; - bool m_bEnableShadows; - bool m_bLightOnlyTarget; - bool m_bLightWorld; - bool m_bCameraSpace; - color32 m_cLightColor; - float m_flAmbient; - char m_SpotlightTextureName[ MAX_PATH ]; - int m_nSpotlightTextureFrame; - int m_nShadowQuality; - bool m_bCurrentShadow; - -public: - C_EnvProjectedTexture *m_pNext; -}; - -C_EnvProjectedTexture* GetEnvProjectedTextureList(); - -#endif - #endif // C_ENVPROJECTEDTEXTURE_H diff --git a/src/game/client/c_env_global_light.cpp b/src/game/client/c_env_global_light.cpp index b143a79dd0e..c280ee0232d 100644 --- a/src/game/client/c_env_global_light.cpp +++ b/src/game/client/c_env_global_light.cpp @@ -255,7 +255,6 @@ void C_GlobalLight::ClientThink() state.m_fQuadraticAtten = 0.0f; state.m_fLinearAtten = m_flSunDistance * 2.0f; state.m_fConstantAtten = 0.0f; - state.m_FarZAtten = m_flSunDistance * 2.0f; #ifdef MAPBASE float flAlpha = m_flCurrentLinearFloatLightAlpha * (1.0f / 255.0f); state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; @@ -269,27 +268,6 @@ void C_GlobalLight::ClientThink() state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; state.m_NearZ = 4.0f; state.m_FarZ = m_flSunDistance * 2.0f; - state.m_fBrightnessScale = 2.0f; - state.m_bGlobalLight = true; - -#ifdef MAPBASE - float flOrthoSize = m_flOrthoSize; -#else - float flOrthoSize = 1000.0f; -#endif - - if ( flOrthoSize > 0 ) - { - state.m_bOrtho = true; - state.m_fOrthoLeft = -flOrthoSize; - state.m_fOrthoTop = -flOrthoSize; - state.m_fOrthoRight = flOrthoSize; - state.m_fOrthoBottom = flOrthoSize; - } - else - { - state.m_bOrtho = false; - } #ifdef MAPBASE //state.m_bDrawShadowFrustum = true; // Don't draw that huge debug thing @@ -334,6 +312,28 @@ void C_GlobalLight::ClientThink() g_pClientShadowMgr->UpdateProjectedTexture( m_LocalFlashlightHandle, true ); } +#ifdef MAPBASE + FlashlightStateExtras_t stateExtras; + stateExtras.m_FarZAtten = m_flSunDistance * 2.0f; + + if ( m_flOrthoSize > 0 ) + { + stateExtras.m_bOrtho = true; + stateExtras.m_fOrthoLeft = -m_flOrthoSize; + stateExtras.m_fOrthoTop = -m_flOrthoSize; + stateExtras.m_fOrthoRight = m_flOrthoSize; + stateExtras.m_fOrthoBottom = m_flOrthoSize; + } + else + { + stateExtras.m_bOrtho = false; + } + + stateExtras.m_bGlobalLight = true; + + g_pClientShadowMgr->SetFlashlightExtras( m_LocalFlashlightHandle, stateExtras ); +#endif + bSupressWorldLights = m_bEnableShadows; } else if ( m_LocalFlashlightHandle != CLIENTSHADOW_INVALID_HANDLE ) diff --git a/src/game/client/c_env_projectedtexture.cpp b/src/game/client/c_env_projectedtexture.cpp index 6644965265a..57d56f69f27 100644 --- a/src/game/client/c_env_projectedtexture.cpp +++ b/src/game/client/c_env_projectedtexture.cpp @@ -5,11 +5,9 @@ //============================================================================= #include "cbase.h" -#ifdef ASW_PROJECTED_TEXTURES +#ifdef MAPBASE #include "C_Env_Projected_Texture.h" #include "vprof.h" -#endif -#ifdef MAPBASE #include "materialsystem/itexture.h" #endif #include "shareddefs.h" @@ -24,7 +22,6 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -#ifdef ASW_PROJECTED_TEXTURES extern ConVarRef mat_slopescaledepthbias_shadowmap; extern ConVarRef mat_depthbias_shadowmap; @@ -397,7 +394,6 @@ void C_EnvProjectedTexture::UpdateLight( void ) state.m_fConstantAtten = m_flConstantAtten; state.m_fLinearAtten = m_flLinearAtten; state.m_fQuadraticAtten = m_flQuadraticAtten; - state.m_FarZAtten = m_flFarZ; state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; @@ -425,10 +421,6 @@ void C_EnvProjectedTexture::UpdateLight( void ) state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality -#ifdef MAPBASE - state.m_bAlwaysDraw = m_bAlwaysDraw; -#endif - if( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE ) { m_LightHandle = g_pClientShadowMgr->CreateFlashlight( state ); @@ -444,6 +436,14 @@ void C_EnvProjectedTexture::UpdateLight( void ) m_bForceUpdate = false; } +#ifdef MAPBASE + FlashlightStateExtras_t stateExtras; + stateExtras.m_FarZAtten = m_flFarZ; + stateExtras.m_bAlwaysDraw = m_bAlwaysDraw; + + g_pClientShadowMgr->SetFlashlightExtras( m_LightHandle, stateExtras ); +#endif + g_pClientShadowMgr->GetFrustumExtents( m_LightHandle, m_vecExtentsMin, m_vecExtentsMax ); m_vecExtentsMin = m_vecExtentsMin - GetAbsOrigin(); @@ -489,305 +489,3 @@ bool C_EnvProjectedTexture::IsBBoxVisible( Vector vecExtentsMin, Vector vecExten return !engine->CullBox( vecExtentsMin, vecExtentsMax ); } -#else - -#ifndef MAPBASE -static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT ); -static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.0005", FCVAR_CHEAT ); -#else -static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "4", FCVAR_CHEAT ); -static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.00001", FCVAR_CHEAT ); -#endif - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -class C_EnvProjectedTexture : public C_BaseEntity -{ - DECLARE_CLASS( C_EnvProjectedTexture, C_BaseEntity ); -public: - DECLARE_CLIENTCLASS(); - - virtual void OnDataChanged( DataUpdateType_t updateType ); - void ShutDownLightHandle( void ); - - virtual void Simulate(); - -#ifdef MAPBASE - void UpdateLight(); -#else - void UpdateLight( bool bForceUpdate ); -#endif - - C_EnvProjectedTexture(); - ~C_EnvProjectedTexture(); - -private: - - ClientShadowHandle_t m_LightHandle; -#ifdef MAPBASE - bool m_bForceUpdate; -#endif - - EHANDLE m_hTargetEntity; - - bool m_bState; -#ifdef MAPBASE - bool m_bAlwaysUpdate; -#endif - float m_flLightFOV; - bool m_bEnableShadows; - bool m_bLightOnlyTarget; - bool m_bLightWorld; - bool m_bCameraSpace; - Vector m_LinearFloatLightColor; - float m_flAmbient; - float m_flNearZ; - float m_flFarZ; - char m_SpotlightTextureName[ MAX_PATH ]; - int m_nSpotlightTextureFrame; - int m_nShadowQuality; -}; - -IMPLEMENT_CLIENTCLASS_DT( C_EnvProjectedTexture, DT_EnvProjectedTexture, CEnvProjectedTexture ) - RecvPropEHandle( RECVINFO( m_hTargetEntity ) ), - RecvPropBool( RECVINFO( m_bState ) ), -#ifdef MAPBASE - RecvPropBool( RECVINFO( m_bAlwaysUpdate ) ), -#endif - RecvPropFloat( RECVINFO( m_flLightFOV ) ), - RecvPropBool( RECVINFO( m_bEnableShadows ) ), - RecvPropBool( RECVINFO( m_bLightOnlyTarget ) ), - RecvPropBool( RECVINFO( m_bLightWorld ) ), - RecvPropBool( RECVINFO( m_bCameraSpace ) ), - RecvPropVector( RECVINFO( m_LinearFloatLightColor ) ), - RecvPropFloat( RECVINFO( m_flAmbient ) ), - RecvPropString( RECVINFO( m_SpotlightTextureName ) ), - RecvPropInt( RECVINFO( m_nSpotlightTextureFrame ) ), - RecvPropFloat( RECVINFO( m_flNearZ ) ), - RecvPropFloat( RECVINFO( m_flFarZ ) ), - RecvPropInt( RECVINFO( m_nShadowQuality ) ), -END_RECV_TABLE() - -C_EnvProjectedTexture::C_EnvProjectedTexture( void ) -{ - m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; -} - -C_EnvProjectedTexture::~C_EnvProjectedTexture( void ) -{ - ShutDownLightHandle(); -} - -void C_EnvProjectedTexture::ShutDownLightHandle( void ) -{ - // Clear out the light - if( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) - { - g_pClientShadowMgr->DestroyFlashlight( m_LightHandle ); - m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : updateType - -//----------------------------------------------------------------------------- -void C_EnvProjectedTexture::OnDataChanged( DataUpdateType_t updateType ) -{ -#ifdef MAPBASE - m_bForceUpdate = true; - UpdateLight(); -#else - UpdateLight( true ); -#endif - BaseClass::OnDataChanged( updateType ); -} - -#ifndef MAPBASE -void C_EnvProjectedTexture::UpdateLight( bool bForceUpdate ) -#else -void C_EnvProjectedTexture::UpdateLight() -#endif -{ -#ifndef MAPBASE - if ( m_bState == false ) - { - if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) - { - ShutDownLightHandle(); - } - - return; - } -#else - if ( m_bAlwaysUpdate ) - { - m_bForceUpdate = true; - } - - if ( m_bState == false ) - { - // Spotlight's extents aren't in view - ShutDownLightHandle(); - - return; - } -#endif - -#ifdef MAPBASE - if ( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE || m_hTargetEntity != NULL || m_bForceUpdate ) - { -#endif - Vector vForward, vRight, vUp, vPos = GetAbsOrigin(); - FlashlightState_t state; - - if ( m_hTargetEntity != NULL ) - { - if ( m_bCameraSpace ) - { - const QAngle &angles = GetLocalAngles(); - - C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); - if( pPlayer ) - { - const QAngle playerAngles = pPlayer->GetAbsAngles(); - - Vector vPlayerForward, vPlayerRight, vPlayerUp; - AngleVectors( playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp ); - - matrix3x4_t mRotMatrix; - AngleMatrix( angles, mRotMatrix ); - - VectorITransform( vPlayerForward, mRotMatrix, vForward ); - VectorITransform( vPlayerRight, mRotMatrix, vRight ); - VectorITransform( vPlayerUp, mRotMatrix, vUp ); - - float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length(); - vPos = m_hTargetEntity->GetAbsOrigin() - vForward*dist; - - VectorNormalize( vForward ); - VectorNormalize( vRight ); - VectorNormalize( vUp ); - } - } - else - { -#ifndef MAPBASE - vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); - VectorNormalize( vForward ); -#else - // VXP: Fixing targeting - Vector vecToTarget; - QAngle vecAngles; - if (m_hTargetEntity == NULL) - { - vecAngles = GetAbsAngles(); - } - else - { - vecToTarget = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); - VectorAngles(vecToTarget, vecAngles); - } - AngleVectors(vecAngles, &vForward, &vRight, &vUp); -#endif - - // JasonM - unimplemented - Assert (0); - - //Quaternion q = DirectionToOrientation( dir ); - - - // - // JasonM - set up vRight, vUp - // - -// VectorNormalize( vRight ); -// VectorNormalize( vUp ); - } - } - else - { - AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp ); - } - - state.m_fHorizontalFOVDegrees = m_flLightFOV; - state.m_fVerticalFOVDegrees = m_flLightFOV; - - state.m_vecLightOrigin = vPos; - BasisToQuaternion( vForward, vRight, vUp, state.m_quatOrientation ); - - state.m_fQuadraticAtten = 0.0; - state.m_fLinearAtten = 100; - state.m_fConstantAtten = 0.0f; - state.m_Color[0] = m_LinearFloatLightColor.x; - state.m_Color[1] = m_LinearFloatLightColor.y; - state.m_Color[2] = m_LinearFloatLightColor.z; - state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; - state.m_NearZ = m_flNearZ; - state.m_FarZ = m_flFarZ; - state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat(); - state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat(); - state.m_bEnableShadows = m_bEnableShadows; - state.m_pSpotlightTexture = materials->FindTexture( m_SpotlightTextureName, TEXTURE_GROUP_OTHER, false ); - state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame; - - state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality - - if( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE ) - { - m_LightHandle = g_pClientShadowMgr->CreateFlashlight( state ); - } - else - { -#ifndef MAPBASE - if ( m_hTargetEntity != NULL || bForceUpdate == true ) - { - g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state ); - } -#else - g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state ); - m_bForceUpdate = false; -#endif - } -#ifdef MAPBASE - } -#endif - - if( m_bLightOnlyTarget ) - { - g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, m_hTargetEntity ); - } - else - { - g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, NULL ); - } - - g_pClientShadowMgr->SetFlashlightLightWorld( m_LightHandle, m_bLightWorld ); - -#ifndef MAPBASE - if ( bForceUpdate == false ) - { - g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true ); - } -#else - if ( !m_bForceUpdate ) - { - g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true ); - } -#endif -} - -void C_EnvProjectedTexture::Simulate( void ) -{ -#ifndef MAPBASE - UpdateLight( false ); -#else - UpdateLight(); -#endif - - BaseClass::Simulate(); -} - -#endif - diff --git a/src/game/client/cdll_client_int.cpp b/src/game/client/cdll_client_int.cpp index fcd80060c65..97e889380c2 100644 --- a/src/game/client/cdll_client_int.cpp +++ b/src/game/client/cdll_client_int.cpp @@ -155,6 +155,10 @@ #endif +#ifdef MAPBASE +#include "mapbase/mapbase_shared.h" +#endif + #ifdef MAPBASE_VSCRIPT #include "vscript_client.h" #endif @@ -1096,6 +1100,11 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi modemanager->Init( ); +#ifdef MAPBASE + // Need to initialize these ahead of the other game systems + g_MapbaseSystem.InitializeRTs(); +#endif + g_pClientMode->InitViewport(); gHUD.Init(); diff --git a/src/game/client/client_mapbase.vpc b/src/game/client/client_mapbase.vpc index 22285799dd5..c3998fcd94c 100644 --- a/src/game/client/client_mapbase.vpc +++ b/src/game/client/client_mapbase.vpc @@ -8,7 +8,7 @@ $Configuration { $Compiler { - $PreprocessorDefinitions "$BASE;ASW_PROJECTED_TEXTURES;DYNAMIC_RTT_SHADOWS;GLOWS_ENABLE" + $PreprocessorDefinitions "$BASE;DYNAMIC_RTT_SHADOWS;GLOWS_ENABLE" $PreprocessorDefinitions "$BASE;MAPBASE_RPC;DISCORD_RPC;STEAM_RPC" [$MAPBASE_RPC&&!$LINUXALL] $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] diff --git a/src/game/client/clientshadowmgr.cpp b/src/game/client/clientshadowmgr.cpp index b1177ff33ea..9affa6b3d92 100644 --- a/src/game/client/clientshadowmgr.cpp +++ b/src/game/client/clientshadowmgr.cpp @@ -83,9 +83,8 @@ #include "cmodel.h" #ifdef MAPBASE #include "renderparm.h" -#endif -#ifdef ASW_PROJECTED_TEXTURES #include "flashlighteffect.h" +#include "mapbase/mapbase_shared.h" #endif #ifdef DYNAMIC_RTT_SHADOWS #include "debugoverlay_shared.h" @@ -99,7 +98,7 @@ static ConVar r_flashlightdrawfrustum( "r_flashlightdrawfrustum", "0" ); static ConVar r_flashlightmodels( "r_flashlightmodels", "1" ); static ConVar r_shadowrendertotexture( "r_shadowrendertotexture", "0" ); -#ifdef ASW_PROJECTED_TEXTURES +#ifdef MAPBASE static ConVar r_shadow_lightpos_lerptime( "r_shadow_lightpos_lerptime", "0.5" ); static ConVar r_shadowfromworldlights_debug( "r_shadowfromworldlights_debug", "0", FCVAR_CHEAT ); static ConVar r_shadow_shortenfactor( "r_shadow_shortenfactor", "2" , 0, "Makes shadows cast from local lights shorter" ); @@ -119,7 +118,7 @@ ConVar r_flashlightdepthres( "r_flashlightdepthres", "1024" ); #endif #endif -#ifdef ASW_PROJECTED_TEXTURES +#ifdef MAPBASE ConVar r_threaded_client_shadow_manager( "r_threaded_client_shadow_manager", "1" ); #else ConVar r_threaded_client_shadow_manager( "r_threaded_client_shadow_manager", "0" ); @@ -128,6 +127,10 @@ ConVar r_threaded_client_shadow_manager( "r_threaded_client_shadow_manager", "0" #ifdef MAPBASE ConVarRef mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap" ); ConVarRef mat_depthbias_shadowmap( "mat_depthbias_shadowmap" ); + +static const int MAX_FALLBACK_DEPTH_TEXTURES = (INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST) + 1; + +#define NUM_DEPTH_TEXTURE_OPTIONS 4 // High, Medium, Low, Very Low #endif #ifdef _WIN32 @@ -776,6 +779,11 @@ class CClientShadowMgr : public IClientShadowMgr // Kicks off rendering into shadow depth maps (if any) void ComputeShadowDepthTextures( const CViewSetup &view ); +#ifdef MAPBASE + void SetFallbackDepthTexture( CMatRenderContextPtr &pRenderContext, int j, ShadowHandle_t handle, FlashlightState_t &flashlightState, ITexture *depthTexture ); + + void SetFlashlightExtras( ClientShadowHandle_t shadowHandle, const FlashlightStateExtras_t &stateExtras ); +#endif // Frees shadow depth textures for use in subsequent view/frame void FreeShadowDepthTextures(); @@ -865,6 +873,9 @@ class CClientShadowMgr : public IClientShadowMgr CTextureReference m_ShadowDepthTexture; int m_nRenderFrame; EHANDLE m_hTargetEntity; +#ifdef MAPBASE + FlashlightStateExtras_t m_FlashlightExtras; +#endif }; private: @@ -895,8 +906,8 @@ class CClientShadowMgr : public IClientShadowMgr void BuildPerspectiveWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ); -#ifdef ASW_PROJECTED_TEXTURES - void BuildOrthoWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ); +#ifdef MAPBASE + void BuildOrthoWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState, const FlashlightStateExtras_t &flashlightExtras ); #endif // Update a shadow @@ -987,16 +998,14 @@ class CClientShadowMgr : public IClientShadowMgr ClientShadowHandle_t CreateProjectedTexture( ClientEntityHandle_t entity, int flags ); // Lock down the usage of a shadow depth texture...must be unlocked use on subsequent views / frames - bool LockShadowDepthTexture( CTextureReference *shadowDepthTexture ); + int LockShadowDepthTexture( CTextureReference *shadowDepthTexture, int iStartIdx = 0 ); void UnlockAllShadowDepthTextures(); // Set and clear flashlight target renderable void SetFlashlightTarget( ClientShadowHandle_t shadowHandle, EHANDLE targetEntity ); -#ifdef ASW_PROJECTED_TEXTURES // Get current frustum extents void GetFrustumExtents( ClientShadowHandle_t handle, Vector &vecMin, Vector &vecMax ); -#endif // Set flashlight light world flag void SetFlashlightLightWorld( ClientShadowHandle_t shadowHandle, bool bLightWorld ); @@ -1006,10 +1015,8 @@ class CClientShadowMgr : public IClientShadowMgr // Builds a list of active shadows requiring shadow depth renders int BuildActiveShadowDepthList( const CViewSetup &viewSetup, int nMaxDepthShadows, ClientShadowHandle_t *pActiveDepthShadows ); -#ifdef ASW_PROJECTED_TEXTURES // Builds a list of active flashlights int BuildActiveFlashlightList( const CViewSetup &viewSetup, int nMaxFlashlights, ClientShadowHandle_t *pActiveFlashlights ); -#endif // Sets the view's active flashlight render state void SetViewFlashlightState( int nActiveFlashlightCount, ClientShadowHandle_t* pActiveFlashlights ); @@ -1037,18 +1044,25 @@ class CClientShadowMgr : public IClientShadowMgr CUtlRBTree< ClientShadowHandle_t, unsigned short > m_DirtyShadows; CUtlVector< ClientShadowHandle_t > m_TransparentShadows; -#ifdef ASW_PROJECTED_TEXTURES int m_nPrevFrameCount; -#endif // These members maintain current state of depth texturing (size and global active state) // If either changes in a frame, PreRender() will catch it and do the appropriate allocation, deallocation or reallocation bool m_bDepthTextureActive; +#ifdef MAPBASE + short m_nDepthTextureResolution[NUM_DEPTH_TEXTURE_OPTIONS]; +#else int m_nDepthTextureResolution; // Assume square (height == width) +#endif CUtlVector< CTextureReference > m_DepthTextureCache; CUtlVector< bool > m_DepthTextureCacheLocks; +#ifdef MAPBASE + byte m_nMaxDepthTextureShadows[NUM_DEPTH_TEXTURE_OPTIONS]; // Each option's number of depth textures + byte m_nDepthTextureShadowIdx[NUM_DEPTH_TEXTURE_OPTIONS]; // Each option's starting index in the depth texture cache +#else int m_nMaxDepthTextureShadows; +#endif #ifdef DYNAMIC_RTT_SHADOWS bool m_bShadowFromWorldLights; @@ -1147,11 +1161,9 @@ void CVisibleShadowList::EnumShadow( unsigned short clientShadowHandle ) if ( shadow.m_nRenderFrame == gpGlobals->framecount ) return; -#ifdef ASW_PROJECTED_TEXTURES // Don't bother with flashlights if ( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) != 0 ) return; -#endif // We don't need to bother with it if it's not render-to-texture if ( s_ClientShadowMgr.GetActualShadowCastType( clientShadowHandle ) != SHADOWS_RENDER_TO_TEXTURE ) @@ -1260,9 +1272,7 @@ int CVisibleShadowList::FindShadows( const CViewSetup *pView, int nLeafCount, Le //----------------------------------------------------------------------------- CClientShadowMgr::CClientShadowMgr() : m_DirtyShadows( 0, 0, ShadowHandleCompareFunc ), -#ifdef ASW_PROJECTED_TEXTURES m_nPrevFrameCount( -1 ), -#endif m_RenderToTextureActive( false ), #ifdef DYNAMIC_RTT_SHADOWS m_bShadowFromWorldLights( false ), @@ -1270,7 +1280,11 @@ CClientShadowMgr::CClientShadowMgr() : #endif m_bDepthTextureActive( false ) { +#ifdef MAPBASE + m_nDepthTextureResolution[0] = r_flashlightdepthres.GetInt(); +#else m_nDepthTextureResolution = r_flashlightdepthres.GetInt(); +#endif m_bThreaded = false; } @@ -1403,9 +1417,48 @@ bool CClientShadowMgr::Init() bool bTools = CommandLine()->CheckParm( "-tools" ) != NULL; m_nMaxDepthTextureShadows = bTools ? 4 : 1; // Just one shadow depth texture in games, more in tools #else - // 5 lets mappers use up to 4 shadow-casting projected textures, which is better than 3. - int iNumShadows = CommandLine()->ParmValue( "-numshadowtextures", 5 ); - m_nMaxDepthTextureShadows = iNumShadows; + // Set initial values + m_nMaxDepthTextureShadows[0] = 5; + m_nDepthTextureShadowIdx[0] = 0; + m_nDepthTextureResolution[0] = r_flashlightdepthres.GetInt(); + + for ( int i = 1; i < NUM_DEPTH_TEXTURE_OPTIONS; i++ ) + m_nMaxDepthTextureShadows[i] = 0; + + const char *pszDepthTextureSymbolNames[NUM_DEPTH_TEXTURE_OPTIONS] = { + "DepthTextureHigh", + "DepthTextureMedium", + "DepthTextureLow", + "DepthTextureVeryLow", + }; + + int nTotal = 0; + for ( int i = 0; i < NUM_DEPTH_TEXTURE_OPTIONS; i++ ) + { + HKeySymbol hSymbol = KeyValuesSystem()->GetSymbolForString( pszDepthTextureSymbolNames[i], false ); + if ( hSymbol == INVALID_KEY_SYMBOL ) + continue; + + const CMapbaseSystem::RenderTargetData_t *pData = g_MapbaseSystem.LookupRenderTargetData( hSymbol ); + if ( pData ) + { + if ( pData->nNum != 0 ) + { + m_nMaxDepthTextureShadows[i] = pData->nNum; + m_nDepthTextureShadowIdx[i] = nTotal; + nTotal += pData->nNum; + } + if ( pData->nRes != 0 ) + m_nDepthTextureResolution[i] = pData->nRes; + } + } + + // Allow the command line parameter to override + int iNumShadowsOverride = CommandLine()->ParmValue( "-numshadowtextures", 0 ); + if ( iNumShadowsOverride != 0 ) + { + m_nMaxDepthTextureShadows[0] = iNumShadowsOverride; + } #endif bool bLowEnd = ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 ); @@ -1460,11 +1513,6 @@ void CClientShadowMgr::InitDepthTextureShadows() { VPROF_BUDGET( "CClientShadowMgr::InitDepthTextureShadows", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); -#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) - // SAUL: set m_nDepthTextureResolution to the depth resolution we want - m_nDepthTextureResolution = r_flashlightdepthres.GetInt(); -#endif - if( !m_bDepthTextureActive ) { m_bDepthTextureActive = true; @@ -1481,9 +1529,9 @@ void CClientShadowMgr::InitDepthTextureShadows() m_DummyColorTexture.InitRenderTargetTexture( r_flashlightdepthres.GetInt(), r_flashlightdepthres.GetInt(), RT_SIZE_OFFSCREEN, IMAGE_FORMAT_BGR565, MATERIAL_RT_DEPTH_SHARED, false, "_rt_ShadowDummy" ); m_DummyColorTexture.InitRenderTargetSurface( r_flashlightdepthres.GetInt(), r_flashlightdepthres.GetInt(), IMAGE_FORMAT_BGR565, true ); #else -#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) +#ifdef MAPBASE // SAUL: we want to create a render target of specific size, so use RT_SIZE_NO_CHANGE - m_DummyColorTexture.InitRenderTarget( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_NO_CHANGE, nullFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_ShadowDummy" ); + m_DummyColorTexture.InitRenderTarget( m_nDepthTextureResolution[0], m_nDepthTextureResolution[0], RT_SIZE_NO_CHANGE, nullFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_ShadowDummy" ); #else m_DummyColorTexture.InitRenderTarget( r_flashlightdepthres.GetInt(), r_flashlightdepthres.GetInt(), RT_SIZE_OFFSCREEN, nullFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_ShadowDummy" ); #endif @@ -1492,6 +1540,41 @@ void CClientShadowMgr::InitDepthTextureShadows() // Create some number of depth-stencil textures m_DepthTextureCache.Purge(); m_DepthTextureCacheLocks.Purge(); + +#ifdef MAPBASE + int i = 0; + int nTotal = 0; + + for( int j=0; j < NUM_DEPTH_TEXTURE_OPTIONS; j++ ) + { + nTotal += m_nMaxDepthTextureShadows[j]; + + for( ; i < nTotal; i++ ) + { + CTextureReference depthTex; // Depth-stencil surface + bool bFalse = false; + + char strRTName[64]; + Q_snprintf( strRTName, ARRAYSIZE( strRTName ), "_rt_ShadowDepthTexture_%d", i ); + + // SAUL: we want to create a *DEPTH TEXTURE* of specific size, so use RT_SIZE_NO_CHANGE and MATERIAL_RT_DEPTH_ONLY + // However, MATERIAL_RT_DEPTH_ONLY forces point filtering to be enabled which negatively affect PCF, so the standard MATERIAL_RT_DEPTH_NONE works better. + depthTex.InitRenderTarget( m_nDepthTextureResolution[j], m_nDepthTextureResolution[j], RT_SIZE_NO_CHANGE, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName ); + + // SAUL: ensure the depth texture size wasn't changed + Assert( depthTex->GetActualWidth() == m_nDepthTextureResolution[j] ); + + if ( i == (nTotal - m_nMaxDepthTextureShadows[j]) ) + { + // Shadow may be resized during allocation (due to resolution constraints etc) + m_nDepthTextureResolution[j] = depthTex->GetActualWidth(); + } + + m_DepthTextureCache.AddToTail( depthTex ); + m_DepthTextureCacheLocks.AddToTail( bFalse ); + } + } +#else for( int i=0; i < m_nMaxDepthTextureShadows; i++ ) { CTextureReference depthTex; // Depth-stencil surface @@ -1505,31 +1588,20 @@ void CClientShadowMgr::InitDepthTextureShadows() // surface is effectively never used depthTex.InitRenderTargetTexture( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_OFFSCREEN, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName ); depthTex.InitRenderTargetSurface( 1, 1, dstFormat, false ); -#else -#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) - // SAUL: we want to create a *DEPTH TEXTURE* of specific size, so use RT_SIZE_NO_CHANGE and MATERIAL_RT_DEPTH_ONLY - // However, MATERIAL_RT_DEPTH_ONLY forces point filtering to be enabled which negatively affect PCF, so the standard MATERIAL_RT_DEPTH_NONE works better. - depthTex.InitRenderTarget( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_NO_CHANGE, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName ); #else depthTex.InitRenderTarget( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_OFFSCREEN, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName ); #endif -#endif - -#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) - // SAUL: ensure the depth texture size wasn't changed - Assert(depthTex->GetActualWidth() == m_nDepthTextureResolution); -#endif if ( i == 0 ) { // Shadow may be resized during allocation (due to resolution constraints etc) - m_nDepthTextureResolution = depthTex->GetActualWidth(); - r_flashlightdepthres.SetValue( m_nDepthTextureResolution ); + m_nDepthTextureResolution[j] = depthTex->GetActualWidth(); } m_DepthTextureCache.AddToTail( depthTex ); m_DepthTextureCacheLocks.AddToTail( bFalse ); } +#endif materials->EndRenderTargetAllocation(); } @@ -2149,21 +2221,12 @@ ClientShadowHandle_t CClientShadowMgr::CreateProjectedTexture( ClientEntityHandl pShadowProxyData = (void*)(uintp)h; } -#ifdef ASW_PROJECTED_TEXTURES if( ( flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE ) || ( flags & ( SHADOW_FLAGS_FLASHLIGHT ) ) ) { pShadowMaterial = NULL; // these materials aren't used for shadow depth texture shadows. pShadowModelMaterial = NULL; pShadowProxyData = (void*)(uintp)h; } -#else - if( flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE ) - { - pShadowMaterial = m_RenderShadow; - pShadowModelMaterial = m_RenderModelShadow; - pShadowProxyData = (void*)(uintp)h; - } -#endif int createShadowFlags; if( flags & SHADOW_FLAGS_FLASHLIGHT ) @@ -2226,7 +2289,6 @@ void CClientShadowMgr::UpdateFlashlightState( ClientShadowHandle_t shadowHandle, { VPROF_BUDGET( "CClientShadowMgr::UpdateFlashlightState", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); -#ifdef ASW_PROJECTED_TEXTURES if( flashlightState.m_bEnableShadows && r_flashlightdepthtexture.GetBool() ) { m_Shadows[shadowHandle].m_Flags |= SHADOW_FLAGS_USE_DEPTH_TEXTURE; @@ -2236,17 +2298,16 @@ void CClientShadowMgr::UpdateFlashlightState( ClientShadowHandle_t shadowHandle, m_Shadows[shadowHandle].m_Flags &= ~SHADOW_FLAGS_USE_DEPTH_TEXTURE; } - if ( flashlightState.m_bOrtho ) +#ifdef MAPBASE + if ( m_Shadows[shadowHandle].m_FlashlightExtras.m_bOrtho ) { - BuildOrthoWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState ); + BuildOrthoWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState, m_Shadows[shadowHandle].m_FlashlightExtras ); } else +#endif { BuildPerspectiveWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState ); } -#else - BuildPerspectiveWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState ); -#endif shadowmgr->UpdateFlashlightState( m_Shadows[shadowHandle].m_ShadowHandle, flashlightState ); } @@ -2357,8 +2418,8 @@ void CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix( VMatrix& matWorl MatrixMultiply( matPerspective, matWorldToShadowView, matWorldToShadow ); } -#ifdef ASW_PROJECTED_TEXTURES -void CClientShadowMgr::BuildOrthoWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ) +#ifdef MAPBASE +void CClientShadowMgr::BuildOrthoWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState, const FlashlightStateExtras_t &flashlightExtras ) { VPROF_BUDGET( "CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); @@ -2368,7 +2429,7 @@ void CClientShadowMgr::BuildOrthoWorldToFlashlightMatrix( VMatrix& matWorldToSha flashlightState.m_quatOrientation ); MatrixBuildOrtho( matPerspective, - flashlightState.m_fOrthoLeft, flashlightState.m_fOrthoTop, flashlightState.m_fOrthoRight, flashlightState.m_fOrthoBottom, + flashlightExtras.m_fOrthoLeft, flashlightExtras.m_fOrthoTop, flashlightExtras.m_fOrthoRight, flashlightExtras.m_fOrthoBottom, flashlightState.m_NearZ, flashlightState.m_FarZ ); // Shift it z/y to 0 to -2 space @@ -2753,12 +2814,7 @@ void CClientShadowMgr::BuildOrthoShadow( IClientRenderable* pRenderable, vecShadowDir, matWorldToTexture, size, nCount, pLeafList, maxHeight, falloffStart, MAX_FALLOFF_AMOUNT, pRenderable->GetRenderOrigin() ); // Compute extra clip planes to prevent poke-thru -// FIXME!!!!!!!!!!!!!! Removing this for now since it seems to mess up the blobby shadows. -#ifdef ASW_PROJECTED_TEXTURES ComputeExtraClipPlanes( pRenderable, handle, vec, mins, maxs, localShadowDir ); -#else -// ComputeExtraClipPlanes( pEnt, handle, vec, mins, maxs, localShadowDir ); -#endif // Add the shadow to the client leaf system so it correctly marks // leafs as being affected by a particular shadow @@ -3257,12 +3313,10 @@ bool CClientShadowMgr::ShouldUseParentShadow( IClientRenderable *pRenderable ) //----------------------------------------------------------------------------- void CClientShadowMgr::PreRender() { -#ifdef ASW_PROJECTED_TEXTURES // only update shadows once per frame if( gpGlobals->framecount == m_nPrevFrameCount ) return; m_nPrevFrameCount = gpGlobals->framecount; -#endif VPROF_BUDGET( "CClientShadowMgr::PreRender", VPROF_BUDGETGROUP_SHADOW_RENDERING ); MDLCACHE_CRITICAL_SECTION(); @@ -3285,12 +3339,18 @@ void CClientShadowMgr::PreRender() bool bDepthTextureActive = r_flashlightdepthtexture.GetBool(); int nDepthTextureResolution = r_flashlightdepthres.GetInt(); +#ifdef MAPBASE + int nMyDepthTextureResolution = m_nDepthTextureResolution[0]; +#else + int nMyDepthTextureResolution = m_nDepthTextureResolution; +#endif + // If shadow depth texture size or enable/disable changed, do appropriate deallocation/(re)allocation - if ( ( bDepthTextureActive != m_bDepthTextureActive ) || ( nDepthTextureResolution != m_nDepthTextureResolution ) ) + if ( ( bDepthTextureActive != m_bDepthTextureActive ) || ( nDepthTextureResolution != nMyDepthTextureResolution ) ) { // If shadow depth texturing remains on, but resolution changed, shut down and reinitialize depth textures if ( ( bDepthTextureActive == true ) && ( m_bDepthTextureActive == true ) && - ( nDepthTextureResolution != m_nDepthTextureResolution ) ) + ( nDepthTextureResolution != nMyDepthTextureResolution ) ) { ShutdownDepthTextureShadows(); InitDepthTextureShadows(); @@ -4269,10 +4329,8 @@ void CClientShadowMgr::AdvanceFrame() //----------------------------------------------------------------------------- int CClientShadowMgr::BuildActiveShadowDepthList( const CViewSetup &viewSetup, int nMaxDepthShadows, ClientShadowHandle_t *pActiveDepthShadows ) { -#ifdef ASW_PROJECTED_TEXTURES Frustum_t viewFrustum; GeneratePerspectiveFrustum( viewSetup.origin, viewSetup.angles, viewSetup.zNear, viewSetup.zFar, viewSetup.fov, viewSetup.m_flAspectRatio, viewFrustum ); -#endif int nActiveDepthShadowCount = 0; for ( ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i) ) @@ -4299,9 +4357,7 @@ int CClientShadowMgr::BuildActiveShadowDepthList( const CViewSetup &viewSetup, i // FIXME: Could do other sorts of culling here, such as frustum-frustum test, distance etc. // If it's not in the view frustum, move on #ifdef MAPBASE - if ( !flashlightState.m_bAlwaysDraw && !flashlightState.m_bOrtho && R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) -#elif ASW_PROJECTED_TEXTURES - if ( !flashlightState.m_bOrtho && R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) + if ( !shadow.m_FlashlightExtras.m_bAlwaysDraw && !shadow.m_FlashlightExtras.m_bOrtho && R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) #else if ( R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) #endif @@ -4329,7 +4385,6 @@ int CClientShadowMgr::BuildActiveShadowDepthList( const CViewSetup &viewSetup, i } -#ifdef ASW_PROJECTED_TEXTURES //----------------------------------------------------------------------------- // Re-render shadow depth textures that lie in the leaf list //----------------------------------------------------------------------------- @@ -4374,7 +4429,6 @@ int CClientShadowMgr::BuildActiveFlashlightList( const CViewSetup &viewSetup, in } return nActiveFlashlightCount; } -#endif //----------------------------------------------------------------------------- // Sets the view's active flashlight render state @@ -4399,7 +4453,6 @@ void CClientShadowMgr::SetViewFlashlightState( int nActiveFlashlightCount, Clien } } -#ifdef ASW_PROJECTED_TEXTURES void AddPointToExtentsHelper( const VMatrix &flashlightToWorld, const Vector &vecPos, Vector &vecMin, Vector &vecMax ) { Vector worldSpacePos; @@ -4431,14 +4484,12 @@ void CClientShadowMgr::GetFrustumExtents( ClientShadowHandle_t handle, Vector &v AddPointToExtentsHelper( flashlightToWorld, Vector( 1.0f, 1.0f, 0.0f ), vecMin, vecMax ); AddPointToExtentsHelper( flashlightToWorld, Vector( 1.0f, 1.0f, 1.0f ), vecMin, vecMax ); } -#endif //----------------------------------------------------------------------------- // Re-render shadow depth textures that lie in the leaf list //----------------------------------------------------------------------------- void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) { -#ifdef ASW_PROJECTED_TEXTURES if ( !r_flashlightdepthtexture.GetBool() ) { // Build list of active flashlights @@ -4447,7 +4498,6 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) SetViewFlashlightState( nActiveFlashlights, pActiveFlashlights ); return; } -#endif VPROF_BUDGET( "CClientShadowMgr::ComputeShadowDepthTextures", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); @@ -4458,19 +4508,102 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) ClientShadowHandle_t pActiveDepthShadows[1024]; int nActiveDepthShadowCount = BuildActiveShadowDepthList( viewSetup, ARRAYSIZE( pActiveDepthShadows ), pActiveDepthShadows ); +#ifdef MAPBASE + // Used to prioritize specific depth textures when there's more than the render parms can support + struct FallbackDepthTextureData_t + { + FallbackDepthTextureData_t( ClientShadow_t *sh, FlashlightState_t *s) : shadow(sh), flashlightState(s) {} + ClientShadow_t *shadow; + FlashlightState_t *flashlightState; + float flDistSqrFromView; + }; + + CUtlVector vecDepthTextures; + + bool bSortFallbackDepthTextures = false; + if ( nActiveDepthShadowCount > MAX_FALLBACK_DEPTH_TEXTURES ) + { + bSortFallbackDepthTextures = true; + + vecDepthTextures.EnsureCapacity( nActiveDepthShadowCount ); + for ( int j = 0; j < nActiveDepthShadowCount; ++j ) + { + ClientShadow_t& shadow = m_Shadows[ pActiveDepthShadows[j] ]; + FlashlightState_t& flashlightState = const_cast( shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ) ); + + FallbackDepthTextureData_t data( &shadow, &flashlightState ); + data.flDistSqrFromView = (viewSetup.origin - flashlightState.m_vecLightOrigin).LengthSqr(); + vecDepthTextures.AddToTail( data ); + } + + // Put the most important depth textures at the head + vecDepthTextures.Sort( []( const FallbackDepthTextureData_t *pLeft, const FallbackDepthTextureData_t *pRight ) -> int { + + // For now, only check distance from view + if ( pLeft->flDistSqrFromView < pRight->flDistSqrFromView ) + return -1; + + return 1; + } ); + } +#endif + // Iterate over all existing textures and allocate shadow textures bool bDebugFrustum = r_flashlightdrawfrustum.GetBool(); for ( int j = 0; j < nActiveDepthShadowCount; ++j ) { +#ifdef MAPBASE + ClientShadow_t& shadow = bSortFallbackDepthTextures ? *vecDepthTextures[j].shadow : m_Shadows[ pActiveDepthShadows[j] ]; + FlashlightState_t& flashlightState = bSortFallbackDepthTextures ? *vecDepthTextures[j].flashlightState : const_cast( shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ) ); +#else ClientShadow_t& shadow = m_Shadows[ pActiveDepthShadows[j] ]; - -#ifdef ASW_PROJECTED_TEXTURES FlashlightState_t& flashlightState = const_cast( shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ) ); #endif CTextureReference shadowDepthTexture; +#ifdef MAPBASE + int iStartIdx = 0; + int nShadowQualityIdx = ((short)flashlightState.m_nShadowQuality) - 1; + if ( nShadowQualityIdx > 0 && nShadowQualityIdx < NUM_DEPTH_TEXTURE_OPTIONS ) + { + // Wants to use one of the other shadow qualities + iStartIdx = m_nDepthTextureShadowIdx[nShadowQualityIdx]; + } + + int iGotShadowDepthTexture = LockShadowDepthTexture( &shadowDepthTexture, iStartIdx ); + if ( iGotShadowDepthTexture != -1 ) + { + // Did we change from our desired resolution? + int iLevelsChanged = 0; + if ( nShadowQualityIdx < (NUM_DEPTH_TEXTURE_OPTIONS-1) && iGotShadowDepthTexture >= m_nDepthTextureShadowIdx[nShadowQualityIdx+1] ) + { + // Determine what resolution we changed to + int k = nShadowQualityIdx; + for ( ; k <= NUM_DEPTH_TEXTURE_OPTIONS; k++ ) + { + if ( iGotShadowDepthTexture <= m_nDepthTextureShadowIdx[k] ) + break; + } + + iLevelsChanged = k - nShadowQualityIdx; + nShadowQualityIdx = k; + } + + if ( shadow.m_FlashlightExtras.m_flBaseShadowFilterSize == 0.0f ) + shadow.m_FlashlightExtras.m_flBaseShadowFilterSize = flashlightState.m_flShadowFilterSize; + + flashlightState.m_flShadowMapResolution = m_nDepthTextureResolution[nShadowQualityIdx]; + + if ( iLevelsChanged > 0 ) + flashlightState.m_flShadowFilterSize = shadow.m_FlashlightExtras.m_flBaseShadowFilterSize * (iLevelsChanged + 1); + else + flashlightState.m_flShadowFilterSize = shadow.m_FlashlightExtras.m_flBaseShadowFilterSize; + } + else +#else bool bGotShadowDepthTexture = LockShadowDepthTexture( &shadowDepthTexture ); if ( !bGotShadowDepthTexture ) +#endif { // If we don't get one, that means we have too many this frame so bind no depth texture static int mapCount = 0; @@ -4483,7 +4616,7 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) Assert(0); shadowmgr->SetFlashlightDepthTexture( shadow.m_ShadowHandle, NULL, 0 ); #ifdef MAPBASE - if ( j <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) + if ( j < MAX_FALLBACK_DEPTH_TEXTURES ) { pRenderContext->SetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, 0 ); } @@ -4498,35 +4631,26 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) shadowView.x = shadowView.y = 0; shadowView.width = shadowDepthTexture->GetActualWidth(); shadowView.height = shadowDepthTexture->GetActualHeight(); -#ifndef ASW_PROJECTED_TEXTURES +#ifndef MAPBASE shadowView.m_bOrtho = false; shadowView.m_bDoBloomAndToneMapping = false; -#ifdef MAPBASE - shadowView.m_flAspectRatio = (flashlightState.m_fHorizontalFOVDegrees / flashlightState.m_fVerticalFOVDegrees); -#endif // MAPBASE #endif // Copy flashlight parameters -#ifdef ASW_PROJECTED_TEXTURES - if ( !flashlightState.m_bOrtho ) +#ifdef MAPBASE + if ( !shadow.m_FlashlightExtras.m_bOrtho ) { shadowView.m_bOrtho = false; - -#ifdef MAPBASE shadowView.m_flAspectRatio = (flashlightState.m_fHorizontalFOVDegrees / flashlightState.m_fVerticalFOVDegrees); -#endif // MAPBASE } else { shadowView.m_bOrtho = true; - shadowView.m_OrthoLeft = flashlightState.m_fOrthoLeft; - shadowView.m_OrthoTop = flashlightState.m_fOrthoTop; - shadowView.m_OrthoRight = flashlightState.m_fOrthoRight; - shadowView.m_OrthoBottom = flashlightState.m_fOrthoBottom; - -#ifdef MAPBASE + shadowView.m_OrthoLeft = shadow.m_FlashlightExtras.m_fOrthoLeft; + shadowView.m_OrthoTop = shadow.m_FlashlightExtras.m_fOrthoTop; + shadowView.m_OrthoRight = shadow.m_FlashlightExtras.m_fOrthoRight; + shadowView.m_OrthoBottom = shadow.m_FlashlightExtras.m_fOrthoBottom; shadowView.m_flAspectRatio = 1.0f; -#endif } shadowView.m_bDoBloomAndToneMapping = false; @@ -4554,16 +4678,12 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) view->UpdateShadowDepthTexture( m_DummyColorTexture, shadowDepthTexture, shadowView ); #ifdef MAPBASE - if ( j <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) + if ( j < MAX_FALLBACK_DEPTH_TEXTURES ) { - pRenderContext->SetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, intp((ITexture*)shadowDepthTexture) ); - - FlashlightState_t state = shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ); - - state.m_nShadowQuality = state.m_nShadowQuality | ( ( j + 1 ) << 16 ); - - shadowmgr->UpdateFlashlightState( shadow.m_ShadowHandle, state ); + SetFallbackDepthTexture( pRenderContext, j, shadow.m_ShadowHandle, flashlightState, shadowDepthTexture ); } + + shadowmgr->UpdateFlashlightState( shadow.m_ShadowHandle, flashlightState ); #endif // Associate the shadow depth texture and stencil bit with the flashlight for use during scene rendering @@ -4573,6 +4693,53 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) SetViewFlashlightState( nActiveDepthShadowCount, pActiveDepthShadows ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CClientShadowMgr::SetFallbackDepthTexture( CMatRenderContextPtr &pRenderContext, int j, ShadowHandle_t handle, FlashlightState_t &flashlightState, ITexture *depthTexture ) +{ + flashlightState.m_nShadowQuality |= ((j + 1) << 16); + +#ifdef PLATFORM_64BITS + // Pointer size is doubled + j *= 2; + + if ( j >= MAX_FALLBACK_DEPTH_TEXTURES ) + { + j -= MAX_FALLBACK_DEPTH_TEXTURES; + + // Awful, but necessary. + float flPtr[ sizeof( intp ) / sizeof( float ) ]; + memcpy( flPtr, &depthTexture, sizeof( intp ) ); + + pRenderContext->SetFloatRenderingParameter( FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, flPtr[0] ); + pRenderContext->SetFloatRenderingParameter( FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j + 1, flPtr[1] ); + } + else + { + // Awful, but necessary. + int iPtr[ sizeof( intp ) / sizeof( int ) ]; + memcpy( iPtr, &depthTexture, sizeof( intp ) ); + + pRenderContext->SetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, iPtr[0] ); + pRenderContext->SetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j + 1, iPtr[1] ); + } +#else + pRenderContext->SetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, intp( depthTexture ) ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CClientShadowMgr::SetFlashlightExtras( ClientShadowHandle_t shadowHandle, const FlashlightStateExtras_t &stateExtras ) +{ + ClientShadow_t &shadow = m_Shadows[ shadowHandle ]; + shadow.m_FlashlightExtras = stateExtras; +} +#endif + //----------------------------------------------------------------------------- // Re-renders all shadow textures for shadow casters that lie in the leaf list @@ -4590,11 +4757,7 @@ void CClientShadowMgr::ComputeShadowTextures( const CViewSetup &viewShadow, int if ( !m_RenderToTextureActive || (r_shadows.GetInt() == 0) || r_shadows_gamecontrol.GetInt() == 0 ) return; -#ifdef ASW_PROJECTED_TEXTURES m_bThreaded = ( r_threaded_client_shadow_manager.GetBool() && g_pThreadPool->NumIdleThreads() ); -#else - m_bThreaded = false;//( r_threaded_client_shadow_manager.GetBool() && g_pThreadPool->NumIdleThreads() ); -#endif MDLCACHE_CRITICAL_SECTION(); // First grab all shadow textures we may want to render @@ -4700,19 +4863,25 @@ void CClientShadowMgr::ComputeShadowTextures( const CViewSetup &viewShadow, int //------------------------------------------------------------------------------------------------------- // Lock down the usage of a shadow depth texture...must be unlocked for use on subsequent views / frames //------------------------------------------------------------------------------------------------------- -bool CClientShadowMgr::LockShadowDepthTexture( CTextureReference *shadowDepthTexture ) +int CClientShadowMgr::LockShadowDepthTexture( CTextureReference *shadowDepthTexture, int iStartIdx ) { - for ( int i=0; i < m_DepthTextureCache.Count(); i++ ) // Search for cached shadow depth texture + for ( int i=iStartIdx; i < m_DepthTextureCache.Count(); i++ ) // Search for cached shadow depth texture { if ( m_DepthTextureCacheLocks[i] == false ) // If a free one is found { *shadowDepthTexture = m_DepthTextureCache[i]; m_DepthTextureCacheLocks[i] = true; - return true; + return i; } } - return false; // Didn't find it... +#ifdef MAPBASE + // If we didn't start at 0, try starting from the beginning + if ( iStartIdx != 0 ) + return LockShadowDepthTexture( shadowDepthTexture ); +#endif + + return -1; // Didn't find it... } //------------------------------------------------------------------ diff --git a/src/game/client/iclientshadowmgr.h b/src/game/client/iclientshadowmgr.h index df8f9352e7a..eb06b11e55a 100644 --- a/src/game/client/iclientshadowmgr.h +++ b/src/game/client/iclientshadowmgr.h @@ -36,6 +36,32 @@ enum ShadowReceiver_t }; +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Extra data for FlashlightState_t +//----------------------------------------------------------------------------- +struct FlashlightStateExtras_t +{ + // From Alien Swarm SDK + // ------------------------------ + float m_fOrthoLeft; + float m_fOrthoRight; + float m_fOrthoTop; + float m_fOrthoBottom; + + float m_FarZAtten; + //float m_fBrightnessScale; + + bool m_bOrtho = false; + bool m_bGlobalLight = false; + // ------------------------------ + + bool m_bAlwaysDraw = false; + float m_flBaseShadowFilterSize = 0.0f; +}; +#endif + + //----------------------------------------------------------------------------- // The class responsible for dealing with shadows on the client side //----------------------------------------------------------------------------- @@ -97,9 +123,7 @@ abstract_class IClientShadowMgr : public IGameSystemPerFrame // Set flashlight light world flag virtual void SetFlashlightLightWorld( ClientShadowHandle_t shadowHandle, bool bLightWorld ) = 0; -#ifdef ASW_PROJECTED_TEXTURES virtual void GetFrustumExtents( ClientShadowHandle_t handle, Vector &vecMin, Vector &vecMax ) = 0; -#endif #ifdef DYNAMIC_RTT_SHADOWS // Toggle shadow casting from world light sources @@ -110,6 +134,10 @@ abstract_class IClientShadowMgr : public IGameSystemPerFrame virtual void ComputeShadowDepthTextures( const CViewSetup &pView ) = 0; +#ifdef MAPBASE + virtual void SetFlashlightExtras( ClientShadowHandle_t shadowHandle, const FlashlightStateExtras_t &stateExtras ) = 0; +#endif + }; diff --git a/src/game/client/viewrender.cpp b/src/game/client/viewrender.cpp index b9fba9f8a07..a24f73cd1b3 100644 --- a/src/game/client/viewrender.cpp +++ b/src/game/client/viewrender.cpp @@ -1535,9 +1535,7 @@ void CViewRender::ViewDrawScene( bool bDrew3dSkybox, SkyboxVisibility_t nSkyboxV if ( r_flashlightdepthtexture.GetBool() && (viewID == VIEW_MAIN) ) { g_pClientShadowMgr->ComputeShadowDepthTextures( viewRender ); -#ifdef ASW_PROJECTED_TEXTURES CMatRenderContextPtr pRenderContext( materials ); -#endif } m_BaseDrawFlags = baseDrawFlags; @@ -3351,9 +3349,7 @@ void CViewRender::ViewDrawScene_Intro( const CViewSetup &viewRender, int nClearF if ( r_flashlightdepthtexture.GetBool() ) { g_pClientShadowMgr->ComputeShadowDepthTextures( viewRender ); -#ifdef ASW_PROJECTED_TEXTURES CMatRenderContextPtr pRenderContext( materials ); -#endif } // ----------------------------------------------------------------------- diff --git a/src/game/server/env_projectedtexture.cpp b/src/game/server/env_projectedtexture.cpp index 15fb1367c51..d48fdd22d79 100644 --- a/src/game/server/env_projectedtexture.cpp +++ b/src/game/server/env_projectedtexture.cpp @@ -6,15 +6,11 @@ #include "cbase.h" #include "shareddefs.h" -#ifdef ASW_PROJECTED_TEXTURES #include "env_projectedtexture.h" -#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -#ifdef ASW_PROJECTED_TEXTURES - LINK_ENTITY_TO_CLASS( env_projectedtexture, CEnvProjectedTexture ); BEGIN_DATADESC( CEnvProjectedTexture ) @@ -72,6 +68,7 @@ BEGIN_DATADESC( CEnvProjectedTexture ) DEFINE_INPUTFUNC( FIELD_STRING, "SpotlightTexture", InputSetSpotlightTexture ), #ifdef MAPBASE DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSpotlightFrame", InputSetSpotlightFrame ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetShadowQuality", InputSetShadowQuality ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetBrightness", InputSetBrightness ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetColorTransitionTime", InputSetColorTransitionTime ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetQuadratic", InputSetQuadratic ), @@ -112,8 +109,8 @@ IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture ) SendPropInt( SENDINFO( m_nSpotlightTextureFrame ) ), SendPropFloat( SENDINFO( m_flNearZ ), 16, SPROP_ROUNDDOWN, 0.0f, 500.0f ), SendPropFloat( SENDINFO( m_flFarZ ), 18, SPROP_ROUNDDOWN, 0.0f, 1500.0f ), - SendPropInt( SENDINFO( m_nShadowQuality ), 1, SPROP_UNSIGNED ), // Just one bit for now #ifdef MAPBASE + SendPropInt( SENDINFO( m_nShadowQuality ), 3, SPROP_UNSIGNED ), SendPropFloat( SENDINFO( m_flConstantAtten ) ), SendPropFloat( SENDINFO( m_flLinearAtten ) ), SendPropFloat( SENDINFO( m_flQuadraticAtten ) ), @@ -123,6 +120,8 @@ IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture ) // Not needed on the client right now, change when it actually is needed //SendPropBool( SENDINFO( m_bProjectedTextureVersion ) ), +#else + SendPropInt( SENDINFO( m_nShadowQuality ), 1, SPROP_UNSIGNED ), // Just one bit for now #endif END_SEND_TABLE() @@ -378,6 +377,11 @@ void CEnvProjectedTexture::InputSetSpotlightFrame( inputdata_t &inputdata ) m_nSpotlightTextureFrame = inputdata.value.Int(); } +void CEnvProjectedTexture::InputSetShadowQuality( inputdata_t &inputdata ) +{ + m_nShadowQuality = inputdata.value.Int(); +} + void CEnvProjectedTexture::InputSetBrightness( inputdata_t &inputdata ) { m_flBrightnessScale = inputdata.value.Float(); @@ -465,317 +469,6 @@ int CEnvProjectedTexture::UpdateTransmitState() return SetTransmitState( FL_EDICT_ALWAYS ); } -#else - -#define ENV_PROJECTEDTEXTURE_STARTON (1<<0) -#ifdef MAPBASE -#define ENV_PROJECTEDTEXTURE_ALWAYSUPDATE (1<<1) -#endif - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -class CEnvProjectedTexture : public CPointEntity -{ - DECLARE_CLASS( CEnvProjectedTexture, CPointEntity ); -public: - DECLARE_DATADESC(); - DECLARE_SERVERCLASS(); - - CEnvProjectedTexture(); - bool KeyValue( const char *szKeyName, const char *szValue ); - - // Always transmit to clients - virtual int UpdateTransmitState(); - virtual void Activate( void ); - - void InputTurnOn( inputdata_t &inputdata ); - void InputTurnOff( inputdata_t &inputdata ); -#ifdef MAPBASE - void InputAlwaysUpdateOn( inputdata_t &inputdata ); - void InputAlwaysUpdateOff( inputdata_t &inputdata ); -#endif - void InputSetFOV( inputdata_t &inputdata ); - void InputSetTarget( inputdata_t &inputdata ); - void InputSetCameraSpace( inputdata_t &inputdata ); - void InputSetLightOnlyTarget( inputdata_t &inputdata ); - void InputSetLightWorld( inputdata_t &inputdata ); - void InputSetEnableShadows( inputdata_t &inputdata ); -#ifndef MAPBASE -// void InputSetLightColor( inputdata_t &inputdata ); -#else - void InputSetLightColor( inputdata_t &inputdata ); -#endif - void InputSetSpotlightTexture( inputdata_t &inputdata ); - void InputSetAmbient( inputdata_t &inputdata ); - - void InitialThink( void ); - - CNetworkHandle( CBaseEntity, m_hTargetEntity ); - -private: - - CNetworkVar( bool, m_bState ); -#ifdef MAPBASE - CNetworkVar( bool, m_bAlwaysUpdate ); -#endif - CNetworkVar( float, m_flLightFOV ); - CNetworkVar( bool, m_bEnableShadows ); - CNetworkVar( bool, m_bLightOnlyTarget ); - CNetworkVar( bool, m_bLightWorld ); - CNetworkVar( bool, m_bCameraSpace ); - CNetworkVector( m_LinearFloatLightColor ); - CNetworkVar( float, m_flAmbient ); - CNetworkString( m_SpotlightTextureName, MAX_PATH ); - CNetworkVar( int, m_nSpotlightTextureFrame ); - CNetworkVar( float, m_flNearZ ); - CNetworkVar( float, m_flFarZ ); - CNetworkVar( int, m_nShadowQuality ); -}; - -LINK_ENTITY_TO_CLASS( env_projectedtexture, CEnvProjectedTexture ); - -BEGIN_DATADESC( CEnvProjectedTexture ) - DEFINE_FIELD( m_hTargetEntity, FIELD_EHANDLE ), - DEFINE_FIELD( m_bState, FIELD_BOOLEAN ), - DEFINE_KEYFIELD( m_flLightFOV, FIELD_FLOAT, "lightfov" ), - DEFINE_KEYFIELD( m_bEnableShadows, FIELD_BOOLEAN, "enableshadows" ), - DEFINE_KEYFIELD( m_bLightOnlyTarget, FIELD_BOOLEAN, "lightonlytarget" ), - DEFINE_KEYFIELD( m_bLightWorld, FIELD_BOOLEAN, "lightworld" ), - DEFINE_KEYFIELD( m_bCameraSpace, FIELD_BOOLEAN, "cameraspace" ), - DEFINE_KEYFIELD( m_flAmbient, FIELD_FLOAT, "ambient" ), -#ifndef MAPBASE - DEFINE_AUTO_ARRAY_KEYFIELD( m_SpotlightTextureName, FIELD_CHARACTER, "texturename" ), -#else - DEFINE_AUTO_ARRAY( m_SpotlightTextureName, FIELD_CHARACTER ), -#endif - DEFINE_KEYFIELD( m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe" ), - DEFINE_KEYFIELD( m_flNearZ, FIELD_FLOAT, "nearz" ), - DEFINE_KEYFIELD( m_flFarZ, FIELD_FLOAT, "farz" ), - DEFINE_KEYFIELD( m_nShadowQuality, FIELD_INTEGER, "shadowquality" ), - DEFINE_FIELD( m_LinearFloatLightColor, FIELD_VECTOR ), - - DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ), - DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), -#ifdef MAPBASE - DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOn", InputAlwaysUpdateOn ), - DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOff", InputAlwaysUpdateOff ), -#endif - DEFINE_INPUTFUNC( FIELD_FLOAT, "FOV", InputSetFOV ), - DEFINE_INPUTFUNC( FIELD_EHANDLE, "Target", InputSetTarget ), - DEFINE_INPUTFUNC( FIELD_BOOLEAN, "CameraSpace", InputSetCameraSpace ), - DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightOnlyTarget", InputSetLightOnlyTarget ), - DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightWorld", InputSetLightWorld ), - DEFINE_INPUTFUNC( FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows ), -#ifndef MAPBASE - // this is broken . . need to be able to set color and intensity like light_dynamic -// DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ), -#else - DEFINE_INPUTFUNC( FIELD_STRING, "LightColor", InputSetLightColor ), -#endif - DEFINE_INPUTFUNC( FIELD_FLOAT, "Ambient", InputSetAmbient ), - DEFINE_INPUTFUNC( FIELD_STRING, "SpotlightTexture", InputSetSpotlightTexture ), - DEFINE_THINKFUNC( InitialThink ), -END_DATADESC() - -IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture ) - SendPropEHandle( SENDINFO( m_hTargetEntity ) ), - SendPropBool( SENDINFO( m_bState ) ), -#ifdef MAPBASE - SendPropBool( SENDINFO( m_bAlwaysUpdate ) ), -#endif - SendPropFloat( SENDINFO( m_flLightFOV ) ), - SendPropBool( SENDINFO( m_bEnableShadows ) ), - SendPropBool( SENDINFO( m_bLightOnlyTarget ) ), - SendPropBool( SENDINFO( m_bLightWorld ) ), - SendPropBool( SENDINFO( m_bCameraSpace ) ), - SendPropVector( SENDINFO( m_LinearFloatLightColor ) ), - SendPropFloat( SENDINFO( m_flAmbient ) ), - SendPropString( SENDINFO( m_SpotlightTextureName ) ), - SendPropInt( SENDINFO( m_nSpotlightTextureFrame ) ), - SendPropFloat( SENDINFO( m_flNearZ ), 16, SPROP_ROUNDDOWN, 0.0f, 500.0f ), - SendPropFloat( SENDINFO( m_flFarZ ), 18, SPROP_ROUNDDOWN, 0.0f, 1500.0f ), - SendPropInt( SENDINFO( m_nShadowQuality ), 1, SPROP_UNSIGNED ), // Just one bit for now -END_SEND_TABLE() - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CEnvProjectedTexture::CEnvProjectedTexture( void ) -{ - m_bState = true; - m_flLightFOV = 45.0f; - m_bEnableShadows = false; - m_bLightOnlyTarget = false; - m_bLightWorld = true; - m_bCameraSpace = false; - -// if ( g_pHardwareConfig->SupportsBorderColor() ) -#if defined( _X360 ) - Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight_border" ); -#else - Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight001" ); -#endif - - m_nSpotlightTextureFrame = 0; - m_LinearFloatLightColor.Init( 1.0f, 1.0f, 1.0f ); - m_flAmbient = 0.0f; - m_flNearZ = 4.0f; - m_flFarZ = 750.0f; - m_nShadowQuality = 0; -} - -void UTIL_ColorStringToLinearFloatColor( Vector &color, const char *pString ) -{ - float tmp[4]; - UTIL_StringToFloatArray( tmp, 4, pString ); - if( tmp[3] <= 0.0f ) - { - tmp[3] = 255.0f; - } - tmp[3] *= ( 1.0f / 255.0f ); - color.x = GammaToLinear( tmp[0] * ( 1.0f / 255.0f ) ) * tmp[3]; - color.y = GammaToLinear( tmp[1] * ( 1.0f / 255.0f ) ) * tmp[3]; - color.z = GammaToLinear( tmp[2] * ( 1.0f / 255.0f ) ) * tmp[3]; -} - -bool CEnvProjectedTexture::KeyValue( const char *szKeyName, const char *szValue ) -{ - if ( FStrEq( szKeyName, "lightcolor" ) ) - { - Vector tmp; - UTIL_ColorStringToLinearFloatColor( tmp, szValue ); - m_LinearFloatLightColor = tmp; - } -#ifdef MAPBASE - else if ( FStrEq(szKeyName, "texturename") ) - { - Q_strcpy(m_SpotlightTextureName.GetForModify(), szValue); - } -#endif - else - { - return BaseClass::KeyValue( szKeyName, szValue ); - } - - return true; -} - -void CEnvProjectedTexture::InputTurnOn( inputdata_t &inputdata ) -{ - m_bState = true; -} - -void CEnvProjectedTexture::InputTurnOff( inputdata_t &inputdata ) -{ - m_bState = false; -} - -#ifdef MAPBASE -void CEnvProjectedTexture::InputAlwaysUpdateOn( inputdata_t &inputdata ) -{ - m_bAlwaysUpdate = true; -} - -void CEnvProjectedTexture::InputAlwaysUpdateOff( inputdata_t &inputdata ) -{ - m_bAlwaysUpdate = false; -} -#endif - -void CEnvProjectedTexture::InputSetFOV( inputdata_t &inputdata ) -{ - m_flLightFOV = inputdata.value.Float(); -} - -void CEnvProjectedTexture::InputSetTarget( inputdata_t &inputdata ) -{ - m_hTargetEntity = inputdata.value.Entity(); -} - -void CEnvProjectedTexture::InputSetCameraSpace( inputdata_t &inputdata ) -{ - m_bCameraSpace = inputdata.value.Bool(); -} - -void CEnvProjectedTexture::InputSetLightOnlyTarget( inputdata_t &inputdata ) -{ - m_bLightOnlyTarget = inputdata.value.Bool(); -} - -void CEnvProjectedTexture::InputSetLightWorld( inputdata_t &inputdata ) -{ - m_bLightWorld = inputdata.value.Bool(); -} - -void CEnvProjectedTexture::InputSetEnableShadows( inputdata_t &inputdata ) -{ - m_bEnableShadows = inputdata.value.Bool(); -} - -#ifndef MAPBASE -//void CEnvProjectedTexture::InputSetLightColor( inputdata_t &inputdata ) -//{ -// m_cLightColor = inputdata.value.Color32(); -//} -#else -void CEnvProjectedTexture::InputSetLightColor( inputdata_t &inputdata ) -{ - Vector tmp; - UTIL_ColorStringToLinearFloatColor( tmp, inputdata.value.String() ); - m_LinearFloatLightColor = tmp; -} -#endif - -void CEnvProjectedTexture::InputSetAmbient( inputdata_t &inputdata ) -{ - m_flAmbient = inputdata.value.Float(); -} - -void CEnvProjectedTexture::InputSetSpotlightTexture( inputdata_t &inputdata ) -{ - Q_strcpy( m_SpotlightTextureName.GetForModify(), inputdata.value.String() ); -} - -void CEnvProjectedTexture::Activate( void ) -{ - if ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) - { - m_bState = true; - } -#ifdef MAPBASE - m_bAlwaysUpdate = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) != 0 ); -#endif - - SetThink( &CEnvProjectedTexture::InitialThink ); - SetNextThink( gpGlobals->curtime + 0.1f ); - - BaseClass::Activate(); -} - -void CEnvProjectedTexture::InitialThink( void ) -{ -#ifndef MAPBASE - m_hTargetEntity = gEntList.FindEntityByName( NULL, m_target ); -#else - if (m_hTargetEntity == NULL && m_target != NULL_STRING) - m_hTargetEntity = gEntList.FindEntityByName(NULL, m_target); - if (m_hTargetEntity == NULL) - return; - Vector vecToTarget = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()); - QAngle vecAngles; - VectorAngles(vecToTarget, vecAngles); - SetAbsAngles(vecAngles); - SetNextThink(gpGlobals->curtime + 0.1); -#endif -} - -int CEnvProjectedTexture::UpdateTransmitState() -{ - return SetTransmitState( FL_EDICT_ALWAYS ); -} - -#endif // Console command for creating env_projectedtexture entities diff --git a/src/game/server/env_projectedtexture.h b/src/game/server/env_projectedtexture.h index 6cb248baad6..442e8dee647 100644 --- a/src/game/server/env_projectedtexture.h +++ b/src/game/server/env_projectedtexture.h @@ -8,7 +8,6 @@ #define ENV_PROJECTEDTEXTURE_STARTON (1<<0) #define ENV_PROJECTEDTEXTURE_ALWAYSUPDATE (1<<1) -#ifdef ASW_PROJECTED_TEXTURES //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -52,6 +51,7 @@ class CEnvProjectedTexture : public CPointEntity void InputSetAmbient( inputdata_t &inputdata ); #ifdef MAPBASE void InputSetSpotlightFrame( inputdata_t &inputdata ); + void InputSetShadowQuality( inputdata_t &inputdata ); void InputSetBrightness( inputdata_t &inputdata ); void InputSetColorTransitionTime( inputdata_t &inputdata ); void InputSetConstant( inputdata_t &inputdata ) { m_flConstantAtten = CorrectConstantAtten(inputdata.value.Float()); } @@ -116,7 +116,6 @@ class CEnvProjectedTexture : public CPointEntity bool m_bProjectedTextureVersion; #endif }; -#endif #endif // ENV_PROJECTEDTEXTURE_H \ No newline at end of file diff --git a/src/game/shared/mapbase/mapbase_shared.cpp b/src/game/shared/mapbase/mapbase_shared.cpp index c749728dbd3..550cf4f412a 100644 --- a/src/game/shared/mapbase/mapbase_shared.cpp +++ b/src/game/shared/mapbase/mapbase_shared.cpp @@ -167,8 +167,6 @@ bool CMapbaseSystem::Init() gameinfo->deleteThis(); #ifdef CLIENT_DLL - InitializeRTs(); - // Shared Mapbase scripts to avoid overwriting mod files g_pVGuiLocalize->AddFile( "resource/mapbase_%language%.txt" ); #ifdef HL2_CLIENT_DLL @@ -314,6 +312,36 @@ void CMapbaseSystem::InitializeRTs() { if (!m_bInitializedRTs) { + SetDefLessFunc( m_RenderTargetData ); + + KeyValues *pKV = new KeyValues("RenderTargets"); + if (pKV->LoadFromFile( filesystem, "scripts/render_targets.txt" )) + { + HKeySymbol hShadowDepthTextures = KeyValuesSystem()->GetSymbolForString( "ShadowDepthTextures", false ); + for (KeyValues *pKey = pKV->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey()) + { + if ( pKey->GetNameSymbol() == hShadowDepthTextures ) + { + // Depth textures are split into subkeys + for (KeyValues *pSub = pKey->GetFirstSubKey(); pSub; pSub = pSub->GetNextKey()) + { + RenderTargetData_t data; + data.nRes = pSub->GetInt( "res" ); + data.nNum = pSub->GetInt( "num" ); + m_RenderTargetData.Insert( pSub->GetNameSymbol(), data ); + } + } + else + { + RenderTargetData_t data; + data.nRes = pKey->GetInt( "res" ); + data.nNum = pKey->GetInt( "num" ); + m_RenderTargetData.Insert( pKey->GetNameSymbol(), data ); + } + } + } + pKV->deleteThis(); + int iNumCameras = CommandLine()->ParmValue( "-numcameratextures", 3 ); materials->BeginRenderTargetAllocation(); diff --git a/src/game/shared/mapbase/mapbase_shared.h b/src/game/shared/mapbase/mapbase_shared.h index 64b10a32145..568477d95c9 100644 --- a/src/game/shared/mapbase/mapbase_shared.h +++ b/src/game/shared/mapbase/mapbase_shared.h @@ -137,6 +137,21 @@ class CMapbaseSystem : public CAutoGameSystem const char *string; }; +#ifdef CLIENT_DLL + struct RenderTargetData_t + { + short nRes, nNum; + }; + + inline const RenderTargetData_t *LookupRenderTargetData( HKeySymbol hSymbol ) + { + unsigned short i = m_RenderTargetData.Find( hSymbol ); + if ( i == m_RenderTargetData.InvalidIndex() ) + return NULL; + return &m_RenderTargetData[i]; + } +#endif + private: HKeySymbol m_iManifestFileSymbols[MANIFEST_NUM_TYPES] = { -1 }; @@ -145,10 +160,14 @@ class CMapbaseSystem : public CAutoGameSystem bool m_bInitializedRTs = false; CUtlVector m_CameraTextures; + CUtlMap m_RenderTargetData; + CUtlVector m_CloseCaptionFileNames; #endif }; +extern CMapbaseSystem g_MapbaseSystem; + // // Dynamic mod-based mod title comments // diff --git a/src/materialsystem/stdshaders/BaseVSShader.cpp b/src/materialsystem/stdshaders/BaseVSShader.cpp index 8cb6a4ac951..3a4da4c3075 100644 --- a/src/materialsystem/stdshaders/BaseVSShader.cpp +++ b/src/materialsystem/stdshaders/BaseVSShader.cpp @@ -1898,7 +1898,7 @@ void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAP vshIndex.SetNORMALMAP( vars.m_bBump ); vshIndex.SetSEAMLESS( bSeamless ); vshIndex.SetDETAIL( bDetail ); - pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs20", vshIndex.GetIndex() ); + pShaderShadow->SetVertexShader( SHADER_PREFIX "lightmappedgeneric_flashlight_vs20", vshIndex.GetIndex() ); unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; if( vars.m_bBump ) @@ -1917,7 +1917,7 @@ void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAP { vertexlitgeneric_flashlight_vs11_Static_Index vshIndex; vshIndex.SetTEETH( vars.m_bTeeth ); - pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() ); + pShaderShadow->SetVertexShader( SHADER_PREFIX "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() ); unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; int numTexCoords = 1; @@ -1941,7 +1941,7 @@ void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAP pshIndex.SetDETAILTEXTURE( bDetail ); pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); pshIndex.SetFLASHLIGHTDEPTHFILTERMODE( nShadowFilterMode ); - pShaderShadow->SetPixelShader( "flashlight_ps20b", pshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( SHADER_PREFIX "flashlight_ps20b", pshIndex.GetIndex() ); } else { @@ -1952,7 +1952,7 @@ void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAP pshIndex.SetSEAMLESS( bSeamless ); pshIndex.SetDETAILTEXTURE( bDetail ); pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); - pShaderShadow->SetPixelShader( "flashlight_ps20", pshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( SHADER_PREFIX "flashlight_ps20", pshIndex.GetIndex() ); } FogToBlack(); } @@ -1962,6 +1962,14 @@ void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAP ITexture *pFlashlightDepthTexture; FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + if ( pFlashlightDepthTexture == NULL ) + { + pFlashlightDepthTexture = GetFallbackDepthTexture( pShaderAPI, flashlightState ); + } + + float flFlashlightPos[4] = { XYZ( flashlightState.m_vecLightOrigin ) }; + pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, flFlashlightPos ); + SetFlashLightColorFromState( flashlightState, pShaderAPI ); BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); @@ -2104,6 +2112,55 @@ void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAP #endif +ITexture *CBaseVSShader::GetFallbackDepthTexture( IShaderDynamicAPI *pShaderAPI, FlashlightState_t &flashlightState ) +{ + int iFlashlightShadowIndex = ( flashlightState.m_nShadowQuality >> 16 ) - 1; + + if ( iFlashlightShadowIndex >= 0 ) + { + const int iMaxIntParam = (INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST); + +#ifdef PLATFORM_64BITS + // Pointer size is doubled + iFlashlightShadowIndex *= 2; +#endif + +#ifdef PLATFORM_64BITS + if ( iFlashlightShadowIndex <= iMaxIntParam ) + { + // Horrid, but necessary. + int iPtr[ sizeof( intp ) / sizeof( int ) ]; + iPtr[0] = pShaderAPI->GetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex ); + iPtr[1] = pShaderAPI->GetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex + 1 ); + + intp ptr; + memcpy( &ptr, &iPtr, sizeof( intp ) ); + return (ITexture *)ptr; + } + else if ( iFlashlightShadowIndex <= ( iMaxIntParam + (FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST) ) ) + { + iFlashlightShadowIndex -= iMaxIntParam; + + // Horrid, but necessary. + float flPtr[sizeof( intp ) / sizeof( float )]; + flPtr[0] = pShaderAPI->GetFloatRenderingParameter( FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex ); + flPtr[1] = pShaderAPI->GetFloatRenderingParameter( FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex + 1 ); + + intp ptr; + memcpy( &ptr, &flPtr, sizeof( intp ) ); + return (ITexture *)ptr; + } +#else + if ( iFlashlightShadowIndex <= iMaxIntParam ) + { + return (ITexture*)pShaderAPI->GetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex ); + } +#endif + } + + return NULL; +} + void CBaseVSShader::InitParamsUnlitGeneric_DX8( int baseTextureVar, int detailScaleVar, diff --git a/src/materialsystem/stdshaders/BaseVSShader.h b/src/materialsystem/stdshaders/BaseVSShader.h index 6ebd2ea0b51..e8ef3b0e743 100644 --- a/src/materialsystem/stdshaders/BaseVSShader.h +++ b/src/materialsystem/stdshaders/BaseVSShader.h @@ -327,6 +327,8 @@ class CBaseVSShader : public CBaseShader }; void DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ); + + ITexture *GetFallbackDepthTexture( IShaderDynamicAPI *pShaderAPI, FlashlightState_t &flashlightState ); #endif // GAME_SHADER_DLL BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 ); diff --git a/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp b/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp index 7226241e84b..90e3063a521 100644 --- a/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp +++ b/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp @@ -588,16 +588,10 @@ void DrawLightmappedGenericFlashlight_DX9_Internal( CBaseVSShader *pShader, IMat ITexture *pFlashlightDepthTexture; FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - /*if ( pFlashlightDepthTexture == NULL ) + if ( pFlashlightDepthTexture == NULL ) { - const int iFlashlightShadowIndex = ( flashlightState.m_nShadowQuality >> 16 ) - 1; - - if ( iFlashlightShadowIndex >= 0 - && iFlashlightShadowIndex <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) - { - pFlashlightDepthTexture = (ITexture*)pShaderAPI->GetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex ); - } - }*/ + pFlashlightDepthTexture = pShader->GetFallbackDepthTexture( pShaderAPI, flashlightState ); + } SetFlashLightColorFromState( flashlightState, pShaderAPI ); diff --git a/src/public/materialsystem/imaterialsystem.h b/src/public/materialsystem/imaterialsystem.h index b59bb6470e8..ff099aad1fe 100644 --- a/src/public/materialsystem/imaterialsystem.h +++ b/src/public/materialsystem/imaterialsystem.h @@ -447,16 +447,11 @@ struct FlashlightState_t { m_bEnableShadows = false; // Provide reasonable defaults for shadow depth mapping parameters m_bDrawShadowFrustum = false; -#ifdef ASW_PROJECTED_TEXTURES +#ifdef MAPBASE m_flShadowMapResolution = 2048.0f; m_flShadowFilterSize = 0.5f; m_flShadowSlopeScaleDepthBias = 16.0f; m_flShadowDepthBias = 0.0005f; -#elif defined(MAPBASE) - m_flShadowMapResolution = 2048; - m_flShadowFilterSize = 1.0f; - m_flShadowSlopeScaleDepthBias = 4.0f; - m_flShadowDepthBias = 0.00001f; #else m_flShadowMapResolution = 1024.0f; m_flShadowFilterSize = 3.0f; @@ -471,14 +466,7 @@ struct FlashlightState_t m_nRight = -1; m_nBottom = -1; m_nShadowQuality = 0; -#ifdef ASW_PROJECTED_TEXTURES - m_bOrtho = false; - m_fOrthoLeft = -1.0f; - m_fOrthoRight = 1.0f; - m_fOrthoTop = -1.0f; - m_fOrthoBottom = 1.0f; - - m_fBrightnessScale = 1.0f; +#ifdef MAPBASE m_pSpotlightTexture = NULL; #endif } @@ -507,22 +495,6 @@ struct FlashlightState_t float m_flShadowAtten; int m_nShadowQuality; -#ifdef ASW_PROJECTED_TEXTURES - bool m_bOrtho; - float m_fOrthoLeft; - float m_fOrthoRight; - float m_fOrthoTop; - float m_fOrthoBottom; - - float m_FarZAtten; - float m_fBrightnessScale; - bool m_bGlobalLight; -#endif - -#ifdef MAPBASE - bool m_bAlwaysDraw; -#endif - // Getters for scissor members bool DoScissor() { return m_bScissor; } int GetLeft() { return m_nLeft; } diff --git a/src/public/renderparm.h b/src/public/renderparm.h index 2a906615ef9..2f0e885fcc6 100644 --- a/src/public/renderparm.h +++ b/src/public/renderparm.h @@ -53,8 +53,9 @@ enum RenderParamInt_t INT_RENDERPARM_BACK_BUFFER_INDEX, + // NOTE: This can only hold half as many pointers in 64-bit. Extended in RenderParamFloat_t INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST, - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST = INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + 4, + INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST = INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + 3, #ifdef SDK_SP // In lieu of dedicated interface functions @@ -89,6 +90,18 @@ enum RenderParamTexture_t enum RenderParamFloat_t { FLOAT_RENDERPARM_MINIMUMLIGHTING = 0, + +#ifdef PLATFORM_64BITS + // Extension of the depth texture fallbacks in RenderParamInt_t, since pointer size is doubled in 64-bit. + // To avoid hogging up all of the remaining int params, we use the comparatively vacant float param space. + // (this is not ideal at all, of course...) + // + // If you need float render params, and this is causing problems for you, then please feel free to change this. + // We mainly only need to send depth textures across to prevent decals from flickering when multiple flashlights + // are shining at once. + FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST, + FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST = FLOAT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + 3, +#endif }; #endif // RENDERPARM_H From 216430c42a59d6de1902e6ef4d25fd5e414bb32e Mon Sep 17 00:00:00 2001 From: Blixibon Date: Fri, 13 Nov 2026 21:27:28 -0600 Subject: [PATCH 7/7] Replace Mapbase's "global strings" with a different standard for optimized classname matching --- src/game/server/baseentity.h | 23 +++++ src/game/server/episodic/npc_hunter.cpp | 23 +---- src/game/server/filters.cpp | 7 -- src/game/server/fire.cpp | 13 +-- src/game/server/hl2/npc_alyx_episodic.cpp | 9 -- src/game/server/hl2/npc_citizen17.cpp | 41 ++------ src/game/server/hl2/npc_combine.cpp | 31 ++---- src/game/server/hl2/npc_metropolice.cpp | 33 ++----- src/game/server/hl2/npc_playercompanion.cpp | 65 ++----------- src/game/server/hl2/npc_playercompanion.h | 14 --- src/game/server/hl2/npc_strider.cpp | 13 +-- src/game/server/hl2/weapon_physcannon.cpp | 9 +- src/game/server/mapbase/GlobalStrings.cpp | 100 -------------------- src/game/server/mapbase/GlobalStrings.h | 81 +--------------- src/game/server/mapbase/ai_grenade.h | 3 +- src/game/server/player.cpp | 3 - src/game/server/props.cpp | 22 +---- src/game/server/server_mapbase.vpc | 2 - src/game/shared/gamestringpool.cpp | 7 -- src/game/shared/hl2mp/weapon_physcannon.cpp | 3 - 20 files changed, 67 insertions(+), 435 deletions(-) delete mode 100644 src/game/server/mapbase/GlobalStrings.cpp diff --git a/src/game/server/baseentity.h b/src/game/server/baseentity.h index 00248ee29c7..cd549ad3f0b 100644 --- a/src/game/server/baseentity.h +++ b/src/game/server/baseentity.h @@ -667,6 +667,11 @@ class CBaseEntity : public IServerEntity bool NameMatches( string_t nameStr ); bool ClassMatches( string_t nameStr ); + // Variant of ClassMatches() optimized for hardcoded classnames with no wildcards. + // Use this when you are matching a single string literal classname. + bool ClassMatchesDirect( const char *pszStrLiteralClass ); + bool ClassMatchesDirect( string_t strPooledString ); + private: bool NameMatchesComplex( const char *pszNameOrWildcard ); bool ClassMatchesComplex( const char *pszClassOrWildcard ); @@ -2534,6 +2539,17 @@ inline bool CBaseEntity::ClassMatches( string_t nameStr ) return ClassMatchesComplex( STRING(nameStr) ); } +inline bool CBaseEntity::ClassMatchesDirect( const char *pszStrLiteralClass ) +{ + const string_t str = AllocPooledString_StaticConstantStringPointer( pszStrLiteralClass ); + return ( m_iClassname == str ); +} + +inline bool CBaseEntity::ClassMatchesDirect( string_t strPooledString ) +{ + return ( m_iClassname == strPooledString ); +} + inline EHANDLE CBaseEntity::ScriptGetEHandle( void ) { return EHANDLE( this ); @@ -3230,6 +3246,13 @@ inline bool FClassnameIs(CBaseEntity *pEntity, const char *szClassname) return pEntity->ClassMatches(szClassname); } +// Variant of FClassnameIs() optimized for hardcoded classnames with no wildcards. +// Use this when you are matching a single string literal classname. +inline bool FClassnameIsDirect(CBaseEntity *pEntity, const char *szStrLiteralClassname) +{ + return pEntity->ClassMatchesDirect(szStrLiteralClassname); +} + class CPointEntity : public CBaseEntity { public: diff --git a/src/game/server/episodic/npc_hunter.cpp b/src/game/server/episodic/npc_hunter.cpp index 0699d890616..2c068392794 100644 --- a/src/game/server/episodic/npc_hunter.cpp +++ b/src/game/server/episodic/npc_hunter.cpp @@ -63,9 +63,6 @@ #include "weapon_striderbuster.h" #include "monstermaker.h" #include "weapon_rpg.h" -#ifdef MAPBASE -#include "mapbase/GlobalStrings.h" -#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -204,19 +201,11 @@ int g_interactionHunterFoundEnemy = 0; //----------------------------------------------------------------------------- // Local stuff. //----------------------------------------------------------------------------- -#ifdef MAPBASE -#define s_iszStriderClassname gm_isz_class_Strider -#define s_iszPhysPropClassname gm_isz_class_PropPhysics -static string_t s_iszStriderBusterClassname; -static string_t s_iszMagnadeClassname; -static string_t s_iszHuntersToRunOver; -#else static string_t s_iszStriderClassname; static string_t s_iszStriderBusterClassname; static string_t s_iszMagnadeClassname; static string_t s_iszPhysPropClassname; static string_t s_iszHuntersToRunOver; -#endif //----------------------------------------------------------------------------- @@ -4421,11 +4410,7 @@ void CNPC_Hunter::HandleAnimEvent( animevent_t *pEvent ) //----------------------------------------------------------------------------- void CNPC_Hunter::AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority ) { -#ifdef MAPBASE - if ( nDisposition == D_HT && pEntity->ClassMatches(gm_isz_class_Bullseye) ) -#else - if ( nDisposition == D_HT && pEntity->ClassMatches("npc_bullseye") ) -#endif + if ( nDisposition == D_HT && pEntity->ClassMatchesDirect("npc_bullseye") ) UpdateEnemyMemory( pEntity, pEntity->GetAbsOrigin() ); BaseClass::AddEntityRelationship( pEntity, nDisposition, nPriority ); } @@ -5060,11 +5045,7 @@ int CNPC_Hunter::RangeAttack2Conditions( float flDot, float flDist ) { return COND_TOO_FAR_TO_ATTACK; } -#ifdef MAPBASE - else if ( !bIsBuster && ( !GetEnemy() || !GetEnemy()->ClassMatches( gm_isz_class_Bullseye ) ) && flDist < hunter_flechette_min_range.GetFloat() ) -#else - else if ( !bIsBuster && ( !GetEnemy() || !GetEnemy()->ClassMatches( "npc_bullseye" ) ) && flDist < hunter_flechette_min_range.GetFloat() ) -#endif + else if ( !bIsBuster && ( !GetEnemy() || !GetEnemy()->ClassMatchesDirect( "npc_bullseye" ) ) && flDist < hunter_flechette_min_range.GetFloat() ) { return COND_TOO_CLOSE_TO_ATTACK; } diff --git a/src/game/server/filters.cpp b/src/game/server/filters.cpp index ca2f6c7af4a..63930cd62ad 100644 --- a/src/game/server/filters.cpp +++ b/src/game/server/filters.cpp @@ -13,7 +13,6 @@ #include "mapbase/matchers.h" #include "AI_Criteria.h" #include "ai_hint.h" -#include "mapbase/GlobalStrings.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -750,9 +749,7 @@ class CFilterEnemy : public CBaseFilter float m_flRadius; // Radius (enemies are acquired at this range) float m_flOuterRadius; // Outer radius (enemies are LOST at this range) int m_nMaxSquadmatesPerEnemy; // Maximum number of squadmates who may share the same enemy -#ifndef MAPBASE string_t m_iszPlayerName; // "!player" -#endif }; //----------------------------------------------------------------------------- @@ -811,9 +808,6 @@ bool CFilterEnemy::PassesNameFilter( CBaseEntity *pEnemy ) if ( m_iszEnemyName == NULL_STRING ) return true; -#ifdef MAPBASE - if ( m_iszEnemyName == gm_isz_name_player ) -#else // Cache off the special case player name if ( m_iszPlayerName == NULL_STRING ) { @@ -821,7 +815,6 @@ bool CFilterEnemy::PassesNameFilter( CBaseEntity *pEnemy ) } if ( m_iszEnemyName == m_iszPlayerName ) -#endif { if ( pEnemy->IsPlayer() ) { diff --git a/src/game/server/fire.cpp b/src/game/server/fire.cpp index 941819c97db..6a8cb5cdec7 100644 --- a/src/game/server/fire.cpp +++ b/src/game/server/fire.cpp @@ -21,7 +21,6 @@ #ifdef HL2_DLL #include "weapon_flaregun.h" #endif -#include "mapbase/GlobalStrings.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -256,11 +255,7 @@ IterationRetval_t CFireSphere::EnumElement( IHandleEntity *pHandleEntity ) { // UNDONE: Measure which of these is faster // CFire *pFire = dynamic_cast(pEntity); -#ifdef MAPBASE - if ( !EntIsClass( pEntity, gm_isz_class_EnvFire ) ) -#else - if ( !FClassnameIs( pEntity, "env_fire" ) ) -#endif + if ( !FClassnameIsDirect( pEntity, "env_fire" ) ) return ITERATION_CONTINUE; CFire *pFire = static_cast(pEntity); @@ -1012,11 +1007,7 @@ void CFire::Update( float simTime ) { continue; } -#ifdef MAPBASE - else if ( EntIsClass( pOther, gm_isz_class_EnvFire ) ) -#else - else if ( FClassnameIs( pOther, "env_fire" ) ) -#endif + else if ( FClassnameIsDirect( pOther, "env_fire" ) ) { if ( fireCount < ARRAYSIZE(pFires) ) { diff --git a/src/game/server/hl2/npc_alyx_episodic.cpp b/src/game/server/hl2/npc_alyx_episodic.cpp index dd5a35b0dda..ce836b5810f 100644 --- a/src/game/server/hl2/npc_alyx_episodic.cpp +++ b/src/game/server/hl2/npc_alyx_episodic.cpp @@ -36,9 +36,6 @@ #include "ai_interactions.h" #include "weapon_flaregun.h" #include "env_debughistory.h" -#ifdef MAPBASE -#include "mapbase/GlobalStrings.h" -#endif extern Vector PointOnLineNearestPoint(const Vector& vStartPos, const Vector& vEndPos, const Vector& vPoint); @@ -403,15 +400,9 @@ void CNPC_Alyx::Precache() UTIL_PrecacheOther( "env_alyxemp" ); CLASSNAME_ALYXGUN = AllocPooledString( "weapon_alyxgun" ); -#ifdef MAPBASE - CLASSNAME_SMG1 = gm_iszSMG1Classname; - CLASSNAME_SHOTGUN = gm_iszShotgunClassname; - CLASSNAME_AR2 = gm_iszAR2Classname; -#else CLASSNAME_SMG1 = AllocPooledString( "weapon_smg1" ); CLASSNAME_SHOTGUN = AllocPooledString( "weapon_shotgun" ); CLASSNAME_AR2 = AllocPooledString( "weapon_ar2" ); -#endif } //----------------------------------------------------------------------------- diff --git a/src/game/server/hl2/npc_citizen17.cpp b/src/game/server/hl2/npc_citizen17.cpp index 181cb7a7302..30d1418f135 100644 --- a/src/game/server/hl2/npc_citizen17.cpp +++ b/src/game/server/hl2/npc_citizen17.cpp @@ -27,7 +27,6 @@ #ifdef MAPBASE #include "hl2_gamerules.h" -#include "mapbase/GlobalStrings.h" #include "collisionutils.h" #endif @@ -939,11 +938,7 @@ void CNPC_Citizen::SelectExpressionType() void CNPC_Citizen::FixupMattWeapon() { CBaseCombatWeapon *pWeapon = GetActiveWeapon(); -#ifdef MAPBASE - if ( pWeapon && EntIsClass( pWeapon, gm_isz_class_Crowbar ) && NameMatches( "matt" ) ) -#else - if ( pWeapon && pWeapon->ClassMatches( "weapon_crowbar" ) && NameMatches( "matt" ) ) -#endif + if ( pWeapon && pWeapon->ClassMatchesDirect( "weapon_crowbar" ) && NameMatches( "matt" ) ) { Weapon_Drop( pWeapon ); UTIL_Remove( pWeapon ); @@ -1402,7 +1397,7 @@ int CNPC_Citizen::SelectSchedule() #endif #ifdef MAPBASE - if ( GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_RPG) ) + if ( GetActiveWeapon() && GetActiveWeapon()->ClassMatchesDirect( "weapon_rpg" ) ) { CWeaponRPG *pRPG = static_cast(GetActiveWeapon()); #else @@ -1723,15 +1718,9 @@ int CNPC_Citizen::TranslateSchedule( int scheduleType ) case SCHED_RANGE_ATTACK1: // If we have an RPG, we use a custom schedule for it -#ifdef MAPBASE - if ( !IsMortar( GetEnemy() ) && GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_RPG) ) + if ( !IsMortar( GetEnemy() ) && GetActiveWeapon() && FClassnameIsDirect( GetActiveWeapon(), "weapon_rpg" ) ) { - if ( GetEnemy() && EntIsClass(GetEnemy(), gm_isz_class_Strider) ) -#else - if ( !IsMortar( GetEnemy() ) && GetActiveWeapon() && FClassnameIs( GetActiveWeapon(), "weapon_rpg" ) ) - { - if ( GetEnemy() && GetEnemy()->ClassMatches( "npc_strider" ) ) -#endif + if ( GetEnemy() && GetEnemy()->ClassMatchesDirect( "npc_strider" ) ) { if (OccupyStrategySlotRange( SQUAD_SLOT_CITIZEN_RPG1, SQUAD_SLOT_CITIZEN_RPG2 ) ) { @@ -2418,8 +2407,8 @@ Vector CNPC_Citizen::GetActualShootPosition( const Vector &shootOrigin ) Vector vecTarget = BaseClass::GetActualShootPosition( shootOrigin ); #ifdef MAPBASE - // The gunship RPG code does not appear to be funcitonal, so only set the laser position. - if ( GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_RPG) && GetEnemy() ) + // The gunship RPG code does not appear to be functional, so only set the laser position. + if ( GetActiveWeapon() && GetActiveWeapon()->ClassMatchesDirect( "weapon_rpg" ) && GetEnemy() ) { CWeaponRPG *pRPG = static_cast(GetActiveWeapon()); pRPG->SetNPCLaserPosition( vecTarget ); @@ -2516,31 +2505,19 @@ bool CNPC_Citizen::ShouldLookForBetterWeapon() { bool bDefer = false; -#ifdef MAPBASE - if ( EntIsClass(pWeapon, gm_isz_class_AR2) ) -#else - if( FClassnameIs( pWeapon, "weapon_ar2" ) ) -#endif + if( FClassnameIsDirect( pWeapon, "weapon_ar2" ) ) { // Content to keep this weapon forever m_flNextWeaponSearchTime = OTHER_DEFER_SEARCH_TIME; bDefer = true; } -#ifdef MAPBASE - else if( EntIsClass(pWeapon, gm_isz_class_RPG) ) -#else - else if( FClassnameIs( pWeapon, "weapon_rpg" ) ) -#endif + else if( FClassnameIsDirect( pWeapon, "weapon_rpg" ) ) { // Content to keep this weapon forever m_flNextWeaponSearchTime = OTHER_DEFER_SEARCH_TIME; bDefer = true; } -#ifdef MAPBASE - else if ( EntIsClass(pWeapon, gm_isz_class_Shotgun) ) -#else - else if( FClassnameIs( pWeapon, "weapon_shotgun" ) ) -#endif + else if( FClassnameIsDirect( pWeapon, "weapon_shotgun" ) ) { // Shotgunners do not defer their weapon search indefinitely. // If more than one citizen in the squad has a shotgun, we force diff --git a/src/game/server/hl2/npc_combine.cpp b/src/game/server/hl2/npc_combine.cpp index c7e961db363..b3562ff2b49 100644 --- a/src/game/server/hl2/npc_combine.cpp +++ b/src/game/server/hl2/npc_combine.cpp @@ -30,7 +30,6 @@ #include "SoundEmitterSystem/isoundemittersystembase.h" #include "npc_headcrab.h" #ifdef MAPBASE -#include "mapbase/GlobalStrings.h" #include "globalstate.h" #include "sceneentity.h" #endif @@ -80,11 +79,7 @@ ConVar npc_combine_fixed_shootpos( "npc_combine_fixed_shootpos", "0", FCVAR_NONE //----------------------------------------------------------------------------- // This is the index to the name of the shotgun's classname in the string pool // so that we can get away with an integer compare rather than a string compare. -#ifdef MAPBASE -#define s_iszShotgunClassname gm_isz_class_Shotgun -#else string_t s_iszShotgunClassname; -#endif //----------------------------------------------------------------------------- // Interactions @@ -430,9 +425,7 @@ void CNPC_Combine::Precache() //----------------------------------------------------------------------------- void CNPC_Combine::Activate() { -#ifndef MAPBASE s_iszShotgunClassname = FindPooledString( "weapon_shotgun" ); -#endif BaseClass::Activate(); } @@ -493,7 +486,7 @@ void CNPC_Combine::Spawn( void ) #ifdef MAPBASE // This was moved from CalcWeaponProficiency() so soldiers don't change skin unnaturally and uncontrollably - if ( GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_Shotgun) && m_nSkin != COMBINE_SKIN_SHOTGUNNER ) + if ( GetActiveWeapon() && FClassnameIsDirect( GetActiveWeapon(), "weapon_shotgun" ) && m_nSkin != COMBINE_SKIN_SHOTGUNNER ) { m_nSkin = COMBINE_SKIN_SHOTGUNNER; } @@ -2290,7 +2283,7 @@ int CNPC_Combine::SelectScheduleAttack() // If I'm fighting a combine turret (it's been hacked to attack me), I can't really // hurt it with bullets, so become grenade happy. #ifdef MAPBASE - if ( GetEnemy() && ( (IsUsingTacticalVariant(TACTICAL_VARIANT_GRENADE_HAPPY)) || GetEnemy()->ClassMatches(gm_isz_class_FloorTurret) ) ) + if ( GetEnemy() && ( (IsUsingTacticalVariant(TACTICAL_VARIANT_GRENADE_HAPPY)) || FClassnameIsDirect(GetEnemy(), "npc_turret_floor") ) ) #else if ( GetEnemy() && GetEnemy()->Classify() == CLASS_COMBINE && FClassnameIs(GetEnemy(), "npc_turret_floor") ) #endif @@ -3827,11 +3820,7 @@ void CNPC_Combine::OnEndMoveAndShoot() //----------------------------------------------------------------------------- WeaponProficiency_t CNPC_Combine::CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ) { -#ifdef MAPBASE - if( pWeapon->ClassMatches( gm_isz_class_AR2 ) ) -#else - if( FClassnameIs( pWeapon, "weapon_ar2" ) ) -#endif + if( FClassnameIsDirect( pWeapon, "weapon_ar2" ) ) { if( hl2_episodic.GetBool() ) { @@ -3842,11 +3831,7 @@ WeaponProficiency_t CNPC_Combine::CalcWeaponProficiency( CBaseCombatWeapon *pWea return WEAPON_PROFICIENCY_GOOD; } } -#ifdef MAPBASE - else if( pWeapon->ClassMatches( gm_isz_class_Shotgun ) ) -#else - else if( FClassnameIs( pWeapon, "weapon_shotgun" ) ) -#endif + else if( FClassnameIsDirect( pWeapon, "weapon_shotgun" ) ) { #ifndef MAPBASE // Moved so soldiers don't change skin unnaturally and uncontrollably if( m_nSkin != COMBINE_SKIN_SHOTGUNNER ) @@ -3857,16 +3842,12 @@ WeaponProficiency_t CNPC_Combine::CalcWeaponProficiency( CBaseCombatWeapon *pWea return WEAPON_PROFICIENCY_PERFECT; } -#ifdef MAPBASE - else if( pWeapon->ClassMatches( gm_isz_class_SMG1 ) ) -#else - else if( FClassnameIs( pWeapon, "weapon_smg1" ) ) -#endif + else if( FClassnameIsDirect( pWeapon, "weapon_smg1" ) ) { return WEAPON_PROFICIENCY_GOOD; } #ifdef MAPBASE - else if ( pWeapon->ClassMatches( gm_isz_class_Pistol ) ) + else if( FClassnameIsDirect( pWeapon, "weapon_pistol" ) ) { // Mods which need a lower soldier pistol accuracy can either change this value or use proficiency override in Hammer. return WEAPON_PROFICIENCY_VERY_GOOD; diff --git a/src/game/server/hl2/npc_metropolice.cpp b/src/game/server/hl2/npc_metropolice.cpp index c8e13fcfd0d..734023f8c0c 100644 --- a/src/game/server/hl2/npc_metropolice.cpp +++ b/src/game/server/hl2/npc_metropolice.cpp @@ -21,7 +21,6 @@ #include "hl2_gamerules.h" #ifdef MAPBASE #include "grenade_frag.h" -#include "mapbase/GlobalStrings.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -758,7 +757,7 @@ void CNPC_MetroPolice::Spawn( void ) pWeapon = GetActiveWeapon(); #ifdef MAPBASE - if (!EntIsClass(pWeapon, gm_isz_class_Pistol) && !EntIsClass(pWeapon, gm_isz_class_357)) + if( !FClassnameIsDirect( pWeapon, "weapon_pistol" ) && !FClassnameIsDirect( pWeapon, "weapon_357" ) ) #else if( !FClassnameIs( pWeapon, "weapon_pistol" ) ) #endif @@ -786,11 +785,7 @@ void CNPC_MetroPolice::Spawn( void ) // Clear out spawnflag if we're missing the smg1 if( HasSpawnFlags( SF_METROPOLICE_ALWAYS_STITCH ) ) { -#ifdef MAPBASE - if ( !Weapon_OwnsThisType( STRING(gm_isz_class_SMG1) ) ) -#else if ( !Weapon_OwnsThisType( "weapon_smg1" ) ) -#endif { Warning( "Warning! Metrocop is trying to use the stitch behavior but he has no smg1!\n" ); RemoveSpawnFlags( SF_METROPOLICE_ALWAYS_STITCH ); @@ -1545,7 +1540,7 @@ void CNPC_MetroPolice::OnUpdateShotRegulator( ) // FIXME: This code (except the burst interval) could be used for all weapon types #ifdef MAPBASE // Only if we actually have the pistol out - if ( GetActiveWeapon() && EntIsClass( GetActiveWeapon(), gm_isz_class_Pistol ) ) + if ( GetActiveWeapon() && GetActiveWeapon()->ClassMatchesDirect( "weapon_pistol" ) ) #else if( Weapon_OwnsThisType( "weapon_pistol" ) ) #endif @@ -5048,7 +5043,7 @@ int CNPC_MetroPolice::SelectSchedule( void ) case NPC_STATE_COMBAT: #ifdef MAPBASE - if (!IsEnemyInAnAirboat() || !GetActiveWeapon() || !EntIsClass(GetActiveWeapon(), gm_isz_class_SMG1)) + if (!IsEnemyInAnAirboat() || !GetActiveWeapon() || !GetActiveWeapon()->ClassMatchesDirect( "weapon_smg1" )) #else if (!IsEnemyInAnAirboat() || !Weapon_OwnsThisType( "weapon_smg1" ) ) #endif @@ -5172,7 +5167,7 @@ int CNPC_MetroPolice::TranslateSchedule( int scheduleType ) #endif #ifdef MAPBASE - if (GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_SMG1)) + if ( GetActiveWeapon() && GetActiveWeapon()->ClassMatchesDirect( "weapon_smg1" ) ) #else if( Weapon_OwnsThisType( "weapon_smg1" ) ) #endif @@ -5228,7 +5223,7 @@ int CNPC_MetroPolice::TranslateSchedule( int scheduleType ) if ( m_NextChargeTimer.Expired() && metropolice_charge.GetBool() ) { #ifdef MAPBASE - if (GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_Pistol)) + if ( GetActiveWeapon() && GetActiveWeapon()->ClassMatchesDirect( "weapon_pistol" ) ) #else if ( Weapon_OwnsThisType( "weapon_pistol" ) ) #endif @@ -5939,20 +5934,12 @@ void CNPC_MetroPolice::BuildScheduleTestBits( void ) //----------------------------------------------------------------------------- WeaponProficiency_t CNPC_MetroPolice::CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ) { -#ifdef MAPBASE - if (EntIsClass(pWeapon, gm_isz_class_Pistol)) -#else - if( FClassnameIs( pWeapon, "weapon_pistol" ) ) -#endif + if( FClassnameIsDirect( pWeapon, "weapon_pistol" ) ) { return WEAPON_PROFICIENCY_POOR; } -#ifdef MAPBASE - if (EntIsClass(pWeapon, gm_isz_class_SMG1)) -#else - if( FClassnameIs( pWeapon, "weapon_smg1" ) ) -#endif + if( FClassnameIsDirect( pWeapon, "weapon_smg1" ) ) { return WEAPON_PROFICIENCY_VERY_GOOD; } @@ -6038,11 +6025,7 @@ bool CNPC_MetroPolice::HasBaton( void ) CBaseCombatWeapon *pWeapon = GetActiveWeapon(); if ( pWeapon ) -#ifdef MAPBASE - return EntIsClass(pWeapon, gm_isz_class_Stunstick); -#else - return FClassnameIs( pWeapon, "weapon_stunstick" ); -#endif + return FClassnameIsDirect( pWeapon, "weapon_stunstick" ); return false; } diff --git a/src/game/server/hl2/npc_playercompanion.cpp b/src/game/server/hl2/npc_playercompanion.cpp index 088dad8ae9e..6768456deb1 100644 --- a/src/game/server/hl2/npc_playercompanion.cpp +++ b/src/game/server/hl2/npc_playercompanion.cpp @@ -32,7 +32,6 @@ #include #include "physics_npc_solver.h" #ifdef MAPBASE -#include "mapbase/GlobalStrings.h" #include "world.h" #include "vehicle_base.h" #include "npc_headcrab.h" @@ -169,20 +168,11 @@ END_DATADESC() CNPC_PlayerCompanion::eCoverType CNPC_PlayerCompanion::gm_fCoverSearchType; bool CNPC_PlayerCompanion::gm_bFindingCoverFromAllEnemies; -#ifdef MAPBASE -string_t CNPC_PlayerCompanion::gm_iszMortarClassname; -string_t CNPC_PlayerCompanion::gm_iszGroundTurretClassname; -#else string_t CNPC_PlayerCompanion::gm_iszMortarClassname; string_t CNPC_PlayerCompanion::gm_iszFloorTurretClassname; string_t CNPC_PlayerCompanion::gm_iszGroundTurretClassname; string_t CNPC_PlayerCompanion::gm_iszShotgunClassname; string_t CNPC_PlayerCompanion::gm_iszRollerMineClassname; -#ifdef MAPBASE -string_t CNPC_PlayerCompanion::gm_iszSMG1Classname; -string_t CNPC_PlayerCompanion::gm_iszAR2Classname; -#endif -#endif //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -233,20 +223,11 @@ bool CNPC_PlayerCompanion::CreateBehaviors() //----------------------------------------------------------------------------- void CNPC_PlayerCompanion::Precache() { -#ifdef MAPBASE - gm_iszMortarClassname = AllocPooledString( "func_tankmortar" ); - gm_iszGroundTurretClassname = AllocPooledString( "npc_turret_ground" ); -#else gm_iszMortarClassname = AllocPooledString( "func_tankmortar" ); gm_iszFloorTurretClassname = AllocPooledString( "npc_turret_floor" ); gm_iszGroundTurretClassname = AllocPooledString( "npc_turret_ground" ); gm_iszShotgunClassname = AllocPooledString( "weapon_shotgun" ); gm_iszRollerMineClassname = AllocPooledString( "npc_rollermine" ); -#ifdef MAPBASE - gm_iszSMG1Classname = AllocPooledString( "weapon_smg1" ); - gm_iszAR2Classname = AllocPooledString( "weapon_ar2" ); -#endif -#endif #ifdef MAPBASE // Moved from Spawn() @@ -397,13 +378,8 @@ Disposition_t CNPC_PlayerCompanion::IRelationType( CBaseEntity *pTarget ) else if ( baseRelationship == D_HT && pTarget->IsNPC() && ((CAI_BaseNPC *)pTarget)->GetActiveWeapon() && -#ifdef MAPBASE - (EntIsClass( ((CAI_BaseNPC *)pTarget)->GetActiveWeapon(), gm_iszShotgunClassname ) && - ( !GetActiveWeapon() || !EntIsClass( GetActiveWeapon(), gm_iszShotgunClassname ) ) ) ) -#else - ((CAI_BaseNPC *)pTarget)->GetActiveWeapon()->ClassMatches( gm_iszShotgunClassname ) && - ( !GetActiveWeapon() || !GetActiveWeapon()->ClassMatches( gm_iszShotgunClassname ) ) ) -#endif + ((CAI_BaseNPC *)pTarget)->GetActiveWeapon()->ClassMatchesDirect( gm_iszShotgunClassname ) && + ( !GetActiveWeapon() || !GetActiveWeapon()->ClassMatchesDirect( gm_iszShotgunClassname ) ) ) { if ( (pTarget->GetAbsOrigin() - GetAbsOrigin()).LengthSqr() < Square( 25 * 12 ) ) { @@ -1306,21 +1282,13 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType ) case SCHED_CHASE_ENEMY: if ( IsMortar( GetEnemy() ) ) return SCHED_TAKE_COVER_FROM_ENEMY; -#ifdef MAPBASE - if ( GetEnemy() && EntIsClass( GetEnemy(), gm_isz_class_Gunship ) ) -#else - if ( GetEnemy() && FClassnameIs( GetEnemy(), "npc_combinegunship" ) ) -#endif + if ( GetEnemy() && FClassnameIsDirect( GetEnemy(), "npc_combinegunship" ) ) return SCHED_ESTABLISH_LINE_OF_FIRE; break; case SCHED_ESTABLISH_LINE_OF_FIRE_FALLBACK: // If we're fighting a gunship, try again -#ifdef MAPBASE - if ( GetEnemy() && EntIsClass( GetEnemy(), gm_isz_class_Gunship ) ) -#else - if ( GetEnemy() && FClassnameIs( GetEnemy(), "npc_combinegunship" ) ) -#endif + if ( GetEnemy() && FClassnameIsDirect( GetEnemy(), "npc_combinegunship" ) ) return SCHED_ESTABLISH_LINE_OF_FIRE; break; @@ -2063,7 +2031,7 @@ bool CNPC_PlayerCompanion::IsReadinessCapable() if (LookupActivity( "ACT_IDLE_AIM_RIFLE_STIMULATED" ) == ACT_INVALID) return false; - if (EntIsClass(GetActiveWeapon(), gm_isz_class_RPG)) + if (GetActiveWeapon()->ClassMatchesDirect("weapon_rpg")) return false; } #else @@ -2835,11 +2803,7 @@ Vector CNPC_PlayerCompanion::GetActualShootPosition( const Vector &shootOrigin ) //------------------------------------------------------------------------------ WeaponProficiency_t CNPC_PlayerCompanion::CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ) { -#ifdef MAPBASE - if ( EntIsClass(pWeapon, gm_iszAR2Classname) ) -#else - if( FClassnameIs( pWeapon, "weapon_ar2" ) ) -#endif + if( FClassnameIsDirect( pWeapon, "weapon_ar2" ) ) { return WEAPON_PROFICIENCY_VERY_GOOD; } @@ -2856,16 +2820,13 @@ bool CNPC_PlayerCompanion::Weapon_CanUse( CBaseCombatWeapon *pWeapon ) // If this weapon is a shotgun, take measures to control how many // are being used in this squad. Don't allow a companion to pick up // a shotgun if a squadmate already has one. -#ifdef MAPBASE - if (EntIsClass(pWeapon, gm_iszShotgunClassname)) -#else - if( pWeapon->ClassMatches( gm_iszShotgunClassname ) ) -#endif + //if( pWeapon->ClassMatchesDirect( gm_iszShotgunClassname ) ) + if( pWeapon->ClassMatchesDirect( gm_iszShotgunClassname ) ) { return (NumWeaponsInSquad("weapon_shotgun") < 1 ); } #ifdef MAPBASE - else if (EntIsClass( pWeapon, gm_isz_class_Pistol ) || EntIsClass( pWeapon, gm_isz_class_357 ) || EntIsClass( pWeapon, gm_isz_class_Crossbow )) + else if ( pWeapon->ClassMatchesDirect( "weapon_pistol" ) || pWeapon->ClassMatchesDirect( "weapon_357" ) || pWeapon->ClassMatchesDirect( "weapon_crossbow" ) ) { // The AI automatically detects these weapons as usable now that there's animations for them, so ensure this behavior can be toggled in situations where that's not desirable return ai_allow_new_weapons.GetBool(); @@ -3513,19 +3474,11 @@ bool CNPC_PlayerCompanion::OverrideMove( float flInterval ) if ( !overrode && GetNavigator()->GetGoalType() != GOALTYPE_NONE ) { -#ifdef MAPBASE - #define iszEnvFire gm_isz_class_EnvFire -#else string_t iszEnvFire = AllocPooledString( "env_fire" ); -#endif string_t iszBounceBomb = AllocPooledString( "combine_mine" ); #ifdef HL2_EPISODIC -#ifdef MAPBASE - #define iszNPCTurretFloor gm_isz_class_FloorTurret -#else string_t iszNPCTurretFloor = AllocPooledString( "npc_turret_floor" ); -#endif string_t iszEntityFlame = AllocPooledString( "entityflame" ); #endif // HL2_EPISODIC diff --git a/src/game/server/hl2/npc_playercompanion.h b/src/game/server/hl2/npc_playercompanion.h index e0f6769ef41..9a3b47ac625 100644 --- a/src/game/server/hl2/npc_playercompanion.h +++ b/src/game/server/hl2/npc_playercompanion.h @@ -475,25 +475,11 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly //----------------------------------------------------- -#ifdef MAPBASE - static string_t gm_iszMortarClassname; - #define gm_iszFloorTurretClassname gm_isz_class_FloorTurret - static string_t gm_iszGroundTurretClassname; - #define gm_iszShotgunClassname gm_isz_class_Shotgun - #define gm_iszRollerMineClassname gm_isz_class_Rollermine - #define gm_iszSMG1Classname gm_isz_class_SMG1 - #define gm_iszAR2Classname gm_isz_class_AR2 -#else static string_t gm_iszMortarClassname; static string_t gm_iszFloorTurretClassname; static string_t gm_iszGroundTurretClassname; static string_t gm_iszShotgunClassname; static string_t gm_iszRollerMineClassname; -#ifdef MAPBASE - static string_t gm_iszSMG1Classname; - static string_t gm_iszAR2Classname; -#endif -#endif //----------------------------------------------------- diff --git a/src/game/server/hl2/npc_strider.cpp b/src/game/server/hl2/npc_strider.cpp index 12524b1d65c..42132228760 100644 --- a/src/game/server/hl2/npc_strider.cpp +++ b/src/game/server/hl2/npc_strider.cpp @@ -56,7 +56,6 @@ #include "eventqueue.h" #ifdef MAPBASE #include "npc_basescanner.h" -#include "mapbase/GlobalStrings.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -1134,11 +1133,7 @@ void CNPC_Strider::GatherConditions() // Don't switch targets if shooting at a bullseye! Level designers depend on bullseyes. if( GetEnemy() && m_pMinigun->IsShooting() && GetTimeEnemyAcquired() != gpGlobals->curtime ) { -#ifdef MAPBASE - if( m_pMinigun->IsOnTarget( 3 ) && !EntIsClass( GetEnemy(), gm_isz_class_Bullseye ) ) -#else - if( m_pMinigun->IsOnTarget( 3 ) && !FClassnameIs( GetEnemy(), "npc_bullseye" ) ) -#endif + if( m_pMinigun->IsOnTarget( 3 ) && !FClassnameIsDirect( GetEnemy(), "npc_bullseye" ) ) { if( m_iVisibleEnemies > 1 ) { @@ -2055,11 +2050,7 @@ Disposition_t CNPC_Strider::IRelationType( CBaseEntity *pTarget ) //--------------------------------------------------------- void CNPC_Strider::AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority ) { -#ifdef MAPBASE - if ( nDisposition == D_HT && EntIsClass(pEntity, gm_isz_class_Bullseye) ) -#else - if ( nDisposition == D_HT && pEntity->ClassMatches("npc_bullseye") ) -#endif + if ( nDisposition == D_HT && pEntity->ClassMatchesDirect("npc_bullseye") ) UpdateEnemyMemory( pEntity, pEntity->GetAbsOrigin() ); BaseClass::AddEntityRelationship( pEntity, nDisposition, nPriority ); } diff --git a/src/game/server/hl2/weapon_physcannon.cpp b/src/game/server/hl2/weapon_physcannon.cpp index 6aec0d088cf..d382756f889 100644 --- a/src/game/server/hl2/weapon_physcannon.cpp +++ b/src/game/server/hl2/weapon_physcannon.cpp @@ -40,9 +40,6 @@ #include "ai_interactions.h" #include "rumble_shared.h" #include "gamestats.h" -#ifdef MAPBASE -#include "mapbase/GlobalStrings.h" -#endif // NVNT haptic utils #include "haptics/haptic_utils.h" @@ -2593,11 +2590,7 @@ bool CWeaponPhysCannon::AttachObject( CBaseEntity *pObject, const Vector &vPosit } #if defined(HL2_DLL) -#ifdef MAPBASE - if( physcannon_right_turrets.GetBool() && EntIsClass(pObject, gm_isz_class_FloorTurret) ) -#else - if( physcannon_right_turrets.GetBool() && pObject->ClassMatches("npc_turret_floor") ) -#endif + if( physcannon_right_turrets.GetBool() && pObject->ClassMatchesDirect("npc_turret_floor") ) { // We just picked up a turret. Is it already upright? Vector vecUp; diff --git a/src/game/server/mapbase/GlobalStrings.cpp b/src/game/server/mapbase/GlobalStrings.cpp deleted file mode 100644 index 4abd6f6382e..00000000000 --- a/src/game/server/mapbase/GlobalStrings.cpp +++ /dev/null @@ -1,100 +0,0 @@ -//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================== -// -// Purpose: See GlobalStrings.h for more information. -// -// $NoKeywords: $ -//============================================================================= - -#include "cbase.h" -#include "GlobalStrings.h" - - -// Global strings must be initially declared here. -// Be sure to sync them with the externs in GlobalStrings.h. - -// ------------------------------------------------------------- -// -// Classnames -// -// ------------------------------------------------------------- - -#ifdef HL2_DLL -string_t gm_isz_class_Shotgun; -string_t gm_isz_class_SMG1; -string_t gm_isz_class_AR2; -string_t gm_isz_class_Pistol; -string_t gm_isz_class_Stunstick; -string_t gm_isz_class_Crowbar; -string_t gm_isz_class_RPG; -string_t gm_isz_class_357; -string_t gm_isz_class_Grenade; -string_t gm_isz_class_Physcannon; -string_t gm_isz_class_Crossbow; - -string_t gm_isz_class_Strider; -string_t gm_isz_class_Gunship; -string_t gm_isz_class_Dropship; -string_t gm_isz_class_FloorTurret; -string_t gm_isz_class_CScanner; -string_t gm_isz_class_ClawScanner; -string_t gm_isz_class_Rollermine; -#endif - -string_t gm_isz_class_Bullseye; - -string_t gm_isz_class_PropPhysics; -string_t gm_isz_class_PropPhysicsOverride; -string_t gm_isz_class_FuncPhysbox; -string_t gm_isz_class_EnvFire; - -// ------------------------------------------------------------- - -string_t gm_isz_name_player; -string_t gm_isz_name_activator; - -// ------------------------------------------------------------- - -// ------------------------------------------------------------- - -// We know it hasn't been allocated yet -#define INITIALIZE_GLOBAL_STRING(string, text) string = AllocPooledString(text) //SetGlobalString(string, text) - -void InitGlobalStrings() -{ -#ifdef HL2_DLL - INITIALIZE_GLOBAL_STRING(gm_isz_class_Shotgun, "weapon_shotgun"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_SMG1, "weapon_smg1"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_AR2, "weapon_ar2"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Pistol, "weapon_pistol"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Stunstick, "weapon_stunstick"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Crowbar, "weapon_crowbar"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_RPG, "weapon_rpg"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_357, "weapon_357"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Grenade, "weapon_frag"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Physcannon, "weapon_physcannon"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Crossbow, "weapon_crossbow"); - - INITIALIZE_GLOBAL_STRING(gm_isz_class_Strider, "npc_strider"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Gunship, "npc_combinegunship"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Dropship, "npc_combinedropship"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_FloorTurret, "npc_turret_floor"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_CScanner, "npc_cscanner"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_ClawScanner, "npc_clawscanner"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_Rollermine, "npc_rollermine"); -#endif - - INITIALIZE_GLOBAL_STRING(gm_isz_class_Bullseye, "npc_bullseye"); - - INITIALIZE_GLOBAL_STRING(gm_isz_class_PropPhysics, "prop_physics"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_PropPhysicsOverride, "prop_physics_override"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_FuncPhysbox, "func_physbox"); - INITIALIZE_GLOBAL_STRING(gm_isz_class_EnvFire, "env_fire"); - - INITIALIZE_GLOBAL_STRING(gm_isz_name_player, "!player"); - INITIALIZE_GLOBAL_STRING(gm_isz_name_activator, "!activator"); -} - -// ------------------------------------------------------------- - - - diff --git a/src/game/server/mapbase/GlobalStrings.h b/src/game/server/mapbase/GlobalStrings.h index 13c4775a6f8..0a46c7920f8 100644 --- a/src/game/server/mapbase/GlobalStrings.h +++ b/src/game/server/mapbase/GlobalStrings.h @@ -2,85 +2,6 @@ // // Purpose: Shared global string library. // -// $NoKeywords: $ //============================================================================= -#ifndef MAPBASE_GLOBAL_STRINGS_H -#define MAPBASE_GLOBAL_STRINGS_H -#ifdef _WIN32 -#pragma once -#endif - -#include "cbase.h" - -// ------------------------------------------------------------- -// -// Valve uses global pooled strings in various parts of the code, particularly Episodic code, -// so they could get away with integer/pointer comparisons instead of string comparisons. -// -// This system was developed early in Mapbase's development as an attempt to make this technique more widely used. -// For the most part, this mainly just serves to apply micro-optimize parts of the code. -// -// ------------------------------------------------------------- - -// ------------------------------------------------------------- -// -// Classnames -// -// ------------------------------------------------------------- - -#ifdef HL2_DLL -extern string_t gm_isz_class_Shotgun; -extern string_t gm_isz_class_SMG1; -extern string_t gm_isz_class_AR2; -extern string_t gm_isz_class_Pistol; -extern string_t gm_isz_class_Stunstick; -extern string_t gm_isz_class_Crowbar; -extern string_t gm_isz_class_RPG; -extern string_t gm_isz_class_357; -extern string_t gm_isz_class_Grenade; -extern string_t gm_isz_class_Physcannon; -extern string_t gm_isz_class_Crossbow; - -extern string_t gm_isz_class_Strider; -extern string_t gm_isz_class_Gunship; -extern string_t gm_isz_class_Dropship; -extern string_t gm_isz_class_FloorTurret; -extern string_t gm_isz_class_CScanner; -extern string_t gm_isz_class_ClawScanner; -extern string_t gm_isz_class_Rollermine; -#endif - -extern string_t gm_isz_class_Bullseye; - -extern string_t gm_isz_class_PropPhysics; -extern string_t gm_isz_class_PropPhysicsOverride; -extern string_t gm_isz_class_FuncPhysbox; -extern string_t gm_isz_class_EnvFire; - -// ------------------------------------------------------------- - -extern string_t gm_isz_name_player; -extern string_t gm_isz_name_activator; - -// ------------------------------------------------------------- - -// Does the classname of this entity match the string_t? -// -// This function is for comparing global strings and allows us to change how we compare them quickly. -inline bool EntIsClass( CBaseEntity *ent, string_t str2 ) -{ - //return ent->ClassMatches(str2); - - // Since classnames are pooled, the global string and the entity's classname should point to the same string in memory. - // As long as this rule is preserved, we only need a pointer comparison. A string comparison isn't necessary. - return ent->m_iClassname == str2; -} - -// ------------------------------------------------------------- - -void InitGlobalStrings(); - -// ------------------------------------------------------------- - -#endif +#error "GlobalStrings.h is no longer used. Please use ClassMatchesDirect() with a string literal instead." diff --git a/src/game/server/mapbase/ai_grenade.h b/src/game/server/mapbase/ai_grenade.h index cc5238f1ad6..511dba6b5fb 100644 --- a/src/game/server/mapbase/ai_grenade.h +++ b/src/game/server/mapbase/ai_grenade.h @@ -18,7 +18,6 @@ #include "grenade_frag.h" #include "basegrenade_shared.h" #include "ai_squad.h" -#include "GlobalStrings.h" #include "gameweaponmanager.h" #include "hl2_gamerules.h" #include "weapon_physcannon.h" @@ -380,7 +379,7 @@ bool CAI_GrenadeUser::CanAltFireEnemy( bool bUseFreeKnowledge ) if( !this->GetEnemy() ) return false; - if (!EntIsClass(this->GetActiveWeapon(), gm_isz_class_AR2) && !EntIsClass(this->GetActiveWeapon(), gm_isz_class_SMG1)) + if (!FClassnameIsDirect(this->GetActiveWeapon(), "weapon_ar2") && !FClassnameIsDirect(this->GetActiveWeapon(), "weapon_smg1")) return false; CBaseEntity *pEnemy = this->GetEnemy(); diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 63f6f8594f1..05c852e5bde 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -84,9 +84,6 @@ #ifdef HL2_DLL #include "combine_mine.h" #include "weapon_physcannon.h" -#ifdef MAPBASE -#include "mapbase/GlobalStrings.h" -#endif #endif #ifdef MAPBASE diff --git a/src/game/server/props.cpp b/src/game/server/props.cpp index b05aee2cb59..540abe7b72d 100644 --- a/src/game/server/props.cpp +++ b/src/game/server/props.cpp @@ -42,7 +42,6 @@ #include "gamestats.h" #include "vehicle_base.h" #ifdef MAPBASE -#include "mapbase/GlobalStrings.h" #include "collisionutils.h" #include "vstdlib/IKeyValuesSystem.h" // From Alien Swarm SDK #endif @@ -3077,13 +3076,9 @@ void CPhysicsProp::Spawn( ) } // Condense classname's to one, except for "prop_physics_override" - if ( FClassnameIs( this, "physics_prop" ) ) + if ( FClassnameIsDirect( this, "physics_prop" ) ) { -#ifdef MAPBASE - m_iClassname = gm_isz_class_PropPhysics; -#else SetClassname( "prop_physics" ); -#endif } BaseClass::Spawn(); @@ -3092,17 +3087,10 @@ void CPhysicsProp::Spawn( ) return; // Now condense all classnames to one -#ifdef MAPBASE - if ( EntIsClass( this, gm_isz_class_PropPhysicsOverride ) ) - { - m_iClassname = gm_isz_class_PropPhysics; - } -#else - if ( FClassnameIs( this, "prop_physics_override") ) + if ( FClassnameIsDirect( this, "prop_physics_override") ) { SetClassname( "prop_physics" ); } -#endif if ( HasSpawnFlags( SF_PHYSPROP_DEBRIS ) || HasInteraction( PROPINTER_PHYSGUN_CREATE_FLARE ) ) { @@ -3252,11 +3240,7 @@ bool CPhysicsProp::CanBePickedUpByPhyscannon( void ) //----------------------------------------------------------------------------- bool CPhysicsProp::OverridePropdata( void ) { -#ifdef MAPBASE - return EntIsClass(this, gm_isz_class_PropPhysicsOverride); -#else - return ( FClassnameIs(this, "prop_physics_override" ) ); -#endif + return ( FClassnameIsDirect(this, "prop_physics_override" ) ); } //----------------------------------------------------------------------------- diff --git a/src/game/server/server_mapbase.vpc b/src/game/server/server_mapbase.vpc index 312ace5756a..b12c9fe1c5b 100644 --- a/src/game/server/server_mapbase.vpc +++ b/src/game/server/server_mapbase.vpc @@ -74,8 +74,6 @@ $Project $File "mapbase\expandedrs_combine.h" $File "mapbase\func_clientclip.cpp" $File "mapbase\func_fake_worldportal.cpp" - $File "mapbase\GlobalStrings.cpp" - $File "mapbase\GlobalStrings.h" $File "mapbase\logic_externaldata.cpp" $File "mapbase\logic_skill.cpp" $File "mapbase\logic_substring.cpp" diff --git a/src/game/shared/gamestringpool.cpp b/src/game/shared/gamestringpool.cpp index 105f991aa89..58676fa7977 100644 --- a/src/game/shared/gamestringpool.cpp +++ b/src/game/shared/gamestringpool.cpp @@ -10,9 +10,6 @@ #include "utlhashtable.h" #include "igamesystem.h" #include "gamestringpool.h" -#if defined(MAPBASE) && defined(GAME_DLL) -#include "mapbase/GlobalStrings.h" -#endif #include "tier1/stringpool.h" @@ -26,10 +23,6 @@ class CGameStringPool : public CStringPool, public CBaseGameSystem { virtual char const *Name() { return "CGameStringPool"; } -#if defined(MAPBASE) && defined(GAME_DLL) - virtual void LevelInitPreEntity() { InitGlobalStrings(); } -#endif - virtual void LevelShutdownPostEntity() { Cleanup(); diff --git a/src/game/shared/hl2mp/weapon_physcannon.cpp b/src/game/shared/hl2mp/weapon_physcannon.cpp index fe2fac0dd6d..044fea47cea 100644 --- a/src/game/shared/hl2mp/weapon_physcannon.cpp +++ b/src/game/shared/hl2mp/weapon_physcannon.cpp @@ -32,9 +32,6 @@ #include "citadel_effects_shared.h" #include "eventqueue.h" #include "player_pickup.h" -#ifdef MAPBASE - #include "mapbase/GlobalStrings.h" -#endif #endif #include "gamerules.h"