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.

331 lines
7.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hud.h"
  8. #include "text_message.h"
  9. #include "hud_macros.h"
  10. #include "iclientmode.h"
  11. #include "view.h"
  12. #include <KeyValues.h>
  13. #include <vgui/ISurface.h>
  14. #include <vgui_controls/Panel.h>
  15. #include "VGuiMatSurface/IMatSystemSurface.h"
  16. #include "materialsystem/imaterial.h"
  17. #include "materialsystem/imesh.h"
  18. #include "materialsystem/imaterialvar.h"
  19. #include "IEffects.h"
  20. #include "hudelement.h"
  21. using namespace vgui;
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. //-----------------------------------------------------------------------------
  25. // Purpose: HDU Damage indication
  26. //-----------------------------------------------------------------------------
  27. class CHudDamageIndicator : public CHudElement, public vgui::Panel
  28. {
  29. DECLARE_CLASS_SIMPLE( CHudDamageIndicator, vgui::Panel );
  30. public:
  31. CHudDamageIndicator( const char *pElementName );
  32. void Init( void );
  33. void Reset( void );
  34. bool ShouldDraw( void );
  35. // Handler for our message
  36. void MsgFunc_Damage(bf_read &msg);
  37. private:
  38. void Paint();
  39. void ApplySchemeSettings(vgui::IScheme *pScheme);
  40. private:
  41. void CalcDamageDirection( const Vector &vecFrom );
  42. void DrawDamageIndicatorFront( float flFade );
  43. void DrawDamageIndicatorRear( float flFade );
  44. void DrawDamageIndicatorLeft( float flFade );
  45. void DrawDamageIndicatorRight( float flFade );
  46. private:
  47. float m_flAttackFront;
  48. float m_flAttackRear;
  49. float m_flAttackLeft;
  50. float m_flAttackRight;
  51. Color m_clrIndicator;
  52. CHudTexture *icon_up;
  53. CHudTexture *icon_down;
  54. CHudTexture *icon_left;
  55. CHudTexture *icon_right;
  56. };
  57. DECLARE_HUDELEMENT( CHudDamageIndicator );
  58. DECLARE_HUD_MESSAGE( CHudDamageIndicator, Damage );
  59. //-----------------------------------------------------------------------------
  60. // Purpose: Constructor
  61. //-----------------------------------------------------------------------------
  62. CHudDamageIndicator::CHudDamageIndicator( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudDamageIndicator")
  63. {
  64. vgui::Panel *pParent = g_pClientMode->GetViewport();
  65. SetParent( pParent );
  66. SetHiddenBits( HIDEHUD_HEALTH );
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose:
  70. //-----------------------------------------------------------------------------
  71. void CHudDamageIndicator::Reset( void )
  72. {
  73. m_flAttackFront = 0.0;
  74. m_flAttackRear = 0.0;
  75. m_flAttackRight = 0.0;
  76. m_flAttackLeft = 0.0;
  77. m_clrIndicator.SetColor( 250, 0, 0, 255 );
  78. }
  79. void CHudDamageIndicator::Init( void )
  80. {
  81. HOOK_HUD_MESSAGE( CHudDamageIndicator, Damage );
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Purpose:
  85. //-----------------------------------------------------------------------------
  86. bool CHudDamageIndicator::ShouldDraw( void )
  87. {
  88. if ( !CHudElement::ShouldDraw() )
  89. return false;
  90. if ( ( m_flAttackFront <= 0.0 ) && ( m_flAttackRear <= 0.0 ) && ( m_flAttackLeft <= 0.0 ) && ( m_flAttackRight <= 0.0 ) )
  91. return false;
  92. return true;
  93. }
  94. void CHudDamageIndicator::DrawDamageIndicatorFront( float flFade )
  95. {
  96. if ( m_flAttackFront > 0.4 )
  97. {
  98. if ( !icon_up )
  99. {
  100. icon_up = gHUD.GetIcon( "pain_up" );
  101. }
  102. if ( !icon_up )
  103. {
  104. return;
  105. }
  106. int x = ( ScreenWidth() / 2 ) - icon_up->Width() / 2;
  107. int y = ( ScreenHeight() / 2 ) - icon_up->Height() * 3;
  108. icon_up->DrawSelf( x, y, m_clrIndicator );
  109. m_flAttackFront = MAX( 0.0, m_flAttackFront - flFade );
  110. }
  111. else
  112. {
  113. m_flAttackFront = 0.0;
  114. }
  115. }
  116. void CHudDamageIndicator::DrawDamageIndicatorRear( float flFade )
  117. {
  118. if ( m_flAttackRear > 0.4 )
  119. {
  120. if ( !icon_down )
  121. {
  122. icon_down = gHUD.GetIcon( "pain_down" );
  123. }
  124. if ( !icon_down )
  125. {
  126. return;
  127. }
  128. int x = ( ScreenWidth() / 2 ) - icon_down->Width() / 2;
  129. int y = ( ScreenHeight() / 2 ) + icon_down->Height() * 2;
  130. icon_down->DrawSelf( x, y, m_clrIndicator );
  131. m_flAttackRear = MAX( 0.0, m_flAttackRear - flFade );
  132. }
  133. else
  134. {
  135. m_flAttackRear = 0.0;
  136. }
  137. }
  138. void CHudDamageIndicator::DrawDamageIndicatorLeft( float flFade )
  139. {
  140. if ( m_flAttackLeft > 0.4 )
  141. {
  142. if ( !icon_left )
  143. {
  144. icon_left = gHUD.GetIcon( "pain_left" );
  145. }
  146. if ( !icon_left )
  147. {
  148. return;
  149. }
  150. int x = ( ScreenWidth() / 2 ) - icon_left->Width() * 3;
  151. int y = ( ScreenHeight() / 2 ) - icon_left->Height() / 2;
  152. icon_left->DrawSelf( x, y, m_clrIndicator );
  153. m_flAttackLeft = MAX( 0.0, m_flAttackLeft - flFade );
  154. }
  155. else
  156. {
  157. m_flAttackLeft = 0.0;
  158. }
  159. }
  160. void CHudDamageIndicator::DrawDamageIndicatorRight( float flFade )
  161. {
  162. if ( m_flAttackRight > 0.4 )
  163. {
  164. if ( !icon_right )
  165. {
  166. icon_right = gHUD.GetIcon( "pain_right" );
  167. }
  168. if ( !icon_right )
  169. {
  170. return;
  171. }
  172. int x = ( ScreenWidth() / 2 ) + icon_right->Width() * 2;
  173. int y = ( ScreenHeight() / 2 ) - icon_right->Height() / 2;
  174. icon_right->DrawSelf( x, y, m_clrIndicator );
  175. m_flAttackRight = MAX( 0.0, m_flAttackRight - flFade );
  176. }
  177. else
  178. {
  179. m_flAttackRight = 0.0;
  180. }
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose: Paints the damage display
  184. //-----------------------------------------------------------------------------
  185. void CHudDamageIndicator::Paint()
  186. {
  187. // draw damage indicators
  188. float flFade = gpGlobals->frametime * 2;
  189. DrawDamageIndicatorFront( flFade );
  190. DrawDamageIndicatorRear( flFade );
  191. DrawDamageIndicatorLeft( flFade );
  192. DrawDamageIndicatorRight( flFade);
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Purpose: Message handler for Damage message
  196. //-----------------------------------------------------------------------------
  197. void CHudDamageIndicator::MsgFunc_Damage( bf_read &msg )
  198. {
  199. int armor = msg.ReadByte(); // armor
  200. int damageTaken = msg.ReadByte(); // health
  201. msg.ReadLong(); // damage bits, ignore
  202. Vector vecFrom;
  203. vecFrom.x = msg.ReadFloat();
  204. vecFrom.y = msg.ReadFloat();
  205. vecFrom.z = msg.ReadFloat();
  206. if ( damageTaken > 0 || armor > 0 )
  207. {
  208. CalcDamageDirection( vecFrom );
  209. }
  210. }
  211. void CHudDamageIndicator::CalcDamageDirection( const Vector &vecFrom )
  212. {
  213. if ( vecFrom == vec3_origin )
  214. {
  215. m_flAttackFront = 0.0;
  216. m_flAttackRear = 0.0;
  217. m_flAttackRight = 0.0;
  218. m_flAttackLeft = 0.0;
  219. return;
  220. }
  221. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  222. if ( !pLocalPlayer )
  223. {
  224. return;
  225. }
  226. Vector vecDelta = ( vecFrom - pLocalPlayer->GetRenderOrigin() );
  227. if ( vecDelta.Length() <= 50 )
  228. {
  229. m_flAttackFront = 1.0;
  230. m_flAttackRear = 1.0;
  231. m_flAttackRight = 1.0;
  232. m_flAttackLeft = 1.0;
  233. return;
  234. }
  235. VectorNormalize( vecDelta );
  236. Vector forward;
  237. Vector right;
  238. AngleVectors( MainViewAngles(), &forward, &right, NULL );
  239. float flFront = DotProduct( vecDelta, forward );
  240. float flSide = DotProduct( vecDelta, right );
  241. if ( flFront > 0 )
  242. {
  243. if ( flFront > 0.3 )
  244. m_flAttackFront = MAX( m_flAttackFront, flFront );
  245. }
  246. else
  247. {
  248. float f = fabs( flFront );
  249. if ( f > 0.3 )
  250. m_flAttackRear = MAX( m_flAttackRear, f );
  251. }
  252. if ( flSide > 0 )
  253. {
  254. if ( flSide > 0.3 )
  255. m_flAttackRight = MAX( m_flAttackRight, flSide );
  256. }
  257. else
  258. {
  259. float f = fabs( flSide );
  260. if ( f > 0.3 )
  261. m_flAttackLeft = MAX( m_flAttackLeft, f );
  262. }
  263. }
  264. //-----------------------------------------------------------------------------
  265. // Purpose: hud scheme settings
  266. //-----------------------------------------------------------------------------
  267. void CHudDamageIndicator::ApplySchemeSettings(vgui::IScheme *pScheme)
  268. {
  269. BaseClass::ApplySchemeSettings(pScheme);
  270. SetPaintBackgroundEnabled(false);
  271. int wide, tall;
  272. GetHudSize(wide, tall);
  273. SetSize(wide, tall);
  274. }