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

426 lines
11 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hud.h"
  8. #include "hudelement.h"
  9. #include "hud_macros.h"
  10. #include "hud_numericdisplay.h"
  11. #include "iclientmode.h"
  12. #include "iclientvehicle.h"
  13. #include <vgui_controls/AnimationController.h>
  14. #include <vgui/ILocalize.h>
  15. #include "ihudlcd.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. //-----------------------------------------------------------------------------
  19. // Purpose: Displays current ammunition level
  20. //-----------------------------------------------------------------------------
  21. class CHudAmmo : public CHudNumericDisplay, public CHudElement
  22. {
  23. DECLARE_CLASS_SIMPLE( CHudAmmo, CHudNumericDisplay );
  24. public:
  25. CHudAmmo( const char *pElementName );
  26. void Init( void );
  27. void VidInit( void );
  28. void Reset();
  29. void SetAmmo(int ammo, bool playAnimation);
  30. void SetAmmo2(int ammo2, bool playAnimation);
  31. protected:
  32. virtual void OnThink();
  33. void UpdateAmmoDisplays();
  34. void UpdatePlayerAmmo( C_BasePlayer *player );
  35. private:
  36. CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
  37. CHandle< C_BaseEntity > m_hCurrentVehicle;
  38. int m_iAmmo;
  39. int m_iAmmo2;
  40. };
  41. DECLARE_HUDELEMENT( CHudAmmo );
  42. //-----------------------------------------------------------------------------
  43. // Purpose: Constructor
  44. //-----------------------------------------------------------------------------
  45. CHudAmmo::CHudAmmo( const char *pElementName ) : BaseClass(NULL, "HudAmmo"), CHudElement( pElementName )
  46. {
  47. SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT | HIDEHUD_WEAPONSELECTION );
  48. hudlcd->SetGlobalStat( "(ammo_primary)", "0" );
  49. hudlcd->SetGlobalStat( "(ammo_secondary)", "0" );
  50. hudlcd->SetGlobalStat( "(weapon_print_name)", "" );
  51. hudlcd->SetGlobalStat( "(weapon_name)", "" );
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. //-----------------------------------------------------------------------------
  56. void CHudAmmo::Init( void )
  57. {
  58. m_iAmmo = -1;
  59. m_iAmmo2 = -1;
  60. wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO");
  61. if (tempString)
  62. {
  63. SetLabelText(tempString);
  64. }
  65. else
  66. {
  67. SetLabelText(L"AMMO");
  68. }
  69. }
  70. //-----------------------------------------------------------------------------
  71. // Purpose:
  72. //-----------------------------------------------------------------------------
  73. void CHudAmmo::VidInit( void )
  74. {
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose: Resets hud after save/restore
  78. //-----------------------------------------------------------------------------
  79. void CHudAmmo::Reset()
  80. {
  81. BaseClass::Reset();
  82. m_hCurrentActiveWeapon = NULL;
  83. m_hCurrentVehicle = NULL;
  84. m_iAmmo = 0;
  85. m_iAmmo2 = 0;
  86. UpdateAmmoDisplays();
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Purpose: called every frame to get ammo info from the weapon
  90. //-----------------------------------------------------------------------------
  91. void CHudAmmo::UpdatePlayerAmmo( C_BasePlayer *player )
  92. {
  93. // Clear out the vehicle entity
  94. m_hCurrentVehicle = NULL;
  95. C_BaseCombatWeapon *wpn = GetActiveWeapon();
  96. hudlcd->SetGlobalStat( "(weapon_print_name)", wpn ? wpn->GetPrintName() : " " );
  97. hudlcd->SetGlobalStat( "(weapon_name)", wpn ? wpn->GetName() : " " );
  98. if ( !wpn || !player || !wpn->UsesPrimaryAmmo() )
  99. {
  100. hudlcd->SetGlobalStat( "(ammo_primary)", "n/a" );
  101. hudlcd->SetGlobalStat( "(ammo_secondary)", "n/a" );
  102. SetPaintEnabled(false);
  103. SetPaintBackgroundEnabled(false);
  104. return;
  105. }
  106. SetPaintEnabled(true);
  107. SetPaintBackgroundEnabled(true);
  108. // get the ammo in our clip
  109. int ammo1 = wpn->Clip1();
  110. int ammo2;
  111. if (ammo1 < 0)
  112. {
  113. // we don't use clip ammo, just use the total ammo count
  114. ammo1 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
  115. ammo2 = 0;
  116. }
  117. else
  118. {
  119. // we use clip ammo, so the second ammo is the total ammo
  120. ammo2 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
  121. }
  122. hudlcd->SetGlobalStat( "(ammo_primary)", VarArgs( "%d", ammo1 ) );
  123. hudlcd->SetGlobalStat( "(ammo_secondary)", VarArgs( "%d", ammo2 ) );
  124. if (wpn == m_hCurrentActiveWeapon)
  125. {
  126. // same weapon, just update counts
  127. SetAmmo(ammo1, true);
  128. SetAmmo2(ammo2, true);
  129. }
  130. else
  131. {
  132. // diferent weapon, change without triggering
  133. SetAmmo(ammo1, false);
  134. SetAmmo2(ammo2, false);
  135. // update whether or not we show the total ammo display
  136. if (wpn->UsesClipsForAmmo1())
  137. {
  138. SetShouldDisplaySecondaryValue(true);
  139. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips");
  140. }
  141. else
  142. {
  143. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips");
  144. SetShouldDisplaySecondaryValue(false);
  145. }
  146. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged");
  147. m_hCurrentActiveWeapon = wpn;
  148. }
  149. }
  150. /*
  151. void CHudAmmo::UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle )
  152. {
  153. m_hCurrentActiveWeapon = NULL;
  154. CBaseEntity *pVehicleEnt = pVehicle->GetVehicleEnt();
  155. if ( !pVehicleEnt || pVehicle->GetPrimaryAmmoType() < 0 )
  156. {
  157. SetPaintEnabled(false);
  158. SetPaintBackgroundEnabled(false);
  159. return;
  160. }
  161. SetPaintEnabled(true);
  162. SetPaintBackgroundEnabled(true);
  163. // get the ammo in our clip
  164. int ammo1 = pVehicle->GetPrimaryAmmoClip();
  165. int ammo2;
  166. if (ammo1 < 0)
  167. {
  168. // we don't use clip ammo, just use the total ammo count
  169. ammo1 = pVehicle->GetPrimaryAmmoCount();
  170. ammo2 = 0;
  171. }
  172. else
  173. {
  174. // we use clip ammo, so the second ammo is the total ammo
  175. ammo2 = pVehicle->GetPrimaryAmmoCount();
  176. }
  177. if (pVehicleEnt == m_hCurrentVehicle)
  178. {
  179. // same weapon, just update counts
  180. SetAmmo(ammo1, true);
  181. SetAmmo2(ammo2, true);
  182. }
  183. else
  184. {
  185. // diferent weapon, change without triggering
  186. SetAmmo(ammo1, false);
  187. SetAmmo2(ammo2, false);
  188. // update whether or not we show the total ammo display
  189. if (pVehicle->PrimaryAmmoUsesClips())
  190. {
  191. SetShouldDisplaySecondaryValue(true);
  192. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips");
  193. }
  194. else
  195. {
  196. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips");
  197. SetShouldDisplaySecondaryValue(false);
  198. }
  199. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged");
  200. m_hCurrentVehicle = pVehicleEnt;
  201. }
  202. }
  203. */
  204. //-----------------------------------------------------------------------------
  205. // Purpose: called every frame to get ammo info from the weapon
  206. //-----------------------------------------------------------------------------
  207. void CHudAmmo::OnThink()
  208. {
  209. UpdateAmmoDisplays();
  210. }
  211. //-----------------------------------------------------------------------------
  212. // Purpose: updates the ammo display counts
  213. //-----------------------------------------------------------------------------
  214. void CHudAmmo::UpdateAmmoDisplays()
  215. {
  216. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  217. UpdatePlayerAmmo( player );
  218. }
  219. //-----------------------------------------------------------------------------
  220. // Purpose: Updates ammo display
  221. //-----------------------------------------------------------------------------
  222. void CHudAmmo::SetAmmo(int ammo, bool playAnimation)
  223. {
  224. if (ammo != m_iAmmo)
  225. {
  226. if (ammo == 0)
  227. {
  228. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoEmpty");
  229. }
  230. else if (ammo < m_iAmmo)
  231. {
  232. // ammo has decreased
  233. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoDecreased");
  234. }
  235. else
  236. {
  237. // ammunition has increased
  238. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoIncreased");
  239. }
  240. m_iAmmo = ammo;
  241. }
  242. SetDisplayValue(ammo);
  243. }
  244. //-----------------------------------------------------------------------------
  245. // Purpose: Updates 2nd ammo display
  246. //-----------------------------------------------------------------------------
  247. void CHudAmmo::SetAmmo2(int ammo2, bool playAnimation)
  248. {
  249. if (ammo2 != m_iAmmo2)
  250. {
  251. if (ammo2 == 0)
  252. {
  253. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Empty");
  254. }
  255. else if (ammo2 < m_iAmmo2)
  256. {
  257. // ammo has decreased
  258. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Decreased");
  259. }
  260. else
  261. {
  262. // ammunition has increased
  263. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Increased");
  264. }
  265. m_iAmmo2 = ammo2;
  266. }
  267. SetSecondaryValue(ammo2);
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Purpose: Displays the secondary ammunition level
  271. //-----------------------------------------------------------------------------
  272. class CHudSecondaryAmmo : public CHudNumericDisplay, public CHudElement
  273. {
  274. DECLARE_CLASS_SIMPLE( CHudSecondaryAmmo, CHudNumericDisplay );
  275. public:
  276. CHudSecondaryAmmo( const char *pElementName ) : BaseClass( NULL, "HudAmmoSecondary" ), CHudElement( pElementName )
  277. {
  278. m_iAmmo = -1;
  279. SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_WEAPONSELECTION | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
  280. }
  281. void Init( void )
  282. {
  283. }
  284. void VidInit( void )
  285. {
  286. }
  287. void SetAmmo( int ammo )
  288. {
  289. if (ammo != m_iAmmo)
  290. {
  291. if (ammo == 0)
  292. {
  293. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryEmpty");
  294. }
  295. else if (ammo < m_iAmmo)
  296. {
  297. // ammo has decreased
  298. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryDecreased");
  299. }
  300. else
  301. {
  302. // ammunition has increased
  303. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryIncreased");
  304. }
  305. m_iAmmo = ammo;
  306. }
  307. SetDisplayValue( ammo );
  308. }
  309. void Reset()
  310. {
  311. // hud reset, update ammo state
  312. BaseClass::Reset();
  313. m_iAmmo = 0;
  314. m_hCurrentActiveWeapon = NULL;
  315. SetAlpha( 0 );
  316. UpdateAmmoState();
  317. }
  318. protected:
  319. virtual void OnThink()
  320. {
  321. // set whether or not the panel draws based on if we have a weapon that supports secondary ammo
  322. C_BaseCombatWeapon *wpn = GetActiveWeapon();
  323. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  324. IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL;
  325. if (!wpn || !player || pVehicle)
  326. {
  327. m_hCurrentActiveWeapon = NULL;
  328. SetPaintEnabled(false);
  329. SetPaintBackgroundEnabled(false);
  330. return;
  331. }
  332. else
  333. {
  334. SetPaintEnabled(true);
  335. SetPaintBackgroundEnabled(true);
  336. }
  337. UpdateAmmoState();
  338. }
  339. void UpdateAmmoState()
  340. {
  341. C_BaseCombatWeapon *wpn = GetActiveWeapon();
  342. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  343. if (player && wpn && wpn->UsesSecondaryAmmo())
  344. {
  345. SetAmmo(player->GetAmmoCount(wpn->GetSecondaryAmmoType()));
  346. }
  347. if ( m_hCurrentActiveWeapon != wpn )
  348. {
  349. if ( wpn->UsesSecondaryAmmo() )
  350. {
  351. // we've changed to a weapon that uses secondary ammo
  352. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesSecondaryAmmo");
  353. }
  354. else
  355. {
  356. // we've changed away from a weapon that uses secondary ammo
  357. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseSecondaryAmmo");
  358. }
  359. m_hCurrentActiveWeapon = wpn;
  360. }
  361. }
  362. private:
  363. CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
  364. int m_iAmmo;
  365. };
  366. DECLARE_HUDELEMENT( CHudSecondaryAmmo );