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.

3608 lines
84 KiB

  1. // ========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // =============================================================================//
  6. #include "cbase.h"
  7. #include "hudelement.h"
  8. #include "mapoverview.h"
  9. #include "hudelement.h"
  10. #include "hud_macros.h"
  11. #include <filesystem.h>
  12. #include "cs_gamerules.h"
  13. #include "c_team.h"
  14. #include "c_cs_playerresource.h"
  15. #include "c_plantedc4.h"
  16. #include "c_cs_hostage.h"
  17. #include "vtf/vtf.h"
  18. #include "clientmode.h"
  19. #include "voice_status.h"
  20. #include "vgui/ILocalize.h"
  21. #include <vstdlib/vstrtools.h>
  22. #include "view.h"
  23. #include "gameui_util.h"
  24. #include "HUD/sfhudfreezepanel.h"
  25. #include "HUD/sfhudwinpanel.h"
  26. #include "HUD/sfhud_teamcounter.h"
  27. #include "c_plantedc4.h"
  28. #include "c_world.h"
  29. #include "gametypes.h"
  30. #include "hltvreplaysystem.h"
  31. #include "clientmode_shared.h"
  32. //memdbgon must be the last include file in a .cpp file!!!
  33. #include "tier0/memdbgon.h"
  34. static const float NOTSPOTTEDRADIUS = 1400.0f;
  35. static const float DEAD_FADE_TIME = 4.0f;
  36. static const float GHOST_FADE_TIME = 6.0f;
  37. static const float BOMB_FADE_TIME = 8.0f;
  38. static const float DEFUSER_FADE_TIME = 8.0f;
  39. static const float TIMER_INIT = -1000.0f;
  40. static const int INVALID_INDEX = -1;
  41. ConVar mapoverview_allow_client_draw( "mapoverview_allow_client_draw", "0", FCVAR_RELEASE, "Allow a client to draw on the map overview" );
  42. ConVar mapoverview_allow_grid_usage( "mapoverview_allow_grid_usage", "0", FCVAR_RELEASE, "When set to 1, allows turning on the (experimental) grid for drawing." );
  43. ConVar mapoverview_icon_scale( "mapoverview_icon_scale", "1.0", FCVAR_RELEASE | FCVAR_ARCHIVE, "Sets the icon scale multiplier for the overview map. Valid values are 0.5 to 3.0.", true, 0.5f, true, 3.0f );
  44. /*******************************************************************************
  45. * data definitions
  46. */
  47. static const char* playerIconNames[] = {
  48. "Greande_HE",
  49. "Greande_FLASH",
  50. "Greande_SMOKE",
  51. "Greande_MOLOTOV",
  52. "Greande_DECOY",
  53. "Defuser",
  54. "AbovePlayer",
  55. "BelowPlayer",
  56. "Flashed",
  57. "PlayerNumber",
  58. "PlayerNameCT",
  59. "PlayerNameT",
  60. // below this, the icons are rotated
  61. "PlayerIndicator",
  62. "SpeakingOnMap",
  63. "HostageTransitOnMap",
  64. "CTOnMap",
  65. "CTDeath",
  66. "CTGhost",
  67. "TOnMap",
  68. "TDeath",
  69. "TGhost",
  70. "EnemyOnMap",
  71. "EnemyDeath",
  72. "EnemyGhost",
  73. "HostageOnMap",
  74. "HostageDeath",
  75. "HostageGhost",
  76. "DirectionalIndicator",
  77. "MuzzleFlash",
  78. "LowHealth",
  79. "Selected",
  80. NULL
  81. };
  82. static const char* hostageIconNames[] = {
  83. "HostageDead",
  84. "HostageRescued",
  85. "HostageAlive",
  86. "HostageTransit",
  87. NULL
  88. };
  89. static const char* overviewIconNames[] = {
  90. "BombPlantedIcon",
  91. "BombPlantedIconMedium",
  92. "BombPlantedIconFast",
  93. "HostageZoneIcon",
  94. NULL
  95. };
  96. static const char *desiredMessageNames[] = {
  97. "game_newmap",
  98. "round_start",
  99. "player_connect",
  100. "player_info",
  101. "player_team",
  102. "player_spawn",
  103. "player_death",
  104. "player_disconnect",
  105. "hostage_killed",
  106. "hostage_rescued",
  107. "bomb_defused",
  108. "bomb_exploded",
  109. "bomb_planted",
  110. "bomb_pickup",
  111. "bomb_dropped",
  112. "defuser_pickup",
  113. "defuser_dropped",
  114. "decoy_started",
  115. "decoy_detonate",
  116. "hegrenade_detonate",
  117. "flashbang_detonate",
  118. "smokegrenade_detonate",
  119. "smokegrenade_expired",
  120. "inferno_startburn",
  121. "inferno_expire",
  122. "bot_takeover",
  123. NULL
  124. };
  125. enum DESIRED_MESSAGE_INDICES
  126. {
  127. GAME_NEWMAP,
  128. ROUND_POST_START,
  129. PLAYER_CONNECT,
  130. PLAYER_INFO,
  131. PLAYER_TEAM,
  132. PLAYER_SPAWN,
  133. PLAYER_DEATH,
  134. PLAYER_DISCONNECT,
  135. HOSTAGE_KILLED,
  136. HOSTAGE_RESCUED,
  137. BOMB_DEFUSED,
  138. BOMB_EXPLODED,
  139. BOMB_PLANTED,
  140. BOMB_PICKUP,
  141. BOMB_DROPPED,
  142. DEFUSER_PICKUP,
  143. DEFUSER_DROPPED,
  144. DECOY_STARTED,
  145. DECOY_DETONATE,
  146. HE_DETONATE,
  147. FLASH_DETONATE,
  148. SMOKE_DETONATE,
  149. SMOKE_EXPIRE,
  150. MOLOTOV_DETONATE,
  151. MOLOTOV_EXPIRE,
  152. BOT_TAKEOVER,
  153. };
  154. /***************************************************
  155. * callback and function declarations
  156. */
  157. static bool maplessfunc( const char* const & s1, const char* const & s2 )
  158. {
  159. return V_strcmp( s1, s2 ) < 0;
  160. }
  161. CUtlMap<const char*, int> SFMapOverview::m_messageMap( maplessfunc );
  162. DECLARE_HUDELEMENT( SFMapOverview );
  163. DECLARE_HUD_MESSAGE( SFMapOverview, ProcessSpottedEntityUpdate );
  164. SFUI_BEGIN_GAME_API_DEF
  165. SFUI_DECL_METHOD( MapLoaded ),
  166. SFUI_DECL_METHOD( ToggleOverviewMap ),
  167. SFUI_DECL_METHOD( AllowMapDrawing ),
  168. SFUI_DECL_METHOD( GetWorldDistance ),
  169. //SFUI_DECL_METHOD( GetNavPath ),
  170. SFUI_END_GAME_API_DEF( SFMapOverview, MapOverview );
  171. CON_COMMAND( drawoverviewmap, "Draws the overview map" )
  172. {
  173. ( GET_HUDELEMENT( SFMapOverview ) )->ShowMapOverview( true );
  174. }
  175. CON_COMMAND( hideoverviewmap, "Hides the overview map" )
  176. {
  177. ( GET_HUDELEMENT( SFMapOverview ) )->ShowMapOverview( false );
  178. }
  179. /**********************************************************************
  180. * SFMapOverviewIconPackage code
  181. */
  182. SFMapOverview::SFMapOverviewIconPackage::SFMapOverviewIconPackage()
  183. {
  184. ClearAll();
  185. }
  186. SFMapOverview::SFMapOverviewIconPackage::~SFMapOverviewIconPackage()
  187. {
  188. }
  189. void SFMapOverview::SFMapOverviewIconPackage::ClearAll( void )
  190. {
  191. m_IconPackage = NULL;
  192. m_IconPackageRotate = NULL;
  193. V_memset( m_Icons, 0, sizeof( m_Icons ) );
  194. m_pScaleformUI = NULL;
  195. m_iCurrentVisibilityFlags = 0;
  196. m_fCurrentAlpha = 1.0f;
  197. m_Health = 0;
  198. m_iPlayerType = 0;
  199. m_iIndex = INVALID_INDEX;
  200. m_iEntityID = 0;
  201. m_bIsActive = false;
  202. m_bOffMap = true;
  203. m_bIsLowHealth = false;
  204. m_bIsSelected = false;
  205. m_bIsFlashed = false;
  206. m_bIsFiring = false;
  207. m_bIsSpotted = false;
  208. m_fGhostTime = TIMER_INIT;
  209. m_bIsDead = false;
  210. m_fDeadTime = TIMER_INIT;
  211. m_fGrenExpireTime = TIMER_INIT;
  212. m_IconPackType = ICON_PACK_PLAYER;
  213. m_bIsRescued = false;
  214. m_bIsOnLocalTeam = false;
  215. m_fRoundStartTime = TIMER_INIT;
  216. m_wcName[0] = 0;
  217. m_Position = vec3_origin;
  218. m_Angle.Init();
  219. m_nGrenadeType = -1;
  220. m_bIsDefuser = false;
  221. }
  222. void SFMapOverview::SFMapOverviewIconPackage::Init( IScaleformUI* pui, SFVALUE iconPackage )
  223. {
  224. m_pScaleformUI = pui;
  225. m_IconPackage = pui->CreateValue( iconPackage );
  226. m_IconPackageRotate = m_pScaleformUI->Value_GetMember( iconPackage, "RotatedLayer" );
  227. for ( uint64 i = 0; i < PI_NUM_ICONS && playerIconNames[i] != NULL; i++ )
  228. {
  229. if ( i < PI_FIRST_ROTATED )
  230. {
  231. m_Icons[i] = pui->Value_GetMember( m_IconPackage, playerIconNames[i] );
  232. }
  233. else
  234. {
  235. if ( m_IconPackageRotate )
  236. {
  237. m_Icons[i] = pui->Value_GetMember( m_IconPackageRotate, playerIconNames[i] );
  238. }
  239. }
  240. if ( m_Icons[i] )
  241. {
  242. pui->Value_SetVisible( m_Icons[i], ( m_iCurrentVisibilityFlags & ( 1ll << i ) ) != 0 );
  243. }
  244. }
  245. ScaleformDisplayInfo displayInfo;
  246. displayInfo.SetAlpha( m_fCurrentAlpha * 100.0f );
  247. displayInfo.SetVisibility( m_iCurrentVisibilityFlags != 0 );
  248. m_pScaleformUI->Value_SetDisplayInfo( m_IconPackage, &displayInfo );
  249. }
  250. void SFMapOverview::SFMapOverviewIconPackage::NukeFromOrbit( SFMapOverview* pSFUI )
  251. {
  252. if ( pSFUI->FlashAPIIsValid() )
  253. {
  254. pSFUI->SafeReleaseSFVALUE( m_IconPackage );
  255. pSFUI->SafeReleaseSFVALUE( m_IconPackageRotate );
  256. for ( uint64 i = 0; i < PI_NUM_ICONS; i++ )
  257. {
  258. pSFUI->SafeReleaseSFVALUE( m_Icons[i] );
  259. }
  260. }
  261. ClearAll();
  262. }
  263. void SFMapOverview::SFMapOverviewIconPackage::StartRound( void )
  264. {
  265. m_Health = 100;
  266. m_bOffMap = false;
  267. m_bIsLowHealth = false;
  268. m_bIsSelected = false;
  269. m_bIsFlashed = false;
  270. m_bIsFiring = false;
  271. m_bIsSpotted = false;
  272. m_fGhostTime = TIMER_INIT;
  273. m_bIsDead = false;
  274. m_fDeadTime = TIMER_INIT;
  275. m_fGrenExpireTime = TIMER_INIT;
  276. m_bIsRescued = false;
  277. m_nAboveOrBelow = R_SAMELEVEL;
  278. m_fRoundStartTime = gpGlobals->curtime;
  279. m_nGrenadeType = -1;
  280. m_Position = vec3_origin;
  281. m_Angle.Init();
  282. SetAlpha( 0 );
  283. SetVisibilityFlags( 0 );
  284. }
  285. bool SFMapOverview::SFMapOverviewIconPackage::IsVisible( void )
  286. {
  287. return ( m_fCurrentAlpha != 0 && m_iCurrentVisibilityFlags != 0 );
  288. }
  289. void SFMapOverview::SFMapOverviewIconPackage::SetIsPlayer( bool value )
  290. {
  291. m_bIsPlayer = value;
  292. }
  293. void SFMapOverview::SFMapOverviewIconPackage::SetIsSpeaking ( bool value )
  294. {
  295. m_bIsSpeaking = value && m_bIsOnLocalTeam;
  296. }
  297. void SFMapOverview::SFMapOverviewIconPackage::SetIsOffMap( bool value )
  298. {
  299. m_bOffMap = value;
  300. }
  301. void SFMapOverview::SFMapOverviewIconPackage::SetIsLowHealth( bool value )
  302. {
  303. m_bIsLowHealth = value;
  304. }
  305. void SFMapOverview::SFMapOverviewIconPackage::SetIsSelected( bool value )
  306. {
  307. m_bIsSelected = value;
  308. }
  309. void SFMapOverview::SFMapOverviewIconPackage::SetIsFlashed( bool value )
  310. {
  311. m_bIsFlashed = value;
  312. }
  313. void SFMapOverview::SFMapOverviewIconPackage::SetIsFiring( bool value )
  314. {
  315. m_bIsFiring = value;
  316. }
  317. void SFMapOverview::SFMapOverviewIconPackage::SetIsAboveOrBelow( int value )
  318. {
  319. m_nAboveOrBelow = value;
  320. }
  321. void SFMapOverview::SFMapOverviewIconPackage::SetIsMovingHostage( bool value )
  322. {
  323. m_bIsMovingHostage = value;
  324. }
  325. void SFMapOverview::SFMapOverviewIconPackage::SetIsRescued( bool value )
  326. {
  327. m_bIsRescued = value;
  328. }
  329. void SFMapOverview::SFMapOverviewIconPackage::SetIsOnLocalTeam( bool value )
  330. {
  331. m_bIsOnLocalTeam = value;
  332. }
  333. void SFMapOverview::SFMapOverviewIconPackage::SetIsControlledBot( void )
  334. {
  335. m_bIsDead = true;
  336. m_bIsSpotted = true;
  337. m_fDeadTime = TIMER_INIT;
  338. m_fGhostTime = TIMER_INIT;
  339. }
  340. void SFMapOverview::SFMapOverviewIconPackage::SetIsDead( bool value )
  341. {
  342. if ( value != m_bIsDead )
  343. {
  344. if ( value )
  345. {
  346. // SetIsSpotted( true );
  347. m_fDeadTime = gpGlobals->curtime;
  348. }
  349. else
  350. {
  351. m_fDeadTime = TIMER_INIT;
  352. }
  353. m_bIsDead = value;
  354. }
  355. }
  356. void SFMapOverview::SFMapOverviewIconPackage::SetGrenadeExpireTime( float value )
  357. {
  358. if ( value )
  359. {
  360. m_fGrenExpireTime = value;
  361. }
  362. }
  363. void SFMapOverview::SFMapOverviewIconPackage::SetIsSpotted( bool value )
  364. {
  365. if ( gpGlobals->curtime - m_fRoundStartTime > 0.25f )
  366. {
  367. if ( value != m_bIsSpotted )
  368. {
  369. if ( !value )
  370. {
  371. m_fGhostTime = gpGlobals->curtime;
  372. }
  373. else
  374. {
  375. m_fGhostTime = TIMER_INIT;
  376. }
  377. m_bIsSpotted = value;
  378. }
  379. }
  380. }
  381. void SFMapOverview::SFMapOverviewIconPackage::SetPlayerTeam( int team )
  382. {
  383. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  384. if( pLocalPlayer == NULL )
  385. {
  386. return;
  387. }
  388. int newType;
  389. switch( team )
  390. {
  391. case TEAM_UNASSIGNED:
  392. newType = PI_HOSTAGE;
  393. break;
  394. case TEAM_TERRORIST:
  395. newType = pLocalPlayer->GetAssociatedTeamNumber() == TEAM_TERRORIST || pLocalPlayer->IsObserver() ? PI_T : PI_ENEMY;
  396. break;
  397. case TEAM_CT:
  398. newType =pLocalPlayer->GetAssociatedTeamNumber() == TEAM_CT || pLocalPlayer->IsObserver() ? PI_CT : PI_ENEMY;
  399. break;
  400. case TEAM_SPECTATOR:
  401. default:
  402. newType = 0;
  403. break;
  404. }
  405. if ( m_iPlayerType != newType )
  406. {
  407. m_iPlayerType = newType;
  408. SetVisibilityFlags( 0 );
  409. }
  410. }
  411. void SFMapOverview::SFMapOverviewIconPackage::SetupIconsFromStates( void )
  412. {
  413. uint64 flags = 0;
  414. float alpha = 1;
  415. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  416. if( pLocalPlayer == NULL )
  417. return;
  418. bool bShowAll = false;
  419. if ( pLocalPlayer->IsSpectator() || g_bEngineIsHLTV )
  420. bShowAll = true;
  421. if ( m_iPlayerType != 0 )
  422. {
  423. flags = 1ll << m_iPlayerType;
  424. if ( m_bIsDead )
  425. {
  426. if ( m_Position.x == 0 && m_Position.y == 0 || !m_bIsSpotted )
  427. {
  428. flags = 0;
  429. }
  430. else
  431. {
  432. float deadElapsedTime = gpGlobals->curtime - m_fDeadTime;
  433. if ( deadElapsedTime > DEAD_FADE_TIME )
  434. {
  435. m_fDeadTime = TIMER_INIT;
  436. flags = 0;
  437. }
  438. else
  439. {
  440. alpha = clamp( 1.0f - deadElapsedTime / DEAD_FADE_TIME, 0.0f, 1.0f );
  441. // the shift below changes the icon to be the dead icon ( the X )
  442. // rescued hostages are marked as dead, but we don't want to show
  443. // the X in that case. So if this guy is a hostage and has been resuced
  444. // we want to skip the code that changes the icon to the dead icon.
  445. bool isRescuedNotDead = IsHostageType() && m_bIsRescued;
  446. if ( !isRescuedNotDead )
  447. {
  448. flags <<= 1;
  449. }
  450. }
  451. }
  452. }
  453. else if ( !m_bIsSpotted )
  454. {
  455. float ghostElapsedTime = gpGlobals->curtime - m_fGhostTime;
  456. if ( ghostElapsedTime > GHOST_FADE_TIME )
  457. {
  458. m_fGhostTime = TIMER_INIT;
  459. flags = 0;
  460. }
  461. else
  462. {
  463. alpha = clamp( 1.0f - ghostElapsedTime / GHOST_FADE_TIME, 0.0f, 1.0f );
  464. // shifting to show the "ghost" icon
  465. flags <<= 2;
  466. }
  467. }
  468. else
  469. {
  470. if ( m_bIsMovingHostage )
  471. {
  472. flags |= 1 << PI_HOSTAGE_MOVING;
  473. }
  474. if ( m_bIsSpeaking )
  475. {
  476. flags |= 1 << PI_SPEAKING;
  477. }
  478. if ( m_bIsLowHealth )
  479. {
  480. flags |= 1 << PI_LOWHEALTH;
  481. }
  482. if ( m_bIsSelected )
  483. {
  484. flags |= 1 << PI_SELECTED;
  485. }
  486. if ( m_bIsFlashed )
  487. {
  488. flags |= 1 << PI_FLASHED;
  489. }
  490. if ( m_bIsFiring )
  491. {
  492. flags |= 1 << PI_MUZZLE_FLASH;
  493. }
  494. bool bSameTeamOrSpec = false;
  495. if ( m_iPlayerType == PI_CT && (pLocalPlayer->GetAssociatedTeamNumber() == TEAM_CT || bShowAll) )
  496. {
  497. flags |= 1 << PI_PLAYER_NAME_CT;
  498. bSameTeamOrSpec = true;
  499. }
  500. if ( m_iPlayerType == PI_T && (pLocalPlayer->GetAssociatedTeamNumber() == TEAM_TERRORIST || bShowAll) )
  501. {
  502. flags |= 1 << PI_PLAYER_NAME_T;
  503. bSameTeamOrSpec = true;
  504. }
  505. if ( bSameTeamOrSpec )
  506. flags |= 1 << PI_PLAYER_NUMBER;
  507. flags |= 1 << PI_DIRECTION_INDICATOR;
  508. if ( m_bIsPlayer )
  509. {
  510. flags |= 1 << PI_PLAYER_INDICATOR;
  511. }
  512. if ( m_fGrenExpireTime != TIMER_INIT )
  513. {
  514. if ( m_fGrenExpireTime < gpGlobals->curtime )
  515. {
  516. m_fGrenExpireTime = TIMER_INIT;
  517. m_bIsSpotted = false;
  518. }
  519. }
  520. }
  521. }
  522. else if ( m_bIsDefuser )
  523. {
  524. // only render after we have received a position update
  525. if ( m_Position != vec3_origin )
  526. {
  527. flags |= 1 << PI_DEFUSER;
  528. if ( m_bIsSpotted )
  529. {
  530. m_fGhostTime = TIMER_INIT;
  531. alpha = 1.0f;
  532. }
  533. else
  534. {
  535. float ghostElapsedTime = gpGlobals->curtime - m_fGhostTime;
  536. if ( ghostElapsedTime > GHOST_FADE_TIME )
  537. {
  538. m_fGhostTime = TIMER_INIT;
  539. flags = 0;
  540. }
  541. else
  542. {
  543. alpha = clamp( 1.0f - ghostElapsedTime / GHOST_FADE_TIME, 0.0f, 1.0f );
  544. }
  545. }
  546. }
  547. }
  548. else if ( m_nGrenadeType > -1 )
  549. {
  550. flags = 1ll << m_nGrenadeType;
  551. float flFadeTime = 1.0f;
  552. float deadElapsedTime = (m_fGrenExpireTime <= 0 ) ? 0 : gpGlobals->curtime - m_fGrenExpireTime;
  553. if ( deadElapsedTime > flFadeTime )
  554. {
  555. m_fGrenExpireTime = TIMER_INIT;
  556. flags = 0;
  557. }
  558. else
  559. {
  560. alpha = clamp( 1.0f - deadElapsedTime / flFadeTime, 0.0f, 1.0f );
  561. }
  562. }
  563. //GetPlayerSlotIndex( m_iEntityID/*engine->GetPlayerForUserID( m_iEntityID )*/ );
  564. SetAlpha( alpha );
  565. SetVisibilityFlags( flags );
  566. }
  567. void SFMapOverview::SFMapOverviewIconPackage::SetVisibilityFlags( uint64 newFlags )
  568. {
  569. newFlags &= ( ( 1ll << PI_NUM_ICONS )-1 );
  570. uint64 diffFlags = m_iCurrentVisibilityFlags ^ newFlags;
  571. if ( diffFlags )
  572. {
  573. if ( m_IconPackage )
  574. {
  575. bool wantVisible = ( newFlags != 0 );
  576. if ( ( m_iCurrentVisibilityFlags != 0 ) != wantVisible )
  577. {
  578. m_pScaleformUI->Value_SetVisible( m_IconPackage, wantVisible );
  579. }
  580. for ( uint64 i = 0; i < PI_NUM_ICONS && ( diffFlags != 0 ); i++, diffFlags >>= 1 )
  581. {
  582. if ( (diffFlags & 1) && ( m_Icons[i] ) )
  583. {
  584. Assert( m_Icons[i] );
  585. if ( m_Icons[i] )
  586. {
  587. m_pScaleformUI->Value_SetVisible( m_Icons[i], ( newFlags & ( 1ll << i ) ) != 0 );
  588. }
  589. }
  590. }
  591. }
  592. m_iCurrentVisibilityFlags = newFlags;
  593. }
  594. }
  595. void SFMapOverview::SFMapOverviewIconPackage::SetAlpha( float newAlpha )
  596. {
  597. if ( newAlpha != m_fCurrentAlpha )
  598. {
  599. m_fCurrentAlpha = newAlpha;
  600. if ( m_IconPackage )
  601. {
  602. ScaleformDisplayInfo displayInfo;
  603. displayInfo.SetAlpha( m_fCurrentAlpha * 100.0f );
  604. m_pScaleformUI->Value_SetDisplayInfo( m_IconPackage, &displayInfo );
  605. }
  606. }
  607. }
  608. void SFMapOverview::SFMapOverviewIconPackage::SetIsDefuse( bool bValue )
  609. {
  610. m_bIsDefuser = bValue;
  611. }
  612. void SFMapOverview::SFMapOverviewIconPackage::SetGrenadeType( int nValue )
  613. {
  614. m_nGrenadeType = nValue;
  615. }
  616. /**********************************************************************
  617. **********************************************************************
  618. **********************************************************************
  619. **********************************************************************
  620. **********************************************************************
  621. * SFHudHostageIcon
  622. */
  623. SFMapOverview::SFMapOverviewHostageIcons::SFMapOverviewHostageIcons()
  624. {
  625. m_IconPackage = NULL;
  626. V_memset( m_Icons, 0,sizeof( m_Icons ) );
  627. m_iCurrentIcon = HI_UNUSED;
  628. }
  629. SFMapOverview::SFMapOverviewHostageIcons::~SFMapOverviewHostageIcons()
  630. {
  631. }
  632. void SFMapOverview::SFMapOverviewHostageIcons::Init( IScaleformUI* scaleformui, SFVALUE iconPackage )
  633. {
  634. m_pScaleformUI = scaleformui;
  635. m_IconPackage = scaleformui->CreateValue( iconPackage );
  636. for ( int i = 0; i < HI_NUM_ICONS && hostageIconNames[i] != NULL; i++ )
  637. {
  638. m_Icons[i] = m_pScaleformUI->Value_GetMember( m_IconPackage, hostageIconNames[i] );
  639. if ( m_Icons[i] )
  640. {
  641. m_pScaleformUI->Value_SetVisible( m_Icons[i], m_iCurrentIcon == i );
  642. }
  643. }
  644. m_pScaleformUI->Value_SetVisible( m_IconPackage, m_iCurrentIcon != HI_UNUSED );
  645. }
  646. void SFMapOverview::SFMapOverviewHostageIcons::SetStatus( int status )
  647. {
  648. if ( status != m_iCurrentIcon )
  649. {
  650. if ( m_IconPackage )
  651. {
  652. if ( m_iCurrentIcon != HI_UNUSED )
  653. {
  654. assert(m_Icons[m_iCurrentIcon]);
  655. m_pScaleformUI->Value_SetVisible( m_Icons[m_iCurrentIcon], false );
  656. }
  657. else
  658. {
  659. m_pScaleformUI->Value_SetVisible( m_IconPackage, true );
  660. }
  661. m_iCurrentIcon = status;
  662. if ( m_iCurrentIcon != HI_UNUSED )
  663. {
  664. assert(m_Icons[m_iCurrentIcon]);
  665. m_pScaleformUI->Value_SetVisible( m_Icons[m_iCurrentIcon], true );
  666. }
  667. else
  668. {
  669. m_pScaleformUI->Value_SetVisible( m_IconPackage, false );
  670. }
  671. }
  672. }
  673. }
  674. void SFMapOverview::SFMapOverviewHostageIcons::ReleaseHandles( SFMapOverview* pradar )
  675. {
  676. if ( m_IconPackage && pradar->FlashAPIIsValid() )
  677. {
  678. pradar->SafeReleaseSFVALUE( m_IconPackage );
  679. for ( int i = 0; i < HI_NUM_ICONS; i++ )
  680. {
  681. pradar->SafeReleaseSFVALUE( m_Icons[i] );
  682. }
  683. }
  684. }
  685. /**********************************************************************
  686. **********************************************************************
  687. **********************************************************************
  688. **********************************************************************
  689. **********************************************************************
  690. * SFMapOverview Code
  691. *
  692. */
  693. SFMapOverview::SFMapOverview( const char *value ) : SFHudFlashInterface( value ),
  694. m_fMapSize( 1.0f ),
  695. m_fMapScale( 1.0f ),
  696. m_fPixelToRadarScale( 1.0f ),
  697. m_fWorldToPixelScale( 1.0f ),
  698. m_fWorldToRadarScale( 1.0f ),
  699. m_RadarModule( NULL ),
  700. m_Radar( NULL ),
  701. m_IconTranslation( NULL ),
  702. m_IconRotation( NULL ),
  703. m_MapRotation( NULL ),
  704. m_MapTranslation( NULL ),
  705. m_iNumGoalIcons( 0 ),
  706. m_iLastPlayerIndex( INVALID_INDEX ),
  707. m_iLastHostageIndex( INVALID_INDEX ),
  708. m_iLastGrenadeIndex( INVALID_INDEX ),
  709. m_iLastDefuserIndex( INVALID_INDEX ),
  710. m_RadarViewpointWorld( vec3_origin ),
  711. m_RadarViewpointMap( vec3_origin ),
  712. m_RadarRotation( 0 ),
  713. m_BombPosition( vec3_origin ),
  714. m_DefuserPosition( vec3_origin ),
  715. m_iCurrentVisibilityFlags( 0 ),
  716. m_fBombSeenTime( TIMER_INIT ),
  717. m_fBombAlpha( 0 ),
  718. m_fDefuserSeenTime( TIMER_INIT ),
  719. m_fDefuserAlpha( 0.0f ),
  720. m_LocationText( NULL ),
  721. m_bFlashLoading( false ),
  722. m_bFlashReady( false ),
  723. m_bGotPlayerIcons( false ),
  724. m_bShowingHostageZone( false ),
  725. m_bBombPlanted( false ),
  726. m_bBombDropped( false ),
  727. m_nBombEntIndex( -1 ),
  728. m_bShowBombHighlight( false ),
  729. m_bShowMapOverview( false ),
  730. m_bShowAll( false ),
  731. m_bShowingDashboard( false ),
  732. m_iObserverMode( OBS_MODE_NONE ),
  733. m_bTrackDefusers( false ),
  734. m_bVisible( false )
  735. {
  736. //SetHiddenBits( HIDEHUD_RADAR );
  737. m_bWantLateUpdate = true;
  738. m_cDesiredMapName[0] = 0;
  739. m_cLoadedMapName[0] = 0;
  740. m_wcLocationString[0] = 0;
  741. V_memset( m_BombZoneIcons, 0, sizeof( m_BombZoneIcons ) );
  742. V_memset( m_HostageZoneIcons, 0, sizeof( m_HostageZoneIcons ) );
  743. V_memset( m_GoalIcons, 0, sizeof( m_GoalIcons ) );
  744. V_memset( m_HostageStatusIcons, 0, sizeof( m_HostageStatusIcons ) );
  745. V_memset( m_AllIcons, 0, sizeof( m_AllIcons ) );
  746. m_EntitySpotted.ClearAll();
  747. }
  748. SFMapOverview::~SFMapOverview()
  749. {
  750. }
  751. /**************************************
  752. * hud element functions
  753. */
  754. void SFMapOverview::Init( void )
  755. {
  756. // register for events as client listener
  757. const char** pwalk = &desiredMessageNames[0];
  758. while( *pwalk != NULL )
  759. {
  760. ListenForGameEvent( *pwalk );
  761. pwalk++;
  762. }
  763. if ( ! m_messageMap.Count() )
  764. {
  765. const char** pwalk = &desiredMessageNames[0];
  766. int i = 0;
  767. while( *pwalk != NULL )
  768. {
  769. m_messageMap.Insert( *pwalk++, i++ );
  770. }
  771. }
  772. HOOK_HUD_MESSAGE( SFMapOverview, ProcessSpottedEntityUpdate );
  773. }
  774. void SFMapOverview::LevelInit( void )
  775. {
  776. if ( !m_bFlashReady && !m_bFlashLoading )
  777. {
  778. SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFMapOverview, this, MapOverview );
  779. }
  780. }
  781. void SFMapOverview::LevelShutdown( void )
  782. {
  783. if ( m_bFlashReady || m_bFlashLoading )
  784. {
  785. RemoveFlashElement();
  786. }
  787. }
  788. bool SFMapOverview::ShouldDraw( void )
  789. {
  790. if ( IsTakingAFreezecamScreenshot() || !m_bShowMapOverview )
  791. return false;
  792. return cl_drawhud.GetBool();// && CHudElement::ShouldDraw();
  793. }
  794. bool SFMapOverview::CanShowOverview( void )
  795. {
  796. CBasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  797. if ( pLocalPlayer && (pLocalPlayer->GetObserverMode() == OBS_MODE_NONE ||
  798. pLocalPlayer->GetObserverMode() == OBS_MODE_DEATHCAM || pLocalPlayer->GetObserverMode() == OBS_MODE_FREEZECAM ) )
  799. {
  800. return false;
  801. }
  802. if ( g_HltvReplaySystem.GetHltvReplayDelay() )
  803. return false;
  804. return true;
  805. }
  806. void SFMapOverview::SetActive( bool bActive )
  807. {
  808. if ( bActive == true && !CanShowOverview() )
  809. return;
  810. Show( bActive );
  811. CHudElement::SetActive( bActive );
  812. }
  813. void SFMapOverview::Show( bool show )
  814. {
  815. if ( show == true && !CanShowOverview() )
  816. return;
  817. if ( m_bFlashReady && show != m_bActive )
  818. {
  819. WITH_SLOT_LOCKED
  820. {
  821. if ( show )
  822. {
  823. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", NULL, 0 );
  824. m_bVisible = true;
  825. }
  826. else
  827. {
  828. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", NULL, 0 );
  829. m_bVisible = false;
  830. }
  831. }
  832. UpdateAllPlayerNamesAndNumbers();
  833. }
  834. }
  835. void SFMapOverview::ShowPanel( bool bShow )
  836. {
  837. if ( bShow != m_bVisible )
  838. {
  839. if ( bShow )
  840. {
  841. Show( true );
  842. }
  843. else
  844. {
  845. Show( false );
  846. }
  847. }
  848. }
  849. //
  850. // /**********************************
  851. // * initialization code goes here
  852. // */
  853. //
  854. //
  855. // these overload the ScaleformFlashInterfaceMixin class
  856. void SFMapOverview::FlashLoaded( void )
  857. {
  858. m_RadarModule = m_pScaleformUI->Value_GetMember( m_FlashAPI, "RadarModule" );
  859. if ( !m_RadarModule )
  860. {
  861. return;
  862. }
  863. m_Radar = m_pScaleformUI->Value_GetMember( m_RadarModule, "Radar" );
  864. if ( m_Radar )
  865. {
  866. m_MapRotation = m_pScaleformUI->Value_GetMember( m_Radar, "MapRotation" );
  867. if ( m_MapRotation )
  868. {
  869. m_MapTranslation =m_pScaleformUI->Value_GetMember( m_MapRotation, "MapTranslation" );
  870. }
  871. m_IconRotation = m_pScaleformUI->Value_GetMember( m_Radar, "IconRotation" );
  872. if ( !m_IconRotation )
  873. {
  874. return;
  875. }
  876. m_IconTranslation = m_pScaleformUI->Value_GetMember( m_IconRotation, "IconTranslation" );
  877. if ( !m_IconTranslation )
  878. {
  879. return;
  880. }
  881. char cHostageZoneIconName[20] = {"HZone0"};
  882. for ( int i = 0; i < MAX_HOSTAGE_RESCUES; i++ )
  883. {
  884. cHostageZoneIconName[5] = '0'+i;
  885. m_HostageZoneIcons[i] = m_pScaleformUI->Value_GetMember( m_IconTranslation, cHostageZoneIconName );
  886. }
  887. m_BombZoneIcons[0] = m_pScaleformUI->Value_GetMember( m_IconTranslation, "BombZoneA" );
  888. m_BombZoneIcons[1] = m_pScaleformUI->Value_GetMember( m_IconTranslation, "BombZoneB" );
  889. }
  890. SFVALUE dashboard = m_pScaleformUI->Value_GetMember( m_RadarModule, "Dashboard" );
  891. m_AllIcons[RI_DASHBOARD] = dashboard;
  892. if ( !dashboard )
  893. {
  894. return;
  895. }
  896. char hostageIconName[20] = {"HostageStatusX"};
  897. int index = 0;
  898. SFVALUE hostageIcon;
  899. do
  900. {
  901. hostageIconName[13] = index + '1';
  902. hostageIcon = m_pScaleformUI->Value_GetMember( dashboard, hostageIconName );
  903. if ( hostageIcon == NULL )
  904. {
  905. break;
  906. }
  907. else
  908. {
  909. m_HostageStatusIcons[index].Init( m_pScaleformUI, hostageIcon );
  910. SafeReleaseSFVALUE( hostageIcon );
  911. }
  912. } while( ++index < MAX_HOSTAGES );
  913. for ( int i = 0; overviewIconNames[i] != NULL; i++ )
  914. {
  915. m_AllIcons[i] = m_pScaleformUI->Value_GetMember( dashboard, overviewIconNames[i] );
  916. }
  917. // m_LocationText = m_pScaleformUI->TextObject_MakeTextObjectFromMember( dashboard, "Location" );
  918. // if ( m_LocationText )
  919. // {
  920. // m_LocationText->SetText( m_wcLocationString );
  921. // }
  922. }
  923. void SFMapOverview::FlashReady( void )
  924. {
  925. // these aren't ready until after the first frame, so they have to get connected here instead of in
  926. // FlashLoaded()
  927. m_AllIcons[RI_BOMB_ICON_PACKAGE] = m_pScaleformUI->Value_Invoke( m_IconTranslation, "createBombPack", NULL, 0 );
  928. if ( m_AllIcons[RI_BOMB_ICON_PACKAGE] )
  929. {
  930. m_AllIcons[RI_BOMB_ICON_DROPPED] = m_pScaleformUI->Value_GetMember( m_AllIcons[RI_BOMB_ICON_PACKAGE], "DroppedBomb" );
  931. m_AllIcons[RI_BOMB_ICON_PLANTED] = m_pScaleformUI->Value_GetMember( m_AllIcons[RI_BOMB_ICON_PACKAGE], "PlantedBomb" );
  932. m_AllIcons[RI_BOMB_ICON_BOMB_CT] = m_pScaleformUI->Value_GetMember( m_AllIcons[RI_BOMB_ICON_PACKAGE], "BombCT" );
  933. m_AllIcons[RI_BOMB_ICON_BOMB_T] = m_pScaleformUI->Value_GetMember( m_AllIcons[RI_BOMB_ICON_PACKAGE], "BombT" );
  934. m_AllIcons[RI_BOMB_ICON_BOMB_ABOVE] = m_pScaleformUI->Value_GetMember( m_AllIcons[RI_BOMB_ICON_PACKAGE], "BombAbove" );
  935. m_AllIcons[RI_BOMB_ICON_BOMB_BELOW] = m_pScaleformUI->Value_GetMember( m_AllIcons[RI_BOMB_ICON_PACKAGE], "BombBelow" );
  936. }
  937. for ( int i = 0; i < RI_NUM_ICONS; i++ )
  938. {
  939. if ( m_AllIcons[i] )
  940. {
  941. m_pScaleformUI->Value_SetVisible( m_AllIcons[i], false );
  942. }
  943. }
  944. m_bFlashLoading = false;
  945. m_bFlashReady = true;
  946. ResetForNewMap();
  947. // there will be a map waiting for us to load
  948. FlashLoadMap( NULL );
  949. if ( m_bActive )
  950. {
  951. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", NULL, 0 );
  952. }
  953. else
  954. {
  955. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", NULL, 0 );
  956. }
  957. }
  958. void SFMapOverview::LazyCreateGoalIcons( void )
  959. {
  960. if ( m_bGotGoalIcons || !m_bFlashReady )
  961. {
  962. return;
  963. }
  964. // The goal entities don't exist on the client, so we have to get them from the CS Resource.
  965. C_CS_PlayerResource *pCSPR = ( C_CS_PlayerResource* )GameResources();
  966. if ( !pCSPR )
  967. {
  968. return;
  969. }
  970. m_iNumGoalIcons = 0;
  971. if ( CSGameRules()->IsBombDefuseMap() )
  972. {
  973. Vector bombA = pCSPR->GetBombsiteAPosition();
  974. if( bombA != vec3_origin )
  975. {
  976. m_GoalIcons[m_iNumGoalIcons].m_Position = bombA;
  977. m_GoalIcons[m_iNumGoalIcons].m_Icon = m_BombZoneIcons[0];
  978. m_pScaleformUI->Value_SetVisible( m_GoalIcons[m_iNumGoalIcons].m_Icon, true );
  979. m_iNumGoalIcons++;
  980. }
  981. Vector bombB = pCSPR->GetBombsiteBPosition();
  982. if( bombB != vec3_origin )
  983. {
  984. m_GoalIcons[m_iNumGoalIcons].m_Position = bombB;
  985. m_GoalIcons[m_iNumGoalIcons].m_Icon = m_BombZoneIcons[1];
  986. m_pScaleformUI->Value_SetVisible( m_GoalIcons[m_iNumGoalIcons].m_Icon, true );
  987. m_iNumGoalIcons++;
  988. }
  989. }
  990. else if ( CSGameRules()->IsHostageRescueMap() )
  991. {
  992. for( int rescueIndex = 0; rescueIndex < MAX_HOSTAGE_RESCUES; rescueIndex++ )
  993. {
  994. int hIndex = 0;
  995. Vector hostageI = pCSPR->GetHostageRescuePosition( rescueIndex );
  996. if( hostageI != vec3_origin )
  997. {
  998. m_GoalIcons[m_iNumGoalIcons].m_Position = hostageI;
  999. m_GoalIcons[m_iNumGoalIcons].m_Icon = m_HostageZoneIcons[hIndex++];
  1000. m_pScaleformUI->Value_SetVisible( m_GoalIcons[m_iNumGoalIcons].m_Icon, true );
  1001. m_iNumGoalIcons++;
  1002. }
  1003. }
  1004. }
  1005. m_bGotGoalIcons = true;
  1006. }
  1007. bool SFMapOverview::PreUnloadFlash( void )
  1008. {
  1009. if ( m_IconTranslation )
  1010. {
  1011. m_pScaleformUI->Value_InvokeWithoutReturn( m_IconTranslation, "removeBombPack", NULL, 0 );
  1012. }
  1013. for ( int i = 0; i < MAX_BOMB_ZONES; i++ )
  1014. {
  1015. SafeReleaseSFVALUE( m_BombZoneIcons[i] );
  1016. }
  1017. for ( int i = 0; i < MAX_HOSTAGE_RESCUES; i++ )
  1018. {
  1019. SafeReleaseSFVALUE( m_HostageZoneIcons[i] );
  1020. }
  1021. while( m_iLastPlayerIndex >= 0 )
  1022. {
  1023. RemovePlayer( m_iLastPlayerIndex );
  1024. }
  1025. while( m_iLastHostageIndex >= 0 )
  1026. {
  1027. RemoveHostage( m_iLastHostageIndex );
  1028. }
  1029. RemoveAllDefusers();
  1030. RemoveAllGrenades();
  1031. SafeReleaseSFVALUE( m_MapRotation );
  1032. SafeReleaseSFVALUE( m_MapTranslation );
  1033. SafeReleaseSFVALUE( m_RadarModule );
  1034. SafeReleaseSFVALUE( m_Radar );
  1035. SafeReleaseSFVALUE( m_IconTranslation );
  1036. SafeReleaseSFVALUE( m_IconRotation );
  1037. SafeReleaseSFTextObject( m_LocationText );
  1038. int index = 0;
  1039. while( m_HostageStatusIcons[index].m_IconPackage )
  1040. {
  1041. m_HostageStatusIcons[index++].ReleaseHandles( this );
  1042. }
  1043. for ( int i =0 ; i < RI_NUM_ICONS; i++ )
  1044. {
  1045. SafeReleaseSFVALUE( m_AllIcons[i] );
  1046. }
  1047. m_bFlashReady = false;
  1048. m_cDesiredMapName[0] = 0;
  1049. m_cLoadedMapName[0] = 0;
  1050. m_bActive = false;
  1051. return true;
  1052. }
  1053. // /*********************************************************
  1054. // * set up the background map
  1055. // */
  1056. void SFMapOverview::SetMap( const char* pMapName )
  1057. {
  1058. FlashLoadMap( pMapName );
  1059. KeyValues* MapKeyValues = new KeyValues( pMapName );
  1060. char tempfile[MAX_PATH];
  1061. Q_snprintf( tempfile, sizeof( tempfile ), "resource/overviews/%s.txt", pMapName );
  1062. if ( !MapKeyValues->LoadFromFile( g_pFullFileSystem, tempfile, "GAME" ) )
  1063. {
  1064. DevMsg( 1, "Error! CMapOverview::SetMap: couldn't load file %s.\n", tempfile );
  1065. m_MapOrigin.x = 0;
  1066. m_MapOrigin.y = 0;
  1067. return;
  1068. }
  1069. // TODO release old texture ?
  1070. m_MapOrigin.x = MapKeyValues->GetInt( "pos_x" );
  1071. m_MapOrigin.y = MapKeyValues->GetInt( "pos_y" );
  1072. m_MapOrigin.z = 0;
  1073. m_fMapScale = MapKeyValues->GetFloat( "scale", 1.0f );
  1074. m_fWorldToPixelScale = 1.0f / m_fMapScale;
  1075. m_fWorldToRadarScale = m_fWorldToPixelScale * m_fPixelToRadarScale;
  1076. MapKeyValues->deleteThis();
  1077. }
  1078. void SFMapOverview::FlashLoadMap( const char* pMapName )
  1079. {
  1080. const char* pMapToLoad = pMapName ? pMapName : m_cDesiredMapName;
  1081. if ( V_strcmp( pMapToLoad, m_cLoadedMapName ) )
  1082. {
  1083. if ( m_bFlashReady )
  1084. {
  1085. if ( pMapToLoad != m_cDesiredMapName )
  1086. {
  1087. V_strncpy( m_cDesiredMapName, pMapToLoad, sizeof( m_cDesiredMapName )+1 );
  1088. }
  1089. WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
  1090. {
  1091. m_pScaleformUI->ValueArray_SetElement( args, 0, pMapToLoad );
  1092. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "loadMap", args, 1 );
  1093. }
  1094. }
  1095. else
  1096. {
  1097. if ( pMapToLoad != m_cDesiredMapName )
  1098. {
  1099. V_strncpy( m_cDesiredMapName, pMapToLoad, sizeof( m_cDesiredMapName )+1 );
  1100. }
  1101. }
  1102. }
  1103. }
  1104. void SFMapOverview::MapLoaded( SCALEFORM_CALLBACK_ARGS_DECL )
  1105. {
  1106. // flash passes in the scaledsize / image size
  1107. m_fMapSize = ( float )pui->Params_GetArgAsNumber( obj, 0 );
  1108. m_fPixelToRadarScale = ( float )pui->Params_GetArgAsNumber( obj, 1 );
  1109. // m_MapOrigin.x = -(m_fMapSize/2);
  1110. // m_MapOrigin.y = -(m_fMapSize/2);
  1111. m_fWorldToRadarScale = m_fWorldToPixelScale * m_fPixelToRadarScale;
  1112. V_strncpy( m_cLoadedMapName, m_cDesiredMapName, sizeof( m_cLoadedMapName )+1 );
  1113. //Get the world's extent
  1114. C_World *world = GetClientWorldEntity();
  1115. if ( !world )
  1116. return;
  1117. Vector worldCenter = ( world->m_WorldMins + world->m_WorldMaxs ) * 0.5f;
  1118. }
  1119. void SFMapOverview::ToggleOverviewMap( SCALEFORM_CALLBACK_ARGS_DECL )
  1120. {
  1121. ShowMapOverview( !IsMapOverviewShown() );
  1122. }
  1123. // /**********************************************
  1124. // * reset functions
  1125. // */
  1126. //
  1127. //
  1128. void SFMapOverview::ResetForNewMap( void )
  1129. {
  1130. if ( m_bFlashReady )
  1131. {
  1132. for ( int i = 0; i < 2; i++ )
  1133. {
  1134. m_pScaleformUI->Value_SetVisible( m_BombZoneIcons[i], false );
  1135. }
  1136. for ( int i = 0; i < MAX_HOSTAGE_RESCUES; i++ )
  1137. {
  1138. m_pScaleformUI->Value_SetVisible( m_HostageZoneIcons[i], false );
  1139. }
  1140. while( m_iLastHostageIndex >= 0 )
  1141. {
  1142. RemoveHostage( m_iLastHostageIndex );
  1143. }
  1144. int index = 0;
  1145. while( m_HostageStatusIcons[index].m_IconPackage && ( index < MAX_HOSTAGES ) )
  1146. {
  1147. m_HostageStatusIcons[index++].SetStatus( SFMapOverviewHostageIcons::HI_UNUSED );
  1148. }
  1149. RemoveAllGrenades();
  1150. RemoveAllDefusers();
  1151. }
  1152. m_iNumGoalIcons = 0;
  1153. m_bGotGoalIcons = false;
  1154. ResetRoundVariables();
  1155. }
  1156. void SFMapOverview::ResetRoundVariables( bool bResetGlobalStates )
  1157. {
  1158. SetVisibilityFlags( 0 );
  1159. SetLocationText( NULL );
  1160. m_RadarViewpointWorld = vec3_origin;
  1161. m_RadarViewpointMap = vec3_origin;
  1162. m_RadarRotation = 0;
  1163. m_fBombSeenTime = TIMER_INIT;
  1164. m_fBombAlpha = 0.0f;
  1165. m_fDefuserSeenTime = TIMER_INIT;
  1166. m_fDefuserAlpha = 0.0f;
  1167. m_bShowingHostageZone = false;
  1168. m_bShowBombHighlight = false;
  1169. m_bShowingDashboard = false;
  1170. m_bShowAll = false;
  1171. m_iObserverMode = OBS_MODE_NONE;
  1172. ApplySpectatorModes(); // reapply here to make sure it stays when it's supposed to
  1173. ConVarRef mp_defuser_allocation( "mp_defuser_allocation" );
  1174. m_bTrackDefusers = ( mp_defuser_allocation.GetInt() == DefuserAllocation::Random );
  1175. if ( bResetGlobalStates )
  1176. {
  1177. m_nBombEntIndex = -1;
  1178. m_BombPosition = vec3_origin;
  1179. m_DefuserPosition = vec3_origin;
  1180. m_bBombIsSpotted = false;
  1181. m_bBombPlanted = false;
  1182. m_bBombDropped = false;
  1183. m_bBombExploded = false;
  1184. m_bBombDefused = false;
  1185. }
  1186. m_EntitySpotted.ClearAll();
  1187. CBasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  1188. if ( pLocalPlayer && (pLocalPlayer->GetObserverMode() == OBS_MODE_NONE ) )
  1189. ShowMapOverview( false );
  1190. }
  1191. void SFMapOverview::ShowMapOverview( bool bValue )
  1192. {
  1193. if ( bValue == true && !CanShowOverview() )
  1194. return;
  1195. ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal();
  1196. if ( mode )
  1197. {
  1198. mode->ReloadScheme();
  1199. }
  1200. m_bShowMapOverview = bValue;
  1201. }
  1202. void SFMapOverview::ResetRadar( bool bResetGlobalStates )
  1203. {
  1204. for ( int i = 0; i <= m_iLastPlayerIndex; i++ )
  1205. {
  1206. ResetPlayer( i );
  1207. }
  1208. if ( CSGameRules()->IsHostageRescueMap() )
  1209. {
  1210. RemoveStaleHostages();
  1211. for ( int i = 0; i <= m_iLastHostageIndex; i++ )
  1212. {
  1213. ResetHostage( i );
  1214. }
  1215. int index = 0;
  1216. while( m_HostageStatusIcons[index].m_IconPackage && ( index < MAX_HOSTAGES ) )
  1217. {
  1218. m_HostageStatusIcons[index++].SetStatus( SFMapOverviewHostageIcons::HI_UNUSED );
  1219. }
  1220. }
  1221. if ( bResetGlobalStates )
  1222. {
  1223. RemoveAllGrenades();
  1224. RemoveAllDefusers();
  1225. }
  1226. ResetRoundVariables( bResetGlobalStates );
  1227. }
  1228. void SFMapOverview::ResetRound( void )
  1229. {
  1230. ResetRadar( true );
  1231. RefreshGraphs();
  1232. }
  1233. void SFMapOverview::RefreshGraphs( void )
  1234. {
  1235. g_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "onRefresh", 0, NULL );
  1236. }
  1237. // /*****************************************************
  1238. // * player icon loading / creating
  1239. // */
  1240. //
  1241. bool SFMapOverview::LazyUpdateIconArray( SFMapOverviewIconPackage* pArray, int lastIndex )
  1242. {
  1243. bool result = true;
  1244. int i;
  1245. SFMapOverviewIconPackage* pwalk;
  1246. for ( pwalk = pArray, i = 0; i <= lastIndex; i++, pwalk++ )
  1247. {
  1248. if ( pwalk->m_bIsActive && !pwalk->m_IconPackage )
  1249. {
  1250. if ( !LazyCreateIconPackage( pwalk ) )
  1251. {
  1252. // keep going, but remember that at least one wasn't loaded correctly
  1253. result = false;
  1254. }
  1255. }
  1256. }
  1257. return result;
  1258. }
  1259. void SFMapOverview::LazyCreatePlayerIcons( void )
  1260. {
  1261. if ( !m_bFlashReady || m_bGotPlayerIcons )
  1262. return;
  1263. // the following code looks odd, but it insures that all three of the LazyUpdate calls are made
  1264. // even if m_bGotPlayerIcons becomes false early.
  1265. m_bGotPlayerIcons = LazyUpdateIconArray( m_Players, m_iLastPlayerIndex );
  1266. m_bGotPlayerIcons = LazyUpdateIconArray( m_Hostages, m_iLastHostageIndex ) && m_bGotPlayerIcons;
  1267. m_bGotPlayerIcons = LazyUpdateIconArray( m_Grenades, m_iLastGrenadeIndex ) && m_bGotPlayerIcons;
  1268. m_bGotPlayerIcons = LazyUpdateIconArray( m_Defusers, m_iLastDefuserIndex ) && m_bGotPlayerIcons;
  1269. }
  1270. bool SFMapOverview::LazyCreateIconPackage( SFMapOverviewIconPackage* pIconPack )
  1271. {
  1272. if ( m_bFlashReady && pIconPack->m_bIsActive && !pIconPack->m_IconPackage )
  1273. {
  1274. SFVALUE result = NULL;
  1275. WITH_SFVALUEARRAY_SLOT_LOCKED( args, 2 )
  1276. {
  1277. m_pScaleformUI->ValueArray_SetElement( args, 0, pIconPack->m_iIndex );
  1278. m_pScaleformUI->ValueArray_SetElement( args, 1, pIconPack->m_IconPackType );
  1279. result = m_pScaleformUI->Value_Invoke( m_IconTranslation, "overviewCreateIconPack", args, 2 );
  1280. pIconPack->Init( m_pScaleformUI, result );
  1281. if ( result )
  1282. {
  1283. m_pScaleformUI->ReleaseValue( result );
  1284. }
  1285. }
  1286. return true;
  1287. }
  1288. else
  1289. {
  1290. return false;
  1291. }
  1292. }
  1293. void SFMapOverview::InitIconPackage( SFMapOverviewIconPackage* pPlayer, int iAbsoluteIndex, ICON_PACK_TYPE iconType )
  1294. {
  1295. if ( pPlayer->m_bIsActive && m_pScaleformUI )
  1296. {
  1297. RemoveIconPackage( pPlayer );
  1298. }
  1299. pPlayer->m_IconPackType = iconType;
  1300. pPlayer->m_iIndex = iAbsoluteIndex;
  1301. pPlayer->m_bIsActive = true;
  1302. pPlayer->StartRound();
  1303. if ( !pPlayer->m_IconPackage && !LazyCreateIconPackage( pPlayer ) )
  1304. {
  1305. m_bGotPlayerIcons = false;
  1306. }
  1307. }
  1308. void SFMapOverview::RemoveIconPackage( SFMapOverviewIconPackage* pPackage )
  1309. {
  1310. if ( pPackage->m_bIsActive && m_pScaleformUI )
  1311. {
  1312. if ( m_bFlashReady && pPackage->m_IconPackage )
  1313. {
  1314. WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
  1315. {
  1316. m_pScaleformUI->ValueArray_SetElement( args, 0, pPackage->m_IconPackage );
  1317. m_pScaleformUI->Value_InvokeWithoutReturn( m_IconTranslation, "removeIconPack", args, 1 );
  1318. }
  1319. }
  1320. WITH_SLOT_LOCKED
  1321. {
  1322. pPackage->NukeFromOrbit( this );
  1323. }
  1324. }
  1325. }
  1326. // /**********************************************
  1327. // * player and hostage initialization and creation
  1328. // */
  1329. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::CreatePlayer( int index )
  1330. {
  1331. SFMapOverviewIconPackage* pPackage = GetRadarPlayer( index );
  1332. InitIconPackage( pPackage, index, ICON_PACK_PLAYER );
  1333. m_iLastPlayerIndex = MAX( index, m_iLastPlayerIndex );
  1334. return pPackage;
  1335. }
  1336. void SFMapOverview::ResetPlayer( int index )
  1337. {
  1338. SFMapOverviewIconPackage* pPackage = GetRadarPlayer( index );
  1339. if ( pPackage->m_bIsActive )
  1340. {
  1341. pPackage->StartRound();
  1342. }
  1343. UpdatePlayerNameAndNumber( pPackage );
  1344. }
  1345. void SFMapOverview::RemovePlayer( int index )
  1346. {
  1347. RemoveIconPackage( GetRadarPlayer( index ) );
  1348. if ( index == m_iLastPlayerIndex )
  1349. {
  1350. while( m_iLastPlayerIndex >= 0 && !m_Players[m_iLastPlayerIndex].m_bIsActive )
  1351. {
  1352. m_iLastPlayerIndex--;
  1353. }
  1354. }
  1355. UpdateAllPlayerNamesAndNumbers();
  1356. }
  1357. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::CreateHostage( int index )
  1358. {
  1359. SFMapOverviewIconPackage* pPackage = GetRadarHostage( index );
  1360. InitIconPackage( pPackage, index, ICON_PACK_HOSTAGE );
  1361. m_iLastHostageIndex = MAX( index, m_iLastHostageIndex );
  1362. return pPackage;
  1363. }
  1364. void SFMapOverview::ResetHostage( int index )
  1365. {
  1366. SFMapOverviewIconPackage* pPackage = GetRadarHostage( index );
  1367. if ( pPackage->m_bIsActive )
  1368. {
  1369. pPackage->StartRound();
  1370. }
  1371. }
  1372. void SFMapOverview::RemoveStaleHostages( void )
  1373. {
  1374. // Remove hostages that are no longer tracked by the player resource (hostages that have died)
  1375. C_CS_PlayerResource *pCSPR = ( C_CS_PlayerResource* )GameResources();
  1376. if ( !pCSPR )
  1377. {
  1378. return;
  1379. }
  1380. for ( int index = 0; index < MAX_HOSTAGES; index++ )
  1381. {
  1382. SFMapOverviewIconPackage* pPackage = GetRadarHostage( index );
  1383. if ( pPackage->m_bIsActive )
  1384. {
  1385. bool bRemove = true;
  1386. for( int i = 0; i < MAX_HOSTAGES; i++ )
  1387. {
  1388. if ( pCSPR->GetHostageEntityID( i ) == pPackage->m_iEntityID )
  1389. {
  1390. bRemove = false;
  1391. break;
  1392. }
  1393. }
  1394. if ( bRemove )
  1395. {
  1396. RemoveHostage( index );
  1397. }
  1398. }
  1399. }
  1400. }
  1401. void SFMapOverview::RemoveHostage( int index )
  1402. {
  1403. RemoveIconPackage( GetRadarHostage( index ) );
  1404. if ( index == m_iLastHostageIndex )
  1405. {
  1406. while( m_iLastHostageIndex >= 0 && !m_Hostages[m_iLastHostageIndex].m_bIsActive )
  1407. {
  1408. m_iLastHostageIndex--;
  1409. }
  1410. }
  1411. }
  1412. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::CreateGrenade( int entityID, int nGrenadeType )
  1413. {
  1414. SFMapOverviewIconPackage* pPackage = NULL;
  1415. int index = m_iLastGrenadeIndex+1;
  1416. for ( int i = 0; i <= m_iLastGrenadeIndex; i++ )
  1417. {
  1418. if ( !m_Grenades[i].m_bIsActive )
  1419. {
  1420. index = i;
  1421. break;
  1422. }
  1423. }
  1424. if ( index < MAX_GRENADES )
  1425. {
  1426. pPackage = GetRadarGrenade( index );
  1427. InitIconPackage( pPackage, index, ICON_PACK_GRENADES );
  1428. pPackage->m_iEntityID = entityID;
  1429. pPackage->m_fRoundStartTime = TIMER_INIT;
  1430. m_iLastGrenadeIndex = MAX( index, m_iLastGrenadeIndex );
  1431. }
  1432. return pPackage;
  1433. }
  1434. void SFMapOverview::RemoveAllGrenades( void )
  1435. {
  1436. for ( int i = 0; i <= m_iLastGrenadeIndex; i++ )
  1437. {
  1438. if ( m_Grenades[i].m_bIsActive )
  1439. {
  1440. RemoveGrenade( i );
  1441. }
  1442. }
  1443. }
  1444. void SFMapOverview::RemoveGrenade( int index )
  1445. {
  1446. RemoveIconPackage( GetRadarGrenade( index ) );
  1447. if ( index == m_iLastGrenadeIndex )
  1448. {
  1449. while( m_iLastGrenadeIndex >= 0 && !m_Grenades[m_iLastGrenadeIndex].m_bIsActive )
  1450. {
  1451. m_iLastGrenadeIndex--;
  1452. }
  1453. }
  1454. }
  1455. SFMapOverview::SFMapOverviewIconPackage * SFMapOverview::GetDefuser( int nEntityID, bool bCreateIfNotFound )
  1456. {
  1457. SFMapOverviewIconPackage * pResult = NULL;
  1458. int nIndex = GetDefuseIndexFromEntityID( nEntityID );
  1459. if ( nIndex != INVALID_INDEX )
  1460. {
  1461. pResult = GetRadarDefuser( nIndex );
  1462. }
  1463. if ( pResult == NULL && bCreateIfNotFound )
  1464. {
  1465. pResult = CreateDefuser( nEntityID );
  1466. }
  1467. return pResult;
  1468. }
  1469. void SFMapOverview::SetDefuserPos( int nEntityID, int x, int y, int z, int a )
  1470. {
  1471. if ( !m_bTrackDefusers )
  1472. {
  1473. return;
  1474. }
  1475. SFMapOverviewIconPackage * pDefuser = GetDefuser( nEntityID, true );
  1476. AssertMsg( pDefuser != NULL, "Defuser not found. Update failed." );
  1477. if ( pDefuser )
  1478. {
  1479. pDefuser->m_Position.Init( x, y, z ) ;
  1480. pDefuser->SetAlpha( 1.0f );
  1481. SetIconPackagePosition( pDefuser );
  1482. }
  1483. }
  1484. // defusers attached to players will update during the PlacePlayer phase
  1485. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::CreateDefuser( int nEntityID )
  1486. {
  1487. if ( !m_bTrackDefusers )
  1488. {
  1489. return NULL;
  1490. }
  1491. SFMapOverviewIconPackage* pPackage = NULL;
  1492. int index = m_iLastDefuserIndex+1;
  1493. AssertMsg( GetDefuseIndexFromEntityID( nEntityID ) == INVALID_INDEX, "Defuser entity ID already exists." );
  1494. for ( int i = 0; i <= m_iLastDefuserIndex; i++ )
  1495. {
  1496. if ( !m_Defusers[i].m_bIsActive )
  1497. {
  1498. index = i;
  1499. break;
  1500. }
  1501. }
  1502. if ( index < MAX_PLAYERS )
  1503. {
  1504. pPackage = GetRadarDefuser( index );
  1505. InitIconPackage( pPackage, index, ICON_PACK_DEFUSER );
  1506. pPackage->m_iEntityID = nEntityID;
  1507. pPackage->m_fRoundStartTime = TIMER_INIT;
  1508. pPackage->SetIsSpotted( false );
  1509. pPackage->SetIsDefuse( true );
  1510. pPackage->m_Position = vec3_origin;
  1511. m_iLastDefuserIndex = MAX( index, m_iLastDefuserIndex );
  1512. }
  1513. else
  1514. {
  1515. AssertMsg( false, "m_Defusers array is full" );
  1516. }
  1517. return pPackage;
  1518. }
  1519. void SFMapOverview::RemoveAllDefusers( void )
  1520. {
  1521. for ( int i = 0; i <= m_iLastDefuserIndex; i++ )
  1522. {
  1523. if ( m_Defusers[i].m_bIsActive )
  1524. {
  1525. RemoveDefuser( i );
  1526. }
  1527. }
  1528. }
  1529. void SFMapOverview::RemoveDefuser( int index )
  1530. {
  1531. RemoveIconPackage( GetRadarDefuser( index ) );
  1532. if ( index == m_iLastDefuserIndex )
  1533. {
  1534. while( m_iLastDefuserIndex >= 0 && !m_Defusers[m_iLastDefuserIndex].m_bIsActive )
  1535. {
  1536. m_iLastDefuserIndex--;
  1537. }
  1538. }
  1539. }
  1540. void SFMapOverview::SetPlayerTeam( int index, int team )
  1541. {
  1542. SFMapOverviewIconPackage* pPlayer = GetRadarPlayer( index );
  1543. pPlayer->SetPlayerTeam( team );
  1544. }
  1545. int SFMapOverview::GetPlayerIndexFromUserID( int userID )
  1546. {
  1547. int nEntityID = engine->GetPlayerForUserID( userID );
  1548. for ( int i = 0; i <= m_iLastPlayerIndex; i++ )
  1549. {
  1550. if ( m_Players[i].m_bIsActive && m_Players[i].m_iEntityID == nEntityID )
  1551. {
  1552. return i;
  1553. }
  1554. }
  1555. return INVALID_INDEX;
  1556. }
  1557. int SFMapOverview::GetHostageIndexFromHostageEntityID( int entityID )
  1558. {
  1559. for ( int i = 0; i <= m_iLastHostageIndex; i++ )
  1560. {
  1561. if ( m_Hostages[i].m_bIsActive && m_Hostages[i].m_iEntityID == entityID )
  1562. {
  1563. return i;
  1564. }
  1565. }
  1566. return INVALID_INDEX;
  1567. }
  1568. int SFMapOverview::GetGrenadeIndexFromEntityID( int entityID )
  1569. {
  1570. for ( int i = 0; i <= m_iLastGrenadeIndex; i++ )
  1571. {
  1572. if ( m_Grenades[i].m_bIsActive && m_Grenades[i].m_iEntityID == entityID )
  1573. {
  1574. return i;
  1575. }
  1576. }
  1577. return INVALID_INDEX;
  1578. }
  1579. int SFMapOverview::GetDefuseIndexFromEntityID( int nEntityID )
  1580. {
  1581. for ( int i = 0; i <= m_iLastDefuserIndex; i++ )
  1582. {
  1583. if ( m_Defusers[i].m_bIsActive && m_Defusers[i].m_iEntityID == nEntityID )
  1584. {
  1585. return i;
  1586. }
  1587. }
  1588. return INVALID_INDEX;
  1589. }
  1590. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::GetRadarPlayer( int index )
  1591. {
  1592. return &m_Players[index];
  1593. }
  1594. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::GetRadarHostage( int index )
  1595. {
  1596. return &m_Hostages[index];
  1597. }
  1598. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::GetRadarGrenade( int index )
  1599. {
  1600. return &m_Grenades[index];
  1601. }
  1602. SFMapOverview::SFMapOverviewIconPackage* SFMapOverview::GetRadarDefuser( int index )
  1603. {
  1604. return &m_Defusers[index];
  1605. }
  1606. // /*************************************************
  1607. // * We don't get updates from the server from players
  1608. // * that are not in our PVS, so there are separate
  1609. // * messages specifically to update the radar
  1610. // */
  1611. bool SFMapOverview::MsgFunc_ProcessSpottedEntityUpdate( const CCSUsrMsg_ProcessSpottedEntityUpdate &msg )
  1612. {
  1613. if ( msg.new_update() )
  1614. {
  1615. // new spotting frame. clean up.
  1616. m_bBombIsSpotted = false;
  1617. m_EntitySpotted.ClearAll();
  1618. }
  1619. for ( int i = 0; i < msg.entity_updates_size(); i ++ )
  1620. {
  1621. const CCSUsrMsg_ProcessSpottedEntityUpdate::SpottedEntityUpdate &update = msg.entity_updates(i);
  1622. int nEntityID = update.entity_idx();
  1623. if ( nEntityID < 0 || nEntityID >= MAX_EDICTS )
  1624. continue; // GeekPwn2016 range check
  1625. m_EntitySpotted.Set( nEntityID, true );
  1626. const char * szEntityClass = NULL;
  1627. int nClassID = update.class_id();
  1628. for ( ClientClass *pCur = g_pClientClassHead; pCur; pCur=pCur->m_pNext )
  1629. {
  1630. if ( pCur->m_ClassID == nClassID )
  1631. {
  1632. szEntityClass = pCur->GetName();
  1633. break;
  1634. }
  1635. }
  1636. if ( szEntityClass == NULL )
  1637. {
  1638. Warning( "Unknown entity class received in ProcessSpottedEntityUpdate.\n" );
  1639. }
  1640. // non-class specific data
  1641. // read position and angle
  1642. int x = update.origin_x() * 4;
  1643. int y = update.origin_y() * 4;
  1644. int z = update.origin_z() * 4;
  1645. int a = update.angle_y();
  1646. // Clients are unaware of the defuser class type, so we need to flag defuse entities manually
  1647. if ( update.defuser() )
  1648. {
  1649. SetDefuserPos( nEntityID, x, y, z, a );
  1650. }
  1651. else if ( V_strcmp( "CCSPlayer", szEntityClass ) == 0 )
  1652. {
  1653. SFMapOverviewIconPackage* pPlayerIcon = NULL;
  1654. pPlayerIcon = GetRadarPlayer( nEntityID - 1 );
  1655. pPlayerIcon->m_Position.Init( x, y, z );
  1656. pPlayerIcon->m_Angle.Init( 0, a, 0 );
  1657. // has defuser?
  1658. if ( update.player_has_defuser() )
  1659. {
  1660. SetDefuserPos( nEntityID, x, y, z, a );
  1661. }
  1662. // has C4?
  1663. if ( update.player_has_c4() )
  1664. {
  1665. m_bBombIsSpotted = true;
  1666. m_BombPosition.Init( x, y, 0 );
  1667. }
  1668. // The following code should no longer be necessary with the new spotting system
  1669. //C_CSPlayer *pPlayer = ToCSPlayer( UTIL_PlayerByIndex( nEntityID ) );
  1670. //// Only update players that are outside of PVS
  1671. //if ( pPlayer && pPlayer->IsDormant() )
  1672. //{
  1673. // // update origin and angle for players out of my PVS
  1674. // Vector origin = pPlayer->GetAbsOrigin();
  1675. // QAngle angles = pPlayer->GetAbsAngles();
  1676. // origin.x = x;
  1677. // origin.y = y;
  1678. // angles.y = a;
  1679. // pPlayer->SetAbsOrigin( origin );
  1680. // pPlayer->SetAbsAngles( angles );
  1681. //}
  1682. }
  1683. else if ( V_strcmp( "CC4", szEntityClass ) == 0 || V_strcmp( "CPlantedC4", szEntityClass ) == 0 )
  1684. {
  1685. m_bBombIsSpotted = true;
  1686. m_BombPosition.Init( x, y, 0 );
  1687. }
  1688. else if ( V_strcmp( "CHostage", szEntityClass ) == 0 )
  1689. {
  1690. int hostageIndex = GetHostageIndexFromHostageEntityID( nEntityID );
  1691. if ( hostageIndex == INVALID_INDEX )
  1692. {
  1693. for ( int i = 0; i <= m_iLastHostageIndex; i++ )
  1694. {
  1695. RemoveHostage( i );
  1696. }
  1697. }
  1698. else
  1699. {
  1700. SFMapOverviewIconPackage* pPackage = GetRadarHostage( hostageIndex );
  1701. if ( pPackage )
  1702. {
  1703. pPackage->m_Position.Init( x, y, z );
  1704. }
  1705. }
  1706. }
  1707. else
  1708. {
  1709. Warning( "Unknown entity update received by ProcessSpottedEntityUpdate: %s.\n", szEntityClass );
  1710. }
  1711. }
  1712. return true;
  1713. }
  1714. void SFMapOverview::UpdateAllPlayerNamesAndNumbers( void )
  1715. {
  1716. //int nMaxPlayers = CCSGameRules::GetMaxPlayers();
  1717. for ( int i = 0; i <= MAX_PLAYERS; ++i )
  1718. {
  1719. SFMapOverviewIconPackage* pPackage = GetRadarPlayer( i );
  1720. if ( pPackage )
  1721. UpdatePlayerNameAndNumber( pPackage );
  1722. }
  1723. }
  1724. void SFMapOverview::UpdatePlayerNameAndNumber( SFMapOverviewIconPackage* pPackage )
  1725. {
  1726. int nMaxPlayers = CCSGameRules::GetMaxPlayers();
  1727. // update the player number
  1728. SFHudTeamCounter* pTeamCounter = GET_HUDELEMENT( SFHudTeamCounter );
  1729. if ( pPackage && pPackage->m_Icons[PI_PLAYER_NUMBER] && pPackage->m_Icons[PI_PLAYER_NAME_CT] && pPackage->m_Icons[PI_PLAYER_NAME_T] )
  1730. {
  1731. if ( pTeamCounter )
  1732. {
  1733. int pidx = pTeamCounter->GetPlayerSlotIndex( pPackage->m_iEntityID );
  1734. if ( pidx != -1 )
  1735. {
  1736. pidx += 1;
  1737. if ( pidx == 10 )
  1738. pidx = 0;
  1739. ISFTextObject* textPanel = g_pScaleformUI->TextObject_MakeTextObjectFromMember( pPackage->m_Icons[PI_PLAYER_NUMBER], "Text" );
  1740. if ( textPanel )
  1741. {
  1742. CBasePlayer * pPlayer = CBasePlayer::GetLocalPlayer();
  1743. bool bIsSpec = (pPlayer && (m_bShowAll || pPlayer->GetObserverMode() != OBS_MODE_NONE ));
  1744. WITH_SLOT_LOCKED
  1745. {
  1746. if ( nMaxPlayers <= 10 && bIsSpec )
  1747. textPanel->SetText( pidx );
  1748. else
  1749. textPanel->SetText( "" );
  1750. }
  1751. SafeReleaseSFTextObject( textPanel );
  1752. }
  1753. }
  1754. }
  1755. int nTeamSlot = PI_PLAYER_NAME_CT;
  1756. if ( pPackage->m_iPlayerType == PI_T )
  1757. nTeamSlot = PI_PLAYER_NAME_T;
  1758. ISFTextObject* textPanelName = g_pScaleformUI->TextObject_MakeTextObjectFromMember( pPackage->m_Icons[nTeamSlot], "Text" );
  1759. if ( textPanelName )
  1760. {
  1761. WITH_SLOT_LOCKED
  1762. {
  1763. textPanelName->SetText( pPackage->m_wcName );
  1764. }
  1765. SafeReleaseSFTextObject( textPanelName );
  1766. }
  1767. }
  1768. }
  1769. //handles all game event messages ( first looks them up in map so there's no long list of strcmps )
  1770. void SFMapOverview::FireGameEvent( IGameEvent *event )
  1771. {
  1772. const char* eventName = event->GetName();
  1773. int elementIndex = m_messageMap.Find( eventName );
  1774. if ( elementIndex == m_messageMap.InvalidIndex() )
  1775. {
  1776. return;
  1777. }
  1778. SF_SPLITSCREEN_PLAYER_GUARD();
  1779. CBasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  1780. int EventUserID = event->GetInt( "userid", -1 );
  1781. int LocalPlayerID = ( pLocalPlayer != NULL ) ? pLocalPlayer->GetUserID() : -2;
  1782. DESIRED_MESSAGE_INDICES messageTypeIndex = ( DESIRED_MESSAGE_INDICES )m_messageMap.Element( elementIndex );
  1783. switch( messageTypeIndex )
  1784. {
  1785. case GAME_NEWMAP:
  1786. ResetForNewMap();
  1787. SetMap( event->GetString( "mapname" ) );
  1788. break;
  1789. case ROUND_POST_START:
  1790. ResetRound();
  1791. break;
  1792. case PLAYER_CONNECT:
  1793. case PLAYER_INFO:
  1794. {
  1795. int index = event->GetInt( "index" ); // = entity index - 1
  1796. int userID = index + 1;
  1797. if ( index < 0 || index >= MAX_PLAYERS )
  1798. {
  1799. return;
  1800. }
  1801. SFMapOverviewIconPackage* pPackage = CreatePlayer( index );
  1802. if ( messageTypeIndex == PLAYER_CONNECT )
  1803. {
  1804. pPackage->SetPlayerTeam( TEAM_SPECTATOR );
  1805. }
  1806. pPackage->m_iEntityID = userID;
  1807. const char* name = event->GetString( "name","unknown" );
  1808. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  1809. {
  1810. if ( pParameters->m_bAnonymousPlayerIdentity )
  1811. name = ""; // suppress names for anonymous playback
  1812. }
  1813. V_UTF8ToUnicode( name, pPackage->m_wcName, sizeof( pPackage->m_wcName ) );
  1814. }
  1815. break;
  1816. case PLAYER_TEAM:
  1817. {
  1818. int playerIndex = GetPlayerIndexFromUserID( event->GetInt( "userid" ) );
  1819. if ( playerIndex == INVALID_INDEX )
  1820. {
  1821. return;
  1822. }
  1823. SFMapOverviewIconPackage* pPackage = GetRadarPlayer( playerIndex );
  1824. pPackage->SetPlayerTeam( event->GetInt( "team" ) );
  1825. }
  1826. break;
  1827. case PLAYER_DEATH:
  1828. {
  1829. int playerIndex = GetPlayerIndexFromUserID( event->GetInt( "userid" ) );
  1830. if ( playerIndex == INVALID_INDEX )
  1831. {
  1832. return;
  1833. }
  1834. SFMapOverviewIconPackage* pPackage = GetRadarPlayer( playerIndex );
  1835. if ( pPackage->m_bIsActive )
  1836. {
  1837. pPackage->SetIsDead( true );
  1838. pPackage->m_Health = 0;
  1839. }
  1840. int nDefuseIndex = GetDefuseIndexFromEntityID( engine->GetPlayerForUserID( event->GetInt( "userid" ) ) );
  1841. if ( nDefuseIndex != INVALID_INDEX )
  1842. {
  1843. RemoveDefuser( nDefuseIndex );
  1844. }
  1845. }
  1846. break;
  1847. case PLAYER_SPAWN:
  1848. {
  1849. if ( EventUserID == LocalPlayerID )
  1850. {
  1851. m_bShowMapOverview = false;
  1852. }
  1853. int playerIndex = GetPlayerIndexFromUserID( event->GetInt( "userid" ) );
  1854. if ( playerIndex != INVALID_INDEX )
  1855. {
  1856. SFMapOverviewIconPackage* pPackage = GetRadarPlayer( playerIndex );
  1857. pPackage->m_Health = 100;
  1858. UpdatePlayerNameAndNumber( pPackage );
  1859. }
  1860. }
  1861. break;
  1862. case PLAYER_DISCONNECT:
  1863. {
  1864. int playerIndex = GetPlayerIndexFromUserID( event->GetInt( "userid" ) );
  1865. if ( playerIndex != INVALID_INDEX )
  1866. {
  1867. RemovePlayer( playerIndex );
  1868. }
  1869. }
  1870. break;
  1871. case HOSTAGE_KILLED:
  1872. {
  1873. int hostageIndex = GetHostageIndexFromHostageEntityID( event->GetInt( "hostage" ) );
  1874. if ( hostageIndex == INVALID_INDEX )
  1875. {
  1876. return;
  1877. }
  1878. SFMapOverviewIconPackage* pPackage = GetRadarHostage( hostageIndex );
  1879. if ( pPackage->m_bIsActive )
  1880. {
  1881. pPackage->SetIsDead( true );
  1882. }
  1883. }
  1884. break;
  1885. case HOSTAGE_RESCUED:
  1886. {
  1887. int hostageIndex = GetHostageIndexFromHostageEntityID( event->GetInt( "hostage" ) );
  1888. if ( hostageIndex == INVALID_INDEX )
  1889. {
  1890. return;
  1891. }
  1892. SFMapOverviewIconPackage* pPackage = GetRadarHostage( hostageIndex );
  1893. if ( pPackage->m_bIsActive )
  1894. {
  1895. pPackage->SetIsRescued( true );
  1896. }
  1897. }
  1898. break;
  1899. case BOMB_DEFUSED:
  1900. {
  1901. m_bBombDefused = true;
  1902. }
  1903. break;
  1904. case BOMB_EXPLODED:
  1905. {
  1906. m_bBombExploded = true;
  1907. }
  1908. break;
  1909. case BOMB_PLANTED:
  1910. {
  1911. m_nBombEntIndex = -1;
  1912. m_bBombPlanted = true;
  1913. m_BombPosition.z = 0;
  1914. }
  1915. break;
  1916. case BOMB_PICKUP:
  1917. {
  1918. m_bBombDropped = false;
  1919. m_nBombEntIndex = -1;
  1920. }
  1921. break;
  1922. case BOMB_DROPPED:
  1923. {
  1924. m_nBombEntIndex = event->GetInt( "entindex", -1 );
  1925. m_bBombDropped = true;
  1926. }
  1927. break;
  1928. case DEFUSER_PICKUP:
  1929. {
  1930. int nDefuseIndex = GetDefuseIndexFromEntityID( event->GetInt( "entityid" ) );
  1931. if ( nDefuseIndex != INVALID_INDEX )
  1932. {
  1933. RemoveDefuser( nDefuseIndex );
  1934. }
  1935. }
  1936. break;
  1937. case DEFUSER_DROPPED:
  1938. {
  1939. int nEntityID = event->GetInt( "entityid" );
  1940. CreateDefuser( nEntityID );
  1941. }
  1942. break;
  1943. case DECOY_STARTED:
  1944. {
  1945. if ( pLocalPlayer )
  1946. {
  1947. int userID = event->GetInt( "userid" );
  1948. CBasePlayer* player = UTIL_PlayerByUserId( userID );
  1949. if ( player )
  1950. {
  1951. bool bShowGrenade = false;
  1952. // if it was placed by a player on our team or if we are a spectator, show the grenade as a grenade icon
  1953. // otherwise, we're going to show it as if it were a fake player
  1954. if ( player->GetAssociatedTeamNumber() == pLocalPlayer->GetAssociatedTeamNumber() || m_bShowAll )
  1955. bShowGrenade = true;
  1956. int entityID = event->GetInt( "entityid" );
  1957. int teamNumber = player->GetAssociatedTeamNumber();
  1958. SFMapOverviewIconPackage* pPackage = CreateGrenade( entityID, PI_GRENADE_DECOY );
  1959. if ( pPackage )
  1960. {
  1961. if ( bShowGrenade )
  1962. pPackage->SetGrenadeType( PI_GRENADE_DECOY );
  1963. else
  1964. {
  1965. pPackage->SetPlayerTeam( teamNumber );
  1966. pPackage->SetIsSpotted( true );
  1967. }
  1968. pPackage->m_Position.Init( ( float )event->GetInt( "x" ), ( float )event->GetInt( "y" ), 0.0f );
  1969. pPackage->m_Angle.Init( 0.0f, RandomFloat( 0.0f, 360.0f ), 0.0f );
  1970. SetIconPackagePosition( pPackage );
  1971. }
  1972. }
  1973. }
  1974. }
  1975. break;
  1976. case DECOY_DETONATE:
  1977. {
  1978. int entityID = event->GetInt( "entityid" );
  1979. int i = GetGrenadeIndexFromEntityID( entityID );
  1980. if ( i != INVALID_INDEX )
  1981. {
  1982. SFMapOverviewIconPackage* pPackage = GetRadarGrenade( i );
  1983. pPackage->SetGrenadeExpireTime( gpGlobals->curtime );
  1984. SetIconPackagePosition( pPackage );
  1985. }
  1986. STEAMWORKS_TESTSECRET_AMORTIZE( 23 );
  1987. }
  1988. break;
  1989. case HE_DETONATE:
  1990. {
  1991. int entityID = event->GetInt( "entityid" );
  1992. int userID = event->GetInt( "userid" );
  1993. CBasePlayer* player = UTIL_PlayerByUserId( userID );
  1994. if ( pLocalPlayer && player )
  1995. {
  1996. // if it was placed by a player on our team or if we are a spectator, show the grenade as usually
  1997. // otherwise, we don't show it at all
  1998. Vector vecGrenade = Vector( ( float )event->GetInt( "x" ), ( float )event->GetInt( "y" ), 0 );
  1999. if ( (player->GetAssociatedTeamNumber() == pLocalPlayer->GetAssociatedTeamNumber() && IsEnemyCloseEnoughToShow( vecGrenade )) || m_bShowAll )
  2000. {
  2001. SFMapOverviewIconPackage* pPackage = CreateGrenade( entityID, PI_GRENADE_HE );
  2002. if ( pPackage )
  2003. {
  2004. pPackage->SetGrenadeType( PI_GRENADE_HE );
  2005. pPackage->SetGrenadeExpireTime( gpGlobals->curtime );
  2006. pPackage->m_Position.Init( vecGrenade.x, vecGrenade.y, 0.0f );
  2007. pPackage->m_Angle.Init( 0.0f, RandomFloat( 0.0f, 360.0f ), 0.0f );
  2008. SetIconPackagePosition( pPackage );
  2009. }
  2010. }
  2011. }
  2012. STEAMWORKS_TESTSECRET_AMORTIZE( 19 );
  2013. }
  2014. break;
  2015. case FLASH_DETONATE:
  2016. {
  2017. int entityID = event->GetInt( "entityid" );
  2018. int userID = event->GetInt( "userid" );
  2019. CBasePlayer* player = UTIL_PlayerByUserId( userID );
  2020. if ( pLocalPlayer && player )
  2021. {
  2022. // if it was placed by a player on our team or if we are a spectator, show the grenade as usually
  2023. // otherwise, we don't show it at all
  2024. Vector vecGrenade = Vector( ( float )event->GetInt( "x" ), ( float )event->GetInt( "y" ), 0 );
  2025. if ( (player->GetAssociatedTeamNumber() == pLocalPlayer->GetAssociatedTeamNumber() && IsEnemyCloseEnoughToShow( vecGrenade )) || m_bShowAll )
  2026. {
  2027. SFMapOverviewIconPackage* pPackage = CreateGrenade( entityID, PI_GRENADE_FLASH );
  2028. if ( pPackage )
  2029. {
  2030. pPackage->SetGrenadeType( PI_GRENADE_FLASH );
  2031. pPackage->SetGrenadeExpireTime( gpGlobals->curtime );
  2032. pPackage->m_Position.Init( vecGrenade.x, vecGrenade.y, 0.0f );
  2033. pPackage->m_Angle.Init( 0.0f, RandomFloat( 0.0f, 360.0f ), 0.0f );
  2034. SetIconPackagePosition( pPackage );
  2035. }
  2036. }
  2037. }
  2038. STEAMWORKS_TESTSECRET_AMORTIZE( 17 );
  2039. }
  2040. break;
  2041. case SMOKE_DETONATE:
  2042. {
  2043. int entityID = event->GetInt( "entityid" );
  2044. int userID = event->GetInt( "userid" );
  2045. CBasePlayer* player = UTIL_PlayerByUserId( userID );
  2046. if ( pLocalPlayer && player )
  2047. {
  2048. // if it was placed by a player on our team or if we are a spectator, show the grenade as usually
  2049. // otherwise, we don't show it at all
  2050. Vector vecGrenade = Vector( ( float )event->GetInt( "x" ), ( float )event->GetInt( "y" ), 0 );
  2051. if ( (player->GetAssociatedTeamNumber() == pLocalPlayer->GetAssociatedTeamNumber() && IsEnemyCloseEnoughToShow( vecGrenade )) || m_bShowAll )
  2052. {
  2053. SFMapOverviewIconPackage* pPackage = CreateGrenade( entityID, PI_GRENADE_SMOKE );
  2054. if ( pPackage )
  2055. {
  2056. pPackage->SetGrenadeType( PI_GRENADE_SMOKE );
  2057. pPackage->m_Position.Init( vecGrenade.x, vecGrenade.y, 0.0f );
  2058. pPackage->m_Angle.Init( 0.0f, RandomFloat( 0.0f, 360.0f ), 0.0f );
  2059. SetIconPackagePosition( pPackage );
  2060. }
  2061. }
  2062. }
  2063. }
  2064. break;
  2065. case SMOKE_EXPIRE:
  2066. {
  2067. int entityID = event->GetInt( "entityid" );
  2068. int i = GetGrenadeIndexFromEntityID( entityID );
  2069. if ( i != INVALID_INDEX )
  2070. {
  2071. SFMapOverviewIconPackage* pPackage = GetRadarGrenade( i );
  2072. pPackage->SetGrenadeExpireTime( gpGlobals->curtime );
  2073. SetIconPackagePosition( pPackage );
  2074. }
  2075. STEAMWORKS_TESTSECRET_AMORTIZE( 11 );
  2076. }
  2077. break;
  2078. case MOLOTOV_DETONATE:
  2079. {
  2080. int entityID = event->GetInt( "entityid" );
  2081. int userID = event->GetInt( "userid" );
  2082. CBasePlayer* player = UTIL_PlayerByUserId( userID );
  2083. if ( pLocalPlayer && player )
  2084. {
  2085. // if it was placed by a player on our team or if we are a spectator, show the grenade as usually
  2086. // otherwise, we don't show it at all
  2087. Vector vecGrenade = Vector( ( float )event->GetInt( "x" ), ( float )event->GetInt( "y" ), 0 );
  2088. if ( (player->GetAssociatedTeamNumber() == pLocalPlayer->GetAssociatedTeamNumber() && IsEnemyCloseEnoughToShow( vecGrenade )) || m_bShowAll )
  2089. {
  2090. SFMapOverviewIconPackage* pPackage = CreateGrenade( entityID, PI_GRENADE_MOLOTOV );
  2091. if ( pPackage )
  2092. {
  2093. pPackage->SetGrenadeType( PI_GRENADE_MOLOTOV );
  2094. pPackage->m_Position.Init( vecGrenade.x, vecGrenade.y, 0.0f );
  2095. pPackage->m_Angle.Init( 0.0f, RandomFloat( 0.0f, 360.0f ), 0.0f );
  2096. SetIconPackagePosition( pPackage );
  2097. }
  2098. }
  2099. }
  2100. }
  2101. break;
  2102. case MOLOTOV_EXPIRE:
  2103. {
  2104. int entityID = event->GetInt( "entityid" );
  2105. int i = GetGrenadeIndexFromEntityID( entityID );
  2106. if ( i != INVALID_INDEX )
  2107. {
  2108. SFMapOverviewIconPackage* pPackage = GetRadarGrenade( i );
  2109. pPackage->SetGrenadeExpireTime( gpGlobals->curtime );
  2110. SetIconPackagePosition( pPackage );
  2111. }
  2112. STEAMWORKS_TESTSECRET_AMORTIZE( 19 );
  2113. }
  2114. break;
  2115. case BOT_TAKEOVER:
  2116. {
  2117. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2118. if ( pLocalPlayer )
  2119. {
  2120. int userID = event->GetInt( "userid" );
  2121. int localID = pLocalPlayer->GetUserID();
  2122. if (localID == userID )
  2123. {
  2124. ResetRadar( false );
  2125. }
  2126. }
  2127. }
  2128. break;
  2129. default:
  2130. break;
  2131. }
  2132. }
  2133. //
  2134. //
  2135. // /*****************************************************
  2136. // * these set lazy update the icons and text based
  2137. // * on the values in the state variables
  2138. // */
  2139. //
  2140. void SFMapOverview::SetupIconsFromStates( void )
  2141. {
  2142. uint64 newFlags = 0;
  2143. if ( CSGameRules()->IsBombDefuseMap() )
  2144. {
  2145. // check to see if the bomb exists before assuming the first exists and trying to get data from it
  2146. if ( !m_bBombDefused && m_bBombPlanted && g_PlantedC4s.Count() > 0 )
  2147. {
  2148. float fPercent = ( g_PlantedC4s[0]->GetDetonationProgress() * 100.0f );
  2149. if ( fPercent > 60.0f )
  2150. {
  2151. newFlags |= 1 << RI_BOMB_IS_PLANTED;
  2152. }
  2153. else if ( fPercent > 30.0f )
  2154. {
  2155. newFlags |= 1 << RI_BOMB_IS_PLANTED_MEDIUM;
  2156. }
  2157. else if ( fPercent > 0.0f )
  2158. {
  2159. newFlags |= 1 << RI_BOMB_IS_PLANTED_FAST;
  2160. }
  2161. }
  2162. if ( m_fBombAlpha > 0.0f )
  2163. {
  2164. newFlags |= 1 << RI_BOMB_ICON_PACKAGE;
  2165. if ( m_bShowBombHighlight )
  2166. {
  2167. if ( m_bBombPlanted )
  2168. {
  2169. newFlags |= 1 << RI_BOMB_ICON_PLANTED;
  2170. }
  2171. else
  2172. {
  2173. newFlags |= 1 << RI_BOMB_ICON_DROPPED;
  2174. }
  2175. C_CSPlayer *pLocalOrObserver = GetLocalOrInEyeCSPlayer();
  2176. if ( pLocalOrObserver )
  2177. {
  2178. if ( m_BombPosition.z > pLocalOrObserver->GetAbsOrigin().z + 180 )
  2179. newFlags |= 1 << RI_BOMB_ICON_BOMB_ABOVE;
  2180. else if ( m_BombPosition.z < pLocalOrObserver->GetAbsOrigin().z - 180 )
  2181. newFlags |= 1 << RI_BOMB_ICON_BOMB_BELOW;
  2182. }
  2183. }
  2184. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2185. if( pLocalPlayer != NULL )
  2186. {
  2187. if ( pLocalPlayer->GetAssociatedTeamNumber() == TEAM_TERRORIST )
  2188. {
  2189. newFlags |= 1 << RI_BOMB_ICON_BOMB_T;
  2190. }
  2191. else
  2192. {
  2193. newFlags |= 1 << RI_BOMB_ICON_BOMB_CT;
  2194. }
  2195. }
  2196. Vector mapPosition;
  2197. WorldToRadar( m_BombPosition, mapPosition );
  2198. Vector newMapPosition = mapPosition;
  2199. newMapPosition -= m_RadarViewpointMap;
  2200. ScaleformDisplayInfo displayInfo;
  2201. displayInfo.SetAlpha( m_fBombAlpha * 100.0f );
  2202. int nBombCarryOffset = 0;
  2203. if ( ((newFlags & (1 << RI_BOMB_ICON_BOMB_T)) || (newFlags & (1 << RI_BOMB_ICON_BOMB_CT))) && !(newFlags & (1 << RI_BOMB_ICON_PLANTED)) )
  2204. {
  2205. nBombCarryOffset = 6;
  2206. }
  2207. displayInfo.SetX( mapPosition.x );
  2208. displayInfo.SetY( mapPosition.y + nBombCarryOffset );
  2209. displayInfo.SetRotation( -m_RadarRotation );
  2210. assert( m_AllIcons[RI_BOMB_ICON_PACKAGE] );
  2211. m_pScaleformUI->Value_SetDisplayInfo( m_AllIcons[RI_BOMB_ICON_PACKAGE], &displayInfo );
  2212. }
  2213. }
  2214. else if ( CSGameRules()->IsHostageRescueMap() )
  2215. {
  2216. if ( m_bShowingHostageZone )
  2217. {
  2218. newFlags |= 1 << RI_IN_HOSTAGE_ZONE;
  2219. }
  2220. }
  2221. if ( m_bShowingDashboard )
  2222. newFlags |= 1 << RI_DASHBOARD;
  2223. SetVisibilityFlags( newFlags );
  2224. }
  2225. void SFMapOverview::SetVisibilityFlags( uint64 newFlags )
  2226. {
  2227. newFlags &= ( ( 1 << RI_NUM_ICONS )-1 );
  2228. uint64 diffFlags = m_iCurrentVisibilityFlags ^ newFlags;
  2229. if ( diffFlags )
  2230. {
  2231. for ( int i = 0; i < RI_NUM_ICONS && ( diffFlags != 0 ); i++, diffFlags >>= 1 )
  2232. {
  2233. if ( diffFlags & 1 )
  2234. {
  2235. if ( m_AllIcons[i] )
  2236. m_pScaleformUI->Value_SetVisible( m_AllIcons[i], ( newFlags & ( 1ll << i ) ) != 0 );
  2237. }
  2238. }
  2239. m_iCurrentVisibilityFlags = newFlags;
  2240. }
  2241. }
  2242. void SFMapOverview::SetLocationText( wchar_t *newText )
  2243. {
  2244. if ( newText == NULL )
  2245. {
  2246. newText = L"";
  2247. }
  2248. if ( V_wcscmp( newText, m_wcLocationString ) )
  2249. {
  2250. V_wcsncpy( m_wcLocationString, newText, sizeof( wchar_t )*MAX_LOCATION_TEXT_LENGTH );
  2251. if ( m_LocationText )
  2252. {
  2253. WITH_SLOT_LOCKED
  2254. m_LocationText->SetText( m_wcLocationString );
  2255. }
  2256. }
  2257. }
  2258. //
  2259. // /********************************************
  2260. // * "drawing" code. Actually just sets position / alpha
  2261. // * of the flash objects
  2262. // */
  2263. //
  2264. void SFMapOverview::WorldToRadar( const Vector& ptin, Vector& ptout )
  2265. {
  2266. ptout.x = ( ptin.x - m_MapOrigin.x ) * m_fWorldToRadarScale;
  2267. ptout.y = ( m_MapOrigin.y - ptin.y ) * m_fWorldToRadarScale;
  2268. ptout.z = 0;
  2269. }
  2270. void SFMapOverview::RadarToWorld( const Vector& ptin, Vector& ptout )
  2271. {
  2272. ptout.x = ( ptin.x + m_MapOrigin.x ) / m_fWorldToRadarScale;
  2273. ptout.y = ( m_MapOrigin.y + ptin.y ) / m_fWorldToRadarScale;
  2274. ptout.z = 0;
  2275. }
  2276. void SFMapOverview::PositionRadarViewpoint( void )
  2277. {
  2278. if ( !m_bFlashReady )
  2279. {
  2280. return;
  2281. }
  2282. int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  2283. CBasePlayer * pPlayer = CBasePlayer::GetLocalPlayer();
  2284. if( pPlayer == NULL )
  2285. {
  2286. pPlayer = GetSplitScreenViewPlayer( nSlot );
  2287. }
  2288. // [jbright] Using GetLocalOrigin addresses an issue which
  2289. // causes the center player indicator to not stay centered
  2290. // on the radar. This solution causes the radar to go jump
  2291. // around while in observer mode, so in those cases rely on
  2292. // MainViewOrigin.
  2293. // if ( pPlayer && m_iObserverMode == OBS_MODE_NONE )
  2294. // {
  2295. // m_RadarViewpointWorld = pPlayer->GetLocalOrigin();
  2296. // }
  2297. // else
  2298. // {
  2299. // m_RadarViewpointWorld = MainViewOrigin( nSlot );
  2300. // }
  2301. // Get the world's extent
  2302. // C_World *world = GetClientWorldEntity();
  2303. // if ( !world )
  2304. // return;
  2305. //
  2306. // Vector worldCenter = ( world->m_WorldMins + world->m_WorldMaxs ) * 0.5f;
  2307. m_RadarViewpointWorld = Vector( m_MapOrigin.x, m_MapOrigin.y, 0 );//worldCenter;
  2308. //m_RadarViewpointWorld.z = 0;
  2309. WorldToRadar( m_RadarViewpointWorld, m_RadarViewpointMap );
  2310. m_RadarRotation = 0;
  2311. ScaleformDisplayInfo displayInfo;
  2312. if ( m_MapRotation )
  2313. {
  2314. displayInfo.SetRotation( m_RadarRotation );
  2315. m_pScaleformUI->Value_SetDisplayInfo( m_MapRotation, &displayInfo );
  2316. if ( m_MapTranslation )
  2317. {
  2318. displayInfo.Clear();
  2319. displayInfo.SetX( -(m_fMapSize/2) );
  2320. displayInfo.SetY( -(m_fMapSize/2) );
  2321. m_pScaleformUI->Value_SetDisplayInfo( m_MapTranslation, &displayInfo );
  2322. }
  2323. }
  2324. if ( m_IconRotation )
  2325. {
  2326. displayInfo.Clear();
  2327. displayInfo.SetRotation( m_RadarRotation );
  2328. m_pScaleformUI->Value_SetDisplayInfo( m_IconRotation, &displayInfo );
  2329. if ( m_IconTranslation )
  2330. {
  2331. displayInfo.Clear();
  2332. displayInfo.SetX( -(m_fMapSize/2) - 1 );
  2333. displayInfo.SetY( -(m_fMapSize/2) - 1 );
  2334. m_pScaleformUI->Value_SetDisplayInfo( m_IconTranslation, &displayInfo );
  2335. }
  2336. }
  2337. }
  2338. void SFMapOverview::PlaceGoalIcons( void )
  2339. {
  2340. C_CS_PlayerResource *pCSPR = ( C_CS_PlayerResource* )GameResources();
  2341. if ( !pCSPR )
  2342. {
  2343. return;
  2344. }
  2345. SFMapOverviewGoalIcon* pwalk = m_GoalIcons;
  2346. Vector mapPosition;
  2347. ScaleformDisplayInfo displayInfo;
  2348. for ( int i = 0; i < m_iNumGoalIcons; i++ )
  2349. {
  2350. WorldToRadar( pwalk->m_Position, mapPosition );
  2351. if ( pwalk->m_Icon )
  2352. {
  2353. Vector newMapPosition = mapPosition;
  2354. newMapPosition -= m_RadarViewpointMap;
  2355. displayInfo.SetX( mapPosition.x );
  2356. displayInfo.SetY( mapPosition.y );
  2357. displayInfo.SetRotation( -m_RadarRotation );
  2358. m_pScaleformUI->Value_SetDisplayInfo( pwalk->m_Icon, &displayInfo );
  2359. }
  2360. pwalk++;
  2361. }
  2362. }
  2363. void SFMapOverview::SetIconPackagePosition( SFMapOverviewIconPackage* pPackage )
  2364. {
  2365. if ( !m_bFlashReady )
  2366. return;
  2367. Vector mapPosition;
  2368. ScaleformDisplayInfo displayInfo;
  2369. float mapAngle;
  2370. WorldToRadar( pPackage->m_Position, mapPosition );
  2371. Vector newMapPosition = mapPosition;
  2372. newMapPosition -= m_RadarViewpointMap;
  2373. pPackage->SetIsOffMap( false );
  2374. if ( pPackage->m_bIsDead || !pPackage->m_bIsSpotted )
  2375. {
  2376. mapAngle = -m_RadarRotation;
  2377. }
  2378. else
  2379. {
  2380. mapAngle = -pPackage->m_Angle[YAW]+90;
  2381. }
  2382. displayInfo.SetX( mapPosition.x );
  2383. displayInfo.SetY( mapPosition.y );
  2384. float flScale = mapoverview_icon_scale.GetFloat();
  2385. displayInfo.SetXScale( 120 * flScale );
  2386. displayInfo.SetYScale( 120 * flScale );
  2387. m_pScaleformUI->Value_SetDisplayInfo( pPackage->m_IconPackage, &displayInfo );
  2388. // only rotated the sublayer, the stuff on top doesn't want to be rotated
  2389. //SFVALUE rotatedIcon;
  2390. //rotatedIcon = m_pScaleformUI->Value_GetMember( pPackage->m_IconPackage, "RotatedLayer" );
  2391. if ( pPackage->m_IconPackageRotate )
  2392. {
  2393. ScaleformDisplayInfo rotatedDisplayInfo;
  2394. rotatedDisplayInfo.SetRotation( mapAngle );
  2395. m_pScaleformUI->Value_SetDisplayInfo( pPackage->m_IconPackageRotate, &rotatedDisplayInfo );
  2396. }
  2397. pPackage->SetupIconsFromStates();
  2398. }
  2399. void SFMapOverview::PlaceHostages( void )
  2400. {
  2401. if ( !m_bFlashReady )
  2402. {
  2403. return;
  2404. }
  2405. if ( !CSGameRules()->IsHostageRescueMap() )
  2406. {
  2407. return;
  2408. }
  2409. C_CS_PlayerResource *pCSPR = ( C_CS_PlayerResource* )GameResources();
  2410. if ( !pCSPR )
  2411. {
  2412. return;
  2413. }
  2414. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2415. if( pLocalPlayer == NULL )
  2416. {
  2417. return;
  2418. }
  2419. int iNumLiveHostages = 0;
  2420. int iNumDeadHostages = 0;
  2421. int iNumMovingHostages = 0;
  2422. int iNumRescuedHostages = 0;
  2423. bool bIsTerrorist = ( pLocalPlayer->GetAssociatedTeamNumber() == TEAM_TERRORIST );
  2424. if ( bIsTerrorist )
  2425. {
  2426. // Taking over a bot after switching to the terrorist team results in
  2427. // the hostage indicators remaining visible, so we need to remove them.
  2428. for ( int i = 0; i <= m_iLastHostageIndex; i++ )
  2429. {
  2430. if ( GetRadarHostage( i )->m_bIsActive )
  2431. RemoveHostage( i );
  2432. }
  2433. // we also want to show the number of hostages that are still alive
  2434. // and unrescued
  2435. for( int i=0; i < MAX_HOSTAGES; i++ )
  2436. {
  2437. if( pCSPR->IsHostageAlive( i ) )
  2438. iNumLiveHostages++;
  2439. }
  2440. }
  2441. else
  2442. {
  2443. // T's can now always see basic hostage info (alive, dead) but not moving or rescued status
  2444. /*
  2445. bool bCanShowHostages = m_bShowAll || ( pLocalPlayer->GetTeamNumber() == TEAM_CT );
  2446. if ( !bCanShowHostages )
  2447. {
  2448. return;
  2449. }
  2450. */
  2451. // Update hostage status
  2452. for( int i=0; i < MAX_HOSTAGES; i++ )
  2453. {
  2454. int nEntityID = pCSPR->GetHostageEntityID( i );
  2455. if ( nEntityID > 0 )
  2456. {
  2457. SFMapOverviewIconPackage* pHostage = NULL;
  2458. int nHostageIndex = GetHostageIndexFromHostageEntityID( nEntityID );
  2459. if ( nHostageIndex == INVALID_INDEX )
  2460. {
  2461. // Create the hostage in next available slot
  2462. for ( nHostageIndex = 0; nHostageIndex < MAX_HOSTAGES; nHostageIndex++ )
  2463. {
  2464. if ( !m_Hostages[nHostageIndex].m_bIsActive )
  2465. {
  2466. pHostage = CreateHostage( nHostageIndex );
  2467. pHostage->SetPlayerTeam( TEAM_UNASSIGNED );
  2468. pHostage->m_iEntityID = nEntityID;
  2469. break;
  2470. }
  2471. }
  2472. }
  2473. else
  2474. {
  2475. pHostage = GetRadarHostage( nHostageIndex );
  2476. }
  2477. if ( pHostage )
  2478. {
  2479. if( pCSPR->IsHostageAlive( i ) )
  2480. {
  2481. if ( !pHostage->m_bIsActive )
  2482. {
  2483. }
  2484. pHostage->SetIsDead( false );
  2485. if ( pCSPR->IsHostageFollowingSomeone( i ) )
  2486. {
  2487. iNumMovingHostages++;
  2488. pHostage->SetIsMovingHostage( true );
  2489. }
  2490. else
  2491. {
  2492. iNumLiveHostages++;
  2493. pHostage->SetIsMovingHostage( false );
  2494. }
  2495. }
  2496. else if ( i <= m_iLastHostageIndex && pHostage->m_bIsActive )
  2497. {
  2498. if ( pHostage->m_bIsRescued )
  2499. {
  2500. iNumRescuedHostages++;
  2501. }
  2502. else
  2503. {
  2504. iNumDeadHostages++;
  2505. }
  2506. pHostage->SetIsDead( true );
  2507. pHostage->SetIsMovingHostage( false );
  2508. }
  2509. }
  2510. }
  2511. }
  2512. // Update hostage positions
  2513. for( int i = 0; i < MAX_HOSTAGES; i++ )
  2514. {
  2515. SFMapOverviewIconPackage* pHostage = GetRadarHostage( i );
  2516. if ( pHostage->m_bIsActive )
  2517. {
  2518. C_BaseEntity * pEntity = ClientEntityList().GetBaseEntity( pHostage->m_iEntityID );
  2519. if ( pEntity && !pEntity->IsDormant() )
  2520. {
  2521. Assert( dynamic_cast<CHostage*>( pEntity ) );
  2522. pHostage->m_Position = pEntity->GetNetworkOrigin();
  2523. }
  2524. pHostage->SetIsSpotted( true );
  2525. SetIconPackagePosition( pHostage );
  2526. }
  2527. }
  2528. }
  2529. int hostageIndex = 0;
  2530. for ( int i = 0; i < iNumDeadHostages; i++ )
  2531. {
  2532. m_HostageStatusIcons[hostageIndex++].SetStatus( SFMapOverviewHostageIcons::HI_DEAD );
  2533. }
  2534. for ( int i = 0; i < iNumRescuedHostages; i++ )
  2535. {
  2536. m_HostageStatusIcons[hostageIndex++].SetStatus( SFMapOverviewHostageIcons::HI_RESCUED );
  2537. }
  2538. for ( int i = 0; i < iNumMovingHostages; i++ )
  2539. {
  2540. m_HostageStatusIcons[hostageIndex++].SetStatus( SFMapOverviewHostageIcons::HI_TRANSIT );
  2541. }
  2542. for ( int i = 0; i < iNumLiveHostages; i++ )
  2543. {
  2544. m_HostageStatusIcons[hostageIndex++].SetStatus( SFMapOverviewHostageIcons::HI_ALIVE );
  2545. }
  2546. for ( ; hostageIndex < MAX_HOSTAGES && m_HostageStatusIcons[hostageIndex].m_IconPackage != NULL; hostageIndex++ )
  2547. {
  2548. m_HostageStatusIcons[hostageIndex].SetStatus( SFMapOverviewHostageIcons::HI_UNUSED );
  2549. }
  2550. }
  2551. void SFMapOverview::UpdateAllDefusers( void )
  2552. {
  2553. if ( !m_bTrackDefusers )
  2554. {
  2555. return;
  2556. }
  2557. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2558. if( pLocalPlayer == NULL )
  2559. {
  2560. return;
  2561. }
  2562. for ( int i = 0; i <= m_iLastDefuserIndex; i++ )
  2563. {
  2564. SFMapOverviewIconPackage * pPackage = GetRadarDefuser( i );
  2565. if ( pPackage && pPackage->m_bIsActive )
  2566. {
  2567. C_BaseEntity * pEntity = ClientEntityList().GetBaseEntity( pPackage->m_iEntityID );
  2568. bool bSpotted = ( pLocalPlayer->GetAssociatedTeamNumber() == TEAM_CT || ( pEntity && pEntity->IsSpotted() ) || m_EntitySpotted.Get( pPackage->m_iEntityID ) );
  2569. pPackage->SetIsSpotted( bSpotted );
  2570. if ( bSpotted && pEntity && !pEntity->IsDormant() )
  2571. {
  2572. SetDefuserPos( pPackage->m_iEntityID,
  2573. pEntity->GetNetworkOrigin().x,
  2574. pEntity->GetNetworkOrigin().y,
  2575. pEntity->GetNetworkOrigin().z,
  2576. pEntity->GetNetworkAngles().y );
  2577. }
  2578. }
  2579. // update radar position and visibility
  2580. if ( pPackage && pPackage->m_bIsActive )
  2581. {
  2582. SetIconPackagePosition( pPackage );
  2583. }
  2584. }
  2585. }
  2586. void SFMapOverview::PlacePlayers( void )
  2587. {
  2588. if ( !m_bFlashReady )
  2589. {
  2590. return;
  2591. }
  2592. C_CS_PlayerResource *pCSPR = ( C_CS_PlayerResource* )GameResources();
  2593. if ( !pCSPR )
  2594. {
  2595. return;
  2596. }
  2597. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2598. if( pLocalPlayer == NULL )
  2599. {
  2600. return;
  2601. }
  2602. int localPlayerIndex = pLocalPlayer->entindex()-1;
  2603. if ( localPlayerIndex == INVALID_INDEX )
  2604. {
  2605. return;
  2606. }
  2607. int localTeamNumber = pLocalPlayer->GetAssociatedTeamNumber();
  2608. SFMapOverviewIconPackage* pwalk = m_Players;
  2609. int playerIndex;
  2610. for ( int i = 0; i <= m_iLastPlayerIndex; i++, pwalk++ )
  2611. {
  2612. if ( pwalk->m_IconPackage && pwalk->m_bIsActive )
  2613. {
  2614. playerIndex = i+1;
  2615. C_CSPlayer *pPlayer = ToCSPlayer( UTIL_PlayerByIndex( playerIndex ) );
  2616. bool playerIsActive = pPlayer != NULL && !pPlayer->IsDormant();
  2617. int nIsAboveOrBelow = R_SAMELEVEL;
  2618. // we do all the pCSPR stuff because the player may not have been given
  2619. // to us by the server yet. If that's the case, we can't use the player
  2620. // pointer to find anything out, we have to use the PCSPR which keeps some
  2621. // of this data ( like team numbers, spotted, hasC4 etc. The dormant means
  2622. // that it's not in our view
  2623. if ( pCSPR->IsConnected( playerIndex ) )
  2624. {
  2625. pwalk->m_Health = pCSPR->GetHealth( playerIndex );
  2626. if ( !pCSPR->IsAlive( playerIndex ) )
  2627. {
  2628. pwalk->m_Health = 0;
  2629. if( pCSPR->GetControlledByPlayer( playerIndex ) )
  2630. {
  2631. pwalk->SetIsControlledBot();
  2632. }
  2633. else
  2634. {
  2635. pwalk->SetIsDead( true );
  2636. }
  2637. }
  2638. else
  2639. {
  2640. pwalk->SetIsDead( false );
  2641. //it's hard to figure out if this player has been spotted, and if spotted has enough info to be
  2642. //shown.
  2643. bool bSameTeam = ( localTeamNumber == pCSPR->GetTeam( playerIndex ) );
  2644. bool bObservingTarget = pLocalPlayer->GetObserverTarget() && (pLocalPlayer->GetObserverTarget() == pPlayer);
  2645. bool bHasValidPosition = playerIsActive || ( pwalk->m_Position.x != 0 || pwalk->m_Position.y != 0 );
  2646. Vector vecEnemy = pwalk->m_Position;
  2647. bool bPlayerSpotted = bObservingTarget || (( m_EntitySpotted.Get( playerIndex ) || ( playerIsActive && pPlayer->IsSpotted() ) )
  2648. && (m_bShowAll || (!bSameTeam && IsEnemyCloseEnoughToShow( vecEnemy ))));
  2649. if ( pPlayer && bHasValidPosition && ( bSameTeam || m_bShowAll || bPlayerSpotted ) )
  2650. {
  2651. pwalk->SetIsSpotted( true );
  2652. if ( playerIsActive && pPlayer->HasDefuser() )
  2653. {
  2654. // attach a defuser icon to this player if one does not already exist
  2655. if ( GetDefuseIndexFromEntityID( playerIndex ) == INVALID_INDEX )
  2656. {
  2657. CreateDefuser( playerIndex );
  2658. }
  2659. }
  2660. if ( playerIsActive && pPlayer->HasC4() && ( bPlayerSpotted || m_bShowAll ) )
  2661. {
  2662. m_bBombIsSpotted = true;
  2663. m_BombPosition = pwalk->m_Position;
  2664. }
  2665. // set is low health
  2666. pwalk->SetIsLowHealth( (playerIsActive && pPlayer->GetHealth() < 40) );
  2667. // set is selected
  2668. C_CSPlayer *pLocalOrObserver = ToCSPlayer( pLocalPlayer->GetObserverTarget() );
  2669. pwalk->SetIsSelected( pLocalOrObserver && pPlayer == pLocalOrObserver );
  2670. // set is flashed
  2671. pwalk->SetIsFlashed( pPlayer->IsBlinded() );
  2672. // set is firing
  2673. pwalk->SetIsFiring( (pPlayer->GetLastFiredWeaponTime() + 0.2) >= gpGlobals->curtime );
  2674. }
  2675. else
  2676. {
  2677. pwalk->SetIsSpotted( false );
  2678. }
  2679. }
  2680. pwalk->SetPlayerTeam( pCSPR->GetTeam( playerIndex ) );
  2681. pwalk->SetIsOnLocalTeam( localTeamNumber == pCSPR->GetTeam( playerIndex ) );
  2682. pwalk->SetIsPlayer( i == localPlayerIndex );
  2683. pwalk->SetIsSpeaking( GetClientVoiceMgr()->IsPlayerSpeaking( playerIndex ) && GetClientVoiceMgr()->IsPlayerAudible( playerIndex ) );
  2684. UpdatePlayerNameAndNumber( pwalk );
  2685. }
  2686. else
  2687. {
  2688. pwalk->SetIsSpotted( false );
  2689. pwalk->SetIsSpeaking( false );
  2690. }
  2691. // when a player dies the system reports the player's position as the position of
  2692. // the spectator camera. If we let that happen, the dead player's X migrates from
  2693. // the point they died to follow another player's position.
  2694. //
  2695. // so, never update the icon position for a dead player
  2696. if ( playerIsActive && pwalk->m_bIsSpotted && !pwalk->m_bIsDead )
  2697. {
  2698. // dkorus and pfreese: Changed from local origin and local angles to last networked version to address jitter issues for pax demo 2011
  2699. pwalk->m_Position = pPlayer->GetNetworkOrigin();
  2700. // only set the angle of the icon if the player isn't above or below us
  2701. if ( nIsAboveOrBelow == R_SAMELEVEL )
  2702. pwalk->m_Angle = pPlayer->GetLocalAngles();
  2703. else
  2704. {
  2705. int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  2706. pwalk->m_Angle = MainViewAngles( nSlot );
  2707. }
  2708. if ( pPlayer->HasC4() )
  2709. {
  2710. m_BombPosition = pwalk->m_Position;
  2711. }
  2712. }
  2713. SetIconPackagePosition( pwalk );
  2714. }
  2715. }
  2716. }
  2717. bool SFMapOverview::IsEnemyCloseEnoughToShow( Vector vecEnemyPos )
  2718. {
  2719. //double check if spotted based on distance
  2720. // we're going to check the distance of this guy from all of the people on our team
  2721. // if they are outside the radius (more or less) of what the radar would allow us to see, consider them not spotted
  2722. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2723. if( !pLocalPlayer )
  2724. return false;
  2725. C_CS_PlayerResource *pCSPR = ( C_CS_PlayerResource* )GameResources();
  2726. if ( !pCSPR )
  2727. return false;
  2728. int localTeamNumber = pLocalPlayer->GetAssociatedTeamNumber();
  2729. bool bTooFar = true;
  2730. SFMapOverviewIconPackage* pTeammate = m_Players;
  2731. for ( int j = 0; j <= (m_iLastPlayerIndex); j++, pTeammate++ )
  2732. {
  2733. if ( pCSPR->IsConnected( (j+1) ) && localTeamNumber == pCSPR->GetTeam( (j+1) ) )
  2734. {
  2735. Vector toEnemy = pTeammate->m_Position - vecEnemyPos;
  2736. float dist = toEnemy.LengthSqr();
  2737. if ( dist <= NOTSPOTTEDRADIUS*NOTSPOTTEDRADIUS )
  2738. {
  2739. bTooFar = false;;
  2740. }
  2741. }
  2742. }
  2743. return !bTooFar;
  2744. }
  2745. void SFMapOverview::UpdateMiscIcons( void )
  2746. {
  2747. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2748. if ( !pLocalPlayer )
  2749. {
  2750. return;
  2751. }
  2752. // We show the entire dashboard in spectator mode now, so you can see bomb/hostage status, etc.
  2753. m_bShowingDashboard = true;
  2754. // Uncomment this line to disable the radar dashboard in spectator mode:
  2755. // m_bShowingDashboard = ( pLocalPlayer->GetObserverMode() == OBS_MODE_NONE );
  2756. const char *pszLocation = pLocalPlayer->GetLastKnownPlaceName();
  2757. if ( pszLocation )
  2758. {
  2759. SetLocationText( g_pVGuiLocalize->Find( pszLocation ) );
  2760. }
  2761. else
  2762. {
  2763. SetLocationText( NULL );
  2764. }
  2765. C_CS_PlayerResource *pCSPR = ( C_CS_PlayerResource* )GameResources();
  2766. if ( !pCSPR )
  2767. {
  2768. return;
  2769. }
  2770. m_fBombAlpha = 0.0f;
  2771. m_fDefuserAlpha = 0.0f;
  2772. if ( CSGameRules()->IsBombDefuseMap() )
  2773. {
  2774. if ( m_bBombPlanted )
  2775. {
  2776. FOR_EACH_VEC( g_PlantedC4s, iBomb )
  2777. {
  2778. C_PlantedC4 * pC4 = g_PlantedC4s[iBomb];
  2779. if ( pC4 && pC4->IsBombActive() )
  2780. {
  2781. bool bLocalPlayerCanSeeBomb =( pLocalPlayer->GetAssociatedTeamNumber() == TEAM_TERRORIST || m_bShowAll || ( pC4 && !pC4->IsDormant() && pC4->IsSpotted() ) && IsEnemyCloseEnoughToShow( pC4->GetNetworkOrigin() ) );
  2782. if ( bLocalPlayerCanSeeBomb && pC4 && !pC4->IsDormant() )
  2783. {
  2784. m_bBombIsSpotted = true;
  2785. m_BombPosition = pC4->GetNetworkOrigin();
  2786. }
  2787. }
  2788. }
  2789. }
  2790. if ( m_nBombEntIndex != -1 && ( !m_bBombIsSpotted || m_bBombDropped ) )
  2791. {
  2792. C_BaseEntity * pEntity = ClientEntityList().GetBaseEntity( m_nBombEntIndex );
  2793. bool bLocalPlayerCanSeeBomb = pLocalPlayer->GetAssociatedTeamNumber() == TEAM_TERRORIST || m_bShowAll || ( pEntity && !pEntity->IsDormant() && pEntity->IsSpotted() && IsEnemyCloseEnoughToShow( pEntity->GetNetworkOrigin() ) );
  2794. if ( bLocalPlayerCanSeeBomb && pEntity && !pEntity->IsDormant() )
  2795. {
  2796. Assert( pEntity && FClassnameIs( pEntity, "weapon_c4" ) );
  2797. m_bBombIsSpotted = true;
  2798. m_BombPosition = pEntity->GetNetworkOrigin();
  2799. }
  2800. }
  2801. float now = gpGlobals->curtime;
  2802. bool drawBomb = false;
  2803. bool bBombPositionIsValid = ( m_BombPosition.x != 0 || m_BombPosition.y != 0 );
  2804. if ( bBombPositionIsValid && !m_bBombExploded && m_bBombIsSpotted )
  2805. {
  2806. drawBomb = true;
  2807. m_fBombSeenTime = now;
  2808. m_fBombAlpha = 1.0f;
  2809. }
  2810. else if ( m_bBombExploded )
  2811. {
  2812. m_fBombAlpha = 0;
  2813. m_fBombSeenTime = TIMER_INIT;
  2814. }
  2815. else
  2816. {
  2817. m_fBombAlpha = clamp( 1.0f - ( now - m_fBombSeenTime )/BOMB_FADE_TIME, 0.0f, 1.0f );
  2818. if ( m_fBombAlpha > 0 )
  2819. {
  2820. drawBomb = true;
  2821. }
  2822. else
  2823. {
  2824. m_fBombSeenTime = TIMER_INIT;
  2825. }
  2826. }
  2827. if ( drawBomb )
  2828. {
  2829. m_bShowBombHighlight = !m_bBombDefused && ( m_bBombPlanted || m_bBombDropped );
  2830. }
  2831. }
  2832. else if ( CSGameRules()->IsHostageRescueMap() )
  2833. {
  2834. m_bShowingHostageZone = pLocalPlayer->IsInHostageRescueZone();
  2835. }
  2836. }
  2837. void SFMapOverview::ApplySpectatorModes( void )
  2838. {
  2839. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  2840. m_bShowAll = false;
  2841. m_iObserverMode = OBS_MODE_NONE;
  2842. if ( pLocalPlayer )
  2843. {
  2844. m_iObserverMode = pLocalPlayer->GetObserverMode();
  2845. if ( pLocalPlayer->IsSpectator() || pLocalPlayer->IsHLTV() )
  2846. {
  2847. m_bShowAll = true;
  2848. return;
  2849. }
  2850. }
  2851. // if ( m_iObserverMode != OBS_MODE_NONE )
  2852. // {
  2853. // // if we're observing in casual, then show everyone everywhere
  2854. // ConVarRef mp_forcecamera( "mp_forcecamera" );
  2855. // m_bShowAll = mp_forcecamera.GetInt() == OBS_ALLOW_ALL;
  2856. // }
  2857. }
  2858. void SFMapOverview::UpdateGrenades( void )
  2859. {
  2860. for ( int i = 0; i <= m_iLastGrenadeIndex; i++ )
  2861. {
  2862. SFMapOverviewIconPackage* pPackage = GetRadarGrenade( i );
  2863. if ( pPackage && pPackage->m_bIsActive )
  2864. {
  2865. SetIconPackagePosition( pPackage );
  2866. if ( !pPackage->IsVisible() )
  2867. {
  2868. RemoveGrenade( i );
  2869. }
  2870. }
  2871. }
  2872. }
  2873. void SFMapOverview::ProcessInput( void )
  2874. {
  2875. LazyCreateGoalIcons();
  2876. LazyCreatePlayerIcons();
  2877. ApplySpectatorModes();
  2878. PositionRadarViewpoint();
  2879. PlaceGoalIcons();
  2880. PlacePlayers();
  2881. PlaceHostages();
  2882. UpdateGrenades();
  2883. UpdateAllDefusers();
  2884. UpdateMiscIcons();
  2885. SetupIconsFromStates();
  2886. }
  2887. static inline bool Helper_AllowMapDrawing()
  2888. {
  2889. if ( mapoverview_allow_client_draw.GetBool() )
  2890. return true;
  2891. if ( sv_competitive_official_5v5.GetBool() )
  2892. return true;
  2893. if ( C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer() )
  2894. {
  2895. if ( pPlayer->IsHLTV() )
  2896. return true;
  2897. if ( pPlayer->IsSpectator() )
  2898. {
  2899. if ( CSGameRules() && CSGameRules()->IsQueuedMatchmaking() )
  2900. return true;
  2901. }
  2902. }
  2903. return false;
  2904. }
  2905. void SFMapOverview::AllowMapDrawing( SCALEFORM_CALLBACK_ARGS_DECL )
  2906. {
  2907. bool bAllow = Helper_AllowMapDrawing();
  2908. m_pScaleformUI->Params_SetResult( obj, bAllow );
  2909. }
  2910. void SFMapOverview::GetWorldDistance( SCALEFORM_CALLBACK_ARGS_DECL )
  2911. {
  2912. int x1 = ( float )pui->Params_GetArgAsNumber( obj, 0 );
  2913. int y1 = ( float )pui->Params_GetArgAsNumber( obj, 1 );
  2914. int x2 = ( float )pui->Params_GetArgAsNumber( obj, 2 );
  2915. int y2 = ( float )pui->Params_GetArgAsNumber( obj, 3 );
  2916. Vector vecStart;
  2917. Vector vecEnd;
  2918. RadarToWorld( Vector( x1, y1, 0 ), vecStart );
  2919. RadarToWorld( Vector( x2, y2, 0 ), vecEnd );
  2920. float flDist = vecStart.AsVector2D().DistTo( vecEnd.AsVector2D() );
  2921. m_pScaleformUI->Params_SetResult( obj, flDist );
  2922. }
  2923. /*
  2924. void SFMapOverview::GetNavPath( SCALEFORM_CALLBACK_ARGS_DECL )
  2925. {
  2926. int x1 = ( float )pui->Params_GetArgAsNumber( obj, 0 );
  2927. int y1 = ( float )pui->Params_GetArgAsNumber( obj, 1 );
  2928. int x2 = ( float )pui->Params_GetArgAsNumber( obj, 2 );
  2929. int y2 = ( float )pui->Params_GetArgAsNumber( obj, 3 );
  2930. Vector vecStart;
  2931. Vector vecEnd;
  2932. RadarToWorld( Vector( x1, y1, 0 ), vecStart );
  2933. RadarToWorld( Vector( x2, y2, 0 ), vecEnd );
  2934. CNavArea *navStartArea = TheNavMesh->GetNearestNavArea( vecStart );
  2935. CNavArea *navEndArea = TheNavMesh->GetNearestNavArea( vecEnd );
  2936. CNavArea *goalArea = NULL;
  2937. NavAreaBuildPath( tArea, ctArea, NULL, cost, &goalArea );
  2938. ShortestPathCost cost = ShortestPathCost();
  2939. float dist_left = NavAreaTravelDistance( TheNavMesh->GetNearestNavArea( ( *left )->GetAbsOrigin() ),
  2940. TheNavMesh->GetNearestNavArea( CSGameRules()->m_vecMainCTSpawnPos ),
  2941. cost );
  2942. float dist_right = NavAreaTravelDistance( TheNavMesh->GetNearestNavArea( ( *right )->GetAbsOrigin() ),
  2943. TheNavMesh->GetNearestNavArea( CSGameRules()->m_vecMainCTSpawnPos ),
  2944. cost );
  2945. //bool bAllow = Helper_AllowMapDrawing();
  2946. //m_pScaleformUI->Params_SetResult( obj, bAllow );
  2947. }
  2948. */