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.

281 lines
8.1 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_spectatorgui.h"
  19. #include "hud_macros.h"
  20. #include "c_playerresource.h"
  21. #include "view.h"
  22. #include "player_vs_environment/c_tf_upgrades.h"
  23. #include "tf_hud_inspectpanel.h"
  24. // memdbgon must be the last include file in a .cpp file!!!
  25. #include "tier0/memdbgon.h"
  26. DECLARE_HUDELEMENT( CHudInspectPanel );
  27. static float s_flLastInspectDownTime = 0.f;
  28. void InspectDown()
  29. {
  30. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  31. if ( pLocalPlayer == NULL )
  32. {
  33. return;
  34. }
  35. s_flLastInspectDownTime = gpGlobals->curtime;
  36. KeyValues *kv = new KeyValues( "+inspect_server" );
  37. engine->ServerCmdKeyValues( kv );
  38. pLocalPlayer->SetInspectTime( gpGlobals->curtime );
  39. }
  40. static ConCommand s_inspect_down_cmd( "+inspect", InspectDown, "", FCVAR_SERVER_CAN_EXECUTE );
  41. void InspectUp()
  42. {
  43. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  44. if ( pLocalPlayer == NULL )
  45. {
  46. return;
  47. }
  48. // quick tap on the inspect button, try to inspect players
  49. if ( gpGlobals->curtime - s_flLastInspectDownTime <= 0.2f )
  50. {
  51. CHudElement *pElement = gHUD.FindElement( "CHudInspectPanel" );
  52. if ( pElement )
  53. {
  54. ((CHudInspectPanel *)pElement)->UserCmd_InspectTarget();
  55. }
  56. }
  57. KeyValues *kv = new KeyValues( "-inspect_server" );
  58. engine->ServerCmdKeyValues( kv );
  59. pLocalPlayer->SetInspectTime( 0.f );
  60. }
  61. static ConCommand s_inspect_up_cmd( "-inspect", InspectUp, "", FCVAR_SERVER_CAN_EXECUTE );
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //-----------------------------------------------------------------------------
  65. CHudInspectPanel::CHudInspectPanel( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudInspectPanel" )
  66. {
  67. Panel *pParent = g_pClientMode->GetViewport();
  68. SetParent( pParent );
  69. SetHiddenBits( HIDEHUD_MISCSTATUS );
  70. m_pItemPanel = new CItemModelPanel( this, "itempanel" ) ;
  71. m_iTargetItemIterator = 0;
  72. RegisterForRenderGroup( "mid" );
  73. RegisterForRenderGroup( "commentary" );
  74. RegisterForRenderGroup( "arena_target_id" );
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose:
  78. //-----------------------------------------------------------------------------
  79. void CHudInspectPanel::ApplySchemeSettings( IScheme *pScheme )
  80. {
  81. // load control settings...
  82. LoadControlSettings( "resource/UI/HudInspectPanel.res" );
  83. BaseClass::ApplySchemeSettings( pScheme );
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Purpose:
  87. //-----------------------------------------------------------------------------
  88. void CHudInspectPanel::LockInspectRenderGroup( bool bLock )
  89. {
  90. int iIndex = gHUD.LookupRenderGroupIndexByName( "inspect_panel" );
  91. if ( bLock )
  92. {
  93. gHUD.LockRenderGroup( iIndex );
  94. }
  95. else
  96. {
  97. gHUD.UnlockRenderGroup( iIndex );
  98. }
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Purpose:
  102. //-----------------------------------------------------------------------------
  103. bool CHudInspectPanel::ShouldDraw( void )
  104. {
  105. C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer();
  106. if ( !CHudElement::ShouldDraw() || !pLocalTFPlayer || !pLocalTFPlayer->IsAlive() )
  107. {
  108. m_hTarget = NULL;
  109. SetPanelVisible( false );
  110. return false;
  111. }
  112. return ( m_hTarget != NULL );
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose:
  116. //-----------------------------------------------------------------------------
  117. void CHudInspectPanel::UserCmd_InspectTarget( void )
  118. {
  119. // If we're in observer mode, we cycle items on the current observer target
  120. C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer();
  121. if ( !pLocalTFPlayer )
  122. return;
  123. C_TFPlayer *pTargetPlayer = GetInspectTarget( pLocalTFPlayer );
  124. bool bVisible = false;
  125. if ( pLocalTFPlayer->IsObserver() )
  126. {
  127. CTFSpectatorGUI *pPanel = (CTFSpectatorGUI*)gViewPortInterface->FindPanelByName( PANEL_SPECGUI );
  128. if ( pPanel )
  129. {
  130. pPanel->ForceItemPanelCycle();
  131. }
  132. }
  133. // In MvM, display player upgrades
  134. else if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
  135. {
  136. CHudUpgradePanel *pUpgradePanel = GET_HUDELEMENT( CHudUpgradePanel );
  137. if ( pUpgradePanel )
  138. {
  139. // Close if open
  140. if ( pUpgradePanel->IsVisible() )
  141. {
  142. pUpgradePanel->OnCommand( "cancel" );
  143. }
  144. // Inspect a player
  145. else if ( pTargetPlayer && ( pTargetPlayer->GetTeamNumber() != TF_TEAM_PVE_INVADERS ) )
  146. {
  147. pUpgradePanel->InspectUpgradesForPlayer( pTargetPlayer );
  148. }
  149. // Inspect self
  150. else if ( !pTargetPlayer && pLocalTFPlayer )
  151. {
  152. pUpgradePanel->InspectUpgradesForPlayer( pLocalTFPlayer );
  153. }
  154. }
  155. }
  156. else
  157. {
  158. if ( pTargetPlayer && !pTargetPlayer->IsEnemyPlayer() )
  159. {
  160. m_hTarget = pTargetPlayer;
  161. CEconItemView *pItem = m_hTarget->GetInspectItem( &m_iTargetItemIterator );
  162. if ( pItem && pItem->IsValid() )
  163. {
  164. m_pItemPanel->SetDialogVariable( "killername", g_PR->GetPlayerName( m_hTarget->entindex() ) );
  165. m_pItemPanel->SetItem( pItem );
  166. // force update description to get the correct panel size
  167. m_pItemPanel->UpdateDescription();
  168. bVisible = true;
  169. int x,y;
  170. GetPos( x, y );
  171. SetPos( x, ScreenHeight() - YRES( 12 ) - m_pItemPanel->GetTall() );
  172. }
  173. }
  174. else
  175. {
  176. m_iTargetItemIterator = 0;
  177. }
  178. }
  179. SetPanelVisible( bVisible );
  180. }
  181. //-----------------------------------------------------------------------------
  182. // Purpose:
  183. //-----------------------------------------------------------------------------
  184. C_TFPlayer *CHudInspectPanel::GetInspectTarget( C_TFPlayer *pLocalTFPlayer )
  185. {
  186. if ( !pLocalTFPlayer )
  187. return NULL;
  188. C_TFPlayer *pTargetPlayer = NULL;
  189. trace_t tr;
  190. Vector vecStart, vecEnd;
  191. VectorMA( MainViewOrigin(), MAX_TRACE_LENGTH, MainViewForward(), vecEnd );
  192. VectorMA( MainViewOrigin(), 10, MainViewForward(), vecStart );
  193. UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, pLocalTFPlayer, COLLISION_GROUP_NONE, &tr );
  194. if ( !tr.startsolid && tr.DidHitNonWorldEntity() )
  195. {
  196. C_BaseEntity *pEntity = tr.m_pEnt;
  197. if ( pEntity && ( pEntity != pLocalTFPlayer ) && pEntity->IsPlayer() )
  198. {
  199. // Get the player under our crosshair
  200. pTargetPlayer = ToTFPlayer( pEntity );
  201. // Fix up if it's a spy disguised as my team
  202. if ( pLocalTFPlayer->m_Shared.IsSpyDisguisedAsMyTeam( pTargetPlayer ) )
  203. {
  204. // Get the player that the spy is disguised as
  205. C_TFPlayer *pDisguiseTarget = ToTFPlayer( pTargetPlayer->m_Shared.GetDisguiseTarget().Get() );
  206. if ( pDisguiseTarget && pDisguiseTarget->GetPlayerClass()->GetClassIndex() == pTargetPlayer->m_Shared.GetDisguiseClass() )
  207. {
  208. // The spy is disguised as the same class as the target, so inspect the disguise target instead
  209. pTargetPlayer = pDisguiseTarget;
  210. }
  211. }
  212. }
  213. }
  214. return pTargetPlayer;
  215. }
  216. //-----------------------------------------------------------------------------
  217. // Purpose:
  218. //-----------------------------------------------------------------------------
  219. void CHudInspectPanel::SetPanelVisible( bool bVisible )
  220. {
  221. if ( m_pItemPanel->IsVisible() != bVisible )
  222. {
  223. LockInspectRenderGroup( bVisible );
  224. m_pItemPanel->SetVisible( bVisible );
  225. }
  226. }
  227. //-----------------------------------------------------------------------------
  228. // Purpose:
  229. //-----------------------------------------------------------------------------
  230. int CHudInspectPanel::HudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
  231. {
  232. if ( IsVisible() && pszCurrentBinding && pszCurrentBinding[0] )
  233. {
  234. if ( FStrEq( pszCurrentBinding, "+attack" ) )
  235. {
  236. CBasePlayer *pLocalPlayer = CBasePlayer::GetLocalPlayer();
  237. if ( pLocalPlayer && ( pLocalPlayer->GetTeamNumber() >= FIRST_GAME_TEAM ) && pLocalPlayer->IsAlive() )
  238. {
  239. SetPanelVisible( false );
  240. }
  241. }
  242. }
  243. return 1; // intentionally not handling the key
  244. }