From 3bf9df6b2785fa6d951086978a3e66f49427166a Mon Sep 17 00:00:00 2001 From: FluorescentCIAAfricanAmerican <0934gj3049fk@protonmail.com> Date: Wed, 22 Apr 2020 12:56:21 -0400 Subject: 1 --- tools/commedit/commeditdoc.cpp | 443 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 443 insertions(+) create mode 100644 tools/commedit/commeditdoc.cpp (limited to 'tools/commedit/commeditdoc.cpp') diff --git a/tools/commedit/commeditdoc.cpp b/tools/commedit/commeditdoc.cpp new file mode 100644 index 0000000..6ebd5fd --- /dev/null +++ b/tools/commedit/commeditdoc.cpp @@ -0,0 +1,443 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "commeditdoc.h" +#include "tier1/KeyValues.h" +#include "tier1/utlbuffer.h" +#include "toolutils/enginetools_int.h" +#include "filesystem.h" +#include "commedittool.h" +#include "toolframework/ienginetool.h" +#include "dmecommentarynodeentity.h" +#include "datamodel/idatamodel.h" +#include "toolutils/attributeelementchoicelist.h" +#include "commentarynodebrowserpanel.h" +#include "vgui_controls/messagebox.h" + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CCommEditDoc::CCommEditDoc( ICommEditDocCallback *pCallback ) : m_pCallback( pCallback ) +{ + m_hRoot = NULL; + m_pTXTFileName[0] = 0; + m_bDirty = false; + g_pDataModel->InstallNotificationCallback( this ); +} + +CCommEditDoc::~CCommEditDoc() +{ + g_pDataModel->RemoveNotificationCallback( this ); +} + + +//----------------------------------------------------------------------------- +// Inherited from INotifyUI +//----------------------------------------------------------------------------- +void CCommEditDoc::NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) +{ + OnDataChanged( pReason, nNotifySource, nNotifyFlags ); +} + + +//----------------------------------------------------------------------------- +// Gets the file name +//----------------------------------------------------------------------------- +const char *CCommEditDoc::GetTXTFileName() +{ + return m_pTXTFileName; +} + +void CCommEditDoc::SetTXTFileName( const char *pFileName ) +{ + Q_strncpy( m_pTXTFileName, pFileName, sizeof( m_pTXTFileName ) ); + Q_FixSlashes( m_pTXTFileName ); + SetDirty( true ); +} + +//----------------------------------------------------------------------------- +// Dirty bits +//----------------------------------------------------------------------------- +void CCommEditDoc::SetDirty( bool bDirty ) +{ + m_bDirty = bDirty; +} + +bool CCommEditDoc::IsDirty() const +{ + return m_bDirty; +} + + +//----------------------------------------------------------------------------- +// Handles creation of the right element for a keyvalue +//----------------------------------------------------------------------------- +class CElementForKeyValueCallback : public IElementForKeyValueCallback +{ +public: + const char *GetElementForKeyValue( const char *pszKeyName, int iNestingLevel ) + { + if ( iNestingLevel == 1 && !Q_strncmp(pszKeyName, "entity", 6) ) + return "DmeCommentaryNodeEntity"; + + return NULL; + } +}; + +//----------------------------------------------------------------------------- +// Saves/loads from file +//----------------------------------------------------------------------------- +bool CCommEditDoc::LoadFromFile( const char *pFileName ) +{ + Assert( !m_hRoot.Get() ); + + CAppDisableUndoScopeGuard guard( "CCommEditDoc::LoadFromFile", 0 ); + SetDirty( false ); + + if ( !pFileName[0] ) + return false; + + char mapname[ 256 ]; + + // Compute the map name + const char *pMaps = Q_stristr( pFileName, "\\maps\\" ); + if ( !pMaps ) + return false; + + // Build map name + //int nNameLen = (int)( (size_t)pComm - (size_t)pMaps ) - 5; + Q_StripExtension( pFileName, mapname, sizeof(mapname) ); + char *pszFileName = (char*)Q_UnqualifiedFileName(mapname); + + // Set the txt file name. + // If we loaded an existing commentary file, keep the same filename. + // If we loaded a .bsp, change the name & the extension. + if ( !V_stricmp( Q_GetFileExtension( pFileName ), "bsp" ) ) + { + const char *pCommentaryAppend = "_commentary.txt"; + Q_StripExtension( pFileName, m_pTXTFileName, sizeof(m_pTXTFileName)- strlen(pCommentaryAppend) - 1 ); + Q_strcat( m_pTXTFileName, pCommentaryAppend, sizeof( m_pTXTFileName ) ); + + if ( g_pFileSystem->FileExists( m_pTXTFileName ) ) + { + char pBuf[1024]; + Q_snprintf( pBuf, sizeof(pBuf), "File %s already exists!\n", m_pTXTFileName ); + m_pTXTFileName[0] = 0; + vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Unable to overwrite file!\n", pBuf, g_pCommEditTool ); + pMessageBox->DoModal( ); + return false; + } + + DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( m_pTXTFileName ); + + m_hRoot = CreateElement( "root", fileid ); + CDmrElementArray<> subkeys( m_hRoot->AddAttribute( "subkeys", AT_ELEMENT_ARRAY ) ); + CDmElement *pRoot2 = CreateElement( "Entities", fileid ); + pRoot2->AddAttribute( "subkeys", AT_ELEMENT_ARRAY ); + subkeys.AddToTail( pRoot2 ); + g_pDataModel->SetFileRoot( fileid, m_hRoot ); + } + else + { + char *pComm = Q_stristr( pszFileName, "_commentary" ); + if ( !pComm ) + { + char pBuf[1024]; + Q_snprintf( pBuf, sizeof(pBuf), "File %s is not a commentary file!\nThe file name must end in _commentary.txt.\n", m_pTXTFileName ); + m_pTXTFileName[0] = 0; + vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Bad file name!\n", pBuf, g_pCommEditTool ); + pMessageBox->DoModal( ); + return false; + } + + // Clip off the "_commentary" at the end of the filename + *pComm = '\0'; + + // This is not undoable + CDisableUndoScopeGuard guardFile; + + CDmElement *pTXT = NULL; + + CElementForKeyValueCallback KeyValuesCallback; + g_pDataModel->SetKeyValuesElementCallback( &KeyValuesCallback ); + DmFileId_t fileid = g_pDataModel->RestoreFromFile( pFileName, NULL, "keyvalues", &pTXT ); + g_pDataModel->SetKeyValuesElementCallback( NULL ); + + if ( fileid == DMFILEID_INVALID ) + { + m_pTXTFileName[0] = 0; + return false; + } + + SetTXTFileName( pFileName ); + m_hRoot = pTXT; + } + + guard.Release(); + SetDirty( false ); + + char cmd[ 256 ]; + Q_snprintf( cmd, sizeof( cmd ), "disconnect; map %s\n", pszFileName ); + enginetools->Command( cmd ); + enginetools->Execute( ); + + return true; +} + +void CCommEditDoc::SaveToFile( ) +{ + if ( m_hRoot.Get() && m_pTXTFileName && m_pTXTFileName[0] ) + { + g_pDataModel->SaveToFile( m_pTXTFileName, NULL, "keyvalues", "keyvalues", m_hRoot ); + } + + SetDirty( false ); +} + + +//----------------------------------------------------------------------------- +// Returns the root object +//----------------------------------------------------------------------------- +CDmElement *CCommEditDoc::GetRootObject() +{ + return m_hRoot; +} + + +//----------------------------------------------------------------------------- +// Returns the entity list +//----------------------------------------------------------------------------- +CDmAttribute *CCommEditDoc::GetEntityList() +{ + CDmrElementArray<> mainKeys( m_hRoot, "subkeys" ); + if ( !mainKeys.IsValid() || mainKeys.Count() == 0 ) + return NULL; + CDmeHandle hEntityList; + hEntityList = mainKeys[ 0 ]; + return hEntityList ? hEntityList->GetAttribute( "subkeys", AT_ELEMENT_ARRAY ) : NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCommEditDoc::AddNewInfoTarget( const Vector &vecOrigin, const QAngle &angAngles ) +{ + CDmrCommentaryNodeEntityList entities( GetEntityList() ); + if ( !entities.IsValid() ) + return; + + CDmeCommentaryNodeEntity *pTarget; + { + CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Add Info Target", "Add Info Target" ); + + pTarget = CreateElement( "target", entities.GetOwner()->GetFileId() ); + pTarget->SetName( "entity" ); + pTarget->SetValue( "classname", "info_target" ); + pTarget->SetRenderOrigin( vecOrigin ); + pTarget->SetRenderAngles( angAngles ); + + entities.AddToTail( pTarget ); + pTarget->MarkDirty(); + pTarget->DrawInEngine( true ); + } + + g_pCommEditTool->GetCommentaryNodeBrowser()->SelectNode( pTarget ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCommEditDoc::AddNewInfoTarget( void ) +{ + Vector vecOrigin; + QAngle angAngles; + float flFov; + clienttools->GetLocalPlayerEyePosition( vecOrigin, angAngles, flFov ); + AddNewInfoTarget( vecOrigin, vec3_angle ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCommEditDoc::AddNewCommentaryNode( const Vector &vecOrigin, const QAngle &angAngles ) +{ + CDmrCommentaryNodeEntityList entities = GetEntityList(); + + CDmeCommentaryNodeEntity *pNode; + { + CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Add Commentary Node", "Add Commentary Node" ); + + pNode = CreateElement( "node", entities.GetOwner()->GetFileId() ); + pNode->SetName( "entity" ); + pNode->SetValue( "classname", "point_commentary_node" ); + pNode->SetRenderOrigin( vecOrigin ); + pNode->SetRenderAngles( angAngles ); + pNode->SetValue( "precommands", "" ); + pNode->SetValue( "postcommands", "" ); + pNode->SetValue( "commentaryfile", "" ); + pNode->SetValue( "viewtarget", "" ); + pNode->SetValue( "viewposition", "" ); + pNode->SetValue( "prevent_movement", 0 ); + pNode->SetValue( "speakers", "" ); + pNode->SetValue( "synopsis", "" ); + + entities.AddToTail( pNode ); + pNode->MarkDirty(); + pNode->DrawInEngine( true ); + } + + g_pCommEditTool->GetCommentaryNodeBrowser()->SelectNode( pNode ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCommEditDoc::AddNewCommentaryNode( void ) +{ + Vector vecOrigin; + QAngle angAngles; + float flFov; + clienttools->GetLocalPlayerEyePosition( vecOrigin, angAngles, flFov ); + AddNewCommentaryNode( vecOrigin, vec3_angle ); +} + + +//----------------------------------------------------------------------------- +// Deletes a commentary node +//----------------------------------------------------------------------------- +void CCommEditDoc::DeleteCommentaryNode( CDmElement *pRemoveNode ) +{ + CDmrCommentaryNodeEntityList entities = GetEntityList(); + int nCount = entities.Count(); + for ( int i = 0; i < nCount; ++i ) + { + if ( pRemoveNode == entities[i] ) + { + CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Delete Commentary Node", "Delete Commentary Node" ); + CDmeCommentaryNodeEntity *pNode = entities[ i ]; + pNode->DrawInEngine( false ); + entities.FastRemove( i ); + return; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &vecOrigin - +// &angAbsAngles - +// Output : CDmeCommentaryNodeEntity +//----------------------------------------------------------------------------- +CDmeCommentaryNodeEntity *CCommEditDoc::GetCommentaryNodeForLocation( Vector &vecOrigin, QAngle &angAbsAngles ) +{ + CDmrCommentaryNodeEntityList entities = GetEntityList(); + int nCount = entities.Count(); + for ( int i = 0; i < nCount; ++i ) + { + CDmeCommentaryNodeEntity *pNode = entities[ i ]; + if ( !pNode ) + continue; + + Vector &vecAngles = *(Vector*)(&pNode->GetRenderAngles()); + if ( pNode->GetRenderOrigin().DistTo( vecOrigin ) < 1e-3 && vecAngles.DistTo( *(Vector*)&angAbsAngles ) < 1e-1 ) + return pNode; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// Populate string choice lists +//----------------------------------------------------------------------------- +bool CCommEditDoc::GetStringChoiceList( const char *pChoiceListType, CDmElement *pElement, + const char *pAttributeName, bool bArrayElement, StringChoiceList_t &list ) +{ + if ( !Q_stricmp( pChoiceListType, "info_targets" ) ) + { + CDmrCommentaryNodeEntityList 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 ) + { + CDmeCommentaryNodeEntity *pNode = entities[ i ]; + if ( !pNode ) + continue; + + if ( !V_stricmp( pNode->GetClassName(), "info_target" ) ) + { + sChoice.m_pValue = pNode->GetTargetName(); + sChoice.m_pChoiceString = pNode->GetTargetName(); + list.AddToTail( sChoice ); + } + } + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Populate element choice lists +//----------------------------------------------------------------------------- +bool CCommEditDoc::GetElementChoiceList( const char *pChoiceListType, CDmElement *pElement, + const char *pAttributeName, bool bArrayElement, ElementChoiceList_t &list ) +{ + if ( !Q_stricmp( pChoiceListType, "allelements" ) ) + { + AddElementsRecursively( m_hRoot, list ); + return true; + } + + if ( !Q_stricmp( pChoiceListType, "info_targets" ) ) + { + CDmrCommentaryNodeEntityList entities = GetEntityList(); + + bool bFound = false; + int nCount = entities.Count(); + for ( int i = 0; i < nCount; ++i ) + { + CDmeCommentaryNodeEntity *pNode = entities[ i ]; + if ( pNode && !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_hRoot, list, pChoiceListType ); + + return list.Count() > 0; +} + + +//----------------------------------------------------------------------------- +// Called when data changes +//----------------------------------------------------------------------------- +void CCommEditDoc::OnDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) +{ + SetDirty( nNotifyFlags & NOTIFY_SETDIRTYFLAG ? true : false ); + m_pCallback->OnDocChanged( pReason, nNotifySource, nNotifyFlags ); +} + + -- cgit v1.2.3