diff options
Diffstat (limited to 'tools/vcdblock/dmevmfentity.cpp')
| -rw-r--r-- | tools/vcdblock/dmevmfentity.cpp | 664 |
1 files changed, 664 insertions, 0 deletions
diff --git a/tools/vcdblock/dmevmfentity.cpp b/tools/vcdblock/dmevmfentity.cpp new file mode 100644 index 0000000..0432634 --- /dev/null +++ b/tools/vcdblock/dmevmfentity.cpp @@ -0,0 +1,664 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "DmeVMFEntity.h" +#include "datamodel/dmelementfactoryhelper.h" +#include "toolframework/itoolentity.h" +#include "materialsystem/imesh.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialsystem.h" +#include "engine/iclientleafsystem.h" +#include "toolutils/enginetools_int.h" +#include "vcdblocktool.h" +#include "tier1/KeyValues.h" + +// for tracing +#include "cmodel.h" +#include "engine/ienginetrace.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +#define SPHERE_RADIUS 16 + +//----------------------------------------------------------------------------- +// Expose this class to the scene database +//----------------------------------------------------------------------------- +IMPLEMENT_ELEMENT_FACTORY( DmeVMFEntity, CDmeVMFEntity ); + + +//----------------------------------------------------------------------------- +// Used to store the next unique entity id; +//----------------------------------------------------------------------------- +int CDmeVMFEntity::s_nNextEntityId; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDmeVMFEntity::OnConstruction() +{ + m_ClassName.Init( this, "classname", FATTRIB_HAS_CALLBACK ); + m_TargetName.Init( this, "targetname" ); + m_bIsPlaceholder.InitAndSet( this, "_placeholder", false, FATTRIB_DONTSAVE ); + m_vecLocalOrigin.Init( this, "origin" ); + m_vecLocalAngles.Init( this, "angles" ); + m_bIsDeleted.Init( this, "deleted" ); + + if ( m_Name.Length() == 0 ) + { + // Assign a unique ID to the name + char pNameString[128]; + Q_snprintf( pNameString, sizeof(pNameString), "%d", GetNextEntityId() ); + m_Name = pNameString; + } + + // See if we need to bump the unique id up + int nEntityId = GetEntityId(); + if ( s_nNextEntityId <= nEntityId ) + { + s_nNextEntityId = nEntityId + 1; + } + + // Get called back when the name changes + m_Name.GetAttribute()->AddFlag( FATTRIB_HAS_CALLBACK ); + + // Used to make sure these aren't saved if they aren't changed + //m_TargetName.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK ); + //m_vecLocalAngles.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK ); + + m_bIsDirty = false; + m_bInfoTarget = false; + m_hEngineEntity = HTOOLHANDLE_INVALID; + + m_Wireframe.Init( "debug/debugwireframevertexcolor", "editor" ); + + // FIXME: Need to abstract out rendering into a separate class + // based on information parsed from the FGD + KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); + pVMTKeyValues->SetString( "$basetexture", "editor/info_target" ); + pVMTKeyValues->SetInt( "$nocull", 1 ); + pVMTKeyValues->SetInt( "$vertexcolor", 1 ); + pVMTKeyValues->SetInt( "$vertexalpha", 1 ); + pVMTKeyValues->SetInt( "$no_fullbright", 1 ); + pVMTKeyValues->SetInt( "$translucent", 1 ); + m_InfoTargetSprite.Init( "__vcdblock_info_target", pVMTKeyValues ); + + pVMTKeyValues = new KeyValues( "UnlitGeneric" ); + pVMTKeyValues->SetInt( "$nocull", 1 ); + pVMTKeyValues->SetString( "$color", "{64 64 64}" ); + pVMTKeyValues->SetInt( "$vertexalpha", 1 ); + pVMTKeyValues->SetInt( "$no_fullbright", 1 ); + pVMTKeyValues->SetInt( "$additive", 1 ); + m_SelectedInfoTarget.Init( "__selected_vcdblock_info_target", pVMTKeyValues ); +} + +void CDmeVMFEntity::OnDestruction() +{ + // Unhook it from the engine + AttachToEngineEntity( false ); + m_Wireframe.Shutdown(); + m_SelectedInfoTarget.Shutdown(); + m_InfoTargetSprite.Shutdown(); +} + + +//----------------------------------------------------------------------------- +// Called whem attributes change +//----------------------------------------------------------------------------- +void CDmeVMFEntity::OnAttributeChanged( CDmAttribute *pAttribute ) +{ + BaseClass::OnAttributeChanged( pAttribute ); + + // Once these have changed, then save them out, and don't bother calling back + if ( pAttribute == m_TargetName.GetAttribute() || + pAttribute == m_vecLocalAngles.GetAttribute() ) + { + pAttribute->RemoveFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK ); + return; + } + + if ( pAttribute == m_ClassName.GetAttribute() ) + { + m_bInfoTarget = !Q_strncmp( m_ClassName, "info_target", 11 ); + + // FIXME: Change the model based on the current class + SetModelName( NULL ); + return; + } + + // Make sure we have unique ids for all entities + if ( pAttribute == m_Name.GetAttribute() ) + { + int nEntityId = GetEntityId(); + if ( s_nNextEntityId <= nEntityId ) + { + s_nNextEntityId = nEntityId + 1; + } + } +} + + +//----------------------------------------------------------------------------- +// Returns the entity ID +//----------------------------------------------------------------------------- +int CDmeVMFEntity::GetEntityId() const +{ + return atoi( GetName() ); +} + + +//----------------------------------------------------------------------------- +// Returns the next available entity id +//----------------------------------------------------------------------------- +int CDmeVMFEntity::GetNextEntityId() +{ + return s_nNextEntityId; +} + +void CDmeVMFEntity::SetNextEntityId( int nEntityId ) +{ + s_nNextEntityId = nEntityId; +} + + +//----------------------------------------------------------------------------- +// Mark the entity as being dirty +//----------------------------------------------------------------------------- +void CDmeVMFEntity::MarkDirty( bool bDirty ) +{ + m_bIsDirty = bDirty; + + // FIXME: this is doing two operations!! + CopyToServer(); +} + + +//----------------------------------------------------------------------------- +// Is the renderable transparent? +//----------------------------------------------------------------------------- +bool CDmeVMFEntity::IsTransparent( void ) +{ + return m_bIsDirty || m_bInfoTarget || BaseClass::IsTransparent(); +} + + +//----------------------------------------------------------------------------- +// Entity Key iteration +//----------------------------------------------------------------------------- +bool CDmeVMFEntity::IsEntityKey( CDmAttribute *pEntityKey ) +{ + return pEntityKey->IsFlagSet( FATTRIB_USERDEFINED ); +} + +CDmAttribute *CDmeVMFEntity::FirstEntityKey() +{ + for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() ) + { + if ( IsEntityKey( pAttribute ) ) + return pAttribute; + } + return NULL; +} + +CDmAttribute *CDmeVMFEntity::NextEntityKey( CDmAttribute *pEntityKey ) +{ + if ( !pEntityKey ) + return NULL; + + for ( CDmAttribute *pAttribute = pEntityKey->NextAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() ) + { + if ( IsEntityKey( pAttribute ) ) + return pAttribute; + } + return NULL; +} + + +//----------------------------------------------------------------------------- +// Attach/detach from an engine entity with the same editor index +//----------------------------------------------------------------------------- +void CDmeVMFEntity::AttachToEngineEntity( HTOOLHANDLE hToolHandle ) +{ + if ( m_hEngineEntity != HTOOLHANDLE_INVALID ) + { + clienttools->SetEnabled( m_hEngineEntity, true ); + } + m_hEngineEntity = hToolHandle; + if ( m_hEngineEntity != HTOOLHANDLE_INVALID ) + { + clienttools->SetEnabled( m_hEngineEntity, false ); + } +} + + +//----------------------------------------------------------------------------- +// Position and bounds for the model +//----------------------------------------------------------------------------- +const Vector &CDmeVMFEntity::GetRenderOrigin( void ) +{ + return m_vecLocalOrigin; +} + +const QAngle &CDmeVMFEntity::GetRenderAngles( void ) +{ + return *(QAngle *)(&m_vecLocalAngles); +} + +void CDmeVMFEntity::GetRenderBounds( Vector& mins, Vector& maxs ) +{ + if ( !m_bInfoTarget ) + { + BaseClass::GetRenderBounds( mins, maxs ); + return; + } + + mins.Init( -SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS ); + maxs.Init( SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS ); +} + + +//----------------------------------------------------------------------------- +// Update renderable position +//----------------------------------------------------------------------------- +void CDmeVMFEntity::SetRenderOrigin( const Vector &vecOrigin ) +{ + m_vecLocalOrigin = vecOrigin; + clienttools->MarkClientRenderableDirty( this ); +} + +void CDmeVMFEntity::SetRenderAngles( const QAngle &angles ) +{ + m_vecLocalAngles.Set( Vector( angles.x, angles.y, angles.z ) ); // FIXME: angles is a vector due to the vmf "angles" having a problem parsing... + clienttools->MarkClientRenderableDirty( this ); +} + + +//----------------------------------------------------------------------------- +// Draws the helper for the entity +//----------------------------------------------------------------------------- +void CDmeVMFEntity::DrawSprite( IMaterial *pMaterial ) +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + + float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f; + + pRenderContext->Bind( pMaterial ); + IMesh* pMesh = pRenderContext->GetDynamicMesh(); + + CMeshBuilder meshBuilder; + meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 4, 4 ); + + unsigned char nBaseR = 255; + unsigned char nBaseG = 255; + unsigned char nBaseB = 255; + unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255; + + meshBuilder.Position3f( -SPHERE_RADIUS, -SPHERE_RADIUS, 0.0f ); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); + meshBuilder.BoneWeight( 0, 1.0f ); + meshBuilder.BoneMatrix( 0, 0 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3f( SPHERE_RADIUS, -SPHERE_RADIUS, 0.0f ); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); + meshBuilder.BoneWeight( 0, 1.0f ); + meshBuilder.BoneMatrix( 0, 0 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3f( SPHERE_RADIUS, SPHERE_RADIUS, 0.0f ); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); + meshBuilder.BoneWeight( 0, 1.0f ); + meshBuilder.BoneMatrix( 0, 0 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3f( -SPHERE_RADIUS, SPHERE_RADIUS, 0.0f ); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); + meshBuilder.BoneWeight( 0, 1.0f ); + meshBuilder.BoneMatrix( 0, 0 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.FastIndex( 0 ); + meshBuilder.FastIndex( 1 ); + meshBuilder.FastIndex( 3 ); + meshBuilder.FastIndex( 2 ); + + meshBuilder.End(); + pMesh->Draw(); +} + + + +//----------------------------------------------------------------------------- +// Draws the helper for the entity +//----------------------------------------------------------------------------- +void CDmeVMFEntity::DrawDragHelpers( IMaterial *pMaterial ) +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + + float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f; + + VMatrix worldToCamera; + // pRenderContext->GetMatrix( MATERIAL_VIEW, &worldToCamera ); + worldToCamera.Identity(); + worldToCamera.SetTranslation( m_vecLocalOrigin ); + + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PushMatrix(); + pRenderContext->LoadMatrix( worldToCamera ); + + pRenderContext->FogMode( MATERIAL_FOG_NONE ); + pRenderContext->SetNumBoneWeights( 0 ); + pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); + + pRenderContext->Bind( pMaterial ); + IMesh* pMesh = pRenderContext->GetDynamicMesh(); + + CMeshBuilder meshBuilder; + meshBuilder.Begin( pMesh, MATERIAL_LINES, 3 ); + + unsigned char nBaseR = 255; + unsigned char nBaseG = 255; + unsigned char nBaseB = 255; + unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255; + + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( 0, 0, 0 ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( SPHERE_RADIUS * 10, 0, 0 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( 0, 0, 0 ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( 0, SPHERE_RADIUS * 10, 0 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( 0, 0, 0 ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( 0, 0, SPHERE_RADIUS * 10 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.End(); + pMesh->Draw(); + + pRenderContext->CullMode( MATERIAL_CULLMODE_CCW ); + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PopMatrix(); +} + + + +//----------------------------------------------------------------------------- +// Draws the helper for the entity +//----------------------------------------------------------------------------- +void CDmeVMFEntity::DrawFloorTarget( IMaterial *pMaterial ) +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + + float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f; + + // test movement + Ray_t ray; + CTraceFilterWorldAndPropsOnly traceFilter; + CBaseTrace tr; + ray.Init( m_vecLocalOrigin.Get()+ Vector( 0, 0, 10 ), m_vecLocalOrigin.Get() + Vector( 0,0, -128 ), Vector( -13, -13, 0 ), Vector( 13, 13, 10 ) ); + enginetools->TraceRayServer( ray, MASK_OPAQUE, &traceFilter, &tr ); + + + VMatrix worldToCamera; + // pRenderContext->GetMatrix( MATERIAL_VIEW, &worldToCamera ); + worldToCamera.Identity(); + worldToCamera.SetTranslation( tr.endpos ); + + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PushMatrix(); + pRenderContext->LoadMatrix( worldToCamera ); + + pRenderContext->FogMode( MATERIAL_FOG_NONE ); + pRenderContext->SetNumBoneWeights( 0 ); + pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); + + pRenderContext->Bind( pMaterial ); + IMesh* pMesh = pRenderContext->GetDynamicMesh(); + + CMeshBuilder meshBuilder; + meshBuilder.Begin( pMesh, MATERIAL_LINES, 3 ); + + unsigned char nBaseR = 255; + unsigned char nBaseG = 255; + unsigned char nBaseB = 0; + unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255; + + float block[4][2][3] = { + { { -13, -13, 0 }, { -13, -13, 10 } }, + { { 13, -13, 0 }, { 13, -13, 10 } }, + { { 13, 13, 0 }, { 13, 13, 10 } }, + { { -13, 13, 0 }, { -13, 13, 10 } } }; + + for (int i = 0; i < 4; i++) + { + int j = (i + 1) % 4; + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( block[i][0][0], block[i][0][1], block[i][0][2] ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( block[i][1][0], block[i][1][1], block[i][1][2] ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( block[i][0][0], block[i][0][1], block[i][0][2] ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( block[j][0][0], block[j][0][1], block[j][0][2] ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( block[i][1][0], block[i][1][1], block[i][1][2] ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha ); + meshBuilder.Position3f( block[j][1][0], block[j][1][1], block[j][1][2] ); + meshBuilder.AdvanceVertex(); + } + + // positive X + meshBuilder.Color4ub( 255, 0, 0, nAlpha ); + meshBuilder.Position3f( 0, 0, 10 ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( 255, 0, 0, nAlpha ); + meshBuilder.Position3f( 10, 0, 10 ); + meshBuilder.AdvanceVertex(); + + // positive Y + meshBuilder.Color4ub( 0, 255, 0, nAlpha ); + meshBuilder.Position3f( 0, 0, 10 ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( 0, 255, 0, nAlpha ); + meshBuilder.Position3f( 0, 10, 10 ); + meshBuilder.AdvanceVertex(); + + // just Z + meshBuilder.Color4ub( 255, 255, 255, nAlpha ); + meshBuilder.Position3f( 0, 0, 10 ); + meshBuilder.AdvanceVertex(); + meshBuilder.Color4ub( 255, 255, 255, nAlpha ); + meshBuilder.Position3f( 0, 0, 0 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.End(); + pMesh->Draw(); + + pRenderContext->CullMode( MATERIAL_CULLMODE_CCW ); + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PopMatrix(); +} + + +//----------------------------------------------------------------------------- +// Draws the helper for the entity +//----------------------------------------------------------------------------- +int CDmeVMFEntity::DrawModel( int flags ) +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + + bool bSelected = ( g_pVcdBlockTool->GetCurrentEntity().Get() == this ); + if ( !m_bInfoTarget ) + { + // If we have a visible engine entity, we don't need to draw it here + // info targets always draw though, because they have no visible model. + CDisableUndoScopeGuard guard; + float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f; + unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255; + if ( bSelected ) + { + GetMDL()->m_Color.SetColor( 255, 64, 64, nAlpha ); + } + else + { + GetMDL()->m_Color.SetColor( 255, 255, 255, nAlpha ); + } + return BaseClass::DrawModel( flags ); + } + + Assert( IsDrawingInEngine() ); + + matrix3x4_t mat; + VMatrix worldToCamera, cameraToWorld; + pRenderContext->GetMatrix( MATERIAL_VIEW, &worldToCamera ); + MatrixInverseTR( worldToCamera, cameraToWorld ); + MatrixCopy( cameraToWorld.As3x4(), mat ); + MatrixSetColumn( m_vecLocalOrigin, 3, mat ); + + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PushMatrix(); + pRenderContext->LoadMatrix( mat ); + + pRenderContext->FogMode( MATERIAL_FOG_NONE ); + pRenderContext->SetNumBoneWeights( 0 ); + pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); + + DrawSprite( m_InfoTargetSprite ); + if ( bSelected ) + { + DrawSprite( m_SelectedInfoTarget ); + + DrawFloorTarget( m_Wireframe ); + + if (g_pVcdBlockTool->IsInNodeDrag()) + { + DrawDragHelpers( m_Wireframe ); + } + // DrawLine( Vector( 0, 0, 0 ), Vector( 10, 0, 0 ), 0, 255, 255, 255 ); + } + + pRenderContext->CullMode( MATERIAL_CULLMODE_CCW ); + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PopMatrix(); + + return 1; +} + + +bool CDmeVMFEntity::CopyFromServer( CBaseEntity *pServerEnt ) +{ + CopyFromServer( pServerEnt, "targetname" ); + CopyFromServer( pServerEnt, "classname" ); + CopyFromServer( pServerEnt, "origin" ); + CopyFromServer( pServerEnt, "angles" ); + + return true; +} + +bool CDmeVMFEntity::CopyFromServer( CBaseEntity *pServerEnt, const char *szField ) +{ + return CopyFromServer( pServerEnt, szField, szField ); +} + +bool CDmeVMFEntity::CopyFromServer( CBaseEntity *pServerEnt, const char *szSrcField, const char *szDstField ) +{ + char text[256]; + if ( servertools->GetKeyValue( pServerEnt, szSrcField, text, sizeof( text ) ) ) + { + SetValueFromString( szDstField, text ); + return true; + } + return false; +} + +bool CDmeVMFEntity::CopyToServer( void ) +{ + if (GetEntityId() != 0) + { + CBaseEntity *pServerEntity = servertools->FindEntityByHammerID( GetEntityId() ); + if (pServerEntity != NULL) + { + servertools->SetKeyValue( pServerEntity, "origin", m_vecLocalOrigin.Get() ); + // FIXME: isn't there a string to vector conversion? + Vector tmp( m_vecLocalAngles.Get().x, m_vecLocalAngles.Get().y, m_vecLocalAngles.Get().z ); + servertools->SetKeyValue( pServerEntity, "angles", tmp ); + return true; + } + else + { + // FIXME: does one need to be spawned? + } + } + return false; +} + +bool CDmeVMFEntity::IsSameOnServer( CBaseEntity *pServerEntity ) +{ + char text[256]; + + if (!pServerEntity) + { + return false; + } + + // FIXME: check targetname? Can it be edited? + Vector mapOrigin; + servertools->GetKeyValue( pServerEntity, "origin", text, sizeof( text ) ); + sscanf( text, "%f %f %f", &mapOrigin.x, &mapOrigin.y, &mapOrigin.z ); + Vector mapAngles; + servertools->GetKeyValue( pServerEntity, "angles", text, sizeof( text ) ); + sscanf( text, "%f %f %f", &mapAngles.x, &mapAngles.y, &mapAngles.z ); + + return ( mapOrigin == m_vecLocalOrigin.Get() && mapAngles == m_vecLocalAngles.Get() ); +} + +bool CDmeVMFEntity::CreateOnServer( void ) +{ + CBaseEntity *pServerEntity = servertools->CreateEntityByName( m_ClassName.Get() ); + + if (pServerEntity) + { + // test movement + Ray_t ray; + CTraceFilterWorldAndPropsOnly traceFilter; + CBaseTrace tr; + ray.Init( m_vecLocalOrigin.Get()+ Vector( 0, 0, 10 ), m_vecLocalOrigin.Get() + Vector( 0,0, -1000 ) ); + enginetools->TraceRayServer( ray, MASK_OPAQUE, &traceFilter, &tr ); + m_vecLocalOrigin.Set( tr.endpos ); + + servertools->SetKeyValue( pServerEntity, "hammerid", GetEntityId() ); + servertools->SetKeyValue( pServerEntity, "targetname", m_TargetName.Get() ); + servertools->SetKeyValue( pServerEntity, "origin", m_vecLocalOrigin.Get() ); + servertools->SetKeyValue( pServerEntity, "angles", m_vecLocalAngles.Get() ); + servertools->DispatchSpawn( pServerEntity ); + + return true; + } + return false; +} |