Team Fortress 2 Source Code as on 22/4/2020
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.

1595 lines
45 KiB

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