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.

292 lines
8.2 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 "ihudlcd.h"
  13. #include "vgui/ILocalize.h"
  14. #include <vgui/ISurface.h>
  15. #include <vgui_controls/AnimationController.h>
  16. //-----------------------------------------------------------------------------
  17. // Purpose: Displays current ammunition level
  18. //-----------------------------------------------------------------------------
  19. class CHudAmmo : public CHudNumericDisplay, public CHudElement
  20. {
  21. DECLARE_CLASS_SIMPLE( CHudAmmo, CHudNumericDisplay );
  22. public:
  23. CHudAmmo( const char *pElementName );
  24. void Init( void );
  25. void VidInit( void );
  26. void SetAmmo(int ammo, bool playAnimation);
  27. void SetAmmo2(int ammo2, bool playAnimation);
  28. protected:
  29. virtual void OnThink();
  30. virtual void Paint( void );
  31. virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
  32. private:
  33. CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
  34. int m_iAmmo;
  35. int m_iAmmo2;
  36. bool m_bUsesClips;
  37. int m_iAdditiveWhiteID;
  38. CPanelAnimationVarAliasType( float, digit_xpos, "digit_xpos", "50", "proportional_float" );
  39. CPanelAnimationVarAliasType( float, digit_ypos, "digit_ypos", "2", "proportional_float" );
  40. CPanelAnimationVarAliasType( float, digit2_xpos, "digit2_xpos", "0", "proportional_float" );
  41. CPanelAnimationVarAliasType( float, digit2_ypos, "digit2_ypos", "0", "proportional_float" );
  42. CPanelAnimationVarAliasType( float, bar_xpos, "bar_xpos", "0", "proportional_float" );
  43. CPanelAnimationVarAliasType( float, bar_ypos, "bar_ypos", "0", "proportional_float" );
  44. CPanelAnimationVarAliasType( float, bar_width, "bar_width", "2", "proportional_float" );
  45. CPanelAnimationVarAliasType( float, bar_height, "bar_height", "2", "proportional_float" );
  46. CPanelAnimationVarAliasType( float, icon_xpos, "icon_xpos", "0", "proportional_float" );
  47. CPanelAnimationVarAliasType( float, icon_ypos, "icon_ypos", "0", "proportional_float" );
  48. CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
  49. CPanelAnimationVar( vgui::HFont, m_hNumberFont, "NumberFont", "HudNumbers" );
  50. };
  51. DECLARE_HUDELEMENT( CHudAmmo );
  52. //-----------------------------------------------------------------------------
  53. // Purpose: Constructor
  54. //-----------------------------------------------------------------------------
  55. CHudAmmo::CHudAmmo( const char *pElementName ) : BaseClass(NULL, "HudAmmo"), CHudElement( pElementName )
  56. {
  57. m_iAdditiveWhiteID = vgui::surface()->CreateNewTextureID();
  58. vgui::surface()->DrawSetTextureFile( m_iAdditiveWhiteID, "vgui/white_additive" , true, false);
  59. SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_WEAPONSELECTION );
  60. hudlcd->SetGlobalStat( "(ammo_primary)", "0" );
  61. hudlcd->SetGlobalStat( "(ammo_secondary)", "0" );
  62. hudlcd->SetGlobalStat( "(weapon_print_name)", "" );
  63. hudlcd->SetGlobalStat( "(weapon_name)", "" );
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Purpose:
  67. //-----------------------------------------------------------------------------
  68. void CHudAmmo::Init( void )
  69. {
  70. m_iAmmo = -1;
  71. m_iAmmo2 = -1;
  72. }
  73. void CHudAmmo::ApplySchemeSettings(vgui::IScheme *pScheme)
  74. {
  75. BaseClass::ApplySchemeSettings(pScheme);
  76. }
  77. //-----------------------------------------------------------------------------
  78. // Purpose:
  79. //-----------------------------------------------------------------------------
  80. void CHudAmmo::VidInit( void )
  81. {
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Purpose: called every frame to get ammo info from the weapon
  85. //-----------------------------------------------------------------------------
  86. void CHudAmmo::OnThink()
  87. {
  88. C_BaseCombatWeapon *wpn = GetActiveWeapon();
  89. hudlcd->SetGlobalStat( "(weapon_print_name)", wpn ? wpn->GetPrintName() : " " );
  90. hudlcd->SetGlobalStat( "(weapon_name)", wpn ? wpn->GetName() : " " );
  91. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  92. if (!wpn || !player || !wpn->UsesPrimaryAmmo())
  93. {
  94. hudlcd->SetGlobalStat( "(ammo_primary)", "n/a" );
  95. hudlcd->SetGlobalStat( "(ammo_secondary)", "n/a" );
  96. SetPaintEnabled(false);
  97. SetPaintBackgroundEnabled(false);
  98. return;
  99. }
  100. else
  101. {
  102. SetPaintEnabled(true);
  103. SetPaintBackgroundEnabled(true);
  104. }
  105. // get the ammo in our clip
  106. int ammo1 = wpn->Clip1();
  107. int ammo2;
  108. if (ammo1 < 0)
  109. {
  110. // we don't use clip ammo, just use the total ammo count
  111. ammo1 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
  112. ammo2 = 0;
  113. }
  114. else
  115. {
  116. // we use clip ammo, so the second ammo is the total ammo
  117. ammo2 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
  118. }
  119. hudlcd->SetGlobalStat( "(ammo_primary)", VarArgs( "%d", ammo1 ) );
  120. hudlcd->SetGlobalStat( "(ammo_secondary)", VarArgs( "%d", ammo2 ) );
  121. if (wpn == m_hCurrentActiveWeapon)
  122. {
  123. // same weapon, just update counts
  124. SetAmmo(ammo1, true);
  125. SetAmmo2(ammo2, true);
  126. }
  127. else
  128. {
  129. // diferent weapon, change without triggering
  130. SetAmmo(ammo1, false);
  131. SetAmmo2(ammo2, false);
  132. // update whether or not we show the total ammo display
  133. if (wpn->UsesClipsForAmmo1())
  134. {
  135. m_bUsesClips = true;
  136. }
  137. else
  138. {
  139. m_bUsesClips = false;
  140. }
  141. m_hCurrentActiveWeapon = wpn;
  142. }
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Purpose: Updates ammo display
  146. //-----------------------------------------------------------------------------
  147. void CHudAmmo::SetAmmo(int ammo, bool playAnimation)
  148. {
  149. if (ammo != m_iAmmo)
  150. {
  151. if (ammo == 0)
  152. {
  153. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("PrimaryAmmoEmpty");
  154. }
  155. else if (ammo < m_iAmmo)
  156. {
  157. // ammo has decreased
  158. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("PrimaryAmmoDecrement");
  159. }
  160. else
  161. {
  162. // ammunition has increased
  163. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("PrimaryAmmoIncrement");
  164. }
  165. m_iAmmo = ammo;
  166. }
  167. SetDisplayValue(ammo);
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Purpose: Updates 2nd ammo display
  171. //-----------------------------------------------------------------------------
  172. void CHudAmmo::SetAmmo2(int ammo2, bool playAnimation)
  173. {
  174. if (ammo2 != m_iAmmo2)
  175. {
  176. if (ammo2 == 0)
  177. {
  178. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SecondaryAmmoEmpty");
  179. }
  180. else if (ammo2 < m_iAmmo2)
  181. {
  182. // ammo has decreased
  183. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SecondaryAmmoDecrement");
  184. }
  185. else
  186. {
  187. // ammunition has increased
  188. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SecondaryAmmoIncrement");
  189. }
  190. m_iAmmo2 = ammo2;
  191. }
  192. }
  193. void CHudAmmo::Paint( void )
  194. {
  195. float alpha = 1.0f;
  196. Color fgColor = GetFgColor();
  197. fgColor[3] *= alpha;
  198. SetFgColor( fgColor );
  199. int x, y;
  200. if( m_bUsesClips )
  201. {
  202. x = digit_xpos;
  203. y = digit_ypos;
  204. }
  205. else
  206. {
  207. x = digit2_xpos;
  208. y = digit2_ypos;
  209. }
  210. // Assume constant width font
  211. int charWidth = vgui::surface()->GetCharacterWidth( m_hNumberFont, '0' );
  212. int digits = clamp( log10((double)m_iAmmo)+1, 1, 3 );
  213. x += ( 3 - digits ) * charWidth;
  214. // draw primary ammo
  215. vgui::surface()->DrawSetTextColor(GetFgColor());
  216. PaintNumbers( m_hNumberFont, x, y, m_iAmmo );
  217. //draw reserve ammo
  218. if( m_bUsesClips )
  219. {
  220. //draw the divider
  221. Color c = GetFgColor();
  222. vgui::surface()->DrawSetColor(c);
  223. vgui::surface()->DrawSetTexture( m_iAdditiveWhiteID );
  224. vgui::surface()->DrawTexturedRect( bar_xpos, bar_ypos, bar_xpos + bar_width, bar_ypos + bar_height );
  225. digits = clamp( log10((double)m_iAmmo2)+1, 1, 3 );
  226. x = digit2_xpos + ( 3 - digits ) * charWidth;
  227. // draw secondary ammo
  228. vgui::surface()->DrawSetTextColor(GetFgColor());
  229. PaintNumbers( m_hNumberFont, x, digit2_ypos, m_iAmmo2 );
  230. }
  231. //draw the icon
  232. C_BaseCombatWeapon *wpn = GetActiveWeapon();
  233. if( wpn )
  234. {
  235. int ammoType = wpn->GetPrimaryAmmoType();
  236. CHudTexture *icon = gWR.GetAmmoIconFromWeapon( ammoType );
  237. if( icon )
  238. {
  239. float icon_tall = GetTall() - YRES(2);
  240. float scale = icon_tall / (float)icon->Height();
  241. float icon_wide = ( scale ) * (float)icon->Width();
  242. icon->DrawSelf( icon_xpos, icon_ypos, icon_wide, icon_tall, GetFgColor() );
  243. }
  244. }
  245. }