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.

397 lines
9.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "hud.h"
  8. #include "hudelement.h"
  9. #include "hud_macros.h"
  10. #include "iclientmode.h"
  11. #include "vgui_controls/AnimationController.h"
  12. #include "vgui_controls/Label.h"
  13. #include "vgui/ILocalize.h"
  14. #include "vgui/ISurface.h"
  15. #include "text_message.h"
  16. #include "dod_hud_freezepanel.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. //-----------------------------------------------------------------------------
  20. // Purpose: Displays current ammunition level
  21. //-----------------------------------------------------------------------------
  22. class CDODHudHintDisplay : public vgui::Panel, public CHudElement
  23. {
  24. DECLARE_CLASS_SIMPLE( CDODHudHintDisplay, vgui::Panel );
  25. public:
  26. CDODHudHintDisplay( const char *pElementName );
  27. void Init();
  28. void Reset();
  29. void MsgFunc_HintText( bf_read &msg );
  30. void FireGameEvent( IGameEvent * event);
  31. bool SetHintText( wchar_t *text );
  32. virtual void PerformLayout();
  33. virtual bool IsVisible( void );
  34. protected:
  35. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  36. virtual void OnThink();
  37. private:
  38. vgui::HFont m_hFont;
  39. Color m_bgColor;
  40. vgui::Label *m_pLabel;
  41. CUtlVector<vgui::Label *> m_Labels;
  42. CPanelAnimationVarAliasType( int, m_iTextX, "text_xpos", "8", "proportional_int" );
  43. CPanelAnimationVarAliasType( int, m_iTextY, "text_ypos", "8", "proportional_int" );
  44. CPanelAnimationVarAliasType( int, m_iCenterX, "center_x", "0", "proportional_int" );
  45. CPanelAnimationVarAliasType( int, m_iCenterY, "center_y", "0", "proportional_int" );
  46. };
  47. DECLARE_HUDELEMENT( CDODHudHintDisplay );
  48. DECLARE_HUD_MESSAGE( CDODHudHintDisplay, HintText );
  49. #define MAX_HINT_STRINGS 5
  50. //-----------------------------------------------------------------------------
  51. // Purpose: Constructor
  52. //-----------------------------------------------------------------------------
  53. CDODHudHintDisplay::CDODHudHintDisplay( const char *pElementName ) : BaseClass(NULL, "HudHintDisplay"), CHudElement( pElementName )
  54. {
  55. vgui::Panel *pParent = g_pClientMode->GetViewport();
  56. SetParent( pParent );
  57. SetVisible( false );
  58. SetAlpha( 0 );
  59. m_pLabel = new vgui::Label( this, "HudHintDisplayLabel", "" );
  60. RegisterForRenderGroup( "winpanel" );
  61. RegisterForRenderGroup( "freezepanel" );
  62. }
  63. //-----------------------------------------------------------------------------
  64. // Purpose:
  65. //-----------------------------------------------------------------------------
  66. void CDODHudHintDisplay::Init()
  67. {
  68. HOOK_HUD_MESSAGE( CDODHudHintDisplay, HintText );
  69. // listen for client side events
  70. ListenForGameEvent( "player_hintmessage" );
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose:
  74. //-----------------------------------------------------------------------------
  75. void CDODHudHintDisplay::Reset()
  76. {
  77. SetHintText( NULL );
  78. SetAlpha( 0 );
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. //-----------------------------------------------------------------------------
  83. void CDODHudHintDisplay::ApplySchemeSettings( vgui::IScheme *pScheme )
  84. {
  85. BaseClass::ApplySchemeSettings( pScheme );
  86. SetFgColor( GetSchemeColor("HintMessageFg", pScheme) );
  87. m_hFont = pScheme->GetFont( "HudHintText", true );
  88. m_pLabel->SetBgColor( GetSchemeColor("HintMessageBg", pScheme) );
  89. m_pLabel->SetPaintBackgroundType( 2 );
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose: Sets the hint text, replacing variables as necessary
  93. //-----------------------------------------------------------------------------
  94. bool CDODHudHintDisplay::SetHintText( wchar_t *text )
  95. {
  96. // clear the existing text
  97. for (int i = 0; i < m_Labels.Count(); i++)
  98. {
  99. m_Labels[i]->MarkForDeletion();
  100. }
  101. m_Labels.RemoveAll();
  102. wchar_t *p = text;
  103. while ( p )
  104. {
  105. wchar_t *line = p;
  106. wchar_t *end = wcschr( p, L'\n' );
  107. if ( end )
  108. {
  109. //*end = 0; //eek
  110. p = end+1;
  111. }
  112. else
  113. {
  114. p = NULL;
  115. }
  116. // copy to a new buf if there are vars
  117. wchar_t buf[512];
  118. buf[0] = '\0';
  119. int pos = 0;
  120. wchar_t *ws = line;
  121. while( ws != end && *ws != 0 )
  122. {
  123. // check for variables
  124. if ( *ws == '%' )
  125. {
  126. ++ws;
  127. wchar_t *end = wcschr( ws, '%' );
  128. if ( end )
  129. {
  130. wchar_t token[64];
  131. wcsncpy( token, ws, end - ws );
  132. token[end - ws] = 0;
  133. ws += end - ws;
  134. // lookup key names
  135. char binding[64];
  136. g_pVGuiLocalize->ConvertUnicodeToANSI( token, binding, sizeof(binding) );
  137. const char *key = engine->Key_LookupBinding( *binding == '+' ? binding + 1 : binding );
  138. if ( !key )
  139. {
  140. key = "< not bound >";
  141. }
  142. //!! change some key names into better names
  143. char friendlyName[64];
  144. Q_snprintf( friendlyName, sizeof(friendlyName), "%s", key );
  145. Q_strupr( friendlyName );
  146. g_pVGuiLocalize->ConvertANSIToUnicode( friendlyName, token, sizeof(token) );
  147. buf[pos] = '\0';
  148. wcscat( buf, token );
  149. pos += wcslen(token);
  150. }
  151. else
  152. {
  153. buf[pos] = *ws;
  154. ++pos;
  155. }
  156. }
  157. else
  158. {
  159. buf[pos] = *ws;
  160. ++pos;
  161. }
  162. ++ws;
  163. }
  164. buf[pos] = '\0';
  165. // put it in a label
  166. //vgui::Label *label = vgui::SETUP_PANEL(new vgui::Label(this, NULL, line));
  167. vgui::Label *label = vgui::SETUP_PANEL(new vgui::Label(this, NULL, buf));
  168. label->SetFont( m_hFont );
  169. label->SetPaintBackgroundEnabled( false );
  170. label->SetPaintBorderEnabled( false );
  171. label->SizeToContents();
  172. label->SetContentAlignment( vgui::Label::a_west );
  173. label->SetFgColor( GetFgColor() );
  174. m_Labels.AddToTail( vgui::SETUP_PANEL(label) );
  175. }
  176. InvalidateLayout( true );
  177. return true;
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Purpose: Resizes the label
  181. //-----------------------------------------------------------------------------
  182. void CDODHudHintDisplay::PerformLayout()
  183. {
  184. BaseClass::PerformLayout();
  185. int i;
  186. int wide, tall;
  187. GetSize( wide, tall );
  188. // find the widest line
  189. int labelWide = 0;
  190. for ( i=0; i<m_Labels.Count(); ++i )
  191. {
  192. labelWide = MAX( labelWide, m_Labels[i]->GetWide() );
  193. }
  194. // find the total height
  195. int fontTall = vgui::surface()->GetFontTall( m_hFont );
  196. int labelTall = fontTall * m_Labels.Count();
  197. labelWide += m_iTextX*2;
  198. labelTall += m_iTextY*2;
  199. int x, y;
  200. if ( m_iCenterX < 0 )
  201. {
  202. x = 0;
  203. }
  204. else if ( m_iCenterX > 0 )
  205. {
  206. x = wide - labelWide;
  207. }
  208. else
  209. {
  210. x = (wide - labelWide) / 2;
  211. }
  212. if ( m_iCenterY > 0 )
  213. {
  214. y = 0;
  215. }
  216. else if ( m_iCenterY < 0 )
  217. {
  218. y = tall - labelTall;
  219. }
  220. else
  221. {
  222. y = (tall - labelTall) / 2;
  223. }
  224. m_pLabel->SetBounds( x, y, labelWide, labelTall );
  225. // now lay out the sub-labels
  226. for ( i=0; i<m_Labels.Count(); ++i )
  227. {
  228. int xOffset = (labelWide - m_Labels[i]->GetWide())/2;
  229. m_Labels[i]->SetPos( x + xOffset, y + m_iTextY + i*fontTall );
  230. }
  231. }
  232. //-----------------------------------------------------------------------------
  233. // Purpose: Updates the label color each frame
  234. //-----------------------------------------------------------------------------
  235. void CDODHudHintDisplay::OnThink()
  236. {
  237. m_pLabel->SetFgColor(GetFgColor());
  238. for (int i = 0; i < m_Labels.Count(); i++)
  239. {
  240. m_Labels[i]->SetFgColor(GetFgColor());
  241. }
  242. }
  243. //-----------------------------------------------------------------------------
  244. // Purpose: Activates the hint display
  245. //-----------------------------------------------------------------------------
  246. void CDODHudHintDisplay::MsgFunc_HintText( bf_read &msg )
  247. {
  248. // read the string(s)
  249. char szString[255];
  250. static wchar_t szBuf[128];
  251. static wchar_t *pszBuf;
  252. // init buffers & pointers
  253. szBuf[0] = 0;
  254. pszBuf = szBuf;
  255. // read string and localize it
  256. msg.ReadString( szString, sizeof(szString) );
  257. char *tmpStr = hudtextmessage->LookupString( szString, NULL );
  258. // try to localize
  259. if ( tmpStr )
  260. {
  261. pszBuf = g_pVGuiLocalize->Find( tmpStr );
  262. }
  263. else
  264. {
  265. pszBuf = g_pVGuiLocalize->Find( szString );
  266. }
  267. if ( !pszBuf )
  268. {
  269. // use plain ASCII string
  270. g_pVGuiLocalize->ConvertANSIToUnicode( szString, szBuf, sizeof(szBuf) );
  271. pszBuf = szBuf;
  272. }
  273. // make it visible
  274. if ( SetHintText( pszBuf ) )
  275. {
  276. SetVisible( true );
  277. //SetAlpha( 255 );
  278. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageShow" );
  279. }
  280. else
  281. {
  282. // it's being cleared, hide the panel
  283. //SetAlpha( 0 );
  284. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageHide" );
  285. }
  286. }
  287. //-----------------------------------------------------------------------------
  288. // Purpose: Activates the hint display upon recieving a hint
  289. //-----------------------------------------------------------------------------
  290. void CDODHudHintDisplay::FireGameEvent( IGameEvent * event)
  291. {
  292. // we sometimes hide the element when it's covered, don't start
  293. // a hint during that time
  294. if ( !ShouldDraw() )
  295. return;
  296. static wchar_t *pszBuf;
  297. static wchar_t szBuf[128];
  298. const char *hintmessage = event->GetString( "hintmessage" );
  299. char *tmpStr = hudtextmessage->LookupString( hintmessage, NULL );
  300. // try to localize
  301. if ( tmpStr )
  302. {
  303. pszBuf = g_pVGuiLocalize->Find( tmpStr );
  304. }
  305. else
  306. {
  307. pszBuf = g_pVGuiLocalize->Find( hintmessage );
  308. }
  309. if ( !pszBuf )
  310. {
  311. // its not in titles.txt or dod_english.txt, just print the text of it
  312. // use plain ASCII string
  313. g_pVGuiLocalize->ConvertANSIToUnicode( hintmessage, szBuf, sizeof(szBuf) );
  314. pszBuf = szBuf;
  315. }
  316. // make it visible
  317. if ( SetHintText( pszBuf ) )
  318. {
  319. SetVisible( true );
  320. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageShow" );
  321. }
  322. else
  323. {
  324. // it's being cleared, hide the panel
  325. g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageHide" );
  326. }
  327. }
  328. bool CDODHudHintDisplay::IsVisible( void )
  329. {
  330. if ( IsTakingAFreezecamScreenshot() )
  331. return false;
  332. if ( !ShouldDraw() )
  333. return false;
  334. return BaseClass::IsVisible();
  335. }