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.

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