mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-04 18:09:53 +03:00
1
This commit is contained in:
664
tools/vcdblock/dmevmfentity.cpp
Normal file
664
tools/vcdblock/dmevmfentity.cpp
Normal file
@@ -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;
|
||||
}
|
||||
131
tools/vcdblock/dmevmfentity.h
Normal file
131
tools/vcdblock/dmevmfentity.h
Normal file
@@ -0,0 +1,131 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Represents an entity in a VMF
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMEVMFENTITY_H
|
||||
#define DMEVMFENTITY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "toolutils/dmemdlrenderable.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "toolframework/itoolentity.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Represents an editable entity; draws its helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmeVMFEntity : public CDmeMdlRenderable<CDmElement>
|
||||
{
|
||||
DEFINE_ELEMENT( CDmeVMFEntity, CDmeMdlRenderable<CDmElement> );
|
||||
|
||||
public:
|
||||
// Inherited from CDmElement
|
||||
virtual void OnAttributeChanged( CDmAttribute *pAttribute );
|
||||
|
||||
public:
|
||||
// Inherited from DmeRenderable
|
||||
virtual const Vector &GetRenderOrigin( void );
|
||||
virtual const QAngle &GetRenderAngles( void );
|
||||
virtual int DrawModel( int flags );
|
||||
virtual bool IsTransparent( void );
|
||||
virtual void GetRenderBounds( Vector& mins, Vector& maxs );
|
||||
|
||||
public:
|
||||
int GetEntityId() const;
|
||||
|
||||
// Returns the next available entity id
|
||||
static int GetNextEntityId();
|
||||
static void SetNextEntityId( int nEntityId );
|
||||
|
||||
const char *GetClassName() const;
|
||||
const char *GetTargetName() const;
|
||||
|
||||
bool IsPlaceholder() const;
|
||||
|
||||
// Entity Key iteration
|
||||
CDmAttribute *FirstEntityKey();
|
||||
CDmAttribute *NextEntityKey( CDmAttribute *pEntityKey );
|
||||
|
||||
// Attach/detach from an engine entity with the same editor index
|
||||
void AttachToEngineEntity( HTOOLHANDLE hToolHandle );
|
||||
|
||||
void SetRenderOrigin( const Vector &vecOrigin );
|
||||
void SetRenderAngles( const QAngle &angles );
|
||||
|
||||
void MarkDirty( bool bDirty = true );
|
||||
bool IsDirty( void ) { return m_bIsDirty; };
|
||||
|
||||
void MarkDeleted( bool bDeleted = true );
|
||||
bool IsDeleted( void ) { return m_bIsDeleted; };
|
||||
|
||||
bool CopyFromServer( CBaseEntity *pServerEnt );
|
||||
bool CopyFromServer( CBaseEntity *pServerEnt, const char *szField );
|
||||
bool CopyFromServer( CBaseEntity *pServerEnt, const char *szSrcField, const char *szDstField );
|
||||
bool CopyToServer( void );
|
||||
|
||||
bool IsSameOnServer( CBaseEntity *pServerEntity );
|
||||
bool CreateOnServer( void );
|
||||
|
||||
private:
|
||||
bool IsEntityKey( CDmAttribute *pEntityKey );
|
||||
|
||||
// Draws the helper for the entity
|
||||
void DrawSprite( IMaterial *pMaterial );
|
||||
void DrawDragHelpers( IMaterial *pMaterial );
|
||||
void DrawFloorTarget( IMaterial *pMaterial );
|
||||
|
||||
CDmaVar<Vector> m_vecLocalOrigin;
|
||||
// CDmAttributeVar<QAngle> m_vecLocalAngles;
|
||||
CDmaVar<Vector> m_vecLocalAngles; // something funky with the vmf importer, it asserts when it's a QAngle
|
||||
|
||||
CDmaString m_ClassName;
|
||||
CDmaString m_TargetName;
|
||||
CDmaVar<bool> m_bIsPlaceholder;
|
||||
|
||||
// The entity it's connected to in the engine
|
||||
HTOOLHANDLE m_hEngineEntity;
|
||||
|
||||
CMaterialReference m_Wireframe;
|
||||
|
||||
CMaterialReference m_SelectedInfoTarget;
|
||||
CMaterialReference m_InfoTargetSprite;
|
||||
|
||||
// pretty sure this entity is edited
|
||||
bool m_bIsDirty;
|
||||
|
||||
// entity needs to be deleted
|
||||
CDmaVar<bool> m_bIsDeleted;
|
||||
|
||||
// FIXME: This is a hack for info targets
|
||||
bool m_bInfoTarget;
|
||||
|
||||
// Used to store the next unique entity id;
|
||||
static int s_nNextEntityId;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char *CDmeVMFEntity::GetClassName() const
|
||||
{
|
||||
return m_ClassName;
|
||||
}
|
||||
|
||||
inline const char *CDmeVMFEntity::GetTargetName() const
|
||||
{
|
||||
return m_TargetName;
|
||||
}
|
||||
|
||||
inline bool CDmeVMFEntity::IsPlaceholder() const
|
||||
{
|
||||
return m_bIsPlaceholder;
|
||||
}
|
||||
|
||||
|
||||
#endif // DMEVMFENTITY_H
|
||||
297
tools/vcdblock/infotargetbrowserpanel.cpp
Normal file
297
tools/vcdblock/infotargetbrowserpanel.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Singleton dialog that generates and presents the entity report.
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "InfoTargetBrowserPanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "iregistry.h"
|
||||
#include "vgui/ivgui.h"
|
||||
#include "vgui_controls/listpanel.h"
|
||||
#include "vgui_controls/textentry.h"
|
||||
#include "vgui_controls/checkbutton.h"
|
||||
#include "vgui_controls/combobox.h"
|
||||
#include "vgui_controls/radiobutton.h"
|
||||
#include "vgui_controls/messagebox.h"
|
||||
#include "vcdblockdoc.h"
|
||||
#include "vcdblocktool.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "vgui/keycode.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by target name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl TargetNameSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("targetname");
|
||||
const char *string2 = item2.kv->GetString("targetname");
|
||||
int nRetVal = Q_stricmp( string1, string2 );
|
||||
if ( nRetVal != 0 )
|
||||
return nRetVal;
|
||||
|
||||
string1 = item1.kv->GetString("classname");
|
||||
string2 = item2.kv->GetString("classname");
|
||||
return Q_stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by class name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl ClassNameSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("classname");
|
||||
const char *string2 = item2.kv->GetString("classname");
|
||||
int nRetVal = Q_stricmp( string1, string2 );
|
||||
if ( nRetVal != 0 )
|
||||
return nRetVal;
|
||||
|
||||
string1 = item1.kv->GetString("targetname");
|
||||
string2 = item2.kv->GetString("targetname");
|
||||
return Q_stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CInfoTargetBrowserPanel::CInfoTargetBrowserPanel( CVcdBlockDoc *pDoc, vgui::Panel* pParent, const char *pName )
|
||||
: BaseClass( pParent, pName ), m_pDoc( pDoc )
|
||||
{
|
||||
SetPaintBackgroundEnabled( true );
|
||||
|
||||
m_pEntities = new vgui::ListPanel( this, "Entities" );
|
||||
m_pEntities->AddColumnHeader( 0, "targetname", "Name", 52, ListPanel::COLUMN_RESIZEWITHWINDOW );
|
||||
m_pEntities->AddColumnHeader( 1, "classname", "Class Name", 52, ListPanel::COLUMN_RESIZEWITHWINDOW );
|
||||
m_pEntities->SetColumnSortable( 0, true );
|
||||
m_pEntities->SetColumnSortable( 1, true );
|
||||
m_pEntities->SetEmptyListText( "No info_targets" );
|
||||
// m_pEntities->SetDragEnabled( true );
|
||||
m_pEntities->AddActionSignalTarget( this );
|
||||
m_pEntities->SetSortFunc( 0, TargetNameSortFunc );
|
||||
m_pEntities->SetSortFunc( 1, ClassNameSortFunc );
|
||||
m_pEntities->SetSortColumn( 0 );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/infotargetbrowserpanel.res" );
|
||||
|
||||
UpdateEntityList();
|
||||
}
|
||||
|
||||
CInfoTargetBrowserPanel::~CInfoTargetBrowserPanel()
|
||||
{
|
||||
SaveUserConfig();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows the most recent selected object in properties window
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::OnProperties(void)
|
||||
{
|
||||
int iSel = m_pEntities->GetSelectedItem( 0 );
|
||||
KeyValues *kv = m_pEntities->GetItem( iSel );
|
||||
CDmeVMFEntity *pEntity = CastElement< CDmeVMFEntity >( (CDmElement *)kv->GetPtr( "entity" ) );
|
||||
g_pVcdBlockTool->ShowEntityInEntityProperties( pEntity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Deletes the marked objects.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::OnDeleteEntities(void)
|
||||
{
|
||||
int iSel = m_pEntities->GetSelectedItem( 0 );
|
||||
|
||||
{
|
||||
// This is undoable
|
||||
CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Delete Entities", "Delete Entities" );
|
||||
|
||||
//
|
||||
// Build a list of objects to delete.
|
||||
//
|
||||
int nCount = m_pEntities->GetSelectedItemsCount();
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
int nItemID = m_pEntities->GetSelectedItem(i);
|
||||
KeyValues *kv = m_pEntities->GetItem( nItemID );
|
||||
CDmeVMFEntity *pEntity = (CDmeVMFEntity *)kv->GetPtr( "entity" );
|
||||
if ( pEntity )
|
||||
{
|
||||
m_pDoc->DeleteInfoTarget( pEntity );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the list box selection.
|
||||
if (iSel >= m_pEntities->GetItemCount())
|
||||
{
|
||||
iSel = m_pEntities->GetItemCount() - 1;
|
||||
}
|
||||
m_pEntities->SetSingleSelectedItem( iSel );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::OnKeyCodeTyped( vgui::KeyCode code )
|
||||
{
|
||||
if ( code == KEY_DELETE )
|
||||
{
|
||||
OnDeleteEntities();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnKeyCodeTyped( code );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::OnItemSelected( void )
|
||||
{
|
||||
OnProperties();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select a particular node
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::SelectNode( CDmeVMFEntity *pNode )
|
||||
{
|
||||
m_pEntities->ClearSelectedItems();
|
||||
for ( int nItemID = m_pEntities->FirstItem(); nItemID != m_pEntities->InvalidItemID(); nItemID = m_pEntities->NextItem( nItemID ) )
|
||||
{
|
||||
KeyValues *kv = m_pEntities->GetItem( nItemID );
|
||||
CDmElement *pEntity = (CDmElement *)kv->GetPtr( "entity" );
|
||||
if ( pEntity == pNode )
|
||||
{
|
||||
m_pEntities->AddSelectedItem( nItemID );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when buttons are clicked
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "delete" ) )
|
||||
{
|
||||
// Confirm we want to do it
|
||||
MessageBox *pConfirm = new MessageBox( "#VcdBlockDeleteObjects", "#VcdBlockDeleteObjectsMsg", g_pVcdBlockTool->GetRootPanel() );
|
||||
pConfirm->AddActionSignalTarget( this );
|
||||
pConfirm->SetOKButtonText( "Yes" );
|
||||
pConfirm->SetCommand( new KeyValues( "DeleteEntities" ) );
|
||||
pConfirm->SetCancelButtonVisible( true );
|
||||
pConfirm->SetCancelButtonText( "No" );
|
||||
pConfirm->DoModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Save" ) )
|
||||
{
|
||||
g_pVcdBlockTool->Save();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "RestartMap" ) )
|
||||
{
|
||||
g_pVcdBlockTool->RestartMap();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "DropInfoTargets" ) )
|
||||
{
|
||||
g_pVcdBlockTool->EnterTargetDropMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "quicksave" ) )
|
||||
{
|
||||
g_pVcdBlockTool->QuickSave();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "quickload" ) )
|
||||
{
|
||||
g_pVcdBlockTool->QuickLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::UpdateEntityList(void)
|
||||
{
|
||||
m_pEntities->RemoveAll();
|
||||
|
||||
const CDmrElementArray<CDmElement> entityList( m_pDoc->GetEntityList() );
|
||||
if ( !entityList.IsValid() )
|
||||
return;
|
||||
|
||||
int nCount = entityList.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pEntity = entityList[i];
|
||||
|
||||
const char *pClassName = pEntity->GetValueString( "classname" );
|
||||
if ( !pClassName || !pClassName[0] )
|
||||
{
|
||||
pClassName = "<no class>";
|
||||
}
|
||||
|
||||
KeyValues *kv = new KeyValues( "node" );
|
||||
kv->SetString( "classname", pClassName );
|
||||
kv->SetPtr( "entity", pEntity );
|
||||
|
||||
const char *pTargetname = pEntity->GetValueString( "targetname" );
|
||||
if ( !pTargetname || !pTargetname[0] )
|
||||
{
|
||||
pTargetname = "<no targetname>";
|
||||
}
|
||||
kv->SetString( "targetname", pTargetname );
|
||||
|
||||
int nItemID = m_pEntities->AddItem( kv, 0, false, false );
|
||||
|
||||
// Hide everything that isn't an info_target
|
||||
m_pEntities->SetItemVisible( nItemID, !Q_stricmp( pClassName, "info_target" ) );
|
||||
}
|
||||
m_pEntities->SortList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetBrowserPanel::Refresh(void)
|
||||
{
|
||||
for ( int nItemID = m_pEntities->FirstItem(); nItemID != m_pEntities->InvalidItemID(); nItemID = m_pEntities->NextItem( nItemID ) )
|
||||
{
|
||||
KeyValues *kv = m_pEntities->GetItem( nItemID );
|
||||
CDmElement *pEntity = (CDmElement *)kv->GetPtr( "entity" );
|
||||
|
||||
const char *pTargetname = pEntity->GetValueString( "targetname" );
|
||||
if ( !pTargetname || !pTargetname[0] )
|
||||
{
|
||||
pTargetname = "<no targetname>";
|
||||
}
|
||||
kv->SetString( "targetname", pTargetname );
|
||||
}
|
||||
}
|
||||
|
||||
68
tools/vcdblock/infotargetbrowserpanel.h
Normal file
68
tools/vcdblock/infotargetbrowserpanel.h
Normal file
@@ -0,0 +1,68 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef INFOTARGETBROWSERPANEL_H
|
||||
#define INFOTARGETBROWSERPANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vgui_controls/editablepanel.h"
|
||||
#include "tier1/utlstring.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVcdBlockDoc;
|
||||
class CDmeVMFEntity;
|
||||
namespace vgui
|
||||
{
|
||||
class ComboBox;
|
||||
class Button;
|
||||
class TextEntry;
|
||||
class ListPanel;
|
||||
class CheckButton;
|
||||
class RadioButton;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Panel that shows all entities in the level
|
||||
//-----------------------------------------------------------------------------
|
||||
class CInfoTargetBrowserPanel : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CInfoTargetBrowserPanel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CInfoTargetBrowserPanel( CVcdBlockDoc *pDoc, vgui::Panel* pParent, const char *pName ); // standard constructor
|
||||
virtual ~CInfoTargetBrowserPanel();
|
||||
|
||||
// Inherited from Panel
|
||||
virtual void OnCommand( const char *pCommand );
|
||||
virtual void OnKeyCodeTyped( vgui::KeyCode code );
|
||||
|
||||
// Methods related to updating the listpanel
|
||||
void UpdateEntityList();
|
||||
void Refresh();
|
||||
|
||||
// Select a particular node
|
||||
void SelectNode( CDmeVMFEntity *pNode );
|
||||
|
||||
private:
|
||||
// Messages handled
|
||||
MESSAGE_FUNC( OnDeleteEntities, "DeleteEntities" );
|
||||
MESSAGE_FUNC( OnItemSelected, "ItemSelected" );
|
||||
|
||||
// Shows the most recent selected object in properties window
|
||||
void OnProperties();
|
||||
|
||||
CVcdBlockDoc *m_pDoc;
|
||||
vgui::ListPanel *m_pEntities;
|
||||
};
|
||||
|
||||
|
||||
#endif // INFOTARGETBROWSERPANEL_H
|
||||
225
tools/vcdblock/infotargetpropertiespanel.cpp
Normal file
225
tools/vcdblock/infotargetpropertiespanel.cpp
Normal file
@@ -0,0 +1,225 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Singleton dialog that generates and presents the entity report.
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "InfoTargetPropertiesPanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "iregistry.h"
|
||||
#include "vgui/ivgui.h"
|
||||
#include "vgui_controls/listpanel.h"
|
||||
#include "vgui_controls/textentry.h"
|
||||
#include "vgui_controls/checkbutton.h"
|
||||
#include "vgui_controls/combobox.h"
|
||||
#include "vgui_controls/radiobutton.h"
|
||||
#include "vgui_controls/messagebox.h"
|
||||
#include "vgui_controls/scrollbar.h"
|
||||
#include "vcdblockdoc.h"
|
||||
#include "vcdblocktool.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "dmevmfentity.h"
|
||||
#include "dme_controls/soundpicker.h"
|
||||
#include "dme_controls/soundrecordpanel.h"
|
||||
#include "matsys_controls/picker.h"
|
||||
#include "vgui_controls/fileopendialog.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
class CScrollableEditablePanel : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CScrollableEditablePanel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CScrollableEditablePanel( vgui::Panel *pParent, vgui::EditablePanel *pChild, const char *pName );
|
||||
virtual ~CScrollableEditablePanel() {}
|
||||
virtual void PerformLayout();
|
||||
|
||||
MESSAGE_FUNC( OnScrollBarSliderMoved, "ScrollBarSliderMoved" );
|
||||
|
||||
private:
|
||||
vgui::ScrollBar *m_pScrollBar;
|
||||
vgui::EditablePanel *m_pChild;
|
||||
};
|
||||
|
||||
|
||||
CScrollableEditablePanel::CScrollableEditablePanel( vgui::Panel *pParent, vgui::EditablePanel *pChild, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
m_pChild = pChild;
|
||||
m_pChild->SetParent( this );
|
||||
|
||||
m_pScrollBar = new vgui::ScrollBar( this, "VerticalScrollBar", true );
|
||||
m_pScrollBar->SetWide( 16 );
|
||||
m_pScrollBar->SetAutoResize( PIN_TOPRIGHT, AUTORESIZE_DOWN, 0, 0, -16, 0 );
|
||||
m_pScrollBar->AddActionSignalTarget( this );
|
||||
}
|
||||
|
||||
void CScrollableEditablePanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
m_pChild->SetWide( GetWide() - 16 );
|
||||
m_pScrollBar->SetRange( 0, m_pChild->GetTall() );
|
||||
m_pScrollBar->SetRangeWindow( GetTall() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the scroll bar moves
|
||||
//-----------------------------------------------------------------------------
|
||||
void CScrollableEditablePanel::OnScrollBarSliderMoved()
|
||||
{
|
||||
InvalidateLayout();
|
||||
|
||||
int nScrollAmount = m_pScrollBar->GetValue();
|
||||
m_pChild->SetPos( 0, -nScrollAmount );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CInfoTargetPropertiesPanel::CInfoTargetPropertiesPanel( CVcdBlockDoc *pDoc, vgui::Panel* pParent )
|
||||
: BaseClass( pParent, "InfoTargetPropertiesPanel" ), m_pDoc( pDoc )
|
||||
{
|
||||
SetPaintBackgroundEnabled( true );
|
||||
SetKeyBoardInputEnabled( true );
|
||||
|
||||
m_pInfoTarget = new vgui::EditablePanel( (vgui::Panel*)NULL, "InfoTarget" );
|
||||
|
||||
m_pTargetName = new vgui::TextEntry( m_pInfoTarget, "TargetName" );
|
||||
m_pTargetName->AddActionSignalTarget( this );
|
||||
|
||||
m_pTargetPosition[0] = new vgui::TextEntry( m_pInfoTarget, "PositionX" );
|
||||
m_pTargetPosition[0]->AddActionSignalTarget( this );
|
||||
m_pTargetPosition[1] = new vgui::TextEntry( m_pInfoTarget, "PositionY" );
|
||||
m_pTargetPosition[1]->AddActionSignalTarget( this );
|
||||
m_pTargetPosition[2] = new vgui::TextEntry( m_pInfoTarget, "PositionZ" );
|
||||
m_pTargetPosition[2]->AddActionSignalTarget( this );
|
||||
|
||||
m_pTargetOrientation[0] = new vgui::TextEntry( m_pInfoTarget, "Pitch" );
|
||||
m_pTargetOrientation[0]->AddActionSignalTarget( this );
|
||||
m_pTargetOrientation[1] = new vgui::TextEntry( m_pInfoTarget, "Yaw" );
|
||||
m_pTargetOrientation[1]->AddActionSignalTarget( this );
|
||||
m_pTargetOrientation[2] = new vgui::TextEntry( m_pInfoTarget, "Roll" );
|
||||
m_pTargetOrientation[2]->AddActionSignalTarget( this );
|
||||
|
||||
m_pInfoTarget->LoadControlSettings( "resource/infotargetpropertiessubpanel_target.res" );
|
||||
|
||||
m_pInfoTargetScroll = new CScrollableEditablePanel( this, m_pInfoTarget, "InfoTargetScroll" );
|
||||
|
||||
LoadControlSettings( "resource/infotargetpropertiespanel.res" );
|
||||
|
||||
m_pInfoTargetScroll->SetVisible( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Text to attribute...
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetPropertiesPanel::TextEntryToAttribute( vgui::TextEntry *pEntry, const char *pAttributeName )
|
||||
{
|
||||
int nLen = pEntry->GetTextLength();
|
||||
char *pBuf = (char*)_alloca( nLen+1 );
|
||||
pEntry->GetText( pBuf, nLen+1 );
|
||||
m_hEntity->SetValue( pAttributeName, pBuf );
|
||||
}
|
||||
|
||||
void CInfoTargetPropertiesPanel::TextEntriesToVector( vgui::TextEntry *pEntry[3], const char *pAttributeName )
|
||||
{
|
||||
Vector vec;
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
int nLen = pEntry[i]->GetTextLength();
|
||||
char *pBuf = (char*)_alloca( nLen+1 );
|
||||
pEntry[i]->GetText( pBuf, nLen+1 );
|
||||
vec[i] = atof( pBuf );
|
||||
}
|
||||
m_hEntity->SetValue( pAttributeName, vec );
|
||||
clienttools->MarkClientRenderableDirty( m_hEntity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Updates entity state when text fields change
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetPropertiesPanel::UpdateInfoTarget()
|
||||
{
|
||||
if ( !m_hEntity.Get() )
|
||||
return;
|
||||
|
||||
CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Info Target Change", "Info Target Change" );
|
||||
TextEntryToAttribute( m_pTargetName, "targetname" );
|
||||
TextEntriesToVector( m_pTargetPosition, "origin" );
|
||||
TextEntriesToVector( m_pTargetOrientation, "angles" );
|
||||
m_hEntity->MarkDirty();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populates the info_target fields
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetPropertiesPanel::PopulateInfoTargetFields()
|
||||
{
|
||||
if ( !m_hEntity.Get() )
|
||||
return;
|
||||
|
||||
m_pTargetName->SetText( m_hEntity->GetTargetName() );
|
||||
|
||||
Vector vecPosition = m_hEntity->GetRenderOrigin();
|
||||
QAngle vecAngles = m_hEntity->GetRenderAngles();
|
||||
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
char pTemp[512];
|
||||
Q_snprintf( pTemp, sizeof(pTemp), "%.2f", vecPosition[i] );
|
||||
m_pTargetPosition[i]->SetText( pTemp );
|
||||
|
||||
Q_snprintf( pTemp, sizeof(pTemp), "%.2f", vecAngles[i] );
|
||||
m_pTargetOrientation[i]->SetText( pTemp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the object to look at
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetPropertiesPanel::SetObject( CDmeVMFEntity *pEntity )
|
||||
{
|
||||
m_hEntity = pEntity;
|
||||
m_pInfoTargetScroll->SetVisible( false );
|
||||
|
||||
if ( pEntity )
|
||||
{
|
||||
if ( !Q_stricmp( pEntity->GetClassName(), "info_target" ) )
|
||||
{
|
||||
PopulateInfoTargetFields();
|
||||
m_pInfoTargetScroll->SetVisible( true );
|
||||
m_pTargetName->RequestFocus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when text is changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CInfoTargetPropertiesPanel::OnTextChanged( KeyValues *pParams )
|
||||
{
|
||||
vgui::Panel *pPanel = (vgui::Panel*)pParams->GetPtr( "panel" );
|
||||
if ( pPanel->GetParent() == m_pInfoTarget )
|
||||
{
|
||||
UpdateInfoTarget();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
76
tools/vcdblock/infotargetpropertiespanel.h
Normal file
76
tools/vcdblock/infotargetpropertiespanel.h
Normal file
@@ -0,0 +1,76 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef INFOTARGETPROPERTIESPANEL_H
|
||||
#define INFOTARGETPROPERTIESPANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vgui_controls/editablepanel.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "datamodel/dmehandle.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVcdBlockDoc;
|
||||
class CDmeVMFEntity;
|
||||
class CScrollableEditablePanel;
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class ComboBox;
|
||||
class Button;
|
||||
class TextEntry;
|
||||
class ListPanel;
|
||||
class CheckButton;
|
||||
class RadioButton;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Panel that shows all entities in the level
|
||||
//-----------------------------------------------------------------------------
|
||||
class CInfoTargetPropertiesPanel : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CInfoTargetPropertiesPanel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CInfoTargetPropertiesPanel( CVcdBlockDoc *pDoc, vgui::Panel* pParent ); // standard constructor
|
||||
|
||||
// Sets the object to look at
|
||||
void SetObject( CDmeVMFEntity *pEntity );
|
||||
|
||||
private:
|
||||
// Populates the info_target fields
|
||||
void PopulateInfoTargetFields();
|
||||
|
||||
// Text to attribute...
|
||||
void TextEntryToAttribute( vgui::TextEntry *pEntry, const char *pAttributeName );
|
||||
void TextEntriesToVector( vgui::TextEntry *pEntry[3], const char *pAttributeName );
|
||||
|
||||
// Updates entity state when text fields change
|
||||
void UpdateInfoTarget();
|
||||
|
||||
// Messages handled
|
||||
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", kv );
|
||||
|
||||
CVcdBlockDoc *m_pDoc;
|
||||
|
||||
vgui::EditablePanel *m_pInfoTargetScroll;
|
||||
vgui::EditablePanel *m_pInfoTarget;
|
||||
|
||||
vgui::TextEntry *m_pTargetName;
|
||||
vgui::TextEntry *m_pTargetPosition[3];
|
||||
vgui::TextEntry *m_pTargetOrientation[3];
|
||||
|
||||
CDmeHandle< CDmeVMFEntity > m_hEntity;
|
||||
};
|
||||
|
||||
|
||||
#endif // INFOTARGETPROPERTIESPANEL_H
|
||||
64
tools/vcdblock/vcdblock.vpc
Normal file
64
tools/vcdblock/vcdblock.vpc
Normal file
@@ -0,0 +1,64 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VCDBLOCK.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin\tools"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,.\,..\common;$SRCDIR\game\shared"
|
||||
$PreprocessorDefinitions "$BASE;VCDBLOCK_EXPORTS"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE Psapi.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Vcdblock"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "dmevmfentity.cpp"
|
||||
$File "infotargetbrowserpanel.cpp"
|
||||
$File "infotargetpropertiespanel.cpp"
|
||||
$File "$SRCDIR\public\interpolatortypes.cpp"
|
||||
$File "$SRCDIR\public\registry.cpp"
|
||||
$File "vcdblockdoc.cpp"
|
||||
$File "vcdblocktool.cpp"
|
||||
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "dmevmfentity.h"
|
||||
$File "infotargetbrowserpanel.h"
|
||||
$File "infotargetpropertiespanel.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "vcdblockdoc.h"
|
||||
$File "vcdblocktool.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib datamodel
|
||||
$Lib dme_controls
|
||||
$Lib dmserializers
|
||||
$Lib mathlib
|
||||
$Lib matsys_controls
|
||||
$Lib movieobjects
|
||||
$Lib sfmobjects
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
$Lib toolutils
|
||||
$Lib vgui_controls
|
||||
}
|
||||
}
|
||||
630
tools/vcdblock/vcdblockdoc.cpp
Normal file
630
tools/vcdblock/vcdblockdoc.cpp
Normal file
@@ -0,0 +1,630 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "vcdblockdoc.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "toolutils/enginetools_int.h"
|
||||
#include "filesystem.h"
|
||||
#include "vcdblocktool.h"
|
||||
#include "toolframework/ienginetool.h"
|
||||
#include "dmevmfentity.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "toolutils/attributeelementchoicelist.h"
|
||||
#include "infotargetbrowserpanel.h"
|
||||
#include "vgui_controls/messagebox.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVcdBlockDoc::CVcdBlockDoc( IVcdBlockDocCallback *pCallback ) : m_pCallback( pCallback )
|
||||
{
|
||||
m_hVMFRoot = NULL;
|
||||
m_hEditRoot = NULL;
|
||||
m_pBSPFileName[0] = 0;
|
||||
m_pVMFFileName[0] = 0;
|
||||
m_pEditFileName[0] = 0;
|
||||
m_bDirty = false;
|
||||
g_pDataModel->InstallNotificationCallback( this );
|
||||
}
|
||||
|
||||
CVcdBlockDoc::~CVcdBlockDoc()
|
||||
{
|
||||
g_pDataModel->RemoveNotificationCallback( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inherited from INotifyUI
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags )
|
||||
{
|
||||
OnDataChanged( pReason, nNotifySource, nNotifyFlags );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the file name
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CVcdBlockDoc::GetBSPFileName()
|
||||
{
|
||||
return m_pBSPFileName;
|
||||
}
|
||||
|
||||
const char *CVcdBlockDoc::GetVMFFileName()
|
||||
{
|
||||
return m_pVMFFileName;
|
||||
}
|
||||
|
||||
void CVcdBlockDoc::SetVMFFileName( const char *pFileName )
|
||||
{
|
||||
Q_strncpy( m_pVMFFileName, pFileName, sizeof( m_pVMFFileName ) );
|
||||
Q_FixSlashes( m_pVMFFileName );
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
const char *CVcdBlockDoc::GetEditFileName()
|
||||
{
|
||||
return m_pEditFileName;
|
||||
}
|
||||
|
||||
void CVcdBlockDoc::SetEditFileName( const char *pFileName )
|
||||
{
|
||||
Q_strncpy( m_pEditFileName, pFileName, sizeof( m_pEditFileName ) );
|
||||
Q_FixSlashes( m_pEditFileName );
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dirty bits
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::SetDirty( bool bDirty )
|
||||
{
|
||||
m_bDirty = bDirty;
|
||||
}
|
||||
|
||||
bool CVcdBlockDoc::IsDirty() const
|
||||
{
|
||||
return m_bDirty;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Saves/loads from file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVcdBlockDoc::LoadFromFile( const char *pFileName )
|
||||
{
|
||||
Assert( !m_hVMFRoot.Get() );
|
||||
Assert( !m_hEditRoot.Get() );
|
||||
|
||||
CAppDisableUndoScopeGuard guard( "CVcdBlockDoc::LoadFromFile", NOTIFY_CHANGE_OTHER );
|
||||
SetDirty( false );
|
||||
|
||||
if ( !pFileName[0] )
|
||||
return false;
|
||||
|
||||
// Construct VMF file name from the BSP
|
||||
const char *pGame = Q_stristr( pFileName, "\\game\\" );
|
||||
if ( !pGame )
|
||||
{
|
||||
pGame = Q_stristr( pFileName, "\\content\\" );
|
||||
if ( !pGame )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute the map name
|
||||
const char *pMaps = Q_stristr( pFileName, "\\maps\\" );
|
||||
if ( !pMaps )
|
||||
return false;
|
||||
|
||||
// Build map name
|
||||
char mapname[ 256 ];
|
||||
Q_StripExtension( pFileName, mapname, sizeof(mapname) );
|
||||
char *pszFileName = (char*)Q_UnqualifiedFileName(mapname);
|
||||
|
||||
int nLen = (int)( (size_t)pGame - (size_t)pFileName ) + 1;
|
||||
Q_strncpy( m_pVMFFileName, pFileName, nLen );
|
||||
Q_strncat( m_pVMFFileName, "\\content\\", sizeof(m_pVMFFileName) );
|
||||
Q_strncat( m_pVMFFileName, pGame + 6, sizeof(m_pVMFFileName) );
|
||||
Q_SetExtension( m_pVMFFileName, ".vmf", sizeof(m_pVMFFileName) );
|
||||
|
||||
// Make sure new entities start with ids at 0
|
||||
CDmeVMFEntity::SetNextEntityId( 0 );
|
||||
|
||||
// Build the Edit file name
|
||||
Q_StripExtension( m_pVMFFileName, m_pEditFileName, sizeof(m_pEditFileName) );
|
||||
Q_strncat( m_pEditFileName, ".vle", sizeof( m_pEditFileName ) );
|
||||
|
||||
// Store the BSP file name
|
||||
Q_strncpy( m_pBSPFileName, pFileName, sizeof( m_pBSPFileName ) );
|
||||
|
||||
// Set the txt file name.
|
||||
// If we loaded a .bsp, clear out what we're doing
|
||||
// load the Edits file into memory, assign it as our "root"
|
||||
CDmElement *pEdit = NULL;
|
||||
if ( !V_stricmp( Q_GetFileExtension( pFileName ), "vle" ) )
|
||||
{
|
||||
if ( g_pDataModel->RestoreFromFile( m_pEditFileName, NULL, "vmf", &pEdit ) != DMFILEID_INVALID )
|
||||
{
|
||||
// If we successfully read the file in, ask it for the max hammer id
|
||||
//int nMaxHammerId = pVMF->GetAttributeValue<int>( "maxHammerId" );
|
||||
//CDmeVMFEntity::SetNextEntityId( nMaxHammerId + 1 );
|
||||
m_hEditRoot = pEdit;
|
||||
SetDirty( false );
|
||||
}
|
||||
}
|
||||
|
||||
if (pEdit == NULL)
|
||||
{
|
||||
if ( g_pFileSystem->FileExists( m_pEditFileName ) )
|
||||
{
|
||||
char pBuf[1024];
|
||||
Q_snprintf( pBuf, sizeof(pBuf), "File %s already exists!\n", m_pEditFileName );
|
||||
m_pEditFileName[0] = 0;
|
||||
vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Unable to overwrite file!\n", pBuf, g_pVcdBlockTool );
|
||||
pMessageBox->DoModal( );
|
||||
return false;
|
||||
}
|
||||
|
||||
DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( m_pEditFileName );
|
||||
m_hEditRoot = CreateElement<CDmElement>( "root", fileid );
|
||||
m_hEditRoot->AddAttribute( "entities", AT_ELEMENT_ARRAY );
|
||||
g_pDataModel->SetFileRoot( fileid, m_hEditRoot );
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
guard.Release();
|
||||
|
||||
// tell the engine to actually load the map
|
||||
char cmd[ 256 ];
|
||||
Q_snprintf( cmd, sizeof( cmd ), "disconnect; map %s\n", pszFileName );
|
||||
enginetools->Command( cmd );
|
||||
enginetools->Execute( );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CVcdBlockDoc::SaveToFile( )
|
||||
{
|
||||
if ( m_hEditRoot.Get() && m_pEditFileName && m_pEditFileName[0] )
|
||||
{
|
||||
g_pDataModel->SaveToFile( m_pEditFileName, NULL, "keyvalues", "vmf", m_hEditRoot );
|
||||
}
|
||||
|
||||
SetDirty( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the root object
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement *CVcdBlockDoc::GetRootObject()
|
||||
{
|
||||
return m_hEditRoot;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the entity list
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmAttribute *CVcdBlockDoc::GetEntityList()
|
||||
{
|
||||
return m_hEditRoot ? m_hEditRoot->GetAttribute( "entities", AT_ELEMENT_ARRAY ) : NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::AddNewInfoTarget( const Vector &vecOrigin, const QAngle &angAngles )
|
||||
{
|
||||
CDmrElementArray<> entities = GetEntityList();
|
||||
|
||||
CDmeVMFEntity *pTarget;
|
||||
{
|
||||
CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Add Info Target", "Add Info Target" );
|
||||
|
||||
pTarget = CreateElement<CDmeVMFEntity>( "", entities.GetOwner()->GetFileId() );
|
||||
pTarget->SetValue( "classname", "info_target" );
|
||||
pTarget->SetRenderOrigin( vecOrigin );
|
||||
pTarget->SetRenderAngles( angAngles );
|
||||
|
||||
entities.AddToTail( pTarget );
|
||||
pTarget->MarkDirty();
|
||||
pTarget->DrawInEngine( true );
|
||||
}
|
||||
|
||||
g_pVcdBlockTool->GetInfoTargetBrowser()->SelectNode( pTarget );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::AddNewInfoTarget( void )
|
||||
{
|
||||
Vector vecOrigin;
|
||||
QAngle angAngles;
|
||||
float flFov;
|
||||
clienttools->GetLocalPlayerEyePosition( vecOrigin, angAngles, flFov );
|
||||
AddNewInfoTarget( vecOrigin, vec3_angle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deletes a commentary node
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::DeleteInfoTarget( CDmeVMFEntity *pNode )
|
||||
{
|
||||
CDmrElementArray<CDmElement> entities = GetEntityList();
|
||||
int nCount = entities.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
if ( pNode == entities[i] )
|
||||
{
|
||||
CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Delete Info Target", "Delete Info Target" );
|
||||
CDmeVMFEntity *pNode = CastElement< CDmeVMFEntity >( entities[ i ] );
|
||||
pNode->DrawInEngine( false );
|
||||
entities.FastRemove( i );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &vecOrigin -
|
||||
// &angAbsAngles -
|
||||
// Output : CDmeVMFEntity
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeVMFEntity *CVcdBlockDoc::GetInfoTargetForLocation( Vector &vecOrigin, QAngle &angAbsAngles )
|
||||
{
|
||||
const CDmrElementArray<> entities = GetEntityList();
|
||||
int nCount = entities.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeVMFEntity *pNode = CastElement< CDmeVMFEntity >( entities[ i ] );
|
||||
Vector &vecAngles = *(Vector*)(&pNode->GetRenderAngles());
|
||||
if ( pNode->GetRenderOrigin().DistTo( vecOrigin ) < 1e-3 && vecAngles.DistTo( *(Vector*)&angAbsAngles ) < 1e-1 )
|
||||
return pNode;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &vecStart -
|
||||
// &vecEnd -
|
||||
// Output : CDmeVMFEntity
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeVMFEntity *CVcdBlockDoc::GetInfoTargetForLocation( Vector &vecStart, Vector &vecEnd )
|
||||
{
|
||||
Vector vecDelta;
|
||||
float flEndDist;
|
||||
|
||||
vecDelta = vecEnd - vecStart;
|
||||
flEndDist = VectorNormalize( vecDelta );
|
||||
|
||||
CDmeVMFEntity *pSelectedNode = NULL;
|
||||
float flMinDistFromLine = 1E30;
|
||||
|
||||
const CDmrElementArray<CDmElement> entities = GetEntityList();
|
||||
int nCount = entities.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeVMFEntity *pNode = CastElement< CDmeVMFEntity >( entities[ i ] );
|
||||
float flDistAway = DotProduct( pNode->GetRenderOrigin() - vecStart, vecDelta );
|
||||
|
||||
if (flDistAway > 0.0 && flDistAway < flEndDist)
|
||||
{
|
||||
float flDistFromLine = (pNode->GetRenderOrigin() - vecStart - vecDelta * flDistAway).Length();
|
||||
if (flDistFromLine < flMinDistFromLine)
|
||||
{
|
||||
pSelectedNode = pNode;
|
||||
flMinDistFromLine = flDistFromLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pSelectedNode;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate string choice lists
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVcdBlockDoc::GetStringChoiceList( const char *pChoiceListType, CDmElement *pElement,
|
||||
const char *pAttributeName, bool bArrayElement, StringChoiceList_t &list )
|
||||
{
|
||||
if ( !Q_stricmp( pChoiceListType, "info_targets" ) )
|
||||
{
|
||||
const CDmrElementArray<> entities = GetEntityList();
|
||||
|
||||
StringChoice_t sChoice;
|
||||
sChoice.m_pValue = "";
|
||||
sChoice.m_pChoiceString = "";
|
||||
list.AddToTail( sChoice );
|
||||
|
||||
int nCount = entities.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeVMFEntity *pNode = CastElement< CDmeVMFEntity >( entities[ i ] );
|
||||
if ( !V_stricmp( pNode->GetClassName(), "info_target" ) )
|
||||
{
|
||||
StringChoice_t sChoice;
|
||||
sChoice.m_pValue = pNode->GetTargetName();
|
||||
sChoice.m_pChoiceString = pNode->GetTargetName();
|
||||
list.AddToTail( sChoice );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate element choice lists
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVcdBlockDoc::GetElementChoiceList( const char *pChoiceListType, CDmElement *pElement,
|
||||
const char *pAttributeName, bool bArrayElement, ElementChoiceList_t &list )
|
||||
{
|
||||
if ( !Q_stricmp( pChoiceListType, "allelements" ) )
|
||||
{
|
||||
AddElementsRecursively( m_hEditRoot, list );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pChoiceListType, "info_targets" ) )
|
||||
{
|
||||
const CDmrElementArray<> entities = GetEntityList();
|
||||
|
||||
bool bFound = false;
|
||||
int nCount = entities.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeVMFEntity *pNode = CastElement< CDmeVMFEntity >( entities[ i ] );
|
||||
if ( !V_stricmp( pNode->GetClassName(), "info_target" ) )
|
||||
{
|
||||
bFound = true;
|
||||
ElementChoice_t sChoice;
|
||||
sChoice.m_pValue = pNode;
|
||||
sChoice.m_pChoiceString = pNode->GetTargetName();
|
||||
list.AddToTail( sChoice );
|
||||
}
|
||||
}
|
||||
return bFound;
|
||||
}
|
||||
|
||||
// by default, try to treat the choice list type as a Dme element type
|
||||
AddElementsRecursively( m_hEditRoot, list, pChoiceListType );
|
||||
|
||||
return list.Count() > 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when data changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::OnDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags )
|
||||
{
|
||||
SetDirty( nNotifyFlags & NOTIFY_SETDIRTYFLAG ? true : false );
|
||||
m_pCallback->OnDocChanged( pReason, nNotifySource, nNotifyFlags );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// List of all entity classnames to copy over from the original block
|
||||
//-----------------------------------------------------------------------------
|
||||
static const char *s_pUseOriginalClasses[] =
|
||||
{
|
||||
"worldspawn",
|
||||
"func_occluder",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The server just loaded, populate the list with the entities is has
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::ServerLevelInitPostEntity( void )
|
||||
{
|
||||
CDmrElementArray<> entityList = GetEntityList();
|
||||
|
||||
if ( entityList.Count() )
|
||||
{
|
||||
VerifyAllEdits( entityList );
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeFromServer( entityList );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create a list of entities based on what the server has
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::InitializeFromServer( CDmrElementArray<> &entityList )
|
||||
{
|
||||
CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Initialize From Server" );
|
||||
|
||||
entityList.RemoveAll();
|
||||
|
||||
// initialize list with entities on the server
|
||||
CBaseEntity *pServerEnt = servertools->FirstEntity();
|
||||
while (pServerEnt)
|
||||
{
|
||||
char classname[256];
|
||||
|
||||
if (servertools->GetKeyValue( pServerEnt, "classname", classname, sizeof( classname ) ) )
|
||||
{
|
||||
if ( !Q_stricmp( classname, "info_target" ))
|
||||
{
|
||||
char hammerid[256];
|
||||
if ( servertools->GetKeyValue( pServerEnt, "hammerid", hammerid, sizeof( hammerid ) ) )
|
||||
{
|
||||
int nextId = CDmeVMFEntity::GetNextEntityId();
|
||||
CDmeVMFEntity::SetNextEntityId( atoi( hammerid ) );
|
||||
|
||||
CDmeVMFEntity *pTarget = CreateElement<CDmeVMFEntity>( "", entityList.GetOwner()->GetFileId() );
|
||||
|
||||
CDmeVMFEntity::SetNextEntityId( nextId );
|
||||
|
||||
if ( pTarget->CopyFromServer( pServerEnt ) )
|
||||
{
|
||||
entityList.AddToTail( pTarget );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pServerEnt = servertools->NextEntity( pServerEnt );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Check the list of entities on the server against the edits that are already made
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVcdBlockDoc::VerifyAllEdits( const CDmrElementArray<> &entityList )
|
||||
{
|
||||
// already filled in
|
||||
for (int i = 0; i < entityList.Count(); i++)
|
||||
{
|
||||
CDmeVMFEntity *pEntity = CastElement<CDmeVMFEntity>( entityList[i] );
|
||||
|
||||
CBaseEntity *pServerEntity = servertools->FindEntityByHammerID( pEntity->GetEntityId() );
|
||||
|
||||
if (pServerEntity != NULL)
|
||||
{
|
||||
if (!pEntity->IsSameOnServer( pServerEntity ))
|
||||
{
|
||||
pEntity->MarkDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntity->MarkDirty(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntity->CreateOnServer();
|
||||
pEntity->MarkDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Load the VMF file, merge in all the edits, write it back out
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVcdBlockDoc::CopyEditsToVMF( )
|
||||
{
|
||||
const CDmrElementArray<CDmElement> entityList = GetEntityList();
|
||||
|
||||
CDmElement *pVMF = NULL;
|
||||
DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( m_pVMFFileName );
|
||||
if ( g_pDataModel->RestoreFromFile( m_pVMFFileName, NULL, "vmf", &pVMF ) == DMFILEID_INVALID )
|
||||
{
|
||||
// needs some kind of error message
|
||||
return false;
|
||||
}
|
||||
|
||||
CDmrElementArray<CDmElement> vmfEntities( pVMF, "entities" );
|
||||
|
||||
int nVMFCount = vmfEntities.Count();
|
||||
for (int i = 0; i < nVMFCount; i++)
|
||||
{
|
||||
CDmElement *pVMFEntity = vmfEntities[i];
|
||||
|
||||
char classname[256];
|
||||
pVMFEntity->GetValueAsString( "classname", classname, sizeof( classname ) );
|
||||
|
||||
if ( Q_stricmp( "info_target", classname ) )
|
||||
continue;
|
||||
|
||||
int nHammerID = atoi( pVMFEntity->GetName() );
|
||||
|
||||
// find a match.
|
||||
int nCount = entityList.Count();
|
||||
for (int j = 0; j < nCount; j++)
|
||||
{
|
||||
CDmeVMFEntity *pEntity = CastElement<CDmeVMFEntity>( entityList[j] );
|
||||
|
||||
if ( pEntity->IsDirty() && pEntity->GetEntityId() == nHammerID)
|
||||
{
|
||||
char text[256];
|
||||
pEntity->GetValueAsString( "targetname", text, sizeof( text ) );
|
||||
pVMFEntity->SetValueFromString( "targetname", text );
|
||||
pEntity->GetValueAsString( "origin", text, sizeof( text ) );
|
||||
pVMFEntity->SetValueFromString( "origin", text );
|
||||
pEntity->GetValueAsString( "angles", text, sizeof( text ) );
|
||||
pVMFEntity->SetValueFromString( "angles", text );
|
||||
|
||||
pEntity->MarkDirty(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add the new entities
|
||||
int nCount = entityList.Count();
|
||||
for (int j = 0; j < nCount; j++)
|
||||
{
|
||||
CDmeVMFEntity *pEntity = CastElement<CDmeVMFEntity>( entityList[j] );
|
||||
|
||||
if ( pEntity->IsDirty())
|
||||
{
|
||||
CDmElement *pVMFEntity = CreateElement<CDmElement>( pEntity->GetName(), fileid );
|
||||
|
||||
char text[256];
|
||||
pEntity->GetValueAsString( "classname", text, sizeof( text ) );
|
||||
pVMFEntity->SetValue( "classname", text );
|
||||
pEntity->GetValueAsString( "targetname", text, sizeof( text ) );
|
||||
pVMFEntity->SetValue( "targetname", text );
|
||||
pEntity->GetValueAsString( "origin", text, sizeof( text ) );
|
||||
pVMFEntity->SetValue( "origin", text );
|
||||
pEntity->GetValueAsString( "angles", text, sizeof( text ) );
|
||||
pVMFEntity->SetValue( "angles", text );
|
||||
|
||||
vmfEntities.AddToTail( pVMFEntity );
|
||||
|
||||
pEntity->MarkDirty(false);
|
||||
}
|
||||
}
|
||||
|
||||
// currently, don't overwrite the vmf, not sure if this is serializing correctly yet
|
||||
char tmpname[ 256 ];
|
||||
Q_StripExtension( m_pVMFFileName, tmpname, sizeof(tmpname) );
|
||||
Q_SetExtension( tmpname, ".vme", sizeof(tmpname) );
|
||||
|
||||
if (!g_pDataModel->SaveToFile( tmpname, NULL, "keyvalues", "vmf", pVMF ))
|
||||
{
|
||||
// needs some kind of error message
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
// If we successfully read the file in, ask it for the max hammer id
|
||||
int nMaxHammerId = pVMF->GetAttributeValue<int>( "maxHammerId" );
|
||||
CDmeVMFEntity::SetNextEntityId( nMaxHammerId + 1 );
|
||||
m_hVMFRoot = pVMF;
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CVcdBlockDoc::RememberPlayerPosition()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
108
tools/vcdblock/vcdblockdoc.h
Normal file
108
tools/vcdblock/vcdblockdoc.h
Normal file
@@ -0,0 +1,108 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef VCDBLOCKDOC_H
|
||||
#define VCDBLOCKDOC_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "dme_controls/inotifyui.h"
|
||||
#include "datamodel/dmehandle.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class IVcdBlockDocCallback;
|
||||
class CVcdBlockDoc;
|
||||
class CDmeVMFEntity;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Contains all editable state
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVcdBlockDoc : public IDmNotify
|
||||
{
|
||||
public:
|
||||
CVcdBlockDoc( IVcdBlockDocCallback *pCallback );
|
||||
~CVcdBlockDoc();
|
||||
|
||||
// Inherited from INotifyUI
|
||||
virtual void NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags );
|
||||
|
||||
// Sets/Gets the file name
|
||||
const char *GetBSPFileName();
|
||||
const char *GetVMFFileName();
|
||||
const char *GetEditFileName();
|
||||
void SetVMFFileName( const char *pFileName );
|
||||
void SetEditFileName( const char *pFileName );
|
||||
|
||||
// Dirty bits (has it changed since the last time it was saved?)
|
||||
void SetDirty( bool bDirty );
|
||||
bool IsDirty() const;
|
||||
|
||||
// Saves/loads from file
|
||||
bool LoadFromFile( const char *pFileName );
|
||||
void SaveToFile( );
|
||||
|
||||
// Returns the root object
|
||||
CDmElement *GetRootObject();
|
||||
|
||||
// Called when data changes (see INotifyUI for flags)
|
||||
void OnDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags );
|
||||
|
||||
// Create a text block the engine can parse containing the entity data to spawn
|
||||
void ServerLevelInitPostEntity( void );
|
||||
|
||||
// Returns the entity list
|
||||
CDmAttribute *GetEntityList();
|
||||
|
||||
// Adds a new info_target
|
||||
void AddNewInfoTarget( void );
|
||||
void AddNewInfoTarget( const Vector &vecOrigin, const QAngle &angAngles );
|
||||
|
||||
// Deletes a commentary node
|
||||
void DeleteInfoTarget( CDmeVMFEntity *pNode );
|
||||
|
||||
// Returns the commentary node at the specified location
|
||||
CDmeVMFEntity *GetInfoTargetForLocation( Vector &vecOrigin, QAngle &angAbsAngles );
|
||||
|
||||
// Returns the info target that's closest to this line
|
||||
CDmeVMFEntity *GetInfoTargetForLocation( Vector &vecStart, Vector &vecEnd );
|
||||
|
||||
// For element choice lists. Return false if it's an unknown choice list type
|
||||
virtual bool GetStringChoiceList( const char *pChoiceListType, CDmElement *pElement,
|
||||
const char *pAttributeName, bool bArrayElement, StringChoiceList_t &list );
|
||||
virtual bool GetElementChoiceList( const char *pChoiceListType, CDmElement *pElement,
|
||||
const char *pAttributeName, bool bArrayElement, ElementChoiceList_t &list );
|
||||
|
||||
|
||||
void VerifyAllEdits( const CDmrElementArray<> &entityList );
|
||||
void InitializeFromServer( CDmrElementArray<> &entityList );
|
||||
|
||||
bool CopyEditsToVMF( void );
|
||||
|
||||
bool RememberPlayerPosition( void );
|
||||
|
||||
private:
|
||||
IVcdBlockDocCallback *m_pCallback;
|
||||
CDmeHandle< CDmElement > m_hVMFRoot; // VMF file
|
||||
CDmeHandle< CDmElement > m_hEditRoot; // VMF Edits file
|
||||
char m_pBSPFileName[512];
|
||||
char m_pVMFFileName[512];
|
||||
char m_pEditFileName[512];
|
||||
bool m_bDirty;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // VCDBLOCKDOC_H
|
||||
1300
tools/vcdblock/vcdblocktool.cpp
Normal file
1300
tools/vcdblock/vcdblocktool.cpp
Normal file
File diff suppressed because it is too large
Load Diff
239
tools/vcdblock/vcdblocktool.h
Normal file
239
tools/vcdblock/vcdblocktool.h
Normal file
@@ -0,0 +1,239 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: VcdBlock tool; main UI smarts class
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VCDBLOCKTOOL_H
|
||||
#define VCDBLOCKTOOL_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "toolutils/basetoolsystem.h"
|
||||
#include "toolutils/recentfilelist.h"
|
||||
#include "toolutils/toolmenubar.h"
|
||||
#include "toolutils/toolswitchmenubutton.h"
|
||||
#include "toolutils/tooleditmenubutton.h"
|
||||
#include "toolutils/toolfilemenubutton.h"
|
||||
#include "toolutils/toolmenubutton.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "dmevmfentity.h"
|
||||
#include "toolframework/ienginetool.h"
|
||||
#include "toolutils/enginetools_int.h"
|
||||
#include "toolutils/savewindowpositions.h"
|
||||
#include "toolutils/toolwindowfactory.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmElement;
|
||||
class CVcdBlockDoc;
|
||||
class CInfoTargetPropertiesPanel;
|
||||
class CInfoTargetBrowserPanel;
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Allows the doc to call back into the VcdBlock editor tool
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IVcdBlockDocCallback
|
||||
{
|
||||
public:
|
||||
// Called by the doc when the data changes
|
||||
virtual void OnDocChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Global methods of the VCD Blocking tool
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IVcdBlockTool
|
||||
{
|
||||
public:
|
||||
// Gets at the rool panel (for modal dialogs)
|
||||
virtual vgui::Panel *GetRootPanel() = 0;
|
||||
|
||||
// Gets the registry name (for saving settings)
|
||||
virtual const char *GetRegistryName() = 0;
|
||||
|
||||
// Shows a particular entity in the entity properties dialog
|
||||
virtual void ShowEntityInEntityProperties( CDmeVMFEntity *pEntity ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation of the VcdBlock tool
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVcdBlockTool : public CBaseToolSystem, public IFileMenuCallbacks, public IVcdBlockDocCallback, public IVcdBlockTool
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CVcdBlockTool, CBaseToolSystem );
|
||||
|
||||
public:
|
||||
CVcdBlockTool();
|
||||
|
||||
// Inherited from IToolSystem
|
||||
virtual const char *GetToolName() { return "VCD Blocking Tool"; }
|
||||
virtual bool Init( );
|
||||
virtual void Shutdown();
|
||||
virtual bool CanQuit();
|
||||
virtual void OnToolActivate();
|
||||
virtual void OnToolDeactivate();
|
||||
virtual void ServerLevelInitPostEntity();
|
||||
virtual void DrawEntitiesInEngine( bool bDrawInEngine );
|
||||
virtual void ClientLevelInitPostEntity();
|
||||
virtual void ClientLevelShutdownPreEntity();
|
||||
virtual bool TrapKey( ButtonCode_t key, bool down );
|
||||
virtual void ClientPreRender();
|
||||
|
||||
// Inherited from IFileMenuCallbacks
|
||||
virtual int GetFileMenuItemsEnabled( );
|
||||
virtual void AddRecentFilesToMenu( vgui::Menu *menu );
|
||||
virtual bool GetPerforceFileName( char *pFileName, int nMaxLen );
|
||||
|
||||
// Inherited from IVcdBlockDocCallback
|
||||
virtual void OnDocChanged( const char *pReason, int nNotifySource, int nNotifyFlags );
|
||||
virtual vgui::Panel *GetRootPanel() { return this; }
|
||||
virtual void ShowEntityInEntityProperties( CDmeVMFEntity *pEntity );
|
||||
|
||||
// Inherited from CBaseToolSystem
|
||||
virtual vgui::HScheme GetToolScheme();
|
||||
virtual vgui::Menu *CreateActionMenu( vgui::Panel *pParent );
|
||||
virtual void OnCommand( const char *cmd );
|
||||
virtual const char *GetRegistryName() { return "VcdBlockTool"; }
|
||||
virtual const char *GetBindingsContextFile() { return "cfg/VcdBlock.kb"; }
|
||||
virtual vgui::MenuBar *CreateMenuBar( CBaseToolSystem *pParent );
|
||||
|
||||
MESSAGE_FUNC( Save, "OnSave" );
|
||||
void SaveAndTest();
|
||||
void RestartMap();
|
||||
|
||||
// Enter mode where we preview dropping nodes
|
||||
void EnterTargetDropMode();
|
||||
void LeaveTargetDropMode();
|
||||
|
||||
bool IsMiniViewportCursor( int x, int y, Vector &org, Vector &forward );
|
||||
|
||||
// Save/Load game state
|
||||
void SetRememberPlayerPosition( bool state = true ) { m_bRememberPlayerPosition = state; };
|
||||
bool GetRememberPlayerPosition( void ) { return m_bRememberPlayerPosition; };
|
||||
void QuickLoad();
|
||||
void QuickSave();
|
||||
|
||||
bool IsInNodeDrag( void ) { return m_bInNodeDragMode; };
|
||||
|
||||
public:
|
||||
MESSAGE_FUNC( OnRestartLevel, "RestartLevel" );
|
||||
MESSAGE_FUNC( OnNew, "OnNew" );
|
||||
MESSAGE_FUNC( OnOpen, "OnOpen" );
|
||||
MESSAGE_FUNC( OnSaveAs, "OnSaveAs" );
|
||||
MESSAGE_FUNC( OnClose, "OnClose" );
|
||||
MESSAGE_FUNC( OnCloseNoSave, "OnCloseNoSave" );
|
||||
MESSAGE_FUNC( OnMarkNotDirty, "OnMarkNotDirty" );
|
||||
MESSAGE_FUNC( OnExit, "OnExit" );
|
||||
|
||||
// Commands related to the edit menu
|
||||
void OnDescribeUndo();
|
||||
|
||||
// Methods related to the VcdBlock menu
|
||||
MESSAGE_FUNC( OnAddNewNodes, "AddNewNodes" );
|
||||
MESSAGE_FUNC( OnCopyEditsToVMF, "CopyEditsToVMF" );
|
||||
MESSAGE_FUNC( OnRememberPosition, "RememberPosition" );
|
||||
|
||||
// Methods related to the view menu
|
||||
MESSAGE_FUNC( OnToggleProperties, "OnToggleProperties" );
|
||||
MESSAGE_FUNC( OnToggleEntityReport, "OnToggleEntityReport" );
|
||||
MESSAGE_FUNC( OnDefaultLayout, "OnDefaultLayout" );
|
||||
|
||||
// Keybindings
|
||||
KEYBINDING_FUNC( undo, KEY_Z, vgui::MODIFIER_CONTROL, OnUndo, "#undo_help", 0 );
|
||||
KEYBINDING_FUNC( redo, KEY_Z, vgui::MODIFIER_CONTROL | vgui::MODIFIER_SHIFT, OnRedo, "#redo_help", 0 );
|
||||
KEYBINDING_FUNC_NODECLARE( VcdBlockAddNewNodes, KEY_A, vgui::MODIFIER_CONTROL, OnAddNewNodes, "#VcdBlockAddNewNodesHelp", 0 );
|
||||
|
||||
void OpenFileFromHistory( int slot );
|
||||
void OpenSpecificFile( const char *pFileName );
|
||||
virtual void SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues );
|
||||
virtual bool OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues );
|
||||
virtual bool OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues );
|
||||
virtual void OnFileOperationCompleted( const char *pFileType, bool bWroteFile, vgui::FileOpenStateMachine::CompletionState_t state, KeyValues *pContextKeyValues );
|
||||
|
||||
void AttachAllEngineEntities();
|
||||
|
||||
// returns the document
|
||||
CVcdBlockDoc *GetDocument();
|
||||
|
||||
// Gets at tool windows
|
||||
CInfoTargetPropertiesPanel *GetProperties();
|
||||
CInfoTargetBrowserPanel *GetInfoTargetBrowser();
|
||||
|
||||
CDmeHandle< CDmeVMFEntity > GetCurrentEntity( void ) { return m_hCurrentEntity; }
|
||||
|
||||
private:
|
||||
// Loads up a new document
|
||||
bool LoadDocument( const char *pDocName );
|
||||
|
||||
// Updates the menu bar based on the current file
|
||||
void UpdateMenuBar( );
|
||||
|
||||
// Shows element properties
|
||||
void ShowElementProperties( );
|
||||
|
||||
virtual const char *GetLogoTextureName();
|
||||
|
||||
// Creates, destroys tools
|
||||
void CreateTools( CVcdBlockDoc *doc );
|
||||
void DestroyTools();
|
||||
|
||||
// Initializes the tools
|
||||
void InitTools();
|
||||
|
||||
// Shows, toggles tool windows
|
||||
void ToggleToolWindow( Panel *tool, char const *toolName );
|
||||
void ShowToolWindow( Panel *tool, char const *toolName, bool visible );
|
||||
|
||||
// Kills all tool windows
|
||||
void DestroyToolContainers();
|
||||
|
||||
// Gets the position of the preview object
|
||||
void GetPlacementInfo( Vector &vecOrigin, QAngle &angles );
|
||||
|
||||
private:
|
||||
// Document
|
||||
CVcdBlockDoc *m_pDoc;
|
||||
|
||||
// The menu bar
|
||||
CToolFileMenuBar *m_pMenuBar;
|
||||
|
||||
// Element properties for editing material
|
||||
vgui::DHANDLE< CInfoTargetPropertiesPanel > m_hProperties;
|
||||
|
||||
// The entity report
|
||||
vgui::DHANDLE< CInfoTargetBrowserPanel > m_hInfoTargetBrowser;
|
||||
|
||||
// The currently viewed entity
|
||||
CDmeHandle< CDmeVMFEntity > m_hCurrentEntity;
|
||||
|
||||
// Separate undo context for the act busy tool
|
||||
bool m_bInNodeDropMode;
|
||||
bool m_bInNodeDragMode;
|
||||
int m_iDragX;
|
||||
int m_iDragY;
|
||||
CDmeHandle< CDmeVMFEntity > m_hPreviewTarget;
|
||||
CToolWindowFactory< ToolWindow > m_ToolWindowFactory;
|
||||
|
||||
// remembered player position
|
||||
bool m_bRememberPlayerPosition;
|
||||
bool m_bHasPlayerPosition;
|
||||
Vector m_vecPlayerOrigin;
|
||||
QAngle m_vecPlayerAngles;
|
||||
};
|
||||
|
||||
extern CVcdBlockTool *g_pVcdBlockTool;
|
||||
|
||||
#endif // VCDBLOCKTOOL_H
|
||||
Reference in New Issue
Block a user