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.

354 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hud_radar.h"
  8. #include "cs_hud_chat.h"
  9. #include "c_cs_player.h"
  10. #include "c_cs_playerresource.h"
  11. #include "hud_macros.h"
  12. #include "text_message.h"
  13. #include "vguicenterprint.h"
  14. #include "vgui/ILocalize.h"
  15. #include "engine/IEngineSound.h"
  16. #include "radio_status.h"
  17. #include "cstrike/bot/shared_util.h"
  18. #include "ihudlcd.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. DECLARE_HUDELEMENT( CHudChat );
  22. DECLARE_HUD_MESSAGE( CHudChat, RadioText );
  23. DECLARE_HUD_MESSAGE( CHudChat, SayText );
  24. DECLARE_HUD_MESSAGE( CHudChat, SayText2 );
  25. DECLARE_HUD_MESSAGE( CHudChat, TextMsg );
  26. DECLARE_HUD_MESSAGE( CHudChat, RawAudio );
  27. //=====================
  28. //CHudChatLine
  29. //=====================
  30. CHudChatLine::CHudChatLine( vgui::Panel *parent, const char *panelName ) : CBaseHudChatLine( parent, panelName )
  31. {
  32. m_text = NULL;
  33. }
  34. void CHudChatLine::ApplySchemeSettings(vgui::IScheme *pScheme)
  35. {
  36. BaseClass::ApplySchemeSettings( pScheme );
  37. }
  38. //=====================
  39. //CHudChatInputLine
  40. //=====================
  41. void CHudChatInputLine::ApplySchemeSettings(vgui::IScheme *pScheme)
  42. {
  43. BaseClass::ApplySchemeSettings(pScheme);
  44. vgui::HFont hFont = pScheme->GetFont( "ChatFont" );
  45. m_pPrompt->SetFont( hFont );
  46. m_pInput->SetFont( hFont );
  47. m_pInput->SetFgColor( pScheme->GetColor( "Chat.TypingText", pScheme->GetColor( "Panel.FgColor", Color( 255, 255, 255, 255 ) ) ) );
  48. }
  49. //=====================
  50. //CHudChat
  51. //=====================
  52. CHudChat::CHudChat( const char *pElementName ) : BaseClass( pElementName )
  53. {
  54. //=============================================================================
  55. // HPE_BEGIN:
  56. // [tj] Add this to the render group that disappears when the scoreboard is up
  57. //
  58. // [pmf] Removed from render group so that chat still works during intermission
  59. // (when the scoreboard is forced to be up). The downside is that chat shows
  60. // over the scoreboard during regular play, but this might be less of an issue
  61. // if we reduce the need to display it constantly by adding HUD support for
  62. // live player counts.
  63. //=============================================================================
  64. // RegisterForRenderGroup("hide_for_scoreboard");
  65. //=============================================================================
  66. // HPE_END
  67. //=============================================================================
  68. }
  69. void CHudChat::CreateChatInputLine( void )
  70. {
  71. m_pChatInput = new CHudChatInputLine( this, "ChatInputLine" );
  72. m_pChatInput->SetVisible( false );
  73. }
  74. void CHudChat::CreateChatLines( void )
  75. {
  76. #ifndef _XBOX
  77. m_ChatLine = new CHudChatLine( this, "ChatLine1" );
  78. m_ChatLine->SetVisible( false );
  79. #endif
  80. }
  81. void CHudChat::Init( void )
  82. {
  83. BaseClass::Init();
  84. HOOK_HUD_MESSAGE( CHudChat, RadioText );
  85. HOOK_HUD_MESSAGE( CHudChat, SayText );
  86. HOOK_HUD_MESSAGE( CHudChat, SayText2 );
  87. HOOK_HUD_MESSAGE( CHudChat, TextMsg );
  88. HOOK_HUD_MESSAGE( CHudChat, RawAudio );
  89. }
  90. //-----------------------------------------------------------------------------
  91. // Purpose: Overrides base reset to not cancel chat at round restart
  92. //-----------------------------------------------------------------------------
  93. void CHudChat::Reset( void )
  94. {
  95. }
  96. //-----------------------------------------------------------------------------
  97. // Purpose: Reads in a player's Radio text from the server
  98. //-----------------------------------------------------------------------------
  99. void CHudChat::MsgFunc_RadioText( bf_read &msg )
  100. {
  101. int msg_dest = msg.ReadByte();
  102. NOTE_UNUSED( msg_dest );
  103. int client = msg.ReadByte();
  104. wchar_t szBuf[6][128];
  105. wchar_t *msg_text = ReadLocalizedString( msg, szBuf[0], sizeof( szBuf[0] ), false );
  106. // keep reading strings and using C format strings for subsituting the strings into the localised text string
  107. ReadChatTextString ( msg, szBuf[1], sizeof( szBuf[1] ) ); // player name
  108. ReadLocalizedString( msg, szBuf[2], sizeof( szBuf[2] ), true ); // location
  109. ReadLocalizedString( msg, szBuf[3], sizeof( szBuf[3] ), true ); // radio text
  110. ReadLocalizedString( msg, szBuf[4], sizeof( szBuf[4] ), true ); // unused :(
  111. g_pVGuiLocalize->ConstructString( szBuf[5], sizeof( szBuf[5] ), msg_text, 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
  112. char ansiString[512];
  113. g_pVGuiLocalize->ConvertUnicodeToANSI( ConvertCRtoNL( szBuf[5] ), ansiString, sizeof( ansiString ) );
  114. ChatPrintf( client, CHAT_FILTER_TEAMCHANGE, "%s", ansiString );
  115. CLocalPlayerFilter filter;
  116. C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HudChat.Message" );
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Purpose: Reads in a player's Chat text from the server
  120. //-----------------------------------------------------------------------------
  121. void CHudChat::MsgFunc_SayText2( bf_read &msg )
  122. {
  123. // Got message during connection
  124. if ( !g_PR )
  125. return;
  126. int client = msg.ReadByte();
  127. bool bWantsToChat = msg.ReadByte();
  128. wchar_t szBuf[6][256];
  129. char untranslated_msg_text[256];
  130. wchar_t *msg_text = ReadLocalizedString( msg, szBuf[0], sizeof( szBuf[0] ), false, untranslated_msg_text, sizeof( untranslated_msg_text ) );
  131. // keep reading strings and using C format strings for subsituting the strings into the localised text string
  132. ReadChatTextString ( msg, szBuf[1], sizeof( szBuf[1] ) ); // player name
  133. ReadChatTextString ( msg, szBuf[2], sizeof( szBuf[2] ) ); // chat text
  134. ReadLocalizedString( msg, szBuf[3], sizeof( szBuf[3] ), true ); // location
  135. ReadLocalizedString( msg, szBuf[4], sizeof( szBuf[4] ), true ); // unused :(
  136. g_pVGuiLocalize->ConstructString( szBuf[5], sizeof( szBuf[5] ), msg_text, 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
  137. char ansiString[512];
  138. g_pVGuiLocalize->ConvertUnicodeToANSI( ConvertCRtoNL( szBuf[5] ), ansiString, sizeof( ansiString ) );
  139. // flash speaking player dot
  140. if ( client > 0 )
  141. Radar_FlashPlayer( client );
  142. if ( bWantsToChat )
  143. {
  144. int iFilter = CHAT_FILTER_NONE;
  145. bool playChatSound = true;
  146. if ( client > 0 && (g_PR->GetTeam( client ) != g_PR->GetTeam( GetLocalPlayerIndex() )) )
  147. {
  148. iFilter = CHAT_FILTER_PUBLICCHAT;
  149. if ( !( iFilter & GetFilterFlags() ) )
  150. {
  151. playChatSound = false;
  152. }
  153. }
  154. // print raw chat text
  155. ChatPrintf( client, iFilter, "%s", ansiString );
  156. Msg( "%s\n", RemoveColorMarkup(ansiString) );
  157. if ( playChatSound )
  158. {
  159. CLocalPlayerFilter filter;
  160. C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HudChat.Message" );
  161. }
  162. }
  163. else
  164. {
  165. // print raw chat text
  166. ChatPrintf( client, GetFilterForString( untranslated_msg_text), "%s", ansiString );
  167. }
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Purpose:
  171. //-----------------------------------------------------------------------------
  172. int CHudChat::GetChatInputOffset( void )
  173. {
  174. if ( m_pChatInput->IsVisible() )
  175. {
  176. return m_iFontHeight;
  177. }
  178. else
  179. {
  180. return 0;
  181. }
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Purpose: Reads in an Audio message from the server (wav file to be played
  185. // via the player's voice, i.e. for bot chatter)
  186. //-----------------------------------------------------------------------------
  187. void CHudChat::MsgFunc_RawAudio( bf_read &msg )
  188. {
  189. char szString[2048];
  190. int pitch = msg.ReadByte();
  191. int playerIndex = msg.ReadByte();
  192. float feedbackDuration = msg.ReadFloat();
  193. msg.ReadString( szString, sizeof(szString) );
  194. EmitSound_t ep;
  195. ep.m_nChannel = CHAN_VOICE;
  196. ep.m_pSoundName = szString;
  197. ep.m_flVolume = 1.0f;
  198. ep.m_SoundLevel = SNDLVL_NORM;
  199. ep.m_nPitch = pitch;
  200. CLocalPlayerFilter filter;
  201. C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, ep );
  202. if ( feedbackDuration > 0.0f )
  203. {
  204. //Flash them on the radar
  205. C_CSPlayer *pPlayer = static_cast<C_CSPlayer*>( cl_entitylist->GetEnt(playerIndex) );
  206. if ( pPlayer )
  207. {
  208. // Create the flashy above player's head
  209. RadioManager()->UpdateVoiceStatus( playerIndex, feedbackDuration );
  210. }
  211. }
  212. }
  213. //-----------------------------------------------------------------------------
  214. Color CHudChat::GetClientColor( int clientIndex )
  215. {
  216. if ( clientIndex == 0 ) // console msg
  217. {
  218. return g_ColorGreen;
  219. }
  220. else if( g_PR )
  221. {
  222. switch ( g_PR->GetTeam( clientIndex ) )
  223. {
  224. case 2 : return g_ColorRed;
  225. case 3 : return g_ColorBlue;
  226. default : return g_ColorGrey;
  227. }
  228. }
  229. return g_ColorYellow;
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose:
  233. //-----------------------------------------------------------------------------
  234. Color CHudChat::GetTextColorForClient( TextColor colorNum, int clientIndex )
  235. {
  236. Color c;
  237. switch ( colorNum )
  238. {
  239. case COLOR_PLAYERNAME:
  240. c = GetClientColor( clientIndex );
  241. break;
  242. case COLOR_LOCATION:
  243. c = g_ColorDarkGreen;
  244. break;
  245. //=============================================================================
  246. // HPE_BEGIN:
  247. // [tj] Adding support for achievement coloring.
  248. // Just doing what all the other games do
  249. //=============================================================================
  250. case COLOR_ACHIEVEMENT:
  251. {
  252. vgui::IScheme *pSourceScheme = vgui::scheme()->GetIScheme( vgui::scheme()->GetScheme( "SourceScheme" ) );
  253. if ( pSourceScheme )
  254. {
  255. c = pSourceScheme->GetColor( "SteamLightGreen", GetBgColor() );
  256. }
  257. else
  258. {
  259. c = GetDefaultTextColor();
  260. }
  261. }
  262. break;
  263. //=============================================================================
  264. // HPE_END
  265. //=============================================================================
  266. default:
  267. c = g_ColorYellow;
  268. }
  269. return Color( c[0], c[1], c[2], 255 );
  270. }
  271. int CHudChat::GetFilterForString( const char *pString )
  272. {
  273. int iFilter = BaseClass::GetFilterForString( pString );
  274. if ( iFilter == CHAT_FILTER_NONE )
  275. {
  276. if ( !Q_stricmp( pString, "#CStrike_Name_Change" ) )
  277. {
  278. return CHAT_FILTER_NAMECHANGE;
  279. }
  280. }
  281. return iFilter;
  282. }
  283. void CHudChat::StartMessageMode( int iMessageModeType )
  284. {
  285. BaseClass::StartMessageMode(iMessageModeType);
  286. vgui::ipanel()->SetTopmostPopup(GetVPanel(), true);
  287. }
  288. void CHudChat::StopMessageMode( void )
  289. {
  290. vgui::ipanel()->SetTopmostPopup(GetVPanel(), false);
  291. BaseClass::StopMessageMode();
  292. }