Counter Strike : Global Offensive Source Code
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.

660 lines
16 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include <mxtk/mx.h>
  9. #include <stdio.h>
  10. #include "resource.h"
  11. #include "EventProperties.h"
  12. #include "mdlviewer.h"
  13. #include "choreoevent.h"
  14. #include "choreoscene.h"
  15. #include "mathlib/mathlib.h"
  16. #include "choreochannel.h"
  17. #include "choreoactor.h"
  18. #include "FileSystem.h"
  19. #include "scriplib.h"
  20. #include "eventproperties_expression.h"
  21. #include "eventproperties_face.h"
  22. #include "eventproperties_firetrigger.h"
  23. #include "eventproperties_flexanimation.h"
  24. #include "eventproperties_generic.h"
  25. #include "eventproperties_gesture.h"
  26. #include "eventproperties_interrupt.h"
  27. #include "eventproperties_lookat.h"
  28. #include "eventproperties_moveto.h"
  29. #include "eventproperties_permitresponses.h"
  30. #include "eventproperties_sequence.h"
  31. #include "eventproperties_speak.h"
  32. #include "eventproperties_subscene.h"
  33. #include "eventproperties_camera.h"
  34. void CBaseEventPropertiesDialog::PopulateTagList( CEventParams *params )
  35. {
  36. CChoreoScene *scene = params->m_pScene;
  37. if ( !scene )
  38. return;
  39. HWND control = GetControl( IDC_TAGS );
  40. if ( control )
  41. {
  42. SendMessage( control, CB_RESETCONTENT, 0, 0 );
  43. SendMessage( control, WM_SETTEXT , 0, (LPARAM)va( "\"%s\" \"%s\"", params->m_szTagName, params->m_szTagWav ) );
  44. for ( int i = 0; i < scene->GetNumActors(); i++ )
  45. {
  46. CChoreoActor *a = scene->GetActor( i );
  47. if ( !a )
  48. continue;
  49. for ( int j = 0; j < a->GetNumChannels(); j++ )
  50. {
  51. CChoreoChannel *c = a->GetChannel( j );
  52. if ( !c )
  53. continue;
  54. for ( int k = 0 ; k < c->GetNumEvents(); k++ )
  55. {
  56. CChoreoEvent *e = c->GetEvent( k );
  57. if ( !e )
  58. continue;
  59. if ( e->GetNumRelativeTags() <= 0 )
  60. continue;
  61. // add each tag to combo box
  62. for ( int t = 0; t < e->GetNumRelativeTags(); t++ )
  63. {
  64. CEventRelativeTag *tag = e->GetRelativeTag( t );
  65. if ( !tag )
  66. continue;
  67. SendMessage( control, CB_ADDSTRING, 0, (LPARAM)va( "\"%s\" \"%s\"", tag->GetName(), e->GetParameters() ) );
  68. }
  69. }
  70. }
  71. }
  72. }
  73. }
  74. #include "mapentities.h"
  75. #include "UtlDict.h"
  76. struct CMapEntityData
  77. {
  78. CMapEntityData()
  79. {
  80. origin.Init();
  81. angles.Init();
  82. }
  83. Vector origin;
  84. QAngle angles;
  85. };
  86. class CMapEntities : public IMapEntities
  87. {
  88. public:
  89. CMapEntities();
  90. ~CMapEntities();
  91. virtual void CheckUpdateMap( char const *mapname );
  92. virtual bool LookupOrigin( char const *name, Vector& origin, QAngle& angles )
  93. {
  94. int idx = FindNamedEntity( name );
  95. if ( idx == -1 )
  96. {
  97. origin.Init();
  98. angles.Init();
  99. return false;
  100. }
  101. CMapEntityData *e = &m_Entities[ idx ];
  102. Assert( e );
  103. origin = e->origin;
  104. angles = e->angles;
  105. return true;
  106. }
  107. virtual int Count( void );
  108. virtual char const *GetName( int number );
  109. int FindNamedEntity( char const *name );
  110. private:
  111. char m_szCurrentMap[ 1024 ];
  112. CUtlDict< CMapEntityData, int > m_Entities;
  113. };
  114. static CMapEntities g_MapEntities;
  115. // Expose to rest of tool
  116. IMapEntities *mapentities = &g_MapEntities;
  117. CMapEntities::CMapEntities()
  118. {
  119. m_szCurrentMap[ 0 ] = 0;
  120. }
  121. CMapEntities::~CMapEntities()
  122. {
  123. m_Entities.RemoveAll();
  124. }
  125. int CMapEntities::FindNamedEntity( char const *name )
  126. {
  127. char lowername[ 128 ];
  128. strcpy( lowername, name );
  129. _strlwr( lowername );
  130. int index = m_Entities.Find( lowername );
  131. if ( index == m_Entities.InvalidIndex() )
  132. return -1;
  133. return index;
  134. }
  135. #include "bspfile.h"
  136. void CMapEntities::CheckUpdateMap( char const *mapname )
  137. {
  138. if ( !mapname || !mapname[ 0 ] )
  139. return;
  140. if ( !stricmp( mapname, m_szCurrentMap ) )
  141. return;
  142. // Latch off the name of the map
  143. Q_strncpy( m_szCurrentMap, mapname, sizeof( m_szCurrentMap ) );
  144. // Load names from map
  145. m_Entities.RemoveAll();
  146. FileHandle_t hfile = filesystem->Open( mapname, "rb" );
  147. if ( hfile == FILESYSTEM_INVALID_HANDLE )
  148. return;
  149. BSPHeader_t header;
  150. filesystem->Read( &header, sizeof( header ), hfile );
  151. // Check the header
  152. if ( header.ident != IDBSPHEADER ||
  153. header.m_nVersion < MINBSPVERSION || header.m_nVersion > BSPVERSION )
  154. {
  155. Con_ErrorPrintf( "BSP file %s is wrong version (%i), expected (%i)\n",
  156. mapname,
  157. header.m_nVersion,
  158. BSPVERSION );
  159. filesystem->Close( hfile );
  160. return;
  161. }
  162. // Find the LUMP_PAKFILE offset
  163. lump_t *entlump = &header.lumps[ LUMP_ENTITIES ];
  164. if ( entlump->filelen <= 0 )
  165. {
  166. Con_ErrorPrintf( "BSP file %s is missing entity lump\n", mapname );
  167. // It's empty or only contains a file header ( so there are no entries ), so don't add to search paths
  168. filesystem->Close( hfile );
  169. return;
  170. }
  171. // Seek to correct position
  172. filesystem->Seek( hfile, entlump->fileofs, FILESYSTEM_SEEK_HEAD );
  173. char *buffer = new char[ entlump->filelen + 1 ];
  174. Assert( buffer );
  175. filesystem->Read( buffer, entlump->filelen, hfile );
  176. filesystem->Close( hfile );
  177. buffer[ entlump->filelen ] = 0;
  178. // Now we have entity buffer, now parse it
  179. ParseFromMemory( buffer, entlump->filelen );
  180. while ( 1 )
  181. {
  182. if (!GetToken (true))
  183. break;
  184. if (Q_stricmp (token, "{") )
  185. Error ("ParseEntity: { not found");
  186. char name[ 256 ];
  187. char origin[ 256 ];
  188. char angles[ 256 ];
  189. name[ 0 ] = 0;
  190. origin[ 0 ] = 0;
  191. angles[ 0 ] = 0;
  192. do
  193. {
  194. char key[ 256 ];
  195. char value[ 256 ];
  196. if (!GetToken (true))
  197. {
  198. Error ("ParseEntity: EOF without closing brace");
  199. }
  200. if (!Q_stricmp (token, "}") )
  201. break;
  202. Q_strncpy( key, token, sizeof( key ) );
  203. GetToken (false);
  204. Q_strncpy( value, token, sizeof( value ) );
  205. // Con_Printf( "Parsed %s -- %s\n", key, value );
  206. if ( !Q_stricmp( key, "name" ) )
  207. {
  208. Q_strncpy( name, value, sizeof( name ) );
  209. }
  210. if ( !Q_stricmp( key, "targetname" ) )
  211. {
  212. Q_strncpy( name, value, sizeof( name ) );
  213. }
  214. if ( !Q_stricmp( key, "origin" ) )
  215. {
  216. Q_strncpy( origin, value, sizeof( origin ) );
  217. }
  218. if ( !Q_stricmp( key, "angles" ) )
  219. {
  220. Q_strncpy( angles, value, sizeof( angles ) );
  221. }
  222. } while (1);
  223. if ( name[ 0 ] )
  224. {
  225. if ( FindNamedEntity( name ) == - 1 )
  226. {
  227. CMapEntityData ent;
  228. float org[3];
  229. if ( origin[ 0 ] )
  230. {
  231. if ( 3 == sscanf( origin, "%f %f %f", &org[ 0 ], &org[ 1 ], &org[ 2 ] ) )
  232. {
  233. ent.origin = Vector( org[ 0 ], org[ 1 ], org[ 2 ] );
  234. // Con_Printf( "read %f %f %f for entity %s\n", org[0], org[1], org[2], name );
  235. }
  236. }
  237. if ( angles[ 0 ] )
  238. {
  239. if ( 3 == sscanf( angles, "%f %f %f", &org[ 0 ], &org[ 1 ], &org[ 2 ] ) )
  240. {
  241. ent.angles = QAngle( org[ 0 ], org[ 1 ], org[ 2 ] );
  242. // Con_Printf( "read %f %f %f for entity %s\n", org[0], org[1], org[2], name );
  243. }
  244. }
  245. m_Entities.Insert( name, ent );
  246. }
  247. }
  248. }
  249. delete[] buffer;
  250. }
  251. int CMapEntities::Count( void )
  252. {
  253. return m_Entities.Count();
  254. }
  255. char const *CMapEntities::GetName( int number )
  256. {
  257. if ( number < 0 || number >= (int)m_Entities.Count() )
  258. return NULL;
  259. return m_Entities.GetElementName( number );
  260. }
  261. bool NameLessFunc( const char *const& name1, const char *const& name2 )
  262. {
  263. if ( Q_stricmp( name1, name2 ) < 0 )
  264. return true;
  265. return false;
  266. }
  267. void CBaseEventPropertiesDialog::SetDialogTitle( CEventParams *params, char const *eventname, char const *desc )
  268. {
  269. char sz[ 256 ];
  270. Q_snprintf( sz, sizeof( sz ), " : %s", eventname );
  271. Q_strncat( params->m_szDialogTitle, sz, sizeof( params->m_szDialogTitle ), COPY_ALL_CHARACTERS );
  272. Q_snprintf( sz, sizeof( sz ), "%s:", desc );
  273. // Set dialog title
  274. SetWindowText( m_hDialog, params->m_szDialogTitle );
  275. // Set type name field
  276. SetDlgItemText( m_hDialog, IDC_TYPENAME, sz );
  277. // Set event name
  278. SetDlgItemText( m_hDialog, IDC_EVENTNAME, params->m_szName );
  279. }
  280. void CBaseEventPropertiesDialog::ShowControlsForEventType( CEventParams *params )
  281. {
  282. // Special processing for various settings
  283. if ( !params->m_bHasEndTime )
  284. {
  285. ShowWindow( GetControl( IDC_ENDTIME ), SW_HIDE );
  286. }
  287. if ( params->m_bFixedLength )
  288. {
  289. ShowWindow( GetControl( IDC_ENDTIME ), SW_HIDE );
  290. ShowWindow( GetControl( IDC_CHECK_ENDTIME ), SW_HIDE );
  291. }
  292. }
  293. void CBaseEventPropertiesDialog::InitControlData( CEventParams *params )
  294. {
  295. SetDlgItemText( m_hDialog, IDC_STARTTIME, va( "%f", params->m_flStartTime ) );
  296. SetDlgItemText( m_hDialog, IDC_ENDTIME, va( "%f", params->m_flEndTime ) );
  297. SendMessage( GetControl( IDC_CHECK_ENDTIME ), BM_SETCHECK,
  298. ( WPARAM ) params->m_bHasEndTime ? BST_CHECKED : BST_UNCHECKED,
  299. ( LPARAM )0 );
  300. if ( GetControl( IDC_CHECK_RESUMECONDITION ) != (HWND)0 )
  301. {
  302. SendMessage( GetControl( IDC_CHECK_RESUMECONDITION ), BM_SETCHECK,
  303. ( WPARAM ) params->m_bResumeCondition ? BST_CHECKED : BST_UNCHECKED,
  304. ( LPARAM )0 );
  305. }
  306. SendMessage( GetControl( IDC_CHECK_DISABLED ), BM_SETCHECK,
  307. ( WPARAM ) params->m_bDisabled ? BST_CHECKED : BST_UNCHECKED,
  308. ( LPARAM )0 );
  309. PopulateTagList( params );
  310. }
  311. BOOL CBaseEventPropertiesDialog::InternalHandleMessage( CEventParams *params, HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, bool& handled )
  312. {
  313. handled = false;
  314. switch(uMsg)
  315. {
  316. default:
  317. break;
  318. case WM_COMMAND:
  319. switch (LOWORD(wParam))
  320. {
  321. default:
  322. break;
  323. case IDC_CHECK_DISABLED:
  324. {
  325. params->m_bDisabled = SendMessage( GetControl( IDC_CHECK_DISABLED ), BM_GETCHECK, 0, 0 ) == BST_CHECKED ? true : false;
  326. handled = true;
  327. return TRUE;
  328. }
  329. break;
  330. }
  331. }
  332. return FALSE;
  333. }
  334. void CBaseEventPropertiesDialog::PopulateNamedActorList( HWND wnd, CEventParams *params )
  335. {
  336. int i;
  337. char const *mapname = NULL;
  338. if ( params->m_pScene )
  339. {
  340. mapname = params->m_pScene->GetMapname();
  341. }
  342. CUtlRBTree< char const *, int > m_SortedNames( 0, 0, NameLessFunc );
  343. if ( mapname )
  344. {
  345. g_MapEntities.CheckUpdateMap( mapname );
  346. for ( i = 0; i < g_MapEntities.Count(); i++ )
  347. {
  348. char const *name = g_MapEntities.GetName( i );
  349. if ( name && name[ 0 ] )
  350. {
  351. m_SortedNames.Insert( name );
  352. }
  353. }
  354. }
  355. for ( i = 0 ; i < params->m_pScene->GetNumActors() ; i++ )
  356. {
  357. CChoreoActor *actor = params->m_pScene->GetActor( i );
  358. if ( actor && actor->GetName() && actor->GetName()[0] )
  359. {
  360. if ( m_SortedNames.Find( actor->GetName() ) == m_SortedNames.InvalidIndex() )
  361. {
  362. m_SortedNames.Insert( actor->GetName() );
  363. }
  364. }
  365. }
  366. i = m_SortedNames.FirstInorder();
  367. while ( i != m_SortedNames.InvalidIndex() )
  368. {
  369. char const *name = m_SortedNames[ i ];
  370. if ( name && name[ 0 ] )
  371. {
  372. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)name );
  373. }
  374. i = m_SortedNames.NextInorder( i );
  375. }
  376. /*
  377. // Note have to do this here, after posting data to the control, since we are storing a raw string pointer in m_SortedNames!!!
  378. if ( allActors )
  379. {
  380. allActors->deleteThis();
  381. }
  382. */
  383. // These events can also be directed at another player or named target, too
  384. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!player" );
  385. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!enemy" );
  386. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!self" );
  387. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!friend" );
  388. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!speechtarget" );
  389. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target1" );
  390. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target2" );
  391. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target3" );
  392. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target4" );
  393. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target5" );
  394. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target6" );
  395. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target7" );
  396. SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target8" );
  397. }
  398. //-----------------------------------------------------------------------------
  399. // Purpose:
  400. // Input : wnd -
  401. // *params -
  402. // Output : static void
  403. //-----------------------------------------------------------------------------
  404. void CBaseEventPropertiesDialog::ParseTags( CEventParams *params )
  405. {
  406. strcpy( params->m_szTagName, "" );
  407. strcpy( params->m_szTagWav, "" );
  408. if ( params->m_bUsesTag )
  409. {
  410. // Parse out the two tokens
  411. char selectedText[ 512 ];
  412. selectedText[ 0 ] = 0;
  413. HWND control = GetControl( IDC_TAGS );
  414. if ( control )
  415. {
  416. SendMessage( control, WM_GETTEXT, (WPARAM)sizeof( selectedText ), (LPARAM)selectedText );
  417. }
  418. ParseFromMemory( selectedText, strlen( selectedText ) );
  419. if ( TokenAvailable() )
  420. {
  421. GetToken( false );
  422. char tagname[ 256 ];
  423. strcpy( tagname, token );
  424. if ( TokenAvailable() )
  425. {
  426. GetToken( false );
  427. char wavename[ 256 ];
  428. strcpy( wavename, token );
  429. // Valid
  430. strcpy( params->m_szTagName, tagname );
  431. strcpy( params->m_szTagWav, wavename );
  432. }
  433. else
  434. {
  435. params->m_bUsesTag = false;
  436. }
  437. }
  438. else
  439. {
  440. params->m_bUsesTag = false;
  441. }
  442. }
  443. }
  444. //-----------------------------------------------------------------------------
  445. // Purpose:
  446. // Input : wnd -
  447. // *params -
  448. // Output : static void
  449. //-----------------------------------------------------------------------------
  450. void CBaseEventPropertiesDialog::UpdateTagRadioButtons( CEventParams *params )
  451. {
  452. if ( params->m_bUsesTag )
  453. {
  454. SendMessage( GetControl( IDC_RELATIVESTART ), BM_SETCHECK, ( WPARAM )BST_CHECKED, (LPARAM)0 );
  455. SendMessage( GetControl( IDC_ABSOLUTESTART ), BM_SETCHECK, ( WPARAM )BST_UNCHECKED, (LPARAM)0 );
  456. }
  457. else
  458. {
  459. SendMessage( GetControl( IDC_ABSOLUTESTART ), BM_SETCHECK, ( WPARAM )BST_CHECKED, (LPARAM)0 );
  460. SendMessage( GetControl( IDC_RELATIVESTART ), BM_SETCHECK, ( WPARAM )BST_UNCHECKED, (LPARAM)0 );
  461. }
  462. }
  463. void CBaseEventPropertiesDialog::GetSplineRect( HWND placeholder, RECT& rcOut )
  464. {
  465. GetWindowRect( placeholder, &rcOut );
  466. RECT rcDlg;
  467. GetWindowRect( m_hDialog, &rcDlg );
  468. OffsetRect( &rcOut, -rcDlg.left, -rcDlg.top );
  469. }
  470. void CBaseEventPropertiesDialog::DrawSpline( HDC hdc, HWND placeholder, CChoreoEvent *e )
  471. {
  472. RECT rcOut;
  473. GetSplineRect( placeholder, rcOut );
  474. HBRUSH bg = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) );
  475. FillRect( hdc, &rcOut, bg );
  476. DeleteObject( bg );
  477. if ( !e )
  478. return;
  479. // Draw spline
  480. float range = ( float )( rcOut.right - rcOut.left );
  481. if ( range <= 1.0f )
  482. return;
  483. float height = ( float )( rcOut.bottom - rcOut.top );
  484. HPEN pen = CreatePen( PS_SOLID, 1, GetSysColor( COLOR_BTNTEXT ) );
  485. HPEN oldPen = (HPEN)SelectObject( hdc, pen );
  486. float duration = e->GetDuration();
  487. float starttime = e->GetStartTime();
  488. for ( int i = 0; i < (int)range; i++ )
  489. {
  490. float frac = ( float )i / ( range - 1 );
  491. float scale = 1.0f - e->GetIntensity( starttime + frac * duration );
  492. int h = ( int ) ( scale * ( height - 1 ) );
  493. if ( i == 0 )
  494. {
  495. MoveToEx( hdc, rcOut.left + i, rcOut.top + h, NULL );
  496. }
  497. else
  498. {
  499. LineTo( hdc, rcOut.left + i, rcOut.top + h );
  500. }
  501. }
  502. SelectObject( hdc, oldPen );
  503. HBRUSH frame = CreateSolidBrush( GetSysColor( COLOR_BTNSHADOW ) );
  504. InflateRect( &rcOut, 1, 1 );
  505. FrameRect( hdc, &rcOut, frame );
  506. DeleteObject( frame );
  507. }
  508. //-----------------------------------------------------------------------------
  509. // Purpose:
  510. // Input : *view -
  511. // *actor -
  512. // Output : int
  513. //-----------------------------------------------------------------------------
  514. int EventProperties( CEventParams *params )
  515. {
  516. int iret = 1;
  517. switch ( params->m_nType )
  518. {
  519. default:
  520. break;
  521. case CChoreoEvent::EXPRESSION:
  522. return EventProperties_Expression( params );
  523. case CChoreoEvent::LOOKAT:
  524. return EventProperties_LookAt( params );
  525. case CChoreoEvent::MOVETO:
  526. return EventProperties_MoveTo( params );
  527. case CChoreoEvent::SPEAK:
  528. return EventProperties_Speak( params );
  529. case CChoreoEvent::GESTURE:
  530. return EventProperties_Gesture( params );
  531. case CChoreoEvent::SEQUENCE:
  532. return EventProperties_Sequence( params );
  533. case CChoreoEvent::FACE:
  534. return EventProperties_Face( params );
  535. case CChoreoEvent::FIRETRIGGER:
  536. return EventProperties_FireTrigger( params );
  537. case CChoreoEvent::FLEXANIMATION:
  538. return EventProperties_FlexAnimation( params );
  539. case CChoreoEvent::SUBSCENE:
  540. return EventProperties_SubScene( params );
  541. case CChoreoEvent::INTERRUPT:
  542. return EventProperties_Interrupt( params );
  543. case CChoreoEvent::PERMIT_RESPONSES:
  544. return EventProperties_PermitResponses( params );
  545. case CChoreoEvent::GENERIC:
  546. return EventProperties_Generic( params );
  547. case CChoreoEvent::CAMERA:
  548. return EventProperties_Camera( params );
  549. }
  550. return iret;
  551. }