Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1594 lines
45 KiB

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=====================================================================================//
  6. #include "stdafx.h"
  7. #include "Manifest.h"
  8. #include "CustomMessages.h"
  9. #include "GlobalFunctions.h"
  10. #include "MainFrm.h"
  11. #include "MapDoc.h"
  12. #include "MapSolid.h"
  13. #include "MapWorld.h"
  14. #include "MapInstance.h"
  15. #include "ToolManager.h"
  16. #include "ChunkFile.h"
  17. #include "ManifestDialog.h"
  18. #include "History.h"
  19. #include "HelperFactory.h"
  20. #include "SaveInfo.h"
  21. #include "p4lib/ip4.h"
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include <tier0/memdbgon.h>
  24. IMPLEMENT_DYNCREATE(CManifest, CMapDoc)
  25. BEGIN_MESSAGE_MAP(CManifest, CMapDoc)
  26. //{{AFX_MSG_MAP(CManifest)
  27. ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
  28. //}}AFX_MSG_MAP
  29. END_MESSAGE_MAP()
  30. IMPLEMENT_MAPCLASS( CManifestInstance )
  31. //-----------------------------------------------------------------------------
  32. // Purpose: default constructor
  33. //-----------------------------------------------------------------------------
  34. CManifestMap::CManifestMap( void )
  35. {
  36. m_Map = NULL;
  37. m_RelativeMapFileName = "";
  38. m_AbsoluteMapFileName = "";
  39. m_FriendlyName = "unnamed";
  40. m_bTopLevelMap = false;
  41. m_bPrimaryMap = false;
  42. m_bProtected = false;
  43. m_bReadOnly = false;
  44. m_bIsVersionControlled = false;
  45. m_bCheckedOut = false;
  46. m_bDefaultCheckin = false;
  47. m_bVisible = true;
  48. m_Entity = NULL;
  49. m_InternalID = 0;
  50. }
  51. //-----------------------------------------------------------------------------
  52. // Purpose: returns true if the manifest map is editable
  53. //-----------------------------------------------------------------------------
  54. bool CManifestMap::IsEditable( void )
  55. {
  56. return ( m_bProtected == false && m_bReadOnly == false && m_bPrimaryMap );
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Purpose: default constructor
  60. //-----------------------------------------------------------------------------
  61. CManifestInstance::CManifestInstance( void ) :
  62. CMapEntity()
  63. {
  64. m_pManifestMap = NULL;
  65. }
  66. //-----------------------------------------------------------------------------
  67. // Purpose: default constructor
  68. //-----------------------------------------------------------------------------
  69. CManifestInstance::CManifestInstance( CManifestMap *pManifestMap ) :
  70. CMapEntity()
  71. {
  72. m_pManifestMap = pManifestMap;
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose: returns true if the manifest map this instance owns is editable
  76. //-----------------------------------------------------------------------------
  77. bool CManifestInstance::IsEditable( void )
  78. {
  79. return m_pManifestMap->IsEditable();
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Purpose: default constructor
  83. //-----------------------------------------------------------------------------
  84. CManifest::CManifest( void ) :
  85. CMapDoc()
  86. {
  87. m_bIsValid = false;
  88. m_bRelocateSave = false;
  89. m_ManifestDir[ 0 ] = 0;
  90. m_pPrimaryMap = NULL;
  91. m_ManifestWorld = NULL;
  92. m_NextInternalID = 1;
  93. m_bManifestChanged = false;
  94. m_bManifestUserPrefsChanged = false;
  95. m_pSaveUndo = m_pUndo;
  96. m_pSaveRedo = m_pRedo;
  97. m_bReadOnly = true;
  98. m_bIsVersionControlled = false;
  99. m_bCheckedOut = false;
  100. m_bDefaultCheckin = false;
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Purpose: default destructor
  104. //-----------------------------------------------------------------------------
  105. CManifest::~CManifest( void )
  106. {
  107. m_Maps.PurgeAndDeleteElements();
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Purpose: this function will parse through the known keys for the manifest map entry
  111. // Input : szKey - the key name
  112. // szValue - the value
  113. // pManifestMap - the manifest map this belongs to
  114. // Output : ChunkFileResult_t - result of the parsing
  115. //-----------------------------------------------------------------------------
  116. ChunkFileResult_t CManifest::LoadKeyInfoCallback( const char *szKey, const char *szValue, CManifest *pDoc )
  117. {
  118. if ( !stricmp( szKey, "NextInternalID" ) )
  119. {
  120. pDoc->m_NextInternalID = atoi( szValue );
  121. }
  122. return ChunkFile_Ok;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose: this function is responsible for setting up the manifest map about to be read in
  126. // Input : pFile - the chunk file being read
  127. // pDoc - the owning manifest document
  128. // Output : ChunkFileResult_t - result of the parsing
  129. //-----------------------------------------------------------------------------
  130. ChunkFileResult_t CManifest::LoadManifestInfoCallback( CChunkFile *pFile, CManifest *pDoc )
  131. {
  132. ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadKeyInfoCallback, pDoc );
  133. return( eResult );
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose: this function will parse through the known keys for the manifest map entry
  137. // Input : szKey - the key name
  138. // szValue - the value
  139. // pManifestMap - the manifest map this belongs to
  140. // Output : ChunkFileResult_t - result of the parsing
  141. //-----------------------------------------------------------------------------
  142. ChunkFileResult_t CManifest::LoadKeyCallback( const char *szKey, const char *szValue, CManifestMap *pManifestMap )
  143. {
  144. if ( !stricmp( szKey, "InternalID" ) )
  145. {
  146. pManifestMap->m_InternalID = atoi( szValue );
  147. }
  148. else if ( !stricmp( szKey, "Name" ) )
  149. {
  150. pManifestMap->m_FriendlyName = szValue;
  151. }
  152. else if ( !stricmp( szKey, "File" ) )
  153. {
  154. pManifestMap->m_RelativeMapFileName = szValue;
  155. pManifestMap->m_AbsoluteMapFileName += szValue;
  156. if ( !pManifestMap->m_Map->LoadVMF( pManifestMap->m_AbsoluteMapFileName, VMF_LOAD_ACTIVATE | VMF_LOAD_IS_SUBMAP ) )
  157. {
  158. delete pManifestMap->m_Map;
  159. pManifestMap->m_Map = NULL;
  160. }
  161. pManifestMap->m_bReadOnly = true;
  162. }
  163. else if ( !stricmp( szKey, "TopLevel" ) )
  164. {
  165. pManifestMap->m_bTopLevelMap = ( atoi( szValue ) == 1 );
  166. }
  167. return ChunkFile_Ok;
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Purpose: this function is responsible for setting up the manifest map about to be read in
  171. // Input : pFile - the chunk file being read
  172. // pDoc - the owning manifest document
  173. // Output : ChunkFileResult_t - result of the parsing
  174. //-----------------------------------------------------------------------------
  175. ChunkFileResult_t CManifest::LoadManifestVMFCallback( CChunkFile *pFile, CManifest *pDoc )
  176. {
  177. char FileName[ MAX_PATH ];
  178. strcpy( FileName, pDoc->m_ManifestDir );
  179. CManifestMap *pManifestMap = pDoc->CreateNewMap( FileName, "", false );
  180. SetActiveMapDoc( pManifestMap->m_Map );
  181. ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadKeyCallback, pManifestMap );
  182. if ( pManifestMap->m_Map )
  183. {
  184. pManifestMap->m_Map->SetEditable( false );
  185. }
  186. SetActiveMapDoc( pDoc );
  187. return( eResult );
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Purpose: this function will load the VMF chunk
  191. // Input : pFile - the chunk file being read
  192. // pDoc - the owning manifest document
  193. // Output : ChunkFileResult_t - result of the parsing
  194. //-----------------------------------------------------------------------------
  195. ChunkFileResult_t CManifest::LoadManifestMapsCallback( CChunkFile *pFile, CManifest *pDoc )
  196. {
  197. CChunkHandlerMap Handlers;
  198. Handlers.AddHandler( "VMF", ( ChunkHandler_t )LoadManifestVMFCallback, pDoc );
  199. pFile->PushHandlers(&Handlers);
  200. ChunkFileResult_t eResult = ChunkFile_Ok;
  201. eResult = pFile->ReadChunk();
  202. pFile->PopHandlers();
  203. return( eResult );
  204. }
  205. typedef struct SManifestLoadPrefs
  206. {
  207. CManifest *pDoc;
  208. CManifestMap *pManifestMap;
  209. } TManifestLoadPrefs;
  210. //-----------------------------------------------------------------------------
  211. // Purpose: this function will parse through the known keys for the manifest map entry
  212. // Input : szKey - the key name
  213. // szValue - the value
  214. // pManifestMap - the manifest map this belongs to
  215. // Output : ChunkFileResult_t - result of the parsing
  216. //-----------------------------------------------------------------------------
  217. ChunkFileResult_t CManifest::LoadKeyPrefsCallback( const char *szKey, const char *szValue, TManifestLoadPrefs *pManifestLoadPrefs )
  218. {
  219. if ( !stricmp( szKey, "InternalID" ) )
  220. {
  221. pManifestLoadPrefs->pManifestMap = pManifestLoadPrefs->pDoc->FindMapByID( atoi( szValue ) );
  222. }
  223. else if ( !stricmp( szKey, "IsPrimary" ) )
  224. {
  225. if ( pManifestLoadPrefs->pManifestMap )
  226. {
  227. pManifestLoadPrefs->pManifestMap->m_bPrimaryMap = ( atoi( szValue ) == 1 );
  228. }
  229. }
  230. else if ( !stricmp( szKey, "IsProtected" ) )
  231. {
  232. if ( pManifestLoadPrefs->pManifestMap )
  233. {
  234. pManifestLoadPrefs->pManifestMap->m_bProtected = ( atoi( szValue ) == 1 );
  235. }
  236. }
  237. else if ( !stricmp( szKey, "IsVisible" ) )
  238. {
  239. if ( pManifestLoadPrefs->pManifestMap )
  240. {
  241. pManifestLoadPrefs->pManifestMap->m_bVisible = ( atoi( szValue ) == 1 );
  242. }
  243. }
  244. return ChunkFile_Ok;
  245. }
  246. //-----------------------------------------------------------------------------
  247. // Purpose: this function is responsible for setting up the manifest map about to be read in
  248. // Input : pFile - the chunk file being read
  249. // pDoc - the owning manifest document
  250. // Output : ChunkFileResult_t - result of the parsing
  251. //-----------------------------------------------------------------------------
  252. ChunkFileResult_t CManifest::LoadManifestVMFPrefsCallback( CChunkFile *pFile, CManifest *pDoc )
  253. {
  254. TManifestLoadPrefs ManifestLoadPrefs;
  255. ManifestLoadPrefs.pDoc = pDoc;
  256. ManifestLoadPrefs.pManifestMap = NULL;
  257. ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadKeyPrefsCallback, &ManifestLoadPrefs );
  258. return( eResult );
  259. }
  260. //-----------------------------------------------------------------------------
  261. // Purpose: this function will load the VMF chunk
  262. // Input : pFile - the chunk file being read
  263. // pDoc - the owning manifest document
  264. // Output : ChunkFileResult_t - result of the parsing
  265. //-----------------------------------------------------------------------------
  266. ChunkFileResult_t CManifest::LoadManifestMapsPrefsCallback( CChunkFile *pFile, CManifest *pDoc )
  267. {
  268. CChunkHandlerMap Handlers;
  269. Handlers.AddHandler( "VMF", ( ChunkHandler_t )LoadManifestVMFPrefsCallback, pDoc );
  270. pFile->PushHandlers(&Handlers);
  271. ChunkFileResult_t eResult = ChunkFile_Ok;
  272. eResult = pFile->ReadChunk();
  273. pFile->PopHandlers();
  274. return( eResult );
  275. }
  276. //-----------------------------------------------------------------------------
  277. // Purpose:
  278. // Input :
  279. // Output :
  280. //-----------------------------------------------------------------------------
  281. ChunkFileResult_t CManifest::LoadManifestCordoningPrefsCallback( CChunkFile *pFile, CManifest *pDoc )
  282. {
  283. CChunkHandlerMap Handlers;
  284. Handlers.AddHandler( "cordons", ( ChunkHandler_t )CMapDoc::LoadCordonsCallback, pDoc );
  285. pFile->PushHandlers(&Handlers);
  286. ChunkFileResult_t eResult = ChunkFile_Ok;
  287. eResult = pFile->ReadChunk();
  288. pFile->PopHandlers();
  289. return( eResult );
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Purpose: This function will load in a vmf manifest
  293. // Input : pszFileName - the file name of the manifest to load
  294. // Output : returns true if the load was successful
  295. //-----------------------------------------------------------------------------
  296. bool CManifest::LoadVMFManifest( const char *pszFileName )
  297. {
  298. FILE *fp = fopen( pszFileName, "rb" );
  299. if ( !fp )
  300. {
  301. return false;
  302. }
  303. V_StripExtension( pszFileName, m_ManifestDir, sizeof( m_ManifestDir ) );
  304. strcat( m_ManifestDir, "\\" );
  305. CChunkFile File;
  306. ChunkFileResult_t eResult = File.Open( pszFileName, ChunkFile_Read );
  307. m_bLoading = true;
  308. if (eResult == ChunkFile_Ok)
  309. {
  310. //
  311. // Set up handlers for the subchunks that we are interested in.
  312. //
  313. CChunkHandlerMap Handlers;
  314. Handlers.AddHandler( "Info", ( ChunkHandler_t )CManifest::LoadManifestInfoCallback, this );
  315. Handlers.AddHandler( "Maps", ( ChunkHandler_t )CManifest::LoadManifestMapsCallback, this );
  316. Handlers.SetErrorHandler( ( ChunkErrorHandler_t )CMapDoc::HandleLoadError, this);
  317. File.PushHandlers(&Handlers);
  318. while (eResult == ChunkFile_Ok)
  319. {
  320. eResult = File.ReadChunk();
  321. }
  322. if (eResult == ChunkFile_EOF)
  323. {
  324. eResult = ChunkFile_Ok;
  325. }
  326. File.PopHandlers();
  327. }
  328. if (eResult == ChunkFile_Ok)
  329. {
  330. }
  331. else
  332. {
  333. GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error loading manifest!", MB_OK | MB_ICONEXCLAMATION );
  334. }
  335. if ( GetNumMaps() == 0 )
  336. {
  337. GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Manifest file does not contain any maps!", MB_OK | MB_ICONEXCLAMATION );
  338. return false;
  339. }
  340. SetActiveMapDoc( this );
  341. PostloadDocument( pszFileName );
  342. m_ManifestWorld->PostloadWorld();
  343. bool bSetIDs = false;
  344. for( int i = 0; i < GetNumMaps(); i++ )
  345. {
  346. CManifestMap *pManifestMap = GetMap( i );
  347. if ( pManifestMap->m_InternalID == 0 )
  348. {
  349. pManifestMap->m_InternalID = m_NextInternalID;
  350. m_NextInternalID++;
  351. bSetIDs = true;
  352. }
  353. if ( pManifestMap->m_Map == NULL || pManifestMap->m_Map->GetMapWorld() == NULL )
  354. {
  355. pManifestMap->m_bPrimaryMap = false;
  356. RemoveSubMap( pManifestMap );
  357. i = -1;
  358. }
  359. }
  360. LoadVMFManifestUserPrefs( pszFileName );
  361. for( int i = 0; i < GetNumMaps(); i++ )
  362. {
  363. CManifestMap *pManifestMap = GetMap( i );
  364. if ( pManifestMap->m_bPrimaryMap )
  365. {
  366. SetPrimaryMap( pManifestMap );
  367. }
  368. }
  369. if ( !m_pPrimaryMap )
  370. {
  371. SetPrimaryMap( GetMap( 0 ) );
  372. }
  373. m_bLoading = false;
  374. m_bIsValid = true;
  375. m_bManifestChanged = bSetIDs;
  376. GetMainWnd()->m_ManifestFilterControl.UpdateManifestList();
  377. return true;
  378. }
  379. //-----------------------------------------------------------------------------
  380. // Purpose: this function will load the user prefs for the manifest file.
  381. // Input : pszFileName - the manifest file name.
  382. // Output : true if prefs were loaded.
  383. //-----------------------------------------------------------------------------
  384. bool CManifest::LoadVMFManifestUserPrefs( const char *pszFileName )
  385. {
  386. char UserName[ MAX_PATH ], FileName[ MAX_PATH ], UserPrefsFileName[ MAX_PATH ];
  387. DWORD UserNameSize;
  388. m_bManifestUserPrefsChanged = false;
  389. UserNameSize = sizeof( UserName );
  390. if ( GetUserName( UserName, &UserNameSize ) == 0 )
  391. {
  392. strcpy( UserPrefsFileName, "default" );
  393. }
  394. strcpy( FileName, m_ManifestDir );
  395. sprintf( UserPrefsFileName, "%s.vmm_prefs", UserName );
  396. strcat( FileName, UserPrefsFileName );
  397. FILE *fp = fopen( FileName, "rb" );
  398. if ( !fp )
  399. {
  400. return false;
  401. }
  402. CChunkFile File;
  403. ChunkFileResult_t eResult = File.Open( FileName, ChunkFile_Read );
  404. m_bLoading = true;
  405. if ( eResult == ChunkFile_Ok )
  406. {
  407. //
  408. // Set up handlers for the subchunks that we are interested in.
  409. //
  410. CChunkHandlerMap Handlers;
  411. Handlers.AddHandler( "Maps", ( ChunkHandler_t )CManifest::LoadManifestMapsPrefsCallback, this );
  412. Handlers.AddHandler( "cordoning", ( ChunkHandler_t )CManifest::LoadManifestCordoningPrefsCallback, this );
  413. Handlers.SetErrorHandler( ( ChunkErrorHandler_t )CMapDoc::HandleLoadError, this);
  414. File.PushHandlers(&Handlers);
  415. while( eResult == ChunkFile_Ok )
  416. {
  417. eResult = File.ReadChunk();
  418. }
  419. if ( eResult == ChunkFile_EOF )
  420. {
  421. eResult = ChunkFile_Ok;
  422. }
  423. File.PopHandlers();
  424. }
  425. if ( eResult == ChunkFile_Ok )
  426. {
  427. }
  428. else
  429. {
  430. // no pref message for now
  431. // GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error loading manifest!", MB_OK | MB_ICONEXCLAMATION );
  432. }
  433. return true;
  434. }
  435. //-----------------------------------------------------------------------------
  436. // Purpose: this function will load in a manifest file ( and its user prefs )
  437. // Input : pszFileName - the name of the manifest file.
  438. // Output : returns true if the manifest was loaded.
  439. //-----------------------------------------------------------------------------
  440. bool CManifest::Load( const char *pszFileName )
  441. {
  442. if ( !LoadVMFManifest( pszFileName ) )
  443. {
  444. return false;
  445. }
  446. return true;
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Purpose: This function will save the manifest, the associated maps, and user prefs.
  450. // Input : pszFileName - the name of the manifest
  451. // bForce - if true, we need to save all files, as we are relocating.
  452. // Output : returns true if all files saved successfully.
  453. //-----------------------------------------------------------------------------
  454. bool CManifest::Save( const char *pszFileName, bool bForce )
  455. {
  456. bool bSuccess = true;
  457. if ( bForce || m_bManifestChanged )
  458. {
  459. if ( !SaveVMFManifest( pszFileName ) )
  460. {
  461. bSuccess = false;
  462. }
  463. }
  464. if ( !SaveVMFManifestMaps( pszFileName ) )
  465. {
  466. bSuccess = false;
  467. }
  468. // if ( bForce || m_bManifestUserPrefsChanged )
  469. {
  470. if ( !SaveVMFManifestUserPrefs( pszFileName ) )
  471. {
  472. bSuccess = false;
  473. }
  474. }
  475. return bSuccess;
  476. }
  477. //-----------------------------------------------------------------------------
  478. // Purpose: this function will save the manifest file and all modified maps. If we are
  479. // relocating the manifest to a new place, all maps will be saved relative to
  480. // the new place
  481. // Input : the file name the manifest should be saved as
  482. // Output : returns true if the save was completely successful. A partial save will
  483. // return false.
  484. //-----------------------------------------------------------------------------
  485. bool CManifest::SaveVMFManifest( const char *pszFileName )
  486. {
  487. bool bSaved = true;
  488. CChunkFile File;
  489. ChunkFileResult_t eResult = File.Open( pszFileName, ChunkFile_Write );
  490. if (eResult != ChunkFile_Ok)
  491. {
  492. GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest!" , MB_OK | MB_ICONEXCLAMATION );
  493. bSaved = false;
  494. }
  495. else
  496. {
  497. eResult = File.BeginChunk( "Info" );
  498. eResult = File.WriteKeyValueInt( "NextInternalID", m_NextInternalID );
  499. eResult = File.EndChunk();
  500. eResult = File.BeginChunk( "Maps" );
  501. if (eResult == ChunkFile_Ok)
  502. {
  503. for( int i = 0; i < GetNumMaps(); i++ )
  504. {
  505. CManifestMap *pManifestMap = GetMap( i );
  506. ChunkFileResult_t eResult = File.BeginChunk("VMF");
  507. if (eResult == ChunkFile_Ok)
  508. {
  509. eResult = File.WriteKeyValue( "Name", pManifestMap->m_FriendlyName );
  510. eResult = File.WriteKeyValue( "File", pManifestMap->m_RelativeMapFileName );
  511. eResult = File.WriteKeyValueInt( "InternalID", pManifestMap->m_InternalID );
  512. if ( pManifestMap->m_bTopLevelMap == true )
  513. {
  514. eResult = File.WriteKeyValue( "TopLevel", "1" );
  515. }
  516. eResult = File.EndChunk();
  517. }
  518. }
  519. }
  520. if (eResult == ChunkFile_Ok)
  521. {
  522. eResult = File.EndChunk();
  523. }
  524. else
  525. {
  526. GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest!", MB_OK | MB_ICONEXCLAMATION );
  527. bSaved = false;
  528. }
  529. File.Close();
  530. }
  531. V_StripExtension( pszFileName, m_ManifestDir, sizeof( m_ManifestDir ) );
  532. CreateDirectory( m_ManifestDir, NULL );
  533. strcat( m_ManifestDir, "\\" );
  534. if ( bSaved )
  535. {
  536. m_bManifestChanged = false;
  537. }
  538. return bSaved;
  539. }
  540. //-----------------------------------------------------------------------------
  541. // Purpose: This function will save all maps associated with a manifest. Only modified
  542. // maps are saved unless we are relocating the manifest.
  543. // Input : pszFileName - the name of the manifest file
  544. // Output : returns true if the maps were saved successfully.
  545. //-----------------------------------------------------------------------------
  546. bool CManifest::SaveVMFManifestMaps( const char *pszFileName )
  547. {
  548. bool bSaved = true;
  549. for( int i = 0; i < GetNumMaps(); i++ )
  550. {
  551. CManifestMap *pManifestMap = GetMap( i );
  552. if ( m_bRelocateSave )
  553. {
  554. char FileName[ MAX_PATH ];
  555. strcpy( FileName, m_ManifestDir );
  556. strcat( FileName, pManifestMap->m_RelativeMapFileName );
  557. pManifestMap->m_AbsoluteMapFileName = FileName;
  558. }
  559. if ( ( pManifestMap->m_Map->IsModified() || m_bRelocateSave ) )
  560. {
  561. if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false )
  562. {
  563. bSaved = false;
  564. }
  565. }
  566. }
  567. if ( !bSaved )
  568. {
  569. GetMainWnd()->MessageBox( "Not all pieces of the manifest were saved!", "Error saving Manifest!", MB_OK | MB_ICONEXCLAMATION );
  570. }
  571. return bSaved;
  572. }
  573. //-----------------------------------------------------------------------------
  574. // Purpose: this function will save the user prefs of the manifest.
  575. // Input : pszFileName - the name of the manifest file.
  576. // Output : returns true if the prefs were saved.
  577. //-----------------------------------------------------------------------------
  578. bool CManifest::SaveVMFManifestUserPrefs( const char *pszFileName )
  579. {
  580. bool bSaved = true;
  581. CChunkFile File;
  582. char UserName[ MAX_PATH ], FileName[ MAX_PATH ], UserPrefsFileName[ MAX_PATH ];
  583. DWORD UserNameSize;
  584. UserNameSize = sizeof( UserName );
  585. if ( GetUserName( UserName, &UserNameSize ) == 0 )
  586. {
  587. strcpy( UserPrefsFileName, "default" );
  588. }
  589. strcpy( FileName, m_ManifestDir );
  590. sprintf( UserPrefsFileName, "%s.vmm_prefs", UserName );
  591. strcat( FileName, UserPrefsFileName );
  592. ChunkFileResult_t eResult = File.Open( FileName, ChunkFile_Write );
  593. if (eResult != ChunkFile_Ok)
  594. {
  595. GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest User Prefs!" , MB_OK | MB_ICONEXCLAMATION );
  596. bSaved = false;
  597. }
  598. else
  599. {
  600. eResult = File.BeginChunk( "Maps" );
  601. if (eResult == ChunkFile_Ok)
  602. {
  603. for( int i = 0; i < GetNumMaps(); i++ )
  604. {
  605. CManifestMap *pManifestMap = GetMap( i );
  606. ChunkFileResult_t eResult = File.BeginChunk("VMF");
  607. if (eResult == ChunkFile_Ok)
  608. {
  609. eResult = File.WriteKeyValueInt( "InternalID", pManifestMap->m_InternalID );
  610. if ( pManifestMap->m_bPrimaryMap )
  611. {
  612. eResult = File.WriteKeyValue( "IsPrimary", "1" );
  613. }
  614. if ( pManifestMap->m_bProtected == true )
  615. {
  616. eResult = File.WriteKeyValue( "IsProtected", "1" );
  617. }
  618. if ( pManifestMap->m_bVisible == false )
  619. {
  620. eResult = File.WriteKeyValue( "IsVisible", "0" );
  621. }
  622. eResult = File.EndChunk();
  623. }
  624. }
  625. }
  626. if (eResult == ChunkFile_Ok)
  627. {
  628. eResult = File.EndChunk();
  629. }
  630. else
  631. {
  632. GetMainWnd()->MessageBox( File.GetErrorText( eResult ), "Error saving Manifest User Prefs!", MB_OK | MB_ICONEXCLAMATION );
  633. bSaved = false;
  634. }
  635. eResult = File.BeginChunk( "cordoning" );
  636. eResult = Cordon_SaveVMF( &File, NULL );
  637. if ( m_bIsCordoning )
  638. {
  639. CSaveInfo SaveInfo;
  640. SaveInfo.SetVisiblesOnly( false );
  641. CMapWorld *pCordonWorld = Cordon_CreateWorld();
  642. eResult = pCordonWorld->SaveSolids( &File, &SaveInfo, 0 );
  643. }
  644. eResult = File.EndChunk();
  645. File.Close();
  646. }
  647. if ( bSaved )
  648. {
  649. m_bManifestUserPrefsChanged = false;
  650. }
  651. return bSaved;
  652. }
  653. //-----------------------------------------------------------------------------
  654. // Purpose: this function will initialize the manifest
  655. //-----------------------------------------------------------------------------
  656. void CManifest::Initialize( void )
  657. {
  658. __super::Initialize();
  659. m_ManifestWorld = new CMapWorld( this );
  660. m_ManifestWorld->CullTree_Build();
  661. }
  662. //-----------------------------------------------------------------------------
  663. // Purpose: this function will update the manifest and all of its sub maps
  664. //-----------------------------------------------------------------------------
  665. void CManifest::Update( void )
  666. {
  667. __super::Update();
  668. for( int i = 0; i < GetNumMaps(); i++ )
  669. {
  670. CManifestMap *pManifestMap = GetMap( i );
  671. pManifestMap->m_Map->Update();
  672. }
  673. }
  674. //-----------------------------------------------------------------------------
  675. // Purpose: this function allows you to indicate if the user prefs have been modified.
  676. // Input : bModified - the new status of the user prefs
  677. //-----------------------------------------------------------------------------
  678. void CManifest::SetManifestPrefsModifiedFlag( bool bModified )
  679. {
  680. m_bManifestUserPrefsChanged = bModified;
  681. }
  682. //-----------------------------------------------------------------------------
  683. // Purpose: this function handles the routing of the manifest's modified flag down to the primary map
  684. // Input : bModified - the new modified status
  685. //-----------------------------------------------------------------------------
  686. void CManifest::SetModifiedFlag( BOOL bModified )
  687. {
  688. if ( m_pPrimaryMap )
  689. {
  690. m_pPrimaryMap->m_Map->SetModifiedFlag( bModified );
  691. }
  692. if ( bModified == false )
  693. {
  694. for( int i = 0; i < GetNumMaps(); i++ )
  695. {
  696. CManifestMap *pManifestMap = GetMap( i );
  697. if ( pManifestMap->m_Map->IsModified() )
  698. {
  699. bModified = true;
  700. break;
  701. }
  702. }
  703. }
  704. if ( bModified != IsModified() )
  705. {
  706. GetMainWnd()->m_ManifestFilterControl.Invalidate();
  707. }
  708. __super::SetModifiedFlag( bModified );
  709. }
  710. //-----------------------------------------------------------------------------
  711. // Purpose: this function will return the full path to a sub map.
  712. // Input : pManifestMapFileName - the relative name of the sub map
  713. // Output : pOutputPath - the full path to the sub map
  714. //-----------------------------------------------------------------------------
  715. void CManifest::GetFullMapPath( const char *pManifestMapFileName, char *pOutputPath )
  716. {
  717. strcpy( pOutputPath, m_ManifestDir );
  718. strcat( pOutputPath, pManifestMapFileName );
  719. }
  720. //-----------------------------------------------------------------------------
  721. // Purpose: this function will attempt to find the manifest map that owns the map doc
  722. // Input : pMap - the map doc to look up
  723. // Output : returns a pointer to the owning manifest map, otherwise NULL
  724. //-----------------------------------------------------------------------------
  725. CManifestMap *CManifest::FindMap( CMapDoc *pMap )
  726. {
  727. for( int i = 0; i < GetNumMaps(); i++ )
  728. {
  729. CManifestMap *pManifestMap = GetMap( i );
  730. if ( pManifestMap->m_Map == pMap )
  731. {
  732. return pManifestMap;
  733. }
  734. }
  735. return NULL;
  736. }
  737. //-----------------------------------------------------------------------------
  738. // Purpose: this function will attempt to look up a map by its internal id.
  739. // Input : InternalID - the internal ID.
  740. // Output : returns the manifest map if one is found.
  741. //-----------------------------------------------------------------------------
  742. CManifestMap *CManifest::FindMapByID( int InternalID )
  743. {
  744. for( int i = 0; i < GetNumMaps(); i++ )
  745. {
  746. CManifestMap *pManifestMap = GetMap( i );
  747. if ( pManifestMap->m_InternalID == InternalID )
  748. {
  749. return pManifestMap;
  750. }
  751. }
  752. return NULL;
  753. }
  754. //-----------------------------------------------------------------------------
  755. // Purpose: this function will set the manifest map as the primary map. All entity / brush
  756. // operations happen exclusively on the primary map.
  757. // Input : pManifestMap - the manifest map to make primary
  758. //-----------------------------------------------------------------------------
  759. void CManifest::SetPrimaryMap( CManifestMap *pManifestMap )
  760. {
  761. if ( m_pPrimaryMap )
  762. {
  763. m_pPrimaryMap->m_bPrimaryMap = false;
  764. m_pPrimaryMap->m_Map->m_nNextMapObjectID = m_nNextMapObjectID;
  765. m_pPrimaryMap->m_Map->m_nNextMapObjectID = m_nNextNodeID;
  766. m_pPrimaryMap->m_Map->SetEditable( false );
  767. }
  768. ClearSelection();
  769. CheckFileStatus();
  770. m_pPrimaryMap = pManifestMap;
  771. if ( m_pPrimaryMap )
  772. {
  773. m_pPrimaryMap->m_bPrimaryMap = true;
  774. m_pWorld = m_pPrimaryMap->m_Map->GetMapWorld();
  775. m_VisGroups = m_pPrimaryMap->m_Map->m_VisGroups;
  776. m_RootVisGroups = m_pPrimaryMap->m_Map->m_RootVisGroups;
  777. m_nNextMapObjectID = m_pPrimaryMap->m_Map->m_nNextMapObjectID;
  778. m_nNextNodeID = m_pPrimaryMap->m_Map->m_nNextMapObjectID;
  779. m_pPrimaryMap->m_Map->SetEditable( !m_pPrimaryMap->m_bReadOnly );
  780. m_pUndo = m_pPrimaryMap->m_Map->m_pUndo;
  781. m_pRedo = m_pPrimaryMap->m_Map->m_pRedo;
  782. CHistory::SetHistory( m_pPrimaryMap->m_Map->m_pUndo );
  783. // m_pSelection = m_pPrimaryMap->m_Map->m_pSelection;
  784. }
  785. m_bManifestUserPrefsChanged = true;
  786. GetMainWnd()->GlobalNotify( WM_MAPDOC_CHANGED );
  787. GetMainWnd()->m_ManifestFilterControl.Invalidate();
  788. UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW );
  789. }
  790. //-----------------------------------------------------------------------------
  791. // Purpose: sets the visibility flag of a sub map.
  792. // Input : pManifestMap - the map to set the flag
  793. // bIsVisible - the visiblity status
  794. //-----------------------------------------------------------------------------
  795. void CManifest::SetVisibility( CManifestMap *pManifestMap, bool bIsVisible )
  796. {
  797. pManifestMap->m_bVisible = bIsVisible;
  798. GetMainWnd()->m_ManifestFilterControl.Invalidate();
  799. UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW );
  800. }
  801. //-----------------------------------------------------------------------------
  802. // Purpose: this function will create and default a new manifest map, add it to the world
  803. // Input : AbsoluteFileName - the full path of the vmf file
  804. // RelativeFileName - the relative path of the vmf file
  805. // Output : returns a pointer to the newly created manifest map.
  806. //-----------------------------------------------------------------------------
  807. CManifestMap *CManifest::CreateNewMap( const char *AbsoluteFileName, const char *RelativeFileName, bool bSetID )
  808. {
  809. CManifestMap *pManifestMap = new CManifestMap();
  810. pManifestMap->m_AbsoluteMapFileName = AbsoluteFileName;
  811. pManifestMap->m_RelativeMapFileName = RelativeFileName;
  812. pManifestMap->m_Map = new CMapDoc();
  813. SetActiveMapDoc( pManifestMap->m_Map );
  814. pManifestMap->m_Map->SetManifest( this );
  815. pManifestMap->m_Map->SetEditable( false );
  816. pManifestMap->m_Entity = new CManifestInstance( pManifestMap );
  817. pManifestMap->m_Entity->SetPlaceholder( true );
  818. pManifestMap->m_Entity->SetOrigin( Vector( 0.0f, 0.0f, 0.0f ) );
  819. pManifestMap->m_Entity->SetClass( "func_instance" );
  820. pManifestMap->m_Entity->SetKeyValue( "classname", "func_instance" );
  821. // ensure we are a pure instance of only the instance helper!
  822. pManifestMap->m_Entity->RemoveAllChildren();
  823. CHelperInfo HI;
  824. HI.SetName( "instance" );
  825. CMapClass *pHelper = CHelperFactory::CreateHelper( &HI, pManifestMap->m_Entity );
  826. if ( pHelper != NULL )
  827. {
  828. pManifestMap->m_Entity->AddHelper( pHelper, false );
  829. }
  830. if ( bSetID )
  831. {
  832. pManifestMap->m_InternalID = m_NextInternalID;
  833. m_NextInternalID++;
  834. }
  835. CMapInstance *pMapInstance = pManifestMap->m_Entity->GetChildOfType( ( CMapInstance * )NULL );
  836. if ( pMapInstance )
  837. {
  838. pMapInstance->SetManifest( pManifestMap );
  839. }
  840. AddManifestObjectToWorld( pManifestMap->m_Entity );
  841. m_Maps.AddToTail( pManifestMap );
  842. m_bManifestChanged = true;
  843. return pManifestMap;
  844. }
  845. //-----------------------------------------------------------------------------
  846. // Purpose: This function will move the selection of the active map to a new sub map.
  847. // Input : pManifestMap - the sub map the selection shoud be moved to
  848. // CenterContents - if the contents should be centered
  849. //-----------------------------------------------------------------------------
  850. void CManifest::MoveSelectionToSubmap( CManifestMap *pManifestMap, bool CenterContents )
  851. {
  852. #if 0
  853. if ( s_Clipboard.Objects.Count() != 0 )
  854. {
  855. return false;
  856. }
  857. #endif
  858. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  859. if ( !pDoc )
  860. {
  861. return;
  862. }
  863. pDoc->Copy();
  864. if ( pDoc->GetClipboardCount() == 0 )
  865. {
  866. return;
  867. }
  868. pDoc->Delete();
  869. 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 );
  870. pManifestMap->m_Entity->CalcBounds( TRUE );
  871. UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW );
  872. }
  873. //-----------------------------------------------------------------------------
  874. // Purpose: this function will cut the selection and move it into a newly created
  875. // map doc and manifest map.
  876. // Input : FriendlyName - this is the text friendly name that the user can refer
  877. // to the map as
  878. // FileName - The relative file name for this new map to be saved as
  879. // CenterContents - whether or not we should center the contents in the new map
  880. // Output : returns a pointer to the newly created manifest map.
  881. //-----------------------------------------------------------------------------
  882. CManifestMap *CManifest::MoveSelectionToNewSubmap( CString &FriendlyName, CString &FileName, bool CenterContents )
  883. {
  884. #if 0
  885. if ( s_Clipboard.Objects.Count() != 0 )
  886. {
  887. return false;
  888. }
  889. #endif
  890. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  891. if ( !pDoc )
  892. {
  893. return NULL;
  894. }
  895. pDoc->Copy();
  896. if ( pDoc->GetClipboardCount() == 0 )
  897. {
  898. return NULL;
  899. }
  900. char AbsoluteFileName[ MAX_PATH ];
  901. strcpy( AbsoluteFileName, m_ManifestDir );
  902. strcat( AbsoluteFileName, FileName );
  903. CManifestMap *pManifestMap = CreateNewMap( AbsoluteFileName, FileName, true );
  904. pManifestMap->m_FriendlyName = FriendlyName;
  905. pManifestMap->m_Map->Initialize();
  906. if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false )
  907. {
  908. m_bLoading = false;
  909. SetActiveMapDoc( this );
  910. delete pManifestMap;
  911. return NULL;
  912. }
  913. pDoc->Delete();
  914. 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 );
  915. pManifestMap->m_Entity->CalcBounds( TRUE );
  916. SetPrimaryMap( pManifestMap );
  917. SetActiveMapDoc( this );
  918. __super::SetModifiedFlag( true );
  919. pDoc->SetModifiedFlag( true );
  920. pManifestMap->m_Map->SetModifiedFlag( true );
  921. UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW );
  922. GetMainWnd()->m_ManifestFilterControl.UpdateManifestList();
  923. return pManifestMap;
  924. }
  925. //-----------------------------------------------------------------------------
  926. // Purpose: this function will add a new sub map to the manifest.
  927. // Input : FriendlyName - the friendly name string
  928. // FileName - the file name of the sub map
  929. // Output : returns a pointer to the new manifest map.
  930. //-----------------------------------------------------------------------------
  931. CManifestMap *CManifest::AddNewSubmap( CString &FriendlyName, CString &FileName )
  932. {
  933. char AbsoluteFileName[ MAX_PATH ];
  934. strcpy( AbsoluteFileName, m_ManifestDir );
  935. strcat( AbsoluteFileName, FileName );
  936. CManifestMap *pManifestMap = CreateNewMap( AbsoluteFileName, FileName, true );
  937. pManifestMap->m_FriendlyName = FriendlyName;
  938. pManifestMap->m_Map->Initialize();
  939. pManifestMap->m_Entity->CalcBounds( TRUE );
  940. if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false )
  941. {
  942. m_bLoading = false;
  943. SetActiveMapDoc( this );
  944. delete pManifestMap;
  945. return NULL;
  946. }
  947. SetPrimaryMap( pManifestMap );
  948. SetActiveMapDoc( this );
  949. __super::SetModifiedFlag( true );
  950. UpdateAllViews( MAPVIEW_UPDATE_SELECTION | MAPVIEW_UPDATE_TOOL | MAPVIEW_RENDER_NOW );
  951. GetMainWnd()->m_ManifestFilterControl.UpdateManifestList();
  952. return pManifestMap;
  953. }
  954. //-----------------------------------------------------------------------------
  955. // Purpose: This function add an external vmf file to the manifest
  956. // Input : pszFileName - the absolute file name of the vmf file
  957. // bFromInstance - if the map is coming from a func_instance somewhere
  958. // Output : returns true if the map could be loaded and the manifest was created
  959. //-----------------------------------------------------------------------------
  960. bool CManifest::AddExistingMap( const char *pszFileName, bool bFromInstance )
  961. {
  962. char AbsoluteFileName[ MAX_PATH ], RelativeFileName[ MAX_PATH ];
  963. char FileExt[ MAX_PATH ];
  964. _splitpath_s( pszFileName, NULL, 0, NULL, 0, RelativeFileName, sizeof( RelativeFileName ), FileExt, sizeof( FileExt ) );
  965. strcat( RelativeFileName, FileExt );
  966. strcpy( AbsoluteFileName, m_ManifestDir );
  967. strcat( AbsoluteFileName, RelativeFileName );
  968. CManifestMap *pManifestMap = CreateNewMap( AbsoluteFileName, RelativeFileName, true );
  969. m_bLoading = true;
  970. if ( !pManifestMap->m_Map->LoadVMF( pszFileName, VMF_LOAD_ACTIVATE | VMF_LOAD_IS_SUBMAP ) )
  971. {
  972. m_bLoading = false;
  973. SetActiveMapDoc( this );
  974. delete pManifestMap;
  975. return false;
  976. }
  977. if ( pManifestMap->m_Map->SaveVMF( pManifestMap->m_AbsoluteMapFileName, 0 ) == false )
  978. {
  979. m_bLoading = false;
  980. SetActiveMapDoc( this );
  981. delete pManifestMap;
  982. return false;
  983. }
  984. pManifestMap->m_Map->GetMapWorld()->CullTree_Build();
  985. pManifestMap->m_Entity->PostUpdate( Notify_Changed );
  986. if ( m_Maps.Count() == 1 )
  987. {
  988. pManifestMap->m_bTopLevelMap = true;
  989. }
  990. SetPrimaryMap( pManifestMap );
  991. m_bLoading = false;
  992. SetActiveMapDoc( this );
  993. __super::SetModifiedFlag( true );
  994. GetMainWnd()->m_ManifestFilterControl.UpdateManifestList();
  995. if ( GetPathName().GetLength() == 0 )
  996. {
  997. char ManifestFile[ MAX_PATH ];
  998. strcpy( ManifestFile, pszFileName );
  999. V_SetExtension( ManifestFile, ".vmm", sizeof( ManifestFile ) );
  1000. m_bRelocateSave = true;
  1001. OnSaveDocument( ManifestFile );
  1002. m_bRelocateSave = false;
  1003. SetPathName( ManifestFile, false );
  1004. }
  1005. return true;
  1006. }
  1007. //-----------------------------------------------------------------------------
  1008. // Purpose: This function will allow the user to browse to an exist map to add to the manifest.
  1009. //-----------------------------------------------------------------------------
  1010. bool CManifest::AddExistingMap( void )
  1011. {
  1012. char szInitialDir[ MAX_PATH ];
  1013. strcpy( szInitialDir, GetPathName() );
  1014. if ( szInitialDir[ 0 ] == '\0' )
  1015. {
  1016. strcpy( szInitialDir, g_pGameConfig->szMapDir );
  1017. }
  1018. CFileDialog dlg( TRUE, NULL, NULL, OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, "Valve Map Files (*.vmf)|*.vmf||" );
  1019. dlg.m_ofn.lpstrInitialDir = szInitialDir;
  1020. int iRvl = dlg.DoModal();
  1021. if ( iRvl == IDCANCEL )
  1022. {
  1023. return false;
  1024. }
  1025. //
  1026. // Get the directory they browsed to for next time.
  1027. //
  1028. CString str = dlg.GetPathName();
  1029. int nSlash = str.ReverseFind( '\\' );
  1030. if ( nSlash != -1 )
  1031. {
  1032. strcpy( szInitialDir, str.Left( nSlash ) );
  1033. }
  1034. if ( str.Find('.') == -1 )
  1035. {
  1036. switch ( dlg.m_ofn.nFilterIndex )
  1037. {
  1038. case 1:
  1039. str += ".vmf";
  1040. break;
  1041. }
  1042. }
  1043. return AddExistingMap( str, false );
  1044. }
  1045. //-----------------------------------------------------------------------------
  1046. // Purpose: This function will remove the sub map from the manifest
  1047. // Input : pManifestMap - the sub map to be removed
  1048. // Output : returns true if it was successful
  1049. //-----------------------------------------------------------------------------
  1050. bool CManifest::RemoveSubMap( CManifestMap *pManifestMap )
  1051. {
  1052. if ( m_Maps.Count() > 1 )
  1053. {
  1054. m_Maps.FindAndRemove( pManifestMap );
  1055. const CMapObjectList *pChildren = m_ManifestWorld->GetChildren();
  1056. FOR_EACH_OBJ( *pChildren, pos )
  1057. {
  1058. CMapClass *pChild = (CUtlReference< CMapClass >)pChildren->Element( pos );
  1059. CMapEntity *pEntity = dynamic_cast< CMapEntity * >( pChild );
  1060. if ( pEntity && stricmp( pEntity->GetClassName(), "func_instance" ) == 0 )
  1061. {
  1062. CMapInstance *pMapInstance = pEntity->GetChildOfType( ( CMapInstance * )NULL );
  1063. if ( pMapInstance )
  1064. {
  1065. if ( pMapInstance->GetManifestMap() == pManifestMap )
  1066. {
  1067. m_ManifestWorld->RemoveObjectFromWorld( pChild, true );
  1068. break;
  1069. }
  1070. }
  1071. }
  1072. }
  1073. delete pManifestMap;
  1074. return true;
  1075. }
  1076. return false;
  1077. }
  1078. //-----------------------------------------------------------------------------
  1079. // Purpose:
  1080. // Input :
  1081. // Output :
  1082. //-----------------------------------------------------------------------------
  1083. bool CManifest::CheckOut( )
  1084. {
  1085. if ( !p4 )
  1086. {
  1087. return false;
  1088. }
  1089. if ( !p4->OpenFileForEdit( GetPathName() ) )
  1090. {
  1091. return false;
  1092. }
  1093. CheckFileStatus();
  1094. return true;
  1095. }
  1096. //-----------------------------------------------------------------------------
  1097. // Purpose:
  1098. // Input :
  1099. // Output :
  1100. //-----------------------------------------------------------------------------
  1101. bool CManifest::AddToVersionControl( )
  1102. {
  1103. if ( !p4 )
  1104. {
  1105. return false;
  1106. }
  1107. if ( !p4->OpenFileForAdd( GetPathName() ) )
  1108. {
  1109. return false;
  1110. }
  1111. CheckFileStatus();
  1112. return true;
  1113. }
  1114. //-----------------------------------------------------------------------------
  1115. // Purpose:
  1116. // Input :
  1117. // Output :
  1118. //-----------------------------------------------------------------------------
  1119. void CManifest::CheckFileStatus( void )
  1120. {
  1121. P4File_t FileInfo;
  1122. m_bReadOnly = !g_pFullFileSystem->IsFileWritable( GetPathName() );
  1123. m_bCheckedOut = false;
  1124. m_bIsVersionControlled = false;
  1125. if ( p4 != NULL && p4->GetFileInfo( GetPathName(), &FileInfo ) == true )
  1126. {
  1127. m_bIsVersionControlled = true;
  1128. if ( FileInfo.m_eOpenState == P4FILE_OPENED_FOR_ADD || FileInfo.m_eOpenState == P4FILE_OPENED_FOR_EDIT )
  1129. {
  1130. m_bCheckedOut = true;
  1131. }
  1132. }
  1133. for( int i = 0; i < GetNumMaps(); i++ )
  1134. {
  1135. CManifestMap *pManifestMap = GetMap( i );
  1136. pManifestMap->m_bReadOnly = !g_pFullFileSystem->IsFileWritable( pManifestMap->m_AbsoluteMapFileName );
  1137. pManifestMap->m_bCheckedOut = false;
  1138. pManifestMap->m_bIsVersionControlled = false;
  1139. if ( p4 != NULL && p4->GetFileInfo( pManifestMap->m_AbsoluteMapFileName, &FileInfo ) == true )
  1140. {
  1141. pManifestMap->m_bIsVersionControlled = true;
  1142. if ( FileInfo.m_eOpenState == P4FILE_OPENED_FOR_ADD || FileInfo.m_eOpenState == P4FILE_OPENED_FOR_EDIT )
  1143. {
  1144. pManifestMap->m_bCheckedOut = true;
  1145. }
  1146. }
  1147. }
  1148. }
  1149. //-----------------------------------------------------------------------------
  1150. // Purpose: This function will clear the selection
  1151. //-----------------------------------------------------------------------------
  1152. void CManifest::ClearSelection( void )
  1153. {
  1154. SelectFace( NULL, 0, scClear | scSaveChanges );
  1155. SelectObject( NULL, scClear | scSaveChanges );
  1156. }
  1157. //-----------------------------------------------------------------------------
  1158. // Purpose: This function will add the object to the primary map of the manifest
  1159. // Input : pObject - a pointer to the object to be added
  1160. // pParent - a pointer to the parent of this object
  1161. //-----------------------------------------------------------------------------
  1162. void CManifest::AddObjectToWorld(CMapClass *pObject, CMapClass *pParent)
  1163. {
  1164. m_pPrimaryMap->m_Map->AddObjectToWorld( pObject, pParent );
  1165. m_pPrimaryMap->m_Entity->PostUpdate( Notify_Changed );
  1166. }
  1167. //-----------------------------------------------------------------------------
  1168. // Purpose: This function will pass on the notification that a map has been updated
  1169. // Input : pInstanceMapDoc - the map that was updated
  1170. //-----------------------------------------------------------------------------
  1171. void CManifest::UpdateInstanceMap( CMapDoc *pInstanceMapDoc )
  1172. {
  1173. const CMapObjectList *pChildren = m_ManifestWorld->GetChildren();
  1174. FOR_EACH_OBJ( *pChildren, pos )
  1175. {
  1176. CMapClass *pChild = (CUtlReference< CMapClass >)pChildren->Element( pos );
  1177. CMapEntity *pEntity = dynamic_cast< CMapEntity * >( pChild );
  1178. if ( pEntity && stricmp( pEntity->GetClassName(), "func_instance" ) == 0 )
  1179. {
  1180. CMapInstance *pMapInstance = pEntity->GetChildOfType( ( CMapInstance * )NULL );
  1181. if ( pMapInstance )
  1182. {
  1183. if ( pMapInstance->GetInstancedMap() == pInstanceMapDoc )
  1184. {
  1185. pMapInstance->UpdateInstanceMap();
  1186. m_ManifestWorld->UpdateChild( pMapInstance );
  1187. }
  1188. }
  1189. }
  1190. }
  1191. }
  1192. //-----------------------------------------------------------------------------
  1193. // Purpose: this function will add the object to the local manifest world. the
  1194. // only objects that should be added are ManifestInstance.
  1195. // Input : pObject - a pointer to the object to be added
  1196. // pParent - a pointer to the parent of this object
  1197. //-----------------------------------------------------------------------------
  1198. void CManifest::AddManifestObjectToWorld( CMapClass *pObject, CMapClass *pParent )
  1199. {
  1200. m_ManifestWorld->AddObjectToWorld( pObject, pParent );
  1201. }
  1202. //-----------------------------------------------------------------------------
  1203. // Purpose: Removes an object from the manifest world.
  1204. // Input : pObject - object to remove from the world.
  1205. // bChildren - whether we're removing the object's children as well.
  1206. //-----------------------------------------------------------------------------
  1207. void CManifest::RemoveManifestObjectFromWorld( CMapClass *pObject, bool bRemoveChildren )
  1208. {
  1209. m_ManifestWorld->RemoveObjectFromWorld( pObject, bRemoveChildren );
  1210. }
  1211. //-----------------------------------------------------------------------------
  1212. // Purpose: this function will start the loading process for a manifest
  1213. // Input : lpszPathName - the absoltue path of the manifest file
  1214. // Output : Returns TRUE on success, FALSE on failure.
  1215. //-----------------------------------------------------------------------------
  1216. BOOL CManifest::OnOpenDocument(LPCTSTR lpszPathName)
  1217. {
  1218. Initialize();
  1219. if (!SelectDocType())
  1220. {
  1221. return FALSE;
  1222. }
  1223. //
  1224. // Call any per-class PreloadWorld functions here.
  1225. //
  1226. CMapSolid::PreloadWorld();
  1227. if ( !Load( lpszPathName ) )
  1228. {
  1229. return FALSE;
  1230. }
  1231. SetModifiedFlag( FALSE );
  1232. Msg( mwStatus, "Opened %s", lpszPathName );
  1233. SetActiveMapDoc( this );
  1234. //
  1235. // We set the active doc before loading for displacements (and maybe other
  1236. // things), but visgroups aren't available until after map load. We have to refresh
  1237. // the visgroups here or they won't be correct.
  1238. //
  1239. GetMainWnd()->GlobalNotify( WM_MAPDOC_CHANGED );
  1240. m_pToolManager->SetTool( TOOL_POINTER );
  1241. return(TRUE);
  1242. }
  1243. //-----------------------------------------------------------------------------
  1244. // Purpose: This function will save out the manifest
  1245. // Input : lpszPathName - the absolute filename of the manifest
  1246. // Output : Returns TRUE on success, FALSE on failure.
  1247. //-----------------------------------------------------------------------------
  1248. BOOL CManifest::OnSaveDocument(LPCTSTR lpszPathName)
  1249. {
  1250. if ( !Save( lpszPathName, m_bRelocateSave ) )
  1251. {
  1252. return FALSE;
  1253. }
  1254. SetModifiedFlag( FALSE );
  1255. return TRUE;
  1256. }
  1257. //-----------------------------------------------------------------------------
  1258. // Purpose: this function will be called when the use select Save As. This will
  1259. // allow all of the submaps to be relocated relative to a new save location
  1260. // of the manifest itself. Directories should be created automatically.
  1261. //-----------------------------------------------------------------------------
  1262. void CManifest::OnFileSaveAs(void)
  1263. {
  1264. m_bRelocateSave = true;
  1265. __super::OnFileSaveAs();
  1266. m_bRelocateSave = false;
  1267. }
  1268. //-----------------------------------------------------------------------------
  1269. // Purpose: this function will delete the manifest world and rest of the contents.
  1270. //-----------------------------------------------------------------------------
  1271. void CManifest::DeleteContents( void )
  1272. {
  1273. m_pSelection->RemoveAll();
  1274. if ( m_ManifestWorld )
  1275. {
  1276. delete m_ManifestWorld;
  1277. m_ManifestWorld = NULL;
  1278. }
  1279. m_pWorld = NULL;
  1280. m_VisGroups = NULL;
  1281. m_RootVisGroups = NULL;
  1282. m_pUndo = m_pSaveUndo;
  1283. m_pRedo = m_pSaveRedo;
  1284. __super::DeleteContents();
  1285. }
  1286. #include <tier0/memdbgoff.h>