//============ Copyright (c) Valve Corporation, All rights reserved. ============ // // Functions to help with map instancing. // //=============================================================================== #ifndef INSTANCINGHELPER_H #define INSTANCINGHELPER_H #if defined( COMPILER_MSVC ) #pragma once #endif class CInstancingHelper { public: //----------------------------------------------------------------------------- // Attempts to locate an instance by its filename, given the // location of the root-level VMF file, the instance directory specified in // the gameinfo.txt file, and the GAME directory. // // pFileSystem - pointer to file system object // pBaseFilename - path of the file including the instance // pInstanceFilename - relative filename of the instance, as read from // a func_instance entity // pInstanceDirectory - instance directory, specified by gameinfo.txt // pResolvedInstanceFilename - pointer to buffer to receive resolved // filename (only valid if function returns true) // nBufferSize - size of the buffer. Should be at least MAX_PATH. // // Returns true on success, false on failure. //----------------------------------------------------------------------------- static bool ResolveInstancePath( IFileSystem *pFileSystem, const char *pBaseFilename, const char *pInstanceFilename, const char *pInstanceDirectory, char *pResolvedInstanceFilename, int nBufferSize ) { Assert( nBufferSize >= MAX_PATH ); char fixedInstanceFilename[MAX_PATH]; Q_strncpy( fixedInstanceFilename, pInstanceFilename, MAX_PATH ); Q_SetExtension( fixedInstanceFilename, ".vmf", MAX_PATH ); Q_FixSlashes( fixedInstanceFilename ); V_FixDoubleSlashes( fixedInstanceFilename ); // Try to locate the instance file relative to the current file's path Q_strncpy( pResolvedInstanceFilename, pBaseFilename, nBufferSize ); Q_StripFilename( pResolvedInstanceFilename ); Q_strncat( pResolvedInstanceFilename, "\\", nBufferSize ); Q_strncat( pResolvedInstanceFilename, fixedInstanceFilename, nBufferSize ); Q_RemoveDotSlashes( pResolvedInstanceFilename ); V_FixDoubleSlashes( pResolvedInstanceFilename ); Q_FixSlashes( pResolvedInstanceFilename ); if ( pFileSystem->FileExists( pResolvedInstanceFilename ) ) { return true; } #ifdef __IN_HAMMER if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true ) { return true; } #endif // #ifdef __IN_HAMMER // Try to locate the instance file relative to the "maps\" directory const char *pMapPath = "\\maps\\"; char *pMapPathPosition = Q_stristr( pResolvedInstanceFilename, pMapPath ); if ( pMapPathPosition != NULL ) { pMapPathPosition += Q_strlen( pMapPath ); } else if ( pMapPathPosition == NULL && Q_strnicmp( pResolvedInstanceFilename, "maps\\", 5 ) == 0 ) { pMapPathPosition = pResolvedInstanceFilename + 5; } // Assuming we found a maps\ directory of some kind if ( pMapPathPosition != NULL ) { *pMapPathPosition = 0; Q_strncat( pResolvedInstanceFilename, fixedInstanceFilename, nBufferSize ); if ( pFileSystem->FileExists( pResolvedInstanceFilename ) ) { return true; } #ifdef __IN_HAMMER if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true ) { return true; } #endif // #ifdef __IN_HAMMER } if ( pInstanceDirectory[0] != '\0' ) { char instanceDirectoryRelativeFilename[MAX_PATH]; Q_snprintf( instanceDirectoryRelativeFilename, nBufferSize, "%s/%s", pInstanceDirectory, fixedInstanceFilename ); Q_SetExtension( instanceDirectoryRelativeFilename, ".vmf", MAX_PATH ); Q_FixSlashes( instanceDirectoryRelativeFilename ); Q_RemoveDotSlashes( instanceDirectoryRelativeFilename ); V_FixDoubleSlashes( instanceDirectoryRelativeFilename ); pFileSystem->RelativePathToFullPath( instanceDirectoryRelativeFilename, "CONTENT", pResolvedInstanceFilename, nBufferSize ); if ( pFileSystem->FileExists( instanceDirectoryRelativeFilename, "CONTENT" ) ) { return true; } #ifdef __IN_HAMMER if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true ) { return true; } #endif // #ifdef __IN_HAMMER } int searchPathLen = pFileSystem->GetSearchPath( "CONTENT", true, NULL, 0 ); char *searchPaths = (char *)stackalloc( searchPathLen + 1 ); pFileSystem->GetSearchPath( "CONTENT", true, searchPaths, searchPathLen ); for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) ) { Q_strncpy( pResolvedInstanceFilename, path, nBufferSize ); Q_strncat( pResolvedInstanceFilename, "maps\\", nBufferSize ); Q_strncat( pResolvedInstanceFilename, fixedInstanceFilename, nBufferSize ); if ( pFileSystem->FileExists( pResolvedInstanceFilename ) ) { return true; } } #ifdef __IN_HAMMER if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true ) { return true; } #endif // #ifdef __IN_HAMMER if ( nBufferSize > 0 ) { pResolvedInstanceFilename[0] = '\0'; } return false; } }; #endif // INSTANCINGHELPER_H