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.

322 lines
7.2 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. #define DMG_IMAGE_LIFE 2 // seconds that image is up
  25. #define NUM_DMG_TYPES 8
  26. typedef struct
  27. {
  28. float flExpire;
  29. float flBaseline;
  30. int x;
  31. int y;
  32. CHudTexture *icon;
  33. long fFlags;
  34. } damagetile_t;
  35. //-----------------------------------------------------------------------------
  36. // Purpose: HDU Damage type tiles
  37. //-----------------------------------------------------------------------------
  38. class CHudDamageTiles : public CHudElement, public vgui::Panel
  39. {
  40. DECLARE_CLASS_SIMPLE( CHudDamageTiles, vgui::Panel );
  41. public:
  42. CHudDamageTiles( const char *pElementName );
  43. void Init( void );
  44. void VidInit( void );
  45. void Reset( void );
  46. bool ShouldDraw( void );
  47. // Handler for our message
  48. void MsgFunc_Damage(bf_read &msg);
  49. private:
  50. void Paint();
  51. void ApplySchemeSettings(vgui::IScheme *pScheme);
  52. private:
  53. CHudTexture *DamageTileIcon( int i );
  54. long DamageTileFlags( int i );
  55. void UpdateTiles( long bits );
  56. private:
  57. long m_bitsDamage;
  58. damagetile_t m_dmgTileInfo[ NUM_DMG_TYPES ];
  59. };
  60. DECLARE_HUDELEMENT( CHudDamageTiles );
  61. DECLARE_HUD_MESSAGE( CHudDamageTiles, Damage );
  62. //-----------------------------------------------------------------------------
  63. // Purpose: Constructor
  64. //-----------------------------------------------------------------------------
  65. CHudDamageTiles::CHudDamageTiles( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudDamageTiles")
  66. {
  67. vgui::Panel *pParent = g_pClientMode->GetViewport();
  68. SetParent( pParent );
  69. SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
  70. }
  71. void CHudDamageTiles::Init( void )
  72. {
  73. HOOK_HUD_MESSAGE( CHudDamageTiles, Damage );
  74. }
  75. void CHudDamageTiles::VidInit( void )
  76. {
  77. Reset();
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Purpose:
  81. //-----------------------------------------------------------------------------
  82. void CHudDamageTiles::Reset( void )
  83. {
  84. m_bitsDamage = 0;
  85. for ( int i = 0; i < NUM_DMG_TYPES; i++ )
  86. {
  87. m_dmgTileInfo[ i ].flExpire = 0;
  88. m_dmgTileInfo[ i ].flBaseline = 0;
  89. m_dmgTileInfo[ i ].x = 0;
  90. m_dmgTileInfo[ i ].y = 0;
  91. m_dmgTileInfo[ i ].icon = DamageTileIcon( i );
  92. m_dmgTileInfo[ i ].fFlags = DamageTileFlags( i );
  93. }
  94. }
  95. CHudTexture *CHudDamageTiles::DamageTileIcon( int i )
  96. {
  97. switch ( i )
  98. {
  99. case 0:
  100. default:
  101. return gHUD.GetIcon( "dmg_poison" );
  102. break;
  103. case 1:
  104. return gHUD.GetIcon( "dmg_chem" );
  105. break;
  106. case 2:
  107. return gHUD.GetIcon( "dmg_cold" );
  108. break;
  109. case 3:
  110. return gHUD.GetIcon( "dmg_drown" );
  111. break;
  112. case 4:
  113. return gHUD.GetIcon( "dmg_heat" );
  114. break;
  115. case 5:
  116. return gHUD.GetIcon( "dmg_gas" );
  117. break;
  118. case 6:
  119. return gHUD.GetIcon( "dmg_rad" );
  120. break;
  121. case 7:
  122. return gHUD.GetIcon( "dmg_shock" );
  123. break;
  124. }
  125. }
  126. long CHudDamageTiles::DamageTileFlags( int i )
  127. {
  128. switch ( i )
  129. {
  130. case 0:
  131. default:
  132. return DMG_POISON;
  133. case 1:
  134. return DMG_ACID;
  135. case 2:
  136. // HL2 hijacked DMG_FREEZE and made it DMG_VEHICLE
  137. // HL2 hijacked DMG_SLOWFREEZE and made it DMG_DISSOLVE
  138. // return DMG_FREEZE | DMG_SLOWFREEZE;
  139. return DMG_VEHICLE | DMG_DISSOLVE;
  140. case 3:
  141. return DMG_DROWN;
  142. case 4:
  143. return DMG_BURN | DMG_SLOWBURN;
  144. case 5:
  145. return DMG_NERVEGAS;
  146. case 6:
  147. return DMG_RADIATION;
  148. case 7:
  149. return DMG_SHOCK;
  150. }
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Purpose: Message handler for Damage message
  154. //-----------------------------------------------------------------------------
  155. void CHudDamageTiles::MsgFunc_Damage( bf_read &msg )
  156. {
  157. msg.ReadByte(); // armor
  158. msg.ReadByte(); // health
  159. long bitsDamage = msg.ReadLong(); // damage bits, ignore
  160. UpdateTiles( bitsDamage );
  161. }
  162. bool CHudDamageTiles::ShouldDraw( void )
  163. {
  164. if ( !CHudElement::ShouldDraw() )
  165. return false;
  166. if ( !m_bitsDamage )
  167. return false;
  168. return true;
  169. }
  170. void CHudDamageTiles::Paint( void )
  171. {
  172. int r, g, b, a, nUnused;
  173. damagetile_t *pDmgTile;
  174. Color clrTile;
  175. (gHUD.m_clrYellowish).GetColor( r, g, b, nUnused );
  176. a = (int)( fabs( sin( gpGlobals->curtime * 2 ) ) * 256.0 );
  177. clrTile.SetColor( r, g, b, a );
  178. int i;
  179. // Draw all the items
  180. for ( i = 0; i < NUM_DMG_TYPES; i++ )
  181. {
  182. pDmgTile = &m_dmgTileInfo[ i ];
  183. if ( m_bitsDamage & pDmgTile->fFlags )
  184. {
  185. if ( pDmgTile->icon )
  186. {
  187. ( pDmgTile->icon )->DrawSelf( pDmgTile->x, pDmgTile->y, clrTile );
  188. }
  189. }
  190. }
  191. // check for bits that should be expired
  192. for ( i = 0; i < NUM_DMG_TYPES; i++ )
  193. {
  194. pDmgTile = &m_dmgTileInfo[ i ];
  195. if ( m_bitsDamage & pDmgTile->fFlags )
  196. {
  197. pDmgTile->flExpire = MIN( gpGlobals->curtime + DMG_IMAGE_LIFE, pDmgTile->flExpire );
  198. if ( pDmgTile->flExpire <= gpGlobals->curtime // when the time has expired
  199. && a < 40 ) // and the flash is at the low point of the cycle
  200. {
  201. pDmgTile->flExpire = 0;
  202. int y = pDmgTile->y;
  203. pDmgTile->x = 0;
  204. pDmgTile->y = 0;
  205. m_bitsDamage &= ~pDmgTile->fFlags; // clear the bits
  206. // move everyone above down
  207. for ( int j = 0; j < NUM_DMG_TYPES; j++ )
  208. {
  209. damagetile_t *pDmgTileIter = &m_dmgTileInfo[ j ];
  210. if ( ( pDmgTileIter->y ) && ( pDmgTileIter->y < y ) && ( pDmgTileIter->icon ) )
  211. pDmgTileIter->y += ( pDmgTileIter->icon )->Height();
  212. }
  213. }
  214. }
  215. }
  216. }
  217. void CHudDamageTiles::UpdateTiles( long bitsDamage )
  218. {
  219. damagetile_t *pDmgTile;
  220. // Which types are new?
  221. long bitsOn = ~m_bitsDamage & bitsDamage;
  222. for ( int i = 0; i < NUM_DMG_TYPES; i++ )
  223. {
  224. pDmgTile = &m_dmgTileInfo[ i ];
  225. // Is this one already on?
  226. if ( m_bitsDamage & pDmgTile->fFlags )
  227. {
  228. pDmgTile->flExpire = gpGlobals->curtime + DMG_IMAGE_LIFE; // extend the duration
  229. if ( !pDmgTile->flBaseline )
  230. {
  231. pDmgTile->flBaseline = gpGlobals->curtime;
  232. }
  233. }
  234. // Are we just turning it on?
  235. if ( bitsOn & pDmgTile->fFlags )
  236. {
  237. // put this one at the bottom
  238. if ( pDmgTile->icon )
  239. {
  240. pDmgTile->x = ( pDmgTile->icon )->Width() / 8;
  241. pDmgTile->y = GetTall() - ( pDmgTile->icon )->Height() * 2;
  242. }
  243. pDmgTile->flExpire = gpGlobals->curtime + DMG_IMAGE_LIFE;
  244. // move everyone else up
  245. for ( int j = 0; j < NUM_DMG_TYPES; j++ )
  246. {
  247. if ( j == i )
  248. continue;
  249. pDmgTile = &m_dmgTileInfo[ j ];
  250. if ( pDmgTile->y && pDmgTile->icon )
  251. pDmgTile->y -= ( pDmgTile->icon )->Height();
  252. }
  253. pDmgTile = &m_dmgTileInfo[ i ];
  254. }
  255. }
  256. // damage bits are only turned on here; they are turned off when the draw time has expired (in Paint())
  257. m_bitsDamage |= bitsDamage;
  258. }
  259. void CHudDamageTiles::ApplySchemeSettings(vgui::IScheme *pScheme)
  260. {
  261. BaseClass::ApplySchemeSettings(pScheme);
  262. SetPaintBackgroundEnabled(false);
  263. }