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.

823 lines
24 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "stdafx.h"
  7. #include "hammer_mathlib.h"
  8. #include "MainFrm.h"
  9. #include "ObjectProperties.h"
  10. #include "Box3D.h"
  11. #include "BSPFile.h"
  12. #include "const.h"
  13. #include "MapDefs.h" // dvs: For COORD_NOTINIT
  14. #include "MapEntity.h"
  15. #include "MapInstance.h"
  16. #include "Manifest.h"
  17. #include "Render2D.h"
  18. #include "Render3D.h"
  19. #include "MapView2D.h"
  20. #include "MapView3D.h"
  21. #include "hammer.h"
  22. #include "Texture.h"
  23. #include "TextureSystem.h"
  24. #include "materialsystem/IMesh.h"
  25. #include "Material.h"
  26. #include "Options.h"
  27. #include "camera.h"
  28. #include "MapWorld.h"
  29. #include "mapview.h"
  30. #include "p4lib/ip4.h"
  31. #define __IN_HAMMER 1
  32. #include "instancing_helper.h"
  33. // memdbgon must be the last include file in a .cpp file!!!
  34. #include <tier0/memdbgon.h>
  35. IMPLEMENT_MAPCLASS(CMapInstance)
  36. char CMapInstance::m_InstancePath[ MAX_PATH ] = "";
  37. //-----------------------------------------------------------------------------
  38. // Purpose: Factory function. Used for creating a CMapInstance.
  39. // Input : pHelperInfo - Pointer to helper info class which gives us information
  40. // about how to create the class.
  41. // pParent - the owning entity ( func_instance )
  42. // Output : Returns a pointer to the class, NULL if an error occurs.
  43. //-----------------------------------------------------------------------------
  44. CMapClass *CMapInstance::Create( CHelperInfo *pHelperInfo, CMapEntity *pParent )
  45. {
  46. char FileName[ MAX_PATH ];
  47. const char *FileNameKey = pParent->GetKeyValue( "file" );
  48. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  49. if ( FileNameKey )
  50. {
  51. strcpy( FileName, pParent->GetKeyValue( "file" ) );
  52. }
  53. else
  54. {
  55. FileName[ 0 ] = 0;
  56. }
  57. CMapInstance *pInstance = new CMapInstance( pDoc->GetPathName(), FileName );
  58. return pInstance;
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Purpose:
  62. // Input :
  63. // Output :
  64. //-----------------------------------------------------------------------------
  65. void CMapInstance::SetInstancePath( const char *pszInstancePath )
  66. {
  67. strcpy( m_InstancePath, pszInstancePath );
  68. V_strlower( m_InstancePath );
  69. V_FixSlashes( m_InstancePath );
  70. }
  71. //-----------------------------------------------------------------------------
  72. // Purpose:
  73. // Input :
  74. // Output :
  75. //-----------------------------------------------------------------------------
  76. bool CMapInstance::IsMapInVersionControl( const char *pszFileName )
  77. {
  78. if ( p4 != NULL && Options.general.bEnablePerforceIntegration == TRUE )
  79. {
  80. if ( p4->IsFileInPerforce( pszFileName ) == true )
  81. {
  82. char szMessage[ MAX_PATH + MAX_PATH+ 256 ];
  83. sprintf( szMessage, "This instance is not local but exists in perforce. Would you like to sync to get the file?\n\n%s", pszFileName );
  84. if ( AfxMessageBox( szMessage, MB_ICONHAND | MB_YESNO ) == IDYES )
  85. {
  86. if ( p4->SyncFile( pszFileName ) == true )
  87. {
  88. if ( g_pFullFileSystem->FileExists( pszFileName ) )
  89. {
  90. return true;
  91. }
  92. }
  93. AfxMessageBox( "Sync operation was NOT successful!", MB_OK ) ;
  94. }
  95. }
  96. }
  97. return false;
  98. }
  99. //-----------------------------------------------------------------------------
  100. // Purpose: Constructor.
  101. //-----------------------------------------------------------------------------
  102. CMapInstance::CMapInstance( void )
  103. {
  104. Initialize();
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose: Constructor.
  108. // Input : pszBaseFileName - the root path of where the instance will be loaded from.
  109. // pszInstanceFileName - the relative name of the instance to be loaded.
  110. // Output :
  111. //-----------------------------------------------------------------------------
  112. CMapInstance::CMapInstance( const char *pszBaseFileName, const char *pszInstanceFileName )
  113. {
  114. Initialize();
  115. if ( pszInstanceFileName[ 0 ] && CInstancingHelper::ResolveInstancePath( g_pFullFileSystem, pszBaseFileName, pszInstanceFileName, m_InstancePath, m_FileName, MAX_PATH ) )
  116. {
  117. bool bSaveVisible = CHammer::IsNewDocumentVisible();
  118. CMapDoc *activeDoc = CMapDoc::GetActiveMapDoc();
  119. CHammer::SetIsNewDocumentVisible( false );
  120. m_pInstancedMap = ( CMapDoc * )APP()->OpenDocumentOrInstanceFile( m_FileName );
  121. if ( m_pInstancedMap )
  122. {
  123. m_pInstancedMap->AddReference();
  124. m_pInstancedMap->Update();
  125. }
  126. CMapDoc::SetActiveMapDoc( activeDoc );
  127. CHammer::SetIsNewDocumentVisible( bSaveVisible );
  128. }
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose: Destructor.
  132. //-----------------------------------------------------------------------------
  133. CMapInstance::~CMapInstance(void)
  134. {
  135. if ( m_pInstancedMap )
  136. {
  137. m_pInstancedMap->RemoveReference();
  138. m_pInstancedMap = NULL;
  139. }
  140. }
  141. GDIV_TYPE CMapInstance::GetFieldType( const char *pInstanceValue )
  142. {
  143. CMapEntityList entityList;
  144. GDinputvariable TempVar;
  145. m_pInstancedMap->FindEntitiesByClassName( entityList, "func_instance_parms", false );
  146. if ( entityList.Count() != 1 )
  147. {
  148. return ivBadType;
  149. }
  150. CMapEntity *pInstanceParmsEntity = entityList.Element( 0 );
  151. const char *InstancePos = strchr( pInstanceValue, ' ' );
  152. if ( InstancePos == NULL )
  153. {
  154. return ivBadType;
  155. }
  156. int len = InstancePos - pInstanceValue;
  157. for ( int i = pInstanceParmsEntity->GetFirstKeyValue(); i != pInstanceParmsEntity->GetInvalidKeyValue(); i = pInstanceParmsEntity->GetNextKeyValue( i ) )
  158. {
  159. LPCTSTR pKey = pInstanceParmsEntity->GetKey( i );
  160. LPCTSTR pValue = pInstanceParmsEntity->GetKeyValue( i );
  161. if ( strnicmp( pKey, "parm", strlen( "parm" ) ) == 0 )
  162. {
  163. const char *InstanceParmsPos = strchr( pValue, ' ' );
  164. if ( InstanceParmsPos == NULL )
  165. {
  166. continue;
  167. }
  168. if ( strnicmp( pInstanceValue, pValue, len ) == 0 )
  169. {
  170. return TempVar.GetTypeFromToken( InstanceParmsPos + 1 );
  171. }
  172. }
  173. }
  174. return ivBadType;
  175. }
  176. void CMapInstance::FindTargetNames( CUtlVector< const char * > &Names )
  177. {
  178. CMapEntity *pEntity = dynamic_cast< CMapEntity * >( GetParent() );
  179. for ( int j = pEntity->GetFirstKeyValue(); j != pEntity->GetInvalidKeyValue(); j = pEntity->GetNextKeyValue( j ) )
  180. {
  181. LPCTSTR pInstanceKey = pEntity->GetKey( j );
  182. LPCTSTR pInstanceValue = pEntity->GetKeyValue( j );
  183. if ( strnicmp( pInstanceKey, "replace", strlen( "replace" ) ) == 0 )
  184. {
  185. GDIV_TYPE FieldType = GetFieldType( pInstanceValue );
  186. if ( FieldType == ivStringInstanced ||
  187. FieldType == ivTargetDest ||
  188. FieldType == ivTargetNameOrClass ||
  189. FieldType == ivTargetSrc )
  190. {
  191. const char *pszInstancePos = strchr( pInstanceValue, ' ' );
  192. if ( pszInstancePos )
  193. {
  194. pszInstancePos++;
  195. char *temp = new char[ strlen( pszInstancePos ) + 1 ];
  196. strcpy( temp, pszInstancePos );
  197. Names.AddToTail( temp );
  198. }
  199. }
  200. }
  201. }
  202. }
  203. void CMapInstance::ReplaceTargetname( const char *szOldName, const char *szNewName )
  204. {
  205. BaseClass::ReplaceTargetname( szOldName, szNewName );
  206. CMapEntity *pEntity = dynamic_cast< CMapEntity * >( GetParent() );
  207. for ( int j = pEntity->GetFirstKeyValue(); j != pEntity->GetInvalidKeyValue(); j = pEntity->GetNextKeyValue( j ) )
  208. {
  209. LPCTSTR pInstanceKey = pEntity->GetKey( j );
  210. LPCTSTR pInstanceValue = pEntity->GetKeyValue( j );
  211. if ( strnicmp( pInstanceKey, "replace", strlen( "replace" ) ) == 0 )
  212. {
  213. const char *InstancePos = strchr( pInstanceValue, ' ' );
  214. if ( InstancePos == NULL )
  215. {
  216. continue;
  217. }
  218. int nLen = InstancePos - pInstanceValue;
  219. if ( strcmp( szOldName, InstancePos + 1 ) == 0 )
  220. {
  221. nLen++;
  222. char *pszResult = ( char * )stackalloc( nLen + strlen( szNewName ) + 1 );
  223. strncpy( pszResult, pInstanceValue, nLen );
  224. strcpy( &pszResult[ nLen ], szNewName );
  225. pEntity->SetKeyValue( pInstanceKey, pszResult );
  226. }
  227. }
  228. }
  229. }
  230. //-----------------------------------------------------------------------------
  231. // Purpose: This function is called when the owning entity's Key/Value pairs have
  232. // been updated. This will attempt to load a new instance if the map has
  233. // been changed.
  234. // Input : none.
  235. // Output : none.
  236. //-----------------------------------------------------------------------------
  237. bool CMapInstance::OnApply( void )
  238. {
  239. CString MapFileName;
  240. char FileName[ MAX_PATH ];
  241. CMapDoc *activeDoc = CMapDoc::GetActiveMapDoc();
  242. MapFileName = activeDoc->GetPathName();
  243. CMapEntity *ent = dynamic_cast< CMapEntity * >( GetParent() );
  244. if ( m_pInstancedMap )
  245. {
  246. m_pInstancedMap->RemoveReference();
  247. }
  248. if ( ent && ent->GetKeyValue( "file" ) )
  249. {
  250. CInstancingHelper::ResolveInstancePath( g_pFullFileSystem, MapFileName, ent->GetKeyValue( "file" ), m_InstancePath, FileName, MAX_PATH );
  251. if ( strcmpi( FileName, m_FileName ) != 0 )
  252. {
  253. bool bSaveVisible = CHammer::IsNewDocumentVisible();
  254. CHammer::SetIsNewDocumentVisible( false );
  255. strcpy( m_FileName, FileName );
  256. m_pInstancedMap = ( CMapDoc * )APP()->OpenDocumentOrInstanceFile( m_FileName );
  257. CHammer::SetIsNewDocumentVisible( bSaveVisible );
  258. }
  259. }
  260. else
  261. {
  262. m_pInstancedMap = NULL;
  263. }
  264. if ( m_pInstancedMap == NULL )
  265. {
  266. m_FileName[ 0 ] = 0;
  267. }
  268. else
  269. {
  270. m_pInstancedMap->AddReference();
  271. m_pInstancedMap->Update();
  272. }
  273. GetMainWnd()->pObjectProperties->MarkDataDirty();
  274. // loading this instance will bring it forward in the MDI - we want to show the original map though
  275. CMapDoc::ActivateMapDoc( activeDoc );
  276. return true;
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Purpose: Calculates our bounding box based on instance map's dimensions.
  280. // Input : bFullUpdate - Whether we should recalculate our children's bounds.
  281. // Output : none.
  282. //-----------------------------------------------------------------------------
  283. void CMapInstance::CalcBounds(BOOL bFullUpdate)
  284. {
  285. CMapClass::CalcBounds(bFullUpdate);
  286. //
  287. // Build our bounds for frustum culling in the 3D view.
  288. //
  289. if ( m_pInstancedMap && GetParent() && m_pInstancedMap->GetMapWorld() )
  290. {
  291. Vector vecMins, vecMaxs, vecExpandedMins, vecExpandedMaxs;
  292. matrix3x4_t Instance3x4Matrix;
  293. CMapClass *pParent = GetParent();
  294. pParent->GetOrigin( m_Origin );
  295. AngleMatrix( m_Angles, m_Origin, Instance3x4Matrix );
  296. m_pInstancedMap->GetMapWorld()->CalcBounds( true );
  297. #if 0
  298. m_pInstancedMap->GetMapWorld()->GetCullBox( vecMins, vecMaxs );
  299. m_pInstancedMap->GetMapWorld()->GetBoundingBox( vecMins, vecMaxs );
  300. TransformAABB( Instance3x4Matrix, vecMins, vecMaxs, vecExpandedMins, vecExpandedMaxs );
  301. m_CullBox.UpdateBounds( vecExpandedMins, vecExpandedMaxs );
  302. #endif
  303. m_pInstancedMap->GetMapWorld()->GetBoundingBox( vecMins, vecMaxs );
  304. TransformAABB( Instance3x4Matrix, vecMins, vecMaxs, vecExpandedMins, vecExpandedMaxs );
  305. m_CullBox.UpdateBounds( vecExpandedMins, vecExpandedMaxs );
  306. m_BoundingBox.UpdateBounds( vecExpandedMins, vecExpandedMaxs );
  307. m_Render2DBox.UpdateBounds( vecExpandedMins, vecExpandedMaxs );
  308. }
  309. else
  310. {
  311. Vector vecExpandedMins, vecExpandedMaxs;
  312. vecExpandedMins.Init( -32.0f, -32.0f, -32.0f );
  313. vecExpandedMins += m_Origin;
  314. vecExpandedMaxs.Init( 32.0f, 32.0f, 32.0f );
  315. vecExpandedMaxs += m_Origin;
  316. m_CullBox.UpdateBounds( vecExpandedMins, vecExpandedMaxs );
  317. m_BoundingBox.UpdateBounds( vecExpandedMins, vecExpandedMaxs );
  318. m_Render2DBox.UpdateBounds( vecExpandedMins, vecExpandedMaxs );
  319. }
  320. }
  321. //-----------------------------------------------------------------------------
  322. // Purpose: Will calculate the bounding box of the instance as a child has changed
  323. // Input : pChild - Pointer to the object that changed.
  324. //-----------------------------------------------------------------------------
  325. void CMapInstance::UpdateChild(CMapClass *pChild)
  326. {
  327. CalcBounds( TRUE );
  328. }
  329. //-----------------------------------------------------------------------------
  330. // Purpose: this function will attempt to find a child inside of the instance. If the bool and matrix
  331. // are supplied, the localized matrix will be built.
  332. // Input : key - the key field to lookup
  333. // value - the value to find
  334. // Output : returns the entity found
  335. // bIsInInstance - optional parameter to indicate if the found entity is inside of an instance
  336. // InstanceMatrix - optional parameter to set the localized matrix of the instance stack
  337. //-----------------------------------------------------------------------------
  338. CMapEntity *CMapInstance::FindChildByKeyValue( const char* key, const char* value, bool *bIsInInstance, VMatrix *InstanceMatrix )
  339. {
  340. if ( m_pInstancedMap && bIsInInstance )
  341. {
  342. CMapEntity *result = m_pInstancedMap->GetMapWorld()->FindChildByKeyValue( key, value );
  343. if ( result )
  344. {
  345. if ( ( *bIsInInstance ) == false )
  346. {
  347. *bIsInInstance = true;
  348. if ( InstanceMatrix )
  349. {
  350. InstanceMatrix->Identity();
  351. }
  352. }
  353. if ( InstanceMatrix )
  354. {
  355. VMatrix LocalInstanceMatrix, Result;
  356. LocalInstanceMatrix.Identity();
  357. AngleMatrix( m_Angles, m_Origin, LocalInstanceMatrix.As3x4() );
  358. Result = ( *InstanceMatrix ) * LocalInstanceMatrix;
  359. *InstanceMatrix = Result;
  360. }
  361. }
  362. return result;
  363. }
  364. return NULL;
  365. }
  366. //-----------------------------------------------------------------------------
  367. // Purpose: this function is called for when an instance has moved
  368. //-----------------------------------------------------------------------------
  369. void CMapInstance::InstanceMoved( void )
  370. {
  371. if ( m_pInstancedMap )
  372. {
  373. m_pInstancedMap->InstanceMoved();
  374. }
  375. }
  376. //-----------------------------------------------------------------------------
  377. // Purpose: Returns a copy of this object.
  378. // Output : Pointer to the new object.
  379. //-----------------------------------------------------------------------------
  380. CMapClass *CMapInstance::Copy(bool bUpdateDependencies)
  381. {
  382. CMapInstance *pCopy = new CMapInstance;
  383. if (pCopy != NULL)
  384. {
  385. pCopy->CopyFrom(this, bUpdateDependencies);
  386. }
  387. return(pCopy);
  388. }
  389. //-----------------------------------------------------------------------------
  390. // Purpose: Turns this into a duplicate of the given object.
  391. // Input : pObject - Pointer to the object to copy from.
  392. // Output : Returns a pointer to this object.
  393. //-----------------------------------------------------------------------------
  394. CMapClass *CMapInstance::CopyFrom(CMapClass *pObject, bool bUpdateDependencies)
  395. {
  396. CMapInstance *pFrom = dynamic_cast<CMapInstance *>(pObject);
  397. Assert(pObject != NULL);
  398. if (pObject != NULL)
  399. {
  400. CMapClass::CopyFrom(pObject, bUpdateDependencies);
  401. m_Angles = pFrom->m_Angles;
  402. strcpy( m_FileName, pFrom->m_FileName );
  403. m_pInstancedMap = pFrom->m_pInstancedMap;
  404. if ( m_pInstancedMap )
  405. {
  406. m_pInstancedMap->AddReference();
  407. m_pInstancedMap->Update();
  408. }
  409. }
  410. return(this);
  411. }
  412. //-----------------------------------------------------------------------------
  413. // Purpose: Set's the map instance's angles
  414. // Input : Angles - the angles to set to
  415. //-----------------------------------------------------------------------------
  416. void CMapInstance::GetAngles(QAngle &Angles)
  417. {
  418. Angles = m_Angles;
  419. }
  420. //-----------------------------------------------------------------------------
  421. // Purpose: Initialized the map instance
  422. //-----------------------------------------------------------------------------
  423. void CMapInstance::Initialize(void)
  424. {
  425. m_Angles.Init();
  426. m_pInstancedMap = NULL;
  427. m_FileName[ 0 ] = 0;
  428. m_pManifestMap = NULL;
  429. }
  430. //-----------------------------------------------------------------------------
  431. // Purpose: Sets the manifest that loaded this instance
  432. // Input : pManifestMap - the manifest
  433. //-----------------------------------------------------------------------------
  434. void CMapInstance::SetManifest( CManifestMap *pManifestMap )
  435. {
  436. Initialize();
  437. m_pManifestMap = pManifestMap;
  438. m_pInstancedMap = m_pManifestMap->m_Map;
  439. strcpy( m_FileName, m_pManifestMap->m_AbsoluteMapFileName );
  440. }
  441. //-----------------------------------------------------------------------------
  442. // Purpose: This will render the map instance into the 3d view.
  443. // Input : pRender - the 3d render
  444. //-----------------------------------------------------------------------------
  445. void CMapInstance::Render3D(CRender3D *pRender)
  446. {
  447. if ( m_pInstancedMap )
  448. {
  449. pRender->RenderInstanceMapClass( this, m_pInstancedMap->GetMapWorld(), m_Origin, m_Angles );
  450. }
  451. }
  452. //-----------------------------------------------------------------------------
  453. // Purpose: this function will display an instance map window. it will also set the
  454. // views to the approx same camera position.
  455. //-----------------------------------------------------------------------------
  456. void CMapInstance::SwitchTo( void )
  457. {
  458. if ( !m_pInstancedMap )
  459. {
  460. return;
  461. }
  462. CMapDoc *pCurrentDoc = CMapDoc::GetActiveMapDoc();
  463. m_pInstancedMap->ShowWindow( true );
  464. CMapDoc::ActivateMapDoc( m_pInstancedMap );
  465. POSITION PositionCurrentView = pCurrentDoc->GetFirstViewPosition();
  466. POSITION PositionNewView = m_pInstancedMap->GetFirstViewPosition();
  467. while ( PositionCurrentView && PositionNewView )
  468. {
  469. CMapView *pViewCurrent = dynamic_cast< CMapView * >( pCurrentDoc->GetNextView( PositionCurrentView ) );
  470. CMapView2D *pViewCurrent2D = dynamic_cast< CMapView2D * >( pViewCurrent );
  471. CMapView3D *pViewCurrent3D = dynamic_cast< CMapView3D * >( pViewCurrent );
  472. CMapView *pViewNew = dynamic_cast< CMapView * >( m_pInstancedMap->GetNextView( PositionNewView ) );
  473. CMapView2D *pViewNew2D = dynamic_cast< CMapView2D * >( pViewNew );
  474. CMapView3D *pViewNew3D = dynamic_cast< CMapView3D * >( pViewNew );
  475. if ( ( !pViewCurrent2D || !pViewNew2D ) && ( !pViewCurrent3D || !pViewNew3D ) )
  476. {
  477. continue;
  478. }
  479. Vector CameraVector;
  480. CCamera *CurrentCamera;
  481. CurrentCamera = pViewCurrent->GetCamera();
  482. CurrentCamera->GetViewPoint( CameraVector );
  483. if ( pViewCurrent2D )
  484. {
  485. CameraVector = CameraVector - m_Origin;
  486. pViewNew2D->GetCamera()->SetViewPoint( CameraVector );
  487. pViewNew2D->GetCamera()->SetZoom( pViewCurrent2D->GetZoom() );
  488. }
  489. else
  490. {
  491. matrix3x4_t Camera3x4Matrix, InstanceMatrix, InstanceInverseMatrix;
  492. matrix3x4_t ResultMatrix;
  493. QAngle InstanceAngles, CameraAngles;
  494. CameraAngles.Init( CurrentCamera->GetPitch(), CurrentCamera->GetYaw(), CurrentCamera->GetRoll() );
  495. InstanceAngles = m_Angles;
  496. InstanceAngles.x = 0;
  497. InstanceAngles.z = 0;
  498. AngleMatrix( InstanceAngles, m_Origin, InstanceMatrix );
  499. MatrixInvert( InstanceMatrix, InstanceInverseMatrix );
  500. AngleMatrix( CameraAngles, CameraVector, Camera3x4Matrix );
  501. MatrixMultiply( InstanceInverseMatrix, Camera3x4Matrix, ResultMatrix );
  502. MatrixPosition( ResultMatrix, CameraVector );
  503. MatrixMultiply( InstanceMatrix, Camera3x4Matrix, ResultMatrix );
  504. MatrixAngles( ResultMatrix, CameraAngles );
  505. pViewNew3D->GetCamera()->SetViewPoint( CameraVector );
  506. pViewNew3D->GetCamera()->SetPitch( CameraAngles.x );
  507. pViewNew3D->GetCamera()->SetYaw( CameraAngles.y );
  508. // pViewNew3D->GetCamera()->SetRoll( CameraAngles.z ); we probably don't want to set this!
  509. }
  510. pViewNew->UpdateView( MAPVIEW_OPTIONS_CHANGED );
  511. }
  512. }
  513. //-----------------------------------------------------------------------------
  514. // Purpose: we do not want to serialize this
  515. // Input : &File -
  516. // bRMF -
  517. // Output : int
  518. //-----------------------------------------------------------------------------
  519. int CMapInstance::SerializeRMF(std::fstream &File, BOOL bRMF)
  520. {
  521. return(0);
  522. }
  523. //-----------------------------------------------------------------------------
  524. // Purpose: we do not want to serialize this
  525. // Input : &File -
  526. // bRMF -
  527. // Output : int
  528. //-----------------------------------------------------------------------------
  529. int CMapInstance::SerializeMAP(std::fstream &File, BOOL bRMF)
  530. {
  531. return(0);
  532. }
  533. //-----------------------------------------------------------------------------
  534. // Purpose: Canculate angles based upon the transform
  535. // Input : pTransBox -
  536. //-----------------------------------------------------------------------------
  537. void CMapInstance::DoTransform(const VMatrix &matrix)
  538. {
  539. CMapClass *pParent = GetParent();
  540. pParent->GetOrigin( m_Origin );
  541. // BaseClass::DoTransform(matrix);
  542. matrix3x4_t fCurrentMatrix,fMatrixNew;
  543. AngleMatrix(m_Angles, fCurrentMatrix);
  544. ConcatTransforms(matrix.As3x4(), fCurrentMatrix, fMatrixNew);
  545. MatrixAngles(fMatrixNew, m_Angles);
  546. CMapEntity *pEntity = dynamic_cast< CMapEntity * >( m_pParent );
  547. if (pEntity != NULL)
  548. {
  549. char szValue[ 80 ];
  550. sprintf( szValue, "%g %g %g", m_Angles[ 0 ], m_Angles[ 1 ], m_Angles[ 2 ] );
  551. pEntity->NotifyChildKeyChanged( this, "angles", szValue );
  552. }
  553. InstanceMoved();
  554. }
  555. //-----------------------------------------------------------------------------
  556. // Purpose: Notifies that this object's parent entity has had a key value change.
  557. // Input : szKey - The key that changed.
  558. // szValue - The new value of the key.
  559. //-----------------------------------------------------------------------------
  560. void CMapInstance::OnParentKeyChanged(const char* szKey, const char* szValue)
  561. {
  562. if (!stricmp(szKey, "angles"))
  563. {
  564. sscanf(szValue, "%f %f %f", &m_Angles[PITCH], &m_Angles[YAW], &m_Angles[ROLL]);
  565. PostUpdate(Notify_Changed);
  566. }
  567. }
  568. //-----------------------------------------------------------------------------
  569. // Purpose: indicates that we should not render last
  570. // Output : returns false.
  571. //-----------------------------------------------------------------------------
  572. bool CMapInstance::ShouldRenderLast(void)
  573. {
  574. return( false );
  575. }
  576. //-----------------------------------------------------------------------------
  577. // Purpose: This will render the map instance into the 2d view as well as a
  578. // bounding box.
  579. // Input : pRender - the 2d render
  580. //-----------------------------------------------------------------------------
  581. void CMapInstance::Render2D(CRender2D *pRender)
  582. {
  583. CMapView2D *pView = ( CMapView2D * )pRender->GetView();
  584. if ( m_pInstancedMap )
  585. {
  586. pView->RenderInstance( this, m_pInstancedMap->GetMapWorld(), m_Origin, m_Angles );
  587. }
  588. if ( m_pManifestMap )
  589. {
  590. return;
  591. }
  592. Vector vecMins;
  593. Vector vecMaxs;
  594. GetRender2DBox(vecMins, vecMaxs);
  595. Vector2D pt,pt2;
  596. pRender->TransformPoint(pt, vecMins);
  597. pRender->TransformPoint(pt2, vecMaxs);
  598. if (!IsSelected())
  599. {
  600. pRender->SetDrawColor( r, g, b );
  601. pRender->SetHandleColor( r, g, b );
  602. }
  603. else
  604. {
  605. pRender->SetDrawColor( GetRValue(Options.colors.clrSelection), GetGValue(Options.colors.clrSelection), GetBValue(Options.colors.clrSelection) );
  606. pRender->SetHandleColor( GetRValue(Options.colors.clrSelection), GetGValue(Options.colors.clrSelection), GetBValue(Options.colors.clrSelection) );
  607. }
  608. // Draw the bounding box.
  609. pRender->DrawBox( vecMins, vecMaxs );
  610. //
  611. // Draw center handle.
  612. //
  613. if ( pRender->IsActiveView() )
  614. {
  615. int sizex = abs(pt.x - pt2.x)+1;
  616. int sizey = abs(pt.y - pt2.y)+1;
  617. // dont draw handle if object is too small
  618. if ( sizex > 6 && sizey > 6 )
  619. {
  620. pRender->SetHandleStyle( HANDLE_RADIUS, CRender::HANDLE_CROSS );
  621. pRender->DrawHandle( (vecMins+vecMaxs)/2 );
  622. }
  623. }
  624. }
  625. //-----------------------------------------------------------------------------
  626. // Called by entity code to render sprites
  627. //-----------------------------------------------------------------------------
  628. void CMapInstance::RenderLogicalAt(CRender2D *pRender, const Vector2D &vecMins, const Vector2D &vecMaxs )
  629. {
  630. }
  631. //-----------------------------------------------------------------------------
  632. // Purpose: Returns if this instance is editable. A pure instance is not editable.
  633. // If it is part of a manifest, it must be the primary map of the manifest
  634. // in order for it to be editable.
  635. //-----------------------------------------------------------------------------
  636. bool CMapInstance::IsEditable( void )
  637. {
  638. if ( m_pManifestMap )
  639. {
  640. return m_pManifestMap->IsEditable();
  641. }
  642. return false;
  643. }
  644. //-----------------------------------------------------------------------------
  645. // Purpose: this function checks to see if the instance is visible.
  646. // Output : returns true if the instance is visible.
  647. //-----------------------------------------------------------------------------
  648. bool CMapInstance::IsInstanceVisible( void )
  649. {
  650. if ( IsInstance() )
  651. {
  652. if ( CMapDoc::GetActiveMapDoc() && CMapDoc::GetActiveMapDoc()->GetShowInstance() == INSTANCES_HIDE )
  653. {
  654. return false;
  655. }
  656. }
  657. else
  658. {
  659. if ( GetManifestMap() && GetManifestMap()->m_bVisible == false )
  660. {
  661. return false;
  662. }
  663. }
  664. return true;
  665. }
  666. //-----------------------------------------------------------------------------
  667. // Purpose: this function will recalculate its bounds because map has changed
  668. //-----------------------------------------------------------------------------
  669. void CMapInstance::UpdateInstanceMap( void )
  670. {
  671. CalcBounds();
  672. }