diff options
Diffstat (limited to 'hammer/manifest.cpp')
| -rw-r--r-- | hammer/manifest.cpp | 1595 |
1 files changed, 1595 insertions, 0 deletions
diff --git a/hammer/manifest.cpp b/hammer/manifest.cpp new file mode 100644 index 0000000..7a1a81d --- /dev/null +++ b/hammer/manifest.cpp @@ -0,0 +1,1595 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include "stdafx.h" +#include "Manifest.h" +#include "CustomMessages.h" +#include "GlobalFunctions.h" +#include "MainFrm.h" +#include "MapDoc.h" +#include "MapSolid.h" +#include "MapWorld.h" +#include "MapInstance.h" +#include "ToolManager.h" +#include "ChunkFile.h" +#include "ManifestDialog.h" +#include "History.h" +#include "HelperFactory.h" +#include "SaveInfo.h" +#include "tier2/tier2.h" +#include "p4lib/ip4.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + +IMPLEMENT_DYNCREATE(CManifest, CMapDoc) + + +BEGIN_MESSAGE_MAP(CManifest, CMapDoc) + //{{AFX_MSG_MAP(CManifest) + ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +IMPLEMENT_MAPCLASS( CManifestInstance ) + + +//----------------------------------------------------------------------------- +// Purpose: default constructor +//----------------------------------------------------------------------------- +CManifestMap::CManifestMap( void ) +{ + m_Map = NULL; + m_RelativeMapFileName = ""; + m_AbsoluteMapFileName = ""; + m_FriendlyName = "unnamed"; + m_bTopLevelMap = false; + m_bPrimaryMap = false; + m_bProtected = false; + m_bReadOnly = false; + m_bIsVersionControlled = false; + m_bCheckedOut = false; + m_bDefaultCheckin = false; + m_bVisible = true; + m_Entity = NULL; + m_InternalID = 0; +} + + +//----------------------------------------------------------------------------- +// Purpose: returns true if the manifest map is editable +//----------------------------------------------------------------------------- +bool CManifestMap::IsEditable( void ) +{ + return ( m_bProtected == false && m_bReadOnly == false && m_bPrimaryMap ); +} + + +//----------------------------------------------------------------------------- +// Purpose: default constructor +//----------------------------------------------------------------------------- +CManifestInstance::CManifestInstance( void ) : + CMapEntity() +{ + m_pManifestMap = NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: default constructor +//----------------------------------------------------------------------------- +CManifestInstance::CManifestInstance( CManifestMap *pManifestMap ) : + CMapEntity() +{ + m_pManifestMap = pManifestMap; +} + + +//----------------------------------------------------------------------------- +// Purpose: returns true if the manifest map this instance owns is editable +//----------------------------------------------------------------------------- +bool CManifestInstance::IsEditable( void ) +{ + return m_pManifestMap->IsEditable(); +} + + +//----------------------------------------------------------------------------- +// Purpose: default constructor +//----------------------------------------------------------------------------- +CManifest::CManifest( void ) : + CMapDoc() +{ + m_bIsValid = false; + m_bRelocateSave = false; + m_ManifestDir[ 0 ] = 0; + m_pPrimaryMap = NULL; + m_ManifestWorld = NULL; + m_NextInternalID = 1; + m_bManifestChanged = false; + m_bManifestUserPrefsChanged = false; + m_pSaveUndo = m_pUndo; + m_pSaveRedo = m_pRedo; + m_bReadOnly = true; + m_bIsVersionControlled = false; + m_bCheckedOut = false; + m_bDefaultCheckin = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: default destructor +//----------------------------------------------------------------------------- +CManifest::~CManifest( void ) +{ + m_Maps.PurgeAndDeleteElements(); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will parse through the known keys for the manifest map entry +// Input : szKey - the key name +// szValue - the value +// pManifestMap - the manifest map this belongs to +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadKeyInfoCallback( const char *szKey, const char *szValue, CManifest *pDoc ) +{ + if ( !stricmp( szKey, "NextInternalID" ) ) + { + pDoc->m_NextInternalID = atoi( szValue ); + } + + return ChunkFile_Ok; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function is responsible for setting up the manifest map about to be read in +// Input : pFile - the chunk file being read +// pDoc - the owning manifest document +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadManifestInfoCallback( CChunkFile *pFile, CManifest *pDoc ) +{ + ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadKeyInfoCallback, pDoc ); + + return( eResult ); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will parse through the known keys for the manifest map entry +// Input : szKey - the key name +// szValue - the value +// pManifestMap - the manifest map this belongs to +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadKeyCallback( const char *szKey, const char *szValue, CManifestMap *pManifestMap ) +{ + if ( !stricmp( szKey, "InternalID" ) ) + { + pManifestMap->m_InternalID = atoi( szValue ); + } + else if ( !stricmp( szKey, "Name" ) ) + { + pManifestMap->m_FriendlyName = szValue; + } + else if ( !stricmp( szKey, "File" ) ) + { + pManifestMap->m_RelativeMapFileName = szValue; + pManifestMap->m_AbsoluteMapFileName += szValue; + if ( !pManifestMap->m_Map->LoadVMF( pManifestMap->m_AbsoluteMapFileName, VMF_LOAD_ACTIVATE | VMF_LOAD_IS_SUBMAP ) ) + { + delete pManifestMap->m_Map; + pManifestMap->m_Map = NULL; + } + pManifestMap->m_bReadOnly = true; + } + else if ( !stricmp( szKey, "TopLevel" ) ) + { + pManifestMap->m_bTopLevelMap = ( atoi( szValue ) == 1 ); + } + + return ChunkFile_Ok; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function is responsible for setting up the manifest map about to be read in +// Input : pFile - the chunk file being read +// pDoc - the owning manifest document +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadManifestVMFCallback( CChunkFile *pFile, CManifest *pDoc ) +{ + char FileName[ MAX_PATH ]; + + strcpy( FileName, pDoc->m_ManifestDir ); + + CManifestMap *pManifestMap = pDoc->CreateNewMap( FileName, "", false ); + SetActiveMapDoc( pManifestMap->m_Map ); + + ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadKeyCallback, pManifestMap ); + + if ( pManifestMap->m_Map ) + { + pManifestMap->m_Map->SetEditable( false ); + } + SetActiveMapDoc( pDoc ); + + return( eResult ); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will load the VMF chunk +// Input : pFile - the chunk file being read +// pDoc - the owning manifest document +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadManifestMapsCallback( CChunkFile *pFile, CManifest *pDoc ) +{ + CChunkHandlerMap Handlers; + Handlers.AddHandler( "VMF", ( ChunkHandler_t )LoadManifestVMFCallback, pDoc ); + pFile->PushHandlers(&Handlers); + + ChunkFileResult_t eResult = ChunkFile_Ok; + + eResult = pFile->ReadChunk(); + + pFile->PopHandlers(); + + return( eResult ); +} + + +typedef struct SManifestLoadPrefs +{ + CManifest *pDoc; + CManifestMap *pManifestMap; +} TManifestLoadPrefs; + + +//----------------------------------------------------------------------------- +// Purpose: this function will parse through the known keys for the manifest map entry +// Input : szKey - the key name +// szValue - the value +// pManifestMap - the manifest map this belongs to +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadKeyPrefsCallback( const char *szKey, const char *szValue, TManifestLoadPrefs *pManifestLoadPrefs ) +{ + if ( !stricmp( szKey, "InternalID" ) ) + { + pManifestLoadPrefs->pManifestMap = pManifestLoadPrefs->pDoc->FindMapByID( atoi( szValue ) ); + } + else if ( !stricmp( szKey, "IsPrimary" ) ) + { + if ( pManifestLoadPrefs->pManifestMap ) + { + pManifestLoadPrefs->pManifestMap->m_bPrimaryMap = ( atoi( szValue ) == 1 ); + } + } + else if ( !stricmp( szKey, "IsProtected" ) ) + { + if ( pManifestLoadPrefs->pManifestMap ) + { + pManifestLoadPrefs->pManifestMap->m_bProtected = ( atoi( szValue ) == 1 ); + } + } + else if ( !stricmp( szKey, "IsVisible" ) ) + { + if ( pManifestLoadPrefs->pManifestMap ) + { + pManifestLoadPrefs->pManifestMap->m_bVisible = ( atoi( szValue ) == 1 ); + } + } + + return ChunkFile_Ok; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function is responsible for setting up the manifest map about to be read in +// Input : pFile - the chunk file being read +// pDoc - the owning manifest document +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadManifestVMFPrefsCallback( CChunkFile *pFile, CManifest *pDoc ) +{ + TManifestLoadPrefs ManifestLoadPrefs; + + ManifestLoadPrefs.pDoc = pDoc; + ManifestLoadPrefs.pManifestMap = NULL; + + ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadKeyPrefsCallback, &ManifestLoadPrefs ); + + return( eResult ); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will load the VMF chunk +// Input : pFile - the chunk file being read +// pDoc - the owning manifest document +// Output : ChunkFileResult_t - result of the parsing +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadManifestMapsPrefsCallback( CChunkFile *pFile, CManifest *pDoc ) +{ + CChunkHandlerMap Handlers; + Handlers.AddHandler( "VMF", ( ChunkHandler_t )LoadManifestVMFPrefsCallback, pDoc ); + pFile->PushHandlers(&Handlers); + + ChunkFileResult_t eResult = ChunkFile_Ok; + + eResult = pFile->ReadChunk(); + + pFile->PopHandlers(); + + return( eResult ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadManifestCordoningPrefsCallback( CChunkFile *pFile, CManifest *pDoc ) +{ + CChunkHandlerMap Handlers; + Handlers.AddHandler( "cordons", ( ChunkHandler_t )CMapDoc::LoadCordonCallback, pDoc ); + pFile->PushHandlers(&Handlers); + + ChunkFileResult_t eResult = ChunkFile_Ok; + + eResult = pFile->ReadChunk(); + + pFile->PopHandlers(); + + return( eResult ); +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will load in a vmf manifest +// Input : pszFileName - the file name of the manifest to load +// Output : returns true if the load was successful +//----------------------------------------------------------------------------- +bool CManifest::LoadVMFManifest( const char *pszFileName ) +{ + FILE *fp = fopen( pszFileName, "rb" ); + if ( !fp ) + { + return false; + } + + V_StripExtension( pszFileName, m_ManifestDir, sizeof( m_ManifestDir ) ); + strcat( m_ManifestDir, "\\" ); + + CChunkFile File; + ChunkFileResult_t eResult = File.Open( pszFileName, ChunkFile_Read ); + + m_bLoading = true; + + if (eResult == ChunkFile_Ok) + { + // + // Set up handlers for the subchunks that we are interested in. + // + CChunkHandlerMap Handlers; + Handlers.AddHandler( "Info", ( ChunkHandler_t )CManifest::LoadManifestInfoCallback, this ); + Handlers.AddHandler( "Maps", ( ChunkHandler_t )CManifest::LoadManifestMapsCallback, this ); + + Handlers.SetErrorHandler( ( ChunkErrorHandler_t )CMapDoc::HandleLoadError, this); + + File.PushHandlers(&Handlers); + + while (eResult == ChunkFile_Ok) + { + eResult = File.ReadChunk(); + } + + if (eResult == ChunkFile_EOF) + { + eResult = ChunkFile_Ok; + } + + File.PopHandlers(); + } + + if (eResult == ChunkFile_Ok) + { + } + else + { + GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error loading manifest!", MB_OK | MB_ICONEXCLAMATION ); + } + + if ( GetNumMaps() == 0 ) + { + GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Manifest file does not contain any maps!", MB_OK | MB_ICONEXCLAMATION ); + return false; + } + + SetActiveMapDoc( this ); + Postload( pszFileName ); + m_ManifestWorld->PostloadWorld(); + + bool bSetIDs = false; + + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + if ( pManifestMap->m_InternalID == 0 ) + { + pManifestMap->m_InternalID = m_NextInternalID; + m_NextInternalID++; + bSetIDs = true; + } + + if ( pManifestMap->m_Map == NULL || pManifestMap->m_Map->GetMapWorld() == NULL ) + { + pManifestMap->m_bPrimaryMap = false; + RemoveSubMap( pManifestMap ); + i = -1; + } + } + + LoadVMFManifestUserPrefs( pszFileName ); + + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + if ( pManifestMap->m_bPrimaryMap ) + { + SetPrimaryMap( pManifestMap ); + } + } + + if ( !m_pPrimaryMap ) + { + SetPrimaryMap( GetMap( 0 ) ); + } + + m_bLoading = false; + m_bIsValid = true; + + m_bManifestChanged = bSetIDs; + + GetMainWnd()->m_ManifestFilterControl.UpdateManifestList(); + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will load the user prefs for the manifest file. +// Input : pszFileName - the manifest file name. +// Output : true if prefs were loaded. +//----------------------------------------------------------------------------- +bool CManifest::LoadVMFManifestUserPrefs( const char *pszFileName ) +{ + char UserName[ MAX_PATH ], FileName[ MAX_PATH ], UserPrefsFileName[ MAX_PATH ]; + DWORD UserNameSize; + + m_bManifestUserPrefsChanged = false; + + UserNameSize = sizeof( UserName ); + if ( GetUserName( UserName, &UserNameSize ) == 0 ) + { + strcpy( UserPrefsFileName, "default" ); + } + + strcpy( FileName, m_ManifestDir ); + sprintf( UserPrefsFileName, "%s.vmm_prefs", UserName ); + strcat( FileName, UserPrefsFileName ); + + FILE *fp = fopen( FileName, "rb" ); + if ( !fp ) + { + return false; + } + + CChunkFile File; + ChunkFileResult_t eResult = File.Open( FileName, ChunkFile_Read ); + + m_bLoading = true; + + if ( eResult == ChunkFile_Ok ) + { + // + // Set up handlers for the subchunks that we are interested in. + // + CChunkHandlerMap Handlers; + Handlers.AddHandler( "Maps", ( ChunkHandler_t )CManifest::LoadManifestMapsPrefsCallback, this ); + Handlers.AddHandler( "cordoning", ( ChunkHandler_t )CManifest::LoadManifestCordoningPrefsCallback, this ); + + Handlers.SetErrorHandler( ( ChunkErrorHandler_t )CMapDoc::HandleLoadError, this); + + File.PushHandlers(&Handlers); + + while( eResult == ChunkFile_Ok ) + { + eResult = File.ReadChunk(); + } + + if ( eResult == ChunkFile_EOF ) + { + eResult = ChunkFile_Ok; + } + + File.PopHandlers(); + } + + if ( eResult == ChunkFile_Ok ) + { + } + else + { + // no pref message for now +// GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error loading manifest!", MB_OK | MB_ICONEXCLAMATION ); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will load in a manifest file ( and its user prefs ) +// Input : pszFileName - the name of the manifest file. +// Output : returns true if the manifest was loaded. +//----------------------------------------------------------------------------- +bool CManifest::Load( const char *pszFileName ) +{ + if ( !LoadVMFManifest( pszFileName ) ) + { + return false; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will save the manifest, the associated maps, and user prefs. +// Input : pszFileName - the name of the manifest +// bForce - if true, we need to save all files, as we are relocating. +// Output : returns true if all files saved successfully. +//----------------------------------------------------------------------------- +bool CManifest::Save( const char *pszFileName, bool bForce ) +{ + bool bSuccess = true; + + if ( bForce || m_bManifestChanged ) + { + if ( !SaveVMFManifest( pszFileName ) ) + { + bSuccess = false; + } + } + + if ( !SaveVMFManifestMaps( pszFileName ) ) + { + bSuccess = false; + } + +// if ( bForce || m_bManifestUserPrefsChanged ) + { + if ( !SaveVMFManifestUserPrefs( pszFileName ) ) + { + bSuccess = false; + } + } + + return bSuccess; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will save the manifest file and all modified maps. If we are +// relocating the manifest to a new place, all maps will be saved relative to +// the new place +// Input : the file name the manifest should be saved as +// Output : returns true if the save was completely successful. A partial save will +// return false. +//----------------------------------------------------------------------------- +bool CManifest::SaveVMFManifest( const char *pszFileName ) +{ + bool bSaved = true; + CChunkFile File; + + ChunkFileResult_t eResult = File.Open( pszFileName, ChunkFile_Write ); + if (eResult != ChunkFile_Ok) + { + GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest!" , MB_OK | MB_ICONEXCLAMATION ); + bSaved = false; + } + else + { + eResult = File.BeginChunk( "Info" ); + eResult = File.WriteKeyValueInt( "NextInternalID", m_NextInternalID ); + eResult = File.EndChunk(); + + eResult = File.BeginChunk( "Maps" ); + if (eResult == ChunkFile_Ok) + { + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + eResult = File.BeginChunk("VMF"); + if (eResult == ChunkFile_Ok) + { + eResult = File.WriteKeyValue( "Name", pManifestMap->m_FriendlyName ); + eResult = File.WriteKeyValue( "File", pManifestMap->m_RelativeMapFileName ); + eResult = File.WriteKeyValueInt( "InternalID", pManifestMap->m_InternalID ); + if ( pManifestMap->m_bTopLevelMap == true ) + { + eResult = File.WriteKeyValue( "TopLevel", "1" ); + } + + eResult = File.EndChunk(); + } + } + } + + if (eResult == ChunkFile_Ok) + { + eResult = File.EndChunk(); + } + else + { + GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest!", MB_OK | MB_ICONEXCLAMATION ); + bSaved = false; + } + + File.Close(); + } + + V_StripExtension( pszFileName, m_ManifestDir, sizeof( m_ManifestDir ) ); + CreateDirectory( m_ManifestDir, NULL ); + strcat( m_ManifestDir, "\\" ); + + if ( bSaved ) + { + m_bManifestChanged = false; + } + + return bSaved; +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will save all maps associated with a manifest. Only modified +// maps are saved unless we are relocating the manifest. +// Input : pszFileName - the name of the manifest file +// Output : returns true if the maps were saved successfully. +//----------------------------------------------------------------------------- +bool CManifest::SaveVMFManifestMaps( const char *pszFileName ) +{ + bool bSaved = true; + + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + if ( m_bRelocateSave ) + { + char FileName[ MAX_PATH ]; + + strcpy( FileName, m_ManifestDir ); + strcat( FileName, pManifestMap->m_RelativeMapFileName ); + pManifestMap->m_AbsoluteMapFileName = FileName; + } + + if ( ( pManifestMap->m_Map->IsModified() || m_bRelocateSave ) ) + { + if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false ) + { + bSaved = false; + } + } + } + + if ( !bSaved ) + { + GetMainWnd()->MessageBox( "Not all pieces of the manifest were saved!", "Error saving Manifest!", MB_OK | MB_ICONEXCLAMATION ); + } + + return bSaved; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will save the user prefs of the manifest. +// Input : pszFileName - the name of the manifest file. +// Output : returns true if the prefs were saved. +//----------------------------------------------------------------------------- +bool CManifest::SaveVMFManifestUserPrefs( const char *pszFileName ) +{ + bool bSaved = true; + CChunkFile File; + char UserName[ MAX_PATH ], FileName[ MAX_PATH ], UserPrefsFileName[ MAX_PATH ]; + DWORD UserNameSize; + + UserNameSize = sizeof( UserName ); + if ( GetUserName( UserName, &UserNameSize ) == 0 ) + { + strcpy( UserPrefsFileName, "default" ); + } + + strcpy( FileName, m_ManifestDir ); + sprintf( UserPrefsFileName, "%s.vmm_prefs", UserName ); + strcat( FileName, UserPrefsFileName ); + + ChunkFileResult_t eResult = File.Open( FileName, ChunkFile_Write ); + if (eResult != ChunkFile_Ok) + { + GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest User Prefs!" , MB_OK | MB_ICONEXCLAMATION ); + bSaved = false; + } + else + { + eResult = File.BeginChunk( "Maps" ); + if (eResult == ChunkFile_Ok) + { + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + eResult = File.BeginChunk("VMF"); + if (eResult == ChunkFile_Ok) + { + eResult = File.WriteKeyValueInt( "InternalID", pManifestMap->m_InternalID ); + if ( pManifestMap->m_bPrimaryMap ) + { + eResult = File.WriteKeyValue( "IsPrimary", "1" ); + } + if ( pManifestMap->m_bProtected == true ) + { + eResult = File.WriteKeyValue( "IsProtected", "1" ); + } + if ( pManifestMap->m_bVisible == false ) + { + eResult = File.WriteKeyValue( "IsVisible", "0" ); + } + + eResult = File.EndChunk(); + } + } + } + + if (eResult == ChunkFile_Ok) + { + eResult = File.EndChunk(); + } + else + { + GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest User Prefs!", MB_OK | MB_ICONEXCLAMATION ); + bSaved = false; + } + + eResult = File.BeginChunk( "cordoning" ); + eResult = CordonSaveVMF( &File, NULL ); + + if ( m_bIsCordoning ) + { + CSaveInfo SaveInfo; + + SaveInfo.SetVisiblesOnly( false ); + CMapWorld *pCordonWorld = CordonCreateWorld(); + eResult = pCordonWorld->SaveSolids( &File, &SaveInfo, 0 ); + } + + eResult = File.EndChunk(); + + File.Close(); + } + + if ( bSaved ) + { + m_bManifestUserPrefsChanged = false; + } + + return bSaved; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will initialize the manifest +//----------------------------------------------------------------------------- +void CManifest::Initialize( void ) +{ + __super::Initialize(); + + m_ManifestWorld = new CMapWorld( this ); + m_ManifestWorld->CullTree_Build(); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will update the manifest and all of its sub maps +//----------------------------------------------------------------------------- +void CManifest::Update( void ) +{ + __super::Update(); + + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + pManifestMap->m_Map->Update(); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: this function allows you to indicate if the user prefs have been modified. +// Input : bModified - the new status of the user prefs +//----------------------------------------------------------------------------- +void CManifest::SetManifestPrefsModifiedFlag( bool bModified ) +{ + m_bManifestUserPrefsChanged = bModified; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function handles the routing of the manifest's modified flag down to the primary map +// Input : bModified - the new modified status +//----------------------------------------------------------------------------- +void CManifest::SetModifiedFlag( BOOL bModified ) +{ + if ( m_pPrimaryMap ) + { + m_pPrimaryMap->m_Map->SetModifiedFlag( bModified ); + } + + if ( bModified == false ) + { + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + if ( pManifestMap->m_Map->IsModified() ) + { + bModified = true; + break; + } + } + } + + if ( bModified != IsModified() ) + { + GetMainWnd()->m_ManifestFilterControl.Invalidate(); + } + + __super::SetModifiedFlag( bModified ); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will return the full path to a sub map. +// Input : pManifestMapFileName - the relative name of the sub map +// Output : pOutputPath - the full path to the sub map +//----------------------------------------------------------------------------- +void CManifest::GetFullMapPath( const char *pManifestMapFileName, char *pOutputPath ) +{ + strcpy( pOutputPath, m_ManifestDir ); + strcat( pOutputPath, pManifestMapFileName ); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will attempt to find the manifest map that owns the map doc +// Input : pMap - the map doc to look up +// Output : returns a pointer to the owning manifest map, otherwise NULL +//----------------------------------------------------------------------------- +CManifestMap *CManifest::FindMap( CMapDoc *pMap ) +{ + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + if ( pManifestMap->m_Map == pMap ) + { + return pManifestMap; + } + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will attempt to look up a map by its internal id. +// Input : InternalID - the internal ID. +// Output : returns the manifest map if one is found. +//----------------------------------------------------------------------------- +CManifestMap *CManifest::FindMapByID( int InternalID ) +{ + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + if ( pManifestMap->m_InternalID == InternalID ) + { + return pManifestMap; + } + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will set the manifest map as the primary map. All entity / brush +// operations happen exclusively on the primary map. +// Input : pManifestMap - the manifest map to make primary +//----------------------------------------------------------------------------- +void CManifest::SetPrimaryMap( CManifestMap *pManifestMap ) +{ + if ( m_pPrimaryMap ) + { + m_pPrimaryMap->m_bPrimaryMap = false; + m_pPrimaryMap->m_Map->m_nNextMapObjectID = m_nNextMapObjectID; + m_pPrimaryMap->m_Map->m_nNextMapObjectID = m_nNextNodeID; + m_pPrimaryMap->m_Map->SetEditable( false ); + } + + ClearSelection(); + CheckFileStatus(); + + m_pPrimaryMap = pManifestMap; + if ( m_pPrimaryMap ) + { + m_pPrimaryMap->m_bPrimaryMap = true; + m_pWorld = m_pPrimaryMap->m_Map->GetMapWorld(); + m_VisGroups = m_pPrimaryMap->m_Map->m_VisGroups; + m_RootVisGroups = m_pPrimaryMap->m_Map->m_RootVisGroups; + m_nNextMapObjectID = m_pPrimaryMap->m_Map->m_nNextMapObjectID; + m_nNextNodeID = m_pPrimaryMap->m_Map->m_nNextMapObjectID; + m_pPrimaryMap->m_Map->SetEditable( !m_pPrimaryMap->m_bReadOnly ); + + m_pUndo = m_pPrimaryMap->m_Map->m_pUndo; + m_pRedo = m_pPrimaryMap->m_Map->m_pRedo; + CHistory::SetHistory( m_pPrimaryMap->m_Map->m_pUndo ); + +// m_pSelection = m_pPrimaryMap->m_Map->m_pSelection; + } + + m_bManifestUserPrefsChanged = true; + + GetMainWnd()->GlobalNotify( WM_MAPDOC_CHANGED ); + GetMainWnd()->m_ManifestFilterControl.Invalidate(); + UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW ); +} + + +//----------------------------------------------------------------------------- +// Purpose: sets the visibility flag of a sub map. +// Input : pManifestMap - the map to set the flag +// bIsVisible - the visiblity status +//----------------------------------------------------------------------------- +void CManifest::SetVisibility( CManifestMap *pManifestMap, bool bIsVisible ) +{ + pManifestMap->m_bVisible = bIsVisible; + + GetMainWnd()->m_ManifestFilterControl.Invalidate(); + UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW ); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will create and default a new manifest map, add it to the world +// Input : AbsoluteFileName - the full path of the vmf file +// RelativeFileName - the relative path of the vmf file +// Output : returns a pointer to the newly created manifest map. +//----------------------------------------------------------------------------- +CManifestMap *CManifest::CreateNewMap( const char *AbsoluteFileName, const char *RelativeFileName, bool bSetID ) +{ + CManifestMap *pManifestMap = new CManifestMap(); + + pManifestMap->m_AbsoluteMapFileName = AbsoluteFileName; + pManifestMap->m_RelativeMapFileName = RelativeFileName; + pManifestMap->m_Map = new CMapDoc(); + SetActiveMapDoc( pManifestMap->m_Map ); + pManifestMap->m_Map->SetManifest( this ); + pManifestMap->m_Map->SetEditable( false ); + + pManifestMap->m_Entity = new CManifestInstance( pManifestMap ); + + pManifestMap->m_Entity->SetPlaceholder( true ); + pManifestMap->m_Entity->SetOrigin( Vector( 0.0f, 0.0f, 0.0f ) ); + pManifestMap->m_Entity->SetClass( "func_instance" ); + pManifestMap->m_Entity->SetKeyValue( "classname", "func_instance" ); + + // ensure we are a pure instance of only the instance helper! + pManifestMap->m_Entity->RemoveAllChildren(); + CHelperInfo HI; + + HI.SetName( "instance" ); + + CMapClass *pHelper = CHelperFactory::CreateHelper( &HI, pManifestMap->m_Entity ); + if ( pHelper != NULL ) + { + pManifestMap->m_Entity->AddHelper( pHelper, false ); + } + + if ( bSetID ) + { + pManifestMap->m_InternalID = m_NextInternalID; + m_NextInternalID++; + } + + CMapInstance *pMapInstance = pManifestMap->m_Entity->GetChildOfType( ( CMapInstance * )NULL ); + if ( pMapInstance ) + { + pMapInstance->SetManifest( pManifestMap ); + } + AddManifestObjectToWorld( pManifestMap->m_Entity ); + m_Maps.AddToTail( pManifestMap ); + + m_bManifestChanged = true; + + return pManifestMap; +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will move the selection of the active map to a new sub map. +// Input : pManifestMap - the sub map the selection shoud be moved to +// CenterContents - if the contents should be centered +//----------------------------------------------------------------------------- +void CManifest::MoveSelectionToSubmap( CManifestMap *pManifestMap, bool CenterContents ) +{ +#if 0 + if ( s_Clipboard.Objects.Count() != 0 ) + { + return false; + } +#endif + + CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); + if ( !pDoc ) + { + return; + } + + pDoc->Copy(); + if ( pDoc->GetClipboardCount() == 0 ) + { + return; + } + pDoc->Delete(); + + pManifestMap->m_Map->ManifestPaste( pManifestMap->m_Map->GetMapWorld(), Vector( 0.0f, 0.0f, 0.0f ), QAngle( 0.0f, 0.0f, 0.0f ), NULL, false, NULL ); + pManifestMap->m_Entity->CalcBounds( TRUE ); + + UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW ); +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will cut the selection and move it into a newly created +// map doc and manifest map. +// Input : FriendlyName - this is the text friendly name that the user can refer +// to the map as +// FileName - The relative file name for this new map to be saved as +// CenterContents - whether or not we should center the contents in the new map +// Output : returns a pointer to the newly created manifest map. +//----------------------------------------------------------------------------- +CManifestMap *CManifest::MoveSelectionToNewSubmap( CString &FriendlyName, CString &FileName, bool CenterContents ) +{ +#if 0 + if ( s_Clipboard.Objects.Count() != 0 ) + { + return false; + } +#endif + + CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); + + if ( !pDoc ) + { + return NULL; + } + + pDoc->Copy(); + if ( pDoc->GetClipboardCount() == 0 ) + { + return NULL; + } + + char AbsoluteFileName[ MAX_PATH ]; + + strcpy( AbsoluteFileName, m_ManifestDir ); + strcat( AbsoluteFileName, FileName ); + + CManifestMap *pManifestMap = CreateNewMap( AbsoluteFileName, FileName, true ); + pManifestMap->m_FriendlyName = FriendlyName; + + pManifestMap->m_Map->Initialize(); + if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false ) + { + m_bLoading = false; + SetActiveMapDoc( this ); + delete pManifestMap; + return NULL; + } + pDoc->Delete(); + pManifestMap->m_Map->ManifestPaste( pManifestMap->m_Map->GetMapWorld(), Vector( 0.0f, 0.0f, 0.0f ), QAngle( 0.0f, 0.0f, 0.0f ), NULL, false, NULL ); + pManifestMap->m_Entity->CalcBounds( TRUE ); + SetPrimaryMap( pManifestMap ); + + SetActiveMapDoc( this ); + __super::SetModifiedFlag( true ); + pDoc->SetModifiedFlag( true ); + pManifestMap->m_Map->SetModifiedFlag( true ); + + UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW ); + GetMainWnd()->m_ManifestFilterControl.UpdateManifestList(); + + return pManifestMap; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will add a new sub map to the manifest. +// Input : FriendlyName - the friendly name string +// FileName - the file name of the sub map +// Output : returns a pointer to the new manifest map. +//----------------------------------------------------------------------------- +CManifestMap *CManifest::AddNewSubmap( CString &FriendlyName, CString &FileName ) +{ + char AbsoluteFileName[ MAX_PATH ]; + + strcpy( AbsoluteFileName, m_ManifestDir ); + strcat( AbsoluteFileName, FileName ); + + CManifestMap *pManifestMap = CreateNewMap( AbsoluteFileName, FileName, true ); + + pManifestMap->m_FriendlyName = FriendlyName; + + pManifestMap->m_Map->Initialize(); + pManifestMap->m_Entity->CalcBounds( TRUE ); + + if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false ) + { + m_bLoading = false; + SetActiveMapDoc( this ); + delete pManifestMap; + return NULL; + } + + SetPrimaryMap( pManifestMap ); + SetActiveMapDoc( this ); + __super::SetModifiedFlag( true ); + + UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW ); + GetMainWnd()->m_ManifestFilterControl.UpdateManifestList(); + + return pManifestMap; +} + + +//----------------------------------------------------------------------------- +// Purpose: This function add an external vmf file to the manifest +// Input : pszFileName - the absolute file name of the vmf file +// bFromInstance - if the map is coming from a func_instance somewhere +// Output : returns true if the map could be loaded and the manifest was created +//----------------------------------------------------------------------------- +bool CManifest::AddExistingMap( const char *pszFileName, bool bFromInstance ) +{ + char AbsoluteFileName[ MAX_PATH ], RelativeFileName[ MAX_PATH ]; + + char FileExt[ MAX_PATH ]; + + _splitpath_s( pszFileName, NULL, 0, NULL, 0, RelativeFileName, sizeof( RelativeFileName ), FileExt, sizeof( FileExt ) ); + strcat( RelativeFileName, FileExt ); + + strcpy( AbsoluteFileName, m_ManifestDir ); + strcat( AbsoluteFileName, RelativeFileName ); + CManifestMap *pManifestMap = CreateNewMap( AbsoluteFileName, RelativeFileName, true ); + + m_bLoading = true; + if ( !pManifestMap->m_Map->LoadVMF( pszFileName, VMF_LOAD_ACTIVATE | VMF_LOAD_IS_SUBMAP ) ) + { + m_bLoading = false; + SetActiveMapDoc( this ); + delete pManifestMap; + return false; + } + + if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false ) + { + m_bLoading = false; + SetActiveMapDoc( this ); + delete pManifestMap; + return false; + } + + pManifestMap->m_Map->GetMapWorld()->CullTree_Build(); + pManifestMap->m_Entity->PostUpdate( Notify_Changed ); + if ( m_Maps.Count() == 1 ) + { + pManifestMap->m_bTopLevelMap = true; + } + + SetPrimaryMap( pManifestMap ); + + m_bLoading = false; + + SetActiveMapDoc( this ); + __super::SetModifiedFlag( true ); + + GetMainWnd()->m_ManifestFilterControl.UpdateManifestList(); + + if ( GetPathName().GetLength() == 0 ) + { + char ManifestFile[ MAX_PATH ]; + + strcpy( ManifestFile, pszFileName ); + V_SetExtension( ManifestFile, ".vmm", sizeof( ManifestFile ) ); + + m_bRelocateSave = true; + OnSaveDocument( ManifestFile ); + m_bRelocateSave = false; + + SetPathName( ManifestFile, false ); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will allow the user to browse to an exist map to add to the manifest. +//----------------------------------------------------------------------------- +bool CManifest::AddExistingMap( void ) +{ + char szInitialDir[ MAX_PATH ]; + + V_strcpy_safe( szInitialDir, GetPathName() ); + if ( szInitialDir[ 0 ] == '\0' ) + { + strcpy( szInitialDir, g_pGameConfig->szMapDir ); + } + + CFileDialog dlg( TRUE, NULL, NULL, OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, "Valve Map Files (*.vmf)|*.vmf||" ); + dlg.m_ofn.lpstrInitialDir = szInitialDir; + int iRvl = dlg.DoModal(); + + if ( iRvl == IDCANCEL ) + { + return false; + } + + // + // Get the directory they browsed to for next time. + // + CString str = dlg.GetPathName(); + int nSlash = str.ReverseFind( '\\' ); + if ( nSlash != -1 ) + { + strcpy( szInitialDir, str.Left( nSlash ) ); + } + + if ( str.Find('.') == -1 ) + { + switch ( dlg.m_ofn.nFilterIndex ) + { + case 1: + str += ".vmf"; + break; + } + } + + return AddExistingMap( str, false ); +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will remove the sub map from the manifest +// Input : pManifestMap - the sub map to be removed +// Output : returns true if it was successful +//----------------------------------------------------------------------------- +bool CManifest::RemoveSubMap( CManifestMap *pManifestMap ) +{ + if ( m_Maps.Count() > 1 ) + { + m_Maps.FindAndRemove( pManifestMap ); + + const CMapObjectList *pChildren = m_ManifestWorld->GetChildren(); + FOR_EACH_OBJ( *pChildren, pos ) + { + CMapClass *pChild = pChildren->Element( pos ); + CMapEntity *pEntity = dynamic_cast< CMapEntity * >( pChild ); + + if ( pEntity && stricmp( pEntity->GetClassName(), "func_instance" ) == 0 ) + { + CMapInstance *pMapInstance = pEntity->GetChildOfType( ( CMapInstance * )NULL ); + if ( pMapInstance ) + { + if ( pMapInstance->GetManifestMap() == pManifestMap ) + { + m_ManifestWorld->RemoveObjectFromWorld( pChild, true ); + break; + } + } + } + } + + delete pManifestMap; + + return true; + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +bool CManifest::CheckOut( ) +{ + if ( !p4 ) + { + return false; + } + + if ( !p4->OpenFileForEdit( GetPathName() ) ) + { + return false; + } + + CheckFileStatus(); + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +bool CManifest::AddToVersionControl( ) +{ + if ( !p4 ) + { + return false; + } + + if ( !p4->OpenFileForAdd( GetPathName() ) ) + { + return false; + } + + CheckFileStatus(); + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CManifest::CheckFileStatus( void ) +{ + P4File_t FileInfo; + + m_bReadOnly = !g_pFullFileSystem->IsFileWritable( GetPathName() ); + m_bCheckedOut = false; + m_bIsVersionControlled = false; + if ( p4 != NULL && p4->GetFileInfo( GetPathName(), &FileInfo ) == true ) + { + m_bIsVersionControlled = true; + if ( FileInfo.m_eOpenState == P4FILE_OPENED_FOR_ADD || FileInfo.m_eOpenState == P4FILE_OPENED_FOR_EDIT ) + { + m_bCheckedOut = true; + } + } + + for( int i = 0; i < GetNumMaps(); i++ ) + { + CManifestMap *pManifestMap = GetMap( i ); + + pManifestMap->m_bReadOnly = !g_pFullFileSystem->IsFileWritable( pManifestMap->m_AbsoluteMapFileName ); + pManifestMap->m_bCheckedOut = false; + pManifestMap->m_bIsVersionControlled = false; + + if ( p4 != NULL && p4->GetFileInfo( pManifestMap->m_AbsoluteMapFileName, &FileInfo ) == true ) + { + pManifestMap->m_bIsVersionControlled = true; + if ( FileInfo.m_eOpenState == P4FILE_OPENED_FOR_ADD || FileInfo.m_eOpenState == P4FILE_OPENED_FOR_EDIT ) + { + pManifestMap->m_bCheckedOut = true; + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will clear the selection +//----------------------------------------------------------------------------- +void CManifest::ClearSelection( void ) +{ + SelectFace( NULL, 0, scClear | scSaveChanges ); + SelectObject( NULL, scClear | scSaveChanges ); +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will add the object to the primary map of the manifest +// Input : pObject - a pointer to the object to be added +// pParent - a pointer to the parent of this object +//----------------------------------------------------------------------------- +void CManifest::AddObjectToWorld(CMapClass *pObject, CMapClass *pParent) +{ + m_pPrimaryMap->m_Map->AddObjectToWorld( pObject, pParent ); + + m_pPrimaryMap->m_Entity->PostUpdate( Notify_Changed ); +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will pass on the notification that a map has been updated +// Input : pInstanceMapDoc - the map that was updated +//----------------------------------------------------------------------------- +void CManifest::UpdateInstanceMap( CMapDoc *pInstanceMapDoc ) +{ + const CMapObjectList *pChildren = m_ManifestWorld->GetChildren(); + FOR_EACH_OBJ( *pChildren, pos ) + { + CMapClass *pChild = pChildren->Element( pos ); + CMapEntity *pEntity = dynamic_cast< CMapEntity * >( pChild ); + + if ( pEntity && stricmp( pEntity->GetClassName(), "func_instance" ) == 0 ) + { + CMapInstance *pMapInstance = pEntity->GetChildOfType( ( CMapInstance * )NULL ); + if ( pMapInstance ) + { + if ( pMapInstance->GetInstancedMap() == pInstanceMapDoc ) + { + pMapInstance->UpdateInstanceMap(); + m_ManifestWorld->UpdateChild( pMapInstance ); + } + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will add the object to the local manifest world. the +// only objects that should be added are ManifestInstance. +// Input : pObject - a pointer to the object to be added +// pParent - a pointer to the parent of this object +//----------------------------------------------------------------------------- +void CManifest::AddManifestObjectToWorld( CMapClass *pObject, CMapClass *pParent ) +{ + m_ManifestWorld->AddObjectToWorld( pObject, pParent ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Removes an object from the manifest world. +// Input : pObject - object to remove from the world. +// bChildren - whether we're removing the object's children as well. +//----------------------------------------------------------------------------- +void CManifest::RemoveManifestObjectFromWorld( CMapClass *pObject, bool bRemoveChildren ) +{ + m_ManifestWorld->RemoveObjectFromWorld( pObject, bRemoveChildren ); +} + +//----------------------------------------------------------------------------- +// Purpose: this function will start the loading process for a manifest +// Input : lpszPathName - the absoltue path of the manifest file +// Output : Returns TRUE on success, FALSE on failure. +//----------------------------------------------------------------------------- +BOOL CManifest::OnOpenDocument(LPCTSTR lpszPathName) +{ + Initialize(); + + if (!SelectDocType()) + { + return FALSE; + } + + // + // Call any per-class PreloadWorld functions here. + // + CMapSolid::PreloadWorld(); + + if ( !Load( lpszPathName ) ) + { + return FALSE; + } + + SetModifiedFlag( FALSE ); + Msg( mwStatus, "Opened %s", lpszPathName ); + SetActiveMapDoc( this ); + + // + // We set the active doc before loading for displacements (and maybe other + // things), but visgroups aren't available until after map load. We have to refresh + // the visgroups here or they won't be correct. + // + GetMainWnd()->GlobalNotify( WM_MAPDOC_CHANGED ); + + m_pToolManager->SetTool( TOOL_POINTER ); + + return(TRUE); +} + + +//----------------------------------------------------------------------------- +// Purpose: This function will save out the manifest +// Input : lpszPathName - the absolute filename of the manifest +// Output : Returns TRUE on success, FALSE on failure. +//----------------------------------------------------------------------------- +BOOL CManifest::OnSaveDocument(LPCTSTR lpszPathName) +{ + if ( !Save( lpszPathName, m_bRelocateSave ) ) + { + return FALSE; + } + + SetModifiedFlag( FALSE ); + + return TRUE; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will be called when the use select Save As. This will +// allow all of the submaps to be relocated relative to a new save location +// of the manifest itself. Directories should be created automatically. +//----------------------------------------------------------------------------- +void CManifest::OnFileSaveAs(void) +{ + m_bRelocateSave = true; + + __super::OnFileSaveAs(); + + m_bRelocateSave = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: this function will delete the manifest world and rest of the contents. +//----------------------------------------------------------------------------- +void CManifest::DeleteContents( void ) +{ + m_pSelection->RemoveAll(); + + if ( m_ManifestWorld ) + { + delete m_ManifestWorld; + m_ManifestWorld = NULL; + } + + m_pWorld = NULL; + m_VisGroups = NULL; + m_RootVisGroups = NULL; + m_pUndo = m_pSaveUndo; + m_pRedo = m_pSaveRedo; + + __super::DeleteContents(); +} + +#include <tier0/memdbgoff.h> |