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.

347 lines
11 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "cs_hud_freezepanel.h"
  9. #include <vgui/IVGui.h>
  10. #include "vgui_controls/AnimationController.h"
  11. #include "iclientmode.h"
  12. #include "c_cs_player.h"
  13. #include "c_cs_playerresource.h"
  14. #include <vgui_controls/Label.h>
  15. #include <vgui/ILocalize.h>
  16. #include <vgui/ISurface.h>
  17. #include "VGUI/bordered_panel.h"
  18. #include "fmtstr.h"
  19. #include "cs_gamerules.h"
  20. #include "view.h"
  21. #include "ivieweffects.h"
  22. #include "viewrender.h"
  23. #include "usermessages.h"
  24. #include "hud_macros.h"
  25. #include "c_baseanimating.h"
  26. #include "backgroundpanel.h" // rounded border support
  27. // memdbgon must be the last include file in a .cpp file!!!
  28. #include "tier0/memdbgon.h"
  29. DECLARE_HUDELEMENT_DEPTH( CCSFreezePanel, 1 );
  30. // DECLARE_HUD_MESSAGE( CCSFreezePanel, Damage );
  31. // DECLARE_HUD_MESSAGE( CCSFreezePanel, DroppedEquipment );
  32. #define CALLOUT_WIDE (XRES(100))
  33. #define CALLOUT_TALL (XRES(50))
  34. ConVar cl_disablefreezecam(
  35. "cl_disablefreezecam",
  36. "0",
  37. FCVAR_ARCHIVE,
  38. "Turn on/off freezecam on client"
  39. );
  40. Color LerpColors( Color cStart, Color cEnd, float flPercent )
  41. {
  42. float r = (float)((float)(cStart.r()) + (float)(cEnd.r() - cStart.r()) * flPercent);
  43. float g = (float)((float)(cStart.g()) + (float)(cEnd.g() - cStart.g()) * flPercent);
  44. float b = (float)((float)(cStart.b()) + (float)(cEnd.b() - cStart.b()) * flPercent);
  45. float a = (float)((float)(cStart.a()) + (float)(cEnd.a() - cStart.a()) * flPercent);
  46. return Color( r, g, b, a );
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose: Clips the health image to the appropriate percentage
  50. //-----------------------------------------------------------------------------
  51. class HorizontalGauge : public vgui::Panel
  52. {
  53. public:
  54. DECLARE_CLASS_SIMPLE( HorizontalGauge, vgui::Panel );
  55. HorizontalGauge( Panel *parent, const char *name ) :
  56. vgui::Panel( parent, name ),
  57. m_fPercent(0.0f)
  58. {
  59. }
  60. /*
  61. void ApplySettings(KeyValues *inResourceData)
  62. {
  63. BaseClass::ApplySettings(inResourceData);
  64. Color color0 = inResourceData->GetColor( "color0");
  65. Color color1 = inResourceData->GetColor( "color1");
  66. }
  67. */
  68. void PaintBackground()
  69. {
  70. int wide, tall;
  71. GetSize(wide, tall);
  72. surface()->DrawSetColor( Color(0, 0, 0, 128) );
  73. surface()->DrawFilledRect(0, 0, wide, tall);
  74. // do the border explicitly here
  75. surface()->DrawSetColor( Color(0,0,0,255));
  76. surface()->DrawOutlinedRect(0, 0, wide, tall);
  77. }
  78. virtual void Paint()
  79. {
  80. int wide, tall;
  81. GetSize(wide, tall);
  82. Color lowHealth(192, 32, 32, 255);
  83. Color highHealth(32, 255, 32, 255);
  84. surface()->DrawSetColor( LerpColors(lowHealth, highHealth, m_fPercent) );
  85. surface()->DrawFilledRect(1, 1, (int)((wide - 1) * m_fPercent), tall - 1);
  86. }
  87. void SetPercent( float fPercent ) { m_fPercent = fPercent; }
  88. private:
  89. float m_fPercent;
  90. };
  91. DECLARE_BUILD_FACTORY( HorizontalGauge );
  92. //-----------------------------------------------------------------------------
  93. // Purpose: Constructor
  94. //-----------------------------------------------------------------------------
  95. CCSFreezePanel::CCSFreezePanel( const char *pElementName ) :
  96. EditablePanel( NULL, "FreezePanel" ),
  97. CHudElement( pElementName ),
  98. m_pBackgroundPanel(NULL),
  99. m_pKillerHealth(NULL),
  100. m_pAvatar(NULL),
  101. m_pDominationIcon(NULL)
  102. {
  103. SetSize( 10, 10 ); // Quiet "parent not sized yet" spew
  104. SetParent(g_pClientMode->GetViewport());
  105. m_bShouldBeVisible = false;
  106. SetScheme( "ClientScheme" );
  107. RegisterForRenderGroup( "hide_for_scoreboard" );
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Purpose:
  111. //-----------------------------------------------------------------------------
  112. void CCSFreezePanel::Reset()
  113. {
  114. Hide();
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose:
  118. //-----------------------------------------------------------------------------
  119. void CCSFreezePanel::Init()
  120. {
  121. CHudElement::Init();
  122. // listen for events
  123. ListenForGameEvent( "show_freezepanel" );
  124. ListenForGameEvent( "hide_freezepanel" );
  125. ListenForGameEvent( "freezecam_started" );
  126. ListenForGameEvent( "player_death" );
  127. Hide();
  128. InitLayout();
  129. }
  130. void CCSFreezePanel::InitLayout()
  131. {
  132. LoadControlSettings( "resource/UI/FreezePanel_Basic.res" );
  133. m_pBackgroundPanel = dynamic_cast<BorderedPanel*>( FindChildByName("FreezePanelBG"));
  134. m_pAvatar = dynamic_cast<CAvatarImagePanel*>( m_pBackgroundPanel->FindChildByName("AvatarImage"));
  135. m_pKillerHealth = dynamic_cast<HorizontalGauge*>( m_pBackgroundPanel->FindChildByName("KillerHealth"));
  136. m_pDominationIcon = dynamic_cast<ImagePanel*>( m_pBackgroundPanel->FindChildByName("DominationIcon"));
  137. m_pAvatar->SetDefaultAvatar(scheme()->GetImage( CSTRIKE_DEFAULT_AVATAR, true ));
  138. m_pAvatar->SetShouldScaleImage(true);
  139. m_pAvatar->SetShouldDrawFriendIcon(false);
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Purpose: Applies scheme settings
  143. //-----------------------------------------------------------------------------
  144. void CCSFreezePanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  145. {
  146. BaseClass::ApplySchemeSettings( pScheme );
  147. }
  148. //-----------------------------------------------------------------------------
  149. // Purpose:
  150. //-----------------------------------------------------------------------------
  151. void CCSFreezePanel::FireGameEvent( IGameEvent * event )
  152. {
  153. const char *pEventName = event->GetName();
  154. if ( Q_strcmp( "player_death", pEventName ) == 0 )
  155. {
  156. // see if the local player died
  157. int iPlayerIndexVictim = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
  158. int iPlayerIndexKiller = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
  159. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  160. CCSPlayer* pKiller = ToCSPlayer(ClientEntityList().GetBaseEntity(iPlayerIndexKiller));
  161. if ( pLocalPlayer && iPlayerIndexVictim == pLocalPlayer->entindex() )
  162. {
  163. // the local player is dead, see if this is a new nemesis or a revenge
  164. if ( event->GetInt( "dominated" ) > 0)
  165. {
  166. m_pDominationIcon->SetImage("../hud/freeze_nemesis");
  167. m_pDominationIcon->SetVisible(true);
  168. m_pBackgroundPanel->SetDialogVariable( "InfoLabel1", g_pVGuiLocalize->Find("#FreezePanel_NewNemesis1"));
  169. m_pBackgroundPanel->SetDialogVariable( "InfoLabel2", g_pVGuiLocalize->Find("#FreezePanel_NewNemesis2"));
  170. }
  171. // was the killer your pre-existing nemesis?
  172. else if ( pKiller != NULL && pKiller->IsPlayerDominated(iPlayerIndexVictim) )
  173. {
  174. m_pDominationIcon->SetImage("../hud/freeze_nemesis");
  175. m_pDominationIcon->SetVisible(true);
  176. m_pBackgroundPanel->SetDialogVariable( "InfoLabel1", g_pVGuiLocalize->Find("#FreezePanel_OldNemesis1"));
  177. m_pBackgroundPanel->SetDialogVariable( "InfoLabel2", g_pVGuiLocalize->Find("#FreezePanel_OldNemesis2"));
  178. }
  179. else if ( event->GetInt( "revenge" ) > 0 )
  180. {
  181. m_pDominationIcon->SetImage("../hud/freeze_revenge");
  182. m_pDominationIcon->SetVisible(true);
  183. m_pBackgroundPanel->SetDialogVariable( "InfoLabel1", g_pVGuiLocalize->Find("#FreezePanel_Revenge1"));
  184. m_pBackgroundPanel->SetDialogVariable( "InfoLabel2", g_pVGuiLocalize->Find("#FreezePanel_Revenge2"));
  185. }
  186. else
  187. {
  188. m_pDominationIcon->SetVisible(false);
  189. m_pBackgroundPanel->SetDialogVariable( "InfoLabel1", g_pVGuiLocalize->Find("#FreezePanel_Killer1"));
  190. m_pBackgroundPanel->SetDialogVariable( "InfoLabel2", g_pVGuiLocalize->Find("#FreezePanel_Killer2"));
  191. }
  192. }
  193. }
  194. else if ( Q_strcmp( "hide_freezepanel", pEventName ) == 0 )
  195. {
  196. Hide();
  197. }
  198. else if ( Q_strcmp( "freezecam_started", pEventName ) == 0 )
  199. {
  200. }
  201. else if ( Q_strcmp( "show_freezepanel", pEventName ) == 0 )
  202. {
  203. C_CS_PlayerResource *cs_PR = dynamic_cast<C_CS_PlayerResource *>( g_PR );
  204. if ( !cs_PR )
  205. return;
  206. Show();
  207. // Get the entity who killed us
  208. int iKillerIndex = event->GetInt( "killer" );
  209. CCSPlayer* pKiller = ToCSPlayer(ClientEntityList().GetBaseEntity(iKillerIndex));
  210. m_pAvatar->ClearAvatar();
  211. if ( pKiller )
  212. {
  213. int iMaxHealth = pKiller->GetMaxHealth();
  214. int iKillerHealth = pKiller->GetHealth();
  215. if ( !pKiller->IsAlive() )
  216. {
  217. iKillerHealth = 0;
  218. }
  219. m_pKillerHealth->SetPercent( (float)iKillerHealth / iMaxHealth );
  220. char killerName[128];
  221. V_snprintf( killerName, sizeof(killerName), "%s", g_PR->GetPlayerName(iKillerIndex) );
  222. // V_strupr( killerName );
  223. m_pBackgroundPanel->SetDialogVariable( "killername", killerName);
  224. int iKillerIndex = pKiller->entindex();
  225. player_info_t pi;
  226. m_pAvatar->SetDefaultAvatar( GetDefaultAvatarImage( pKiller ) );
  227. if ( engine->GetPlayerInfo(iKillerIndex, &pi) )
  228. {
  229. m_pAvatar->SetPlayer( (C_BasePlayer*)pKiller, k_EAvatarSize64x64);
  230. m_pAvatar->SetVisible(true);
  231. }
  232. }
  233. }
  234. }
  235. //-----------------------------------------------------------------------------
  236. // Purpose:
  237. //-----------------------------------------------------------------------------
  238. bool CCSFreezePanel::ShouldDraw( void )
  239. {
  240. //=============================================================================
  241. // HPE_BEGIN:
  242. // [Forrest] Added sv_disablefreezecam check
  243. //=============================================================================
  244. static ConVarRef sv_disablefreezecam( "sv_disablefreezecam" );
  245. return ( m_bShouldBeVisible && !cl_disablefreezecam.GetBool() && !sv_disablefreezecam.GetBool() && CHudElement::ShouldDraw() );
  246. //=============================================================================
  247. // HPE_END
  248. //=============================================================================
  249. }
  250. void CCSFreezePanel::OnScreenSizeChanged( int nOldWide, int nOldTall )
  251. {
  252. BaseClass::OnScreenSizeChanged(nOldWide, nOldTall);
  253. InitLayout();
  254. }
  255. void CCSFreezePanel::SetActive( bool bActive )
  256. {
  257. CHudElement::SetActive( bActive );
  258. if ( bActive )
  259. {
  260. // Setup replay key binding in UI
  261. const char *pKey = engine->Key_LookupBinding( "save_replay" );
  262. if ( pKey == NULL || FStrEq( pKey, "(null)" ) )
  263. {
  264. pKey = "<NOT BOUND>";
  265. }
  266. char szKey[16];
  267. Q_snprintf( szKey, sizeof(szKey), "%s", pKey );
  268. wchar_t wKey[16];
  269. wchar_t wLabel[256];
  270. g_pVGuiLocalize->ConvertANSIToUnicode( szKey, wKey, sizeof( wKey ) );
  271. g_pVGuiLocalize->ConstructString( wLabel, sizeof( wLabel ), g_pVGuiLocalize->Find("#FreezePanel_SaveReplay" ), 1, wKey );
  272. m_pBackgroundPanel->SetDialogVariable( "savereplay", wLabel );
  273. }
  274. }
  275. //-----------------------------------------------------------------------------
  276. // Purpose:
  277. //-----------------------------------------------------------------------------
  278. void CCSFreezePanel::Show()
  279. {
  280. m_bShouldBeVisible = true;
  281. }
  282. //-----------------------------------------------------------------------------
  283. // Purpose:
  284. //-----------------------------------------------------------------------------
  285. void CCSFreezePanel::Hide()
  286. {
  287. m_bShouldBeVisible = false;
  288. }