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.

692 lines
22 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Displays HUD elements about health and armor
  4. //
  5. //=====================================================================================//
  6. #include "cbase.h"
  7. #include "hud.h"
  8. #include "hudelement.h"
  9. #include "hud_element_helper.h"
  10. #include "iclientmode.h"
  11. #include "view.h"
  12. #include "vgui_controls/Controls.h"
  13. #include "vgui/ISurface.h"
  14. #include "ivrenderview.h"
  15. #include "scaleformui/scaleformui.h"
  16. #include "sfhudweaponpanel.h"
  17. #include "vgui/ILocalize.h"
  18. #include "c_cs_hostage.h"
  19. #include "HUD/sfweaponselection.h"
  20. #include "clientsteamcontext.h"
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include "tier0/memdbgon.h"
  23. #define SAFECALL( handle, func ) \
  24. if ( handle ) \
  25. { \
  26. func \
  27. }
  28. DECLARE_HUDELEMENT( SFHudWeaponPanel );
  29. SFUI_BEGIN_GAME_API_DEF
  30. SFUI_END_GAME_API_DEF( SFHudWeaponPanel, WeaponModule ); // Asset named WeaponModule to maintain consistency with Flash file naming
  31. extern ConVar cl_draw_only_deathnotices;
  32. SFHudWeaponPanel::SFHudWeaponPanel( const char *value ) : SFHudFlashInterface( value ),
  33. m_PanelHandle( NULL ),
  34. m_CurrentWeaponImageHandle( NULL ),
  35. m_CurrentWeaponTextHandle( NULL ),
  36. m_AmmoTextClipHandle( NULL ),
  37. m_AmmoTextTotalHandle( NULL ),
  38. m_AmmoAnimationHandle( NULL ),
  39. m_BurstIcons_Burst( NULL ),
  40. m_BurstIcons_Single( NULL ),
  41. m_WeaponPenetration1( NULL ),
  42. m_WeaponPenetration2( NULL ),
  43. m_WeaponPenetration3( NULL ),
  44. m_UpgradeKill1( NULL ),
  45. m_UpgradeKill2( NULL ),
  46. m_UpgradeKillText( NULL ),
  47. m_BombHandle( NULL ),
  48. m_DefuseHandle( NULL ),
  49. m_BombZoneHandle( NULL ),
  50. m_WeaponItemName( NULL ),
  51. m_PrevAmmoClipCount( -1 ),
  52. m_PrevAmmoTotalCount( -1 ),
  53. m_PrevAmmoType( -1 ),
  54. m_PrevWeaponID( -1 ),
  55. m_PrevTRGunGameUpgradePoints( 0 ),
  56. m_bHiddenNoAmmo( false ),
  57. m_bCarryingC4( false ),
  58. m_bCarryingDefuse( false ),
  59. m_bInBombZone( false ),
  60. m_lastEntityIndex( 0 ),
  61. m_LastNumRoundKills( 0 ),
  62. m_lastKillEaterCount( 0 )
  63. {
  64. // TODO Auto-generated constructor stub
  65. SetHiddenBits( HIDEHUD_WEAPONSELECTION );
  66. }
  67. SFHudWeaponPanel::~SFHudWeaponPanel()
  68. {
  69. // TODO Auto-generated destructor stub
  70. }
  71. void SFHudWeaponPanel::ShowPanel( bool value )
  72. {
  73. if ( !m_pScaleformUI )
  74. return;
  75. WITH_SLOT_LOCKED
  76. {
  77. if ( m_FlashAPI )
  78. {
  79. if ( value )
  80. {
  81. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showNow", NULL, 0 );
  82. }
  83. else
  84. {
  85. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hideNow", NULL, 0 );
  86. }
  87. }
  88. }
  89. }
  90. void SFHudWeaponPanel::SetVisible( bool bVisible )
  91. {
  92. if ( FlashAPIIsValid() )
  93. {
  94. WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
  95. {
  96. m_pScaleformUI->ValueArray_SetElement( data, 0, bVisible );
  97. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setVisible", data, 1 );
  98. }
  99. }
  100. }
  101. void SFHudWeaponPanel::LockSlot( bool wantItLocked, bool& currentlyLocked )
  102. {
  103. if ( currentlyLocked != wantItLocked )
  104. {
  105. if ( wantItLocked )
  106. {
  107. LockScaleformSlot();
  108. }
  109. else
  110. {
  111. UnlockScaleformSlot();
  112. }
  113. currentlyLocked = wantItLocked;
  114. }
  115. }
  116. void SFHudWeaponPanel::ProcessInput( void )
  117. {
  118. // Update stats
  119. int currentClip = 0;
  120. // we need the map clip to calculate the percentage of ammo left
  121. // in the clip so the hud knows when to warn you
  122. int maxClip = 0;
  123. int totalAmmo = 0;
  124. int ammoType = -1;
  125. int weaponID = -1;
  126. const char *weaponName = NULL;
  127. const char *shortWeaponName = NULL;
  128. bool bInTRBombMode = false;
  129. bool bHideNoAmmo = false;
  130. int CurrTRPoints = -1;
  131. // Collect all player, weapon and game state data first:
  132. if ( CSGameRules()->IsPlayingGunGame() )
  133. {
  134. if ( CSGameRules()->IsPlayingGunGameTRBomb() )
  135. {
  136. bInTRBombMode = true;
  137. }
  138. }
  139. C_CSPlayer *pPlayer = GetHudPlayer();
  140. CWeaponCSBase *pWeapon = NULL;
  141. int entityIndex = pPlayer->entindex();
  142. if ( pPlayer)
  143. {
  144. if ( CSGameRules()->IsBombDefuseMap() || CSGameRules()->IsHostageRescueMap() )
  145. {
  146. if ( m_bCarryingC4 != pPlayer->HasC4() )
  147. {
  148. m_bCarryingC4 = pPlayer->HasC4();
  149. }
  150. SFWeaponSelection *pHudWS = GET_HUDELEMENT( SFWeaponSelection );
  151. if ( pHudWS )
  152. {
  153. static ConVarRef cl_hud_bomb_under_radar( "cl_hud_bomb_under_radar" );
  154. bool bShowBomb = ( cl_hud_bomb_under_radar.GetInt( ) == 0 && m_bCarryingC4 );
  155. //SAFECALL( m_BombHandle, m_pScaleformUI->Value_SetVisible( m_BombHandle, bShowBomb ); );
  156. WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
  157. {
  158. m_pScaleformUI->ValueArray_SetElement( args, 0, bShowBomb );
  159. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "ShowBomb", args, 1 );
  160. }
  161. }
  162. if ( m_bCarryingDefuse != pPlayer->HasDefuser() )
  163. {
  164. m_bCarryingDefuse = pPlayer->HasDefuser();
  165. SAFECALL( m_DefuseHandle, m_pScaleformUI->Value_SetVisible( m_DefuseHandle, m_bCarryingDefuse ); );
  166. }
  167. if ( m_bInBombZone != pPlayer->m_bInBombZone )
  168. {
  169. m_bInBombZone = pPlayer->m_bInBombZone;
  170. SAFECALL( m_BombZoneHandle, m_pScaleformUI->Value_SetVisible( m_BombZoneHandle, m_bInBombZone ); );
  171. }
  172. }
  173. int nRoundKills = pPlayer->GetNumRoundKills();
  174. int nRoundKillsHeadshots = pPlayer->GetNumRoundKillsHeadshots();
  175. if( pPlayer->IsControllingBot() )
  176. {
  177. C_CSPlayer *controlledPlayerScorer = ToCSPlayer( UTIL_PlayerByIndex( pPlayer->GetControlledBotIndex() ) );
  178. if( controlledPlayerScorer )
  179. {
  180. nRoundKills = controlledPlayerScorer->GetNumRoundKills();
  181. nRoundKillsHeadshots = controlledPlayerScorer->GetNumRoundKillsHeadshots();
  182. }
  183. }
  184. if ( m_LastNumRoundKills != nRoundKills )
  185. {
  186. int nCurIndex = pPlayer->GetPlayerGunGameWeaponIndex();
  187. int nRequiredKills = 0;
  188. if ( CSGameRules()->IsPlayingGunGameProgressive() )
  189. nRequiredKills = CSGameRules()->GetGunGameNumKillsRequiredForWeapon( nCurIndex, pPlayer->GetTeamNumber() );
  190. WITH_SFVALUEARRAY_SLOT_LOCKED( args, 3 )
  191. {
  192. m_pScaleformUI->ValueArray_SetElement( args, 0, nRoundKills );
  193. m_pScaleformUI->ValueArray_SetElement( args, 1, nRoundKillsHeadshots );
  194. m_pScaleformUI->ValueArray_SetElement( args, 2, nRequiredKills );
  195. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setNumberKills", args, 3 );
  196. }
  197. m_LastNumRoundKills = nRoundKills;
  198. }
  199. if ( bInTRBombMode == true )
  200. {
  201. CurrTRPoints = pPlayer->GetNumGunGameTRKillPoints();
  202. const int nUpgradedFlag = 99;
  203. // We track "upgrade achieved" by saving the upgrade points as 99 - which means it will
  204. // always differ from the actual kill points once we've already upgraded. So, we don't
  205. // want to push another change to the panel until our points get reset at the next round
  206. bool bAlreadyUpgraded = ( m_PrevTRGunGameUpgradePoints == nUpgradedFlag );
  207. bool bZeroed = ( CurrTRPoints == 0 );
  208. if ( ( m_PrevTRGunGameUpgradePoints != CurrTRPoints ) && ( !bAlreadyUpgraded || bZeroed ) )
  209. {
  210. // disable the little kill flags now because with the NEXT WEAPON panel serves this purpose and the flags cause confusion
  211. // TODO: find a way to bring the kill flags back some way because they add a lot of value
  212. /*
  213. switch( CurrTRPoints )
  214. {
  215. case 0:
  216. SAFECALL( m_UpgradeKill1, m_pScaleformUI->Value_SetVisible( m_UpgradeKill1, false); );
  217. SAFECALL( m_UpgradeKill2, m_pScaleformUI->Value_SetVisible( m_UpgradeKill2, false); );
  218. SAFECALL( m_UpgradeKillText, m_pScaleformUI->Value_SetVisible( m_UpgradeKillText, false ); );
  219. break;
  220. case 1:
  221. SAFECALL( m_UpgradeKill1, m_pScaleformUI->Value_SetVisible( m_UpgradeKill1, true); );
  222. break;
  223. case 2:
  224. SAFECALL( m_UpgradeKill2, m_pScaleformUI->Value_SetVisible( m_UpgradeKill2, true); );
  225. break;
  226. default:
  227. break;
  228. }
  229. */
  230. static ConVarRef mp_ggtr_bomb_pts_for_upgrade( "mp_ggtr_bomb_pts_for_upgrade" );
  231. if ( CurrTRPoints >= mp_ggtr_bomb_pts_for_upgrade.GetInt() )
  232. {
  233. // disable the little kill flags now because with the NEXT WEAPON panel serves this purpose and the flags cause confusion
  234. // TODO: find a way to bring the kill flags back some way because they add a lot of value
  235. /*
  236. SAFECALL( m_UpgradeKillText, m_pScaleformUI->Value_SetVisible( m_UpgradeKillText, true); );
  237. WITH_SLOT_LOCKED
  238. {
  239. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "playUpgradeAnim", NULL, 0 );
  240. }
  241. */
  242. m_PrevTRGunGameUpgradePoints = nUpgradedFlag;
  243. }
  244. else
  245. {
  246. m_PrevTRGunGameUpgradePoints = CurrTRPoints;
  247. }
  248. }
  249. }
  250. pWeapon = pPlayer ? (CWeaponCSBase*)pPlayer->GetActiveWeapon() : NULL;
  251. if ( pWeapon )
  252. {
  253. weaponName = pWeapon->GetPrintName();
  254. shortWeaponName = pWeapon->GetName();
  255. // remap weaponID to our ammo numbering (defined in the action script for this hud element) - currently, just bullets vs grenades
  256. // $TODO: are we going to reflect any other ammo types, like XBLA did?
  257. weaponID = pWeapon->GetCSWeaponID();
  258. switch ( weaponID )
  259. {
  260. case WEAPON_DECOY: // $FIXME: prototype grenades just display with the flashbang ammo
  261. case WEAPON_MOLOTOV:
  262. case WEAPON_INCGRENADE:
  263. case WEAPON_FLASHBANG:
  264. case WEAPON_TAGRENADE:
  265. ammoType = 1;
  266. break;
  267. case WEAPON_HEGRENADE:
  268. ammoType = 2;
  269. break;
  270. case WEAPON_SMOKEGRENADE:
  271. ammoType = 3;
  272. break;
  273. case WEAPON_HEALTHSHOT:
  274. ammoType = 10;
  275. break;
  276. default:
  277. ammoType = 0;
  278. break;
  279. }
  280. // determine what to display for ammo: "clip/total", "total" or nothing (for knife, c4, etc)
  281. if ( !pWeapon->UsesPrimaryAmmo() )
  282. {
  283. currentClip = -1;
  284. maxClip = -1;
  285. totalAmmo = -1;
  286. }
  287. else
  288. {
  289. currentClip = pWeapon->Clip1();
  290. maxClip = pWeapon->GetMaxClip1();
  291. if ( currentClip < 0 )
  292. {
  293. // we don't use clip ammo, just use the total ammo count
  294. currentClip = pWeapon->GetReserveAmmoCount( AMMO_POSITION_PRIMARY );
  295. totalAmmo = -1;
  296. }
  297. else
  298. {
  299. // we use clip ammo, so the second ammo is the total ammo
  300. totalAmmo = pWeapon->GetReserveAmmoCount( AMMO_POSITION_PRIMARY );
  301. ;
  302. }
  303. }
  304. }
  305. }
  306. // Updating flash, slot locking begins...
  307. bool bSlotIsLocked = false;
  308. char cNewStr[ 128 ];
  309. // Update weapon image and text
  310. if ( m_PrevWeaponID != weaponID )
  311. {
  312. LockSlot( true, bSlotIsLocked );
  313. if ( weaponName )
  314. {
  315. SAFECALL( m_CurrentWeaponTextHandle, m_pScaleformUI->Value_SetText( m_CurrentWeaponTextHandle, weaponName ); );
  316. }
  317. // Update the selected weapon image as well
  318. if ( FlashAPIIsValid() && shortWeaponName )
  319. {
  320. WITH_SFVALUEARRAY( data, 1 )
  321. {
  322. m_pScaleformUI->ValueArray_SetElement( data, 0, shortWeaponName );
  323. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "switchWeaponName", data, 1 );
  324. }
  325. }
  326. // CCSWeaponInfo const * pWeaponInfo = GetWeaponInfo( static_cast<CSWeaponID>( weaponID ) );
  327. CEconItemView *pItem = pWeapon ? pWeapon->GetEconItemView() : NULL;
  328. // if ( pWeaponInfo )
  329. // {
  330. // SAFECALL( m_WeaponPenetration1, m_pScaleformUI->Value_SetVisible( m_WeaponPenetration1, pWeaponInfo->GetAttributeFloat( "penetration", pItem ) == 1 ? true : false ); );
  331. // SAFECALL( m_WeaponPenetration2, m_pScaleformUI->Value_SetVisible( m_WeaponPenetration2, pWeaponInfo->GetAttributeFloat( "penetration", pItem ) == 2 ? true : false ); );
  332. // SAFECALL( m_WeaponPenetration3, m_pScaleformUI->Value_SetVisible( m_WeaponPenetration3, pWeaponInfo->GetAttributeFloat( "penetration", pItem ) == 3 ? true : false ); );
  333. // }
  334. // update the weapon name
  335. if ( pWeapon )
  336. {
  337. if ( !pItem || !pItem->IsValid() || pItem->GetItemID() <= 0 || !GetItemSchema() || !GetItemSchema()->GetRarityDefinition( pItem->GetRarity() ) )
  338. {
  339. SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetVisible( m_WeaponItemName, false ); );
  340. }
  341. else
  342. {
  343. const CEconItemRarityDefinition* pRarity = GetItemSchema()->GetRarityDefinition( pItem->GetRarity() );
  344. SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetVisible( m_WeaponItemName, true ); );
  345. const int kColorBufSize = 128;
  346. wchar_t rwchColor[kColorBufSize];
  347. Q_UTF8ToUnicode( GetHexColorForAttribColor( pRarity->GetAttribColor() ), rwchColor, kColorBufSize );
  348. // Update target name
  349. wchar_t wcTargetWeaponFormatted[128];
  350. V_snwprintf( wcTargetWeaponFormatted, ARRAYSIZE( wcTargetWeaponFormatted ), L"<font color=\"" PRI_WS_FOR_WS L"\">" PRI_WS_FOR_WS L"</font>", rwchColor, pItem->GetItemName() );
  351. SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetTextHTML( m_WeaponItemName, wcTargetWeaponFormatted ); );
  352. }
  353. }
  354. }
  355. // Determine if this weapon has no ammo at all, so the panel should be hidden
  356. bHideNoAmmo = (( totalAmmo < 0 ) && ( currentClip < 0 )) || !pWeapon;
  357. if ( ( bInTRBombMode && CurrTRPoints > 0 ) ||
  358. m_bCarryingC4 || m_bCarryingDefuse || m_bInBombZone || weaponID == WEAPON_KNIFE )
  359. {
  360. // Ensure we still show this when in TR Bomb AND we have kill points to display
  361. // or if we have bomb/defuse kit or are in the bomb zone
  362. bHideNoAmmo = false;
  363. }
  364. // Update ammo type/count/animating bullets elements
  365. if (
  366. ( totalAmmo != m_PrevAmmoTotalCount ) ||
  367. ( currentClip != m_PrevAmmoClipCount ) ||
  368. ( weaponID != m_PrevWeaponID ) )
  369. {
  370. LockSlot( true, bSlotIsLocked );
  371. // Display current weapon ammunition (or lack thereof)
  372. bool bAmmoShown = true;
  373. if ( totalAmmo < 0 )
  374. {
  375. // doesn't use ammo at all (knife, c4, etc)
  376. cNewStr[0] = 0;
  377. bAmmoShown = false;
  378. }
  379. else
  380. {
  381. V_snprintf( cNewStr, sizeof( cNewStr ), "%d", currentClip );
  382. }
  383. if ( bAmmoShown )
  384. {
  385. SAFECALL( m_AmmoTextClipHandle, m_pScaleformUI->Value_SetText( m_AmmoTextClipHandle, cNewStr ); );
  386. V_snprintf( cNewStr, sizeof( cNewStr ), "/ %d", totalAmmo );
  387. SAFECALL( m_AmmoTextTotalHandle, m_pScaleformUI->Value_SetText( m_AmmoTextTotalHandle, cNewStr ); );
  388. }
  389. SAFECALL( m_AmmoTextClipHandle, m_pScaleformUI->Value_SetVisible( m_AmmoTextClipHandle, bAmmoShown ); );
  390. SAFECALL( m_AmmoTextTotalHandle, m_pScaleformUI->Value_SetVisible( m_AmmoTextTotalHandle, bAmmoShown ); );
  391. }
  392. bool bShowBurstBurst = (pWeapon && pWeapon->WeaponHasBurst() && pWeapon->IsInBurstMode());
  393. bool bShowBurstSingle = (pWeapon && pWeapon->WeaponHasBurst() && !pWeapon->IsInBurstMode());
  394. SAFECALL( m_BurstIcons_Burst, m_pScaleformUI->Value_SetVisible( m_BurstIcons_Burst, bShowBurstBurst ); );
  395. SAFECALL( m_BurstIcons_Single, m_pScaleformUI->Value_SetVisible( m_BurstIcons_Single, bShowBurstSingle ); );
  396. // Show the appropriate ammo for our weapon type
  397. if ( ( m_PrevAmmoType != ammoType ) ||
  398. ( m_PrevAmmoClipCount != currentClip ) || (ammoType != 0 && weaponID != m_PrevWeaponID) )
  399. {
  400. if ( m_FlashAPI )
  401. {
  402. LockSlot( true, bSlotIsLocked );
  403. WITH_SFVALUEARRAY( data, 4 )
  404. {
  405. m_pScaleformUI->ValueArray_SetElement( data, 0, ammoType );
  406. m_pScaleformUI->ValueArray_SetElement( data, 1, currentClip );
  407. m_pScaleformUI->ValueArray_SetElement( data, 2, maxClip );
  408. m_pScaleformUI->ValueArray_SetElement( data, 3, shortWeaponName );
  409. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "updateAmmo", data, 4 );
  410. }
  411. }
  412. }
  413. // Notify the HUD when we fire - detected by not changing weapon/observed player, and our ammo count decreases
  414. if ( entityIndex == m_lastEntityIndex && m_PrevWeaponID == weaponID && (ammoType == 0) && m_PrevAmmoClipCount > 0 && currentClip < m_PrevAmmoClipCount )
  415. {
  416. if ( m_FlashAPI )
  417. {
  418. LockSlot( true, bSlotIsLocked );
  419. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "weaponFired", NULL, 0 );
  420. }
  421. }
  422. // Update previous state so we know which elements need to be refreshed next time
  423. m_PrevAmmoClipCount = currentClip;
  424. m_PrevAmmoTotalCount = totalAmmo;
  425. m_PrevAmmoType = ammoType;
  426. m_PrevWeaponID = weaponID;
  427. m_lastEntityIndex = entityIndex;
  428. LockSlot( false, bSlotIsLocked );
  429. // Now determine if the panel should be entirely hidden, because our current weapon uses no ammo
  430. if ( bHideNoAmmo != m_bHiddenNoAmmo )
  431. {
  432. if ( m_bActive )
  433. {
  434. ShowPanel( !bHideNoAmmo );
  435. }
  436. m_bHiddenNoAmmo = bHideNoAmmo;
  437. }
  438. }
  439. void SFHudWeaponPanel::FireGameEvent( IGameEvent *event )
  440. {
  441. const char *type = event->GetName();
  442. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  443. if ( !pLocalPlayer )
  444. return;
  445. int nPlayerUserID = pLocalPlayer->GetUserID();
  446. int nEventUserID = event->GetInt( "userid" );
  447. if ( StringHasPrefix( type, "round_start" ) ||
  448. ( StringHasPrefix( type, "player_death" ) && nPlayerUserID == nEventUserID ) ||
  449. ( StringHasPrefix( type, "bot_takeover" ) && nEventUserID == nPlayerUserID ) )
  450. {
  451. // reset these when the reound restarts of if the player dies
  452. m_bCarryingC4 = false;
  453. m_bCarryingDefuse = false;
  454. SAFECALL( m_BombHandle, m_pScaleformUI->Value_SetVisible( m_BombHandle, false ); );
  455. SAFECALL( m_DefuseHandle, m_pScaleformUI->Value_SetVisible( m_DefuseHandle, false ); );
  456. if ( ( StringHasPrefix( type, "player_death" ) && !CSGameRules()->IsWarmupPeriod() ) )
  457. {
  458. int nCurIndex = pLocalPlayer->GetPlayerGunGameWeaponIndex();
  459. int nRequiredKills = 0;
  460. if ( CSGameRules()->IsPlayingGunGameProgressive() )
  461. nRequiredKills = CSGameRules()->GetGunGameNumKillsRequiredForWeapon( nCurIndex, pLocalPlayer->GetTeamNumber() );
  462. WITH_SFVALUEARRAY_SLOT_LOCKED( args, 3 )
  463. {
  464. m_pScaleformUI->ValueArray_SetElement( args, 0, 0 );
  465. m_pScaleformUI->ValueArray_SetElement( args, 1, 0 );
  466. m_pScaleformUI->ValueArray_SetElement( args, 2, nRequiredKills );
  467. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setNumberKills", args, 3 );
  468. }
  469. }
  470. if ( CSGameRules()->IsPlayingGunGameProgressive() )
  471. {
  472. m_LastNumRoundKills = -1;
  473. }
  474. }
  475. }
  476. static void GetTextBoxForElement( IScaleformUI *pScaleformUI, SFVALUE root, const char *elementName, const char *textElementName, SFVALUE &sfv )
  477. {
  478. SFVALUE TempHandle = pScaleformUI->Value_GetMember( root, elementName );
  479. if ( TempHandle )
  480. {
  481. sfv = pScaleformUI->Value_GetMember( TempHandle, textElementName );
  482. pScaleformUI->ReleaseValue( TempHandle );
  483. }
  484. }
  485. void SFHudWeaponPanel::FlashReady( void )
  486. {
  487. m_PanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanel" );
  488. if ( m_PanelHandle )
  489. {
  490. SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_PanelHandle, "WeaponPanel" );
  491. if ( AnimatedPanelHandle )
  492. {
  493. m_CurrentWeaponImageHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "CurrentWeapon" );
  494. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "WeaponText", "TextBox", m_CurrentWeaponTextHandle );
  495. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "AmmoCountClip", "TextBox", m_AmmoTextClipHandle );
  496. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "AmmoCountTotal", "TextBox", m_AmmoTextTotalHandle );
  497. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "WeaponName", "TextBox", m_WeaponItemName );
  498. m_AmmoAnimationHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "AmmoAnim" );
  499. m_BurstIcons_Burst = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "BurstTypeBurst" );
  500. m_BurstIcons_Single = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "BurstTypeSingle" );
  501. m_WeaponPenetration1 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Penetration1" );
  502. m_WeaponPenetration2 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Penetration2" );
  503. m_WeaponPenetration3 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Penetration3" );
  504. m_UpgradeKill1 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Kill1" );
  505. m_UpgradeKill2 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Kill2" );
  506. m_UpgradeKillText = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "UpgradeText" );
  507. m_BombHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "BombCarrierIcon" );
  508. m_DefuseHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "DefuseKitIcon" );
  509. m_BombZoneHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "InBombZoneIcon" );
  510. SAFECALL( m_UpgradeKill1, m_pScaleformUI->Value_SetVisible( m_UpgradeKill1, false); );
  511. SAFECALL( m_UpgradeKill2, m_pScaleformUI->Value_SetVisible( m_UpgradeKill2, false); );
  512. SAFECALL( m_UpgradeKillText, m_pScaleformUI->Value_SetVisible( m_UpgradeKillText, false); );
  513. SAFECALL( m_BombHandle, m_pScaleformUI->Value_SetVisible( m_BombHandle, false ); );
  514. SAFECALL( m_DefuseHandle, m_pScaleformUI->Value_SetVisible( m_DefuseHandle, false ); );
  515. SAFECALL( m_BombZoneHandle, m_pScaleformUI->Value_SetVisible( m_BombZoneHandle, false ); );
  516. SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetVisible( m_WeaponItemName, false ); );
  517. m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
  518. }
  519. }
  520. if ( m_FlashAPI && m_pScaleformUI )
  521. {
  522. ListenForGameEvent( "round_start" );
  523. ListenForGameEvent( "player_death" );
  524. ListenForGameEvent( "bot_takeover" );
  525. }
  526. // hide everything initially
  527. SetVisible( false );
  528. }
  529. bool SFHudWeaponPanel::PreUnloadFlash( void )
  530. {
  531. SafeReleaseSFVALUE( m_PanelHandle );
  532. SafeReleaseSFVALUE( m_CurrentWeaponImageHandle );
  533. SafeReleaseSFVALUE( m_CurrentWeaponTextHandle );
  534. SafeReleaseSFVALUE( m_AmmoTextClipHandle );
  535. SafeReleaseSFVALUE( m_AmmoTextTotalHandle );
  536. SafeReleaseSFVALUE( m_AmmoAnimationHandle );
  537. SafeReleaseSFVALUE( m_BurstIcons_Burst );
  538. SafeReleaseSFVALUE( m_BurstIcons_Single );
  539. SafeReleaseSFVALUE( m_WeaponPenetration1 );
  540. SafeReleaseSFVALUE( m_WeaponPenetration2 );
  541. SafeReleaseSFVALUE( m_WeaponPenetration3 );
  542. SafeReleaseSFVALUE( m_UpgradeKill1 );
  543. SafeReleaseSFVALUE( m_UpgradeKill2 );
  544. SafeReleaseSFVALUE( m_UpgradeKillText );
  545. SafeReleaseSFVALUE( m_BombHandle );
  546. SafeReleaseSFVALUE( m_DefuseHandle );
  547. SafeReleaseSFVALUE( m_BombZoneHandle );
  548. SafeReleaseSFVALUE( m_WeaponItemName );
  549. return true;
  550. }
  551. void SFHudWeaponPanel::LevelInit( void )
  552. {
  553. if ( !FlashAPIIsValid() )
  554. {
  555. SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudWeaponPanel, this, WeaponModule );
  556. }
  557. else
  558. {
  559. // When initially loaded, hide this panel
  560. SetVisible( false );
  561. }
  562. // Reset all transient data
  563. m_PrevAmmoClipCount = -1;
  564. m_PrevAmmoTotalCount = -1;
  565. m_PrevAmmoType = -1;
  566. m_PrevWeaponID = -1;
  567. m_PrevTRGunGameUpgradePoints = 0;
  568. m_bHiddenNoAmmo = false;
  569. }
  570. void SFHudWeaponPanel::LevelShutdown( void )
  571. {
  572. if ( FlashAPIIsValid() )
  573. {
  574. RemoveFlashElement();
  575. }
  576. }
  577. bool SFHudWeaponPanel::ShouldDraw( void )
  578. {
  579. return cl_drawhud.GetBool() && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
  580. }
  581. void SFHudWeaponPanel::SetActive( bool bActive )
  582. {
  583. // Do not show the panel if we have hidden it because of an ammo-less weapon
  584. if ( bActive != m_bActive && !m_bHiddenNoAmmo )
  585. {
  586. ShowPanel( bActive );
  587. }
  588. CHudElement::SetActive( bActive );
  589. }