From 1f761faee0f26444c31ed6d8b9d2e034c8fa5e6b Mon Sep 17 00:00:00 2001 From: evmarcus <110736118+evmarcus@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:40:18 -0400 Subject: [PATCH] Close #11512: Add coloured usernames in multiplayer servers by group Co-authored-by: mbilik Co-authored-by: Matt --- distribution/changelog.txt | 1 + src/openrct2/network/NetworkBase.cpp | 65 +++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 9fe2a96371..1bb633bf3f 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.4.11 (in development) ------------------------------------------------------------------------ +- Feature: [#11512] Coloured usernames by group on multiplayer servers. - Feature: [#21734] Park admittance price can now be set via text input. - Improved: [#21769] Expose “animation is backwards” wall property in Tile Inspector. - Change: [#21715] [Plugin] Remove access to the internal `owner` property. Note: `ownership` is still accessible. diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 79700af5c3..052bc1cbbf 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -711,15 +711,70 @@ int32_t NetworkBase::GetNumVisiblePlayers() const noexcept return static_cast(player_list.size()); } -const char* NetworkBase::FormatChat(NetworkPlayer* fromplayer, const char* text) +const char* NetworkBase::FormatChat(NetworkPlayer* fromPlayer, const char* text) { static std::string formatted; formatted.clear(); - formatted += "{OUTLINE}"; - if (fromplayer != nullptr) + + if (fromPlayer != nullptr) { - formatted += "{BABYBLUE}"; - formatted += fromplayer->Name; + auto& network = OpenRCT2::GetContext()->GetNetwork(); + auto it = network.GetGroupByID(fromPlayer->Id); + std::string groupName = ""; + std::vector colours; + if (it != nullptr) + { + groupName = it->GetName(); + if (groupName[0] != '{') + { + colours.push_back("{WHITE}"); + } + } + + for (size_t i = 0; i < groupName.size(); ++i) + { + if (groupName[i] == '{') + { + std::string colour = "{"; + ++i; + while (i < groupName.size() && groupName[i] != '}' && groupName[i] != '{') + { + colour += groupName[i]; + ++i; + } + colour += '}'; + if (groupName[i] == '}' && i < groupName.size()) + { + colours.push_back(colour); + } + } + } + + if (colours.size() == 0 || (colours.size() == 1 && colours[0] == "{WHITE}")) + { + formatted += "{BABYBLUE}"; + formatted += fromPlayer->Name; + } + else + { + size_t j = 0; + size_t proportionalSize = fromPlayer->Name.size() / colours.size(); + for (size_t i = 0; i < colours.size(); ++i) + { + formatted += colours[i]; + size_t numCharacters = proportionalSize + j; + for (; j < numCharacters && j < fromPlayer->Name.size(); ++j) + { + formatted += fromPlayer->Name[j]; + } + } + while (j < fromPlayer->Name.size()) + { + formatted += fromPlayer->Name[j]; + j++; + } + } + formatted += ": "; } formatted += "{WHITE}";