Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

599 lines
19 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Singleton dialog that generates and presents the entity report.
  4. //
  5. //===========================================================================//
  6. #include "particlesystemdefinitionbrowser.h"
  7. #include "tier1/KeyValues.h"
  8. #include "tier1/utlbuffer.h"
  9. #include "iregistry.h"
  10. #include "vgui/ivgui.h"
  11. #include "vgui_controls/listpanel.h"
  12. #include "vgui_controls/inputdialog.h"
  13. #include "vgui_controls/messagebox.h"
  14. #include "petdoc.h"
  15. #include "pettool.h"
  16. #include "datamodel/dmelement.h"
  17. #include "vgui/keycode.h"
  18. #include "dme_controls/dmecontrols_utils.h"
  19. #include "dme_controls/particlesystempanel.h"
  20. #include "filesystem.h"
  21. #include "vgui_controls/FileOpenDialog.h"
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include <tier0/memdbgon.h>
  24. using namespace vgui;
  25. //-----------------------------------------------------------------------------
  26. // Sort by particle system definition name
  27. //-----------------------------------------------------------------------------
  28. static int __cdecl ParticleSystemNameSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
  29. {
  30. const char *string1 = item1.kv->GetString("name");
  31. const char *string2 = item2.kv->GetString("name");
  32. return Q_stricmp( string1, string2 );
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Constructor
  36. //-----------------------------------------------------------------------------
  37. CParticleSystemDefinitionBrowser::CParticleSystemDefinitionBrowser( CPetDoc *pDoc, vgui::Panel* pParent, const char *pName )
  38. : BaseClass( pParent, pName ), m_pDoc( pDoc )
  39. {
  40. SetKeyBoardInputEnabled( true );
  41. SetPaintBackgroundEnabled( true );
  42. m_pParticleSystemsDefinitions = new vgui::ListPanel( this, "ParticleSystems" );
  43. m_pParticleSystemsDefinitions->AddColumnHeader( 0, "name", "Name", 52, ListPanel::COLUMN_RESIZEWITHWINDOW );
  44. m_pParticleSystemsDefinitions->SetColumnSortable( 0, true );
  45. m_pParticleSystemsDefinitions->SetEmptyListText( "No Particle System Definitions" );
  46. m_pParticleSystemsDefinitions->AddActionSignalTarget( this );
  47. m_pParticleSystemsDefinitions->SetSortFunc( 0, ParticleSystemNameSortFunc );
  48. m_pParticleSystemsDefinitions->SetSortColumn( 0 );
  49. LoadControlSettingsAndUserConfig( "resource/particlesystemdefinitionbrowser.res" );
  50. UpdateParticleSystemList();
  51. }
  52. CParticleSystemDefinitionBrowser::~CParticleSystemDefinitionBrowser()
  53. {
  54. SaveUserConfig();
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Gets the ith selected particle system
  58. //-----------------------------------------------------------------------------
  59. CDmeParticleSystemDefinition* CParticleSystemDefinitionBrowser::GetSelectedParticleSystem( int i )
  60. {
  61. int iSel = m_pParticleSystemsDefinitions->GetSelectedItem( i );
  62. KeyValues *kv = m_pParticleSystemsDefinitions->GetItem( iSel );
  63. return GetElementKeyValue< CDmeParticleSystemDefinition >( kv, "particleSystem" );
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Purpose: Deletes the marked objects.
  67. //-----------------------------------------------------------------------------
  68. void CParticleSystemDefinitionBrowser::DeleteParticleSystems()
  69. {
  70. int iSel = m_pParticleSystemsDefinitions->GetSelectedItem( 0 );
  71. int nRow = m_pParticleSystemsDefinitions->GetItemCurrentRow( iSel ) - 1;
  72. {
  73. // This is undoable
  74. CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Delete Particle Systems", "Delete Particle Systems" );
  75. //
  76. // Build a list of objects to delete.
  77. //
  78. CUtlVector< CDmeParticleSystemDefinition* > itemsToDelete;
  79. int nCount = m_pParticleSystemsDefinitions->GetSelectedItemsCount();
  80. for (int i = 0; i < nCount; i++)
  81. {
  82. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  83. if ( pParticleSystem )
  84. {
  85. itemsToDelete.AddToTail( pParticleSystem );
  86. }
  87. }
  88. nCount = itemsToDelete.Count();
  89. for ( int i = 0; i < nCount; ++i )
  90. {
  91. m_pDoc->DeleteParticleSystemDefinition( itemsToDelete[i] );
  92. }
  93. }
  94. // Update the list box selection.
  95. if ( m_pParticleSystemsDefinitions->GetItemCount() > 0 )
  96. {
  97. if ( nRow < 0 )
  98. {
  99. nRow = 0;
  100. }
  101. else if ( nRow >= m_pParticleSystemsDefinitions->GetItemCount() )
  102. {
  103. nRow = m_pParticleSystemsDefinitions->GetItemCount() - 1;
  104. }
  105. iSel = m_pParticleSystemsDefinitions->GetItemIDFromRow( nRow );
  106. m_pParticleSystemsDefinitions->SetSingleSelectedItem( iSel );
  107. }
  108. else
  109. {
  110. m_pParticleSystemsDefinitions->ClearSelectedItems();
  111. }
  112. }
  113. //-----------------------------------------------------------------------------
  114. void CParticleSystemDefinitionBrowser::LoadKVSection( CDmeParticleSystemDefinition *pNew, KeyValues *pOverridesKv, ParticleFunctionType_t eType )
  115. {
  116. // Operator KV
  117. KeyValues *pOperator = pOverridesKv->FindKey( GetParticleFunctionTypeName(eType), NULL );
  118. if ( !pOperator )
  119. return;
  120. // Function
  121. FOR_EACH_TRUE_SUBKEY( pOperator, pFunctionBlock )
  122. {
  123. int iFunction = pNew->FindFunction( eType, pFunctionBlock->GetName() );
  124. if ( iFunction >= 0 )
  125. {
  126. CDmeParticleFunction *pDmeFunction = pNew->GetParticleFunction( eType, iFunction );
  127. // Elements
  128. FOR_EACH_SUBKEY( pFunctionBlock, pAttributeItem )
  129. {
  130. CDmAttribute *pAttribute = pDmeFunction->GetAttribute( pAttributeItem->GetName() );
  131. if ( !pAttribute )
  132. {
  133. Warning( "Unable to Find Attribute [%s] in Function [%s] in Operator [%s] for Definition [%s]\n", pAttributeItem->GetName(), pFunctionBlock->GetName(), GetParticleFunctionTypeName(eType), pNew->GetName() );
  134. }
  135. else
  136. {
  137. pAttribute->SetValueFromString( pAttributeItem->GetString() );
  138. }
  139. }
  140. }
  141. else
  142. {
  143. Warning( "Function [%s] not found under Operator [%s] for Definition [%s]\n", pFunctionBlock->GetName(), GetParticleFunctionTypeName(eType), pNew->GetName() );
  144. }
  145. }
  146. }
  147. //-----------------------------------------------------------------------------
  148. // Given a KV, create, add and return an effect
  149. //-----------------------------------------------------------------------------
  150. CDmeParticleSystemDefinition* CParticleSystemDefinitionBrowser::CreateParticleFromKV( KeyValues *pKeyValue )
  151. {
  152. CDmeParticleSystemDefinition* pBaseParticleDef = NULL;
  153. // Get the Base Particle Effect Def
  154. const char* pBaseParticleName = pKeyValue->GetString( "base_effect", "" );
  155. for ( int i = 0; i < m_pParticleSystemsDefinitions->GetItemCount(); ++i )
  156. {
  157. KeyValues *kv = m_pParticleSystemsDefinitions->GetItem( i );
  158. if ( !V_strcmp( kv->GetString( "name", "" ), pBaseParticleName ) )
  159. {
  160. //
  161. pBaseParticleDef = GetElementKeyValue< CDmeParticleSystemDefinition >( kv, "particleSystem" );
  162. break;
  163. }
  164. }
  165. // Base Particle could not be found, end;
  166. if ( !pBaseParticleDef )
  167. {
  168. Warning( "Unable to to find base particle system [%s]", pBaseParticleName );
  169. return NULL;
  170. }
  171. // Create a Copy of the Base Effect
  172. const char *pszNewParticleName = pKeyValue->GetName();
  173. //CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Copy Particle System", "Copy Particle System" );
  174. CDmeParticleSystemDefinition *pNew = CastElement<CDmeParticleSystemDefinition>( pBaseParticleDef->Copy() );
  175. pNew->SetName( pszNewParticleName );
  176. // Overrides
  177. //
  178. //"properties"
  179. KeyValues *pProperties = pKeyValue->FindKey( "Properties", NULL );
  180. if ( pProperties )
  181. {
  182. FOR_EACH_SUBKEY( pProperties, pProperty )
  183. {
  184. CDmAttribute *pAttribute = pNew->GetAttribute( pProperty->GetName() );
  185. if ( !pAttribute )
  186. {
  187. Warning( "Unable to Find Attribute [%s] in Function [%s]\n", pProperty->GetName(), "Properties" );
  188. }
  189. else
  190. {
  191. pAttribute->SetValueFromString( pProperty->GetString() );
  192. }
  193. }
  194. }
  195. LoadKVSection( pNew, pKeyValue, FUNCTION_RENDERER );
  196. LoadKVSection( pNew, pKeyValue, FUNCTION_OPERATOR );
  197. LoadKVSection( pNew, pKeyValue, FUNCTION_INITIALIZER );
  198. LoadKVSection( pNew, pKeyValue, FUNCTION_EMITTER );
  199. LoadKVSection( pNew, pKeyValue, FUNCTION_FORCEGENERATOR );
  200. LoadKVSection( pNew, pKeyValue, FUNCTION_CONSTRAINT );
  201. // Remove copied children
  202. int iChildrenCount = pNew->GetParticleFunctionCount( FUNCTION_CHILDREN );
  203. for ( int i = iChildrenCount - 1; i >= 0; i-- )
  204. {
  205. pNew->RemoveFunction( FUNCTION_CHILDREN, i );
  206. }
  207. // Search Children
  208. KeyValues *pChildren = pKeyValue->FindKey( "Children", NULL );
  209. if ( pChildren )
  210. {
  211. FOR_EACH_TRUE_SUBKEY( pChildren, pChild )
  212. {
  213. // each Child is its own effect so we need to add it and return it
  214. CDmeParticleSystemDefinition* pChildEffect = CreateParticleFromKV( pChild );
  215. if ( pChildEffect )
  216. {
  217. pNew->AddChild( pChildEffect );
  218. }
  219. }
  220. }
  221. m_pDoc->ReplaceParticleSystemDefinition( pNew );
  222. m_pDoc->UpdateAllParticleSystems();
  223. return pNew;
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Create from KV
  227. void CParticleSystemDefinitionBrowser::CreateParticleSystemsFromKV( const char *pFileName )
  228. {
  229. //
  230. //const char * pFileName = "particles\\_weapon_prefab_override_kv.txt";
  231. CUtlBuffer bufRawData;
  232. bool bReadFileOK = g_pFullFileSystem->ReadFile( pFileName, "MOD", bufRawData );
  233. if ( !bReadFileOK )
  234. {
  235. Warning( "Unable to Open KV file [%s]\n", pFileName );
  236. return;
  237. }
  238. // Wrap it with a text buffer reader
  239. CUtlBuffer bufText( bufRawData.Base(), bufRawData.TellPut(), CUtlBuffer::READ_ONLY | CUtlBuffer::TEXT_BUFFER );
  240. KeyValues *pBaseKeyValue = NULL;
  241. pBaseKeyValue = new KeyValues( "CCreateParticlesFromKV" );
  242. if ( !pBaseKeyValue->LoadFromBuffer( NULL, bufText ) )
  243. {
  244. Warning( "Unable to Read KV file [%s]\n", pFileName );
  245. pBaseKeyValue->deleteThis();
  246. return;
  247. }
  248. FOR_EACH_TRUE_SUBKEY( pBaseKeyValue, pKVOver )
  249. {
  250. CreateParticleFromKV( pKVOver );
  251. }
  252. }
  253. //-----------------------------------------------------------------------------
  254. // Purpose:
  255. //-----------------------------------------------------------------------------
  256. void CParticleSystemDefinitionBrowser::OnKeyCodeTyped( vgui::KeyCode code )
  257. {
  258. if ( code == KEY_DELETE )
  259. {
  260. DeleteParticleSystems();
  261. }
  262. else
  263. {
  264. BaseClass::OnKeyCodeTyped( code );
  265. }
  266. }
  267. //-----------------------------------------------------------------------------
  268. void CParticleSystemDefinitionBrowser::OnFileSelected(const char *fullpath)
  269. {
  270. CreateParticleSystemsFromKV( fullpath );
  271. }
  272. //-----------------------------------------------------------------------------
  273. // Called when the selection changes
  274. //-----------------------------------------------------------------------------
  275. void CParticleSystemDefinitionBrowser::UpdateParticleSystemSelection()
  276. {
  277. if ( m_pParticleSystemsDefinitions->GetSelectedItemsCount() == 1 )
  278. {
  279. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( 0 );
  280. g_pPetTool->SetCurrentParticleSystem( pParticleSystem, false );
  281. }
  282. else
  283. {
  284. g_pPetTool->SetCurrentParticleSystem( NULL, false );
  285. }
  286. }
  287. //-----------------------------------------------------------------------------
  288. // Item selection/deselection
  289. //-----------------------------------------------------------------------------
  290. void CParticleSystemDefinitionBrowser::OnItemSelected( void )
  291. {
  292. UpdateParticleSystemSelection();
  293. }
  294. void CParticleSystemDefinitionBrowser::OnItemDeselected( void )
  295. {
  296. UpdateParticleSystemSelection();
  297. }
  298. //-----------------------------------------------------------------------------
  299. // Select a particular node
  300. //-----------------------------------------------------------------------------
  301. void CParticleSystemDefinitionBrowser::SelectParticleSystem( CDmeParticleSystemDefinition *pFind )
  302. {
  303. m_pParticleSystemsDefinitions->ClearSelectedItems();
  304. for ( int nItemID = m_pParticleSystemsDefinitions->FirstItem(); nItemID != m_pParticleSystemsDefinitions->InvalidItemID(); nItemID = m_pParticleSystemsDefinitions->NextItem( nItemID ) )
  305. {
  306. KeyValues *kv = m_pParticleSystemsDefinitions->GetItem( nItemID );
  307. CDmeParticleSystemDefinition *pParticleSystem = GetElementKeyValue<CDmeParticleSystemDefinition>( kv, "particleSystem" );
  308. if ( pParticleSystem == pFind )
  309. {
  310. m_pParticleSystemsDefinitions->AddSelectedItem( nItemID );
  311. break;
  312. }
  313. }
  314. }
  315. //-----------------------------------------------------------------------------
  316. // Called when buttons are clicked
  317. //-----------------------------------------------------------------------------
  318. void CParticleSystemDefinitionBrowser::OnInputCompleted( KeyValues *pKeyValues )
  319. {
  320. const char *pText = pKeyValues->GetString( "text", NULL );
  321. if ( m_pDoc->IsParticleSystemDefined( pText ) )
  322. {
  323. char pBuf[1024];
  324. Q_snprintf( pBuf, sizeof(pBuf), "Particle System \"%s\" already exists!\n", pText );
  325. vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Duplicate Particle System Name!\n", pBuf, g_pPetTool->GetRootPanel() );
  326. pMessageBox->DoModal( );
  327. return;
  328. }
  329. if ( pKeyValues->FindKey( "create" ) )
  330. {
  331. CDmeParticleSystemDefinition *pParticleSystem = m_pDoc->AddNewParticleSystemDefinition( pText );
  332. g_pPetTool->SetCurrentParticleSystem( pParticleSystem );
  333. }
  334. else if ( pKeyValues->FindKey( "copy" ) )
  335. {
  336. int nCount = m_pParticleSystemsDefinitions->GetSelectedItemsCount();
  337. if ( nCount )
  338. {
  339. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( 0 );
  340. CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Copy Particle System",
  341. "Copy Particle System" );
  342. CDmeParticleSystemDefinition * pNew =
  343. CastElement<CDmeParticleSystemDefinition>( pParticleSystem->Copy( ) );
  344. pNew->SetName( pText );
  345. m_pDoc->AddNewParticleSystemDefinition( pNew, guard );
  346. }
  347. }
  348. }
  349. //-----------------------------------------------------------------------------
  350. // Copy to clipboard
  351. //-----------------------------------------------------------------------------
  352. void CParticleSystemDefinitionBrowser::CopyToClipboard( )
  353. {
  354. int nCount = m_pParticleSystemsDefinitions->GetSelectedItemsCount();
  355. CUtlVector< KeyValues * > list;
  356. CUtlRBTree< CDmeParticleSystemDefinition* > defs( 0, 0, DefLessFunc( CDmeParticleSystemDefinition* ) );
  357. for ( int i = 0; i < nCount; ++i )
  358. {
  359. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  360. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  361. if ( g_pDataModel->Serialize( buf, "keyvalues2", "pcf", pParticleSystem->GetHandle() ) )
  362. {
  363. KeyValues *pData = new KeyValues( "Clipboard" );
  364. pData->SetString( "pcf", (char*)buf.Base() );
  365. list.AddToTail( pData );
  366. }
  367. }
  368. if ( list.Count() )
  369. {
  370. g_pDataModel->SetClipboardData( list );
  371. }
  372. }
  373. //-----------------------------------------------------------------------------
  374. // Paste from clipboard
  375. //-----------------------------------------------------------------------------
  376. void CParticleSystemDefinitionBrowser::ReplaceDef_r( CUndoScopeGuard& guard, CDmeParticleSystemDefinition *pDef )
  377. {
  378. if ( !pDef )
  379. return;
  380. m_pDoc->ReplaceParticleSystemDefinition( pDef );
  381. int nChildCount = pDef->GetParticleFunctionCount( FUNCTION_CHILDREN );
  382. for ( int i = 0; i < nChildCount; ++i )
  383. {
  384. CDmeParticleChild *pChildFunction = static_cast< CDmeParticleChild* >( pDef->GetParticleFunction( FUNCTION_CHILDREN, i ) );
  385. CDmeParticleSystemDefinition* pChild = pChildFunction->m_Child;
  386. ReplaceDef_r( guard, pChild );
  387. }
  388. }
  389. void CParticleSystemDefinitionBrowser::PasteFromClipboard( )
  390. {
  391. // This is undoable
  392. CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Paste From Clipboard", "Paste From Clipboard" );
  393. bool bRefreshAll = false;
  394. CUtlVector< KeyValues * > list;
  395. g_pDataModel->GetClipboardData( list );
  396. int nItems = list.Count();
  397. for ( int i = 0; i < nItems; ++i )
  398. {
  399. const char *pData = list[i]->GetString( "pcf" );
  400. if ( !pData )
  401. continue;
  402. int nLen = Q_strlen( pData );
  403. CUtlBuffer buf( pData, nLen, CUtlBuffer::TEXT_BUFFER | CUtlBuffer::READ_ONLY );
  404. DmElementHandle_t hRoot;
  405. if ( !g_pDataModel->Unserialize( buf, "keyvalues2", "pcf", NULL, "paste", CR_FORCE_COPY, hRoot ) )
  406. continue;
  407. CDmeParticleSystemDefinition *pDef = GetElement<CDmeParticleSystemDefinition>( hRoot );
  408. if ( !pDef )
  409. continue;
  410. ReplaceDef_r( guard, pDef );
  411. bRefreshAll = true;
  412. }
  413. guard.Release();
  414. if ( bRefreshAll )
  415. {
  416. m_pDoc->UpdateAllParticleSystems();
  417. }
  418. }
  419. //-----------------------------------------------------------------------------
  420. // Called when buttons are clicked
  421. //-----------------------------------------------------------------------------
  422. void CParticleSystemDefinitionBrowser::OnCommand( const char *pCommand )
  423. {
  424. if ( !Q_stricmp( pCommand, "create" ) )
  425. {
  426. vgui::InputDialog *pInputDialog = new vgui::InputDialog( g_pPetTool->GetRootPanel(), "Enter Particle System Name", "Name:", "" );
  427. pInputDialog->SetSmallCaption( true );
  428. pInputDialog->SetMultiline( false );
  429. pInputDialog->AddActionSignalTarget( this );
  430. pInputDialog->DoModal( new KeyValues("create") );
  431. return;
  432. }
  433. if ( !Q_stricmp( pCommand, "copy" ) )
  434. {
  435. vgui::InputDialog *pInputDialog = new vgui::InputDialog( g_pPetTool->GetRootPanel(), "Enter Particle System Name", "Name:", "" );
  436. pInputDialog->SetSmallCaption( true );
  437. pInputDialog->SetMultiline( false );
  438. pInputDialog->AddActionSignalTarget( this );
  439. pInputDialog->DoModal( new KeyValues("copy") );
  440. return;
  441. }
  442. if ( !Q_stricmp( pCommand, "Create From KeyValue" ) )
  443. {
  444. vgui::FileOpenDialog *pDialog = new vgui::FileOpenDialog( g_pPetTool->GetRootPanel(), "Select KV File", vgui::FOD_OPEN );
  445. pDialog->SetTitle( "Choose KeyValue File", true );
  446. pDialog->AddFilter( "*.txt", "KeyValue File (*.txt)", true );
  447. pDialog->AddActionSignalTarget( this );
  448. char szParticlesDir[MAX_PATH];
  449. pDialog->SetStartDirectory( g_pFullFileSystem->RelativePathToFullPath( "particles", "MOD", szParticlesDir, sizeof(szParticlesDir) ) );
  450. pDialog->DoModal( new KeyValues( "Create From KeyValue" ) );
  451. return;
  452. }
  453. if ( !Q_stricmp( pCommand, "delete" ) )
  454. {
  455. DeleteParticleSystems();
  456. return;
  457. }
  458. if ( !Q_stricmp( pCommand, "Save" ) )
  459. {
  460. g_pPetTool->Save();
  461. return;
  462. }
  463. if ( !Q_stricmp( pCommand, "SaveAndTest" ) )
  464. {
  465. g_pPetTool->SaveAndTest();
  466. return;
  467. }
  468. BaseClass::OnCommand( pCommand );
  469. }
  470. //-----------------------------------------------------------------------------
  471. // Purpose:
  472. //-----------------------------------------------------------------------------
  473. void CParticleSystemDefinitionBrowser::UpdateParticleSystemList(void)
  474. {
  475. const CDmrParticleSystemList particleSystemList = m_pDoc->GetParticleSystemDefinitionList();
  476. if ( !particleSystemList.IsValid() )
  477. return;
  478. // Maintain selection if possible
  479. CUtlVector< CUtlString > selectedItems;
  480. int nCount = m_pParticleSystemsDefinitions->GetSelectedItemsCount();
  481. for ( int i = 0; i < nCount; ++i )
  482. {
  483. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  484. if ( pParticleSystem )
  485. {
  486. selectedItems.AddToTail( pParticleSystem->GetName() );
  487. }
  488. }
  489. m_pParticleSystemsDefinitions->RemoveAll();
  490. int nSelectedItemCount = selectedItems.Count();
  491. nCount = particleSystemList.Count();
  492. for ( int i = 0; i < nCount; ++i )
  493. {
  494. CDmeParticleSystemDefinition *pParticleSystem = particleSystemList[i];
  495. if ( !pParticleSystem )
  496. continue;
  497. const char *pName = pParticleSystem->GetName();
  498. if ( !pName || !pName[0] )
  499. {
  500. pName = "<no name>";
  501. }
  502. KeyValues *kv = new KeyValues( "node" );
  503. kv->SetString( "name", pName );
  504. SetElementKeyValue( kv, "particleSystem", pParticleSystem );
  505. int nItemID = m_pParticleSystemsDefinitions->AddItem( kv, 0, false, false );
  506. for ( int j = 0; j < nSelectedItemCount; ++j )
  507. {
  508. if ( Q_stricmp( selectedItems[j], pName ) )
  509. continue;
  510. m_pParticleSystemsDefinitions->AddSelectedItem( nItemID );
  511. selectedItems.FastRemove(j);
  512. --nSelectedItemCount;
  513. break;
  514. }
  515. }
  516. m_pParticleSystemsDefinitions->SortList();
  517. }