Counter Strike : Global Offensive Source Code
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.

703 lines
21 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: CS's custom C_PlayerResource
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "c_cs_playerresource.h"
  9. #include <shareddefs.h>
  10. #include <cs_shareddefs.h>
  11. #include "hud.h"
  12. #include "vgui/ILocalize.h"
  13. #include "vstdlib/vstrtools.h"
  14. #include "cs_gamerules.h"
  15. #include "c_cs_player.h"
  16. #include "c_cs_team.h"
  17. #include "bannedwords.h"
  18. // memdbgon must be the last include file in a .cpp file!!!
  19. #include "tier0/memdbgon.h"
  20. IMPLEMENT_CLIENTCLASS_DT(C_CS_PlayerResource, DT_CSPlayerResource, CCSPlayerResource)
  21. RecvPropInt( RECVINFO( m_iPlayerC4 ) ),
  22. RecvPropInt( RECVINFO( m_iPlayerVIP ) ),
  23. RecvPropArray3( RECVINFO_ARRAY(m_bHostageAlive), RecvPropInt( RECVINFO(m_bHostageAlive[0]))),
  24. RecvPropArray3( RECVINFO_ARRAY(m_isHostageFollowingSomeone), RecvPropInt( RECVINFO(m_isHostageFollowingSomeone[0]))),
  25. RecvPropArray3( RECVINFO_ARRAY(m_iHostageEntityIDs), RecvPropInt( RECVINFO(m_iHostageEntityIDs[0]))),
  26. RecvPropVector( RECVINFO(m_bombsiteCenterA) ),
  27. RecvPropVector( RECVINFO(m_bombsiteCenterB) ),
  28. RecvPropArray3( RECVINFO_ARRAY(m_hostageRescueX), RecvPropInt( RECVINFO(m_hostageRescueX[0]))),
  29. RecvPropArray3( RECVINFO_ARRAY(m_hostageRescueY), RecvPropInt( RECVINFO(m_hostageRescueY[0]))),
  30. RecvPropArray3( RECVINFO_ARRAY(m_hostageRescueZ), RecvPropInt( RECVINFO(m_hostageRescueZ[0]))),
  31. RecvPropArray3( RECVINFO_ARRAY(m_iMVPs), RecvPropInt( RECVINFO(m_iMVPs[0]))),
  32. RecvPropArray3( RECVINFO_ARRAY(m_iArmor), RecvPropInt( RECVINFO(m_iArmor[0]))),
  33. RecvPropArray3( RECVINFO_ARRAY(m_bHasHelmet), RecvPropInt( RECVINFO(m_bHasHelmet[0]))),
  34. RecvPropArray3( RECVINFO_ARRAY(m_bHasDefuser), RecvPropInt( RECVINFO(m_bHasDefuser[0]))),
  35. RecvPropArray3( RECVINFO_ARRAY(m_iScore), RecvPropInt( RECVINFO(m_iScore[0]))),
  36. RecvPropArray3( RECVINFO_ARRAY(m_iCompetitiveRanking), RecvPropInt( RECVINFO(m_iCompetitiveRanking[0]))),
  37. RecvPropArray3( RECVINFO_ARRAY(m_iCompetitiveWins), RecvPropInt( RECVINFO(m_iCompetitiveWins[0]))),
  38. RecvPropArray3( RECVINFO_ARRAY( m_iCompTeammateColor ), RecvPropInt( RECVINFO( m_iCompTeammateColor[0] ) ) ),
  39. #if CS_CONTROLLABLE_BOTS_ENABLED
  40. RecvPropArray3( RECVINFO_ARRAY(m_bControllingBot), RecvPropInt( RECVINFO(m_bControllingBot[0]))),
  41. RecvPropArray3( RECVINFO_ARRAY(m_iControlledPlayer), RecvPropInt( RECVINFO(m_iControlledPlayer[0]))),
  42. RecvPropArray3( RECVINFO_ARRAY(m_iControlledByPlayer), RecvPropInt( RECVINFO(m_iControlledByPlayer[0]))),
  43. #endif
  44. RecvPropArray3( RECVINFO_ARRAY(m_iBotDifficulty), RecvPropInt( RECVINFO( m_iBotDifficulty[0] ) ) ),
  45. RecvPropArray3( RECVINFO_ARRAY(m_szClan), RecvPropString( RECVINFO(m_szClan[0]))),
  46. RecvPropArray3( RECVINFO_ARRAY(m_iTotalCashSpent), RecvPropInt( RECVINFO(m_iTotalCashSpent[0]))),
  47. RecvPropArray3( RECVINFO_ARRAY(m_iCashSpentThisRound), RecvPropInt( RECVINFO(m_iCashSpentThisRound[0]))),
  48. RecvPropArray3( RECVINFO_ARRAY(m_nEndMatchNextMapVotes), RecvPropInt( RECVINFO(m_nEndMatchNextMapVotes[0]))),
  49. RecvPropBool( RECVINFO( m_bEndMatchNextMapAllVoted ) ),
  50. RecvPropArray3( RECVINFO_ARRAY(m_nActiveCoinRank), RecvPropInt( RECVINFO(m_nActiveCoinRank[0]))),
  51. RecvPropArray3( RECVINFO_ARRAY(m_nMusicID), RecvPropInt( RECVINFO(m_nMusicID[0]))),
  52. // RecvPropArray3( RECVINFO_ARRAY(m_bIsAssassinationTarget), RecvPropBool( RECVINFO(m_bIsAssassinationTarget[0]))),
  53. RecvPropArray3( RECVINFO_ARRAY(m_nPersonaDataPublicLevel), RecvPropInt( RECVINFO(m_nPersonaDataPublicLevel[0]))),
  54. RecvPropArray3( RECVINFO_ARRAY(m_nPersonaDataPublicCommendsLeader), RecvPropInt( RECVINFO(m_nPersonaDataPublicCommendsLeader[0]))),
  55. RecvPropArray3( RECVINFO_ARRAY(m_nPersonaDataPublicCommendsTeacher), RecvPropInt( RECVINFO(m_nPersonaDataPublicCommendsTeacher[0]))),
  56. RecvPropArray3( RECVINFO_ARRAY(m_nPersonaDataPublicCommendsFriendly), RecvPropInt( RECVINFO(m_nPersonaDataPublicCommendsFriendly[0]))),
  57. END_RECV_TABLE()
  58. ConVar cl_show_playernames_max_chars_console( "cl_show_playernames_max_chars_console", "0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY, "Shows all player names (including bots) as 16 W's." );
  59. extern ConVar cl_spec_use_tournament_content_standards;
  60. extern ConVar sv_spec_use_tournament_content_standards;
  61. //-----------------------------------------------------------------------------
  62. // Purpose:
  63. //-----------------------------------------------------------------------------
  64. C_CS_PlayerResource::C_CS_PlayerResource()
  65. {
  66. m_Colors[TEAM_TERRORIST] = COLOR_RED;
  67. m_Colors[TEAM_CT] = COLOR_BLUE;
  68. memset( m_iMVPs, 0, sizeof( m_iMVPs ) );
  69. memset( m_bHasHelmet, 0, sizeof( m_bHasHelmet ) );
  70. memset( m_bHasDefuser, 0, sizeof( m_bHasDefuser ) );
  71. memset( m_iArmor, 0, sizeof( m_iArmor ) );
  72. memset( m_iScore, 0, sizeof( m_iScore ) );
  73. memset( m_iCompetitiveRanking, 0, sizeof( m_iCompetitiveRanking ) );
  74. memset( m_iCompetitiveWins, 0, sizeof( m_iCompetitiveWins ) );
  75. memset( m_iCompTeammateColor, 0, sizeof( m_iCompTeammateColor ) );
  76. memset( m_nEndMatchNextMapVotes, 0, sizeof( m_nEndMatchNextMapVotes ) );
  77. memset( m_nActiveCoinRank, 0, sizeof( m_nActiveCoinRank ) );
  78. memset( m_nMusicID, 0, sizeof( m_nMusicID ) );
  79. memset( m_bIsAssassinationTarget, 0, sizeof( m_bIsAssassinationTarget ) );
  80. memset( m_nPersonaDataPublicLevel, 0, sizeof( m_nPersonaDataPublicLevel ) );
  81. memset( m_nPersonaDataPublicCommendsLeader, 0, sizeof( m_nPersonaDataPublicCommendsLeader ) );
  82. memset( m_nPersonaDataPublicCommendsTeacher, 0, sizeof( m_nPersonaDataPublicCommendsTeacher ) );
  83. memset( m_nPersonaDataPublicCommendsFriendly, 0, sizeof( m_nPersonaDataPublicCommendsFriendly ) );
  84. m_bDisableAssassinationTargetNameOverride = false;
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Purpose:
  88. //-----------------------------------------------------------------------------
  89. C_CS_PlayerResource::~C_CS_PlayerResource()
  90. {
  91. #if defined ENABLE_CLIENT_INVENTORIES_FOR_OTHER_PLAYERS
  92. for ( int i = 0; i < Q_ARRAYSIZE( m_Inventory ); ++ i )
  93. {
  94. m_Inventory[i].Shutdown();
  95. }
  96. #endif
  97. }
  98. bool C_CS_PlayerResource::IsVIP(int iIndex )
  99. {
  100. return m_iPlayerVIP == iIndex;
  101. }
  102. bool C_CS_PlayerResource::HasC4(int iIndex )
  103. {
  104. return m_iPlayerC4 == iIndex;
  105. }
  106. bool C_CS_PlayerResource::IsHostageAlive(int iIndex)
  107. {
  108. if ( iIndex < 0 || iIndex >= MAX_HOSTAGES )
  109. return false;
  110. return m_bHostageAlive[iIndex];
  111. }
  112. bool C_CS_PlayerResource::IsHostageFollowingSomeone(int iIndex)
  113. {
  114. if ( iIndex < 0 || iIndex >= MAX_HOSTAGES )
  115. return false;
  116. return m_isHostageFollowingSomeone[iIndex];
  117. }
  118. int C_CS_PlayerResource::GetHostageEntityID(int iIndex)
  119. {
  120. if ( iIndex < 0 || iIndex >= MAX_HOSTAGES )
  121. return -1;
  122. return m_iHostageEntityIDs[iIndex];
  123. }
  124. const Vector C_CS_PlayerResource::GetBombsiteAPosition()
  125. {
  126. if ( CSGameRules() && CSGameRules()->IsBombDefuseMap() == false )
  127. return vec3_origin;
  128. return m_bombsiteCenterA;
  129. }
  130. const Vector C_CS_PlayerResource::GetBombsiteBPosition()
  131. {
  132. if ( CSGameRules() && CSGameRules()->IsBombDefuseMap() == false )
  133. return vec3_origin;
  134. return m_bombsiteCenterB;
  135. }
  136. const Vector C_CS_PlayerResource::GetHostageRescuePosition( int iIndex )
  137. {
  138. if ( iIndex < 0 || iIndex >= MAX_HOSTAGE_RESCUES )
  139. return vec3_origin;
  140. Vector ret;
  141. ret.x = m_hostageRescueX[iIndex];
  142. ret.y = m_hostageRescueY[iIndex];
  143. ret.z = m_hostageRescueZ[iIndex];
  144. return ret;
  145. }
  146. //--------------------------------------------------------------------------------------------------------
  147. int C_CS_PlayerResource::GetNumMVPs( int iIndex )
  148. {
  149. if ( !IsConnected( iIndex ) )
  150. return false;
  151. return m_iMVPs[iIndex];
  152. }
  153. //--------------------------------------------------------------------------------------------------------
  154. bool C_CS_PlayerResource::HasDefuser( int iIndex )
  155. {
  156. if ( !IsConnected( iIndex ) )
  157. return false;
  158. return m_bHasDefuser[iIndex];
  159. }
  160. //--------------------------------------------------------------------------------------------------------
  161. bool C_CS_PlayerResource::HasHelmet( int iIndex )
  162. {
  163. if ( !IsConnected( iIndex ) )
  164. return false;
  165. return m_bHasHelmet[iIndex];
  166. }
  167. //--------------------------------------------------------------------------------------------------------
  168. int C_CS_PlayerResource::GetArmor( int iIndex )
  169. {
  170. if ( !IsConnected( iIndex ) )
  171. return 0;
  172. return m_iArmor[iIndex];
  173. }
  174. //--------------------------------------------------------------------------------------------------------
  175. int C_CS_PlayerResource::GetScore( int iIndex )
  176. {
  177. if ( !IsConnected( iIndex ) )
  178. return 0;
  179. return m_iScore[iIndex];
  180. }
  181. //--------------------------------------------------------------------------------------------------------
  182. int C_CS_PlayerResource::GetCompetitiveRanking( int iIndex )
  183. {
  184. if ( !IsConnected( iIndex ) )
  185. return 0;
  186. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  187. {
  188. if ( pParameters->m_bAnonymousPlayerIdentity )
  189. return 0;
  190. }
  191. return m_iCompetitiveRanking[iIndex];
  192. }
  193. //--------------------------------------------------------------------------------------------------------
  194. int C_CS_PlayerResource::GetCompetitiveWins( int iIndex )
  195. {
  196. if ( !IsConnected( iIndex ) )
  197. return 0;
  198. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  199. {
  200. if ( pParameters->m_bAnonymousPlayerIdentity )
  201. return 0;
  202. }
  203. return m_iCompetitiveWins[iIndex];
  204. }
  205. //--------------------------------------------------------------------------------------------------------
  206. int C_CS_PlayerResource::GetCompTeammateColor( int iIndex )
  207. {
  208. if ( !IsConnected( iIndex ) || !CSGameRules( ) )
  209. return -1;
  210. if ( !CSGameRules( )->IsPlayingAnyCompetitiveStrictRuleset( ) )
  211. return -1;
  212. if ( IsFakePlayer( iIndex ) )
  213. return -2;
  214. return m_iCompTeammateColor[iIndex];
  215. }
  216. //--------------------------------------------------------------------------------------------------------
  217. int C_CS_PlayerResource::GetTotalCashSpent( int iIndex )
  218. {
  219. if ( !IsConnected( iIndex ) )
  220. return 0;
  221. return m_iTotalCashSpent[iIndex];
  222. }
  223. //--------------------------------------------------------------------------------------------------------
  224. int C_CS_PlayerResource::GetCashSpentThisRound( int iIndex )
  225. {
  226. if ( !IsConnected( iIndex ) )
  227. return 0;
  228. return m_iCashSpentThisRound[iIndex];
  229. }
  230. //--------------------------------------------------------------------------------------------------------
  231. int C_CS_PlayerResource::GetEndMatchNextMapVote( int iIndex )
  232. {
  233. if ( !IsConnected( iIndex ) )
  234. return -1;
  235. return m_nEndMatchNextMapVotes[iIndex];
  236. }
  237. int C_CS_PlayerResource::GetActiveCoinRank( int iIndex )
  238. {
  239. if ( !IsConnected( iIndex ) )
  240. return 0;
  241. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  242. {
  243. if ( pParameters->m_bAnonymousPlayerIdentity )
  244. return 0;
  245. }
  246. return m_nActiveCoinRank[iIndex];
  247. }
  248. int C_CS_PlayerResource::GetPersonaDataPublicLevel( int iIndex )
  249. {
  250. if ( !IsConnected( iIndex ) )
  251. return 0;
  252. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  253. {
  254. if ( pParameters->m_bAnonymousPlayerIdentity )
  255. return 0;
  256. }
  257. return m_nPersonaDataPublicLevel[ iIndex ];
  258. }
  259. int C_CS_PlayerResource::GetPersonaDataPublicCommendsLeader( int iIndex )
  260. {
  261. if ( !IsConnected( iIndex ) )
  262. return 0;
  263. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  264. {
  265. if ( pParameters->m_bAnonymousPlayerIdentity )
  266. return 0;
  267. }
  268. return m_nPersonaDataPublicCommendsLeader[ iIndex ];
  269. }
  270. int C_CS_PlayerResource::GetPersonaDataPublicCommendsTeacher( int iIndex )
  271. {
  272. if ( !IsConnected( iIndex ) )
  273. return 0;
  274. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  275. {
  276. if ( pParameters->m_bAnonymousPlayerIdentity )
  277. return 0;
  278. }
  279. return m_nPersonaDataPublicCommendsTeacher[ iIndex ];
  280. }
  281. int C_CS_PlayerResource::GetPersonaDataPublicCommendsFriendly( int iIndex )
  282. {
  283. if ( !IsConnected( iIndex ) )
  284. return 0;
  285. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  286. {
  287. if ( pParameters->m_bAnonymousPlayerIdentity )
  288. return 0;
  289. }
  290. return m_nPersonaDataPublicCommendsFriendly[ iIndex ];
  291. }
  292. int C_CS_PlayerResource::GetMusicID( int iIndex )
  293. {
  294. if ( !IsConnected( iIndex ) )
  295. return 0;
  296. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  297. {
  298. if ( pParameters->m_bAnonymousPlayerIdentity )
  299. return 0;
  300. }
  301. return m_nMusicID[ iIndex ];
  302. }
  303. void C_CS_PlayerResource::OnDataChanged(DataUpdateType_t updateType)
  304. {
  305. BaseClass::OnDataChanged( updateType );
  306. #if defined ENABLE_CLIENT_INVENTORIES_FOR_OTHER_PLAYERS
  307. static XUID s_mySteamID = steamapicontext->SteamUser()->GetSteamID().ConvertToUint64();
  308. // Request player inventories that we haven't requested yet regardless if they are in our out of PVS
  309. for ( int i = 1; i <= MAX_PLAYERS; i ++ )
  310. {
  311. if ( ( m_Xuids[i] != INVALID_XUID ) && ( m_Xuids[i] != s_mySteamID ) )
  312. {
  313. bool bRequest = false;
  314. if ( CSteamID( m_Xuids[i] ).GetAccountID() != CSteamID( m_Inventory[i].GetOwner().ID() ).GetAccountID() )
  315. bRequest = true;
  316. else if ( !m_Inventory[i].GetSOC() )
  317. bRequest = true;
  318. else if ( !m_Inventory[i].GetSOC()->BIsInitialized() || !m_Inventory[i].GetSOC()->BIsSubscribed() )
  319. bRequest = true;
  320. if ( bRequest )
  321. {
  322. // We need to request this user's inventory
  323. CSInventoryManager()->SteamRequestInventory( &m_Inventory[i], CSteamID( m_Xuids[i] ) );
  324. }
  325. }
  326. }
  327. #endif
  328. }
  329. bool C_CS_PlayerResource::EndMatchNextMapAllVoted( void )
  330. {
  331. return m_bEndMatchNextMapAllVoted;
  332. }
  333. const char *C_CS_PlayerResource::GetClanTag( int iIndex )
  334. {
  335. if ( iIndex < 1 || iIndex > MAX_PLAYERS )
  336. {
  337. Assert( false );
  338. return "";
  339. }
  340. if ( !IsConnected( iIndex ) )
  341. return "";
  342. if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
  343. {
  344. if ( pParameters->m_bAnonymousPlayerIdentity )
  345. return "";
  346. }
  347. g_BannedWords.CensorBannedWordsInplace( m_szClan[iIndex] );
  348. return m_szClan[iIndex];
  349. }
  350. #if CS_CONTROLLABLE_BOTS_ENABLED
  351. bool C_CS_PlayerResource::IsControllingBot( int index )
  352. {
  353. return m_bControllingBot[ index ];
  354. }
  355. int C_CS_PlayerResource::GetControlledPlayer( int index )
  356. {
  357. return m_iControlledPlayer[ index ];
  358. }
  359. int C_CS_PlayerResource::GetControlledByPlayer( int index )
  360. {
  361. return m_iControlledByPlayer[ index ];
  362. }
  363. bool C_CS_PlayerResource::IsAssassinationTarget( int index )
  364. {
  365. if ( m_bDisableAssassinationTargetNameOverride )
  366. return false;
  367. return m_bIsAssassinationTarget[ index ];
  368. }
  369. C_CS_PlayerResource * GetCSResources( void )
  370. {
  371. return ( C_CS_PlayerResource* ) g_PR;
  372. }
  373. const char *C_CS_PlayerResource::GetPlayerName( int index )
  374. {
  375. if ( cl_show_playernames_max_chars_console.GetBool() )
  376. return "WWWWWWWWWWWWWWWW";
  377. CEconQuestDefinition *pQuestDef = CSGameRules()->GetActiveAssassinationQuest();
  378. if ( IsAssassinationTarget( index ) && pQuestDef )
  379. {
  380. static char szAssassinationTargetName[ MAX_PLAYER_NAME_LENGTH ];
  381. const char* szLocToken = Helper_GetLocalPlayerAssassinationQuestLocToken( pQuestDef );
  382. if ( szLocToken )
  383. {
  384. V_UnicodeToUTF8( g_pVGuiLocalize->Find( szLocToken ), szAssassinationTargetName, MAX_PLAYER_NAME_LENGTH );
  385. return szAssassinationTargetName;
  386. }
  387. }
  388. return BaseClass::GetPlayerName( index );
  389. }
  390. void C_CS_PlayerResource::UpdatePlayerName( int slot )
  391. {
  392. if ( slot < 1 || slot > MAX_PLAYERS )
  393. {
  394. Error( "UpdatePlayerName with bogus slot %d\n", slot );
  395. return;
  396. }
  397. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer( );
  398. char const *pchPlayerName = NULL;
  399. player_info_t sPlayerInfo;
  400. bool bUseTournamentContentStandards = cl_spec_use_tournament_content_standards.GetBool( ) || sv_spec_use_tournament_content_standards.GetBool( );
  401. // is this spectator insisting to use official pro player names?
  402. bool bGetProPlayerName = bUseTournamentContentStandards;
  403. if ( IsConnected( slot ) && ( pLocalPlayer->IsSpectator( ) || pLocalPlayer->IsHLTV( ) ) && bGetProPlayerName )
  404. {
  405. CProPlayerData const *pProPlayerData = pProPlayerData = GEconItemSchema( ).GetProPlayerDataByAccountID( GetXuid( index ) );
  406. if ( pProPlayerData )
  407. {
  408. pchPlayerName = pProPlayerData->GetName( );
  409. }
  410. }
  411. // not a pro or we don't care.
  412. if ( !pchPlayerName &&
  413. IsConnected( slot ) &&
  414. engine->GetPlayerInfo( slot, &sPlayerInfo ) )
  415. {
  416. pchPlayerName = sPlayerInfo.name;
  417. if ( sPlayerInfo.fakeplayer && pchPlayerName && *pchPlayerName )
  418. { // also avoids censorship in pre-localized names
  419. UpdateAsLocalizedFakePlayerName( slot, pchPlayerName );
  420. return;
  421. }
  422. }
  423. if ( !pchPlayerName )
  424. pchPlayerName = PLAYER_UNCONNECTED_NAME;
  425. if ( g_BannedWords.BInitialized() )
  426. {
  427. int nLen = V_strlen( pchPlayerName );
  428. char *chPlayerName = ( char * ) stackalloc( 1 + nLen );
  429. V_memcpy( chPlayerName, pchPlayerName, 1 + nLen );
  430. if ( g_BannedWords.CensorBannedWordsInplace( chPlayerName ) )
  431. pchPlayerName = chPlayerName;
  432. }
  433. if ( !m_szName[ slot ] || Q_stricmp( m_szName[ slot ], pchPlayerName ) )
  434. {
  435. m_szName[ slot ] = AllocPooledString( pchPlayerName );
  436. }
  437. }
  438. int C_CS_PlayerResource::GetBotDifficulty( int index )
  439. {
  440. return m_iBotDifficulty[index];
  441. }
  442. #if defined ENABLE_CLIENT_INVENTORIES_FOR_OTHER_PLAYERS
  443. CCSPlayerInventory * C_CS_PlayerResource::GetInventory( int index )
  444. {
  445. return &m_Inventory[index];
  446. }
  447. #endif
  448. const wchar_t* C_CS_PlayerResource::GetDecoratedPlayerName( int index, wchar_t* buffer, int buffsize, EDecoratedPlayerNameFlag_t flags )
  449. {
  450. if ( IsConnected( index ) )
  451. {
  452. bool addBotToNameIfControllingBot = !!(flags & k_EDecoratedPlayerNameFlag_AddBotToNameIfControllingBot);
  453. bool useNameOfControllingPlayer = !(flags & k_EDecoratedPlayerNameFlag_DontUseNameOfControllingPlayer);
  454. bool bShowClanName = !(flags & k_EDecoratedPlayerNameFlag_DontShowClanName);
  455. bool bMakeStringSafe = !(flags & k_EDecoratedPlayerNameFlag_DontMakeStringSafe);
  456. bool bSkipAssassinationTargetName = !!(flags & k_EDecoratedPlayerNameFlag_DontUseAssassinationTargetName);
  457. int nameIndex = index;
  458. int controlledBy = GetControlledByPlayer( index );
  459. int nBotControlStringType = 0; // normal name
  460. if( controlledBy && useNameOfControllingPlayer )
  461. {
  462. nBotControlStringType = 1;// BOT ( name )
  463. nameIndex = controlledBy;
  464. // HACK: We want to have a fake name for this player if they're our target
  465. // but we want to show the real player name if they're controlling a bot AND show the fake name in the scoreboard
  466. // for their dead player entry.
  467. Assert( m_bDisableAssassinationTargetNameOverride == false );
  468. m_bDisableAssassinationTargetNameOverride = true;
  469. }
  470. else if ( IsFakePlayer( index ) && !cl_show_playernames_max_chars_console.GetBool() && CSGameRules() && !CSGameRules()->IsPlayingCooperativeGametype() )
  471. {
  472. nBotControlStringType = 2; // BOT name
  473. }
  474. else if ( IsControllingBot( index ) && addBotToNameIfControllingBot )
  475. {
  476. nBotControlStringType = 1; // BOT ( name )
  477. Assert( m_bDisableAssassinationTargetNameOverride == false );
  478. m_bDisableAssassinationTargetNameOverride = true;
  479. }
  480. wchar_t wide_name[MAX_PLAYER_NAME_LENGTH];
  481. wide_name[0] = L'\0';
  482. char nameBuf[MAX_PLAYER_NAME_LENGTH] = {0};
  483. if ( nBotControlStringType == 2 && GetBotDifficulty( index ) >= 0 )
  484. {
  485. ConVarRef sv_show_bot_difficulty_in_name( "sv_show_bot_difficulty_in_name" );
  486. if ( sv_show_bot_difficulty_in_name.GetBool() )
  487. {
  488. // Show bot difficulty as part of the bot name
  489. V_snprintf( nameBuf, ARRAYSIZE( nameBuf ) - 1, "%s[%d]", GetPlayerName( nameIndex ), GetBotDifficulty( index ) );
  490. }
  491. else
  492. {
  493. // Hide bot difficulty
  494. V_snprintf( nameBuf, ARRAYSIZE( nameBuf ) - 1, "%s", GetPlayerName( nameIndex ) );
  495. }
  496. }
  497. else if ( GetCoachingTeam( index ) != 0 )
  498. {
  499. char const *szCoach = NULL;
  500. switch( GetCoachingTeam( index ) )
  501. {
  502. case TEAM_TERRORIST:
  503. szCoach = "#SFUI_coach_name_t";
  504. break;
  505. case TEAM_CT:
  506. szCoach = "#SFUI_coach_name_ct";
  507. break;
  508. }
  509. if ( szCoach )
  510. {
  511. V_strcpy_safe( nameBuf, g_pVGuiLocalize->FindAsUTF8( szCoach ) );
  512. V_strcat_safe( nameBuf, " " );
  513. }
  514. V_strcat_safe( nameBuf, GetPlayerName( nameIndex ) );
  515. }
  516. else
  517. {
  518. //wchar_t wszClanTag[ MAX_PLAYER_NAME_LENGTH ];
  519. char szClan[MAX_PLAYER_NAME_LENGTH];
  520. if ( bShowClanName && Q_strlen( GetClanTag( index ) ) > 1 )
  521. {
  522. const char* optionalSpace = "";
  523. if ( GetClanTag( index )[0] == '#' )
  524. {
  525. optionalSpace = " ";
  526. }
  527. Q_snprintf( szClan, sizeof( szClan ), "%s%s ", optionalSpace, GetClanTag( index ) );
  528. }
  529. else
  530. {
  531. szClan[0] = 0;
  532. }
  533. //g_pVGuiLocalize->ConvertANSIToUnicode( szClan, wszClanTag, sizeof( wszClanTag ) );
  534. V_snprintf( nameBuf, ARRAYSIZE( nameBuf ) - 1, "%s%s", szClan, GetPlayerName( nameIndex ) );
  535. }
  536. V_UTF8ToUnicode( nameBuf /*GetPlayerName( nameIndex )*/, wide_name, sizeof( wide_name ) );
  537. g_BannedWords.CensorBannedWordsInplace( wide_name );
  538. wchar_t safe_wide_name[4 * MAX_DECORATED_PLAYER_NAME_LENGTH]; // add enough room to safely escape all 64 name characters
  539. safe_wide_name[0] = L'\0';
  540. wchar_t *pSafeWideName = wide_name;
  541. if ( bMakeStringSafe )
  542. {
  543. g_pScaleformUI->MakeStringSafe( wide_name, safe_wide_name, sizeof( safe_wide_name ) );
  544. pSafeWideName = safe_wide_name;
  545. }
  546. if ( !nBotControlStringType ) // normal name
  547. {
  548. if ( IsAssassinationTarget( index ) && !bSkipAssassinationTargetName )
  549. {
  550. Helper_GetDecoratedAssassinationTargetName( CSGameRules()->GetActiveAssassinationQuest(), buffer, buffsize/sizeof(wchar_t) );
  551. }
  552. else
  553. {
  554. V_wcsncpy( buffer, pSafeWideName, buffsize );
  555. }
  556. }
  557. else
  558. {
  559. const char* translationID = ( nBotControlStringType == 1 ) ? "#SFUI_bot_controlled_by" : "#SFUI_bot_decorated_name";
  560. g_pVGuiLocalize->ConstructString( buffer, buffsize, g_pVGuiLocalize->Find( translationID ), 1, pSafeWideName );
  561. }
  562. }
  563. else
  564. {
  565. *buffer = L'\0';
  566. }
  567. m_bDisableAssassinationTargetNameOverride = false;
  568. return buffer;
  569. }
  570. #endif