summaryrefslogtreecommitdiff
path: root/hammer/manifest.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/manifest.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/manifest.cpp')
-rw-r--r--hammer/manifest.cpp1595
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>