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.

664 lines
20 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "DmeVMFEntity.h"
  7. #include "datamodel/dmelementfactoryhelper.h"
  8. #include "toolframework/itoolentity.h"
  9. #include "materialsystem/imesh.h"
  10. #include "materialsystem/imaterial.h"
  11. #include "materialsystem/imaterialsystem.h"
  12. #include "engine/iclientleafsystem.h"
  13. #include "toolutils/enginetools_int.h"
  14. #include "vcdblocktool.h"
  15. #include "tier1/KeyValues.h"
  16. // for tracing
  17. #include "cmodel.h"
  18. #include "engine/ienginetrace.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. #define SPHERE_RADIUS 16
  22. //-----------------------------------------------------------------------------
  23. // Expose this class to the scene database
  24. //-----------------------------------------------------------------------------
  25. IMPLEMENT_ELEMENT_FACTORY( DmeVMFEntity, CDmeVMFEntity );
  26. //-----------------------------------------------------------------------------
  27. // Used to store the next unique entity id;
  28. //-----------------------------------------------------------------------------
  29. int CDmeVMFEntity::s_nNextEntityId;
  30. //-----------------------------------------------------------------------------
  31. // Purpose:
  32. //-----------------------------------------------------------------------------
  33. void CDmeVMFEntity::OnConstruction()
  34. {
  35. m_ClassName.Init( this, "classname", FATTRIB_HAS_CALLBACK );
  36. m_TargetName.Init( this, "targetname" );
  37. m_bIsPlaceholder.InitAndSet( this, "_placeholder", false, FATTRIB_DONTSAVE );
  38. m_vecLocalOrigin.Init( this, "origin" );
  39. m_vecLocalAngles.Init( this, "angles" );
  40. m_bIsDeleted.Init( this, "deleted" );
  41. if ( m_Name.Length() == 0 )
  42. {
  43. // Assign a unique ID to the name
  44. char pNameString[128];
  45. Q_snprintf( pNameString, sizeof(pNameString), "%d", GetNextEntityId() );
  46. m_Name = pNameString;
  47. }
  48. // See if we need to bump the unique id up
  49. int nEntityId = GetEntityId();
  50. if ( s_nNextEntityId <= nEntityId )
  51. {
  52. s_nNextEntityId = nEntityId + 1;
  53. }
  54. // Get called back when the name changes
  55. m_Name.GetAttribute()->AddFlag( FATTRIB_HAS_CALLBACK );
  56. // Used to make sure these aren't saved if they aren't changed
  57. //m_TargetName.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  58. //m_vecLocalAngles.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  59. m_bIsDirty = false;
  60. m_bInfoTarget = false;
  61. m_hEngineEntity = HTOOLHANDLE_INVALID;
  62. m_Wireframe.Init( "debug/debugwireframevertexcolor", "editor" );
  63. // FIXME: Need to abstract out rendering into a separate class
  64. // based on information parsed from the FGD
  65. KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
  66. pVMTKeyValues->SetString( "$basetexture", "editor/info_target" );
  67. pVMTKeyValues->SetInt( "$nocull", 1 );
  68. pVMTKeyValues->SetInt( "$vertexcolor", 1 );
  69. pVMTKeyValues->SetInt( "$vertexalpha", 1 );
  70. pVMTKeyValues->SetInt( "$no_fullbright", 1 );
  71. pVMTKeyValues->SetInt( "$translucent", 1 );
  72. m_InfoTargetSprite.Init( "__vcdblock_info_target", pVMTKeyValues );
  73. pVMTKeyValues = new KeyValues( "UnlitGeneric" );
  74. pVMTKeyValues->SetInt( "$nocull", 1 );
  75. pVMTKeyValues->SetString( "$color", "{64 64 64}" );
  76. pVMTKeyValues->SetInt( "$vertexalpha", 1 );
  77. pVMTKeyValues->SetInt( "$no_fullbright", 1 );
  78. pVMTKeyValues->SetInt( "$additive", 1 );
  79. m_SelectedInfoTarget.Init( "__selected_vcdblock_info_target", pVMTKeyValues );
  80. }
  81. void CDmeVMFEntity::OnDestruction()
  82. {
  83. // Unhook it from the engine
  84. AttachToEngineEntity( false );
  85. m_Wireframe.Shutdown();
  86. m_SelectedInfoTarget.Shutdown();
  87. m_InfoTargetSprite.Shutdown();
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Called whem attributes change
  91. //-----------------------------------------------------------------------------
  92. void CDmeVMFEntity::OnAttributeChanged( CDmAttribute *pAttribute )
  93. {
  94. BaseClass::OnAttributeChanged( pAttribute );
  95. // Once these have changed, then save them out, and don't bother calling back
  96. if ( pAttribute == m_TargetName.GetAttribute() ||
  97. pAttribute == m_vecLocalAngles.GetAttribute() )
  98. {
  99. pAttribute->RemoveFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  100. return;
  101. }
  102. if ( pAttribute == m_ClassName.GetAttribute() )
  103. {
  104. m_bInfoTarget = !Q_strncmp( m_ClassName, "info_target", 11 );
  105. // FIXME: Change the model based on the current class
  106. SetModelName( NULL );
  107. return;
  108. }
  109. // Make sure we have unique ids for all entities
  110. if ( pAttribute == m_Name.GetAttribute() )
  111. {
  112. int nEntityId = GetEntityId();
  113. if ( s_nNextEntityId <= nEntityId )
  114. {
  115. s_nNextEntityId = nEntityId + 1;
  116. }
  117. }
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Returns the entity ID
  121. //-----------------------------------------------------------------------------
  122. int CDmeVMFEntity::GetEntityId() const
  123. {
  124. return atoi( GetName() );
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Returns the next available entity id
  128. //-----------------------------------------------------------------------------
  129. int CDmeVMFEntity::GetNextEntityId()
  130. {
  131. return s_nNextEntityId;
  132. }
  133. void CDmeVMFEntity::SetNextEntityId( int nEntityId )
  134. {
  135. s_nNextEntityId = nEntityId;
  136. }
  137. //-----------------------------------------------------------------------------
  138. // Mark the entity as being dirty
  139. //-----------------------------------------------------------------------------
  140. void CDmeVMFEntity::MarkDirty( bool bDirty )
  141. {
  142. m_bIsDirty = bDirty;
  143. // FIXME: this is doing two operations!!
  144. CopyToServer();
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Is the renderable transparent?
  148. //-----------------------------------------------------------------------------
  149. bool CDmeVMFEntity::IsTransparent( void )
  150. {
  151. return m_bIsDirty || m_bInfoTarget || BaseClass::IsTransparent();
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Entity Key iteration
  155. //-----------------------------------------------------------------------------
  156. bool CDmeVMFEntity::IsEntityKey( CDmAttribute *pEntityKey )
  157. {
  158. return pEntityKey->IsFlagSet( FATTRIB_USERDEFINED );
  159. }
  160. CDmAttribute *CDmeVMFEntity::FirstEntityKey()
  161. {
  162. for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  163. {
  164. if ( IsEntityKey( pAttribute ) )
  165. return pAttribute;
  166. }
  167. return NULL;
  168. }
  169. CDmAttribute *CDmeVMFEntity::NextEntityKey( CDmAttribute *pEntityKey )
  170. {
  171. if ( !pEntityKey )
  172. return NULL;
  173. for ( CDmAttribute *pAttribute = pEntityKey->NextAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  174. {
  175. if ( IsEntityKey( pAttribute ) )
  176. return pAttribute;
  177. }
  178. return NULL;
  179. }
  180. //-----------------------------------------------------------------------------
  181. // Attach/detach from an engine entity with the same editor index
  182. //-----------------------------------------------------------------------------
  183. void CDmeVMFEntity::AttachToEngineEntity( HTOOLHANDLE hToolHandle )
  184. {
  185. if ( m_hEngineEntity != HTOOLHANDLE_INVALID )
  186. {
  187. clienttools->SetEnabled( m_hEngineEntity, true );
  188. }
  189. m_hEngineEntity = hToolHandle;
  190. if ( m_hEngineEntity != HTOOLHANDLE_INVALID )
  191. {
  192. clienttools->SetEnabled( m_hEngineEntity, false );
  193. }
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Position and bounds for the model
  197. //-----------------------------------------------------------------------------
  198. const Vector &CDmeVMFEntity::GetRenderOrigin( void )
  199. {
  200. return m_vecLocalOrigin;
  201. }
  202. const QAngle &CDmeVMFEntity::GetRenderAngles( void )
  203. {
  204. return *(QAngle *)(&m_vecLocalAngles);
  205. }
  206. void CDmeVMFEntity::GetRenderBounds( Vector& mins, Vector& maxs )
  207. {
  208. if ( !m_bInfoTarget )
  209. {
  210. BaseClass::GetRenderBounds( mins, maxs );
  211. return;
  212. }
  213. mins.Init( -SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS );
  214. maxs.Init( SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS );
  215. }
  216. //-----------------------------------------------------------------------------
  217. // Update renderable position
  218. //-----------------------------------------------------------------------------
  219. void CDmeVMFEntity::SetRenderOrigin( const Vector &vecOrigin )
  220. {
  221. m_vecLocalOrigin = vecOrigin;
  222. clienttools->MarkClientRenderableDirty( this );
  223. }
  224. void CDmeVMFEntity::SetRenderAngles( const QAngle &angles )
  225. {
  226. m_vecLocalAngles.Set( Vector( angles.x, angles.y, angles.z ) ); // FIXME: angles is a vector due to the vmf "angles" having a problem parsing...
  227. clienttools->MarkClientRenderableDirty( this );
  228. }
  229. //-----------------------------------------------------------------------------
  230. // Draws the helper for the entity
  231. //-----------------------------------------------------------------------------
  232. void CDmeVMFEntity::DrawSprite( IMaterial *pMaterial )
  233. {
  234. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  235. float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f;
  236. pRenderContext->Bind( pMaterial );
  237. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  238. CMeshBuilder meshBuilder;
  239. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 4, 4 );
  240. unsigned char nBaseR = 255;
  241. unsigned char nBaseG = 255;
  242. unsigned char nBaseB = 255;
  243. unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255;
  244. meshBuilder.Position3f( -SPHERE_RADIUS, -SPHERE_RADIUS, 0.0f );
  245. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  246. meshBuilder.TexCoord2f( 0, 0.0f, 1.0f );
  247. meshBuilder.BoneWeight( 0, 1.0f );
  248. meshBuilder.BoneMatrix( 0, 0 );
  249. meshBuilder.AdvanceVertex();
  250. meshBuilder.Position3f( SPHERE_RADIUS, -SPHERE_RADIUS, 0.0f );
  251. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  252. meshBuilder.TexCoord2f( 0, 1.0f, 1.0f );
  253. meshBuilder.BoneWeight( 0, 1.0f );
  254. meshBuilder.BoneMatrix( 0, 0 );
  255. meshBuilder.AdvanceVertex();
  256. meshBuilder.Position3f( SPHERE_RADIUS, SPHERE_RADIUS, 0.0f );
  257. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  258. meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
  259. meshBuilder.BoneWeight( 0, 1.0f );
  260. meshBuilder.BoneMatrix( 0, 0 );
  261. meshBuilder.AdvanceVertex();
  262. meshBuilder.Position3f( -SPHERE_RADIUS, SPHERE_RADIUS, 0.0f );
  263. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  264. meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
  265. meshBuilder.BoneWeight( 0, 1.0f );
  266. meshBuilder.BoneMatrix( 0, 0 );
  267. meshBuilder.AdvanceVertex();
  268. meshBuilder.FastIndex( 0 );
  269. meshBuilder.FastIndex( 1 );
  270. meshBuilder.FastIndex( 3 );
  271. meshBuilder.FastIndex( 2 );
  272. meshBuilder.End();
  273. pMesh->Draw();
  274. }
  275. //-----------------------------------------------------------------------------
  276. // Draws the helper for the entity
  277. //-----------------------------------------------------------------------------
  278. void CDmeVMFEntity::DrawDragHelpers( IMaterial *pMaterial )
  279. {
  280. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  281. float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f;
  282. VMatrix worldToCamera;
  283. // pRenderContext->GetMatrix( MATERIAL_VIEW, &worldToCamera );
  284. worldToCamera.Identity();
  285. worldToCamera.SetTranslation( m_vecLocalOrigin );
  286. pRenderContext->MatrixMode( MATERIAL_MODEL );
  287. pRenderContext->PushMatrix();
  288. pRenderContext->LoadMatrix( worldToCamera );
  289. pRenderContext->FogMode( MATERIAL_FOG_NONE );
  290. pRenderContext->SetNumBoneWeights( 0 );
  291. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  292. pRenderContext->Bind( pMaterial );
  293. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  294. CMeshBuilder meshBuilder;
  295. meshBuilder.Begin( pMesh, MATERIAL_LINES, 3 );
  296. unsigned char nBaseR = 255;
  297. unsigned char nBaseG = 255;
  298. unsigned char nBaseB = 255;
  299. unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255;
  300. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  301. meshBuilder.Position3f( 0, 0, 0 );
  302. meshBuilder.AdvanceVertex();
  303. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  304. meshBuilder.Position3f( SPHERE_RADIUS * 10, 0, 0 );
  305. meshBuilder.AdvanceVertex();
  306. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  307. meshBuilder.Position3f( 0, 0, 0 );
  308. meshBuilder.AdvanceVertex();
  309. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  310. meshBuilder.Position3f( 0, SPHERE_RADIUS * 10, 0 );
  311. meshBuilder.AdvanceVertex();
  312. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  313. meshBuilder.Position3f( 0, 0, 0 );
  314. meshBuilder.AdvanceVertex();
  315. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  316. meshBuilder.Position3f( 0, 0, SPHERE_RADIUS * 10 );
  317. meshBuilder.AdvanceVertex();
  318. meshBuilder.End();
  319. pMesh->Draw();
  320. pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
  321. pRenderContext->MatrixMode( MATERIAL_MODEL );
  322. pRenderContext->PopMatrix();
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Draws the helper for the entity
  326. //-----------------------------------------------------------------------------
  327. void CDmeVMFEntity::DrawFloorTarget( IMaterial *pMaterial )
  328. {
  329. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  330. float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f;
  331. // test movement
  332. Ray_t ray;
  333. CTraceFilterWorldAndPropsOnly traceFilter;
  334. CBaseTrace tr;
  335. ray.Init( m_vecLocalOrigin.Get()+ Vector( 0, 0, 10 ), m_vecLocalOrigin.Get() + Vector( 0,0, -128 ), Vector( -13, -13, 0 ), Vector( 13, 13, 10 ) );
  336. enginetools->TraceRayServer( ray, MASK_OPAQUE, &traceFilter, &tr );
  337. VMatrix worldToCamera;
  338. // pRenderContext->GetMatrix( MATERIAL_VIEW, &worldToCamera );
  339. worldToCamera.Identity();
  340. worldToCamera.SetTranslation( tr.endpos );
  341. pRenderContext->MatrixMode( MATERIAL_MODEL );
  342. pRenderContext->PushMatrix();
  343. pRenderContext->LoadMatrix( worldToCamera );
  344. pRenderContext->FogMode( MATERIAL_FOG_NONE );
  345. pRenderContext->SetNumBoneWeights( 0 );
  346. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  347. pRenderContext->Bind( pMaterial );
  348. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  349. CMeshBuilder meshBuilder;
  350. meshBuilder.Begin( pMesh, MATERIAL_LINES, 3 );
  351. unsigned char nBaseR = 255;
  352. unsigned char nBaseG = 255;
  353. unsigned char nBaseB = 0;
  354. unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255;
  355. float block[4][2][3] = {
  356. { { -13, -13, 0 }, { -13, -13, 10 } },
  357. { { 13, -13, 0 }, { 13, -13, 10 } },
  358. { { 13, 13, 0 }, { 13, 13, 10 } },
  359. { { -13, 13, 0 }, { -13, 13, 10 } } };
  360. for (int i = 0; i < 4; i++)
  361. {
  362. int j = (i + 1) % 4;
  363. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  364. meshBuilder.Position3f( block[i][0][0], block[i][0][1], block[i][0][2] );
  365. meshBuilder.AdvanceVertex();
  366. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  367. meshBuilder.Position3f( block[i][1][0], block[i][1][1], block[i][1][2] );
  368. meshBuilder.AdvanceVertex();
  369. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  370. meshBuilder.Position3f( block[i][0][0], block[i][0][1], block[i][0][2] );
  371. meshBuilder.AdvanceVertex();
  372. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  373. meshBuilder.Position3f( block[j][0][0], block[j][0][1], block[j][0][2] );
  374. meshBuilder.AdvanceVertex();
  375. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  376. meshBuilder.Position3f( block[i][1][0], block[i][1][1], block[i][1][2] );
  377. meshBuilder.AdvanceVertex();
  378. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  379. meshBuilder.Position3f( block[j][1][0], block[j][1][1], block[j][1][2] );
  380. meshBuilder.AdvanceVertex();
  381. }
  382. // positive X
  383. meshBuilder.Color4ub( 255, 0, 0, nAlpha );
  384. meshBuilder.Position3f( 0, 0, 10 );
  385. meshBuilder.AdvanceVertex();
  386. meshBuilder.Color4ub( 255, 0, 0, nAlpha );
  387. meshBuilder.Position3f( 10, 0, 10 );
  388. meshBuilder.AdvanceVertex();
  389. // positive Y
  390. meshBuilder.Color4ub( 0, 255, 0, nAlpha );
  391. meshBuilder.Position3f( 0, 0, 10 );
  392. meshBuilder.AdvanceVertex();
  393. meshBuilder.Color4ub( 0, 255, 0, nAlpha );
  394. meshBuilder.Position3f( 0, 10, 10 );
  395. meshBuilder.AdvanceVertex();
  396. // just Z
  397. meshBuilder.Color4ub( 255, 255, 255, nAlpha );
  398. meshBuilder.Position3f( 0, 0, 10 );
  399. meshBuilder.AdvanceVertex();
  400. meshBuilder.Color4ub( 255, 255, 255, nAlpha );
  401. meshBuilder.Position3f( 0, 0, 0 );
  402. meshBuilder.AdvanceVertex();
  403. meshBuilder.End();
  404. pMesh->Draw();
  405. pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
  406. pRenderContext->MatrixMode( MATERIAL_MODEL );
  407. pRenderContext->PopMatrix();
  408. }
  409. //-----------------------------------------------------------------------------
  410. // Draws the helper for the entity
  411. //-----------------------------------------------------------------------------
  412. int CDmeVMFEntity::DrawModel( int flags )
  413. {
  414. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  415. bool bSelected = ( g_pVcdBlockTool->GetCurrentEntity().Get() == this );
  416. if ( !m_bInfoTarget )
  417. {
  418. // If we have a visible engine entity, we don't need to draw it here
  419. // info targets always draw though, because they have no visible model.
  420. CDisableUndoScopeGuard guard;
  421. float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f;
  422. unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255;
  423. if ( bSelected )
  424. {
  425. GetMDL()->m_Color.SetColor( 255, 64, 64, nAlpha );
  426. }
  427. else
  428. {
  429. GetMDL()->m_Color.SetColor( 255, 255, 255, nAlpha );
  430. }
  431. return BaseClass::DrawModel( flags );
  432. }
  433. Assert( IsDrawingInEngine() );
  434. matrix3x4_t mat;
  435. VMatrix worldToCamera, cameraToWorld;
  436. pRenderContext->GetMatrix( MATERIAL_VIEW, &worldToCamera );
  437. MatrixInverseTR( worldToCamera, cameraToWorld );
  438. MatrixCopy( cameraToWorld.As3x4(), mat );
  439. MatrixSetColumn( m_vecLocalOrigin, 3, mat );
  440. pRenderContext->MatrixMode( MATERIAL_MODEL );
  441. pRenderContext->PushMatrix();
  442. pRenderContext->LoadMatrix( mat );
  443. pRenderContext->FogMode( MATERIAL_FOG_NONE );
  444. pRenderContext->SetNumBoneWeights( 0 );
  445. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  446. DrawSprite( m_InfoTargetSprite );
  447. if ( bSelected )
  448. {
  449. DrawSprite( m_SelectedInfoTarget );
  450. DrawFloorTarget( m_Wireframe );
  451. if (g_pVcdBlockTool->IsInNodeDrag())
  452. {
  453. DrawDragHelpers( m_Wireframe );
  454. }
  455. // DrawLine( Vector( 0, 0, 0 ), Vector( 10, 0, 0 ), 0, 255, 255, 255 );
  456. }
  457. pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
  458. pRenderContext->MatrixMode( MATERIAL_MODEL );
  459. pRenderContext->PopMatrix();
  460. return 1;
  461. }
  462. bool CDmeVMFEntity::CopyFromServer( CBaseEntity *pServerEnt )
  463. {
  464. CopyFromServer( pServerEnt, "targetname" );
  465. CopyFromServer( pServerEnt, "classname" );
  466. CopyFromServer( pServerEnt, "origin" );
  467. CopyFromServer( pServerEnt, "angles" );
  468. return true;
  469. }
  470. bool CDmeVMFEntity::CopyFromServer( CBaseEntity *pServerEnt, const char *szField )
  471. {
  472. return CopyFromServer( pServerEnt, szField, szField );
  473. }
  474. bool CDmeVMFEntity::CopyFromServer( CBaseEntity *pServerEnt, const char *szSrcField, const char *szDstField )
  475. {
  476. char text[256];
  477. if ( servertools->GetKeyValue( pServerEnt, szSrcField, text, sizeof( text ) ) )
  478. {
  479. SetValueFromString( szDstField, text );
  480. return true;
  481. }
  482. return false;
  483. }
  484. bool CDmeVMFEntity::CopyToServer( void )
  485. {
  486. if (GetEntityId() != 0)
  487. {
  488. CBaseEntity *pServerEntity = servertools->FindEntityByHammerID( GetEntityId() );
  489. if (pServerEntity != NULL)
  490. {
  491. servertools->SetKeyValue( pServerEntity, "origin", m_vecLocalOrigin.Get() );
  492. // FIXME: isn't there a string to vector conversion?
  493. Vector tmp( m_vecLocalAngles.Get().x, m_vecLocalAngles.Get().y, m_vecLocalAngles.Get().z );
  494. servertools->SetKeyValue( pServerEntity, "angles", tmp );
  495. return true;
  496. }
  497. else
  498. {
  499. // FIXME: does one need to be spawned?
  500. }
  501. }
  502. return false;
  503. }
  504. bool CDmeVMFEntity::IsSameOnServer( CBaseEntity *pServerEntity )
  505. {
  506. char text[256];
  507. if (!pServerEntity)
  508. {
  509. return false;
  510. }
  511. // FIXME: check targetname? Can it be edited?
  512. Vector mapOrigin;
  513. servertools->GetKeyValue( pServerEntity, "origin", text, sizeof( text ) );
  514. sscanf( text, "%f %f %f", &mapOrigin.x, &mapOrigin.y, &mapOrigin.z );
  515. Vector mapAngles;
  516. servertools->GetKeyValue( pServerEntity, "angles", text, sizeof( text ) );
  517. sscanf( text, "%f %f %f", &mapAngles.x, &mapAngles.y, &mapAngles.z );
  518. return ( mapOrigin == m_vecLocalOrigin.Get() && mapAngles == m_vecLocalAngles.Get() );
  519. }
  520. bool CDmeVMFEntity::CreateOnServer( void )
  521. {
  522. CBaseEntity *pServerEntity = servertools->CreateEntityByName( m_ClassName.Get() );
  523. if (pServerEntity)
  524. {
  525. // test movement
  526. Ray_t ray;
  527. CTraceFilterWorldAndPropsOnly traceFilter;
  528. CBaseTrace tr;
  529. ray.Init( m_vecLocalOrigin.Get()+ Vector( 0, 0, 10 ), m_vecLocalOrigin.Get() + Vector( 0,0, -1000 ) );
  530. enginetools->TraceRayServer( ray, MASK_OPAQUE, &traceFilter, &tr );
  531. m_vecLocalOrigin.Set( tr.endpos );
  532. servertools->SetKeyValue( pServerEntity, "hammerid", GetEntityId() );
  533. servertools->SetKeyValue( pServerEntity, "targetname", m_TargetName.Get() );
  534. servertools->SetKeyValue( pServerEntity, "origin", m_vecLocalOrigin.Get() );
  535. servertools->SetKeyValue( pServerEntity, "angles", m_vecLocalAngles.Get() );
  536. servertools->DispatchSpawn( pServerEntity );
  537. return true;
  538. }
  539. return false;
  540. }