diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 417807e84..5396ed233 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -577,7 +577,7 @@ MACRO_CONFIG_COL(ClMessageFriendColor, cl_message_friend_color, 65425, CFGFLAG_C MACRO_CONFIG_INT(ConnTimeout, conn_timeout, 100, 5, 1000, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Network timeout") MACRO_CONFIG_INT(ConnTimeoutProtection, conn_timeout_protection, 1000, 5, 10000, CFGFLAG_SERVER, "Network timeout protection") -MACRO_CONFIG_INT(ClShowIds, cl_show_ids, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Whether to show client ids in scoreboard") +MACRO_CONFIG_INT(ClShowIds, cl_show_ids, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Whether to show client IDs in scoreboard, chat and spectator menu") MACRO_CONFIG_INT(ClScoreboardOnDeath, cl_scoreboard_on_death, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Whether to show scoreboard after death or not") MACRO_CONFIG_INT(ClAutoRaceRecord, cl_auto_race_record, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Save the best demo of each race") MACRO_CONFIG_INT(ClReplays, cl_replays, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable/disable replays") diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index b94339dfa..507918d92 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -977,18 +977,12 @@ void CChat::OnPrepareLines(float y) TextRender()->DeleteTextContainer(Line.m_TextContainerIndex); Graphics()->DeleteQuadContainer(Line.m_QuadContainerIndex); - char aName[64 + 12] = ""; - + char aClientId[16] = ""; if(g_Config.m_ClShowIds && Line.m_ClientId >= 0 && Line.m_aName[0] != '\0') { - if(Line.m_ClientId < 10) - str_format(aName, sizeof(aName), " %d: ", Line.m_ClientId); - else - str_format(aName, sizeof(aName), "%d: ", Line.m_ClientId); + GameClient()->FormatClientId(Line.m_ClientId, aClientId, EClientIdFormat::INDENT_AUTO); } - str_append(aName, Line.m_aName); - char aCount[12]; if(Line.m_ClientId < 0) str_format(aCount, sizeof(aCount), "[%d] ", Line.m_TimesRepeated + 1); @@ -1029,7 +1023,8 @@ void CChat::OnPrepareLines(float y) } } - TextRender()->TextEx(&Cursor, aName); + TextRender()->TextEx(&Cursor, aClientId); + TextRender()->TextEx(&Cursor, Line.m_aName); if(Line.m_TimesRepeated > 0) TextRender()->TextEx(&Cursor, aCount); @@ -1099,7 +1094,8 @@ void CChat::OnPrepareLines(float y) NameColor = ColorRGBA(0.8f, 0.8f, 0.8f, 1.f); TextRender()->TextColor(NameColor); - TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &Cursor, aName); + TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &Cursor, aClientId); + TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &Cursor, Line.m_aName); if(Line.m_TimesRepeated > 0) { diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index b22d50ec2..9eff2b3af 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -2544,7 +2544,7 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView) RightView.HSplitTop(MarginSmall, nullptr, &RightView); // Switches of various DDRace HUD elements - DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClShowIds, Localize("Show client IDs in scoreboard"), &g_Config.m_ClShowIds, &RightView, LineSize); + DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClShowIds, Localize("Show client IDs (scoreboard, chat, spectator)"), &g_Config.m_ClShowIds, &RightView, LineSize); DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClShowhudDDRace, Localize("Show DDRace HUD"), &g_Config.m_ClShowhudDDRace, &RightView, LineSize); if(g_Config.m_ClShowhudDDRace) { @@ -2750,18 +2750,12 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView) LocalCursor.m_LineWidth = LineWidth; const auto &Line = s_vLines[LineIndex]; - char aName[64 + 12] = ""; - + char aClientId[16] = ""; if(g_Config.m_ClShowIds && Line.m_ClientId >= 0 && Line.m_aName[0] != '\0') { - if(Line.m_ClientId < 10) - str_format(aName, sizeof(aName), " %d: ", Line.m_ClientId); - else - str_format(aName, sizeof(aName), "%d: ", Line.m_ClientId); + GameClient()->FormatClientId(Line.m_ClientId, aClientId, EClientIdFormat::INDENT_FORCE); } - str_append(aName, Line.m_aName); - char aCount[12]; if(Line.m_ClientId < 0) str_format(aCount, sizeof(aCount), "[%d] ", Line.m_TimesRepeated + 1); @@ -2793,7 +2787,8 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView) if(Render) TextRender()->TextColor(NameColor); - TextRender()->TextEx(&LocalCursor, aName, -1); + TextRender()->TextEx(&LocalCursor, aClientId); + TextRender()->TextEx(&LocalCursor, Line.m_aName); if(Line.m_TimesRepeated > 0) { diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index de08db6a8..a08823be6 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -206,8 +206,8 @@ void CScoreboard::RenderSpectators(CUIRect Spectators) if(g_Config.m_ClShowIds) { - char aClientId[5]; - str_format(aClientId, sizeof(aClientId), "%d: ", pInfo->m_ClientId); + char aClientId[16]; + GameClient()->FormatClientId(pInfo->m_ClientId, aClientId, EClientIdFormat::NO_INDENT); TextRender()->TextEx(&Cursor, aClientId); } TextRender()->TextEx(&Cursor, GameClient()->m_aClients[pInfo->m_ClientId].m_aName); @@ -512,13 +512,11 @@ void CScoreboard::RenderScoreboard(CUIRect Scoreboard, int Team, int CountStart, } if(g_Config.m_ClShowIds) { - str_format(aBuf, sizeof(aBuf), "%s%d: %s", pInfo->m_ClientId < 10 ? " " : "", pInfo->m_ClientId, ClientData.m_aName); - TextRender()->TextEx(&Cursor, aBuf); - } - else - { - TextRender()->TextEx(&Cursor, ClientData.m_aName); + char aClientId[16]; + GameClient()->FormatClientId(pInfo->m_ClientId, aClientId, EClientIdFormat::INDENT_AUTO); + TextRender()->TextEx(&Cursor, aClientId); } + TextRender()->TextEx(&Cursor, ClientData.m_aName); // ready / watching if(Client()->IsSixup() && Client()->m_TranslationContext.m_aClients[pInfo->m_ClientId].m_PlayerFlags7 & protocol7::PLAYERFLAG_READY) diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp index 11b4fd383..97b9d955b 100644 --- a/src/game/client/components/spectator.cpp +++ b/src/game/client/components/spectator.cpp @@ -477,7 +477,16 @@ void CSpectator::OnRender() TextRender()->TextColor(1.0f, 1.0f, 1.0f, PlayerSelected ? 1.0f : 0.5f); TeeAlpha = 1.0f; } - TextRender()->Text(Width / 2.0f + x + 50.0f, Height / 2.0f + y + BoxMove + (LineHeight - FontSize) / 2.f, FontSize, m_pClient->m_aClients[m_pClient->m_Snap.m_apInfoByDDTeamName[i]->m_ClientId].m_aName, 220.0f); + CTextCursor NameCursor; + TextRender()->SetCursor(&NameCursor, Width / 2.0f + x + 50.0f, Height / 2.0f + y + BoxMove + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END); + NameCursor.m_LineWidth = 180.0f; + if(g_Config.m_ClShowIds) + { + char aClientId[16]; + GameClient()->FormatClientId(m_pClient->m_Snap.m_apInfoByDDTeamName[i]->m_ClientId, aClientId, EClientIdFormat::INDENT_AUTO); + TextRender()->TextEx(&NameCursor, aClientId); + } + TextRender()->TextEx(&NameCursor, m_pClient->m_aClients[m_pClient->m_Snap.m_apInfoByDDTeamName[i]->m_ClientId].m_aName); if(GameClient()->m_MultiViewActivated) { diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 3233e9d35..b4ab98477 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -846,6 +846,32 @@ ColorRGBA CGameClient::GetDDTeamColor(int DDTeam, float Lightness) const return color_cast(ColorHSLA(Hue, 1.0f, Lightness)); } +void CGameClient::FormatClientId(int ClientId, char (&aClientId)[16], EClientIdFormat Format) const +{ + if(Format == EClientIdFormat::NO_INDENT) + { + str_format(aClientId, sizeof(aClientId), "%d", ClientId); + } + else + { + const int HighestClientId = Format == EClientIdFormat::INDENT_AUTO ? m_Snap.m_HighestClientId : 64; + const char *pFigureSpace = " "; + char aNumber[8]; + str_format(aNumber, sizeof(aNumber), "%d", ClientId); + aClientId[0] = '\0'; + if(ClientId < 100 && HighestClientId >= 100) + { + str_append(aClientId, pFigureSpace); + } + if(ClientId < 10 && HighestClientId >= 10) + { + str_append(aClientId, pFigureSpace); + } + str_append(aClientId, aNumber); + } + str_append(aClientId, ": "); +} + void CGameClient::OnRelease() { // release all systems @@ -1520,6 +1546,8 @@ void CGameClient::OnNewSnapshot() } } + m_Snap.m_HighestClientId = maximum(m_Snap.m_HighestClientId, pInfo->m_ClientId); + // calculate team-balance if(pInfo->m_Team != TEAM_SPECTATORS) { diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 60aa7f4e0..1def52441 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -111,6 +111,13 @@ public: const CNetObj_EntityEx *m_pDataEx; }; +enum class EClientIdFormat +{ + NO_INDENT, + INDENT_AUTO, + INDENT_FORCE, // for rendering settings preview +}; + class CGameClient : public IGameClient { public: @@ -315,6 +322,7 @@ public: int m_LocalClientId; int m_NumPlayers; int m_aTeamSize[2]; + int m_HighestClientId; // spectate data struct CSpectateInfo @@ -575,6 +583,7 @@ public: bool PredictDummy() { return g_Config.m_ClPredictDummy && Client()->DummyConnected() && m_Snap.m_LocalClientId >= 0 && m_PredictedDummyId >= 0 && !m_aClients[m_PredictedDummyId].m_Paused; } const CTuningParams *GetTuning(int i) { return &m_aTuningList[i]; } ColorRGBA GetDDTeamColor(int DDTeam, float Lightness = 0.5f) const; + void FormatClientId(int ClientId, char (&aClientId)[16], EClientIdFormat Format) const; CGameWorld m_GameWorld; CGameWorld m_PredictedWorld;