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.

858 lines
23 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include <vgui/ISurface.h>
  9. #include <vgui/ILocalize.h>
  10. #include "tf_shareddefs.h"
  11. #include "tf_overview.h"
  12. #include "c_playerresource.h"
  13. #include "c_tf_objective_resource.h"
  14. #include "usermessages.h"
  15. #include "coordsize.h"
  16. #include "clientmode.h"
  17. #include <vgui_controls/AnimationController.h>
  18. #include "voice_status.h"
  19. #include "spectatorgui.h"
  20. #include "c_team_objectiveresource.h"
  21. using namespace vgui;
  22. void __MsgFunc_UpdateRadar( bf_read &msg )
  23. {
  24. if ( !g_pMapOverview )
  25. return;
  26. int iPlayerEntity = msg.ReadByte();
  27. while ( iPlayerEntity > 0 )
  28. {
  29. int x = msg.ReadSBitLong( COORD_INTEGER_BITS-1 ) * 4;
  30. int y = msg.ReadSBitLong( COORD_INTEGER_BITS-1 ) * 4;
  31. int a = msg.ReadSBitLong( 9 );
  32. Vector origin( x, y, 0 );
  33. QAngle angles( 0, a, 0 );
  34. g_pMapOverview->SetPlayerPositions( iPlayerEntity-1, origin, angles );
  35. iPlayerEntity = msg.ReadByte(); // read index for next player
  36. }
  37. }
  38. extern ConVar _overview_mode;
  39. ConVar _cl_minimapzoom( "_cl_minimapzoom", "1", FCVAR_ARCHIVE );
  40. ConVar _overview_mode( "_overview_mode", "1", FCVAR_ARCHIVE, "Overview mode - 0=off, 1=inset, 2=full\n", true, 0, true, 2 );
  41. CTFMapOverview *GetTFOverview( void )
  42. {
  43. return dynamic_cast<CTFMapOverview *>( g_pMapOverview );
  44. }
  45. // overview_togglezoom rotates through 3 levels of zoom for the small map
  46. //-----------------------------------------------------------------------
  47. void ToggleZoom( void )
  48. {
  49. if ( !GetTFOverview() )
  50. return;
  51. GetTFOverview()->ToggleZoom();
  52. }
  53. static ConCommand overview_togglezoom( "overview_togglezoom", ToggleZoom );
  54. // overview_largemap toggles showing the large map
  55. //------------------------------------------------
  56. void ShowLargeMap( void )
  57. {
  58. if ( !GetTFOverview() )
  59. return;
  60. GetTFOverview()->ShowLargeMap();
  61. }
  62. static ConCommand overview_showlargemap( "+overview_largemap", ShowLargeMap );
  63. void HideLargeMap( void )
  64. {
  65. if ( !GetTFOverview() )
  66. return;
  67. GetTFOverview()->HideLargeMap();
  68. }
  69. static ConCommand overview_hidelargemap( "-overview_largemap", HideLargeMap );
  70. //--------------------------------
  71. // map border ?
  72. // icon minimum zoom
  73. // flag swipes
  74. // chatting icon
  75. // voice com icon
  76. //---------------------------------
  77. DECLARE_HUDELEMENT( CTFMapOverview );
  78. ConVar tf_overview_voice_icon_size( "tf_overview_voice_icon_size", "64", FCVAR_ARCHIVE );
  79. //-----------------------------------------------------------------------------
  80. // Purpose:
  81. //-----------------------------------------------------------------------------
  82. CTFMapOverview::CTFMapOverview( const char *pElementName ) : BaseClass( pElementName )
  83. {
  84. InitTeamColorsAndIcons();
  85. m_flIconSize = 96.0f;
  86. m_iLastMode = MAP_MODE_OFF;
  87. m_bDisabled = false;
  88. m_nMapTextureOverlayID = -1;
  89. usermessages->HookMessage( "UpdateRadar", __MsgFunc_UpdateRadar );
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose:
  93. //-----------------------------------------------------------------------------
  94. void CTFMapOverview::Update()
  95. {
  96. UpdateCapturePoints();
  97. BaseClass::Update();
  98. }
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. //-----------------------------------------------------------------------------
  102. void CTFMapOverview::VidInit( void )
  103. {
  104. BaseClass::VidInit();
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose:
  108. //-----------------------------------------------------------------------------
  109. void CTFMapOverview::UpdateCapturePoints()
  110. {
  111. if ( !g_pObjectiveResource )
  112. return;
  113. Color colorGreen( 0,255,0,255 );
  114. for( int i = 0 ; i < g_pObjectiveResource->GetNumControlPoints() ; i++ )
  115. {
  116. // check if CP is visible at all
  117. if( !g_pObjectiveResource->IsCPVisible( i ) )
  118. {
  119. if ( m_CapturePoints[i] != 0 )
  120. {
  121. // remove capture point from map
  122. RemoveObject( m_CapturePoints[i] );
  123. m_CapturePoints[i] = 0;
  124. }
  125. continue;
  126. }
  127. // ok, show CP
  128. int iOwningTeam = g_pObjectiveResource->GetOwningTeam(i);
  129. int iCappingTeam = g_pObjectiveResource->GetCappingTeam(i);
  130. int iOwningIcon = g_pObjectiveResource->GetIconForTeam( i, iOwningTeam );
  131. if ( iOwningIcon <= 0 )
  132. continue; // baah
  133. const char *textureName = GetMaterialNameFromIndex( iOwningIcon );
  134. int objID = m_CapturePoints[i];
  135. if ( objID == 0 )
  136. {
  137. // add object if not already there
  138. objID = m_CapturePoints[i] = AddObject( textureName, 0, -1 );
  139. // objective positions never change (so far)
  140. SetObjectPosition( objID, g_pObjectiveResource->GetCPPosition(i), vec3_angle );
  141. AddObjectFlags( objID, MAP_OBJECT_ALIGN_TO_MAP );
  142. }
  143. SetObjectIcon( objID, textureName, 128.0 );
  144. // draw cap percentage
  145. if( iCappingTeam != TEAM_UNASSIGNED )
  146. {
  147. SetObjectStatus( objID, g_pObjectiveResource->GetCPCapPercentage(i), colorGreen );
  148. }
  149. else
  150. {
  151. SetObjectStatus( objID, -1, colorGreen ); // turn it off
  152. }
  153. }
  154. }
  155. //-----------------------------------------------------------------------------
  156. // Purpose:
  157. //-----------------------------------------------------------------------------
  158. void CTFMapOverview::InitTeamColorsAndIcons()
  159. {
  160. BaseClass::InitTeamColorsAndIcons();
  161. m_TeamColors[TF_TEAM_RED] = COLOR_TF_RED;
  162. m_TeamIcons[TF_TEAM_RED] = AddIconTexture( "sprites/minimap_icons/red_player" );
  163. m_CameraIcons[TF_TEAM_RED] = AddIconTexture( "sprites/minimap_icons/red_camera" );
  164. m_TeamColors[TF_TEAM_BLUE] = COLOR_TF_BLUE;
  165. m_TeamIcons[TF_TEAM_BLUE] = AddIconTexture( "sprites/minimap_icons/blue_player" );
  166. m_CameraIcons[TF_TEAM_BLUE] = AddIconTexture( "sprites/minimap_icons/blue_camera" );
  167. Q_memset( m_flPlayerChatTime, 0, sizeof(m_flPlayerChatTime ) );
  168. m_iVoiceIcon = AddIconTexture( "voice/icntlk_pl" );
  169. m_iChatIcon = AddIconTexture( "sprites/minimap_icons/voiceIcon" );
  170. Q_memset( m_CapturePoints, 0, sizeof(m_CapturePoints) );
  171. }
  172. //-----------------------------------------------------------------------------
  173. // Purpose:
  174. //-----------------------------------------------------------------------------
  175. void CTFMapOverview::DrawCamera()
  176. {
  177. C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
  178. if ( !localPlayer )
  179. return;
  180. int iTexture = m_CameraIcons[localPlayer->GetTeamNumber()];
  181. if ( localPlayer->IsObserver() || iTexture <= 0 )
  182. {
  183. BaseClass::DrawCamera();
  184. }
  185. else
  186. {
  187. MapObject_t obj;
  188. memset( &obj, 0, sizeof(MapObject_t) );
  189. obj.icon = iTexture;
  190. obj.position = localPlayer->GetAbsOrigin();
  191. obj.size = m_flIconSize * 1.5;
  192. obj.angle = localPlayer->EyeAngles();
  193. obj.status = -1;
  194. DrawIcon( &obj );
  195. DrawVoiceIconForPlayer( localPlayer->entindex() - 1 );
  196. }
  197. }
  198. //-----------------------------------------------------------------------------
  199. // Purpose:
  200. //-----------------------------------------------------------------------------
  201. void CTFMapOverview::FireGameEvent( IGameEvent *event )
  202. {
  203. const char * type = event->GetName();
  204. if ( Q_strcmp( type, "player_death" ) == 0 )
  205. {
  206. MapPlayer_t *player = GetPlayerByUserID( event->GetInt( "userid" ) );
  207. if ( player && CanPlayerBeSeen( player ) )
  208. {
  209. // create skull icon for 3 seconds
  210. int handle = AddObject( "sprites/minimap_icons/death", 0, 3 );
  211. SetObjectText( handle, player->name, player->color );
  212. SetObjectPosition( handle, player->position, player->angle );
  213. }
  214. }
  215. else if ( Q_strcmp( type, "game_newmap" ) == 0 )
  216. {
  217. SetMode( _overview_mode.GetInt() );
  218. }
  219. BaseClass::FireGameEvent( event );
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Purpose:
  223. //-----------------------------------------------------------------------------
  224. bool CTFMapOverview::CanPlayerBeSeen( MapPlayer_t *player )
  225. {
  226. // rules that define if you can see a player on the overview or not
  227. C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
  228. if ( !localPlayer || !player )
  229. return false;
  230. // don't draw ourselves
  231. if ( localPlayer->entindex() == (player->index+1) )
  232. return false;
  233. // if local player is on spectator team, he can see everyone
  234. if ( localPlayer->GetTeamNumber() <= TEAM_SPECTATOR )
  235. return true;
  236. // we never track unassigned or real spectators
  237. if ( player->team <= TEAM_SPECTATOR )
  238. return false;
  239. // ingame and as dead player we can only see our own teammates
  240. return ( localPlayer->GetTeamNumber() == player->team );
  241. }
  242. //-----------------------------------------------------------------------------
  243. // Purpose:
  244. //-----------------------------------------------------------------------------
  245. void CTFMapOverview::ShowLargeMap( void )
  246. {
  247. if ( IsDisabled() )
  248. {
  249. return;
  250. }
  251. // remember old mode
  252. m_iLastMode = GetMode();
  253. // if we hit the toggle while full, set to disappear when we release
  254. if ( m_iLastMode == MAP_MODE_FULL )
  255. {
  256. m_iLastMode = MAP_MODE_OFF;
  257. }
  258. SetMode( MAP_MODE_FULL );
  259. }
  260. //-----------------------------------------------------------------------------
  261. // Purpose:
  262. //-----------------------------------------------------------------------------
  263. void CTFMapOverview::HideLargeMap( void )
  264. {
  265. if ( IsDisabled() )
  266. {
  267. return;
  268. }
  269. SetMode( m_iLastMode );
  270. }
  271. //-----------------------------------------------------------------------------
  272. // Purpose:
  273. //-----------------------------------------------------------------------------
  274. void CTFMapOverview::ToggleZoom( void )
  275. {
  276. if ( IsDisabled() )
  277. {
  278. return;
  279. }
  280. if ( GetMode() != MAP_MODE_INSET )
  281. return;
  282. int iZoomLevel = ( _cl_minimapzoom.GetInt() + 1 ) % TF_MAP_ZOOM_LEVELS;
  283. _cl_minimapzoom.SetValue( iZoomLevel );
  284. switch( _cl_minimapzoom.GetInt() )
  285. {
  286. case 0:
  287. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomLevel1" );
  288. break;
  289. case 1:
  290. default:
  291. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomLevel2" );
  292. break;
  293. }
  294. }
  295. //-----------------------------------------------------------------------------
  296. // Purpose:
  297. //-----------------------------------------------------------------------------
  298. void CTFMapOverview::SetMode(int mode)
  299. {
  300. if ( IsDisabled() )
  301. {
  302. return;
  303. }
  304. m_flChangeSpeed = 0; // change size instantly
  305. if ( mode == MAP_MODE_OFF )
  306. {
  307. ShowPanel( false );
  308. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapOff" );
  309. }
  310. else if ( mode == MAP_MODE_INSET )
  311. {
  312. switch( _cl_minimapzoom.GetInt() )
  313. {
  314. case 0:
  315. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomLevel1" );
  316. break;
  317. case 1:
  318. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomLevel2" );
  319. break;
  320. case 2:
  321. default:
  322. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomLevel3" );
  323. break;
  324. }
  325. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  326. if ( pPlayer )
  327. SetFollowEntity( pPlayer->entindex() );
  328. ShowPanel( true );
  329. if ( m_nMode == MAP_MODE_FULL )
  330. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapScaleToSmall" );
  331. else
  332. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "SnapToSmall" );
  333. }
  334. else if ( mode == MAP_MODE_FULL )
  335. {
  336. SetFollowEntity( 0 );
  337. ShowPanel( true );
  338. if ( m_nMode == MAP_MODE_INSET )
  339. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ZoomToLarge" );
  340. else
  341. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "SnapToLarge" );
  342. }
  343. // finally set mode
  344. m_nMode = mode;
  345. // save in a cvar for archive
  346. _overview_mode.SetValue( m_nMode );
  347. UpdateSizeAndPosition();
  348. }
  349. //-----------------------------------------------------------------------------
  350. // Purpose:
  351. //-----------------------------------------------------------------------------
  352. void CTFMapOverview::UpdateSizeAndPosition()
  353. {
  354. // move back up if the spectator menu is not visible
  355. if ( !g_pSpectatorGUI || ( !g_pSpectatorGUI->IsVisible() && GetMode() == MAP_MODE_INSET ) )
  356. {
  357. int x,y,w,h;
  358. GetBounds( x,y,w,h );
  359. y = YRES(5); // hax, align to top of the screen
  360. SetBounds( x,y,w,h );
  361. }
  362. BaseClass::UpdateSizeAndPosition();
  363. }
  364. ConVar cl_voicetest( "cl_voicetest", "0", FCVAR_CHEAT );
  365. ConVar cl_overview_chat_time( "cl_overview_chat_time", "2.0", FCVAR_ARCHIVE );
  366. //-----------------------------------------------------------------------------
  367. // Purpose:
  368. //-----------------------------------------------------------------------------
  369. void CTFMapOverview::PlayerChat( int index )
  370. {
  371. m_flPlayerChatTime[index-1] = gpGlobals->curtime + cl_overview_chat_time.GetFloat();
  372. }
  373. //-----------------------------------------------------------------------------
  374. // Purpose:
  375. //-----------------------------------------------------------------------------
  376. void CTFMapOverview::DrawMapPlayers()
  377. {
  378. BaseClass::DrawMapPlayers();
  379. C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
  380. Assert( localPlayer );
  381. int iLocalPlayer = localPlayer->entindex() - 1;
  382. for ( int i = 0 ; i < MAX_PLAYERS ; i++ )
  383. {
  384. if ( i == iLocalPlayer )
  385. continue;
  386. MapPlayer_t *player = &m_Players[i];
  387. if ( !CanPlayerBeSeen( player ) )
  388. continue;
  389. if ( player->health <= 0 ) // don't draw dead players / spectators
  390. continue;
  391. DrawVoiceIconForPlayer( i );
  392. }
  393. }
  394. //-----------------------------------------------------------------------------
  395. // Purpose:
  396. //-----------------------------------------------------------------------------
  397. void CTFMapOverview::DrawVoiceIconForPlayer( int playerIndex )
  398. {
  399. Assert( playerIndex >= 0 && playerIndex < MAX_PLAYERS );
  400. MapPlayer_t *player = &m_Players[playerIndex];
  401. // if they just sent a chat msg, or are using voice, or did a hand signal or voice command
  402. // draw a chat icon
  403. if ( cl_voicetest.GetInt() || GetClientVoiceMgr()->IsPlayerSpeaking( player->index+1 ) )
  404. {
  405. MapObject_t obj;
  406. memset( &obj, 0, sizeof(MapObject_t) );
  407. obj.icon = m_iVoiceIcon;
  408. obj.position = player->position;
  409. obj.size = tf_overview_voice_icon_size.GetFloat();
  410. obj.status = -1;
  411. DrawIcon( &obj );
  412. }
  413. else if ( m_flPlayerChatTime[player->index] > gpGlobals->curtime )
  414. {
  415. MapObject_t obj;
  416. memset( &obj, 0, sizeof(MapObject_t) );
  417. obj.icon = m_iChatIcon;
  418. obj.position = player->position;
  419. obj.size = tf_overview_voice_icon_size.GetFloat();
  420. obj.status = -1;
  421. DrawIcon( &obj );
  422. }
  423. }
  424. //-----------------------------------------------------------------------------
  425. // Purpose:
  426. //-----------------------------------------------------------------------------
  427. bool CTFMapOverview::DrawIcon( MapObject_t *obj )
  428. {
  429. for ( int i = 0 ; i < MAX_CONTROL_POINTS ; i++ )
  430. {
  431. if ( obj->objectID == m_CapturePoints[i] && obj->objectID != 0 )
  432. {
  433. return DrawCapturePoint( i, obj );
  434. }
  435. }
  436. return BaseClass::DrawIcon( obj );
  437. }
  438. //-----------------------------------------------------------------------------
  439. // Purpose:
  440. //-----------------------------------------------------------------------------
  441. void CTFMapOverview::DrawQuad( Vector pos, int scale, float angle, int textureID, int alpha )
  442. {
  443. Vector offset;
  444. offset.z = 0;
  445. offset.x = -scale; offset.y = scale;
  446. VectorYawRotate( offset, angle, offset );
  447. Vector2D pos1 = WorldToMap( pos + offset );
  448. offset.x = scale; offset.y = scale;
  449. VectorYawRotate( offset, angle, offset );
  450. Vector2D pos2 = WorldToMap( pos + offset );
  451. offset.x = scale; offset.y = -scale;
  452. VectorYawRotate( offset, angle, offset );
  453. Vector2D pos3 = WorldToMap( pos + offset );
  454. offset.x = -scale; offset.y = -scale;
  455. VectorYawRotate( offset, angle, offset );
  456. Vector2D pos4 = WorldToMap( pos + offset );
  457. Vertex_t points[4] =
  458. {
  459. Vertex_t( MapToPanel ( pos1 ), Vector2D(0,0) ),
  460. Vertex_t( MapToPanel ( pos2 ), Vector2D(1,0) ),
  461. Vertex_t( MapToPanel ( pos3 ), Vector2D(1,1) ),
  462. Vertex_t( MapToPanel ( pos4 ), Vector2D(0,1) )
  463. };
  464. surface()->DrawSetColor( 255, 255, 255, alpha );
  465. surface()->DrawSetTexture( textureID );
  466. surface()->DrawTexturedPolygon( 4, points );
  467. }
  468. //-----------------------------------------------------------------------------
  469. // Purpose:
  470. //-----------------------------------------------------------------------------
  471. bool CTFMapOverview::DrawCapturePoint( int iCP, MapObject_t *obj )
  472. {
  473. int textureID = obj->icon;
  474. Vector pos = obj->position;
  475. float scale = obj->size;
  476. Vector2D pospanel = WorldToMap( pos );
  477. pospanel = MapToPanel( pospanel );
  478. if ( !IsInPanel( pospanel ) )
  479. return false; // player is not within overview panel
  480. // draw capture swipe
  481. DrawQuad( pos, scale, 0, textureID, 255 );
  482. int iCappingTeam = g_pObjectiveResource->GetCappingTeam( iCP );
  483. if ( iCappingTeam != TEAM_UNASSIGNED )
  484. {
  485. int iCapperIcon = g_pObjectiveResource->GetCPCappingIcon( iCP );
  486. const char *textureName = GetMaterialNameFromIndex( iCapperIcon );
  487. float flCapPercent = g_pObjectiveResource->GetCPCapPercentage(iCP);
  488. bool bSwipeLeft = ( iCappingTeam == TF_TEAM_RED ) ? true : false;
  489. DrawHorizontalSwipe( pos, scale, AddIconTexture( textureName ), flCapPercent, bSwipeLeft );
  490. }
  491. // fixup for noone is capping, but someone is in the area
  492. int iNumBlue = g_pObjectiveResource->GetNumPlayersInArea( iCP, TF_TEAM_BLUE );
  493. int iNumRed = g_pObjectiveResource->GetNumPlayersInArea( iCP, TF_TEAM_RED );
  494. int iOwningTeam = g_pObjectiveResource->GetOwningTeam( iCP );
  495. if ( iCappingTeam == TEAM_UNASSIGNED )
  496. {
  497. if ( iNumBlue > 0 && iNumRed == 0 && iOwningTeam != TF_TEAM_BLUE )
  498. {
  499. iCappingTeam = TF_TEAM_BLUE;
  500. }
  501. else if ( iNumRed > 0 && iNumBlue == 0 && iOwningTeam != TF_TEAM_RED )
  502. {
  503. iCappingTeam = TF_TEAM_RED;
  504. }
  505. }
  506. if ( iCappingTeam != TEAM_UNASSIGNED )
  507. {
  508. // Draw the number of cappers below the icon
  509. int numPlayers = g_pObjectiveResource->GetNumPlayersInArea( iCP, iCappingTeam );
  510. int requiredPlayers = g_pObjectiveResource->GetRequiredCappers( iCP, iCappingTeam );
  511. if ( requiredPlayers > 1 )
  512. {
  513. numPlayers = MIN( numPlayers, requiredPlayers );
  514. wchar_t wText[6];
  515. _snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"%d", numPlayers );
  516. int wide, tall;
  517. surface()->GetTextSize( m_hIconFont, wText, wide, tall );
  518. int x = pospanel.x-(wide/2);
  519. int y = pospanel.y;
  520. // match the offset that MapOverview uses
  521. y += GetPixelOffset( scale ) + 4;
  522. // draw black shadow text
  523. surface()->DrawSetTextColor( 0, 0, 0, 255 );
  524. surface()->DrawSetTextPos( x+1, y );
  525. surface()->DrawPrintText( wText, wcslen(wText) );
  526. // draw name in color
  527. surface()->DrawSetTextColor( g_PR->GetTeamColor( iCappingTeam ) );
  528. surface()->DrawSetTextPos( x, y );
  529. surface()->DrawPrintText( wText, wcslen(wText) );
  530. }
  531. }
  532. return true;
  533. }
  534. //-----------------------------------------------------------------------------
  535. // Purpose:
  536. //-----------------------------------------------------------------------------
  537. void CTFMapOverview::DrawHorizontalSwipe( Vector pos, int scale, int textureID, float flCapPercentage, bool bSwipeLeft )
  538. {
  539. float flIconSize = scale * 2;
  540. float width = ( flIconSize * flCapPercentage );
  541. float uv1 = 0.0f;
  542. float uv2 = 1.0f;
  543. Vector2D uv11( uv1, uv2 );
  544. Vector2D uv21( flCapPercentage, uv2 );
  545. Vector2D uv22( flCapPercentage, uv1 );
  546. Vector2D uv12( uv1, uv1 );
  547. // reversing the direction of the swipe effect
  548. if ( bSwipeLeft )
  549. {
  550. uv11.x = uv2 - flCapPercentage;
  551. uv21.x = uv2;
  552. uv22.x = uv2;
  553. uv12.x = uv2 - flCapPercentage;
  554. }
  555. float flXPos = pos.x - scale;
  556. float flYPos = pos.y - scale;
  557. Vector upperLeft( flXPos, flYPos, 0 );
  558. Vector upperRight( flXPos + width, flYPos, 0 );
  559. Vector lowerRight( flXPos + width, flYPos + flIconSize, 0 );
  560. Vector lowerLeft ( flXPos, flYPos + flIconSize, 0 );
  561. /// reversing the direction of the swipe effect
  562. if ( bSwipeLeft )
  563. {
  564. upperLeft.x = flXPos + flIconSize - width;
  565. upperRight.x = flXPos + flIconSize;
  566. lowerRight.x = flXPos + flIconSize;
  567. lowerLeft.x = flXPos + flIconSize - width;
  568. }
  569. vgui::Vertex_t vert[4];
  570. Vector2D pos0 = WorldToMap( upperLeft );
  571. vert[0].Init( MapToPanel( pos0 ), uv11 );
  572. Vector2D pos3 = WorldToMap( lowerLeft );
  573. vert[1].Init( MapToPanel( pos3 ), uv12 );
  574. Vector2D pos2 = WorldToMap( lowerRight );
  575. vert[2].Init( MapToPanel( pos2 ), uv22 );
  576. Vector2D pos1 = WorldToMap( upperRight );
  577. vert[3].Init( MapToPanel( pos1 ), uv21 );
  578. surface()->DrawSetColor( 255, 255, 255, 255 );
  579. surface()->DrawSetTexture( textureID );
  580. surface()->DrawTexturedPolygon( 4, vert );
  581. }
  582. //-----------------------------------------------------------------------------
  583. // Purpose:
  584. //-----------------------------------------------------------------------------
  585. void CTFMapOverview::SetMap( const char * levelname )
  586. {
  587. BaseClass::SetMap( levelname );
  588. if ( m_nMapTextureID != -1 )
  589. {
  590. // we found a texture for this map
  591. SetDisabled( false );
  592. SetMode( m_nMode );
  593. }
  594. else
  595. {
  596. // we failed to load a map image
  597. SetDisabled( true );
  598. }
  599. }
  600. //-----------------------------------------------------------------------------
  601. // Purpose:
  602. //-----------------------------------------------------------------------------
  603. bool CTFMapOverview::ShouldDraw( void )
  604. {
  605. if ( IsDisabled() )
  606. {
  607. return false;
  608. }
  609. return BaseClass::ShouldDraw();
  610. }
  611. //-----------------------------------------------------------------------------
  612. // Purpose:
  613. //-----------------------------------------------------------------------------
  614. void CTFMapOverview::Paint()
  615. {
  616. UpdateMapOverlayTexture();
  617. UpdateSizeAndPosition();
  618. UpdateFollowEntity();
  619. UpdateObjects();
  620. UpdatePlayers();
  621. // UpdatePlayerTrails();
  622. DrawMapTexture();
  623. DrawMapOverlayTexture();
  624. // DrawMapPlayerTrails();
  625. DrawObjects();
  626. DrawMapPlayers();
  627. DrawCamera();
  628. Panel::Paint();
  629. }
  630. extern ConVar overview_alpha;
  631. //-----------------------------------------------------------------------------
  632. // Purpose:
  633. //-----------------------------------------------------------------------------
  634. void CTFMapOverview::DrawMapOverlayTexture()
  635. {
  636. // now draw a box around the outside of this panel
  637. int x0, y0, x1, y1;
  638. int wide, tall;
  639. GetSize( wide, tall );
  640. x0 = 0; y0 = 0; x1 = wide - 2; y1 = tall - 2;
  641. if ( m_nMapTextureOverlayID < 0 )
  642. {
  643. return;
  644. }
  645. Vertex_t points[4] =
  646. {
  647. Vertex_t( MapToPanel ( Vector2D(0,0) ), Vector2D(0,0) ),
  648. Vertex_t( MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,0) ), Vector2D(1,0) ),
  649. Vertex_t( MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,OVERVIEW_MAP_SIZE-1) ), Vector2D(1,1) ),
  650. Vertex_t( MapToPanel ( Vector2D(0,OVERVIEW_MAP_SIZE-1) ), Vector2D(0,1) )
  651. };
  652. int alpha = 255.0f * overview_alpha.GetFloat(); clamp( alpha, 1, 255 );
  653. surface()->DrawSetColor( 255,255,255, alpha );
  654. surface()->DrawSetTexture( m_nMapTextureOverlayID );
  655. surface()->DrawTexturedPolygon( 4, points );
  656. }
  657. //-----------------------------------------------------------------------------
  658. // Purpose:
  659. //-----------------------------------------------------------------------------
  660. void CTFMapOverview::UpdateMapOverlayTexture()
  661. {
  662. /*
  663. char tempfile[MAX_PATH];
  664. Q_snprintf( tempfile, sizeof( tempfile ), "overviews/%s_%s_%s_%s", levelname, roundname, capname, teamname );
  665. // TODO release old texture ?
  666. m_nMapTextureOverlayID = surface()->CreateNewTextureID();
  667. //if we have not uploaded yet, lets go ahead and do so
  668. surface()->DrawSetTextureFile( m_nMapTextureOverlayID, tempfile, true, false );
  669. int wide, tall;
  670. surface()->DrawGetTextureSize( m_nMapTextureOverlayID, wide, tall );
  671. if ( wide != tall )
  672. {
  673. DevMsg( 1, "Error! CTFMapOverview::UpdateMapOverlayTexture: map overlay image must be a square.\n" );
  674. m_nMapTextureOverlayID = -1;
  675. return;
  676. }
  677. */
  678. }