mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
//========= 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 "foundrytool.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 );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeVMFEntity::OnConstruction()
|
||||
{
|
||||
m_ClassName.Init( this, "classname" );
|
||||
m_TargetName.Init( this, "targetname" );
|
||||
m_bIsPlaceholder.InitAndSet( this, "_placeholder", false, FATTRIB_DONTSAVE );
|
||||
m_vecLocalOrigin.Init( this, "origin" );
|
||||
m_vecLocalAngles.Init( this, "angles" );
|
||||
|
||||
// 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_hEngineEntity = HTOOLHANDLE_INVALID;
|
||||
|
||||
m_Wireframe.Init( "debug/debugwireframe", "editor" );
|
||||
}
|
||||
|
||||
void CDmeVMFEntity::OnDestruction()
|
||||
{
|
||||
// Unhook it from the engine
|
||||
AttachToEngineEntity( false );
|
||||
m_Wireframe.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the entity ID
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeVMFEntity::GetEntityId() const
|
||||
{
|
||||
return atoi( GetName() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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( bool bAttach )
|
||||
{
|
||||
if ( !bAttach )
|
||||
{
|
||||
m_hEngineEntity = HTOOLHANDLE_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws the helper for the entity
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeVMFEntity::DrawModel( int flags )
|
||||
{
|
||||
Assert( IsDrawingInEngine() );
|
||||
|
||||
matrix3x4_t mat;
|
||||
AngleMatrix( m_vecLocalAngles, m_vecLocalOrigin, mat );
|
||||
|
||||
CMatRenderContextPtr rc( g_pMaterialSystem->GetRenderContext() );
|
||||
|
||||
rc->MatrixMode( MATERIAL_MODEL );
|
||||
rc->PushMatrix();
|
||||
rc->LoadMatrix( mat );
|
||||
|
||||
int nTheta = 20, nPhi = 20;
|
||||
float flRadius = SPHERE_RADIUS;
|
||||
int nVertices = nTheta * nPhi;
|
||||
int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
|
||||
|
||||
rc->FogMode( MATERIAL_FOG_NONE );
|
||||
rc->SetNumBoneWeights( 0 );
|
||||
rc->Bind( m_Wireframe );
|
||||
rc->CullMode( MATERIAL_CULLMODE_CW );
|
||||
|
||||
IMesh* pMesh = rc->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
|
||||
|
||||
//
|
||||
// Build the index buffer.
|
||||
//
|
||||
int i, j;
|
||||
for ( i = 0; i < nPhi; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
float u = j / ( float )(nTheta - 1);
|
||||
float v = i / ( float )(nPhi - 1);
|
||||
float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
|
||||
float phi = M_PI * v;
|
||||
|
||||
Vector vecPos;
|
||||
vecPos.x = flRadius * sin(phi) * cos(theta);
|
||||
vecPos.y = flRadius * cos(phi);
|
||||
vecPos.z = -flRadius * sin(phi) * sin(theta);
|
||||
|
||||
unsigned char red = (int)( u * 255.0f );
|
||||
unsigned char green = (int)( v * 255.0f );
|
||||
unsigned char blue = (int)( v * 255.0f );
|
||||
unsigned char alpha = (int)( v * 255.0f );
|
||||
|
||||
meshBuilder.Position3fv( vecPos.Base() );
|
||||
meshBuilder.Color4ub( red, green, blue, alpha );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the triangle strips.
|
||||
//
|
||||
int idx = 0;
|
||||
for ( i = 0; i < nPhi - 1; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
idx = nTheta * i + j;
|
||||
|
||||
meshBuilder.FastIndex( idx );
|
||||
meshBuilder.FastIndex( idx + nTheta );
|
||||
}
|
||||
|
||||
//
|
||||
// Emit a degenerate triangle to skip to the next row without
|
||||
// a connecting triangle.
|
||||
//
|
||||
if ( i < nPhi - 2 )
|
||||
{
|
||||
meshBuilder.FastIndex( idx + 1 );
|
||||
meshBuilder.FastIndex( idx + 1 + nTheta );
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
|
||||
rc->CullMode( MATERIAL_CULLMODE_CCW );
|
||||
rc->MatrixMode( MATERIAL_MODEL );
|
||||
rc->PopMatrix();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Position and bounds for the model
|
||||
//-----------------------------------------------------------------------------
|
||||
const Vector &CDmeVMFEntity::GetRenderOrigin( void )
|
||||
{
|
||||
return m_vecLocalOrigin;
|
||||
}
|
||||
|
||||
const QAngle &CDmeVMFEntity::GetRenderAngles( void )
|
||||
{
|
||||
return m_vecLocalAngles;
|
||||
}
|
||||
|
||||
void CDmeVMFEntity::GetRenderBounds( Vector& mins, Vector& maxs )
|
||||
{
|
||||
mins.Init( -SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS );
|
||||
maxs.Init( SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS );
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//========= 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/dmerenderable.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "toolframework/itoolentity.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Represents an editable entity; draws its helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmeVMFEntity : public CDmeVisibilityControl< CDmeRenderable< CDmElement > >
|
||||
{
|
||||
DEFINE_ELEMENT( CDmeVMFEntity, CDmeVisibilityControl< CDmeRenderable< 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 void GetRenderBounds( Vector& mins, Vector& maxs );
|
||||
|
||||
public:
|
||||
int GetEntityId() const;
|
||||
|
||||
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( bool bAttach );
|
||||
|
||||
private:
|
||||
bool IsEntityKey( CDmAttribute *pEntityKey );
|
||||
|
||||
CDmaVar<Vector> m_vecLocalOrigin;
|
||||
CDmaVar<QAngle> m_vecLocalAngles;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
@@ -0,0 +1,639 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Singleton dialog that generates and presents the entity report.
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "EntityReportPanel.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 "dmevmfentity.h"
|
||||
#include "foundrydoc.h"
|
||||
#include "foundrytool.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
|
||||
//-----------------------------------------------------------------------------
|
||||
CEntityReportPanel::CEntityReportPanel( CFoundryDoc *pDoc, vgui::Panel* pParent, const char *pName )
|
||||
: BaseClass( pParent, pName ), m_pDoc( pDoc )
|
||||
{
|
||||
m_bSuppressEntityListUpdate = false;
|
||||
m_iFilterByType = FILTER_SHOW_EVERYTHING;
|
||||
m_bFilterByKeyvalue = false;
|
||||
m_bFilterByClass = false;
|
||||
m_bFilterByHidden = false;
|
||||
m_bFilterByKeyvalue = false;
|
||||
m_bExact = false;
|
||||
m_bFilterTextChanged = false;
|
||||
|
||||
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 Entities" );
|
||||
// m_pEntities->SetDragEnabled( true );
|
||||
m_pEntities->AddActionSignalTarget( this );
|
||||
m_pEntities->SetSortFunc( 0, TargetNameSortFunc );
|
||||
m_pEntities->SetSortFunc( 1, ClassNameSortFunc );
|
||||
m_pEntities->SetSortColumn( 0 );
|
||||
|
||||
// Filtering checkboxes
|
||||
m_pFilterByClass = new vgui::CheckButton( this, "ClassnameCheck", "" );
|
||||
m_pFilterByClass->AddActionSignalTarget( this );
|
||||
m_pFilterByKeyvalue = new vgui::CheckButton( this, "KeyvalueCheck", "" );
|
||||
m_pFilterByKeyvalue->AddActionSignalTarget( this );
|
||||
m_pFilterByHidden = new vgui::CheckButton( this, "HiddenCheck", "" );
|
||||
m_pFilterByHidden->AddActionSignalTarget( this );
|
||||
m_pExact = new vgui::CheckButton( this, "ExactCheck", "" );
|
||||
m_pExact->AddActionSignalTarget( this );
|
||||
|
||||
// Filtering text entries
|
||||
m_pFilterKey = new vgui::TextEntry( this, "KeyTextEntry" );
|
||||
m_pFilterValue = new vgui::TextEntry( this, "ValueTextEntry" );
|
||||
|
||||
// Classname combobox
|
||||
m_pFilterClass = new vgui::ComboBox( this, "ClassNameComboBox", 16, true );
|
||||
|
||||
// Filter by type radio buttons
|
||||
m_pFilterEverything = new vgui::RadioButton( this, "EverythingRadio", "" );
|
||||
m_pFilterPointEntities = new vgui::RadioButton( this, "PointRadio", "" );
|
||||
m_pFilterBrushModels = new vgui::RadioButton( this, "BrushRadio", "" );
|
||||
|
||||
LoadControlSettings( "resource/entityreportpanel.res" );
|
||||
|
||||
ReadSettingsFromRegistry();
|
||||
|
||||
// Used for updating filter while changing text
|
||||
ivgui()->AddTickSignal( GetVPanel(), 300 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads settings from registry
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::ReadSettingsFromRegistry()
|
||||
{
|
||||
m_bSuppressEntityListUpdate = true;
|
||||
|
||||
const char *pKeyBase = g_pFoundryTool->GetRegistryName();
|
||||
m_pFilterByKeyvalue->SetSelected( registry->ReadInt(pKeyBase, "FilterByKeyvalue", 0) );
|
||||
m_pFilterByClass->SetSelected( registry->ReadInt(pKeyBase, "FilterByClass", 0) );
|
||||
m_pFilterByHidden->SetSelected( registry->ReadInt(pKeyBase, "FilterByHidden", 1) );
|
||||
m_pExact->SetSelected( registry->ReadInt(pKeyBase, "Exact", 0) );
|
||||
|
||||
m_iFilterByType = (FilterType_t)registry->ReadInt(pKeyBase, "FilterByType", FILTER_SHOW_EVERYTHING);
|
||||
m_pFilterEverything->SetSelected( m_iFilterByType == FILTER_SHOW_EVERYTHING );
|
||||
m_pFilterPointEntities->SetSelected( m_iFilterByType == FILTER_SHOW_POINT_ENTITIES );
|
||||
m_pFilterBrushModels->SetSelected( m_iFilterByType == FILTER_SHOW_BRUSH_ENTITIES );
|
||||
|
||||
// Gotta call change functions manually since SetText doesn't post an action signal
|
||||
const char *pValue = registry->ReadString( pKeyBase, "FilterClass", "" );
|
||||
m_pFilterClass->SetText( pValue );
|
||||
OnChangeFilterclass( pValue );
|
||||
|
||||
pValue = registry->ReadString( pKeyBase, "FilterKey", "" );
|
||||
m_pFilterKey->SetText( pValue );
|
||||
OnChangeFilterkey( pValue );
|
||||
|
||||
pValue = registry->ReadString( pKeyBase, "FilterValue", "" );
|
||||
m_pFilterValue->SetText( pValue );
|
||||
OnChangeFiltervalue( pValue );
|
||||
|
||||
m_bSuppressEntityListUpdate = false;
|
||||
UpdateEntityList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes settings to registry
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::SaveSettingsToRegistry()
|
||||
{
|
||||
const char *pKeyBase = g_pFoundryTool->GetRegistryName();
|
||||
registry->WriteInt(pKeyBase, "FilterByKeyvalue", m_bFilterByKeyvalue);
|
||||
registry->WriteInt(pKeyBase, "FilterByClass", m_bFilterByClass);
|
||||
registry->WriteInt(pKeyBase, "FilterByHidden", m_bFilterByHidden);
|
||||
registry->WriteInt(pKeyBase, "FilterByType", m_iFilterByType);
|
||||
registry->WriteInt(pKeyBase, "Exact", m_bExact);
|
||||
|
||||
registry->WriteString(pKeyBase, "FilterClass", m_szFilterClass);
|
||||
registry->WriteString(pKeyBase, "FilterKey", m_szFilterKey);
|
||||
registry->WriteString(pKeyBase, "FilterValue", m_szFilterValue);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows the most recent selected object in properties window
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnProperties(void)
|
||||
{
|
||||
int iSel = m_pEntities->GetSelectedItem( 0 );
|
||||
KeyValues *kv = m_pEntities->GetItem( iSel );
|
||||
CDmeVMFEntity *pEntity = (CDmeVMFEntity *)kv->GetPtr( "entity" );
|
||||
g_pFoundryTool->ShowEntityInEntityProperties( pEntity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Deletes the marked objects.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnDeleteEntities(void)
|
||||
{
|
||||
// This is undoable
|
||||
CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Delete Entities", "Delete Entities" );
|
||||
|
||||
int iSel = m_pEntities->GetSelectedItem( 0 );
|
||||
|
||||
//
|
||||
// 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->DeleteEntity( pEntity );
|
||||
}
|
||||
}
|
||||
|
||||
guard.Release();
|
||||
|
||||
UpdateEntityList();
|
||||
|
||||
// Update the list box selection.
|
||||
if (iSel >= m_pEntities->GetItemCount())
|
||||
{
|
||||
iSel = m_pEntities->GetItemCount() - 1;
|
||||
}
|
||||
m_pEntities->SetSingleSelectedItem( iSel );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when buttons are clicked
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "delete" ) )
|
||||
{
|
||||
// Confirm we want to do it
|
||||
MessageBox *pConfirm = new MessageBox( "#FoundryDeleteObjects", "#FoundryDeleteObjectsMsg", g_pFoundryTool->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, "ShowProperties" ) )
|
||||
{
|
||||
OnProperties();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Call this when our settings are dirty
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::MarkDirty( bool bFilterDirty )
|
||||
{
|
||||
float flTime = Plat_FloatTime();
|
||||
m_bRegistrySettingsChanged = true;
|
||||
m_flRegistryTime = flTime;
|
||||
if ( bFilterDirty && !m_bFilterTextChanged )
|
||||
{
|
||||
m_bFilterTextChanged = true;
|
||||
m_flFilterTime = flTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods related to filtering
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnFilterByHidden( bool bState )
|
||||
{
|
||||
m_bFilterByHidden = bState;
|
||||
UpdateEntityList();
|
||||
MarkDirty( false );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnFilterByKeyvalue( bool bState )
|
||||
{
|
||||
m_bFilterByKeyvalue = bState;
|
||||
UpdateEntityList();
|
||||
MarkDirty( false );
|
||||
|
||||
m_pFilterKey->SetEnabled( bState );
|
||||
m_pFilterValue->SetEnabled( bState );
|
||||
m_pExact->SetEnabled( bState );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnFilterKeyValueExact( bool bState )
|
||||
{
|
||||
m_bExact = bState;
|
||||
UpdateEntityList();
|
||||
MarkDirty( false );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnFilterByType( FilterType_t type )
|
||||
{
|
||||
m_iFilterByType = type;
|
||||
UpdateEntityList();
|
||||
MarkDirty( false );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnFilterByClass( bool bState )
|
||||
{
|
||||
m_bFilterByClass = bState;
|
||||
UpdateEntityList();
|
||||
MarkDirty( false );
|
||||
|
||||
m_pFilterClass->SetEnabled( bState );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnChangeFilterkey( const char *pText )
|
||||
{
|
||||
m_szFilterKey = pText;
|
||||
MarkDirty( true );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnChangeFiltervalue( const char *pText )
|
||||
{
|
||||
m_szFilterValue = pText;
|
||||
MarkDirty( true );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnChangeFilterclass( const char *pText )
|
||||
{
|
||||
m_szFilterClass = pText;
|
||||
MarkDirty( true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deals with all check buttons
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnTextChanged( KeyValues *kv )
|
||||
{
|
||||
TextEntry *pPanel = (TextEntry*)kv->GetPtr( "panel", NULL );
|
||||
|
||||
int nLength = pPanel->GetTextLength();
|
||||
char *pBuf = (char*)_alloca( nLength + 1 );
|
||||
pPanel->GetText( pBuf, nLength+1 );
|
||||
|
||||
if ( pPanel == m_pFilterClass )
|
||||
{
|
||||
OnChangeFilterclass( pBuf );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pFilterKey )
|
||||
{
|
||||
OnChangeFilterkey( pBuf );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pFilterValue )
|
||||
{
|
||||
OnChangeFiltervalue( pBuf );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deals with all check buttons
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnButtonToggled( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel*)kv->GetPtr( "panel", NULL );
|
||||
bool bState = kv->GetInt( "state", 0 ) != 0;
|
||||
|
||||
if ( pPanel == m_pFilterByClass )
|
||||
{
|
||||
OnFilterByClass( bState );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pFilterByKeyvalue )
|
||||
{
|
||||
OnFilterByKeyvalue( bState );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pFilterByHidden )
|
||||
{
|
||||
OnFilterByHidden( bState );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pExact )
|
||||
{
|
||||
OnFilterKeyValueExact( bState );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pFilterEverything )
|
||||
{
|
||||
OnFilterByType( FILTER_SHOW_EVERYTHING );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pFilterPointEntities )
|
||||
{
|
||||
OnFilterByType( FILTER_SHOW_POINT_ENTITIES );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pFilterBrushModels )
|
||||
{
|
||||
OnFilterByType( FILTER_SHOW_BRUSH_ENTITIES );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FIXME: Necessary because SetSelected doesn't cause a ButtonToggled message to trigger
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnCheckButtonChecked( KeyValues *kv )
|
||||
{
|
||||
OnButtonToggled( kv );
|
||||
}
|
||||
|
||||
void CEntityReportPanel::OnRadioButtonChecked( KeyValues *kv )
|
||||
{
|
||||
OnButtonToggled( kv );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Centers the 2D and 3D views on the selected entities.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnGoto()
|
||||
{
|
||||
MarkSelectedEntities();
|
||||
m_pDoc->CenterViewsOnSelection();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::MarkSelectedEntities()
|
||||
{
|
||||
m_pDoc->SelectObject(NULL, CMapDoc::scClear);
|
||||
|
||||
for(int i = 0; i < m_cEntities.GetCount(); i++)
|
||||
{
|
||||
if(!m_cEntities.GetSel(i))
|
||||
continue;
|
||||
CMapEntity *pEntity = (CMapEntity*) m_cEntities.GetItemDataPtr(i);
|
||||
m_pDoc->SelectObject(pEntity, CMapDoc::scSelect);
|
||||
}
|
||||
|
||||
m_pDoc->SelectObject(NULL, CMapDoc::scUpdateDisplay);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void CEntityReportPanel::OnTick( )
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
// check filters
|
||||
float flTime = Plat_FloatTime();
|
||||
if ( m_bFilterTextChanged )
|
||||
{
|
||||
if ( (flTime - m_flFilterTime) > 1e-3 )
|
||||
{
|
||||
m_bFilterTextChanged = false;
|
||||
m_flFilterTime = flTime;
|
||||
UpdateEntityList();
|
||||
}
|
||||
}
|
||||
if ( m_bRegistrySettingsChanged )
|
||||
{
|
||||
if ( (flTime - m_flRegistryTime) > 1e-3 )
|
||||
{
|
||||
m_bRegistrySettingsChanged = false;
|
||||
m_flRegistryTime = flTime;
|
||||
SaveSettingsToRegistry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CEntityReportPanel::ShouldAddEntityToList( CDmeVMFEntity *pEntity )
|
||||
{
|
||||
// nope.
|
||||
if ( !m_bFilterByHidden && !pEntity->IsVisible() )
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (!pDlg->m_pDoc->selection.IsEmpty() && !pEntity->IsSelected())
|
||||
return true;
|
||||
*/
|
||||
|
||||
if ( m_iFilterByType == FILTER_SHOW_POINT_ENTITIES && pEntity->IsPlaceholder() )
|
||||
return false;
|
||||
|
||||
if ( m_iFilterByType == FILTER_SHOW_BRUSH_ENTITIES && !pEntity->IsPlaceholder() )
|
||||
return false;
|
||||
|
||||
const char* pClassName = pEntity->GetClassName();
|
||||
|
||||
if ( m_bFilterByClass )
|
||||
{
|
||||
if ( !m_szFilterClass.IsEmpty() )
|
||||
{
|
||||
if ( !Q_stristr( pClassName, m_szFilterClass ) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !m_bFilterByKeyvalue || m_szFilterValue.IsEmpty() )
|
||||
return true;
|
||||
|
||||
CUtlBuffer buf( 256, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
for ( CDmAttribute *pKey = pEntity->FirstEntityKey(); pKey; pKey = pEntity->NextEntityKey( pKey ) )
|
||||
{
|
||||
// first, check key
|
||||
if ( m_szFilterKey.IsEmpty() || !Q_stricmp( m_szFilterKey, pKey->GetName() ) )
|
||||
{
|
||||
// now, check value (as a string)
|
||||
buf.Clear();
|
||||
pKey->Serialize( buf );
|
||||
const char *pValue = (const char*)buf.Base();
|
||||
if ( (!m_bExact && Q_stristr( pValue, m_szFilterValue ) ) || !Q_stricmp( pValue, m_szFilterValue ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::UpdateEntityList(void)
|
||||
{
|
||||
if ( m_bSuppressEntityListUpdate )
|
||||
return;
|
||||
|
||||
m_bFilterTextChanged = false;
|
||||
|
||||
m_pEntities->RemoveAll();
|
||||
|
||||
const CDmrElementArray<CDmElement> entityList( m_pDoc->GetEntityList() );
|
||||
int nCount = entityList.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeVMFEntity *pEntity = CastElement<CDmeVMFEntity>( entityList[i] );
|
||||
if ( ShouldAddEntityToList( pEntity ) )
|
||||
{
|
||||
const char *pClassName = pEntity->GetClassName( );
|
||||
const char *pTargetName = pEntity->GetTargetName( );
|
||||
if ( !pTargetName || !pTargetName[0] )
|
||||
{
|
||||
pTargetName = "<no name>";
|
||||
}
|
||||
if ( !pClassName || !pClassName[0] )
|
||||
{
|
||||
pClassName = "<no class>";
|
||||
}
|
||||
|
||||
KeyValues *kv = new KeyValues( "node", "targetname", pTargetName );
|
||||
kv->SetString( "classname", pClassName );
|
||||
kv->SetPtr( "entity", pEntity );
|
||||
|
||||
m_pEntities->AddItem( kv, 0, false, false );
|
||||
}
|
||||
}
|
||||
m_pEntities->SortList();
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::GenerateReport()
|
||||
{
|
||||
POSITION p = pGD->Classes.GetHeadPosition();
|
||||
CString str;
|
||||
while(p)
|
||||
{
|
||||
GDclass *pc = pGD->Classes.GetNext(p);
|
||||
if(!pc->IsBaseClass())
|
||||
{
|
||||
str = pc->GetName();
|
||||
if(str != "worldspawn")
|
||||
m_cFilterClass.AddString(str);
|
||||
}
|
||||
}
|
||||
|
||||
SetTimer(1, 500, NULL);
|
||||
|
||||
OnFilterbykeyvalue();
|
||||
OnFilterbytype();
|
||||
OnFilterbyclass();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnSelChangeEntityList()
|
||||
{
|
||||
MarkSelectedEntities();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnDblClkEntityList()
|
||||
{
|
||||
m_pDoc->CenterViewsOnSelection();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnOK()
|
||||
{
|
||||
DestroyWindow();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnClose()
|
||||
{
|
||||
DestroyWindow();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when our window is being destroyed.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEntityReportPanel::OnDestroy()
|
||||
{
|
||||
SaveToIni();
|
||||
s_pDlg = NULL;
|
||||
delete this;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef ENTITYREPORTPANEL_H
|
||||
#define ENTITYREPORTPANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vgui_controls/editablepanel.h"
|
||||
#include "tier1/utlstring.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFoundryDoc;
|
||||
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 CEntityReportPanel : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CEntityReportPanel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CEntityReportPanel( CFoundryDoc *pDoc, vgui::Panel* pParent, const char *pName ); // standard constructor
|
||||
|
||||
// Inherited from Panel
|
||||
virtual void OnTick();
|
||||
virtual void OnCommand( const char *pCommand );
|
||||
|
||||
private:
|
||||
enum FilterType_t
|
||||
{
|
||||
FILTER_SHOW_EVERYTHING = 0,
|
||||
FILTER_SHOW_POINT_ENTITIES = 1,
|
||||
FILTER_SHOW_BRUSH_ENTITIES = 2
|
||||
};
|
||||
|
||||
// Messages handled
|
||||
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", kv );
|
||||
MESSAGE_FUNC_PARAMS( OnButtonToggled, "ButtonToggled", kv );
|
||||
MESSAGE_FUNC( OnDeleteEntities, "DeleteEntities" );
|
||||
|
||||
// FIXME: Necessary because SetSelected doesn't cause a ButtonToggled message to trigger
|
||||
MESSAGE_FUNC_PARAMS( OnCheckButtonChecked, "CheckButtonChecked", kv );
|
||||
MESSAGE_FUNC_PARAMS( OnRadioButtonChecked, "RadioButtonChecked", kv );
|
||||
|
||||
// Methods related to filtering
|
||||
void OnFilterByHidden( bool bState );
|
||||
void OnFilterByKeyvalue( bool bState );
|
||||
void OnFilterByClass( bool bState );
|
||||
void OnFilterKeyValueExact( bool bState );
|
||||
void OnFilterByType( FilterType_t type );
|
||||
void OnChangeFilterkey( const char *pText );
|
||||
void OnChangeFiltervalue( const char *pText );
|
||||
void OnChangeFilterclass( const char *pText );
|
||||
|
||||
// Methods related to updating the listpanel
|
||||
void UpdateEntityList();
|
||||
bool ShouldAddEntityToList( CDmeVMFEntity *pEntity );
|
||||
|
||||
// Methods related to saving settings
|
||||
void ReadSettingsFromRegistry();
|
||||
void SaveSettingsToRegistry();
|
||||
|
||||
// Call this when our settings are dirty
|
||||
void MarkDirty( bool bFilterDirty );
|
||||
|
||||
// Shows the most recent selected object in properties window
|
||||
void OnProperties();
|
||||
|
||||
CFoundryDoc *m_pDoc;
|
||||
FilterType_t m_iFilterByType;
|
||||
bool m_bFilterByClass;
|
||||
bool m_bFilterByHidden;
|
||||
bool m_bFilterByKeyvalue;
|
||||
bool m_bExact;
|
||||
bool m_bSuppressEntityListUpdate;
|
||||
|
||||
CUtlString m_szFilterKey;
|
||||
CUtlString m_szFilterValue;
|
||||
CUtlString m_szFilterClass;
|
||||
|
||||
bool m_bFilterTextChanged;
|
||||
float m_flFilterTime;
|
||||
|
||||
bool m_bRegistrySettingsChanged;
|
||||
float m_flRegistryTime;
|
||||
|
||||
vgui::CheckButton *m_pExact;
|
||||
vgui::ComboBox *m_pFilterClass;
|
||||
vgui::CheckButton *m_pFilterByClass;
|
||||
vgui::ListPanel *m_pEntities;
|
||||
vgui::TextEntry *m_pFilterKey;
|
||||
vgui::TextEntry *m_pFilterValue;
|
||||
vgui::CheckButton *m_pFilterByKeyvalue;
|
||||
vgui::CheckButton *m_pFilterByHidden;
|
||||
|
||||
vgui::RadioButton *m_pFilterEverything;
|
||||
vgui::RadioButton *m_pFilterPointEntities;
|
||||
vgui::RadioButton *m_pFilterBrushModels;
|
||||
};
|
||||
|
||||
|
||||
#endif // ENTITYREPORTPANEL_H
|
||||
@@ -0,0 +1,67 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// FOUNDRY.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin\tools"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,.\,$SRCDIR\game\shared"
|
||||
$PreprocessorDefinitions "$BASE;FOUNDRY_EXPORTS"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE Psapi.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "foundry"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "DmeVMFEntity.cpp"
|
||||
$File "DmeVMFEntity.h"
|
||||
$File "entityreportpanel.cpp"
|
||||
$File "entityreportpanel.h"
|
||||
$File "foundrydoc.cpp"
|
||||
$File "foundrytool.cpp"
|
||||
$File "$SRCDIR\public\interpolatortypes.cpp"
|
||||
$File "$SRCDIR\public\registry.cpp"
|
||||
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "foundrydoc.h"
|
||||
$File "foundrytool.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib datamodel
|
||||
$Lib dmxloader
|
||||
$Lib dme_controls
|
||||
$Lib dmserializers
|
||||
$Lib mathlib
|
||||
$Lib matsys_controls
|
||||
$Lib movieobjects
|
||||
$Lib sfmobjects
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
$Lib toolutils
|
||||
$Lib vgui_controls
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "foundrydoc.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "toolutils/enginetools_int.h"
|
||||
#include "filesystem.h"
|
||||
#include "foundrytool.h"
|
||||
#include "toolframework/ienginetool.h"
|
||||
#include "dmevmfentity.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFoundryDoc::CFoundryDoc( IFoundryDocCallback *pCallback ) : m_pCallback( pCallback )
|
||||
{
|
||||
m_hRoot = NULL;
|
||||
m_pBSPFileName[0] = 0;
|
||||
m_pVMFFileName[0] = 0;
|
||||
m_bDirty = false;
|
||||
g_pDataModel->InstallNotificationCallback( this );
|
||||
}
|
||||
|
||||
CFoundryDoc::~CFoundryDoc()
|
||||
{
|
||||
g_pDataModel->RemoveNotificationCallback( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inherited from INotifyUI
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFoundryDoc::NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags )
|
||||
{
|
||||
OnDataChanged( pReason, nNotifySource, nNotifyFlags );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the file name
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CFoundryDoc::GetBSPFileName()
|
||||
{
|
||||
return m_pBSPFileName;
|
||||
}
|
||||
|
||||
const char *CFoundryDoc::GetVMFFileName()
|
||||
{
|
||||
return m_pVMFFileName;
|
||||
}
|
||||
|
||||
void CFoundryDoc::SetVMFFileName( const char *pFileName )
|
||||
{
|
||||
Q_strncpy( m_pVMFFileName, pFileName, sizeof( m_pVMFFileName ) );
|
||||
Q_FixSlashes( m_pVMFFileName );
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dirty bits
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFoundryDoc::SetDirty( bool bDirty )
|
||||
{
|
||||
m_bDirty = bDirty;
|
||||
}
|
||||
|
||||
bool CFoundryDoc::IsDirty() const
|
||||
{
|
||||
return m_bDirty;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Saves/loads from file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFoundryDoc::LoadFromFile( const char *pFileName )
|
||||
{
|
||||
Assert( !m_hRoot.Get() );
|
||||
|
||||
// This is not undoable
|
||||
CAppDisableUndoScopeGuard guard( "CFoundryDoc::LoadFromFile", 0 );
|
||||
SetDirty( false );
|
||||
|
||||
if ( !pFileName[0] )
|
||||
return false;
|
||||
|
||||
// Store the BSP file name
|
||||
Q_strncpy( m_pBSPFileName, pFileName, sizeof( m_pBSPFileName ) );
|
||||
|
||||
// Construct VMF file name from the BSP
|
||||
const char *pGame = Q_stristr( pFileName, "\\game\\" );
|
||||
if ( !pGame )
|
||||
return false;
|
||||
|
||||
// Compute the map name
|
||||
char mapname[ 256 ];
|
||||
const char *pMaps = Q_stristr( pFileName, "\\maps\\" );
|
||||
if ( !pMaps )
|
||||
return false;
|
||||
|
||||
Q_strncpy( mapname, pMaps + 6, sizeof( 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) );
|
||||
|
||||
CDmElement *pVMF = NULL;
|
||||
if ( g_pDataModel->RestoreFromFile( m_pVMFFileName, NULL, "vmf", &pVMF ) == DMFILEID_INVALID )
|
||||
{
|
||||
m_pBSPFileName[0] = 0;
|
||||
m_pVMFFileName[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hRoot = pVMF;
|
||||
|
||||
guard.Release();
|
||||
SetDirty( false );
|
||||
|
||||
char cmd[ 256 ];
|
||||
Q_snprintf( cmd, sizeof( cmd ), "disconnect; map %s\n", mapname );
|
||||
enginetools->Command( cmd );
|
||||
enginetools->Execute( );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CFoundryDoc::SaveToFile( )
|
||||
{
|
||||
if ( m_hRoot.Get() && m_pVMFFileName && m_pVMFFileName[0] )
|
||||
{
|
||||
g_pDataModel->SaveToFile( m_pVMFFileName, NULL, "keyvalues", "vmf", m_hRoot );
|
||||
}
|
||||
|
||||
SetDirty( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the root object
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement *CFoundryDoc::GetRootObject()
|
||||
{
|
||||
return m_hRoot;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the entity list
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmAttribute *CFoundryDoc::GetEntityList()
|
||||
{
|
||||
return m_hRoot ? m_hRoot->GetAttribute( "entities", AT_ELEMENT_ARRAY ) : NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deletes an entity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFoundryDoc::DeleteEntity( CDmeVMFEntity *pEntity )
|
||||
{
|
||||
CDmrElementArray<> entities( GetEntityList() );
|
||||
if ( !entities.IsValid() )
|
||||
return;
|
||||
|
||||
int nCount = entities.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
if ( pEntity == CastElement< CDmeVMFEntity >( entities[i] ) )
|
||||
{
|
||||
entities.FastRemove( i );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when data changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFoundryDoc::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
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Always copy the worldspawn and other entities that had data built into them by VBSP out
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFoundryDoc::AddOriginalEntities( CUtlBuffer &entityBuf, const char *pActualEntityData )
|
||||
{
|
||||
while ( *pActualEntityData )
|
||||
{
|
||||
pActualEntityData = strchr( pActualEntityData, '{' );
|
||||
if ( !pActualEntityData )
|
||||
break;
|
||||
|
||||
const char *pBlockStart = pActualEntityData;
|
||||
|
||||
pActualEntityData = strstr( pActualEntityData, "\"classname\"" );
|
||||
if ( !pActualEntityData )
|
||||
break;
|
||||
|
||||
// Skip "classname"
|
||||
pActualEntityData += 11;
|
||||
|
||||
pActualEntityData = strchr( pActualEntityData, '\"' );
|
||||
if ( !pActualEntityData )
|
||||
break;
|
||||
|
||||
// Skip "
|
||||
++pActualEntityData;
|
||||
|
||||
char pClassName[512];
|
||||
int j = 0;
|
||||
while (*pActualEntityData != 0 && *pActualEntityData != '\"' )
|
||||
{
|
||||
pClassName[j++] = *pActualEntityData++;
|
||||
}
|
||||
pClassName[j] = 0;
|
||||
|
||||
pActualEntityData = strchr( pActualEntityData, '}' );
|
||||
if ( !pActualEntityData )
|
||||
break;
|
||||
|
||||
// Skip }
|
||||
++pActualEntityData;
|
||||
|
||||
for ( int i = 0; s_pUseOriginalClasses[i]; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pClassName, s_pUseOriginalClasses[i] ) )
|
||||
{
|
||||
// Found one we need to keep, add it to the buffer
|
||||
int nBytes = (int)( (size_t)pActualEntityData - (size_t)pBlockStart );
|
||||
entityBuf.Put( pBlockStart, nBytes );
|
||||
entityBuf.PutChar( '\n' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copy in other entities from the editable VMF
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFoundryDoc::AddVMFEntities( CUtlBuffer &entityBuf, const char *pActualEntityData )
|
||||
{
|
||||
const CDmrElementArray<CDmElement> entityArray( m_hRoot, "entities" );
|
||||
if ( !entityArray.IsValid() )
|
||||
return;
|
||||
|
||||
int nCount = entityArray.Count();
|
||||
for ( int iEntity = 0; iEntity < nCount; ++iEntity )
|
||||
{
|
||||
CDmElement *pEntity = entityArray[iEntity];
|
||||
const char *pClassName = pEntity->GetValueString( "classname" );
|
||||
if ( !pClassName || !pClassName[0] )
|
||||
continue;
|
||||
|
||||
// Don't spawn those classes we grab from the actual compiled map
|
||||
bool bDontUse = false;
|
||||
for ( int i = 0; s_pUseOriginalClasses[i]; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pClassName, s_pUseOriginalClasses[i] ) )
|
||||
{
|
||||
bDontUse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bDontUse )
|
||||
continue;
|
||||
|
||||
entityBuf.PutString( "{\n" );
|
||||
entityBuf.Printf( "\"id\" \"%d\"\n", atol( pEntity->GetName() ) );
|
||||
|
||||
for( CDmAttribute *pAttribute = pEntity->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) )
|
||||
continue;
|
||||
|
||||
if ( IsArrayType( pAttribute->GetType() ) )
|
||||
continue;
|
||||
|
||||
if ( !Q_stricmp( pAttribute->GetName(), "editorType" ) || !Q_stricmp( pAttribute->GetName(), "editor" ) )
|
||||
continue;
|
||||
|
||||
entityBuf.Printf( "\"%s\" ", pAttribute->GetName() );
|
||||
|
||||
// FIXME: Set up standard delimiters
|
||||
entityBuf.PutChar( '\"' );
|
||||
pAttribute->Serialize( entityBuf );
|
||||
entityBuf.PutString( "\"\n" );
|
||||
}
|
||||
|
||||
entityBuf.PutString( "}\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create a text block the engine can parse containing the entity data to spawn
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* CFoundryDoc::GenerateEntityData( const char *pActualEntityData )
|
||||
{
|
||||
if ( !m_hRoot.Get() )
|
||||
return pActualEntityData;
|
||||
|
||||
// Contains the text block the engine can parse containing the entity data to spawn
|
||||
static CUtlBuffer entityBuf( 2048, 2048, CUtlBuffer::TEXT_BUFFER );
|
||||
entityBuf.Clear();
|
||||
|
||||
// Always copy the worldspawn and other entities that had data built into them by VBSP out
|
||||
AddOriginalEntities( entityBuf, pActualEntityData );
|
||||
|
||||
// Copy in other entities from the editable VMF
|
||||
AddVMFEntities( entityBuf, pActualEntityData );
|
||||
|
||||
return (const char*)entityBuf.Base();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef FOUNDRYDOC_H
|
||||
#define FOUNDRYDOC_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "dme_controls/inotifyui.h"
|
||||
#include "datamodel/dmehandle.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class IFoundryDocCallback;
|
||||
class CDmeVMFEntity;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Contains all editable state
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFoundryDoc : public IDmNotify
|
||||
{
|
||||
public:
|
||||
CFoundryDoc( IFoundryDocCallback *pCallback );
|
||||
~CFoundryDoc();
|
||||
|
||||
// Inherited from INotifyUI
|
||||
virtual void NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags );
|
||||
|
||||
// Sets/Gets the file name
|
||||
const char *GetBSPFileName();
|
||||
const char *GetVMFFileName();
|
||||
void SetVMFFileName( 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
|
||||
const char* GenerateEntityData( const char *pActualEntityData );
|
||||
|
||||
// Returns the entity list
|
||||
CDmAttribute *GetEntityList();
|
||||
|
||||
// Deletes an entity
|
||||
void DeleteEntity( CDmeVMFEntity *pEntity );
|
||||
|
||||
private:
|
||||
// Always copy the worldspawn and other entities that had data built into them by VBSP out
|
||||
void AddOriginalEntities( CUtlBuffer &entityBuf, const char *pActualEntityData );
|
||||
|
||||
// Copy in other entities from the editable VMF
|
||||
void AddVMFEntities( CUtlBuffer &entityBuf, const char *pActualEntityData );
|
||||
|
||||
IFoundryDocCallback *m_pCallback;
|
||||
CDmeHandle< CDmElement > m_hRoot;
|
||||
char m_pBSPFileName[512];
|
||||
char m_pVMFFileName[512];
|
||||
bool m_bDirty;
|
||||
};
|
||||
|
||||
|
||||
#endif // FOUNDRYDOC_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Foundry tool; main UI smarts class
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef FOUNDRYTOOL_H
|
||||
#define FOUNDRYTOOL_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmeEditorTypeDictionary;
|
||||
class CDmeVMFEntity;
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
extern CDmeEditorTypeDictionary *g_pEditorTypeDict;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Allows the doc to call back into the Foundry editor tool
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IFoundryDocCallback
|
||||
{
|
||||
public:
|
||||
// Called by the doc when the data changes
|
||||
virtual void OnDocChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Global methods of the foundry tool
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IFoundryTool
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
extern IFoundryTool *g_pFoundryTool;
|
||||
|
||||
|
||||
#endif // FOUNDRYTOOL_H
|
||||
Reference in New Issue
Block a user