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.

275 lines
7.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "cbase.h"
  8. #include "hud.h"
  9. #include "hudelement.h"
  10. #include "c_tf_player.h"
  11. #include "iclientmode.h"
  12. #include "ienginevgui.h"
  13. #include <vgui/ILocalize.h>
  14. #include <vgui/ISurface.h>
  15. #include <vgui/IVGui.h>
  16. #include <vgui_controls/EditablePanel.h>
  17. #include <vgui_controls/ProgressBar.h>
  18. #include "tf_weaponbase.h"
  19. #include "c_tf_projectile_arrow.h"
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include "tier0/memdbgon.h"
  22. using namespace vgui;
  23. //-----------------------------------------------------------------------------
  24. // Purpose:
  25. //-----------------------------------------------------------------------------
  26. class CHudBowChargeMeter : public CHudElement, public EditablePanel
  27. {
  28. DECLARE_CLASS_SIMPLE( CHudBowChargeMeter, EditablePanel );
  29. public:
  30. CHudBowChargeMeter( const char *pElementName );
  31. virtual void ApplySchemeSettings( IScheme *scheme );
  32. virtual bool ShouldDraw( void );
  33. virtual void OnTick( void );
  34. virtual void Init( void );
  35. virtual void FireGameEvent( IGameEvent *event );
  36. private:
  37. vgui::ContinuousProgressBar *m_pChargeMeter;
  38. };
  39. DECLARE_HUDELEMENT( CHudBowChargeMeter );
  40. //-----------------------------------------------------------------------------
  41. // Purpose:
  42. //-----------------------------------------------------------------------------
  43. CHudBowChargeMeter::CHudBowChargeMeter( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudBowCharge" )
  44. {
  45. Panel *pParent = g_pClientMode->GetViewport();
  46. SetParent( pParent );
  47. m_pChargeMeter = new ContinuousProgressBar( this, "ChargeMeter" );
  48. SetHiddenBits( HIDEHUD_MISCSTATUS );
  49. vgui::ivgui()->AddTickSignal( GetVPanel() );
  50. RegisterForRenderGroup( "inspect_panel" );
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Purpose:
  54. //-----------------------------------------------------------------------------
  55. void CHudBowChargeMeter::ApplySchemeSettings( IScheme *pScheme )
  56. {
  57. // load control settings...
  58. LoadControlSettings( "resource/UI/HudBowCharge.res" );
  59. BaseClass::ApplySchemeSettings( pScheme );
  60. }
  61. //-----------------------------------------------------------------------------
  62. // Purpose:
  63. //-----------------------------------------------------------------------------
  64. void CHudBowChargeMeter::Init( void )
  65. {
  66. ListenForGameEvent( "arrow_impact" );
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose:
  70. //-----------------------------------------------------------------------------
  71. void CHudBowChargeMeter::FireGameEvent( IGameEvent *event )
  72. {
  73. if ( !event )
  74. return;
  75. const char *pszEventName = event->GetName();
  76. if ( FStrEq( pszEventName, "arrow_impact" ) )
  77. {
  78. int attachedEntity = event->GetInt( "attachedEntity" );
  79. C_BaseFlex *pFlex = dynamic_cast<C_BaseFlex*>( ClientEntityList().GetEnt( attachedEntity ) );
  80. if ( !pFlex )
  81. return;
  82. // Create a client side arrow and have it attach itself.
  83. C_TFProjectile_Arrow *pArrow = new C_TFProjectile_Arrow;
  84. if ( !pArrow )
  85. return;
  86. int boneIndexAttached = event->GetInt( "boneIndexAttached" );
  87. Vector bonePosition(
  88. event->GetFloat( "bonePositionX"),
  89. event->GetFloat( "bonePositionY"),
  90. event->GetFloat( "bonePositionZ") );
  91. QAngle boneAngles(
  92. event->GetFloat( "boneAnglesX"),
  93. event->GetFloat( "boneAnglesY"),
  94. event->GetFloat( "boneAnglesZ") );
  95. const char* pszModelName = NULL;
  96. int type = event->GetInt( "projectileType" );
  97. float flScale = 1.0f;
  98. switch ( type )
  99. {
  100. case TF_PROJECTILE_STICKY_BALL:
  101. pszModelName = g_pszArrowModels[MODEL_SNOWBALL];
  102. break;
  103. case TF_PROJECTILE_ARROW:
  104. pszModelName = g_pszArrowModels[MODEL_ARROW_REGULAR];
  105. break;
  106. case TF_PROJECTILE_BUILDING_REPAIR_BOLT:
  107. pszModelName = g_pszArrowModels[MODEL_ARROW_BUILDING_REPAIR];
  108. break;
  109. case TF_PROJECTILE_FESTIVE_ARROW:
  110. pszModelName = g_pszArrowModels[MODEL_FESTIVE_ARROW_REGULAR];
  111. break;
  112. case TF_PROJECTILE_HEALING_BOLT:
  113. #ifdef STAGING_ONLY
  114. case TF_PROJECTILE_MILK_BOLT:
  115. #endif
  116. {
  117. pszModelName = g_pszArrowModels[MODEL_SYRINGE];
  118. // pull the syringe back slightly
  119. Vector vForward;
  120. AngleVectors( boneAngles, &vForward );
  121. bonePosition = bonePosition - (vForward * 6.0f);
  122. flScale = 1.6f;
  123. }
  124. break;
  125. case TF_PROJECTILE_FESTIVE_HEALING_BOLT:
  126. {
  127. pszModelName = g_pszArrowModels[MODEL_FESTIVE_HEALING_BOLT];
  128. // pull the syringe back slightly
  129. Vector vForward;
  130. AngleVectors( boneAngles, &vForward );
  131. bonePosition = bonePosition - ( vForward * 1.0f );
  132. flScale = 1.4f;
  133. }
  134. break;
  135. case TF_PROJECTILE_BREAD_MONSTER:
  136. case TF_PROJECTILE_BREADMONSTER_JARATE:
  137. case TF_PROJECTILE_BREADMONSTER_MADMILK:
  138. {
  139. pszModelName = g_pszArrowModels[MODEL_BREAD_MONSTER];
  140. // pull the syringe back slightly
  141. Vector vForward;
  142. AngleVectors( boneAngles, &vForward );
  143. bonePosition = bonePosition - ( vForward * 1.0f );
  144. flScale = 2.5f;
  145. pArrow->SetLifeTime( 10.0f );
  146. if ( event->GetBool( "isCrit" ) )
  147. {
  148. flScale = RandomFloat( 3.0f, 5.0f );
  149. }
  150. break;
  151. }
  152. #ifdef STAGING_ONLY
  153. case TF_PROJECTILE_THROWING_KNIFE:
  154. {
  155. pszModelName = g_pszArrowModels[MODEL_THROWING_KNIFE];
  156. // pull the syringe back slightly
  157. Vector vForward;
  158. AngleVectors( boneAngles, &vForward );
  159. //bonePosition = bonePosition + ( vForward * 5.0f );
  160. //bonePosition = ( vForward * -7.0f ) + Vector(0, 0, 2);
  161. //flScale = 5.0f;
  162. break;
  163. }
  164. case TF_PROJECTILE_SNIPERBULLET:
  165. pszModelName = g_pszArrowModels[MODEL_SYRINGE];
  166. break;
  167. #endif // STAGING_ONLY
  168. default:
  169. Warning( " Unsupported Projectile type on event arrow_impact - %d", type );
  170. return;
  171. }
  172. pArrow->InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY );
  173. pArrow->SetModelScale( flScale );
  174. CTFPlayer *pPlayer = ToTFPlayer( ClientEntityList().GetEnt( event->GetInt( "shooter" ) ) );
  175. if ( pPlayer )
  176. {
  177. pArrow->m_nSkin = ( pPlayer->GetTeamNumber() == TF_TEAM_BLUE ) ? 1 : 0;
  178. }
  179. pArrow->AttachEntityToBone( pFlex, boneIndexAttached, bonePosition, boneAngles );
  180. }
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose:
  184. //-----------------------------------------------------------------------------
  185. bool CHudBowChargeMeter::ShouldDraw( void )
  186. {
  187. C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
  188. if ( !pPlayer || !pPlayer->IsPlayerClass( TF_CLASS_SNIPER ) || !pPlayer->IsAlive() )
  189. {
  190. return false;
  191. }
  192. CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
  193. if ( !pWpn )
  194. {
  195. return false;
  196. }
  197. int iWeaponID = pWpn->GetWeaponID();
  198. if ( iWeaponID != TF_WEAPON_COMPOUND_BOW )
  199. {
  200. return false;
  201. }
  202. return CHudElement::ShouldDraw();
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose:
  206. //-----------------------------------------------------------------------------
  207. void CHudBowChargeMeter::OnTick( void )
  208. {
  209. C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
  210. if ( !pPlayer )
  211. return;
  212. CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
  213. ITFChargeUpWeapon *pChargeupWeapon = dynamic_cast< ITFChargeUpWeapon *>( pWpn );
  214. if ( !pWpn || !pChargeupWeapon )
  215. return;
  216. if ( m_pChargeMeter )
  217. {
  218. float flChargeMaxTime = pChargeupWeapon->GetChargeMaxTime();
  219. if ( flChargeMaxTime != 0 )
  220. {
  221. float flChargeBeginTime = pChargeupWeapon->GetChargeBeginTime();
  222. if ( flChargeBeginTime > 0 )
  223. {
  224. float flTimeCharged = MAX( 0, gpGlobals->curtime - flChargeBeginTime );
  225. flTimeCharged = MIN( flTimeCharged, 1.f );
  226. float flPercentCharged = MIN( 1.0, flTimeCharged / flChargeMaxTime );
  227. m_pChargeMeter->SetProgress( flPercentCharged );
  228. }
  229. else
  230. {
  231. m_pChargeMeter->SetProgress( 0.0f );
  232. }
  233. }
  234. }
  235. }